diff --git a/Autofill/chrome.manifest b/Autofill/chrome.manifest
new file mode 100644
index 0000000..d85d28c
--- /dev/null
+++ b/Autofill/chrome.manifest
@@ -0,0 +1,6 @@
+content autofill chrome/content/
+skin autofill classic/1.0 chrome/skin/
+skin autofill classic/1.0 chrome/skin-linux/ os=Linux
+locale autofill en-US chrome/locale/en-US/
+locale autofill vi-VN chrome/locale/vi-VN/
+overlay chrome://browser/content/browser.xul chrome://autofill/content/ff-overlay.xul
diff --git a/Autofill/chrome/content/catdelete.xul b/Autofill/chrome/content/catdelete.xul
new file mode 100644
index 0000000..2e943b2
--- /dev/null
+++ b/Autofill/chrome/content/catdelete.xul
@@ -0,0 +1,21 @@
+
+
+
+
diff --git a/Autofill/chrome/content/catnew.xul b/Autofill/chrome/content/catnew.xul
new file mode 100644
index 0000000..3dac7e3
--- /dev/null
+++ b/Autofill/chrome/content/catnew.xul
@@ -0,0 +1,55 @@
+
+
+
+
diff --git a/Autofill/chrome/content/catrename.xul b/Autofill/chrome/content/catrename.xul
new file mode 100644
index 0000000..ed4b832
--- /dev/null
+++ b/Autofill/chrome/content/catrename.xul
@@ -0,0 +1,59 @@
+
+
+
+
diff --git a/Autofill/chrome/content/confirm.xul b/Autofill/chrome/content/confirm.xul
new file mode 100644
index 0000000..9540195
--- /dev/null
+++ b/Autofill/chrome/content/confirm.xul
@@ -0,0 +1,33 @@
+
+
+
+
diff --git a/Autofill/chrome/content/editbox.xul b/Autofill/chrome/content/editbox.xul
new file mode 100644
index 0000000..b5610c3
--- /dev/null
+++ b/Autofill/chrome/content/editbox.xul
@@ -0,0 +1,39 @@
+
+
+
+
diff --git a/Autofill/chrome/content/ff-overlay.js b/Autofill/chrome/content/ff-overlay.js
new file mode 100644
index 0000000..1090d48
--- /dev/null
+++ b/Autofill/chrome/content/ff-overlay.js
@@ -0,0 +1,511 @@
+/*
+ * @package Autofill
+ * @author Tom Doan
+ * @copyright (c) Tom Doan
+ * @license GNU General Public License
+ * @link http://www.tohodo.com/
+ */
+
+if (typeof Autofill=='undefined') {
+ var Autofill = {
+ /* Preferences interface */
+ P: Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch),
+ /* Complex strings interface (for Unicode support) */
+ SS: Components.interfaces.nsISupportsString,
+ /* Options window */
+ O: null,
+ /* Wizard window */
+ W: null,
+ /* Is right-clicked element a field? */
+ field: false,
+ /* Delay 1 sec to allow dynamically built iframes to be detected */
+ delay: function(e) {
+ var n = +Autofill.P.getCharPref('extensions.autofill.delaysec');
+ if (n>0) window.setTimeout(function(){Autofill.execute(e);}, n*1000);
+ else Autofill.execute(e);
+ },
+ /* Initialize */
+ init: function() {
+ var oMenu = document.getElementById('contentAreaContextMenu');
+ oMenu.addEventListener('popupshowing', this.drawMenu, false);
+ gBrowser.addEventListener('DOMContentLoaded', this.delay, true);
+ },
+ /* Render main Autofill context menu */
+ drawMenu: function() {
+ var D = document,
+ sTag = gContextMenu.target.nodeName,
+ bHide = (gContextMenu.onImage || gContextMenu.onLink || !Autofill.P.getBoolPref('extensions.autofill.menu'));
+ Autofill.field = (gContextMenu.onTextInput || sTag=='INPUT' || sTag=='SELECT' || sTag=='OPTION');
+ D.getElementById('autofill-menu').hidden = bHide;
+ D.getElementById('autofill-menusep').hidden = bHide;
+ D.getElementById('autofill-menu-wizform').hidden = Autofill.field;
+ D.getElementById('autofill-menu-wizfield').hidden = !Autofill.field;
+ },
+ /* Render Profiles context submenu */
+ drawCatsMenu: function() {
+ var sX = 'extensions.autofill.',
+ oMenuCats = document.getElementById('autofill-menu-cats'),
+ aCats = (this.P.prefHasUserValue(sX + 'cats')) ? JSON.parse(this.P.getComplexValue(sX + 'cats', this.SS).data) : [],
+ nCatIndex = this.P.getIntPref(sX + 'catnow');
+ for (var i=2, imax=Math.max(oMenuCats.itemCount-2, aCats.length), j=0, o; i-2|<.+?> *<.+?>/gi, n = 0,
+ oRules = (this.P.prefHasUserValue(sX + 'rules')) ? JSON.parse(this.P.getComplexValue(sX + 'rules', this.SS).data) : {},
+ aCats = (this.P.prefHasUserValue(sX + 'cats')) ? JSON.parse(this.P.getComplexValue(sX + 'cats', this.SS).data) : [],
+ nCatIndex = this.P.getIntPref(sX + 'catnow'),
+ aExceptions = (this.P.getCharPref(sX + 'exceptions')) ? this.P.getComplexValue(sX + 'exceptions', this.SS).data.split('\n') : [],
+ oOther = {
+ labelmatch: this.P.getBoolPref(sX + 'labelmatch'),
+ vars: this.P.getBoolPref(sX + 'vars'),
+ sound: this.P.getBoolPref(sX + 'sound')
+ },
+ bOverwrite = 0,
+ sLb, reLb = /^\(\?<([!=])([^)]+)\)(.+)/, reLbEnd,
+ sAlpha = 'abcdefghijklmnopqrstuvwxyz',
+ sNum = '0123456789',
+ sAlphaNum = sAlpha + sAlpha.toUpperCase() + sNum + sNum,
+ T = function(o) {
+ if (!sLb) {
+ if (re.test(o.name) || re.test(o.id)) return true;
+ else if ((sType=='button' || sType=='submit') && re.test(o.value)) return true;
+ else if (!(o.name || o.id) && re.test(o.className)) return true;
+ else if (o.src && re.test(o.src)) return true; // for certain iframes, e.g. WYMeditor
+ // Try to find match in text label
+ else if (oOther['labelmatch']) return Autofill.findText(o, re);
+ } else {
+ /* Process Regular Expression 'lookbehind' syntax */
+ var bLb = false,
+ sHaystack = (o.name || o.id) ? o.name + ' ' + o.id : o.className,
+ aMatch;
+ while (aMatch = reLbEnd.x.reG(sHaystack)) {
+ /* If the inner pattern matched, but the leading or trailing lookbehind failed */
+ if (reLbEnd.x.re.test(sHaystack.slice(0, aMatch.index))!=reLbEnd.x.type) bLb = true;
+ }
+ return bLb;
+ }
+ };
+ // Exit if rules table is empty
+ for (var i in oRules) {
+ if (oRules.hasOwnProperty(i)) n++;
+ }
+ if (n<1) return;
+ else n = 0;
+ // Exit if document title or URL matches a pattern in aExceptions
+ for (var i=0, imax=aExceptions.length; i1) ? aCats[nCatIndex-2].k : (nCatIndex==0) ? 'all' : '';
+ // If profile is not All or Unfiled...
+ if (sCat && sCat!='all') {
+ // Define site Regular Expression pattern for profile
+ re = new RegExp(aCats[nCatIndex-2].s || '.', 'i');
+ // Only proceed if profile filter matches document title or URL
+ if (!(re.test(doc.title) || re.test(doc.location.href))) return;
+ // Get profile overwrite flag
+ bOverwrite = aCats[nCatIndex-2].o || 0;
+ // If profile is All...
+ } else if (sCat=='all') {
+ var oCats = {};
+ for (var i=0, imax=aCats.length; i0) {
+ sOut = R(1, 9);
+ for (var k=1; k-1) {
+ aInts = sValue.replace(/ {2,}/g, ' ').split(' ');
+ o.selectedIndex = -1; // unselect all
+ for (var k=0, kmax=aInts.length; k0) {
+ var player = Cc['@mozilla.org/sound;1'].createInstance(Ci.nsISound),
+ ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
+ player.play(ios.newURI('chrome://autofill/content/sound.wav', null, null));
+ }
+ },
+ /* Clean Regular Expressions */
+ cleanRE: function(s) {
+ // Strip comment
+ s = s.replace(/\/\*.*?\*\/\s*/g, '');
+ // Escape forward slashes
+ s = s.replace(/\//g, '\\/') || '.';
+ // Escape stand-alone quantifiers
+ if (/^[+*?]|[^\\]([+*]{2}|[+*?]{3})|\[[^]]|\[\]/.test(s)) {
+ s = s.replace(/([[+*?])/g, '\\$1');
+ }
+ return s;
+ },
+ // Traverse DOM backwards to find first text node
+ findText: function(oNode, reTest) {
+ var bFound = false,
+ bAlt = false,
+ /* Find text node */
+ find = function(o, re) {
+ var oElm;
+ while (o) {
+ switch (o.nodeType) {
+ case 1:
+ // Go down...
+ if (o.lastChild && ((o.nodeName!='SELECT' && oNode.nodeName!='IFRAME' && o.nodeName.indexOf('SCRIPT')<0)
+ || (oNode.nodeName=='IFRAME' && o.nodeName!='DIV' && o.nodeName.slice(0, 1)!='H'))) find(o.lastChild, re);
+ // Go up...
+ else up(o, re);
+ break;
+ case 3:
+ if (o.textContent.replace(/\W+/, '')) {
+ // Text found!
+ if (re.test(o.textContent)) bFound = true;
+ // Text not found -- trying alternate route...
+ else if (oNode.parentNode.nodeName=='TD' && oNode.nodeName!='IFRAME' && !bAlt) {
+ bAlt = true;
+ oElm = oNode.parentNode.previousSibling;
+ while (oElm && !oElm.lastChild) {
+ oElm = oElm.previousSibling;
+ }
+ // Alternate route found
+ if (oElm && oElm.lastChild) find(oElm.lastChild, re);
+ // No alternatives -- exiting...
+ else bFound = null;
+ // No matches found -- exiting...
+ } else bFound = null;
+ } else up(o, re);
+ break;
+ }
+ if (bFound || bFound==null) break;
+ o = o.previousSibling;
+ }
+ },
+ /* Go up until there's a parent node that has a previous sibling */
+ up = function(o, re) {
+ if (o.parentNode && !o.previousSibling) {
+ var oElm = o.parentNode;
+ while (oElm && !oElm.previousSibling) {
+ oElm = oElm.parentNode;
+ }
+ if (oElm && oElm.previousSibling) find(oElm.previousSibling, re);
+ }
+ };
+ find(oNode, reTest);
+ return bFound || false;
+ },
+ /* Return random integer between nFrom and nTo */
+ rand: function(nFrom, nTo) {
+ return Math.round(Math.random()*(nTo-nFrom+1)+(nFrom-.5));
+ },
+ /* Show Options window */
+ showPrefs: function() {
+ if (!this.O || this.O.closed) this.O = window.openDialog('chrome://autofill/content/options.xul', '', 'centerscreen, chrome, dialog=no, resizable, toolbar');
+ else this.O.focus();
+ },
+ /* Show Form Fields Wizard */
+ showWizard: function() {
+ var oParam = {
+ i: {
+ isField: this.field,
+ target: gContextMenu.target,
+ options: this.O
+ }
+ };
+ if (!this.W || this.W.closed) this.W = window.openDialog('chrome://autofill/content/wizard.xul', '', 'alwaysRaised, centerscreen, chrome, dialog', oParam);
+ else this.W.focus();
+ }
+ };
+}
diff --git a/Autofill/chrome/content/ff-overlay.xul b/Autofill/chrome/content/ff-overlay.xul
new file mode 100644
index 0000000..abef899
--- /dev/null
+++ b/Autofill/chrome/content/ff-overlay.xul
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Autofill/chrome/content/moverule.xul b/Autofill/chrome/content/moverule.xul
new file mode 100644
index 0000000..5b248e4
--- /dev/null
+++ b/Autofill/chrome/content/moverule.xul
@@ -0,0 +1,38 @@
+
+
+
+
diff --git a/Autofill/chrome/content/options.js b/Autofill/chrome/content/options.js
new file mode 100644
index 0000000..490b5ff
--- /dev/null
+++ b/Autofill/chrome/content/options.js
@@ -0,0 +1,1020 @@
+/*
+ * @package Autofill
+ * @author Tom Doan
+ * @copyright (c) Tom Doan
+ * @license GNU General Public License
+ * @link http://www.tohodo.com/
+ */
+
+// Add method to get object size (length)
+Object.size = function(o) {
+ var n = 0;
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) n++;
+ }
+ return n;
+};
+
+// Define global variables
+var nVer = '3.6',
+ D = document,
+ Cc = Components.classes,
+ Ci = Components.interfaces,
+ P = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefBranch),
+ SS = Ci.nsISupportsString,
+ F, FP, W,
+ sAP = 'autofill-panel-',
+ sX = 'extensions.autofill.',
+ sV = sX + 'ver',
+ sR = sX + 'rules',
+ sRC = sX + 'rulecount',
+ sC = sX + 'cats',
+ sCC = sX + 'catcount',
+ sCI = sX + 'catnow',
+ sE = sX + 'exceptions',
+ oAO,
+ oR, nR,
+ oRLB, oC2, oC3, oC4,
+ oBRR, oBRU, oBRD, oBRM, oBRS,
+ aC, nC, nCI,
+ oC, sCN, oCS, oCO,
+ oBCR, oBCD,
+ oCCT, oCCB,
+ oTB,
+ oOO,
+ oD, oDO,
+ oNB,
+ oSB,
+ bRC = false, bCC = false,
+ bMac = navigator.platform.indexOf('Mac')>-1;
+
+// Add table row
+// n : rule ID
+function addRow(n, nSel, sName, sValue, sSite, sCat) {
+ var oRLI = oRLB.appendChild(D.createElement('richlistitem')),
+ oML = oRLI.appendChild(D.createElement('menulist')),
+ oTB1 = oRLI.appendChild(D.createElement('textbox')),
+ oTB2 = oRLI.appendChild(D.createElement('textbox')),
+ oTB3 = oRLI.appendChild(D.createElement('textbox')),
+ oElm = oRLI.firstChild,
+ sCatTooltip,
+ sBoxTooltip = oSB.getString('boxTooltip');
+ // Get profile name for tooltip
+ if (nCI==0) {
+ if (sCat=='all' || !sCat) sCatTooltip = 'Profile: Unfiled\n';
+ else {
+ for (var i=0, imax=aC.length; i0) {
+ for (var j=0, jmax=aC.length; j0; i--) {
+ if (a[i].selected) {
+ sSI += '[' + i + ']';
+ // Enable Move button only when valid rows selected
+ sN = a[i].id.slice(2); // extract # from r_#
+ if (!D.getElementById('n_' + sN).value
+ && !D.getElementById('v_' + sN).value
+ && !D.getElementById('s_' + sN).value) sSI += '[!]';
+ }
+ }
+ oBRM.disabled = (sSI.indexOf('[!]')>-1 || !sSI);
+ oBRU.disabled = (sSI.indexOf('[1]')>-1 || !sSI);
+ oBRD.disabled = (sSI.indexOf('[' + oRLB.itemCount + ']')>-1 || !sSI);
+}
+
+// Import settings from CSV file
+function importCSV() {
+ var sImportError = oSB.getString('importError'),
+ sImportOK = oSB.getString('importOK'),
+ sImportDialog = oSB.getString('importDialog');
+ FP.init(window, sImportDialog, F.modeOpen);
+ if (FP.show()==F.returnOK) {
+ var fstream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream),
+ cstream = Cc['@mozilla.org/intl/converter-input-stream;1'].createInstance(Ci.nsIConverterInputStream),
+ oStr = {},
+ nRead = 0,
+ sData = '',
+ aRows,
+ aCols,
+ sSplit,
+ bAppend = D.getElementById('radio-append').selected,
+ bExist,
+ oCatId = {},
+ i = 1,
+ imax,
+ n;
+ // Turn off notifications
+ oNB.removeAllNotifications();
+ // Begin reading from file stream...
+ fstream.init(FP.file, -1, 0, 0);
+ cstream.init(fstream, 'UTF-8', 0, 0);
+ do {
+ // Read as much as we can and put it in oStr.value
+ nRead = cstream.readString(0xffffffff, oStr);
+ sData += oStr.value;
+ } while (nRead!=0);
+ // Close file stream
+ cstream.close();
+ // Prepare to store in aRows array
+ sData = sData.replace(/^\s+|[ \r\n]+$/g, '');
+ sData = sData.replace(/@@/g, '\\@\\@');
+ sData = sData.replace(/~~/g, '\\~\\~');
+ sData = sData.replace(/%%/g, '\\%\\%');
+ sData = sData.replace(/\r?\n/g, '@@');
+ // Comma-separated values
+ if (/^### PROFILES ###,,,,/i.test(sData)) {
+ sData = sData.replace(/,(?=[^"]*"(?:[^"]*"[^"]*")*[^"]*$)/g, '~~');
+ sData = sData.replace(/@@([^"]+?,)/g, '\n$1');
+ sSplit = ',';
+ // Tab-separated values
+ } else if (/^### PROFILES ###\t\t\t\t/i.test(sData)) {
+ sData = sData.replace(/\t(?=[^"]*"(?:[^"]*"[^"]*")*[^"]*$)/g, '%%');
+ sData = sData.replace(/(\t|@@)("[^"(@@)]*")(\t|@@)/g, '$1"$2"$3');
+ sData = sData.replace(/@@([^"]+?\t)/g, '\n$1');
+ sSplit = '\t';
+ }
+ aRows = sData.split('\n');
+ imax = aRows.length;
+ // Validate CSV format
+ if (imax==0 || aRows[0].split(sSplit).length<5) {
+ oNB.appendNotification(sImportError, '', '', oNB.PRIORITY_WARNING_LOW);
+ return;
+ }
+ if (!bAppend) {
+ // Clear rules table
+ oR = {};
+ nR = 1;
+ // Clear profile list
+ aC = [];
+ nC = 1;
+ }
+ // Default to "All" profile so user can review all rules
+ nCI = 0;
+ n = setInterval(function() {
+ aCols = aRows[i].split(sSplit);
+ // Preprocess rules data
+ for (var j=0, jmax=aCols.length; jP.getCharPref(sV)) {
+ oAO.showPane(D.getElementById(sAP + 'support'));
+ P.setCharPref(sV, nVer)
+ // Switch to Form Fields if called from wizard
+ } else if (window.arguments) {
+ oAO.showPane(D.getElementById(sAP + 'fields'));
+ }
+ oRLB = D.getElementById('content-fields');
+ oC2 = D.getElementById('col2');
+ oC3 = D.getElementById('col3');
+ oC4 = D.getElementById('col4');
+ oC = D.getElementById('content-cats');
+ oCS = D.getElementById('content-cat-site');
+ oCO = D.getElementById('content-cat-overwrite');
+ oBCR = D.getElementById('button-rename');
+ oBCD = D.getElementById('button-delete');
+ oBRR = D.getElementById('button-remove');
+ oBRU = D.getElementById('button-up');
+ oBRD = D.getElementById('button-down');
+ oBRM = D.getElementById('button-move');
+ oBRS = D.getElementById('button-save');
+ oCCT = D.getElementById('content-ctrl-top');
+ oCCB = D.getElementById('content-ctrl-bottom');
+ oOO = {
+ delay: D.getElementById('content-delay'),
+ overwrite: D.getElementById('content-overwrite'),
+ vars: D.getElementById('content-vars'),
+ sound: D.getElementById('content-sound'),
+ mask: D.getElementById('content-mask'),
+ menu: D.getElementById('content-menu'),
+ confirm: D.getElementById('content-confirm')
+ };
+ oD = D.getElementById('content-delay-sec');
+ oDO = D.getElementById('content-delay-out');
+ // Convert old oF to new oR with shorter property names
+ migrateData();
+ // Populate profiles (categories)
+ popCats();
+ // Switch to current profile
+ // Default to Unfiled if nCI out of range
+ if (nCI>oC.itemCount-1) nCI = 1;
+ changeCat(nCI);
+ // Load exceptions
+ oTB = D.getElementById('content-exceptions');
+ oTB.value = P.getComplexValue(sE, SS).data;
+ // Load delay settings
+ oD.value = P.getCharPref(sX + 'delaysec')*10;
+ oDO.textContent = oD.value/10 + ' sec';
+ // Initiate these last
+ oNB = D.getElementById('status');
+ F = Ci.nsIFilePicker;
+ FP = Cc['@mozilla.org/filepicker;1'].createInstance(F);
+ FP.appendFilter('CSV Files', '*.csv');
+ FP.appendFilters(F.filterAll);
+ W = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator).getMostRecentWindow('navigator:browser');
+ // Enable/Disable buttons as needed
+ oRLB.addEventListener('select', handleSelect, false);
+ window.addEventListener('keydown', doKeyDown, false);
+ window.addEventListener('resize', alignHeaders, false);
+}
+
+// Migrate data structures starting with v2.5
+function migrateData() {
+ var sF = sX + 'fields',
+ str = Cc['@mozilla.org/supports-string;1'].createInstance(SS);
+ if (P.prefHasUserValue(sF)) {
+ var oF = JSON.parse(P.getComplexValue(sF, SS).data);
+ for (var i in oF) {
+ oR['r' + nR++] = {
+ t: oF[i].type,
+ n: oF[i].name,
+ v: oF[i].value,
+ s: oF[i].site,
+ c: ''
+ }
+ }
+ str.data = JSON.stringify(oR);
+ P.setComplexValue(sR, SS, str);
+ P.setIntPref(sRC, nR);
+ P.deleteBranch(sF);
+ }
+}
+
+// Move autofill rule to another profile
+function moveRule() {
+ var oParam = {
+ i: {
+ cats: aC
+ },
+ o: null
+ };
+ window.openDialog('chrome://autofill/content/moverule.xul', '', 'centerscreen, chrome, dialog, modal', oParam);
+ if (oParam.o && oRLB.selectedCount>0) {
+ for (var i=oRLB.itemCount, a=oRLB.childNodes, sBoxTooltip=oSB.getString('boxTooltip'), sN, oRow; i>0; i--) {
+ if (a[i].selected) {
+ sN = a[i].id.slice(2); // extract # from r_#
+ oRow = oR['r' + sN];
+ // Move selected item to target profile if it exists
+ if (oRow) oRow.c = oParam.o.cat;
+ // Else save newly created item before moving
+ else {
+ oRow = {
+ t: D.getElementById('t_'+ sN).selectedIndex,
+ n: D.getElementById('n_'+ sN).value,
+ v: D.getElementById('v_'+ sN).value,
+ s: D.getElementById('s_'+ sN).value,
+ c: oParam.o.cat
+ };
+ }
+ // Only update tooltip and 'cat' if in "All" profile; else remove selected item
+ if (sCN=='all') {
+ var oElm = a[i].firstChild;
+ while (oElm) {
+ if (oElm.nodeType==1) {
+ oElm.setAttribute('tooltiptext', 'Profile: ' + oParam.o.catlabel + '\n');
+ if (oElm.nodeName=='textbox') oElm.tooltipText += sBoxTooltip;
+ }
+ oElm = oElm.nextSibling;
+ }
+ // If 'cat' property is not updated, categorization won't be saved if in "All" profile
+ a[i].cat = oParam.o.cat;
+ } else oRLB.removeItemAt(i-1);
+ }
+ }
+ // Don't do these if in "All" profile
+ if (sCN!='all') {
+ alignHeaders();
+ oBRR.disabled = true;
+ oBRU.disabled = true;
+ oBRD.disabled = true;
+ oBRM.disabled = true;
+ }
+ oBRS.disabled = false;
+ bCC = true;
+ // Refresh item counts
+ popCats();
+ }
+}
+
+// Create new profile
+function newCat() {
+ var oParam = {
+ i: {
+ cats: aC,
+ catReserved: oSB.getString('catReserved'),
+ catExists: oSB.getString('catExists')
+ },
+ o: null
+ };
+ window.openDialog('chrome://autofill/content/catnew.xul', '', 'centerscreen, chrome, dialog, modal', oParam);
+ if (oParam.o && oParam.o.value) {
+ aC[aC.length] = {
+ k: 'c' + nC++,
+ n: oParam.o.value,
+ s: '',
+ o: +oOO['overwrite'].checked
+ };
+ aC.sort(sortByName);
+ popCats(sCN);
+ saveOptions('cats');
+ }
+}
+
+// Confirm window close on unsaved changes
+function onCancel() {
+ // Save profile site filter and overwrite option
+ saveOptions('cats');
+ if (bRC || bCC) {
+ var oParam = {
+ i: {
+ desc: (bRC && !bCC) ? 'changedRules' : (!bRC && bCC) ? 'changedCats' : 'changedBoth',
+ type: 'confirmClose'
+ },
+ o: null
+ };
+ window.openDialog('chrome://autofill/content/confirm.xul', '', 'centerscreen, chrome, dialog, modal', oParam);
+ if (oParam.o) return true;
+ else return false;
+ }
+}
+
+// Build profile list
+function popCats(sCat) {
+ var nCatCount = 0,
+ nTotalCount = Object.size(oR),
+ sAll = oC.getItemAtIndex(0).label,
+ sUnfiled = oC.getItemAtIndex(1).label;
+ for (var i=2, imax=Math.max(oC.itemCount-2, aC.length), j=0, o, n; i-20) o.label += ' (' + n + ')';
+ if (aC[j].k==sCat) oC.selectedIndex = (nCI=i);
+ } else if (o) oC.removeItemAt(i);
+ }
+ // Add item count for "All" and "Unfiled" profiles
+ if (nTotalCount>0) {
+ oC.getItemAtIndex(0).label = sAll.replace(/^([^(]+)\b.*$/, '$1 (' + nTotalCount + ')');
+ oC.getItemAtIndex(1).label = sUnfiled.replace(/^([^(]+)\b.*$/, ((nTotalCount>nCatCount) ? '$1 (' + (nTotalCount-nCatCount) + ')' : '$1'));
+ }
+}
+
+// Open document in a new tab
+function openWin(sURL) {
+ W.gBrowser.selectedTab = W.gBrowser.addTab(sURL);
+}
+
+// Refresh panel if profiles/rules have been modified by wizard
+function refresh() {
+ if (JSON.stringify(aC).length!=P.getComplexValue(sC, SS).data.length
+ || JSON.stringify(oR).length!=P.getComplexValue(sR, SS).data.length) loadOptions();
+}
+
+// Remove all rules
+function removeAllRows() {
+ if (oRLB.itemCount>0) {
+ // Unselect everything first to disable buttons
+ oRLB.clearSelection();
+ // Remove all items
+ while (oRLB.itemCount) {
+ oRLB.removeItemAt(0);
+ }
+ }
+}
+
+// Remove selected rule(s)
+function removeRow() {
+ if (oRLB.selectedCount>0) {
+ // Remove selected items (exclude header row)
+ for (var i=oRLB.itemCount, a=oRLB.childNodes; i>0; i--) {
+ if (a[i].selected) {
+ // Rules have changed if saved item deleted
+ if (oR['r' + a[i].id.slice(2)]) bRC = true; // extract # from r_#
+ oRLB.removeItemAt(i-1);
+ }
+ }
+ alignHeaders();
+ oBRR.disabled = true;
+ oBRU.disabled = true;
+ oBRD.disabled = true;
+ oBRS.disabled = false;
+ }
+}
+
+// Rename profile
+function renameCat() {
+ var oParam = {
+ i: {
+ text: oC.getItemAtIndex(nCI).label.replace(/ \(\d+\)/, ''),
+ cats: aC,
+ catnow: nCI,
+ catReserved: oSB.getString('catReserved'),
+ catExists: oSB.getString('catExists')
+ },
+ o: null
+ };
+ window.openDialog('chrome://autofill/content/catrename.xul', '', 'centerscreen, chrome, dialog, modal', oParam);
+ if (oParam.o) {
+ aC = oParam.o.cats;
+ aC.sort(sortByName);
+ popCats(sCN);
+ saveOptions('cats');
+ }
+}
+
+// Reorder rule down
+function rowDown() {
+ if (oRLB.selectedCount>0) {
+ for (var i=oRLB.itemCount, a=oRLB.childNodes, oElm, oData; i>0; i--) {
+ if (a[i].selected) {
+ if (i+1==oRLB.itemCount) oBRD.disabled = true;
+ else if (i0) {
+ for (var i=1, imax=oRLB.itemCount+1, a=oRLB.childNodes, oElm, oData; i1) oBRD.disabled = false;
+ else return;
+ // Rules have changed if saved item moved
+ if (oR['r' + a[i].id.slice(2)]) bRC = true; // extract # from r_#
+ // Retain data or it will be lost after reordering
+ oData = {};
+ oElm = a[i].firstChild;
+ while (oElm) {
+ if (oElm.nodeName=='textbox') {
+ oData[oElm.id] = oElm.value;
+ }
+ oElm = oElm.nextSibling;
+ }
+ oRLB.insertBefore(a[i], a[i-1]);
+ // Restore data after reordering
+ for (var j in oData) {
+ D.getElementById(j).value = oData[j];
+ }
+ oRLB.ensureElementIsVisible(a[i-1]);
+ }
+ }
+ oBRS.disabled = false;
+ }
+}
+
+// Save options to prefs.js
+function saveOptions(sPref, nFlag) {
+ var aRLI = D.getElementsByTagName('richlistitem'),
+ oName,
+ oSite,
+ sN,
+ sName,
+ sValue,
+ sSite,
+ str = Cc['@mozilla.org/supports-string;1'].createInstance(SS);
+ // Save changes to profile list and current profile index
+ if (sPref=='cats' || !sPref) {
+ // Save profile site filter and overwrite option
+ if (nCI>1) {
+ aC[nCI-2].s = oCS.value.replace(/^\s+|\s+$/g, '');
+ aC[nCI-2].o = +oCO.checked;
+ }
+ str.data = JSON.stringify(aC);
+ P.setComplexValue(sC, SS, str);
+ P.setIntPref(sCC, nC);
+ P.setIntPref(sCI, nCI);
+ }
+ // Save autofill rules
+ if (sPref=='rules' || !sPref) {
+ // Clear rules in current profile
+ for (var i in oR) {
+ if (sCN=='all' || sCN==oR[i].c) delete oR[i];
+ }
+ // Save table data to oR object
+ for (var i=0, imax=aRLI.length; i-1; i--) {
+ sN = aRLI[i].id.slice(2); // extract # from r_#
+ if (!D.getElementById('n_' + sN).value
+ && !D.getElementById('v_' + sN).value
+ && !D.getElementById('s_' + sN).value) oRLB.removeItemAt(i);
+ }
+ alignHeaders();
+ oBRS.disabled = true;
+ // Refresh item counts
+ popCats();
+ str.data = JSON.stringify(oR);
+ P.setComplexValue(sR, SS, str);
+ P.setIntPref(sRC, nR);
+ // Also save profiles in case of importing
+ saveOptions('cats');
+ // Reset change flags
+ bRC = false;
+ bCC = false;
+ }
+ // Save exceptions
+ if (sPref=='exceptions' || !sPref) {
+ oTB.value = cleanText(oTB.value);
+ str.data = oTB.value;
+ if (P.getComplexValue(sE, SS).data!=oTB.value) P.setComplexValue(sE, SS, str);
+ }
+ // Save other settings
+ if (sPref=='other' || !sPref) {
+ for (var i in oOO) {
+ if (P.getBoolPref(sX + i)!=oOO[i].checked) P.setBoolPref(sX + i, oOO[i].checked);
+ }
+ }
+ // Toggle autofill delay
+ // nFlag : 0 = checkbox, 1 = scale
+ if (sPref=='delay') {
+ var n;
+ switch (nFlag) {
+ case 0:
+ oD.value = +oOO[sPref].checked*10;
+ n = oD.value/10;
+ oDO.textContent = n + ' sec';
+ P.setCharPref(sX + sPref + 'sec', n);
+ break;
+ case 1:
+ n = oD.value/10;
+ oOO[sPref].checked = (n>0);
+ oDO.textContent = n + ' sec';
+ P.setBoolPref(sX + sPref, oOO[sPref].checked);
+ return n;
+ }
+ }
+ // Toggle password masking
+ if (sPref=='mask') {
+ var nLR = oRLB.lastChild.id.slice(2); // extract # from r_#
+ if (D.getElementById('n_' + nLR).value || D.getElementById('v_' + nLR).value) saveOptions('rules');
+ buildRules(oC.value);
+ }
+}
+
+// Show Edit Box
+function showEditBox(oCell, e) {
+ if (e) {
+ switch (e.type) {
+ case 'click': /* require a triple-click */
+ if (e.detail<3) return;
+ break;
+ case 'keydown': /* or Alt|Ctrl+Enter */
+ if (!(((!bMac)?e.altKey:e.ctrlKey) && e.keyCode==13)) return;
+ break;
+ }
+ }
+ var oParam = {
+ i: {
+ id: oCell.id,
+ value: oCell.value.replace(/(\*\/)\s*/, '$1\n')
+ },
+ o: null
+ };
+ // Preprocess Value to Autofill column
+ if (oCell.id.indexOf('v_')>-1) {
+ // Replace \n with newlines
+ while (/([^\\])\\n/.test(oParam.i.value)) {
+ oParam.i.value = oParam.i.value.replace(/([^\\])\\n/g, '$1\n');
+ }
+ // Replace \\n with literal \n
+ oParam.i.value = oParam.i.value.replace(/\\\\n/g, '\\n');
+ }
+ // Replace pipes with newlines in Site Filter
+ if (oCell.id.indexOf('s_')>-1) oParam.i.value = oParam.i.value.replace(/\|/g, '\n');
+ window.openDialog('chrome://autofill/content/editbox.xul', '', 'centerscreen, chrome, dialog=no, modal, resizable', oParam);
+ if (oParam.o) {
+ oCell.value = oParam.o.value;
+ if (oR['r' + oCell.id.slice(2)][oCell.id.slice(0, 1)]!=oCell.value) oBRS.disabled = false; // extract # from x_# and x from x_#
+ }
+}
+
+// Sort names alphabetically
+function sortByName(a, b) {
+ var s1 = a.n.toLowerCase(),
+ s2 = b.n.toLowerCase();
+ return ((s1s2) ? 1 : 0));
+}
+
+// Validate Form Fields row data
+function validRow(o) {
+ var sN = o.id.slice(2), /* extract # from x_# */
+ oRow = oR['r' + sN];
+ switch (o.nodeName) {
+ case 'menulist':
+ // Change Value column to password input box if Type = Password
+ if (oOO['mask'].checked) {
+ D.getElementById('v_' + sN).setAttribute('type', (o.selectedIndex==1) ? 'password' : null);
+ }
+ // Add read-only state and set value to "*click*" if changing to Type = Button
+ if (o.selectedIndex==5) {
+ D.getElementById('v_' + sN).value = '*click*';
+ D.getElementById('v_' + sN).setAttribute('disabled', 'disabled');
+ // Remove read-only state and empty Value if changing from Type = Button
+ } else {
+ D.getElementById('v_' + sN).value = oRow.v;
+ D.getElementById('v_' + sN).removeAttribute('disabled');
+ }
+ // Put focus on Name column if newly added rule
+ if (!oRow) D.getElementById('n_' + sN).focus();
+ // Enable Save button only if new item selected
+ if (oRow && o.selectedIndex!=oRow.t) oBRS.disabled = false;
+ break;
+ case 'textbox':
+ // Enable Move and Save buttons only if data has changed
+ if ((oRow && o.value!=oRow[o.id.slice(0, 1)]) || (o.value && !oRow)) { // extract x from x_#
+ oBRM.disabled = false;
+ oBRS.disabled = false;
+ bRC = true;
+ } else if (!D.getElementById('n_' + sN).value
+ && !D.getElementById('v_' + sN).value
+ && !D.getElementById('s_' + sN).value) oBRM.disabled = true;
+ break;
+ }
+}
+
+window.addEventListener('load', loadOptions, false);
diff --git a/Autofill/chrome/content/options.xul b/Autofill/chrome/content/options.xul
new file mode 100644
index 0000000..ddd78c0
--- /dev/null
+++ b/Autofill/chrome/content/options.xul
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &exceptions.desc.1; Regular Expressions&exceptions.desc.2;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &other.import.desc;
+
+ &other.importmode.desc;:
+
+
+
+
+
+
+
+
+ &other.export.desc;
+
+
+
+
+
+
+
+
+
+ &support.desc.1; Autofill support group&support.desc.2; firefox-autofill@googlegroups.com &support.desc.3; Practice Form.
+
+
+ Added ability to autofill contentEditable divs
+ Added ability to import individual profiles (Append)
+ Added option to set autofill delay
+ Added option to enable "overwrite" by default
+ Added option to disable fuzzy text label matching
+ Improved support for rich text editors
+ Improved rich text autofill to retain formatting
+ Updated layout in Other Stuff panel
+ Fixed bug: line breaks stripped in Value to Autofill
+ Fixed bug: false positive text label match
+ Fixed bug: duplicate Options window can be opened
+ Fixed bug: symbols in Exceptions returning errors
+
+ &support.desc.4; Version History &support.desc.5;
+ &support.desc.6;
+
+ Autofill hotkey to manually trigger autofill operation
+ Variables panel to define custom variables
+ Text clips functionality similar to InformEnter add-on
+ GUI options (toolbar icon, statusbar icon, Tools menu, context menu)
+ AES data encryption for improved security
+
+
+
+
+
+
+
+
+
diff --git a/Autofill/chrome/content/sound.wav b/Autofill/chrome/content/sound.wav
new file mode 100644
index 0000000..8375261
Binary files /dev/null and b/Autofill/chrome/content/sound.wav differ
diff --git a/Autofill/chrome/content/wizard.js b/Autofill/chrome/content/wizard.js
new file mode 100644
index 0000000..0c323e8
--- /dev/null
+++ b/Autofill/chrome/content/wizard.js
@@ -0,0 +1,454 @@
+/*
+ * @package Autofill
+ * @author Tom Doan
+ * @copyright (c) Tom Doan
+ * @license GNU General Public License
+ * @link http://www.tohodo.com/
+ */
+
+var D = document,
+ L = opener.content.location,
+ Cc = Components.classes,
+ Ci = Components.interfaces,
+ P = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefBranch),
+ SS = Ci.nsISupportsString,
+ sX = 'extensions.autofill.',
+ sR = sX + 'rules',
+ sRC = sX + 'rulecount',
+ sC = sX + 'cats',
+ sCC = sX + 'catcount',
+ sCI = sX + 'catnow',
+ oSB, /* string bundle */
+ oNB, /* notification box */
+ oC, /* profiles menu */
+ oCN, /* new profile name */
+ oCB, /* checkbox option */
+ oI = window.arguments[0].i,
+ bF = oI.isField;
+
+// Initiate step 1
+function init1() {
+ oSB = D.getElementById('string-bundle');
+ D.getElementById('content-desc').textContent = (!bF) ? oSB.getString('wizDescForm') : oSB.getString('wizDescField');
+ // Highlight selected field
+ selField(1);
+}
+
+// Initiate step 2
+function init2() {
+ var aC = (P.prefHasUserValue(sC)) ? JSON.parse(P.getComplexValue(sC, SS).data) : [],
+ nCI = P.getIntPref(sCI),
+ aSel = [{k:'', n:'Unfiled'}],
+ nSelIndex = (nCI>1) ? nCI-1 : 0;
+ oNB = D.getElementById('status');
+ oC = D.getElementById('content-cats');
+ oCN = D.getElementById('content-catnew');
+ oCB = D.getElementById('content-wizopen');
+ // Populate profiles (categories)
+ aSel = aSel.concat(aC);
+ aSel[aSel.length] = {k:'new', n:'New...'};
+ if (oC.itemCount>0) oC.removeAllItems();
+ for (var i=0, imax=aSel.length; i-1) {
+ aRules[aRules.length] = {
+ t: 3,
+ n: aRadio[i].n,
+ v: aRadio[i].v
+ }
+ }
+ }
+ // Create rules for textareas
+ for (var i=0, imax=aT.length; i0) {
+ var str = Cc['@mozilla.org/supports-string;1'].createInstance(SS);
+ // If new site, move profile site filter to rule level
+ if (sCatSite) {
+ for (var i in oR) {
+ if (oR[i].c==sCat) oR[i].s = sCatSite;
+ }
+ }
+ for (var i=0, imax=aRules.length; is2) ? 1 : 0));
+}
diff --git a/Autofill/chrome/content/wizard.xul b/Autofill/chrome/content/wizard.xul
new file mode 100644
index 0000000..337e6f5
--- /dev/null
+++ b/Autofill/chrome/content/wizard.xul
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+ &wizard.step2.desc.1;
+
+
+
+
+
+
+
+
+ &wizard.step2.desc.2;
+
+
+
+
+
+
+
+
diff --git a/Autofill/chrome/locale/en-US/translations.dtd b/Autofill/chrome/locale/en-US/translations.dtd
new file mode 100644
index 0000000..510359a
--- /dev/null
+++ b/Autofill/chrome/locale/en-US/translations.dtd
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Autofill/chrome/locale/en-US/translations.properties b/Autofill/chrome/locale/en-US/translations.properties
new file mode 100644
index 0000000..f057e0f
--- /dev/null
+++ b/Autofill/chrome/locale/en-US/translations.properties
@@ -0,0 +1,16 @@
+boxTooltip=Triple-click to open Edit Box
+importError=Import failed. Click Help for correct CSV format.
+importOK=Settings imported. Click Save in Form Fields to commit changes.
+importDialog=Import Settings
+exportDialog=Export Settings
+whatsNew=What's new in Version
+changedRules=You have unsaved autofill rule changes.
+changedCats=You have unsaved autofill rule transfers.
+changedBoth=You have unsaved changes.
+confirmChange=Discard Changes and Switch Profile
+confirmClose=Discard Changes and Close Window
+wizDescForm=This wizard will create autofill rules for you. First, fill out all the fields in the form that you would like to add rules for.
+wizDescField=This wizard will create an autofill rule for the form field you selected. First, fill out the field (highlighted in blue).
+catReserved=is a reserved name.
+catExists=profile already exists.
+catEmpty=Enter a new profile name.
diff --git a/Autofill/chrome/locale/vi-VN/translations.dtd b/Autofill/chrome/locale/vi-VN/translations.dtd
new file mode 100644
index 0000000..ef4f13e
--- /dev/null
+++ b/Autofill/chrome/locale/vi-VN/translations.dtd
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Autofill/chrome/locale/vi-VN/translations.properties b/Autofill/chrome/locale/vi-VN/translations.properties
new file mode 100644
index 0000000..3894bcd
--- /dev/null
+++ b/Autofill/chrome/locale/vi-VN/translations.properties
@@ -0,0 +1,16 @@
+boxTooltip=Ba-click vào để mở Hộp Biên tập
+importError=Nhập khẩu không thành công. Nhấp vào Help để xem dạng mẫu CSV chính xác.
+importOK=Thiết lập đã được nhập khẩu. Nhấp vào Lưu trong Trường Form để lưu thay đổi.
+importDialog=Nhập khẩu Thiết lập
+exportDialog=Xuất khẩu Thiết lập
+whatsNew=Có gì mới trong Phiên bản
+changedRules=Bạn chưa lưu thay đổi quy tắc tự động điền.
+changedCats=Bạn chưa lưu di chuyển quy tắc tự động điền.
+changedBoth=Bạn chưa lưu thay đổi.
+confirmChange=Hủy bỏ Thay đổi và Chuyển Profile
+confirmClose=Hủy bỏ Thay đổi và Đóng Cửa sổ
+wizDescForm=Cái "thuật sĩ" này sẽ tạo ra quy tắc tự động điền cho bạn. Trước tiên, hãy điền vào tất cả các trường form mà bạn muốn tạo quy tắc cho.
+wizDescField=Cái "thuật sĩ" này sẽ tạo ra một quy tắc tự động điền cho phần tử mà bạn vừa chọn. Trước tiên, hãy điền cái gì vào phần tử này (màu nền xanh).
+catReserved=là một tên dành riêng.
+catExists=đã được tạo ra rồi.
+catEmpty=Nhập tên profile mới.
diff --git a/Autofill/chrome/skin-linux/ff-overlay.css b/Autofill/chrome/skin-linux/ff-overlay.css
new file mode 100644
index 0000000..ddedfc6
--- /dev/null
+++ b/Autofill/chrome/skin-linux/ff-overlay.css
@@ -0,0 +1 @@
+#autofill-menu{list-style-image:url(icon_16x16.png)}
\ No newline at end of file
diff --git a/Autofill/chrome/skin-linux/icon_16x16.png b/Autofill/chrome/skin-linux/icon_16x16.png
new file mode 100644
index 0000000..72be2c8
Binary files /dev/null and b/Autofill/chrome/skin-linux/icon_16x16.png differ
diff --git a/Autofill/chrome/skin-linux/icon_48x48.png b/Autofill/chrome/skin-linux/icon_48x48.png
new file mode 100644
index 0000000..d73a419
Binary files /dev/null and b/Autofill/chrome/skin-linux/icon_48x48.png differ
diff --git a/Autofill/chrome/skin-linux/icon_64x64.png b/Autofill/chrome/skin-linux/icon_64x64.png
new file mode 100644
index 0000000..2ba1db2
Binary files /dev/null and b/Autofill/chrome/skin-linux/icon_64x64.png differ
diff --git a/Autofill/chrome/skin-linux/options.css b/Autofill/chrome/skin-linux/options.css
new file mode 100644
index 0000000..00a8fe9
--- /dev/null
+++ b/Autofill/chrome/skin-linux/options.css
@@ -0,0 +1,76 @@
+@import url("chrome://global/skin/");
+
+/* Global */
+a {
+ color: #000080;
+ cursor: pointer;
+ text-decoration: underline;
+}
+vbox > label {
+ margin-top: 8px;
+}
+vbox > label + label {
+ margin-top: 12px;
+ margin-right: 2px;
+}
+description,
+menulist {
+ font-size: 90%;
+}
+menuitem {
+ font-size: 90%;
+ padding: 0 2px;
+}
+listheader,
+notificationbox {
+ font-size: 85%;
+}
+textbox {
+ font-size: 85%;
+ padding: 2px;
+}
+
+/* Options window */
+#autofill-options {
+ width: 724px;
+ height: 559px;
+}
+
+/* Panel bar */
+#autofill-options radio[pane] {
+ list-style-image: url("options.png");
+ padding: 5px 0 1px 0;
+}
+#autofill-options radio[pane="autofill-panel-fields"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+#autofill-options radio[pane="autofill-panel-exceptions"] {
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
+#autofill-options radio[pane="autofill-panel-other"] {
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+#autofill-options radio[pane="autofill-panel-support"] {
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
+
+/* Form Fields panel */
+#content-editbox {
+ font: normal 100% Courier New, monospace;
+}
+
+/* Other Stuff panel */
+#autofill-panel-other {
+ padding-top: 0;
+}
+#autofill-panel-other notificationbox + groupbox {
+ margin-top: 13px;
+}
+#content-delay-out {
+ margin-top: 3px;
+}
+
+/* Dialogs */
+dialog notificationbox {
+ margin: -7px -10px 7px -10px;
+}
diff --git a/Autofill/chrome/skin-linux/options.png b/Autofill/chrome/skin-linux/options.png
new file mode 100644
index 0000000..4524b8c
Binary files /dev/null and b/Autofill/chrome/skin-linux/options.png differ
diff --git a/Autofill/chrome/skin-linux/wizard.css b/Autofill/chrome/skin-linux/wizard.css
new file mode 100644
index 0000000..0889a5f
--- /dev/null
+++ b/Autofill/chrome/skin-linux/wizard.css
@@ -0,0 +1 @@
+@import url(chrome://global/skin/);description,menulist{font-size:90%}menuitem{font-size:90%;padding:0 2px}notificationbox{font-size:85%}textbox{font-size:85%;padding:2px}#autofill-wizard{width:430px;height:300px}#autofill-wizard-step2{margin:-10px -44px}#autofill-wizard-step2>notificationbox+description{margin:11px 50px 10px}#autofill-wizard-step2>description,#autofill-wizard-step2>menulist,#autofill-wizard-step2>textbox{margin-left:50px;margin-right:50px}#autofill-wizard-step2>checkbox{margin:8px 46px}
\ No newline at end of file
diff --git a/Autofill/chrome/skin/ff-overlay.css b/Autofill/chrome/skin/ff-overlay.css
new file mode 100644
index 0000000..ddedfc6
--- /dev/null
+++ b/Autofill/chrome/skin/ff-overlay.css
@@ -0,0 +1 @@
+#autofill-menu{list-style-image:url(icon_16x16.png)}
\ No newline at end of file
diff --git a/Autofill/chrome/skin/icon_16x16.png b/Autofill/chrome/skin/icon_16x16.png
new file mode 100644
index 0000000..72be2c8
Binary files /dev/null and b/Autofill/chrome/skin/icon_16x16.png differ
diff --git a/Autofill/chrome/skin/icon_48x48.png b/Autofill/chrome/skin/icon_48x48.png
new file mode 100644
index 0000000..d73a419
Binary files /dev/null and b/Autofill/chrome/skin/icon_48x48.png differ
diff --git a/Autofill/chrome/skin/icon_64x64.png b/Autofill/chrome/skin/icon_64x64.png
new file mode 100644
index 0000000..2ba1db2
Binary files /dev/null and b/Autofill/chrome/skin/icon_64x64.png differ
diff --git a/Autofill/chrome/skin/options.css b/Autofill/chrome/skin/options.css
new file mode 100644
index 0000000..d158aa3
--- /dev/null
+++ b/Autofill/chrome/skin/options.css
@@ -0,0 +1,70 @@
+@import url("chrome://global/skin/");
+
+/* Global */
+a {
+ color: #000080;
+ cursor: pointer;
+ text-decoration: underline;
+}
+vbox > label {
+ margin-top: 6px;
+}
+vbox > label + label {
+ margin-top: 10px;
+ margin-right: 2px;
+}
+menuitem {
+ padding: 0 2px;
+}
+textbox {
+ padding: 2px;
+}
+
+/* Options window */
+#autofill-options {
+ width: 646px;
+ height: 464px;
+}
+
+/* Panel bar */
+#autofill-options radio[pane] {
+ list-style-image: url("options.png");
+ padding: 5px 0 1px 0;
+}
+#autofill-options radio[pane="autofill-panel-fields"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+#autofill-options radio[pane="autofill-panel-exceptions"] {
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
+#autofill-options radio[pane="autofill-panel-other"] {
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+#autofill-options radio[pane="autofill-panel-support"] {
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
+
+/* Form Fields panel */
+#content-editbox {
+ font: normal 120% Courier New, monospace;
+}
+
+/* Other Stuff panel */
+#autofill-panel-other {
+ padding: 0 0 10px 0;
+}
+#autofill-panel-other groupbox {
+ margin-left: 11px;
+ margin-right: 13px;
+}
+#autofill-panel-other notificationbox + groupbox {
+ margin-top: 11px;
+}
+#content-delay-out {
+ margin-top: 3px;
+}
+
+/* Dialogs */
+dialog notificationbox {
+ margin: -7px -10px 7px -10px;
+}
diff --git a/Autofill/chrome/skin/options.png b/Autofill/chrome/skin/options.png
new file mode 100644
index 0000000..4524b8c
Binary files /dev/null and b/Autofill/chrome/skin/options.png differ
diff --git a/Autofill/chrome/skin/wizard.css b/Autofill/chrome/skin/wizard.css
new file mode 100644
index 0000000..6e2e0b7
--- /dev/null
+++ b/Autofill/chrome/skin/wizard.css
@@ -0,0 +1 @@
+@import url(chrome://global/skin/);#autofill-wizard{width:390px;height:290px}#autofill-wizard-step2{margin:-10px -44px}#autofill-wizard-step2>notificationbox+description{margin:11px 50px 10px}#autofill-wizard-step2>description,#autofill-wizard-step2>menulist,#autofill-wizard-step2>textbox{margin-left:50px;margin-right:50px}#autofill-wizard-step2>checkbox{margin:8px 46px}
\ No newline at end of file
diff --git a/Autofill/defaults/preferences/prefs.js b/Autofill/defaults/preferences/prefs.js
new file mode 100644
index 0000000..d7d401d
--- /dev/null
+++ b/Autofill/defaults/preferences/prefs.js
@@ -0,0 +1,15 @@
+pref("extensions.autofill.ver", "1");
+pref("extensions.autofill.rulecount", 1);
+pref("extensions.autofill.catcount", 2);
+pref("extensions.autofill.catnow", 0);
+pref("extensions.autofill.exceptions", "");
+pref("extensions.autofill.delay", true);
+pref("extensions.autofill.delaysec", "1");
+pref("extensions.autofill.labelmatch", true);
+pref("extensions.autofill.overwrite", false);
+pref("extensions.autofill.vars", true);
+pref("extensions.autofill.sound", false);
+pref("extensions.autofill.mask", true);
+pref("extensions.autofill.menu", true);
+pref("extensions.autofill.confirm", true);
+pref("extensions.autofill.wizopen", false);
diff --git a/Autofill/install.rdf b/Autofill/install.rdf
new file mode 100644
index 0000000..ab9d388
--- /dev/null
+++ b/Autofill/install.rdf
@@ -0,0 +1,30 @@
+
+
+
+ firefox-autofill@googlegroups.com
+ 2
+ Autofill
+ 3.6
+ Tom Doan
+ Fill form fields automatically on page load.
+ chrome://autofill/skin/icon_48x48.png
+ chrome://autofill/skin/icon_64x64.png
+ chrome://autofill/content/options.xul
+ http://www.tohodo.com/
+
+
+ vi-VN
+ Autofill
+ Tự động điền mẫu biểu (form) khi trang web được tải.
+
+
+
+
+ {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+ 3.5
+ 20.*
+
+
+
+