Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Filler

A Chrome extension for managing autofill profiles and filling web forms with a single click. Create reusable profiles for addresses, logins, and more — then fill any form instantly from the popup.

Built for QA workflows, form testing, and anyone tired of typing the same data over and over.

Features

  • Profile management — Create and organize multiple profiles by type (Address, Login)
  • Smart field detection — Heuristic scoring engine that matches form fields using autocomplete attributes, names, IDs, labels, placeholders, and ARIA labels
  • One-click autofill — Fill matched fields from the popup, with framework-aware event dispatching (works with React, Vue, Angular, and vanilla forms)
  • Form submission listening — Optionally detect form submissions and prompt to save the data as a new profile or update an existing one
  • Profile matching — Automatically suggests existing profiles to update based on field similarity
  • Sensitive data masking — Passwords and sensitive fields are masked in the save prompt preview
  • Extensible form types — Adding a new form type is a single declarative configuration

Tech Stack

  • TypeScript (strict mode, ES2022)
  • Vite 8 (build & watch)
  • Chrome Extension Manifest V3
  • Chrome Storage API for local persistence
  • No external UI frameworks — pure CSS

Getting Started

Prerequisites

  • Node.js (v18+)
  • A Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)

Install & Build

git clone https://github.com/coldiary/filler.git
cd filler
npm install
npm run build

Load the Extension

  1. Open chrome://extensions in your browser
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the dist/ folder
  4. Pin the Filler extension to your toolbar

Development

npm run dev

This starts Vite in watch mode. After each rebuild, go to chrome://extensions and click the reload button on the Filler card (or press the refresh icon).

Project Structure

src/
background/
service-worker.ts # MV3 service worker — message routing & storage
content/
content.ts # Content script entry point
autofill.ts # Field filling logic (input, select, framework compat)
field-matchers.ts # Heuristic field detection & scoring engine
form-listener.ts # Form submission detection & data extraction
popup/
popup.html / .css / .ts # Main popup — profile list, filtering, quick actions
profiles/
profile-editor.html / .css / .ts # Profile create/edit UI
save-prompt/
save-prompt.ts / .css # Injected save dialog (shadow DOM)
settings/
settings.html / .css / .ts # Settings modal
lib/
constants.ts # Form type registry & field definitions
storage.ts # Chrome storage wrapper
utils.ts # Shared helpers
types/
index.ts # TypeScript types & message contracts
manifest.json # Extension manifest (MV3)
icons/ # Extension icons (16, 48, 128)
tests/
test-form.html # 7 test forms for manual validation

How It Works

Field Matching

Filler scores each visible form element against known field definitions using weighted heuristics:

SignalWeight
autocomplete attr100
name attr60
id attr50
type attr40
<label> text30
placeholder20
ARIA labels15

Fields are assigned greedily — each element maps to at most one profile field, and vice versa.

Autofill

When filling, Filler sets values using native property descriptors and dispatches input, change, and blur events. This ensures compatibility with controlled components in React, Vue, and other frameworks.

For <select> elements, matching tries exact value, text content, country code/name mapping, and partial matches as fallbacks.

Form Submission Detection

When enabled in settings, Filler listens for form submissions on the page. It extracts field data using the same matching engine, auto-detects the form type based on field presence thresholds, and shows an injected save prompt (rendered in a shadow DOM to avoid style conflicts).

Message Passing

Communication between extension contexts uses typed discriminated unions:

  • AUTOFILL — Popup to Content: fill form fields with a profile
  • FORM_SUBMITTED — Content to Background: extracted form data
  • SHOW_SAVE_PROMPT — Background to Content: trigger save dialog
  • SAVE_PROFILE — Save Prompt to Background: persist profile
  • GET_PROFILES / GET_SETTINGS — Data fetch requests

Adding a New Form Type

Form types are fully declarative. Add a new entry to FORM_TYPES in src/lib/constants.ts:

{key: 'payment',label: 'Payment',icon: '<svg>...</svg>',badgeColor: '#10b981',fields: [{key: 'cardNumber',label: 'Card Number',autocomplete: 'cc-number', ... },// ...],editorSections: [...],editorFieldRows: [...],detectionKeys: ['cardNumber','cardHolder','expiry','cvv'],detectionThreshold: 3,buildSummary: (p)=>`${p.cardNumber||'Card'}`,}

Then add keyword matchers for the new fields in src/content/field-matchers.ts.

Testing

Open tests/test-form.html in your browser with the extension loaded. The page includes 7 form variants:

  1. Standard Form — common field names and IDs
  2. Autocomplete Form — relies on autocomplete attributes with unusual names
  3. Label-Only Form — generic names, detection via labels
  4. Placeholder-Only Form — detection via placeholders
  5. Login Form — username, password, email
  6. Login Form (Placeholder Only) — login fields without labels
  7. Minimal Form — email + name only, tests detection thresholds

Permissions

PermissionPurpose
storageRead/write profiles and settings locally
activeTabAccess the active tab for message passing
scriptingInject the save prompt script and styles

Content scripts run on all URLs (<all_urls>) to enable autofill on any page.

License

MIT

About

Chrome extension for managing autofill profiles

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages