[Pkg-mozext-commits] [autofill-forms] 01/13: moving autofill to GitHub
David Prévot
taffit at moszumanska.debian.org
Thu Oct 29 20:57:36 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository autofill-forms.
commit 191ec882808b47dfdd19a513dbbb8fa35697584a
Author: Sarah Avilov <sarah.avilov at gmail.com>
Date: Sun Jun 21 11:50:39 2015 +0430
moving autofill to GitHub
---
aff.xpi | Bin 0 -> 152327 bytes
chrome.manifest | 29 +
chrome/content/autofillForms.js | 5452 ++++++++++++++++++++++++++
chrome/content/autofillFormsOptions.js | 10 +
chrome/content/autofillFormsOptions.xul | 620 +++
chrome/content/autofillFormsOverlay.js | 10 +
chrome/content/autofillFormsOverlay.xul | 183 +
chrome/content/autofillFormsRuleEditor.js | 11 +
chrome/content/autofillFormsRuleEditor.xul | 41 +
chrome/content/autofillFormsTagEditor.js | 11 +
chrome/content/autofillFormsTagEditor.xul | 51 +
chrome/content/inject.js | 24 +
chrome/locale/cs-CZ/autofillForms.dtd | 102 +
chrome/locale/cs-CZ/autofillForms.properties | 88 +
chrome/locale/de-DE/autofillForms.dtd | 102 +
chrome/locale/de-DE/autofillForms.properties | 88 +
chrome/locale/el-GR/autofillForms.dtd | 102 +
chrome/locale/el-GR/autofillForms.properties | 88 +
chrome/locale/en-US/autofillForms.dtd | 102 +
chrome/locale/en-US/autofillForms.properties | 88 +
chrome/locale/es-ES/autofillForms.dtd | 102 +
chrome/locale/es-ES/autofillForms.properties | 88 +
chrome/locale/fi-FI/autofillForms.dtd | 102 +
chrome/locale/fi-FI/autofillForms.properties | 88 +
chrome/locale/fr-FR/autofillForms.dtd | 102 +
chrome/locale/fr-FR/autofillForms.properties | 88 +
chrome/locale/he-IL/autofillForms.dtd | 102 +
chrome/locale/he-IL/autofillForms.properties | 88 +
chrome/locale/hr-HR/autofillForms.dtd | 102 +
chrome/locale/hr-HR/autofillForms.properties | 88 +
chrome/locale/hu-HU/autofillForms.dtd | 102 +
chrome/locale/hu-HU/autofillForms.properties | 88 +
chrome/locale/it-IT/autofillForms.dtd | 102 +
chrome/locale/it-IT/autofillForms.properties | 88 +
chrome/locale/nl-NL/autofillForms.dtd | 102 +
chrome/locale/nl-NL/autofillForms.properties | 88 +
chrome/locale/pl-PL/autofillForms.dtd | 102 +
chrome/locale/pl-PL/autofillForms.properties | 88 +
chrome/locale/pt-BR/autofillForms.dtd | 102 +
chrome/locale/pt-BR/autofillForms.properties | 88 +
chrome/locale/ro-RO/autofillForms.dtd | 102 +
chrome/locale/ro-RO/autofillForms.properties | 88 +
chrome/locale/ru-RU/autofillForms.dtd | 102 +
chrome/locale/ru-RU/autofillForms.properties | 88 +
chrome/locale/sk-SK/autofillForms.dtd | 102 +
chrome/locale/sk-SK/autofillForms.properties | 88 +
chrome/locale/sv-SE/autofillForms.dtd | 102 +
chrome/locale/sv-SE/autofillForms.properties | 88 +
chrome/locale/tr-TR/autofillForms.dtd | 102 +
chrome/locale/tr-TR/autofillForms.properties | 88 +
chrome/locale/zh-CN/autofillForms.dtd | 102 +
chrome/locale/zh-CN/autofillForms.properties | 88 +
chrome/locale/zh-TW/autofillForms.dtd | 102 +
chrome/locale/zh-TW/autofillForms.properties | 88 +
chrome/skin/arrows.png | Bin 0 -> 1283 bytes
chrome/skin/autofillForms.css | 59 +
chrome/skin/autofillFormsMac.css | 13 +
chrome/skin/autofillFormsOptions.css | 84 +
chrome/skin/autofillFormsOptions1.5.css | 10 +
chrome/skin/autofillFormsOptions2.css | 4 +
chrome/skin/autofillFormsRuleEditor.css | 1 +
chrome/skin/autofillFormsTagEditor.css | 1 +
chrome/skin/help-small.png | Bin 0 -> 848 bytes
chrome/skin/icon.png | Bin 0 -> 1325 bytes
chrome/skin/pencil-active-mac.png | Bin 0 -> 2032 bytes
chrome/skin/pencil-big.png | Bin 0 -> 1325 bytes
chrome/skin/pencil-mac.png | Bin 0 -> 1625 bytes
chrome/skin/pencil-small.png | Bin 0 -> 619 bytes
chrome/skin/pencil.png | Bin 0 -> 923 bytes
chrome/skin/profile-small.png | Bin 0 -> 795 bytes
chrome/skin/settings-small.png | Bin 0 -> 826 bytes
defaults/preferences/autofillForms.js | 55 +
install.rdf | 52 +
install.sh | 2 +
74 files changed, 10713 insertions(+)
diff --git a/aff.xpi b/aff.xpi
new file mode 100644
index 0000000..f198e4b
Binary files /dev/null and b/aff.xpi differ
diff --git a/chrome.manifest b/chrome.manifest
new file mode 100644
index 0000000..82f2961
--- /dev/null
+++ b/chrome.manifest
@@ -0,0 +1,29 @@
+content autofillforms chrome/content/
+locale autofillforms cs-CZ chrome/locale/cs-CZ/
+locale autofillforms de-DE chrome/locale/de-DE/
+locale autofillforms el-GR chrome/locale/el-GR/
+locale autofillforms en-US chrome/locale/en-US/
+locale autofillforms es-ES chrome/locale/es-ES/
+locale autofillforms fr-FR chrome/locale/fr-FR/
+locale autofillforms fi-FI chrome/locale/fi-FI/
+locale autofillforms he-IL chrome/locale/he-IL/
+locale autofillforms hr-HR chrome/locale/hr-HR/
+locale autofillforms hu-HU chrome/locale/hu-HU/
+locale autofillforms it-IT chrome/locale/it-IT/
+locale autofillforms nl-NL chrome/locale/nl-NL/
+locale autofillforms pl-PL chrome/locale/pl-PL/
+locale autofillforms pt-BR chrome/locale/pt-BR/
+locale autofillforms ro-RO chrome/locale/ro-RO/
+locale autofillforms ru-RU chrome/locale/ru-RU/
+locale autofillforms sk-SK chrome/locale/sk-SK/
+locale autofillforms sv-SE chrome/locale/sv-SE/
+locale autofillforms tr-TR chrome/locale/tr-TR/
+locale autofillforms zh-CN chrome/locale/zh-CN/
+locale autofillforms zh-TW chrome/locale/zh-TW/
+skin autofillforms classic/1.0 chrome/skin/
+overlay chrome://browser/content/browser.xul chrome://autofillforms/content/autofillFormsOverlay.xul
+style chrome://global/content/customizeToolbar.xul chrome://autofillforms/skin/autofillForms.css
+style chrome://autofillforms/content/autofillFormsOptions.xul chrome://autofillforms/skin/autofillFormsOptions2.css appversion<3.0
+style chrome://autofillforms/content/autofillFormsOptions.xul chrome://autofillforms/skin/autofillFormsOptions1.5.css appversion<2.0
+style chrome://browser/content/browser.xul chrome://autofillforms/skin/autofillFormsMac.css appversion>=3.0 os=Darwin
+style chrome://global/content/customizeToolbar.xul chrome://autofillforms/skin/autofillFormsMac.css appversion>=3.0 os=Darwin
diff --git a/chrome/content/autofillForms.js b/chrome/content/autofillForms.js
new file mode 100644
index 0000000..a2fec47
--- /dev/null
+++ b/chrome/content/autofillForms.js
@@ -0,0 +1,5452 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+var autofillForms = {
+
+ // The selected profile index:
+ profileIndex: null,
+ // The selected global profile index:
+ globalProfileIndex: null,
+ // The selected form fields context menu profile index
+ formFieldsContextMenuProfileIndex: null,
+ // The list of profile labels:
+ profileLabels: null,
+ // The list of profile site rules:
+ profileSiteRules: null,
+ // The list of form field rules:
+ fieldRules: null,
+ // The tree representing the field rules list:
+ tree: null,
+ // The tree view:
+ treeView: null,
+ // The tree view frontend:
+ treeBox: null,
+ // Holds the selection object for the treeview:
+ selection: null,
+ // Remembers the last selected index of the treeview:
+ lastSelectedIndex: null,
+ // Determines if sort is to be ascending or descending:
+ ascending: null,
+ // The profiles listBox:
+ profilesTree: null,
+ // The profiles tree view:
+ profilesTreeView: null,
+ // The profiles tree view frontend:
+ profilesTreeBox: null,
+ // Holds the selection object for the profiles treeview:
+ profilesSelection: null,
+ // The profiles sort order:
+ profilesAscending: null,
+ // Autofill forms preferences branch:
+ autofillFormsPrefs: null,
+ // Object containing the shortcuts information (modifiers, key or keycode):
+ shortcut: null,
+ // Object containing the mouse button shortcuts information:
+ mouseButton: null,
+ // Helper var to do the opposite of the current setting:
+ invertedSetting: null,
+ // Array containing the rule element types ("begins with", "contains", ...):
+ ruleElementTypes: null,
+ // Containes the reference to the current rule field:
+ currentRuleField: null,
+ // Defines the index selected for the last alternative fieldRules selection:
+ fieldRuleAlternativesIndex: null,
+ // Stores the length of the last created list of alternative fieldRules:
+ fieldRuleAlternativesLength: null,
+ // Hash to store lists of alternatives (used for radio input fields):
+ fieldRuleAlternativesHash: null,
+ // Cache to reuse/clone fieldRuleAlternatives on the same form fill run:
+ fieldRuleAlternativesCache: null,
+ // Array of dynamic tags:
+ dynamicTags: null,
+ // Array of dynamic tag codes, associated to the dynamic tags:
+ dynamicTagCodes: null,
+ // Determines if a textbox is focused on the rule editor:
+ ruleEditorTextBoxFocused: null,
+ // Determines if a textbox is focused on the tag editor:
+ tagEditorTextBoxFocused: null,
+ // References the last matched form element (used to set the focus):
+ lastFormElementMatch: null,
+ // References the current window when filling out forms:
+ currentWindow: null,
+ // Holds the index of the current form when filling out forms:
+ currentFormIndex:null,
+ // Holds the index of the current form element when filling out forms:
+ currentElementIndex: null,
+ // References the target form field on which the context menu has been invoked:
+ targetFormField: null,
+ // Event listener for the content area context menu:
+ contentAreaContextMenuEventListener: null,
+ // Holds the the tooltip grid which displays commands and their mouse buttons and keyboard shortcuts:
+ tooltipGrid: null,
+ // Holds the current profile tooltip label:
+ tooltipCurrentProfile: null,
+ // Keep track of open dialogs
+ currentDialogs: null,
+ // current version number
+ version: "1.0.4",
+
+ action: function (elem, cmd) {
+ elem.setAttribute('data-aff-' + cmd, true);
+ var wm = Components.classes['@mozilla.org/appshell/window-mediator;1']
+ .getService(Components.interfaces.nsIWindowMediator);
+ var browser = wm.getMostRecentWindow('navigator:browser').gBrowser.selectedBrowser;
+ var mm = browser.messageManager;
+ if (!browser.slScript) {
+ mm.loadFrameScript('chrome://autofillforms/content/inject.js', true);
+ browser.slScript = true;
+ }
+ mm.sendAsyncMessage(cmd);
+ },
+
+ initialize: function() {
+
+ // Save the reference to the Autofill Forms preferences branch:
+ this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+ // Add a preferences observer to the autofillForms preferences branch:
+ this.autofillFormsPrefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
+ this.autofillFormsPrefs.addObserver('', this, false);
+
+ // Implement the event listener for the content area context menu:
+ this.contentAreaContextMenuEventListener = function(event) {
+ autofillForms.initContentAreaContextMenu(event);
+ }
+
+ // Initialize the preferences settings:
+ this.initializePrefs();
+
+ var self = this;
+ document.addEventListener("SSTabRestored", function (event) {
+ function welcome (version) {
+ var pre = self.autofillFormsPrefs.getCharPref("version");
+ if (pre === version) {
+ return;
+ }
+ //Showing welcome screen
+ setTimeout(function () {
+ try {
+ var newTab = getBrowser().addTab(self.autofillFormsPrefs.getCharPref("post_install_url") + "?v=" + version + (pre ? "&p=" + pre + "&type=upgrade" : "&type=install"));
+ getBrowser().selectedTab = newTab;
+ }catch (e) {}
+ }, 5000);
+ self.autofillFormsPrefs.setCharPref("version", version);
+ }
+
+ //Detect Firefox version
+ var version = "";
+ try {
+ version = (navigator.userAgent.match(/Firefox\/([\d\.]*)/) || navigator.userAgent.match(/Thunderbird\/([\d\.]*)/))[1];
+ } catch (e) {}
+ //FF < 4.*
+ var versionComparator = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
+ .getService(Components.interfaces.nsIVersionComparator)
+ .compare(version, "4.0");
+ if (versionComparator < 0) {
+ var addon = qfnServices.extMan.getItemForID("autofillForms at blueimp.net");
+ welcome(addon.version);
+ }
+ //FF > 4.*
+ else {
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+ AddonManager.getAddonByID("autofillForms at blueimp.net", function(addon) {
+ welcome(addon.version);
+ });
+ }
+ });
+ },
+
+ initContentAreaContextMenu: function(event) {
+ var cm0 = document.getElementById('autofillFormsContextMenuItem');
+ var cm1 = document.getElementById('autofillFormsContextMenu');
+ var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
+ var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
+ var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
+ var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
+ var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
+ var cm7 = document.getElementById('autofillFormsDisplayFormDetailsContextMenuItem');
+ if(cm0 && gContextMenu) {
+ if(gContextMenu.target && this.isValidFormField(gContextMenu.target)) {
+ cm0.hidden = true;
+ cm1.hidden = true;
+ if(this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
+ cm2.hidden = true;
+ cm3.hidden = true;
+ cm4.hidden = true;
+ cm5.hidden = true;
+ cm6.hidden = true;
+ cm7.hidden = true;
+ this.targetFormField = null;
+ } else {
+ cm2.hidden = false;
+ cm3.hidden = false;
+ cm4.hidden = false;
+ // Show menuseparators if not already separated:
+ if(this.isPreviousNodeSeparated(cm5)) {
+ cm5.hidden = true;
+ } else {
+ cm5.hidden = false;
+ }
+ if(this.isNextNodeSeparated(cm6)) {
+ cm6.hidden = true;
+ } else {
+ cm6.hidden = false;
+ }
+ this.targetFormField = gContextMenu.target;
+ }
+ return;
+ }
+
+ if(this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
+ || gContextMenu.isContentSelected
+ || gContextMenu.onTextInput
+ || gContextMenu.onImage
+ || gContextMenu.onLink
+ || gContextMenu.onCanvas
+ || gContextMenu.onMathML
+ || !this.getDoc().forms
+ || !this.getDoc().forms.length) {
+ cm0.hidden = true;
+ cm1.hidden = true;
+ cm5.hidden = true;
+ cm6.hidden = true;
+ cm7.hidden = true;
+ } else {
+ if(this.getProfileLabels().length == 1) {
+ cm0.hidden = false;
+ cm1.hidden = true;
+ } else {
+ cm0.hidden = true;
+ cm1.hidden = false;
+ }
+ // Show menuseparators if not already separated:
+ if(this.isPreviousNodeSeparated(cm5)) {
+ cm5.hidden = true;
+ } else {
+ cm5.hidden = false;
+ }
+ if(this.isNextNodeSeparated(cm6)) {
+ cm6.hidden = true;
+ } else {
+ cm6.hidden = false;
+ }
+ cm7.hidden = false;
+ }
+ cm2.hidden = true;
+ cm3.hidden = true;
+ cm4.hidden = true;
+ this.targetFormField = null;
+ }
+ },
+
+ isNextNodeSeparated: function(node) {
+ while(node) {
+ node = node.nextSibling
+ if(node.hidden) {
+ continue;
+ }
+ if(node.nodeName == 'menuseparator') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ isPreviousNodeSeparated: function(node) {
+ while(node) {
+ node = node.previousSibling;
+ if(node.hidden) {
+ continue;
+ }
+ if(node.nodeName == 'menuseparator') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ initializePrefs: function() {
+ // Initialize the keyboard shortcut object container:
+ this.shortcut = new Object();
+ this.shortcut['shortcut'] = null;
+ this.shortcut['shortcutSubmit'] = null;
+ this.shortcut['shortcutAllTabs'] = null;
+ this.shortcut['shortcutFromProfileSelection'] = null;
+ this.shortcut['shortcutProfile'] = null;
+ this.shortcut['shortcutSettings'] = null;
+ this.shortcut['shortcutDisplayFormDetails'] = null;
+ for(var property in this.shortcut) {
+ this.updateShortcut(property);
+ }
+ // Initialize toolbar and statusbar icons and context menu:
+ this.hideToolbarButtonUpdate();
+ this.hideToolbarButtonMenuUpdate();
+ this.hideStatusbarIconUpdate();
+ this.hideContextMenuItemUpdate();
+ },
+
+ observe: function(subject, topic, data) {
+ // Only observe preferences changes:
+ if (topic != 'nsPref:changed')
+ return;
+ switch(data) {
+ case 'profileIndex':
+ // If set to null, the profileIndex will be updated on next getProfileIndex() call:
+ this.profileIndex = null;
+ this.tooltipCurrentProfile = null;
+ break;
+ case 'globalProfileIndex':
+ // If set to null, the globalProfileIndex will be updated on next getGlobalProfileIndex() call:
+ this.globalProfileIndex = null;
+ break;
+ case 'formFieldsContextMenuProfileIndex':
+ // If set to null, the formFieldsContextMenuProfileIndex will be updated on next getFormFieldsContextMenuProfileIndex() call:
+ this.formFieldsContextMenuProfileIndex = null;
+ break;
+ case 'profileLabels':
+ // If set to null, the profileLabels will be updated on next getProfileLabels() call:
+ this.profileLabels = null;
+ this.tooltipCurrentProfile = null;
+ break;
+ case 'profileSiteRules':
+ // If set to null, the profileSiteRules will be updated on next getProfileSiteRules() call:
+ this.profileSiteRules = null;
+ break;
+ case 'shortcut':
+ this.updateShortcut('shortcut');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutSubmit':
+ this.updateShortcut('shortcutSubmit');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutAllTabs':
+ this.updateShortcut('shortcutAllTabs');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutFromProfileSelection':
+ this.updateShortcut('shortcutFromProfileSelection');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutProfile':
+ this.updateShortcut('shortcutProfile');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutSettings':
+ this.updateShortcut('shortcutSettings');
+ this.tooltipGrid = null;
+ break;
+ case 'shortcutDisplayFormDetails':
+ this.updateShortcut('shortcutDisplayFormDetails');
+ this.tooltipGrid = null;
+ break;
+ case 'mouseShortcut':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcut'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutSubmit':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutSubmit'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutAllTabs':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutAllTabs'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutFromProfileSelection':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutFromProfileSelection'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutProfile':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutProfile'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutSettings':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutSettings'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'mouseShortcutDisplayFormDetails':
+ if(this.mouseButton) {
+ this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
+ this.tooltipGrid = null;
+ }
+ break;
+ case 'fieldRules':
+ if(!this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // If set to null, the fieldRules will be updated on next getFieldRules() call:
+ this.fieldRules = null;
+ }
+ break;
+ case 'storeEncrypted':
+ // To update the stored data, we must decrypt or may not decrypt
+ // the prefString in opposition to the setting which just changed -
+ // the "invertedSetting" helper var helps to identify this situation:
+ this.invertedSetting = true;
+ // Store data encrypted/decrypted:
+ this.setFieldRules();
+ this.invertedSetting = false;
+ break;
+ case 'dynamicTags':
+ // If set to null, the dynamicTags will be updated on next getDynamicTags() call:
+ this.dynamicTags = null;
+ break;
+ case 'dynamicTagCodes':
+ // If set to null, the dynamicTagCodes will be updated on next getDynamicTagCodes() call:
+ this.dynamicTagCodes = null;
+ break;
+ case 'hideContextMenuItem':
+ this.hideContextMenuItemUpdate();
+ break;
+ case 'hideFormFieldsContextMenu':
+ this.hideContextMenuItemUpdate();
+ break;
+ case 'hideStatusbarIcon':
+ this.hideStatusbarIconUpdate();
+ break;
+ case 'hideToolbarButton':
+ this.hideToolbarButtonUpdate();
+ this.hideToolbarButtonMenuUpdate();
+ break;
+ case 'hideToolbarButtonMenu':
+ this.hideToolbarButtonMenuUpdate();
+ break;
+ case 'useConfigDirectory':
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.exportToConfigDirectory();
+ } else {
+ this.importFromConfigDirectory();
+ }
+ break;
+ }
+ },
+
+ hideContextMenuItemUpdate: function() {
+ var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
+ if(contentAreaContextMenu) {
+ if(!this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
+ || !this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
+ // Add the content area context menu listener:
+ contentAreaContextMenu.addEventListener(
+ 'popupshowing',
+ this.contentAreaContextMenuEventListener,
+ false
+ );
+ } else {
+ var cm0 = document.getElementById('autofillFormsContextMenuItem');
+ var cm1 = document.getElementById('autofillFormsContextMenu');
+ var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
+ var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
+ var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
+ var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
+ var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
+ if(cm0) {
+ cm0.hidden = true;
+ cm1.hidden = true;
+ cm2.hidden = true;
+ cm3.hidden = true;
+ cm4.hidden = true;
+ cm5.hidden = true;
+ cm6.hidden = true;
+ }
+ // Remove the content area context menu listener:
+ this.targetFormField = null;
+ contentAreaContextMenu.removeEventListener(
+ 'popupshowing',
+ this.contentAreaContextMenuEventListener,
+ false
+ );
+ }
+ }
+ },
+
+ hideStatusbarIconUpdate: function() {
+ // Change the statusbar icon visibility:
+ var autofillFormsPanelIcon = document.getElementById('autofillFormsPanelIcon');
+ if(autofillFormsPanelIcon) {
+ autofillFormsPanelIcon.setAttribute(
+ 'hidden',
+ this.autofillFormsPrefs.getBoolPref('hideStatusbarIcon')
+ );
+ }
+ },
+
+ installToolbarButton: function(buttonID, beforeNodeID, toolbarID) {
+ beforeNodeID = beforeNodeID ? beforeNodeID : 'home-button';
+ toolbarID = toolbarID ? toolbarID : 'navigation-toolbar';
+ if(!document.getElementById(buttonID)) {
+ var toolbar = document.getElementById(toolbarID);
+ if(!toolbar) {
+ // Firefox < 3:
+ toolbar = document.getElementById('nav-bar');
+ }
+ if(toolbar && 'insertItem' in toolbar) {
+ var beforeNode = document.getElementById(beforeNodeID);
+ if(beforeNode && beforeNode.parentNode != toolbar) {
+ beforeNode = null;
+ }
+ // Insert before the given node or at the end of the toolbar if the node is not available:
+ toolbar.insertItem(buttonID, beforeNode, null, false);
+ toolbar.setAttribute('currentset', toolbar.currentSet);
+ document.persist(toolbar.id, 'currentset');
+ }
+ }
+ },
+
+ hideToolbarButtonUpdate: function() {
+ var autofillFormsButton = document.getElementById('autofillFormsButton');
+ var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
+ if(!autofillFormsButton && !hideToolbarButton) {
+ // Add the toolbar button to the toolbar:
+ this.installToolbarButton('autofillFormsButton');
+ autofillFormsButton = document.getElementById('autofillFormsButton');
+ }
+ if(autofillFormsButton) {
+ autofillFormsButton.setAttribute(
+ 'hidden',
+ hideToolbarButton
+ );
+ }
+ },
+
+ hideToolbarButtonMenuUpdate: function() {
+ var autofillFormsButton = document.getElementById('autofillFormsButton');
+ if(autofillFormsButton) {
+ if(this.autofillFormsPrefs.getBoolPref('hideToolbarButtonMenu')) {
+ autofillFormsButton.removeAttribute('type');
+ } else {
+ autofillFormsButton.setAttribute('type','menu-button');
+ }
+ }
+ },
+
+ commandHandler: function(event) {
+ if(typeof event.button == 'undefined') {
+ // If no event.button is set, the command has been done by the left mouse button:
+ event.button = 0;
+ }
+ // Recognize the mouse button and perform the associated action:
+ var mouseButtonObj = this.recognizeMouseButton(event);
+ if(this.getMouseButton('mouseShortcut').equals(mouseButtonObj)) {
+ this.fillForms();
+ } else if(this.getMouseButton('mouseShortcutSubmit').equals(mouseButtonObj)) {
+ this.fillForms(null, null, true);
+ } else if(this.getMouseButton('mouseShortcutAllTabs').equals(mouseButtonObj)) {
+ this.fillForms(null, null, null, true);
+ } else if(this.getMouseButton('mouseShortcutFromProfileSelection').equals(mouseButtonObj)) {
+ this.profileSelectionFormFillPopup(event);
+ } else if(this.getMouseButton('mouseShortcutProfile').equals(mouseButtonObj)) {
+ this.showProfileSwitcher(event);
+ } else if(this.getMouseButton('mouseShortcutSettings').equals(mouseButtonObj)) {
+ this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');
+ } else if(this.getMouseButton('mouseShortcutDisplayFormDetails').equals(mouseButtonObj)) {
+ this.displayFormDetails();
+ }
+ },
+
+ clickHandler: function(event) {
+ switch(event.button) {
+ case 0:
+ // The left mouse button is already handled for clicks on the toolbar button,
+ // but not for clicks on the status bar icon:
+ if(event.target.id == 'autofillFormsPanelIcon') {
+ this.commandHandler(event);
+ }
+ break;
+ default:
+ this.commandHandler(event);
+ }
+ },
+
+ profileSelectionFormFillPopup: function(event) {
+ var popup = document.getElementById('autofillFormsProfileSelectionPopup');
+ if(popup && typeof popup.openPopup == 'function') {
+ this.prepareProfileSelectionFormFillMenu(popup);
+ // Show the popup menu (only available for Firefox >= 3):
+ popup.openPopup(event.target, null, 0, 0, false, true);
+ } else {
+ this.profileSelectionFormFillPrompt(event);
+ }
+ },
+
+ prepareProfileSelectionFormFillMenu: function(menupopup) {
+ // Remove all children nodes:
+ while(menupopup.hasChildNodes()) {
+ menupopup.removeChild(menupopup.firstChild);
+ }
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('class','menuitem-iconic autofillFormsIcon');
+ // Add the profile labels as menu items:
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ menuitem = menuitem.cloneNode(false);
+ menuitem.setAttribute('label', this.getProfileLabel(i));
+ menuitem.setAttribute('data-index', i);
+ menuitem.addEventListener("command", function () {
+ var i = +this.getAttribute('data-index');
+ autofillForms.fillForms(null, i);
+ });
+ menupopup.appendChild(menuitem);
+ }
+ },
+
+ profileSelectionFormFillPrompt: function(event) {
+ // Show a profile selection prompt and fill out forms with the selected profile:
+ var list = this.getProfileLabels();
+ var selected = {};
+ var ok = this.getPrompts().select(
+ window,
+ this.getStringBundle().getString('profileSelectionFormFillTitle'),
+ this.getStringBundle().getString('profileSelectionPrompt'),
+ list.length,
+ list,
+ selected
+ );
+ if(ok) {
+ this.fillForms(null, selected.value);
+ }
+ },
+
+ fillForms: function(win, profileIndex, autoSubmit, allTabs) {
+ if(!win || !win.document) {
+ win = this.getWin();
+ }
+
+ var currentProfileIndex = this.getProfileIndex();
+ var toggleAutoSelectBestProfile;
+ if(typeof profileIndex == 'number') {
+ // Temporarily set the given profile index:
+ this.setProfileIndex(profileIndex);
+
+ if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+ // Temporarily disable autoSelectBestProfile:
+ this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', false);
+ toggleAutoSelectBestProfile = true;
+ }
+ }
+
+ autoSubmit = autoSubmit ? autoSubmit : null;
+
+ if(allTabs) {
+ // Fill out forms on all open browser tabs:
+ for(var i=0; i<this.getBrowser().browsers.length; i++) {
+ this.searchAndFillForms(
+ this.getBrowser().getBrowserAtIndex(i).contentWindow,
+ autoSubmit
+ );
+ }
+ } else {
+ // Fill out forms on the current tab (or the given window object):
+ this.searchAndFillForms(win, autoSubmit);
+ }
+
+ // Reset Alternatives (including the cache):
+ this.fieldRuleAlternativesIndex = null;
+ this.fieldRuleAlternativesLength = null;
+ this.fieldRuleAlternativesHash = null;
+ this.fieldRuleAlternativesCache = null;
+
+ // Reset objects to release used memory:
+ this.fieldRules = null;
+ this.profileSiteRules = null;
+ this.dynamicTags = null;
+ this.dynamicTagCodes = null;
+
+ // Reset the selected profile:
+ this.setProfileIndex(currentProfileIndex);
+
+ if(toggleAutoSelectBestProfile) {
+ // Reenable autoSelectBestProfile:
+ this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', true);
+ }
+ },
+
+ searchAndFillForms: function(win, autoSubmit) {
+ var doc = this.getDoc(win);
+
+ // Check if any web forms are available on the current window:
+ if(doc && doc.forms && doc.forms.length > 0) {
+
+ var url = doc.location.href;
+
+ if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+ // Remember the currently selected profile:
+ var currentProfileIndex = this.getProfileIndex();
+ }
+
+ // Select the best matching profile - returns false if none matches:
+ if(!this.selectBestMatchingProfile(url)) {
+ return;
+ }
+
+ this.currentWindow = win;
+
+ // Holds the form to be submitted:
+ var submitForm;
+ // Holds the first submit element found on the form:
+ var submitElement;
+
+ // Go through the forms:
+ for(var i = 0; i < doc.forms.length; i++) {
+ this.currentFormIndex = i;
+
+ // The form elements list:
+ var elements = doc.forms[i].elements;
+
+ // A hash to store the alternatives for radio input fields:
+ this.fieldRuleAlternativesHash = new Object();
+
+ // Go through the form elements:
+ for(var j = 0; j < elements.length; j++) {
+ this.currentElementIndex = j;
+
+ // Fill out valid form field types:
+ if(this.isValidFormField(elements[j])) {
+ this.setFormField(elements[j], url);
+ }
+
+ // Collect the first submit button of the form if autoSubmit is enabled:
+ if(autoSubmit && elements[j].type && elements[j].type == 'submit' && !submitElement) {
+ submitElement = elements[j];
+ }
+ }
+
+ this.applyStoredFieldRulesAlternatives();
+
+ if(autoSubmit) {
+ if(this.lastFormElementMatch && this.lastFormElementMatch.form == doc.forms[i]) {
+ // Elements have been matched on this form, check the submitElement:
+ if(!submitElement) {
+ submitElement = this.getImageSubmitButton(doc.forms[i]);
+ }
+ submitForm = doc.forms[i];
+ // Break out of the forms loop:
+ break;
+ } else {
+ submitElement = null;
+ }
+ }
+ }
+
+ if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+ // Reset the selected profile to the manually selected one:
+ this.setProfileIndex(currentProfileIndex);
+ }
+
+ if(this.lastFormElementMatch && this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
+ // Set the focus to the last matched form element:
+ //this.lastFormElementMatch.focus();
+ autofillForms.action(this.lastFormElementMatch, 'focus');
+ }
+
+ // Reset the last matched form element:
+ this.lastFormElementMatch = null;
+
+ this.currentWindow = null;
+ this.currentFormIndex = null;
+ this.currentElementIndex = null;
+
+ if (autoSubmit && submitForm) {
+ // autoSubmit the form with a click on the submit button if found
+ // or else by calling the submit() method on the form:
+ if(submitElement) {
+ //submitElement.click();
+ autofillForms.action(submitElement, 'click');
+ } else {
+ //submitForm.submit();
+ autofillForms.action(submitForm, 'submit');
+ }
+ }
+ }
+
+ // Recursive call for all subframes:
+ for(var f=0; f < win.frames.length; f++) {
+ this.searchAndFillForms(win.frames[f], autoSubmit);
+ }
+ },
+
+ getImageSubmitButton: function(form) {
+ var inputElements = form.getElementsByTagName('input');
+ for(var i = 0; i < inputElements.length; i++) {
+ if(inputElements[i].type == 'image') {
+ return inputElements[i];
+ }
+ }
+ },
+
+ selectBestMatchingProfile: function(url) {
+ if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+ var match;
+ // The emtpy siteRule (?:) has a match length of 0, so we set the initial value to -1:
+ var maxMatch = -1;
+ var index = -1;
+ // First test the currently selected profile:
+ try {
+ match = url.match(new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i'));
+ if(match && (match.toString()).length > maxMatch) {
+ maxMatch = (match.toString()).length;
+ index = this.getProfileIndex();
+ }
+ } catch(e) {
+ // Catch errors caused by invalid profile site rules
+ }
+ for(var i=0; i<this.getProfileSiteRules().length; i++) {
+ if(i == this.getProfileIndex()) {
+ // Skip the current profile (already tested):
+ continue;
+ }
+ try {
+ match = url.match(new RegExp(this.getProfileSiteRule(i),'i'));
+ if(match && (match.toString()).length > maxMatch) {
+ maxMatch = (match.toString()).length;
+ index = i;
+ }
+ } catch(e) {
+ // Catch errors caused by invalid profile site rules
+ }
+ }
+ if(index > -1) {
+ // Select the profile with the best match:
+ this.setProfileIndex(index);
+ return true;
+ }
+ } else {
+ try {
+ var regExp = new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i');
+ if(regExp.test(url)) {
+ return true;
+ }
+ } catch(e) {
+ // Catch errors caused by invalid profile site rules
+ }
+ }
+ return false;
+ },
+
+ setFormField: function(element,url) {
+ var matchFound = false;
+
+ // Apply the fieldRules of the current profile:
+ matchFound = this.applyFieldRulesOnElement(element,url,this.getFieldRules());
+
+ // If no match has been found, apply the fieldRules of the global profile, if enabled:
+ if(!matchFound && this.autofillFormsPrefs.getBoolPref('enableGlobalProfile')) {
+ // Only apply the global profile fieldRules if the current profile is not the global profile;
+ if(this.getProfileIndex() != this.getGlobalProfileIndex()) {
+ // Only apply the global profile if the global profile site rule matches the url:
+ try {
+ var regExp = new RegExp(this.getProfileSiteRule(this.getGlobalProfileIndex()),'i');
+ if(regExp.test(url)) {
+ matchFound = this.applyFieldRulesOnElement(element,url,this.getGlobalFieldRules());
+ }
+ } catch(e) {
+ // Catch errors caused by invalid profile site rules
+ }
+ }
+ }
+
+ // Highlight styles:
+ var highlightStyleMatch = this.autofillFormsPrefs.getCharPref('highlightStyleMatch');
+ var highlightStyleNoMatch = this.autofillFormsPrefs.getCharPref('highlightStyleNoMatch');
+
+ if(matchFound) {
+ // Set the current element as the last matched form element:
+ this.lastFormElementMatch = element;
+
+ if(highlightStyleMatch) {
+ // Highlight matched form fieds:
+ element.setAttribute('style', highlightStyleMatch);
+ }
+ } else if(highlightStyleNoMatch) {
+ // Highlight not matched form fieds:
+ element.setAttribute('style', highlightStyleNoMatch);
+ }
+ },
+
+ getIndexForFieldRules: function(fieldRules) {
+ if(this.fieldRules) {
+ for(var i=0; i<this.fieldRules.length; i++) {
+ if(this.fieldRules[i] === fieldRules) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ },
+
+ fieldRuleAlternativeFactory: function(fieldRules, index) {
+ var af = this;
+ if(typeof arguments.callee.fieldRuleAlternative == 'undefined') {
+ arguments.callee.fieldRuleAlternative = function(fieldRules, index) {
+ this.fieldRules = fieldRules;
+ this.index = index;
+ this.fieldRule = this.fieldRules[this.index];
+ return this;
+ }
+ arguments.callee.fieldRuleAlternative.prototype = {
+ af : af,
+ fieldRuleValue: null,
+ fieldRuleValueRegExp: null,
+ fieldRuleRegExp: null,
+ siteRuleRegExp: null,
+ optionsIndex: null,
+ element: null,
+ getValue: function() {
+ if(this.fieldRuleValue === null) {
+ // Replace dynamic tags if enabled:
+ if(this.af.autofillFormsPrefs.getBoolPref('enableDynamicTags'))
+ this.fieldRuleValue = this.af.replaceDynamicTags(this.fieldRule['fieldRuleValue']);
+ else
+ this.fieldRuleValue = this.fieldRule['fieldRuleValue'];
+ }
+ return this.fieldRuleValue;
+ },
+ getRule: function() {
+ return this.fieldRule['fieldRuleFieldRule'];
+ },
+ getName: function() {
+ return this.fieldRule['fieldRuleName'];
+ },
+ isEnabled: function() {
+ return this.fieldRule['fieldRuleEnabled'];
+ },
+ isURLMatching: function(url) {
+ if(this.siteRuleRegExp === null) {
+ this.siteRuleRegExp = new RegExp(this.fieldRule['fieldRuleSiteRule'],'i');
+ }
+ // Test if the siteRule matches the given URL:
+ return this.siteRuleRegExp.test(url);
+ },
+ isRuleMatching: function(str) {
+ if(this.fieldRuleRegExp === null) {
+ this.fieldRuleRegExp = new RegExp(this.fieldRule['fieldRuleFieldRule'],'i');
+ }
+ // Test if the fieldRule matches the given string:
+ return this.fieldRuleRegExp.test(str);
+ },
+ isValueMatching: function(str) {
+ try {
+ if(this.fieldRuleValueRegExp === null) {
+ this.fieldRuleValueRegExp = new RegExp(this.getValue(),'i');
+ }
+ // Test if the value as regular expression matches the given string:
+ return this.fieldRuleValueRegExp.test(str);
+ } catch(e) {
+ // If turning the value into a regular expression fails, compare the strings:
+ return (str == this.getValue());
+ }
+ },
+ isOverwrite: function() {
+ // This setting defines if existing field contents should be overwritten
+ // and if checkboxes and radio buttons should be checked or unchecked
+ // and if selection options should be selected or unselected:
+ return this.fieldRule['fieldRuleOverwrite']
+ },
+ getIndex: function() {
+ return this.index;
+ },
+ getOptionsIndex: function() {
+ return this.optionsIndex;
+ },
+ setOptionsIndex: function(optionsIndex) {
+ this.optionsIndex = optionsIndex;
+ },
+ getElement: function() {
+ return this.element;
+ },
+ setElement: function(element) {
+ this.element = element;
+ },
+ clone: function() {
+ // This creates only a shallow copy,
+ // though we only need a shallow copy:
+ var clone = new this.constructor();
+ for(var key in this) {
+ clone[key] = this[key];
+ }
+ return clone;
+ }
+ }
+ }
+ if(this.fieldRuleAlternativesCache == null) {
+ this.fieldRuleAlternativesCache = new Object();
+ }
+ var identifier = this.getIndexForFieldRules(fieldRules)+'-'+index;
+ if(!this.fieldRuleAlternativesCache[identifier]) {
+ this.fieldRuleAlternativesCache[identifier] = new arguments.callee.fieldRuleAlternative(
+ fieldRules,
+ index
+ );
+ } else {
+ // Clone the cached alternative and set the clone as new cached element:
+ this.fieldRuleAlternativesCache[identifier] = this.fieldRuleAlternativesCache[identifier].clone()
+ }
+ return this.fieldRuleAlternativesCache[identifier];
+ },
+
+ getLabelForElement: function(element) {
+ if(element.form && element.id) {
+ // Method to retrieve the textual content of the label assigned to the form element:
+ var labels = element.form.getElementsByTagName('label');
+ for(var i=0; i<labels.length; i++) {
+ if(labels[i].htmlFor && labels[i].htmlFor == element.id) {
+ // label elements may contain other inline elements,
+ // so we just use the innerHTML content and strip it of all HTML tags
+ // whitespace is removed from the beginning and end of the string for convenience:
+ return this.trim(this.stripTags(labels[i].innerHTML));
+ }
+ }
+ }
+ if(!this.autofillFormsPrefs.getBoolPref('labelsStrictMode')) {
+ return this.getLabelCloseToElement(element);
+ }
+ return null;
+ },
+
+ getLabelCloseToElement: function(element) {
+ var label = null;
+ var node = element;
+ var nextNode;
+ if(element.type == 'checkbox' || element.type == 'radio') {
+ // For checkboxes and radio buttons the label is usually placed as nextSibling:
+ nextNode = 'nextSibling';
+ } else {
+ // For other elements the label is usually placed as previousSibling:
+ nextNode = 'previousSibling';
+ }
+ // Check if a sibling contains the element label:
+ while(node[nextNode]) {
+ node = node[nextNode];
+ label = this.getNodeTextContent(node, true);
+ if(label) {
+ return label;
+ }
+ }
+ // Parse the siblings of the parentNode:
+ node = element.parentNode;
+ if(node) {
+ while(node[nextNode]) {
+ node = node[nextNode];
+ label = this.getNodeTextContent(node, true);
+ if(label) {
+ return label;
+ }
+ }
+ // If the parentNode of the parentNode is a table cell,
+ // also parse the siblings of this node:
+ node = element.parentNode.parentNode;
+ if(node && node.nodeName == 'TD') {
+ while(node[nextNode]) {
+ node = node[nextNode];
+ label = this.getNodeTextContent(node, true);
+ if(label) {
+ return label;
+ }
+ }
+ }
+ }
+ return null;
+ },
+
+ getNodeTextContent: function(node, trim) {
+ // Get the text content from the current node or its child nodes:
+ var text;
+ if(node.nodeType == 3) {
+ // nodeType 3 is a text node:
+ text = node.nodeValue;
+ } else {
+ // Do not follow selection nodes, script nodes or noscript nodes:
+ if(node.nodeName == 'SELECT' || node.nodeName == 'SCRIPT' || node.nodeName == 'NOSCRIPT') {
+ return '';
+ }
+ text = '';
+ for(var i=0; i<node.childNodes.length; i++) {
+ text += this.getNodeTextContent(node.childNodes[i]);
+ }
+ }
+ if(trim) {
+ return this.trim(text);
+ } else {
+ return text;
+ }
+ },
+
+ applyFieldRulesOnElement: function(element,url,fieldRules) {
+
+ var labelValue = this.autofillFormsPrefs.getBoolPref('matchAgainstLabels') ?
+ this.getLabelForElement(element) : null;
+
+ var positionString = this.autofillFormsPrefs.getBoolPref('matchAgainstPositions') ?
+ this.currentFormIndex + this.autofillFormsPrefs.getCharPref('positionsIdentifier')
+ + this.currentElementIndex : null;
+
+ var fieldRuleAlternatives = new Array();
+
+ // Go through the list of fieldRules:
+ for(var i=0; i < fieldRules.length; i++) {
+
+ var rule = this.fieldRuleAlternativeFactory(fieldRules, i);
+
+ // Skip this rule if
+ // a) the rule is disabled and disabled rules are to be ignored or
+ // b) the current URL is not matching the siteRule or
+ // c) all of the following are false:
+ // 1) the element name does not match the fieldRule
+ // 2) label matching is disabled or the element label does not match the fieldRule
+ // 3) the element name is not empty or the element id does not match the fieldRule
+ // 4) position matching is disabled or the position does not match the fieldRule
+ if( !rule.isEnabled() &&
+ this.autofillFormsPrefs.getBoolPref('ignoreDisabledRulesOnAutofill') ||
+ !rule.isURLMatching(url) ||
+ (
+ !rule.isRuleMatching(element.name) &&
+ (labelValue === null || !rule.isRuleMatching(labelValue)) &&
+ (element.name || !rule.isRuleMatching(element.id)) &&
+ (positionString === null || !rule.isRuleMatching(positionString))
+ )
+ ) {
+ if(fieldRuleAlternatives.length > 0) {
+ // Break out of the loop, if we already have an alternative:
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ if(element.type == 'select-one' || element.type == 'select-multiple') {
+ // Go through the selection options:
+ for(var j = 0; j < element.options.length; j++) {
+ // Match either the value or the text (the selection option label):
+ if(rule.isValueMatching(element.options[j].value) || rule.isValueMatching(element.options[j].text)) {
+ // Remember the matching option:
+ rule.setOptionsIndex(j);
+ // Remember the element:
+ rule.setElement(element);
+ // Add a clone of the alternative and continue to see if the value matches several options:
+ fieldRuleAlternatives.push(rule.clone());
+ }
+ }
+ } else if(element.type == 'checkbox' || element.type == 'radio') {
+ if(rule.isValueMatching(element.value)) {
+ // Remember the element:
+ rule.setElement(element);
+ // Add the alternative:
+ fieldRuleAlternatives.push(rule);
+ // Only one rule has to match a checkbox/radio button, so we break out of the loop:
+ break;
+ }
+ } else {
+ // Remember the element:
+ rule.setElement(element);
+ // Add the alternative:
+ fieldRuleAlternatives.push(rule);
+ }
+ if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
+ this.fireEvent(element,'change')
+ }
+ }
+
+ return this.applyFieldRulesAlternativesOnElement(element,fieldRuleAlternatives);
+ },
+
+ applyFieldRulesAlternativesOnElement: function(element,fieldRuleAlternatives) {
+ if(fieldRuleAlternatives.length == 0) {
+ return false;
+ }
+
+ if (this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
+ //element.focus();
+ autofillForms.action(element, 'focus');
+ }
+
+ // Add a box (with some help from Mike Ratcliffe)
+ // http://groups.google.com/group/firebug/browse_thread/thread/7d4bd89537cd24e7/2c9483d699efe257?hl=en
+ // TODO: why doesn't getBoundingClientRect return the absolute coordinates of the element?
+ // At the moment, I'm looking at the offset of the doc.body and use that to calculate the absolute coordinates
+ // what's the offset -4,+1 pixel relative to? the size of the window border?
+ //
+ var doc = this.getDoc();
+ var div1 = doc.createElement('div');
+
+ var rect = element.getBoundingClientRect();
+ var rectBody = doc.body.getBoundingClientRect();
+
+ //Firebug.Console.log(element);
+ //Firebug.Console.log(rect.left+' '+rect.top+' '+rect.right+' '+rect.bottom+' '+rect.width+' '+rect.height);
+ //Firebug.Console.log(rectBody.left+' '+rectBody.top+' '+rectBody.right+' '+rectBody.bottom+' '+rectBody.width+' '+rectBody.height);
+
+ //maybe something here...
+ //Firebug.Console.log(element.clientLeft+' '+element.clientTop)
+ //Firebug.Console.log(element.scrollLeft+' '+element.scrollTop)
+
+ //Firebug.Console.log(doc.body)
+ //Firebug.Console.log(rect)
+ //Firebug.Console.log(rectBody)
+
+ //div1.setAttribute('id', 'autoformHighlight');
+ div1.setAttribute('style', 'position:absolute;z-index:2147483646'
+ + ';border-width: 2px; border-color: red; border-style:solid'
+ + ';left:'+(rect.left-rectBody.left-1)+'px'
+ + ';top:'+(rect.top-rectBody.top+3)+'px'
+ + ';width:'+rect.width+'px'
+ + ';height:'+rect.height+'px'
+ );
+ doc.body.appendChild(div1);
+
+ // Use all alternatives for select-multiple elements:
+ if(element.type == 'select-multiple') {
+ for(var i=0; i < fieldRuleAlternatives.length; i++) {
+ var rule = fieldRuleAlternatives[i];
+ if(rule.isOverwrite()) {
+ element.options[rule.getOptionsIndex()].selected = true;
+ } else {
+ element.options[rule.getOptionsIndex()].selected = false;
+ }
+ }
+ doc.body.removeChild(div1);
+ return true;
+ }
+
+ // Select the alternatives index (displays a selection dialog if required):
+ var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
+
+ if(index == -1) {
+ doc.body.removeChild(div1);
+ return false;
+ } else {
+ var rule = fieldRuleAlternatives[index];
+ if(element.type == 'select-one') {
+ if(rule.isOverwrite()) {
+ element.options[rule.getOptionsIndex()].selected = true;
+ } else {
+ element.options[rule.getOptionsIndex()].selected = false;
+ }
+ } else if(element.type == 'checkbox') {
+ if(rule.isOverwrite()) {
+ element.checked = true;
+ } else {
+ element.checked = false;
+ }
+ } else if(element.type == 'radio') {
+ try {
+ // Rules matching radio elements are stored and handled as group
+ // at the end of each form loop with the applyStoredFieldRulesAlternatives method:
+ if(!this.fieldRuleAlternativesHash[element.name]) {
+ this.fieldRuleAlternativesHash[element.name] = new Array();
+ }
+ this.fieldRuleAlternativesHash[element.name].push(rule);
+ } catch(e) {
+ this.log(e);
+ doc.body.removeChild(div1);
+ return false;
+ }
+ } else {
+ if(!element.value || rule.isOverwrite()) {
+ if(element.type == 'textarea') {
+ // Replace control character placeholders:
+ element.value = this.replaceControlCharacterPlaceholders(rule.getValue());
+ } else {
+ element.value = rule.getValue();
+ }
+ }
+ }
+ if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
+ this.fireEvent(element,'change')
+ }
+
+
+ }
+
+ //remove the div, not needed anymore
+ doc.body.removeChild(div1);
+ return true;
+ },
+
+ fireEvent: function(element,anEvent) {
+ var evt = document.createEvent("HTMLEvents");
+ evt.initEvent(anEvent, true, true ); // event type,bubbling,cancelable
+ return !element.dispatchEvent(evt);
+ },
+
+ applyStoredFieldRulesAlternatives: function() {
+ for(var key in this.fieldRuleAlternativesHash) {
+ var fieldRuleAlternatives = this.filterRealFieldRuleAlternatives(
+ this.fieldRuleAlternativesHash[key]
+ );
+ var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
+ if(index != -1) {
+ var rule = fieldRuleAlternatives[index];
+ // This is currently only used for radio input fields:
+ if(rule.isOverwrite()) {
+ rule.getElement().checked = true;
+ } else {
+ rule.getElement().checked = false;
+ }
+ }
+ }
+ },
+
+ filterRealFieldRuleAlternatives: function(fieldRuleAlternatives) {
+ // Sort the fieldRuleAlternatives by index:
+ fieldRuleAlternatives.sort(this.compareFieldRuleAlternativesByIndex);
+ // Make sure only real Alternatives (placed next to each other) are included:
+ for(var i=1; i<fieldRuleAlternatives.length; i++) {
+ // If the fieldRules index is more than one step larger than the previous one,
+ // the remaining array items can be sliced off - they are no real Alternatives:
+ if(fieldRuleAlternatives[i].getIndex()-1 > fieldRuleAlternatives[i-1].getIndex()) {
+ fieldRuleAlternatives = fieldRuleAlternatives.slice(0, i);
+ break;
+ }
+ }
+ return fieldRuleAlternatives;
+ },
+
+ compareFieldRuleAlternativesByIndex: function(ruleA, ruleB) {
+ if(ruleA.getIndex() < ruleB.getIndex()) {
+ return -1;
+ } else if(ruleA.getIndex() > ruleB.getIndex()) {
+ return 1;
+ }
+ return 0;
+ },
+
+ getFieldRulesAlternativeLabel: function(rule) {
+ // This method returns a label for this alternative
+ // to be displayed on the alternatives selection
+ switch(rule.getElement().type) {
+ case 'select-multiple':
+ case 'select-one':
+ // Use the options text:
+ return rule.getElement().options[rule.getOptionsIndex()].text;
+ case 'radio':
+ case 'checkbox':
+ // Try to retrieve the element label:
+ var label = this.getLabelForElement(rule.getElement());
+ // Remove the colon, if present:
+ if(label && label.charAt(label.length-1) == ':') {
+ label = label.substr(0, label.length-1);
+ }
+ // If no label could be found,
+ // use the element value:
+ if(!label) {
+ label = rule.getElement().value;
+ }
+ return label;
+ default:
+ // Use the calculated value:
+ return rule.getValue();
+ }
+ },
+
+ selectFieldRulesAlternativesIndex: function(fieldRuleAlternatives) {
+ // Display a selection prompt if we have alternatives and no alternativesIndex has been set yet
+ // or the rememberAlternativesIndex setting is false or the saved alternativesLength is different:
+ if(fieldRuleAlternatives.length > 1) {
+ // When alternatives are disabled, return either 0 (remember the alternative)
+ // or cycle through the available alternatives.
+ if(this.autofillFormsPrefs.getBoolPref('disableAlternatives') == true) {
+ var fieldRuleAlternativesIndex = 0;
+ /*
+ //todo take into account multiple instances of the form field. Can't increase the index blindly...
+ if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false) {
+ fieldRuleAlternativesIndex = this.fieldRuleAlternativesIndex;
+ if (this.fieldRuleAlternativesIndex == fieldRuleAlternatives.length-1) {
+ this.fieldRuleAlternativesIndex = 0;
+ }
+ else {
+ this.fieldRuleAlternativesIndex += 1;
+ }
+ }
+ */
+ return fieldRuleAlternativesIndex;
+ }
+
+ if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false
+ || this.fieldRuleAlternativesIndex === null
+ || fieldRuleAlternatives.length != this.fieldRuleAlternativesLength) {
+ // The selection list displays the index number and the current fieldRuleValues:
+ var list = new Array();
+ var maxFigureLength = fieldRuleAlternatives.length.toString().length;
+ for(var i=0; i < fieldRuleAlternatives.length; i++) {
+ list.push(
+ this.addLeadingZeros(i+1, maxFigureLength)
+ + '. '
+ + this.getFieldRulesAlternativeLabel(fieldRuleAlternatives[i])
+ + ' - '
+ + fieldRuleAlternatives[i].getName()
+ );
+ }
+ var selected = {};
+ // Show the selection prompt:
+ var ok = this.getPrompts().select(
+ window,
+ this.getStringBundle().getString('alternativesSelectionWindowTitle'),
+ this.getStringBundle().getString('alternativesSelectionPrompt'),
+ list.length,
+ list,
+ selected
+ );
+ // Save the selected alternatives index, return -1 on cancel:
+ if(ok)
+ this.fieldRuleAlternativesIndex = selected.value;
+ else
+ return -1;
+
+ this.fieldRuleAlternativesLength = fieldRuleAlternatives.length;
+ }
+ // Use the fieldRuleAlternative with the selected fieldRuleAlternativesIndex:
+ return this.fieldRuleAlternativesIndex;
+ } else if(fieldRuleAlternatives.length == 1) {
+ return 0;
+ }
+ return -1;
+ },
+
+ stripTags: function(str) {
+ if (!arguments.callee.regExp) {
+ arguments.callee.regExp = new RegExp('<\\/?[^>]+?>', 'g');
+ }
+ // Return string stripped from HTML tags:
+ return str.replace(arguments.callee.regExp, '');
+ },
+
+ trim: function(str) {
+ if (!arguments.callee.regExp) {
+ arguments.callee.regExp = new RegExp('(?:^\\s+)|(?:\\s+$)', 'g');
+ }
+ // Return string with whitespace removed at beginning and end of the string:
+ return str.replace(arguments.callee.regExp, '');
+ },
+
+ initProfilesPopupMenu: function(event) {
+ var menupopup = event.target;
+ // Remove all children nodes:
+ while(menupopup.hasChildNodes()) {
+ menupopup.removeChild(menupopup.firstChild);
+ }
+ // Add the profile labels as menu items:
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label', this.getProfileLabel(i));
+ menuitem.setAttribute('data-index', i);
+ menuitem.addEventListener("command", function () {
+ var i = +this.getAttribute('data-index');
+ autofillForms.setProfileIndex(i);
+ });
+ menuitem.setAttribute('type', 'radio');
+ if(i == this.getProfileIndex()) {
+ menuitem.setAttribute('checked', true);
+ }
+ menupopup.appendChild(menuitem);
+ }
+ },
+
+ initManualFillContextMenu: function(event) {
+ var menupopup = event.target;
+ // Remove all children nodes:
+ while(menupopup.hasChildNodes()) {
+ menupopup.removeChild(menupopup.firstChild);
+ }
+
+ var authenticationNeeded = false;
+ if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
+ // Determine if a master password is set and the user has not been authenticated yet:
+ authenticationNeeded = this.getMasterSecurityDevice().getInternalKeyToken().needsLogin()
+ && !this.getMasterSecurityDevice().getInternalKeyToken().isLoggedIn();
+ }
+
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+ this.profileLabels = null;
+ }
+
+ // Check if only one profile is to be shown:
+ if((this.getFormFieldsContextMenuProfileIndex() != -3) || (this.getProfileLabels().length == 1)) {
+ var profileIndex = (this.getFormFieldsContextMenuProfileIndex() == -2)
+ ? this.getProfileIndex() : this.getFormFieldsContextMenuProfileIndex();
+ if(authenticationNeeded) {
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label', this.getProfileLabel(profileIndex)+'...');
+ menuitem.setAttribute('data-profileIndex', profileIndex);
+ menuitem.addEventListener("command", function () {
+ var i = +this.getAttribute('data-profileIndex');
+ autofillForms.authenticateAndShowManualFillDialog(i);
+ });
+ menupopup.appendChild(menuitem);
+ } else {
+ this.initManualFillProfileContextMenu(event, profileIndex);
+ }
+ return;
+ }
+
+ // Add the profile labels as menus or menuitems if authentication is needed:
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ if(authenticationNeeded) {
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label', this.getProfileLabel(i)+'...');
+ menuitem.setAttribute('data-index', i);
+ menuitem.addEventListener("command", function () {
+ var i = +this.getAttribute('data-index');
+ autofillForms.authenticateAndShowManualFillDialog(i);
+ });
+ menupopup.appendChild(menuitem);
+ } else {
+ var menu = document.createElement('menu');
+ menu.setAttribute('label', this.getProfileLabel(i));
+
+ // Add a menupopup for each profile:
+ var profilemenupopup = document.createElement('menupopup');
+ profilemenupopup.setAttribute('data-index', i);
+ profilemenupopup.addEventListener("popupshowing", function (event) {
+ if(event.target == this) {
+ var i = +this.getAttribute('data-index');
+ autofillForms.initManualFillProfileContextMenu(event, i);
+ }
+ });
+ menu.appendChild(profilemenupopup);
+ menupopup.appendChild(menu);
+ }
+ }
+ },
+
+ initManualFillProfileContextMenu: function(event, profileID) {
+ var menupopup = event.target;
+ // Remove all children nodes:
+ while(menupopup.hasChildNodes()) {
+ menupopup.removeChild(menupopup.firstChild);
+ }
+ var menuPopupMore;
+ // Add the profile field rules as menu items:
+ for(var i=0; i < this.getFieldRules(profileID).length; i++) {
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label', this.getFieldRules(profileID)[i]['fieldRuleName']);
+ menuitem.setAttribute('data-index', i);
+ menuitem.setAttribute('data-profileID', profileID);
+ menuitem.addEventListener("command", function () {
+ var i = +this.getAttribute('data-index');
+ var profileID = +this.getAttribute('data-profileID');
+ autofillForms.fillTargetFormField(profileID, i);
+ });
+ if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
+ menupopup.appendChild(menuitem);
+ } else {
+ // Add disabled items to a "More..." menu:
+ if(!menuPopupMore) {
+ menuPopupMore = document.createElement('menupopup');
+ }
+ menuPopupMore.appendChild(menuitem);
+ }
+ }
+ if(menuPopupMore) {
+ if(!menupopup.hasChildNodes()) {
+ // All field rules of this profile are disabled, so no need to create a submenu:
+ while(menuPopupMore.hasChildNodes()) {
+ // appendChild removes the node from the current parent node
+ // and adds it to the new parent node:
+ menupopup.appendChild(menuPopupMore.firstChild);
+ }
+ } else {
+ // Append the "More..." menu:
+ var menuMore = document.createElement('menu');
+ menuMore.setAttribute('label', this.getStringBundle().getString('contextMenuMore'));
+ menuMore.appendChild(menuPopupMore);
+ menupopup.appendChild(menuMore);
+ }
+ }
+ // Reset object to release used memory:
+ this.fieldRules = null;
+ },
+
+ authenticateAndShowManualFillDialog: function(profileID) {
+ try {
+ Components.classes['@mozilla.org/security/pk11tokendb;1']
+ .getService(Components.interfaces.nsIPK11TokenDB).getInternalKeyToken().login(false);
+
+ var prompts = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+ .getService(Components.interfaces.nsIPromptService);
+ // The selection and the subselection lists:
+ var list = new Array();
+ var listMore;
+ // Hashs mapping the list positions to the original indices:
+ var listIndexMapping = new Object();;
+ var listMoreIndexMapping;
+ for(var i=0; i < this.getFieldRules(profileID).length; i++) {
+ if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
+ list.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
+ listIndexMapping[list.length-1] = i;
+ } else {
+ // Add disabled items to a "More..." list:
+ if(!listMore) {
+ listMore = new Array();
+ listMoreIndexMapping = new Object();
+ }
+ listMore.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
+ listMoreIndexMapping[listMore.length-1] = i;
+ }
+ }
+ if(listMore) {
+ // If all field rules of this profile are disabled, there is no need of a sublist:
+ if(!list.length) {
+ list = listMore;
+ listIndexMapping = listMoreIndexMapping;
+ listMore = null;
+ listMoreIndexMapping = null;
+ } else {
+ list.push(this.getStringBundle().getString('contextMenuMore'));
+ }
+ }
+ var selected = {};
+ var ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+ .getService(Components.interfaces.nsIPromptService)
+ .select(
+ window,
+ null, // Window title - defaults to locale version of "Select"
+ null, // Prompt text - defaults to empty string
+ list.length,
+ list,
+ selected
+ );
+ if(ok) {
+ // If "More..." is selected, show the disabled items as selection list:
+ if(listMore && selected.value == list.length-1) {
+ selected = {};
+ ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+ .getService(Components.interfaces.nsIPromptService)
+ .select(
+ window,
+ null, // Window title - defaults to locale version of "Select"
+ null, // Prompt text - defaults to empty string
+ listMore.length,
+ listMore,
+ selected
+ );
+ if(ok) {
+ this.fillTargetFormField(
+ profileID,
+ listMoreIndexMapping[selected.value]
+ );
+ }
+ } else {
+ this.fillTargetFormField(
+ profileID,
+ listIndexMapping[selected.value]
+ );
+ }
+ }
+ } catch(e) {
+ // Authentication with master security device failed
+ }
+ // Reset object to release used memory:
+ this.fieldRules = null;
+ },
+
+ fillTargetFormField: function(profileID, ruleID) {
+ if(this.targetFormField) {
+ var value = this.getFieldRules(profileID)[ruleID]['fieldRuleValue'];
+ // Replace dynamic tags if enabled:
+ if(this.autofillFormsPrefs.getBoolPref('enableDynamicTags')) {
+ value = this.replaceDynamicTags(value);
+ }
+ try {
+ // Try to use selection information:
+ var newCursorPos = this.targetFormField.selectionStart + value.length;
+ this.targetFormField.value = this.targetFormField.value.substr(0, this.targetFormField.selectionStart)
+ + value
+ + this.targetFormField.value.substr(this.targetFormField.selectionEnd);
+ // Adjust the cursor position:
+ this.targetFormField.selectionEnd = newCursorPos;
+ this.targetFormField.selectionStart = newCursorPos;
+ } catch(e) {
+ // This input field does not support selections - just try to set the value:
+ try {
+ this.targetFormField.value = value;
+ } catch(e) {
+ // Catch errors if value could not be set on the form field
+ }
+ }
+ // Reset objects to release used memory:
+ this.fieldRules = null;
+ this.dynamicTags = null;
+ this.dynamicTagCodes = null;
+ }
+ },
+
+ tooltip: function(event) {
+ if (!document.tooltipNode) {
+ return;
+ }
+ // Get the tooltip node:
+ var tooltip = document.getElementById('autofillFormsTooltip');
+ if(tooltip) {
+ // Add the associated tooltip content for each toolbar button menu item, toolbar button and statusbar icon:
+ if(document.tooltipNode.id == 'autofillFormsButton' || document.tooltipNode.id == 'autofillFormsPanelIcon') {
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+ this.profileLabels = null;
+ this.tooltipCurrentProfile = null;
+ }
+ if(!this.tooltipCurrentProfile || !this.tooltipGrid) {
+ // Remove all children nodes:
+ while(tooltip.hasChildNodes()) {
+ tooltip.removeChild(tooltip.firstChild);
+ }
+ // Add the current profile label:
+ tooltip.appendChild(this.getTooltipCurrentProfile());
+ // Add the tooltip grid with the command labels, mouse buttons and keyboard shortcuts:
+ tooltip.appendChild(this.getTooltipGrid());
+ }
+ } else {
+ // Don't show tooltips for the toolbar button menu items:
+ event.preventDefault();
+ }
+ }
+ },
+
+ getTooltipCurrentProfile: function() {
+ if(!this.tooltipCurrentProfile) {
+ var hbox = document.createElement('hbox');
+ hbox.setAttribute(
+ 'id',
+ 'autofillFormsTooltipCurrentProfile'
+ );
+ var label = document.createElement('label');
+ label.setAttribute(
+ 'value',
+ this.getStringBundle().getString('currentProfileLabel')
+ );
+ label.setAttribute(
+ 'id',
+ 'autofillFormsTooltipCurrentProfileCaption'
+ );
+ hbox.appendChild(label);
+ label = label.cloneNode(false);
+ label.setAttribute(
+ 'value',
+ this.getProfileLabel(this.getProfileIndex())
+ );
+ label.setAttribute(
+ 'id',
+ 'autofillFormsTooltipCurrentProfileLabel'
+ );
+ hbox.appendChild(label);
+ this.tooltipCurrentProfile = hbox;
+ }
+ return this.tooltipCurrentProfile;
+ },
+
+ getTooltipGrid: function() {
+ if(!this.tooltipGrid) {
+ var commands = new Array();
+ for(var property in this.shortcut) {
+ commands.push(new Array(
+ this.getStringBundle().getString('tooltip'+property.replace(/shortcut/,'')),
+ this.getFormattedMouseButton(this.getMouseButton('mouseS'+property.substr(1))),
+ this.getFormattedShortcut(this.getShortcut(property))
+ ));
+ }
+ var grid = document.createElement('grid');
+ grid.setAttribute(
+ 'id',
+ 'autofillFormsTooltipGrid'
+ );
+ var columns = document.createElement('columns');
+ var column = document.createElement('column');
+ var rows = document.createElement('rows');
+ var row = document.createElement('row');
+ var label = document.createElement('label');
+ columns.appendChild(column);
+ columns.appendChild(column.cloneNode(false));
+ columns.appendChild(column.cloneNode(false));
+ grid.appendChild(columns);
+ // Create the column headers:
+ label.setAttribute(
+ 'class',
+ 'autofillFormsTooltipGridHeader'
+ );
+ label.setAttribute(
+ 'value',
+ this.getStringBundle().getString('command')
+ );
+ row.appendChild(label);
+ label = label.cloneNode(false);
+ label.setAttribute(
+ 'value',
+ this.getStringBundle().getString('mousebutton')
+ );
+ row.appendChild(label);
+ label = label.cloneNode(false);
+ label.setAttribute(
+ 'value',
+ this.getStringBundle().getString('keyboardShortcut')
+ );
+ row.appendChild(label);
+ rows.appendChild(row);
+ // Create a row for each command:
+ for(var i=0; i<commands.length; i++) {
+ row = row.cloneNode(false);
+ // Skip if neither mouseButton nor keyboard shortcut is set:
+ if(!commands[i][1] && !commands[i][2]) {
+ continue;
+ }
+ for(var j=0; j<commands[i].length; j++) {
+ label = label.cloneNode(false);
+ label.setAttribute(
+ 'value',
+ commands[i][j]
+ );
+ if(j == 0) {
+ label.setAttribute(
+ 'class',
+ 'autofillFormsTooltipGridCommand'
+ );
+ } else if(j == 1) {
+ label.setAttribute(
+ 'class',
+ 'autofillFormsTooltipGridMouseButton'
+ );
+ } else {
+ label.setAttribute(
+ 'class',
+ 'autofillFormsTooltipGridKeyboardShortcut'
+ );
+ }
+ row.appendChild(label);
+ }
+ rows.appendChild(row);
+ }
+ grid.appendChild(rows);
+ this.tooltipGrid = grid;
+ }
+ return this.tooltipGrid;
+ },
+
+ resetAllProfiles: function() {
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('resetAllProfilesTitle'),
+ this.getStringBundle().getString('resetAllProfilesText')
+ )
+ ) {
+ return;
+ }
+ }
+
+ // Reset the user preferences:
+ if(this.autofillFormsPrefs.prefHasUserValue('useConfigDirectory')) {
+ this.autofillFormsPrefs.clearUserPref('useConfigDirectory');
+ }
+ if(this.autofillFormsPrefs.prefHasUserValue('storeEncrypted')) {
+ this.autofillFormsPrefs.clearUserPref('storeEncrypted');
+ }
+ if(this.autofillFormsPrefs.prefHasUserValue('profileIndex')) {
+ this.autofillFormsPrefs.clearUserPref('profileIndex');
+ }
+ if(this.autofillFormsPrefs.prefHasUserValue('profileLabels')) {
+ this.autofillFormsPrefs.clearUserPref('profileLabels');
+ }
+ if(this.autofillFormsPrefs.prefHasUserValue('profileSiteRules')) {
+ this.autofillFormsPrefs.clearUserPref('profileSiteRules');
+ }
+ if(this.autofillFormsPrefs.prefHasUserValue('fieldRules')) {
+ this.autofillFormsPrefs.clearUserPref('fieldRules');
+ }
+
+ this.profileIndex = null;
+ this.profileLabels = null;
+ this.profileSiteRules = null;
+ this.fieldRules = null;
+
+ // Re-init the profiles lists:
+ this.initProfilesLists();
+ // Re-init the fieldRules tree:
+ this.initTree();
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+
+ if(this.tree && this.selection) {
+ try {
+ // Clear out the fieldRules tree selections
+ this.selection.select(-1);
+ } catch(e) {
+ this.log(e);
+ }
+ }
+ },
+
+ initProfilesLists: function(event) {
+ // The profiles tree:
+ this.initProfilesTree();
+
+ // Editable profiles menu list:
+ var profilesMenuList = document.getElementById('profilesMenuList');
+ if(profilesMenuList) {
+ profilesMenuList.removeAllItems();
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ profilesMenuList.appendItem(
+ this.getProfileLabel(i)
+ );
+ }
+ profilesMenuList.selectedIndex = this.getProfileIndex();
+ }
+ // Simple interface profiles menu list:
+ var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+ if(simpleInterfaceProfileMenuList) {
+ simpleInterfaceProfileMenuList.removeAllItems();
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ simpleInterfaceProfileMenuList.appendItem(
+ this.getProfileLabel(i)
+ );
+ }
+ simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
+ }
+ // Global profile selection:
+ var globalProfileMenuList = document.getElementById('globalProfileMenuList');
+ if(globalProfileMenuList) {
+ globalProfileMenuList.removeAllItems();
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ globalProfileMenuList.appendItem(
+ this.getProfileLabel(i)
+ );
+ }
+ globalProfileMenuList.selectedIndex = this.getGlobalProfileIndex();
+ }
+ // Form fields context menu selection:
+ var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
+ if(contextMenuProfileMenuList) {
+ // The first 3 items are "All profiles", "Active profile" and a menuseparator:
+ while(contextMenuProfileMenuList.firstChild.childNodes[3]) {
+ // The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
+ // so we use DOM methods on the menupopup child node of the menu node instead:
+ contextMenuProfileMenuList.firstChild.removeChild(
+ contextMenuProfileMenuList.firstChild.childNodes[3]
+ );
+ }
+ for(var i=0; i < this.getProfileLabels().length; i++) {
+ contextMenuProfileMenuList.appendItem(
+ this.getProfileLabel(i)
+ );
+ }
+ contextMenuProfileMenuList.selectedIndex
+ = this.getFormFieldsContextMenuProfileIndex()+3;
+ }
+
+ // The profile site rule textbox:
+ this.initProfileSiteRuleTextBox();
+ },
+
+ updateProfilesLists: function() {
+ // The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
+ // so we use DOM methods on the menupopup child node of the menu nodes instead:
+
+ // Editable profiles menu list:
+ var profilesMenuList = document.getElementById('profilesMenuList');
+ if(profilesMenuList) {
+ profilesMenuList
+ .firstChild.childNodes[this.getProfileIndex()].label
+ = this.getProfileLabel(this.getProfileIndex());
+ }
+ // Simple interface profiles menu list:
+ var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+ if(simpleInterfaceProfileMenuList) {
+ simpleInterfaceProfileMenuList
+ .firstChild.childNodes[this.getProfileIndex()].label
+ = this.getProfileLabel(this.getProfileIndex());
+ }
+ // Global profile selection:
+ var globalProfileMenuList = document.getElementById('globalProfileMenuList');
+ if(globalProfileMenuList) {
+ globalProfileMenuList
+ .firstChild.childNodes[this.getProfileIndex()].label
+ = this.getProfileLabel(this.getProfileIndex());
+ }
+ // Form fields context menu selection:
+ var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
+ if(contextMenuProfileMenuList) {
+ // The first 3 items are "All profiles", "Active profile" and a menuseparator:
+ contextMenuProfileMenuList
+ .firstChild.childNodes[this.getProfileIndex()+3].label
+ = this.getProfileLabel(this.getProfileIndex());
+ }
+ // The profiles tree:
+ if(this.profilesTreeBox) {
+ this.profilesTreeBox.invalidateRow(this.getProfileIndex());
+ }
+ },
+
+ getProfileIndex: function() {
+ if(this.profileIndex == null)
+ this.profileIndex = this.autofillFormsPrefs.getIntPref('profileIndex');
+ return this.profileIndex;
+ },
+
+ setProfileIndex: function(index) {
+ if(this.profileIndex == index)
+ return;
+
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ this.autofillFormsPrefs.setIntPref('profileIndex',parseInt(index));
+ // Update the tree view if present:
+ if(this.tree) {
+ // The settings page doesn't observe preferences changes - set the profileIndex manually:
+ this.profileIndex = index;
+ // Re-init the tree:
+ this.initTree();
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ }
+ // Update the profiles tree selection if present and not already updated:
+ if(this.profilesTree && this.profilesSelection.currentIndex != index) {
+ // Select the current profile:
+ this.profilesSelection.select(index);
+
+ // Ensure row is visible (scrolls if not):
+ this.profilesTreeBox.ensureRowIsVisible(index);
+ }
+ // Editable profiles menu list:
+ var profilesMenuList = document.getElementById('profilesMenuList');
+ if(profilesMenuList) {
+ profilesMenuList.selectedIndex = this.getProfileIndex();
+ }
+ // Simple interface profiles menu list:
+ var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+ if(simpleInterfaceProfileMenuList) {
+ simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
+ }
+
+ // The profile site rule textbox:
+ this.initProfileSiteRuleTextBox();
+ },
+
+ getGlobalProfileIndex: function() {
+ if(this.globalProfileIndex == null) {
+ this.globalProfileIndex = this.autofillFormsPrefs.getIntPref('globalProfileIndex');
+ }
+ return this.globalProfileIndex;
+ },
+
+ setGlobalProfileIndex: function(index) {
+ if(this.globalProfileIndex == index) {
+ return;
+ }
+ this.autofillFormsPrefs.setIntPref('globalProfileIndex',parseInt(index));
+ // The settings page doesn't observe preferences changes - set the profileIndex manually:
+ this.globalProfileIndex = index;
+ },
+
+ getFormFieldsContextMenuProfileIndex: function() {
+ if(this.formFieldsContextMenuProfileIndex == null) {
+ this.formFieldsContextMenuProfileIndex
+ = this.autofillFormsPrefs.getIntPref('formFieldsContextMenuProfileIndex');
+ }
+ return this.formFieldsContextMenuProfileIndex;
+ },
+
+ setFormFieldsContextMenuProfileIndex: function(index) {
+ if(this.formFieldsContextMenuProfileIndex == index) {
+ return;
+ }
+ this.autofillFormsPrefs.setIntPref('formFieldsContextMenuProfileIndex',parseInt(index));
+ // The settings page doesn't observe preferences changes - set the profileIndex manually:
+ this.formFieldsContextMenuProfileIndex = index;
+ },
+
+ getProfileLabelsFile: function() {
+ var file = this.getConfigDirectory();
+ file.append('profileLabels.txt');
+ if(!file.exists()) {
+ file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+ }
+ return file;
+ },
+
+ exportProfileLabelsToConfigDirectory: function() {
+ var prefString;
+ // Get the profileLabels string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ if(prefString) {
+ this.setFileContent(this.getProfileLabelsFile(), prefString);
+ }
+ },
+
+ importProfileLabelsFromConfigDirectory: function() {
+ var prefString;
+ prefString = this.getFileContent(this.getProfileLabelsFile());
+ if(prefString) {
+ // Store the profileLabels as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'profileLabels',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getProfileLabels: function() {
+ if(this.profileLabels == null) {
+ var prefString;
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Get the profileLabels string from the profileLabels file in the configDirectory:
+ prefString = this.getFileContent(this.getProfileLabelsFile());
+ }
+ if(!prefString) {
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ }
+ // The profile labels are stored as a string with tabs as separators:
+ this.profileLabels = prefString.split('\t');
+ }
+ return this.profileLabels;
+ },
+
+ setProfileLabels: function(profileLabels) {
+ // Save the profile labels separated by tabs:
+ var prefString = profileLabels.join('\t');
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.setFileContent(this.getProfileLabelsFile(), prefString);
+ } else {
+ this.autofillFormsPrefs.setComplexValue(
+ 'profileLabels',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getProfileLabel: function(index) {
+ while(this.getProfileLabels().length <= index) {
+ this.getProfileLabels().push(this.getUniqueProfileLabel());
+ }
+ return this.getProfileLabels()[index];
+ },
+
+ setProfileLabel: function(index, label) {
+ while(this.getProfileLabels().length <= index) {
+ this.getProfileLabels().push(this.getUniqueProfileLabel());
+ }
+ this.getProfileLabels()[index] = label;
+ // Save the profileLabels list in the preferences:
+ this.setProfileLabels(this.getProfileLabels());
+ },
+
+ getUniqueProfileLabel: function(profileLabel) {
+ if(!profileLabel) {
+ profileLabel = 'Profile';
+ }
+
+ // Make sure the profile label is unique:
+ if(!this.inArray(this.getProfileLabels(), profileLabel)) {
+ return profileLabel;
+ }
+ var i = profileLabel.lastIndexOf(' ');
+ var n = parseInt(profileLabel.substr(i+2));
+ if(isNaN(n)) {
+ return this.getUniqueProfileLabel(profileLabel+' (2)');
+ }
+ n++;
+ profileLabel = profileLabel.substr(0, i)+' ('+n+')';
+ return this.getUniqueProfileLabel(profileLabel);
+ },
+
+ changeProfileLabel: function(newProfileLabel) {
+ var profilesMenuList = document.getElementById('profilesMenuList');
+ if(profilesMenuList) {
+ // Make sure the new profile label is safe and unique:
+ newProfileLabel = this.getUniqueProfileLabel(this.makeSafe(newProfileLabel));
+ // Update the label of the selected profile:
+ this.setProfileLabel(this.getProfileIndex(), newProfileLabel);
+ // Update the profiles textbox contents:
+ profilesMenuList.inputField.value = newProfileLabel;
+ document.getElementById('profileLabelTextBox').value = newProfileLabel;
+ // Update the profiles lists:
+ this.updateProfilesLists();
+ }
+ },
+
+ initProfileSiteRuleTextBox: function(event) {
+ var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
+ if(profileSiteRuleTextBox) {
+ profileSiteRuleTextBox.value = this.getProfileSiteRule(this.getProfileIndex());
+ }
+ },
+
+ changeProfileSiteRule: function(siteRule) {
+ var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
+ if(profileSiteRuleTextBox) {
+ // Check the regular expression before updating the profile site rules:
+ try {
+ siteRule = this.getRegExpStr(
+ this.makeSafe(siteRule)
+ );
+ profileSiteRuleTextBox.value = siteRule;
+ document.getElementById('profileSiteRuleTextBox2').value = siteRule;
+
+ var newProfileSiteRules = this.getProfileSiteRules();
+ newProfileSiteRules[this.getProfileIndex()] = siteRule;
+ this.setProfileSiteRules(newProfileSiteRules);
+
+ // Update the profiles tree:
+ if(this.profilesTreeBox) {
+ this.profilesTreeBox.invalidateRow(this.getProfileIndex());
+ }
+ } catch(e) {
+ this.invalidRegExpAlert(e);
+ }
+ }
+ },
+
+ getProfileSiteRulesFile: function() {
+ var file = this.getConfigDirectory();
+ file.append('profileSiteRules.txt');
+ if(!file.exists()) {
+ file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+ }
+ return file;
+ },
+
+ exportProfileSiteRulesToConfigDirectory: function() {
+ var prefString;
+ // Get the profileSiteRules string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
+ .data;
+ if(prefString) {
+ this.setFileContent(this.getProfileSiteRulesFile(), prefString);
+ }
+ },
+
+ importProfileSiteRulesFromConfigDirectory: function() {
+ var prefString;
+ prefString = this.getFileContent(this.getProfileSiteRulesFile());
+ if(prefString) {
+ // Store the profileSiteRules as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'profileSiteRules',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getProfileSiteRules: function() {
+ if(this.profileSiteRules == null) {
+ var prefString;
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Get the profileSiteRules string from the profileSiteRules file in the configDirectory:
+ prefString = this.getFileContent(this.getProfileSiteRulesFile());
+ }
+ if(!prefString) {
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
+ .data;
+ }
+ // The profile SiteRules are stored as a string with tabs as separators:
+ this.profileSiteRules = prefString.split('\t');
+ }
+ return this.profileSiteRules;
+ },
+
+ setProfileSiteRules: function(profileSiteRules) {
+ // Save the profile SiteRules separated by tabs:
+ var prefString = profileSiteRules.join('\t');
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.setFileContent(this.getProfileSiteRulesFile(), prefString);
+ } else {
+ this.autofillFormsPrefs.setComplexValue(
+ 'profileSiteRules',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getProfileSiteRule: function(index) {
+ while(this.getProfileSiteRules().length <= index) {
+ this.getProfileSiteRules().push('(?:)');
+ }
+ return this.getProfileSiteRules()[index];
+ },
+
+ setProfileSiteRule: function(index, siteRule) {
+ while(this.getProfileSiteRules().length <= index) {
+ this.getProfileSiteRules().push('(?:)');
+ }
+ this.getProfileSiteRules()[index] = siteRule;
+ // Save the profileSiteRules in the preferences:
+ this.setProfileSiteRules(this.getProfileSiteRules());
+ },
+
+ addFormAsProfile: function(event) {
+ if(this.targetFormField && this.targetFormField.form) {
+ var elements = this.targetFormField.form.elements;
+ var doc = this.targetFormField.form.ownerDocument;
+
+ var newProfile = new Array();
+
+ // Go through the form elements:
+ for(var i=0; i<elements.length; i++) {
+ // Only use valid form fields:
+ if(this.isValidFormField(elements[i])) {
+ var value;
+ var overwrite = true;
+
+ // Create the fieldRule (from name, label or id):
+ var fieldRule = this.getFieldRuleForElement(elements[i]);
+
+ switch(elements[i].type) {
+ case 'checkbox':
+ // Add a rule to uncheck the checkbox if it is unchecked:
+ if(!elements[i].checked) {
+ overwrite = false;
+ }
+ value = this.getRegExpStrForValue(elements[i].value);
+ break;
+ case 'radio':
+ // Only add checked radio buttons:
+ if(!elements[i].checked) {
+ continue;
+ }
+ value = this.getRegExpStrForValue(elements[i].value);
+ break;
+ case 'select-one':
+ value = this.getRegExpStrForValue(elements[i].value);
+ break;
+ case 'select-multiple':
+ var fieldRuleLabel = this.makeSafe(this.getFieldRuleNameForElement(elements[i]));
+ // Add all options as fieldRules, set "overwrite" to true if selected:
+ for(var j = 0; j < elements[i].options.length; j++) {
+ newProfile.push(
+ this.createFieldRule(
+ fieldRuleLabel+' ('+j+')',
+ this.getRegExpStrForValue(elements[i].options[j].value),
+ fieldRule,
+ '(?:)',
+ elements[i].options[j].selected,
+ true
+ )
+ );
+ }
+ continue;
+ default:
+ value = this.makeSafe(this.replaceControlCharacters(elements[i].value));
+ break;
+ }
+
+ // Add the current element as new rule to the profile list:
+ newProfile.push(
+ this.createFieldRule(
+ this.makeSafe(this.getFieldRuleNameForElement(elements[i])),
+ value,
+ fieldRule,
+ '(?:)',
+ overwrite,
+ true
+ )
+ );
+ }
+ }
+
+ // Initialize the fieldRules:
+ this.getFieldRules();
+
+ // Add the new profile to the fieldRules:
+ this.fieldRules.push(newProfile);
+ // Save the profiles in the preferences:
+ this.setFieldRules();
+
+ // Add a label for default empty profile:
+ if(this.getProfileLabels().length == 0) {
+ this.getProfileLabels().push(this.getUniqueProfileLabel());
+ }
+ // Use the documents hostname as profile label and add it to the profile labels list:
+ this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(doc.location.host)));
+ // Save the profileLabels list in the preferences:
+ this.setProfileLabels(this.getProfileLabels());
+
+ // Use the protocol and domain of the web form as profile siteRule:
+ this.getProfileSiteRules().push(this.getSiteRuleForURL(doc.location.protocol+'//'+doc.location.host));
+ // Save the profileSiteRules in the preferences:
+ this.setProfileSiteRules(this.getProfileSiteRules());
+
+ // Save the the new profile index as selected profileIndex:
+ this.setProfileIndex(this.getProfileLabels().length-1);
+
+ // Reset the target form field:
+ this.targetFormField = null;
+
+ // Create parameters for the settings page:
+ var params = new Object();
+ params.newProfileFromForm = true;
+
+ // Open up the settings page:
+ this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul', params);
+ }
+ },
+
+ addProfile: function(newProfileLabel) {
+ // Duplicate the selected profile (do a deep copy):
+ this.fieldRules.push(
+ this.copyFieldRules(this.getFieldRules())
+ );
+ // Save the profiles in the preferences:
+ this.setFieldRules();
+ // Add profile label for default empty profile:
+ if(this.getProfileLabels().length == 0) {
+ this.getProfileLabels().push(this.getUniqueProfileLabel());
+ }
+ // Add the (unique) newProfileLabel to the profileLabels list:
+ this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(newProfileLabel)));
+ // Save the profileLabels list in the preferences:
+ this.setProfileLabels(this.getProfileLabels());
+ // Add a new empty profileSiteRule:
+ this.getProfileSiteRules().push('(?:)');
+ // Save the profileSiteRules in the preferences:
+ this.setProfileSiteRules(this.getProfileSiteRules());
+ // Save the the new profile index as selected profileIndex:
+ this.setProfileIndex(this.getProfileLabels().length-1);
+ // Update the profiles lists:
+ this.initProfilesLists();
+ // Re-init the fieldRules tree:
+ this.initTree();
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ },
+
+ removeProfile: function(event) {
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('removeProfileTitle'),
+ this.getStringBundle().getString('removeProfileText')
+ )
+ ) {
+ return;
+ }
+ }
+
+ // Remove the selected profile from the list:
+ this.fieldRules.splice(this.getProfileIndex(),1);
+ // Save the profiles in the preferences:
+ this.setFieldRules();
+ // Remove the selected profile from the profileLabels list:
+ this.getProfileLabels().splice(this.getProfileIndex(),1);
+ // Save the profileLabels list in the preferences:
+ this.setProfileLabels(this.getProfileLabels());
+ // Remove the selected profile's siteRule:
+ this.getProfileSiteRules().splice(this.getProfileIndex(),1);
+ // Save the profileSiteRules in the preferences:
+ this.setProfileSiteRules(this.getProfileSiteRules());
+ // Adjust the profileIndex if the last profile on the list has been deleted:
+ if(this.getProfileIndex()+1 > this.fieldRules.length) {
+ var newIndex = this.fieldRules.length>0 ? this.fieldRules.length-1 : 0;
+ this.setProfileIndex(newIndex);
+ }
+ // Update the profiles lists:
+ this.initProfilesLists();
+ // Re-init the tree:
+ this.initTree();
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ },
+
+ createFieldRule: function(name,value,fieldRule,siteRule,overwrite,enabled) {
+ var rule = new Object();
+ rule['fieldRuleName'] = name;
+ rule['fieldRuleValue'] = value;
+ rule['fieldRuleFieldRule'] = fieldRule;
+ rule['fieldRuleSiteRule'] = siteRule;
+ rule['fieldRuleOverwrite'] = overwrite;
+ rule['fieldRuleEnabled'] = enabled;
+ return rule;
+ },
+
+ getRegExpPasswordLabel: function() {
+ if(!arguments.callee.regExpPass) {
+ arguments.callee.regExpPass = new RegExp(
+ this.autofillFormsPrefs
+ .getComplexValue('regExpPasswordLabel',Components.interfaces.nsIPrefLocalizedString)
+ .data,
+ 'i');
+ }
+ return arguments.callee.regExpPass;
+ },
+
+ initTree: function() {
+ // Get the tree:
+ this.tree = document.getElementById('fieldRulesTree');
+
+ if(this.tree) {
+
+ // Implement the TreeView interface:
+ this.treeView = {
+ rowCount: 0,
+ setTree: function(tree){},
+ getImageSrc: function(row,column) {},
+ getProgressMode: function(row,column) {},
+ getCellValue: function(row,column) {
+ var rowObj = this.parent.getFieldRules()[row];
+ if(rowObj) {
+ return rowObj[column.id];
+ }
+ },
+ getCellText: function(row,column){
+ var rowObj = this.parent.getFieldRules()[row];
+ if(rowObj) {
+ if(column.id=='fieldRuleValue' &&
+ this.parent.getRegExpPasswordLabel().test(rowObj['fieldRuleName'])) {
+ // Show passwords as asterisks:
+ return rowObj[column.id].replace(/./g, '*');
+ } else {
+ return rowObj[column.id];
+ }
+ }
+ return '';
+ },
+ isEditable: function(row,column){
+ // Only checkbox columns are editable:
+ if(column.id=='fieldRuleOverwrite' || column.id=='fieldRuleEnabled')
+ return true;
+ else
+ return false;
+ },
+ setCellValue: function(row,column,value){
+ var rowObj = this.parent.getFieldRules()[row];
+ if(rowObj) {
+ rowObj[column.id] = value;
+ // Notify the tree:
+ this.parent.treeBox.invalidateRow(row);
+ // Update the preferences:
+ this.parent.setFieldRules();
+ // Update the simple interface (add/remove enabled/disabled rules):
+ if(column.id=='fieldRuleEnabled') {
+ if(value == 'true') {
+ this.parent.addSimpleInterfaceRow(row);
+ } else {
+ this.parent.removeSimpleInterfaceRow(row);
+ }
+ }
+ }
+ },
+ isSeparator: function(index) {return false;},
+ isSorted: function() {return false;},
+ isContainer: function(index) {return false;},
+ cycleHeader: function(column) {},
+ getRowProperties: function(row,prop){},
+ getColumnProperties: function(column,prop){},
+ getCellProperties: function(row,column,prop){},
+ getParentIndex: function(index) {return -1}
+ };
+ // Set the autofillForms object as parent:
+ this.treeView.parent = this;
+
+ // Set the tree length using the fieldRules list length:
+ this.treeView.rowCount = this.getFieldRules().length;
+
+ // Assign the treeview:
+ this.tree.view = this.treeView;
+
+ // The TreeSelection object:
+ this.selection = this.tree.view.selection;
+
+ // The TreeBox object:
+ this.treeBox = this.tree.treeBoxObject;
+ }
+ },
+
+ sortFieldRules: function(event) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('sortFieldRulesTitle'),
+ this.getStringBundle().getString('sortFieldRulesText')
+ )
+ ) {
+ return;
+ }
+ }
+
+ // Get the id of the column:
+ var id = event.target.id;
+
+ // Helper function to sort the fieldRules objects:
+ function customSort(a,b) {
+ // This enables comparison of boolean true and false:
+ var x = a[id].toString();
+ var y = b[id].toString();
+
+ if(x > y) return 1;
+ if(x < y) return -1;
+ return 0;
+ }
+
+ // Sort the form field rules using the helper function:
+ this.getFieldRules().sort(customSort);
+
+ // Change sort direction for next click:
+ if(this.ascending) {
+ this.ascending = false;
+ } else {
+ this.getFieldRules().reverse();
+ this.ascending = true;
+ }
+
+ // Notify the tree:
+ this.treeBox.invalidate();
+
+ // Clear out selections
+ this.selection.select(-1);
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ },
+
+ selectedFieldRule: function(event) {
+ if(this.selection.currentIndex == -1) {
+ // Disable buttons:
+ document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'true');
+ document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
+ document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
+
+ this.lastSelectedIndex = null;
+ } else if(this.selection.count == 1) {
+ // The onchange event (as well as onblur, etc.) of the textboxes seems to be ignored if a new item is selected,
+ // so we try and apply the field rules of the last element (if changed):
+ if(this.lastSelectedIndex !== null) {
+ this.applyFieldRuleOnIndex(this.lastSelectedIndex);
+ }
+
+ // Update the textboxes with the selected fieldRule:
+ var index = this.selection.currentIndex;
+ document.getElementById('fieldRuleNameTextBox').value = this.getFieldRules()[index]['fieldRuleName'];
+ document.getElementById('fieldRuleValueTextBox').value = this.getFieldRules()[index]['fieldRuleValue'];
+ document.getElementById('fieldRuleFieldRuleTextBox').value = this.getFieldRules()[index]['fieldRuleFieldRule'];
+ document.getElementById('fieldRuleSiteRuleTextBox').value = this.getFieldRules()[index]['fieldRuleSiteRule'];
+
+ // Enable/Disable buttons:
+ document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
+ document.getElementById('buttonMoveUpFieldRule').setAttribute(
+ 'disabled',
+ (index == 0)
+ );
+ document.getElementById('buttonMoveDownFieldRule').setAttribute(
+ 'disabled',
+ (index == this.getFieldRules().length-1)
+ );
+
+ // Save the last selected index and reset it to null for any other action than just a single selection:
+ this.lastSelectedIndex = index;
+ } else if(this.selection.count > 1) {
+ // Enable/Disable buttons:
+ document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
+ document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
+ document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
+
+ this.lastSelectedIndex = null;
+ }
+ },
+
+ initProfilesTree: function() {
+ this.profilesTree = document.getElementById('profilesTree');
+ if(this.profilesTree) {
+
+ // Implement the profiles TreeView interface:
+ this.profilesTreeView = {
+ rowCount: 0,
+ setTree: function(tree){},
+ getImageSrc: function(row,column) {},
+ getProgressMode: function(row,column) {},
+ getCellValue: function(row,column) {
+ if(column.id=='profilesTreeColName') {
+ return this.parent.getProfileLabel(row);
+ } else {
+ return this.parent.getProfileSiteRule(row);
+ }
+ },
+ getCellText: function(row,column){
+ if(column.id=='profilesTreeColName') {
+ return this.parent.getProfileLabel(row);
+ } else {
+ return this.parent.getProfileSiteRule(row);
+ }
+ },
+ isEditable: function(row,column){return false;},
+ setCellValue: function(row,column,value){},
+ isSeparator: function(index) {return false;},
+ isSorted: function() {return false;},
+ isContainer: function(index) {return false;},
+ cycleHeader: function(column) {},
+ getRowProperties: function(row,prop){},
+ getColumnProperties: function(column,prop){},
+ getCellProperties: function(row,column,prop){},
+ getParentIndex: function(index) {return -1}
+ };
+ // Set the autofillForms object as parent:
+ this.profilesTreeView.parent = this;
+
+ // Seems like we need to reset these arrays to have a consistens UI:
+ this.profileLabels = null;
+ this.profileSiteRules = null;
+
+ // Set the tree length using the profiles labels list length:
+ this.profilesTreeView.rowCount = this.getProfileLabels().length;
+
+ // Assign the treeview:
+ this.profilesTree.view = this.profilesTreeView;
+
+ // The TreeSelection object:
+ this.profilesSelection = this.profilesTree.view.selection;
+
+ // The TreeBox object:
+ this.profilesTreeBox = this.profilesTree.treeBoxObject;
+
+ // Select the current profile:
+ this.profilesSelection.select(this.getProfileIndex());
+
+ // Ensure row is visible (scrolls if not):
+ this.profilesTreeBox.ensureRowIsVisible(this.getProfileIndex());
+ }
+ },
+
+ selectedProfile: function(event) {
+ var index = this.profilesSelection.currentIndex;
+ if(index != -1) {
+ this.setProfileIndex(index);
+
+ if(index > 0) {
+ document.getElementById('buttonMoveUpProfile').disabled = false;
+ } else {
+ document.getElementById('buttonMoveUpProfile').disabled = true;
+ }
+ if(index+1 < this.getProfileLabels().length) {
+ document.getElementById('buttonMoveDownProfile').disabled = false;
+ } else {
+ document.getElementById('buttonMoveDownProfile').disabled = true;
+ }
+
+ if(document.getElementById('profileLabelTextBox')) {
+ document.getElementById('profileLabelTextBox').value = this.getProfileLabel(this.getProfileIndex());
+ }
+ if(document.getElementById('profileSiteRuleTextBox2')) {
+ document.getElementById('profileSiteRuleTextBox2').value = this.getProfileSiteRule(this.getProfileIndex());
+ }
+ } else {
+ document.getElementById('buttonMoveUpProfile').disabled = true;
+ document.getElementById('buttonMoveDownProfile').disabled = true;
+ }
+ },
+
+ moveUpProfile: function(event) {
+ var tmpProfile = this.getFieldRules(this.getProfileIndex()-1);
+ this.fieldRules[this.getProfileIndex()-1] = this.getFieldRules(this.getProfileIndex());
+ this.fieldRules[this.getProfileIndex()] = tmpProfile;
+ this.setFieldRules();
+
+ var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()-1);
+ this.getProfileLabels()[this.getProfileIndex()-1] = this.getProfileLabel(this.getProfileIndex());
+ this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
+ this.setProfileLabels(this.getProfileLabels());
+
+ var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()-1);
+ this.getProfileSiteRules()[this.getProfileIndex()-1] = this.getProfileSiteRule(this.getProfileIndex());
+ this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
+ this.setProfileSiteRules(this.getProfileSiteRules());
+
+ this.setProfileIndex(this.getProfileIndex()-1);
+
+ this.initProfilesLists();
+ },
+
+ moveDownProfile: function(event) {
+ var tmpProfile = this.getFieldRules(this.getProfileIndex()+1);
+ this.fieldRules[this.getProfileIndex()+1] = this.getFieldRules(this.getProfileIndex());
+ this.fieldRules[this.getProfileIndex()] = tmpProfile;
+ this.setFieldRules();
+
+ var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()+1);
+ this.getProfileLabels()[this.getProfileIndex()+1] = this.getProfileLabel(this.getProfileIndex());
+ this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
+ this.setProfileLabels(this.getProfileLabels());
+
+ var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()+1);
+ this.getProfileSiteRules()[this.getProfileIndex()+1] = this.getProfileSiteRule(this.getProfileIndex());
+ this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
+ this.setProfileSiteRules(this.getProfileSiteRules());
+
+ this.setProfileIndex(this.getProfileIndex()+1);
+
+ this.initProfilesLists();
+ },
+
+ sortProfiles: function(event) {
+ var newSelectedIndex = this.getProfileIndex();
+ var fieldArray = this.getFieldsArray();
+ var oldIndex;
+
+ switch(event.target.id) {
+ case 'profilesTreeColName':
+ //Sort by Profile Label
+ fieldArray.sort(function (a, b) {
+ if (a[1] == b[1]) {
+ return 0;
+ }
+ if (a[1] < b[1]) {
+ return -1;
+ }
+ return 1;
+ });
+ if (!this.profilesAscending) {
+ fieldArray.reverse();
+ }
+ for(var i=0; i<this.getProfileLabels().length; i++) {
+ oldIndex = fieldArray[i][0];
+ if(oldIndex == this.getProfileIndex()) {
+ newSelectedIndex = i;
+ }
+ this.getProfileLabels()[i] = fieldArray[i][1];
+ this.getProfileSiteRules()[i] = fieldArray[i][2];
+ this.fieldRules[i] = fieldArray[i][3];
+ }
+ break;
+
+ case 'profilesTreeColSiteRule':
+ //Sort by Profile Site Rule
+ fieldArray.sort(function (a, b) {
+ if (a[2] == b[2]) {
+ return 0;
+ }
+ if (a[2] < b[2]) {
+ return -1;
+ }
+ return 1;
+ });
+ if (!this.profilesAscending) {
+ fieldArray.reverse();
+ }
+ for(var i=0; i<this.getProfileLabels().length; i++) {
+ oldIndex = fieldArray[i][0];
+ if(oldIndex == this.getProfileIndex()) {
+ newSelectedIndex = i;
+ }
+ this.getProfileLabels()[i] = fieldArray[i][1];
+ this.getProfileSiteRules()[i] = fieldArray[i][2];
+ this.fieldRules[i] = fieldArray[i][3];
+ }
+ break;
+ }
+ // Change sort direction for next click:
+ this.profilesAscending = !this.profilesAscending;
+
+ this.setFieldRules();
+ this.setProfileLabels(this.getProfileLabels());
+ this.setProfileSiteRules(this.getProfileSiteRules());
+
+ this.setProfileIndex(newSelectedIndex);
+
+ this.initProfilesLists();
+ },
+ getFieldsArray: function() {
+ // This creates an array of [i, ProfileLabel, ProfileSiteRule, fieldRules] rows
+ // we can then sort by rows[1] or rows[2] and store the row elements back in
+ // their respective arrays.
+ var row;
+ var fieldArray = new Array();
+ var tmpProfileLabels = this.getProfileLabels().slice(0);
+ var tmpProfileSiteRules = this.getProfileSiteRules().slice(0);
+
+ for(var i=0; i<this.getProfileSiteRules().length; i++) {
+ row = new Array();
+ row.push(i);
+ row.push(tmpProfileLabels[i]);
+ row.push(tmpProfileSiteRules[i]);
+ row.push(this.getFieldRules(i));
+ fieldArray.push(row);
+ }
+ return fieldArray;
+ },
+ profilesTreeHandleKeyPress: function(event) {
+ if(event.keyCode == 46) {
+ this.removeProfile();
+ }
+ },
+
+ invalidRegExpAlert: function(error) {
+ // Invalid regular expression alert:
+ this.getPrompts().alert(
+ null,
+ this.getStringBundle().getString('invalidRegExpTitle'),
+ this.getStringBundle().getString('invalidRegExpText') + "\n\n" + error
+ );
+ },
+
+ makeSafe: function(str) {
+ // Remove all tabs and linefeeds from the given string
+ // (these are used as separators):
+ return str.replace(/\t|\n/g, '');
+ },
+
+ replaceControlCharacters: function(str) {
+ return str.replace(
+ /\n|\t/g,
+ this.replaceControlCharactersCallback
+ );
+ },
+
+ replaceControlCharactersCallback: function(str) {
+ switch(str) {
+ case "\n":
+ return autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak');
+ case "\t":
+ return ' ';
+ default:
+ return str;
+ }
+ },
+
+ replaceControlCharacterPlaceholders: function(str) {
+ try {
+ var regExpObj = new RegExp(
+ '('
+ +this.autofillFormsPrefs.getCharPref('placeholderLineBreak')
+ +')|('
+ +this.autofillFormsPrefs.getCharPref('placeholderTab')
+ +')',
+ 'g'
+ );
+ return str.replace(
+ regExpObj,
+ this.replaceControlCharacterPlaceholdersCallback
+ );
+ } catch(e) {
+ return str;
+ }
+ },
+
+ replaceControlCharacterPlaceholdersCallback: function(str) {
+ switch(str) {
+ case autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak'):
+ return "\n";
+ case autofillForms.autofillFormsPrefs.getCharPref('placeholderTab'):
+ return "\t";
+ default:
+ return str;
+ }
+ },
+
+ applyFieldRuleOnIndex: function(index) {
+ // Check the regular expressions:
+ try {
+ var fieldRule = this.getRegExpStr(
+ this.makeSafe(document.getElementById('fieldRuleFieldRuleTextBox').value)
+ );
+ document.getElementById('fieldRuleFieldRuleTextBox').value = fieldRule;
+
+ var siteRule = this.getRegExpStr(
+ this.makeSafe(document.getElementById('fieldRuleSiteRuleTextBox').value)
+ );
+ document.getElementById('fieldRuleSiteRuleTextBox').value = siteRule;
+ } catch(e) {
+ this.invalidRegExpAlert(e);
+ return;
+ }
+
+ var ruleName = this.makeSafe(document.getElementById('fieldRuleNameTextBox').value);
+ var ruleValue = this.makeSafe(document.getElementById('fieldRuleValueTextBox').value);
+
+ if( this.getFieldRules()[index] && (
+ this.getFieldRules()[index]['fieldRuleName'] != ruleName ||
+ this.getFieldRules()[index]['fieldRuleValue'] != ruleValue ||
+ this.getFieldRules()[index]['fieldRuleFieldRule'] != fieldRule ||
+ this.getFieldRules()[index]['fieldRuleSiteRule'] != siteRule)) {
+ // Update the formFieldRule on the given index:
+ this.getFieldRules()[index]['fieldRuleName'] = ruleName;
+ this.getFieldRules()[index]['fieldRuleValue'] = ruleValue;
+ this.getFieldRules()[index]['fieldRuleFieldRule'] = fieldRule;
+ this.getFieldRules()[index]['fieldRuleSiteRule'] = siteRule;
+
+ // Notify the tree:
+ this.treeBox.invalidateRow(index);
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Update the related row of the simple interface:
+ this.updateSimpleInterfaceRow(index);
+ }
+ },
+
+ applyFieldRule: function(event) {
+ // Only apply changes if one item is selected:
+ if(this.selection.count == 1) {
+ // Update the selected formFieldRule:
+ this.applyFieldRuleOnIndex(this.selection.currentIndex);
+ }
+ },
+
+ addFieldRule: function(event) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ // Check the regular expressions:
+ try {
+ var fieldRuleFieldRuleTextBox = document.getElementById('fieldRuleFieldRuleTextBox');
+ var fieldRule = this.getRegExpStr(
+ this.makeSafe(fieldRuleFieldRuleTextBox.value)
+ );
+ fieldRuleFieldRuleTextBox.value = fieldRule;
+
+ var fieldRuleSiteRuleTextBox = document.getElementById('fieldRuleSiteRuleTextBox');
+ var siteRule = this.getRegExpStr(
+ this.makeSafe(fieldRuleSiteRuleTextBox.value)
+ );
+ fieldRuleSiteRuleTextBox.value = siteRule;
+ } catch(e) {
+ this.invalidRegExpAlert(e);
+ return;
+ }
+
+ var newFieldRule = this.createFieldRule(
+ this.makeSafe(document.getElementById('fieldRuleNameTextBox').value),
+ this.makeSafe(document.getElementById('fieldRuleValueTextBox').value),
+ fieldRule,
+ siteRule,
+ true,
+ true
+ )
+
+ var newFieldRuleIndex;
+
+ // Add the new formFieldRule right after the selected position or to the start of the list:
+ if(this.selection.currentIndex == -1 || this.selection.currentIndex == this.treeView.rowCount) {
+ this.getFieldRules().unshift(newFieldRule);
+ newFieldRuleIndex = 0;
+ } else {
+ newFieldRuleIndex = this.selection.currentIndex+1;
+ this.getFieldRules().splice(
+ newFieldRuleIndex,
+ 0,
+ newFieldRule
+ );
+ }
+
+ // Update the tree count and notify the tree:
+ this.treeView.rowCount++;
+ this.treeBox.rowCountChanged(this.treeView.rowCount, +1);
+ this.treeBox.invalidate();
+
+ // Select the new item:
+ this.selection.select(newFieldRuleIndex);
+
+ // Ensure row is visible (scrolls if not):
+ this.treeBox.ensureRowIsVisible(newFieldRuleIndex);
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ },
+
+ removeFieldRule: function(event) {
+ this.removeSelectedFieldRules();
+ },
+
+ moveUpFieldRule: function(event) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ var index = this.selection.currentIndex;
+
+ // Change place with the next upper item:
+ var sibling = this.getFieldRules()[index-1];
+ this.getFieldRules()[index-1] = this.getFieldRules()[index];
+ this.getFieldRules()[index] = sibling;
+
+ // Keep moved item selected:
+ this.selection.select(index-1);
+
+ // Notify the tree:
+ this.treeBox.invalidate();
+
+ // Ensure row is visible (scrolls if not):
+ this.treeBox.ensureRowIsVisible(index-1);
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Update the related rows of the simple interface:
+ this.updateSimpleInterfaceRow(index-1);
+ this.updateSimpleInterfaceRow(index);
+ },
+
+ moveDownFieldRule: function(event) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ var index = this.selection.currentIndex;
+
+ // Change place with the next lower item:
+ var sibling = this.getFieldRules()[index+1];
+ this.getFieldRules()[index+1] = this.getFieldRules()[index];
+ this.getFieldRules()[index] = sibling;
+
+ // Keep moved item selected:
+ this.selection.select(index+1);
+
+ // Notify the tree:
+ this.treeBox.invalidate();
+
+ // Ensure row is visible (scrolls if not):
+ this.treeBox.ensureRowIsVisible(index+1);
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Update the related rows of the simple interface:
+ this.updateSimpleInterfaceRow(index+1);
+ this.updateSimpleInterfaceRow(index);
+ },
+
+ removeSelectedFieldRules: function(event) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('removeFieldRulesTitle'),
+ this.getStringBundle().getString('removeFieldRulesText')
+ )
+ ) {
+ return;
+ }
+ }
+
+ // Start of update batch:
+ this.treeBox.beginUpdateBatch();
+
+ // Helper object to store a range:
+ function Range(start, end) {
+ this.start = start.value;
+ this.end = end.value;
+ }
+
+ // List of ranges:
+ var ranges = new Array();
+
+ // Get the number of ranges:
+ var numRanges = this.selection.getRangeCount();
+
+ // Helper vars to store the range end points:
+ var start = new Object();
+ var end = new Object();
+
+ // We store the list of ranges first, as calling
+ // this.treeBox.rowCountChanged()
+ // seems to invalidate the current selection
+
+ for(var i=0; i < numRanges; i++) {
+ // Get the current range end points:
+ this.selection.getRangeAt(i,start,end);
+ // Store them as a Range object in the ranges list:
+ ranges[i] = new Range(start, end);
+ }
+
+ for(var i=0; i < numRanges; i++) {
+ // Go through the stored ranges:
+ for(var j = ranges[i].start; j <= ranges[i].end; j++) {
+ // Set the selected fieldRules to null:
+ this.getFieldRules()[j] = null;
+ }
+
+ // Calculate the new tree count:
+ var count = ranges[i].end - ranges[i].start + 1;
+
+ // Update the tree count and notify the tree:
+ this.treeView.rowCount -= count;
+ this.treeBox.rowCountChanged(ranges[i].start, -count);
+ }
+
+ // Collapse list by removing all the null entries
+ for (var i=0; i < this.getFieldRules().length; i++) {
+ if (!this.getFieldRules()[i]) {
+ var j = i;
+ while (j < this.getFieldRules().length && !this.getFieldRules()[j])
+ j++;
+ this.getFieldRules().splice(i, j-i);
+ }
+ }
+
+ // Clear out selections
+ this.selection.select(-1);
+
+ // End of update batch:
+ this.treeBox.endUpdateBatch();
+
+ // Update the preferences:
+ this.setFieldRules();
+
+ // Re-initialize the simple interface:
+ this.initSimpleInterface();
+ },
+
+ handleKeyPress: function(event) {
+ if(event.keyCode == 46) {
+ this.removeSelectedFieldRules();
+ } else if(event.ctrlKey && event.which == 97) {
+ if(this.tree && this.selection) {
+ try {
+ // Select all rows:
+ this.selection.selectAll();
+ } catch(e) {
+ this.log(e);
+ }
+ }
+ }
+ },
+
+ getGlobalFieldRules: function() {
+ // Return the fieldRules for the selected global profile if globalProfileIndex is not out of range:
+ if(this.getGlobalProfileIndex() >= 0 && this.getGlobalProfileIndex() < this.getProfileLabels().length) {
+ return this.getFieldRules(this.getGlobalProfileIndex());
+ } else {
+ this.globalProfileIndex = 0;
+ return this.getFieldRules(0);
+ }
+ },
+
+ getFileContent: function(file) {
+ var fileContent = null;
+ try {
+ var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fis.init(file, -1, 0, 0);
+ var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+ .createInstance(Components.interfaces.nsIConverterInputStream);
+ is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ if(is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+ var line = {};
+ var cont;
+ do {
+ cont = is.readLine(line);
+ if(fileContent == null) {
+ fileContent = line.value;
+ } else {
+ fileContent += '\n'+line.value;
+ }
+ } while (cont);
+ }
+ is.close();
+ fis.close();
+ } catch(e) {
+ this.log(e);
+ }
+ return fileContent;
+ },
+
+ setFileContent: function(file, str) {
+ try {
+ var fos = Components.classes['@mozilla.org/network/file-output-stream;1']
+ .createInstance(Components.interfaces.nsIFileOutputStream);
+ fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
+ var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+ .createInstance(Components.interfaces.nsIConverterOutputStream);
+ os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ os.writeString(str);
+ os.close();
+ fos.close();
+ } catch(e) {
+ this.log(e);
+ }
+ },
+
+ getFieldRulesFile: function() {
+ var file = this.getConfigDirectory();
+ file.append('fieldRules.txt');
+ if(!file.exists()) {
+ file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+ }
+ return file;
+ },
+
+ getConfigDirectory: function() {
+ var configDirectory;
+ if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+ try {
+ configDirectory = this.autofillFormsPrefs.getComplexValue(
+ 'configDirectory',
+ Components.interfaces.nsILocalFile
+ );
+ } catch(e) {
+ this.autofillFormsPrefs.clearUserPref('configDirectory');
+ }
+ }
+ if(!configDirectory) {
+ configDirectory = this.getDefaultConfigDirectory();
+ }
+ return configDirectory;
+ },
+
+ getDefaultConfigDirectory: function() {
+ // Use a directory "autofillForms at blueimp.net" inside Firefox profile directory as default:
+ var configDirectory = Components.classes['@mozilla.org/file/directory_service;1']
+ .getService(Components.interfaces.nsIProperties)
+ .get('ProfD', Components.interfaces.nsILocalFile);
+ configDirectory.append('autofillForms at blueimp.net');
+ if(!configDirectory.exists()) {
+ configDirectory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0770);
+ }
+ return configDirectory;
+ },
+
+ setConfigDirectory: function(textBox) {
+ try {
+ // Create a file picker instance:
+ var fp = Components.classes['@mozilla.org/filepicker;1']
+ .createInstance(Components.interfaces.nsIFilePicker);
+
+ // Initialize the file picker window:
+ fp.init(
+ window,
+ this.getStringBundle().getString('selectConfigDirectory'),
+ Components.interfaces.nsIFilePicker.modeGetFolder
+ );
+
+ // Show the file picker window:
+ var rv = fp.show();
+
+ if (rv == Components.interfaces.nsIFilePicker.returnOK) {
+ var newDir = fp.file;
+ if(newDir.path == this.getConfigDirectory().path) {
+ return;
+ }
+ this.moveConfigFiles(newDir);
+ // Save the selected directory in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'configDirectory',
+ Components.interfaces.nsILocalFile, newDir
+ );
+ if(textBox) {
+ // Set the textbox value to the directory path:
+ textBox.value = newDir.path;
+ }
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+
+ resetConfigDirectory: function(textBox) {
+ if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+ var newDir = this.getDefaultConfigDirectory();
+ this.moveConfigFiles(newDir);
+ this.autofillFormsPrefs.clearUserPref('configDirectory');
+ if(textBox) {
+ // Set the textbox value to an empty string:
+ textBox.value = '';
+ }
+ }
+ },
+
+ openConfigDirectory: function() {
+ var configDirectory = this.getConfigDirectory();
+ if(configDirectory) {
+ try {
+ // Open the config directory in the operating system file manager:
+ configDirectory.reveal();
+ } catch(e) {
+ // reveal method may not be supported on some platforms,
+ // use nsIExternalProtocolService instead:
+ var uri = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService)
+ .newFileURI(configDirectory);
+ var protocolSvc =
+ Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
+ .getService(Components.interfaces.nsIExternalProtocolService);
+ protocolSvc.loadUrl(uri);
+ }
+ }
+ },
+
+ moveConfigFiles: function(newDir) {
+ if(this.checkConfigDirectoryOverwrite(newDir)) {
+ this.moveFile(this.getFieldRulesFile(), newDir);
+ this.moveFile(this.getDynamicTagsFile(), newDir);
+ this.moveFile(this.getDynamicTagCodesFile(), newDir);
+ this.moveFile(this.getProfileLabelsFile(), newDir);
+ this.moveFile(this.getProfileSiteRulesFile(), newDir);
+ return true;
+ }
+ return false;
+ },
+
+ importFromConfigDirectory: function() {
+ var ok = true;
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ ok = this.getPrompts().confirm(
+ window,
+ this.getStringBundle().getString('importFromConfigDirectoryTitle'),
+ this.getStringBundle().getString('importFromConfigDirectoryText')
+ );
+ }
+ if(ok) {
+ this.importFieldRulesFromConfigDirectory();
+ this.importDynamicTagsFromConfigDirectory();
+ this.importDynamicTagCodesFromConfigDirectory();
+ this.importProfileLabelsFromConfigDirectory();
+ this.importProfileSiteRulesFromConfigDirectory();
+ }
+ },
+
+ exportToConfigDirectory: function() {
+ if(this.checkConfigDirectoryOverwrite(this.getConfigDirectory())) {
+ this.exportFieldRulesToConfigDirectory();
+ this.exportDynamicTagsToConfigDirectory();
+ this.exportDynamicTagCodesToConfigDirectory();
+ this.exportProfileLabelsToConfigDirectory();
+ this.exportProfileSiteRulesToConfigDirectory();
+ return true;
+ }
+ return false;
+ },
+
+ moveFile: function(file, newDir, newFileName) {
+ try {
+ // The new fileName - uses the current fileName if empty:
+ newFileName = (typeof newFileName == 'string') ? newFileName : null;
+
+ file.moveTo(newDir, newFileName);
+ return true;
+ } catch(e) {
+ this.log(e);
+ return false;
+ }
+ },
+
+ checkConfigDirectoryOverwrite: function(newDir) {
+ var ok = true;
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ if(newDir.directoryEntries.hasMoreElements()) {
+ ok = this.getPrompts().confirm(
+ window,
+ this.getStringBundle().getString('newConfigDirectoryNotEmptyTitle'),
+ this.getStringBundle().getString('newConfigDirectoryNotEmptyText')
+ );
+ }
+ }
+ return ok;
+ },
+
+ exportFieldRulesToConfigDirectory: function() {
+ var prefString;
+ // Get the fieldRules string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ if(prefString) {
+ this.setFileContent(this.getFieldRulesFile(), prefString);
+ }
+ },
+
+ importFieldRulesFromConfigDirectory: function() {
+ var prefString;
+ prefString = this.getFileContent(this.getFieldRulesFile());
+ if(prefString) {
+ // Store the fieldRules as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'fieldRules',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getFieldRules: function(profileIndex) {
+ if(this.fieldRules == null) {
+ this.fieldRules = new Array();
+
+ var prefString;
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Get the fieldRules string from the fieldRules file in the configDirectory:
+ prefString = this.getFileContent(this.getFieldRulesFile());
+ }
+ if(!prefString) {
+ // Get the fieldRules string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ }
+
+ // On change of the "storeEncrypted" setting, we must decrypt or may not decrypt
+ // the prefString in opposition to the setting - the "invertedSetting" helper var
+ // helps to identify this situation:
+ var boolTest = this.invertedSetting ? false : true;
+
+ // If the fieldRules are stored encrypted, decrypt the prefString:
+ if(this.autofillFormsPrefs.getBoolPref('storeEncrypted') == boolTest) {
+ try {
+ // nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
+ // The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
+ prefString = this.getCryptoService().decryptString(prefString);
+ } catch(e) {
+ // Decrypting failed - return an empty default profile:
+ this.fieldRules.push(new Array());
+ this.profileIndex = 0;
+ return this.fieldRules[0];
+ }
+ }
+
+ // Get the profiles (separated by \n\n):
+ var profiles = prefString.split('\n\n');
+
+ for(var i=0; i<profiles.length; i++) {
+ // Create an array for each profile:
+ this.fieldRules.push(new Array());
+
+ // Get the fieldRules rows (separated by \n):
+ var rows = profiles[i].split('\n');
+ if(rows[0]) {
+ for(var j=0; j<rows.length; j++) {
+ if(!rows[j])
+ continue;
+
+ // Get the fieldRules column items (separated by \t):
+ var cols = rows[j].split('\t');
+
+ // Create fieldRules objects and save them in the current fieldRules Array:
+ if(cols.length && cols.length == 6) {
+
+ // Decode the fieldRule properties:
+ for(var k=0; k<cols.length; k++) {
+ cols[k] = decodeURI(cols[k]);
+ }
+
+ this.fieldRules[i].push(
+ this.createFieldRule(
+ cols[0],cols[1],cols[2],cols[3],
+ (cols[4] != 'false'),
+ (cols[5] != 'false')
+ )
+ );
+ }
+ }
+ } else
+ this.fieldRules[i] = new Array();
+ }
+ }
+
+ profileIndex = (typeof profileIndex != 'undefined') ? profileIndex : this.getProfileIndex();
+
+ // Return the fieldRules for the selected profile if profileIndex is not out of range:
+ if(profileIndex >= 0 && profileIndex < this.fieldRules.length)
+ return this.fieldRules[profileIndex];
+ else {
+ this.profileIndex = 0;
+ if(this.fieldRules[0] == null)
+ this.fieldRules[0] = new Array();
+ return this.fieldRules[0];
+ }
+ },
+
+ setFieldRules: function() {
+ if(this.fieldRules == null) {
+ // Initialize the field rules:
+ this.getFieldRules();
+ }
+
+ var profiles = '';
+ var rows, cols;
+ for(var i=0; i < this.fieldRules.length; i++) {
+ rows = '';
+ for(var j=0; j<this.fieldRules[i].length; j++) {
+ cols = null;
+ for(var property in this.fieldRules[i][j]) {
+ if(cols == null)
+ cols = '';
+ else
+ cols += '\t';
+ // Encode the fieldRule property before adding it to the string:
+ cols += encodeURI(this.fieldRules[i][j][property]);
+ }
+ if(j!=0)
+ rows += '\n';
+ rows += cols;
+ }
+ if(i!=0)
+ profiles += '\n\n';
+ profiles += rows;
+ }
+
+ // If the fieldRules are to be stored encrypted, encrypt the prefString:
+ if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
+ try {
+ // nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
+ // The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
+ profiles = this.getCryptoService().encryptString(profiles);
+ } catch(e) {
+ // Decrypting failed - return:
+ return;
+ }
+ }
+
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.setFileContent(this.getFieldRulesFile(), profiles);
+ } else {
+ // Store the fieldRules objects as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'fieldRules',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(profiles)
+ );
+ }
+ },
+
+ copyFieldRules: function(origin) {
+ var copy = new Array();
+ for(var i=0; i<origin.length; i++) {
+ copy.push(
+ this.createFieldRule(
+ origin[i]['fieldRuleName'],
+ origin[i]['fieldRuleValue'],
+ origin[i]['fieldRuleFieldRule'],
+ origin[i]['fieldRuleSiteRule'],
+ origin[i]['fieldRuleOverwrite'],
+ origin[i]['fieldRuleEnabled']
+ )
+ )
+ }
+ return copy;
+ },
+ importDynamicTagsFromSettings: function() {
+ //Here the tags are added directly
+ var prefString = null;
+
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ var dynamicTags = prefString.split('\t');
+
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ var dynamicTagCodes = prefString.split('\t');
+
+ this.importDynamicTags(dynamicTags, dynamicTagCodes);
+ this.setDynamicTags(dynamicTags);
+ this.setDynamicTagCodes(dynamicTagCodes);
+ },
+ importDynamicTagsFromTagEditor: function() {
+ //Here the tags are added to the editor window, can be cancelled if necessary
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+ var textboxes;
+
+ var dynamicTags = new Array();
+ var dynamicTagCodes = new Array();
+
+ // Go through the richlistbox items:
+ for(var i=0; i<richlistitems.length; i++) {
+ textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+ // Add the dynamic tags and their associated tag codes to the lists:
+ if (textboxes[0].value != '' && textboxes[1].value != '') {
+ dynamicTags.push(this.makeSafe(textboxes[0].value));
+ dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+ }
+ }
+ this.importDynamicTags(dynamicTags, dynamicTagCodes);
+ }
+ },
+ importDynamicTags: function(dynamicTags, dynamicTagCodes) {
+ try {
+ var file = this.filePicker('modeOpen', this.getStringBundle().getString('importDynamicTags'));
+ if(file) {
+ var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fis.init(file, -1, 0, 0);
+
+ var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+ .createInstance(Components.interfaces.nsIConverterInputStream);
+ is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+ var line = {};
+ var cont;
+ var firstLine = true;
+ var i;
+
+ do {
+ cont = is.readLine(line);
+
+ // Get the dynamicTags column items (separated by \t) from the file:
+ var cols = line.value.split('\t');
+
+ if (firstLine == true) {
+ // The first row has the following syntax (added in version 0.9.5):
+ // autofillForms at blueimp.net Version dynamictags
+ if(cols.length && cols.length != 3)
+ cont = false;
+ else if (cols[0] != 'autofillForms at blueimp.net')
+ cont = false;
+ else if (cols[2] != 'dynamictags')
+ cont = false;
+ firstLine = false;
+ }
+ else if (cols.length && cols.length == 2) {
+ //Check the imported pair isn't already defined or empty.
+ i = dynamicTags.indexOf(cols[0]);
+ if ((i >= 0 && dynamicTagCodes[i] == cols[1])||(cols[0]=='' && cols[1]=='')) {
+ continue;
+ } else {
+ dynamicTags.push(cols[0]);
+ dynamicTagCodes.push(cols[1]);
+ this.tagEditorAdd(cols[0],cols[1])
+ }
+ }
+ } while (cont);
+
+ }
+ is.close();
+ fis.close();
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ exportDynamicTagsFromSettings: function() {
+ var prefString = null;
+
+ // Write the tags to file analog to storing them in the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ var dynamicTagCodes = prefString.split('\t');
+
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ var dynamicTags = prefString.split('\t');
+ this.exportDynamicTags(dynamicTags, dynamicTagCodes);
+ },
+ exportDynamicTagsFromTagEditor: function() {
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+ var textboxes;
+
+ var dynamicTags = new Array();
+ var dynamicTagCodes = new Array();
+
+ // Go through the richlistbox items:
+ for(var i=0; i<richlistitems.length; i++) {
+ textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+ // Add the dynamic tags and their associated tag codes to the lists:
+ if (textboxes[0].value != '' && textboxes[1].value != '') {
+ dynamicTags.push(this.makeSafe(textboxes[0].value));
+ dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+ }
+ }
+ this.exportDynamicTags(dynamicTags, dynamicTagCodes);
+ }
+ },
+ exportDynamicTags: function(dynamicTags, dynamicTagCodes) {
+ try {
+ var file = this.filePicker(
+ 'modeSave',
+ this.getStringBundle().getString('exportDynamicTags'),
+ this.getProfileLabel(this.getProfileIndex())+'.txt'
+ );
+ if(file) {
+ var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+ createInstance(Components.interfaces.nsIFileOutputStream);
+ fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+ var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+ .createInstance(Components.interfaces.nsIConverterOutputStream);
+ os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+
+ var header = 'autofillForms at blueimp.net' + '\t'
+ + this.version + '\t'
+ + 'dynamictags\n';
+ os.writeString(header);
+
+ var cols;
+ for(var i=0; i<dynamicTags.length; i++) {
+ cols = dynamicTags[i]+'\t'+dynamicTagCodes[i];
+ os.writeString('\n' + cols);
+ }
+ os.close();
+ fos.close();
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ importProfile: function() {
+ try {
+ var file = this.filePicker('modeOpen', this.getStringBundle().getString('importProfile'));
+ if(file) {
+ var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fis.init(file, -1, 0, 0);
+
+ var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+ .createInstance(Components.interfaces.nsIConverterInputStream);
+ is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ if(this.fieldRules == null) {
+ // Initialize the field rules:
+ this.getFieldRules();
+ }
+
+ // Create a new fieldRule profile (index is incremented when a valid header is found):
+ var newProfileLabel = '';
+ var newProfileSiteRule = '(?:)';
+ var newProfileIndex = this.fieldRules.length-1;
+ var validProfile = false;
+
+ if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+ var line = {};
+ var cont;
+ do {
+ cont = is.readLine(line);
+
+ // Get the fieldRules column items (separated by \t) from the file:
+ var cols = line.value.split('\t');
+
+ if(cols.length && cols.length < 6 && cols[0] == 'autofillForms at blueimp.net') {
+ // The first row has the following syntax (added SiteRule for version 0.9.1):
+ // autofillForms at blueimp.net Version Label SiteRule
+ // Every time such a row is encountered, a new profile is generated.
+ if(cols.length >= 3) {
+ newProfileLabel = cols[2];
+ // Add profile label for default empty profile:
+ if(this.getProfileLabels().length == 0) {
+ this.getProfileLabels().push(this.getUniqueProfileLabel());
+ }
+ // Add the newProfileLabel to the profileLabels list (make sure it is unique):
+ this.getProfileLabels().push(this.getUniqueProfileLabel(newProfileLabel));
+ }
+ if(cols.length >= 4) {
+ try {
+ newProfileSiteRule = this.getRegExpStr(cols[3]);
+ // Add a new profileSiteRule:
+ this.getProfileSiteRules().push(newProfileSiteRule);
+ } catch(e) {
+ // Catch missing or invalid site rule
+ }
+ }
+ // Increment the ProfileIndex
+ newProfileIndex += 1;
+ this.fieldRules.push(new Array());
+ validProfile = true;
+ } else if(cols.length && cols.length == 6 && validProfile == true) {
+ // Create fieldRules objects and save them in the fieldRules Array:
+ this.fieldRules[newProfileIndex].push(
+ this.createFieldRule(
+ cols[0],cols[1],cols[2],cols[3],
+ (cols[4] != 'false'),
+ (cols[5] != 'false')
+ )
+ );
+ }
+
+ } while (cont);
+ }
+
+ // Save the profileLabels list in the preferences:
+ this.setProfileLabels(this.getProfileLabels());
+ // Save the profileSiteRules in the preferences:
+ this.setProfileSiteRules(this.getProfileSiteRules());
+ // Update the profiles lists:
+ this.initProfilesLists();
+
+ // Update the fieldRules:
+ this.setFieldRules();
+
+ is.close();
+ fis.close();
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ exportProfile: function() {
+ try {
+ var file = this.filePicker(
+ 'modeSave',
+ this.getStringBundle().getString('exportProfile'),
+ this.getProfileLabel(this.getProfileIndex())+'.txt'
+ );
+ if(file) {
+ var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+ createInstance(Components.interfaces.nsIFileOutputStream);
+ fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+ var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+ .createInstance(Components.interfaces.nsIConverterOutputStream);
+ os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ var profileIndex = this.getProfileIndex();
+ this.writeProfile(os, profileIndex);
+
+ os.close();
+ fos.close();
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ exportAllProfiles: function() {
+ try {
+ //use the first profile label as the filename
+ var file = this.filePicker(
+ 'modeSave',
+ this.getStringBundle().getString('exportProfile'),
+ this.getProfileLabel(0)+'.txt'
+ );
+ if(file) {
+ var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+ createInstance(Components.interfaces.nsIFileOutputStream);
+ fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+ var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+ .createInstance(Components.interfaces.nsIConverterOutputStream);
+
+ os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ for(var i=0; i<this.getProfileLabels().length; i++) {
+ this.writeProfile(os, i);
+ os.writeString('\n\n');
+ }
+ os.close();
+ fos.close();
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ writeProfile: function(os, profileIndex) {
+ try {
+ var header = 'autofillForms at blueimp.net' + '\t'
+ + this.version + '\t'
+ + this.getProfileLabel(profileIndex) + '\t'
+ + this.getProfileSiteRule(profileIndex) + '\n';
+
+
+ os.writeString(header);
+ // Write the rules to file analog to storing them in the preferences:
+ var cols;
+ for(var i=0; i<this.getFieldRules(profileIndex).length; i++) {
+ cols = null;
+ for(var property in this.getFieldRules(profileIndex)[i]) {
+ if(cols == null)
+ cols = '';
+ else
+ cols += '\t';
+ cols += this.getFieldRules(profileIndex)[i][property];
+ }
+ os.writeString('\n' + cols);
+ }
+ } catch(e) {
+ this.log(e);
+ }
+ },
+ filePicker: function(mode, title, fileName) {
+ try {
+ // Create a file picker instance:
+ var fp = Components.classes['@mozilla.org/filepicker;1']
+ .createInstance(Components.interfaces.nsIFilePicker);
+
+ // The filename suggested to the user as a default:
+ if(fileName) {
+ fp.defaultString = fileName;
+ }
+
+ // Initialize the file picker window:
+ fp.init(
+ window,
+ title,
+ Components.interfaces.nsIFilePicker[mode]
+ );
+
+ // Show the file picker window:
+ var rv = fp.show();
+
+ if(rv==Components.interfaces.nsIFilePicker.returnOK || rv==Components.interfaces.nsIFilePicker.returnReplace)
+ return fp.file;
+ else
+ return null;
+ } catch(e) {
+ return null;
+ }
+ },
+
+ getUnicodeString: function(stringData) {
+ // Create an Unicode String:
+ var str = Components.classes['@mozilla.org/supports-string;1']
+ .createInstance(Components.interfaces.nsISupportsString);
+ // Set the String value:
+ str.data = stringData;
+ // Return the Unicode String:
+ return str;
+ },
+
+ getStringBundle: function() {
+ return document.getElementById('autofillFormsStringBundle');
+ },
+
+ getDoc: function(win) {
+ if(win)
+ return win.document;
+ else if(content)
+ return content.document;
+ else
+ return this.getBrowser().contentDocument;
+ },
+
+ getWin: function() {
+ if(content)
+ return content;
+ else
+ return this.getBrowser().contentWindow;
+ },
+
+ getBrowser: function() {
+ try {
+ return gBrowser;
+ } catch(e) {
+ // gBrowser is not available, so make use of the WindowMediator service instead:
+ return this.getWindowMediator().getMostRecentWindow('navigator:browser').getBrowser();
+ }
+ },
+
+ getWindowMediator: function() {
+ return Components.classes['@mozilla.org/appshell/window-mediator;1']
+ .getService(Components.interfaces.nsIWindowMediator);
+ },
+
+ getRegExpStr: function(str) {
+ // Create a RegExp object using the given String:
+ var regExpStr = new RegExp(str).toString();
+ // Return the String representation without the surrounding slashes:
+ return regExpStr.substr(1,regExpStr.length-2);
+ },
+
+ getPrefManager: function() {
+ return Components.classes['@mozilla.org/preferences-service;1']
+ .getService(Components.interfaces.nsIPrefService);
+ },
+
+ getCryptoService: function() {
+ return Components.classes['@mozilla.org/security/sdr;1']
+ .createInstance(Components.interfaces.nsISecretDecoderRing);
+ },
+
+ getPrompts: function() {
+ return Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+ .getService(Components.interfaces.nsIPromptService);
+ },
+
+ recognizeMouseButton: function(event) {
+ var modifiers = new Array();
+
+ // Get the modifiers:
+ if(event.altKey) modifiers.push('alt');
+ if(event.ctrlKey) modifiers.push('control');
+ if(event.metaKey) modifiers.push('meta');
+ if(event.shiftKey) modifiers.push('shift');
+
+ // Return a mouseButtonObj:
+ return this.mouseButtonFactory(modifiers, 'mousebutton'+event.button);
+ },
+
+ mouseButtonFactory: function(modifiers, mouseButton) {
+ if(typeof arguments.callee.mouseButtonObj == 'undefined') {
+ arguments.callee.mouseButtonObj = function(modifiers, mouseButton) {
+ this.modifiers = modifiers ? modifiers : new Array();
+ this.mouseButton = mouseButton;
+ this.toString = function() {
+ if(this.modifiers.length) {
+ return this.modifiers.join('+')+'+'+this.mouseButton;
+ } else {
+ return this.mouseButton;
+ }
+ }
+ this.equals = function(mouseButtonObj) {
+ if(this.mouseButton != mouseButtonObj.mouseButton) {
+ return false;
+ }
+ if(this.modifiers.length != mouseButtonObj.modifiers.length) {
+ return false;
+ }
+ for(var i=0; i<this.modifiers.length; i++) {
+ if(this.modifiers[i] != mouseButtonObj.modifiers[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return this;
+ }
+ }
+ return new arguments.callee.mouseButtonObj(modifiers, mouseButton);
+ },
+
+ getFormattedMouseButton: function(mouseButtonObj) {
+ var formattedMouseButton = '';
+ if(!mouseButtonObj.mouseButton) {
+ return formattedMouseButton;
+ }
+ // Add the modifiers:
+ for(var i=0; i < mouseButtonObj.modifiers.length; i++) {
+ try {
+ formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.modifiers[i])+'+';
+ } catch(e) {
+ this.log(e);
+ // Error in shortcut string, return empty String:
+ return '';
+ }
+ }
+ try {
+ formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.mouseButton);
+ } catch(e) {
+ // No localization for this mouse button, add generic button string :
+ formattedMouseButton += this.getStringBundle().getString('mousebutton');
+ // Add the index of the given mouseButton:
+ formattedMouseButton += ' '+mouseButtonObj.mouseButton.substr('mousebutton'.length);
+ }
+ return formattedMouseButton;
+ },
+
+ applyMouseButton: function(event, id) {
+ // Recognize the mouse button event:
+ var mouseButtonObj = this.recognizeMouseButton(event);
+ if(!mouseButtonObj)
+ return;
+ // Ignore the right mouse button (mousebutton2), as this already invokes the context menu:
+ if(mouseButtonObj.mouseButton == 'mousebutton2') {
+ return;
+ }
+ // Save the new mouse button object:
+ this.setMouseButton(id, mouseButtonObj);
+ // Update the mouse button textbox:
+ if(event.view.document && event.view.document.getElementById(id)) {
+ event.view.document.getElementById(id).value = this.getFormattedMouseButton(mouseButtonObj);
+ }
+ },
+
+ disableMouseButton: function(event, id) {
+ // Disable the mouse button:
+ this.setMouseButton(id, null);
+ // Update the mouse button textbox:
+ if(event.view.document && event.view.document.getElementById(id)) {
+ event.view.document.getElementById(id).value = '';
+ }
+ },
+
+ getMouseButton: function(id) {
+ if(this.mouseButton == null) {
+ // Create a new mouseButton container object:
+ this.mouseButton = new Object();
+ }
+ if(this.mouseButton[id] == null) {
+ var mouseButtonItems = this.autofillFormsPrefs.getCharPref(id).split('+');
+ var mouseButton;
+ if(mouseButtonItems.length == 0) {
+ mouseButton = '';
+ } else {
+ // Remove the last element and save it as mouseButton
+ // the remaining mouseButtonItems are the modifiers:
+ mouseButton = mouseButtonItems.pop();
+ }
+ // Create a new mouseButton object:
+ this.mouseButton[id] = this.mouseButtonFactory(mouseButtonItems, mouseButton);
+ }
+ return this.mouseButton[id];
+ },
+
+ setMouseButton: function(id, mouseButtonObj) {
+ var stringData;
+ if(mouseButtonObj) {
+ stringData = mouseButtonObj.toString();
+ } else {
+ stringData = '';
+ }
+ // Save the mouseButtonObj as Unicode String in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ id,
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(stringData)
+ );
+ },
+
+ recognizeKeys: function(event) {
+ var modifiers = new Array();
+ var key = '';
+ var keycode = '';
+
+ // Get the modifiers:
+ if(event.altKey) modifiers.push('alt');
+ if(event.ctrlKey) modifiers.push('control');
+ if(event.metaKey) modifiers.push('meta');
+ if(event.shiftKey) modifiers.push('shift');
+
+ // Get the key or keycode:
+ if(event.charCode) {
+ key = String.fromCharCode(event.charCode).toUpperCase();
+ } else {
+ // Get the keycode from the keycodes list:
+ keycode = this.getKeyCodes()[event.keyCode];
+ if(!keycode) {
+ return null;
+ }
+ }
+
+ // Shortcut may be anything, but not 'VK_TAB' alone (without modifiers),
+ // as this button is used to change focus to the 'Apply' button:
+ if(modifiers.length > 0 || keycode != 'VK_TAB') {
+ return this.shortcutFactory(modifiers, key, keycode);
+ }
+ return null;
+ },
+
+ shortcutFactory: function(modifiers, key, keycode) {
+ if(typeof arguments.callee.shortcut == 'undefined') {
+ arguments.callee.shortcut = function(modifiers, key, keycode) {
+ this.modifiers = modifiers ? modifiers : new Array();
+ this.key = key;
+ this.keycode = keycode;
+ this.toString = function() {
+ if(this.modifiers.length) {
+ return this.modifiers.join('+')+'+'+this.key+this.keycode;
+ } else {
+ return this.key+this.keycode;
+ }
+ }
+ this.equals = function(shortcut) {
+ if(this.key != shortcut.key) {
+ return false;
+ }
+ if(this.keycode != shortcut.keycode) {
+ return false;
+ }
+ if(this.modifiers.length != shortcut.modifiers.length) {
+ return false;
+ }
+ for(var i=0; i<this.modifiers.length; i++) {
+ if(this.modifiers[i] != shortcut.modifiers[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return this;
+ }
+ }
+ return new arguments.callee.shortcut(modifiers, key, keycode);
+ },
+
+ getKeyCodes: function() {
+ var keycodes = new Array();
+ // Get the list of keycodes from the KeyEvent object:
+ for(var property in KeyEvent) {
+ keycodes[KeyEvent[property]] = property.replace('DOM_','');
+ }
+ // VK_BACK_SPACE (index 8) must be VK_BACK:
+ keycodes[8] = 'VK_BACK';
+ return keycodes;
+ },
+
+ applyShortcut: function(event, id) {
+ // Recognize the pressed keys:
+ var shortcut = this.recognizeKeys(event)
+ if(!shortcut)
+ return;
+ // Save the new shortcut:
+ this.setShortcut(id, shortcut);
+ // Update the shortcut textbox:
+ if(event.view.document && event.view.document.getElementById(id)) {
+ event.view.document.getElementById(id).value = this.getFormattedShortcut(shortcut);
+ }
+ },
+
+ disableShortcut: function(event, id) {
+ // Disable the shortcut:
+ this.setShortcut(id, null);
+ // Update the shortcut textbox:
+ if(event.view.document && event.view.document.getElementById(id)) {
+ event.view.document.getElementById(id).value = '';
+ }
+ },
+
+ getShortcut: function(id) {
+ if(this.shortcut == null) {
+ // Create a new shortcut container object:
+ this.shortcut = new Object();
+ }
+ if(this.shortcut[id] == null) {
+ var key = null;
+ var keycode = null;
+ var shortcutItems = this.autofillFormsPrefs
+ .getComplexValue(id,Components.interfaces.nsIPrefLocalizedString)
+ .data.split('+');
+ if(shortcutItems.length > 0) {
+ // Remove the last element and save it as key
+ // the remaining shortcutItems are the modifiers:
+ key = shortcutItems.pop();
+ // Check if the key is a keycode:
+ if(key.indexOf('VK') == 0) {
+ keycode = key;
+ key = null;
+ }
+ }
+ // Create a new shortcut object:
+ this.shortcut[id] = this.shortcutFactory(shortcutItems, key, keycode);
+ }
+ return this.shortcut[id];
+ },
+
+ setShortcut: function(id, shortcut) {
+ var stringData;
+ if(shortcut) {
+ stringData = shortcut.toString();
+ } else {
+ stringData = '';
+ }
+ // Save the shortcut as Unicode String in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ id,
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(stringData)
+ );
+ },
+
+ updateShortcut: function(id) {
+ if(this.shortcut == null) {
+ this.shortcut = new Object();
+ }
+ // Setting the shortcut object to "null" will update it on the next getShortcut() call:
+ this.shortcut[id] = null;
+
+ // Get the keyboard shortcut elements:
+ var modifiers = this.getShortcut(id).modifiers.join(' ');
+ var key = this.getShortcut(id).key;
+ var keycode = this.getShortcut(id).keycode;
+
+ var domId = 'autofillForms' + id.replace(/shortcut/, 'Shortcut');
+ var command = 'autofillForms' + id.replace(/shortcut/i, '');
+
+ // Remove current key if existing:
+ if(document.getElementById(domId)) {
+ document.getElementById('mainKeyset').removeChild(
+ document.getElementById(domId)
+ );
+ }
+
+ // Check if keyboard shortcut is enabled:
+ if(key || keycode) {
+ // Create a key element:
+ var keyNode = document.createElement('key');
+
+ keyNode.setAttribute('id', domId);
+ keyNode.setAttribute('command', command);
+
+ // Set the key attributes from saved shortcut:
+ keyNode.setAttribute('modifiers', modifiers);
+ if(key) {
+ keyNode.setAttribute('key', key);
+ } else {
+ keyNode.setAttribute('keycode', keycode);
+ }
+
+ // Add the key to the mainKeyset:
+ document.getElementById('mainKeyset').appendChild(keyNode);
+ }
+ },
+
+ getFormattedShortcut: function(shortcut) {
+ var formattedShortcut = '';
+ // Add the modifiers:
+ for(var i=0; i < shortcut.modifiers.length; i++) {
+ try {
+ formattedShortcut += this.getStringBundle().getString(shortcut.modifiers[i]) + '+';
+ } catch(e) {
+ // Error in shortcut string, return empty String;
+ return '';
+ }
+ }
+ if(shortcut.key) {
+ // Add the key:
+ if(shortcut.key == ' ') {
+ formattedShortcut += this.getStringBundle().getString('VK_SPACE');
+ } else {
+ formattedShortcut += shortcut.key;
+ }
+ } else if(shortcut.keycode) {
+ // Add the keycode (instead of the key):
+ try {
+ formattedShortcut += this.getStringBundle().getString(shortcut.keycode);
+ } catch(e) {
+ formattedShortcut += shortcut.keycode.replace('VK_', '');
+ }
+ }
+ return formattedShortcut;
+ },
+
+ replaceDynamicTags: function(fieldRuleValue) {
+ // Replace all dynamic tags with the return values of their associated tag codes:
+ for(var j=0; j<this.getDynamicTags().length; j++) {
+ // Catch if the number of tags doesn't match the number of tag codes or if the tag code is invalid:
+ try {
+ var regExpObj = new RegExp(this.getDynamicTags()[j],'g');
+ // We use eval() here without restrictions - the given tagCode must be trusted:
+ fieldRuleValue = fieldRuleValue.replace(regExpObj, eval(this.getDynamicTagCodes()[j]));
+ } catch(e) {
+ this.log(e);
+ }
+ }
+ return fieldRuleValue;
+ },
+
+ getDynamicTagsFile: function() {
+ var file = this.getConfigDirectory();
+ file.append('dynamicTags.txt');
+ if(!file.exists()) {
+ file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+ }
+ return file;
+ },
+
+ exportDynamicTagsToConfigDirectory: function() {
+ var prefString;
+ // Get the dynamicTags string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ if(prefString) {
+ this.setFileContent(this.getDynamicTagsFile(), prefString);
+ }
+ },
+
+ importDynamicTagsFromConfigDirectory: function() {
+ var prefString;
+ prefString = this.getFileContent(this.getDynamicTagsFile());
+ if(prefString) {
+ // Store the dynamicTags as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'dynamicTags',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getDynamicTags: function() {
+ if(this.dynamicTags == null) {
+ var prefString;
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Get the dynamicTags string from the dynamicTags file in the configDirectory:
+ prefString = this.getFileContent(this.getDynamicTagsFile());
+ }
+ if(!prefString) {
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ }
+ this.dynamicTags = prefString.split('\t');
+ }
+ return this.dynamicTags;
+ },
+
+ setDynamicTags: function(dynamicTags) {
+ // Save the dynamic tags separated by tabs:
+ var prefString = dynamicTags.join('\t');
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.setFileContent(this.getDynamicTagsFile(), prefString);
+ } else {
+ this.autofillFormsPrefs.setComplexValue(
+ 'dynamicTags',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getDynamicTagCodesFile: function() {
+ var file = this.getConfigDirectory();
+ file.append('dynamicTagCodes.txt');
+ if(!file.exists()) {
+ file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+ }
+ return file;
+ },
+
+ exportDynamicTagCodesToConfigDirectory: function() {
+ var prefString;
+ // Get the dynamicTagCodes string from the preferences:
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ if(prefString) {
+ this.setFileContent(this.getDynamicTagCodesFile(), prefString);
+ }
+ },
+
+ importDynamicTagCodesFromConfigDirectory: function() {
+ var prefString;
+ prefString = this.getFileContent(this.getDynamicTagCodesFile());
+ if(prefString) {
+ // Store the dynamicTagCodes as unicode string in the preferences:
+ this.autofillFormsPrefs.setComplexValue(
+ 'dynamicTagCodes',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ getDynamicTagCodes: function() {
+ if(this.dynamicTagCodes == null) {
+ var prefString;
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Get the dynamicTagCodes string from the dynamicTagCodes file in the configDirectory:
+ prefString = this.getFileContent(this.getDynamicTagCodesFile());
+ }
+ if(!prefString) {
+ prefString = this.autofillFormsPrefs
+ .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+ .data;
+ }
+ this.dynamicTagCodes = prefString.split('\t');
+ }
+ return this.dynamicTagCodes;
+ },
+
+ setDynamicTagCodes: function(dynamicTagCodes) {
+ // Save the dynamic tag codes separated by tabs:
+ var prefString = dynamicTagCodes.join('\t');
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ this.setFileContent(this.getDynamicTagCodesFile(), prefString);
+ } else {
+ this.autofillFormsPrefs.setComplexValue(
+ 'dynamicTagCodes',
+ Components.interfaces.nsISupportsString,
+ this.getUnicodeString(prefString)
+ );
+ }
+ },
+
+ optionsInitialize: function() {
+ // Save the reference to the Autofill Forms preferences branch:
+ this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+ // Initialize the profile lists:
+ this.initProfilesLists();
+ // Initialize the fieldRules tree:
+ this.initTree();
+ // Initialize the simple interface:
+ this.initSimpleInterface();
+
+ // Sort is to be ascending if clicked first:
+ this.ascending = true;
+ this.profilesAscending = true;
+
+ var configDirectoryTextbox = document.getElementById('configDirectoryTextBox');
+ if(configDirectoryTextbox && this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+ var configDirectory = this.getConfigDirectory();
+ if(configDirectory) {
+ configDirectoryTextbox.value = configDirectory.path;
+ }
+ }
+
+ // Initialize the keyboard shortcut objects:
+ this.shortcut = new Object();
+ this.shortcut['shortcut'] = null;
+ this.shortcut['shortcutSubmit'] = null;
+ this.shortcut['shortcutAllTabs'] = null;
+ this.shortcut['shortcutFromProfileSelection'] = null;
+ this.shortcut['shortcutProfile'] = null;
+ this.shortcut['shortcutSettings'] = null;
+ this.shortcut['shortcutDisplayFormDetails'] = null;
+
+ // Display the shortcut combinations:
+ for(var property in this.shortcut) {
+ if(document.getElementById(property)) {
+ document.getElementById(property).value = this.getFormattedShortcut(this.getShortcut(property));
+ }
+ }
+
+ // Initialize the mouse button objects:
+ this.mouseButton = new Object();
+ this.mouseButton['mouseShortcut'] = null;
+ this.mouseButton['mouseShortcutSubmit'] = null;
+ this.mouseButton['mouseShortcutAllTabs'] = null;
+ this.mouseButton['mouseShortcutFromProfileSelection'] = null;
+ this.mouseButton['mouseShortcutProfile'] = null;
+ this.mouseButton['mouseShortcutSettings'] = null;
+ this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
+
+ // Display the mouse button combinations:
+ for(var property in this.mouseButton) {
+ if(document.getElementById(property)) {
+ document.getElementById(property).value = this.getFormattedMouseButton(this.getMouseButton(property));
+ }
+ }
+
+ // Parse the window params (e.g. initializing the target form field values):
+ this.parseOptionsWindowParams();
+ },
+
+ initSimpleInterface: function() {
+ var rows = document.getElementById('simpleInterfaceRows');
+ if(rows) {
+ while(rows.hasChildNodes()) {
+ rows.removeChild(rows.firstChild);
+ }
+ for(var i=0; i<this.getFieldRules().length; i++) {
+ // Only show enabled fieldRules:
+ if(!this.getFieldRules()[i]['fieldRuleEnabled']) {
+ continue;
+ }
+ rows.appendChild(
+ this.getSimpleInterfaceRow(
+ i,
+ this.getFieldRules()[i]['fieldRuleName'],
+ this.getFieldRules()[i]['fieldRuleValue']
+ )
+ );
+ }
+ }
+ },
+
+ addSimpleInterfaceRow: function(index) {
+ var row = this.getSimpleInterfaceRow(
+ index,
+ this.getFieldRules()[index]['fieldRuleName'],
+ this.getFieldRules()[index]['fieldRuleValue']
+ )
+ var rows = document.getElementById('simpleInterfaceRows');
+ if(rows) {
+ var nextSibling;
+ if(rows.childNodes) {
+ for(var i=index+1; i<rows.childNodes.length; i++) {
+ nextSibling = document.getElementById('simpleInterfaceRow_'+i);
+ if(nextSibling) {
+ rows.insertBefore(row, nextSibling);
+ break;
+ }
+ }
+ }
+ if(!nextSibling) {
+ rows.appendChild(row);
+ }
+ }
+ },
+
+ removeSimpleInterfaceRow: function(index) {
+ var row = document.getElementById('simpleInterfaceRow_'+index);
+ if(row) {
+ row.parentNode.removeChild(row);
+ }
+ },
+
+ getSimpleInterfaceRow: function(index, name, value) {
+ if(!arguments.callee.row) {
+ arguments.callee.row = document.createElement('row');
+ arguments.callee.row.setAttribute('align', 'center');
+ var label = document.createElement('label');
+ var textbox = document.createElement('textbox');
+ textbox.setAttribute('newlines', 'pasteintact');
+ arguments.callee.row.appendChild(label);
+ arguments.callee.row.appendChild(textbox);
+ }
+ var row = arguments.callee.row.cloneNode(true);
+ row.setAttribute('id', 'simpleInterfaceRow_'+index);
+ row.firstChild.setAttribute('value', name+':');
+ row.firstChild.setAttribute('id', 'simpleInterfaceLabel_'+index);
+ row.firstChild.setAttribute('control', 'simpleInterfaceTextbox_'+index);
+ row.lastChild.setAttribute('id', 'simpleInterfaceTextbox_'+index);
+ row.lastChild.setAttribute('value', value);
+ row.lastChild.addEventListener('change', function (){
+ autofillForms.applySimpleInterfaceValue(this);
+ }, false);
+ row.lastChild.addEventListener('input', function () {
+ this.value = autofillForms.replaceControlCharacters(this.value);
+ }, false);
+
+ // Is textbox a password field?
+ if(this.getRegExpPasswordLabel().test(name)) {
+ row.lastChild.setAttribute('type', 'password');
+ }
+ return row;
+ },
+
+ applySimpleInterfaceValue: function(textBox) {
+ // See method selectedFieldRule() why this has to be set to null:
+ this.lastSelectedIndex = null;
+
+ var index = parseInt(textBox.getAttribute('id').split('_')[1]);
+ this.getFieldRules()[index]['fieldRuleValue'] = this.makeSafe(textBox.value);
+
+ // Notify the tree (of the advanced interface):
+ try {
+ this.treeBox.invalidateRow(index);
+ } catch(e) {
+ }
+
+ // Update the preferences:
+ this.setFieldRules();
+ },
+
+ updateSimpleInterfaceRow: function(index) {
+ var row = document.getElementById('simpleInterfaceRow_'+index);
+ if(row) {
+ row.firstChild.value = this.getFieldRules()[index]['fieldRuleName']+':';
+ row.lastChild.value = this.getFieldRules()[index]['fieldRuleValue'];
+ // Is textbox a password field?
+ if(this.getRegExpPasswordLabel().test(this.getFieldRules()[index]['fieldRuleName'])) {
+ row.lastChild.setAttribute('type', 'password');
+ } else {
+ row.lastChild.removeAttribute('type');
+ }
+ }
+ },
+
+ getFieldRuleNameForElement: function(element) {
+ // Use the form field label as name if available:
+ var labelValue = this.getLabelForElement(element);
+ // Remove the colon, if present:
+ if(labelValue && labelValue.charAt(labelValue.length-1) == ':') {
+ labelValue = labelValue.substr(0, labelValue.length-1);
+ }
+ // If no label could be found, use the name or the id with the first character in upper case:
+ if(!labelValue) {
+ labelValue = element.name;
+ if(!labelValue) {
+ labelValue = element.id;
+ }
+ if(labelValue) {
+ labelValue = labelValue.charAt(0).toUpperCase() + labelValue.substr(1);
+ }
+ }
+ return labelValue;
+ },
+
+ getRegExpStrForValue: function(value) {
+ try {
+ // Remove unsave characters, escape regexp characters and return the regexp string:
+ return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(value))+'$)');
+ } catch(e) {
+ // If an error occurs, return the safe value string.
+ // If using it as regular expression fails a simple string comparison is used:
+ return this.makeSafe(value);
+ }
+ },
+
+ getFieldRuleForElement: function(element) {
+ var name = element.name;
+ // If no name is available use the label as fallback:
+ if(!name) {
+ name = this.getLabelForElement(element);
+ }
+ // If no name and no label is available use the id as fallback:
+ if(!name) {
+ name = element.id;
+ }
+ try {
+ // Remove unsave characters, escape regexp characters and return the regexp string:
+ return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(name))+'$)');
+ } catch(e) {
+ // If an error occurs, return an always matching regexp string:
+ return '(?:)';
+ }
+ },
+
+ getSiteRuleForURL: function(url) {
+ try {
+ // Remove unsave characters, escape regexp characters and return the regexp string:
+ return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(url))+')');
+ } catch(e) {
+ // If an error occurs, return an always matching regexp string:
+ return '(?:)';
+ }
+ },
+
+ parseOptionsWindowParams: function() {
+ // Check the windows arguments:
+ if(window.arguments && window.arguments[0]) {
+ if(window.arguments[0].targetFormField) {
+ var formFieldObject = window.arguments[0].targetFormField;
+
+ var value;
+ switch(formFieldObject.type) {
+ case 'checkbox':
+ case 'radio':
+ case 'select-one':
+ case 'select-multiple':
+ value = this.getRegExpStrForValue(formFieldObject.value);
+ break;
+ default:
+ value = this.replaceControlCharacters(formFieldObject.value);
+ break;
+ }
+
+ var location = this.getDoc().location;
+
+ // Reset the targetFormField of the autofillForms object referenced by window.arguments[0]:
+ window.arguments[0].targetFormField = null;
+
+ // Set the textbox values using the form field properties and the current document location:
+ document.getElementById('fieldRuleNameTextBox').value
+ = this.getFieldRuleNameForElement(formFieldObject)
+ + (location.hostname ? ' - ' + location.hostname : '');
+ document.getElementById('fieldRuleValueTextBox').value = value;
+ document.getElementById('fieldRuleFieldRuleTextBox').value
+ = this.getFieldRuleForElement(formFieldObject);
+ document.getElementById('fieldRuleSiteRuleTextBox').value
+ = this.getSiteRuleForURL(location.protocol + '//' + location.host);
+
+ // Make sure the main pane is selected:
+ document.getElementById('autofillFormsPrefs').showPane(
+ document.getElementById('autofillFormsPrefPaneMain')
+ );
+
+ // Set the focus to the name field:
+ //document.getElementById('fieldRuleNameTextBox').focus();
+ autofillForms.action(document.getElementById('fieldRuleNameTextBox'), 'focus');
+ } else if(window.arguments[0].newProfileFromForm) {
+ // Make sure the main pane is selected:
+ document.getElementById('autofillFormsPrefs').showPane(
+ document.getElementById('autofillFormsPrefPaneMain')
+ );
+ }
+ }
+ },
+
+ optionsFinalize: function() {
+ },
+
+ showProfileSwitcher: function() {
+ if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+ // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+ this.profileLabels = null;
+ }
+ // The nsIPromptService select() method doesn't offer to set a preselection,
+ // so we switch the current profile label with the first item (which is selected by default):
+ var list;
+ var currentIndex = this.getProfileIndex();
+ if(currentIndex != 0) {
+ // Copy the profilLabels array (so we don't change the original):
+ list = new Array().concat(this.getProfileLabels());
+ // Switch the current profile label with the first item:
+ var tmp = list[0];
+ list[0] = list[currentIndex];
+ list[currentIndex] = tmp;
+ } else {
+ // Set the list to the profilLabels reference if it is not to be changed:
+ list = this.getProfileLabels();
+ }
+ var selected = {};
+ // Show the selection prompt:
+ var ok = this.getPrompts().select(
+ window,
+ this.getStringBundle().getString('profileSelectionWindowTitle'),
+ this.getStringBundle().getString('profileSelectionPrompt'),
+ list.length,
+ list,
+ selected
+ );
+ if(ok) {
+ // If nothing changed, return:
+ if(selected.value == 0)
+ return;
+ // If the currentIndex has been selected and is not 0, it is in fact the index 0:
+ if(currentIndex != 0 && selected.value == currentIndex)
+ selected.value = 0;
+ // Set the profile index to the selected one:
+ this.setProfileIndex(selected.value)
+ }
+ },
+
+ showDialog: function(url, params) {
+ if (this.currentDialogs == null) {
+ this.currentDialogs = new Object();
+ }
+
+ // Is the window already
+ var win = this.currentDialogs[url];
+ if (win == null || win.closed)
+ {
+ var paramObject = params ? params : this;
+ win = window.openDialog(
+ url,
+ '',
+ 'chrome=yes,resizable=yes,toolbar=yes,centerscreen=yes,modal=no,dependent=no,dialog=no',
+ paramObject
+ );
+
+ this.currentDialogs[url] = win;
+ return win;
+ } else {
+ win.focus();
+ }
+ },
+
+ inArray: function(array, item) {
+ var i = array.length;
+ while(i--)
+ if(array[i] === item)
+ return true;
+ return false;
+ },
+
+ displayFormDetails: function() {
+ this.searchAndDisplayFormDetails(this.getWin());
+ },
+
+ searchAndDisplayFormDetails: function(win) {
+ win = win ? win : this.getWin();
+
+ var doc = this.getDoc(win);
+
+ // Check if any web forms are available on the current window:
+ if(doc && doc.forms && doc.forms.length > 0) {
+
+ // Go through the forms:
+ for(var i = 0; i < doc.forms.length; i++) {
+
+ // The form elements list:
+ var elements = doc.forms[i].elements;
+
+ // Go through the form elements:
+ for(var j = 0; j < elements.length; j++) {
+ this.displayFormElementDetails(elements[j], j, i, doc);
+ }
+ }
+ }
+
+ // Recursive call for all subframes:
+ for(var f=0; f < win.frames.length; f++) {
+ this.searchAndDisplayFormDetails(win.frames[f]);
+ }
+ },
+
+ isValidFormField: function(element) {
+ // ignore disabled (and return false) only if 'ignore disabled fields' is ticked
+ if(element.disabled && this.autofillFormsPrefs.getBoolPref('ignoreDisabledFields')) {
+ return false;
+ }
+ if(!arguments.callee.regExpFormFieldType) {
+ arguments.callee.regExpFormFieldType = new RegExp(
+ this.autofillFormsPrefs.getCharPref('regExpFormFieldTypes')
+ );
+ }
+ return arguments.callee.regExpFormFieldType.test(element.type);
+ },
+
+ displayFormElementDetails: function(element, elementNumber, formNumber, doc) {
+ // Create a unique id for the form element:
+ var id = 'autofillForms-f' + formNumber + '-e' + elementNumber;
+
+ // Remove the form details node if already present
+ // (nodeType 1 is an element node):
+ if(element.nextSibling && element.nextSibling.nodeType == 1 && element.nextSibling.getAttribute('id') == id) {
+ element.parentNode.removeChild(element.nextSibling);
+ return;
+ }
+
+ // Only display valid form fields:
+ if(this.isValidFormField(element)) {
+ // Create a "span" node with element details:
+ var text;
+ // Display the element name if available, else the element id if available, else an empty name:
+ if(element.name || !element.id) {
+ text = 'name="' + element.name;
+ } else {
+ text = 'id="' + element.id;
+ }
+ // Display the element value:
+ text += '" value="' + element.value + '"';
+ var span = doc.createElement('span');
+ span.setAttribute('id', id);
+ span.setAttribute('style', this.autofillFormsPrefs.getCharPref('formDetailsStyle'));
+ span.setAttribute('title', text);
+ span.appendChild(doc.createTextNode(text));
+
+ // Insert the form details node after the element:
+ if(element.nextSibling)
+ element.parentNode.insertBefore(span, element.nextSibling);
+ else
+ element.parentNode.appendChild(span);
+ }
+ },
+
+ ruleEditorInitialize: function() {
+ // Save the reference to the Autofill Forms preferences branch:
+ this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+ if(window.arguments && window.arguments[0] && window.arguments[0].attributes) {
+ this.currentRuleField = window.arguments[0];
+ }
+
+ // Initialize the ruleElementTypes:
+ this.ruleElementTypes = new Array();
+ this.ruleElementTypes.push('contains');
+ this.ruleElementTypes.push('beginsWith');
+ this.ruleElementTypes.push('endsWith');
+ this.ruleElementTypes.push('equals');
+
+ // If the rule editor is used to edit the site rule, add two predefined protocol rules:
+ if(this.currentRuleField && this.currentRuleField.id && this.currentRuleField.id.indexOf('SiteRule') != -1) {
+ this.ruleEditorAdd('beginsWith', 'http:\/\/');
+ this.ruleEditorAdd('beginsWith', 'https:\/\/');
+ } else {
+ this.ruleEditorAdd();
+ }
+ },
+
+ ruleEditorSave: function() {
+ if(document.getElementById('ruleElementsList')) {
+ var str = '';
+ var richlistbox = document.getElementById('ruleElementsList');
+ var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+ var menulists,textboxes;
+
+ // Go through the richlistbox items:
+ for(var i=0; i<richlistitems.length; i++) {
+ // Link the conditions as disjunctions (OR-Relations);
+ if(str.length != 0)
+ str += '|';
+ menulists = richlistitems[i].getElementsByTagName('menulist');
+ textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+ // Add the current condition to the string:
+ switch(menulists[0].selectedItem.value) {
+ case 'contains':
+ str += '(?:' + textboxes[0].value + ')';
+ break;
+ case 'beginsWith':
+ str += '(?:^' + textboxes[0].value + ')';
+ break;
+ case 'endsWith':
+ str += '(?:' + textboxes[0].value + '$)';
+ break;
+ case 'equals':
+ str += '(?:^' + textboxes[0].value + '$)';
+ break;
+ }
+ }
+ if(this.currentRuleField) {
+ // Set the current field value to the created string:
+ this.currentRuleField.value = str;
+ // Call the onchange handler:
+ if(this.currentRuleField.onchange) {
+ this.currentRuleField.onchange();
+ }
+ // Call the focus handler:
+ if(this.currentRuleField.focus) {
+ //this.currentRuleField.focus();
+ autofillForms.action(this.currentRuleField, 'focus');
+ }
+ }
+ }
+ return true;
+ },
+
+ ruleEditorAdd: function(type, ruleElement) {
+ if(document.getElementById('ruleElementsList')) {
+ var richlistbox = document.getElementById('ruleElementsList');
+
+ var richlistitem,menulist,menupopup,menuitem,textbox,label;
+
+ richlistitem = document.createElement('richlistitem');
+
+ // Create the condition type menu:
+ menulist = document.createElement('menulist');
+ menupopup = document.createElement('menupopup');
+
+ var selectedIndex = 0;
+
+ // Create the menu of ruleElementTypes:
+ for(var i=0; i<this.ruleElementTypes.length; i++) {
+ menuitem = document.createElement('menuitem');
+ menuitem.setAttribute(
+ 'value',
+ this.ruleElementTypes[i]
+ );
+ menuitem.setAttribute(
+ 'label',
+ this.getStringBundle().getString(this.ruleElementTypes[i] + 'RuleType')
+ );
+ menupopup.appendChild(menuitem);
+
+ // Set the selectedIndex:
+ if(type != null && type == this.ruleElementTypes[i])
+ selectedIndex = i;
+ }
+
+ menulist.appendChild(menupopup);
+ richlistitem.appendChild(menulist);
+
+ // Create the textbox:
+ textbox = document.createElement('textbox');
+ if(ruleElement != null)
+ textbox.setAttribute('value',ruleElement);
+ textbox.setAttribute('flex','1');
+ richlistitem.appendChild(textbox);
+
+ richlistbox.appendChild(richlistitem);
+
+ // Select the menuitem:
+ menulist.selectedIndex = selectedIndex;
+ }
+ },
+
+ ruleEditorRemove: function(index) {
+ var ruleElementsList = document.getElementById('ruleElementsList');
+ if(ruleElementsList) {
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('removeRuleConditionTitle'),
+ this.getStringBundle().getString('removeRuleConditionText')
+ )
+ ) {
+ return;
+ }
+ }
+
+ var richlistbox = ruleElementsList;
+ if(index)
+ richlistbox.selectedIndex = index;
+ if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
+ richlistbox.removeChild(richlistbox.selectedItem);
+ }
+ },
+
+ ruleEditorIsTextBoxFocused: function() {
+ return this.ruleEditorTextBoxFocused;
+ },
+
+ ruleEditorFocus: function() {
+ var focusedElement = document.commandDispatcher.focusedElement;
+
+ // Monitor if a textbox is focused:
+ if(!this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
+ this.ruleEditorTextBoxFocused = true;
+ } else if(this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
+ this.ruleEditorTextBoxFocused = false;
+ }
+ },
+
+ ruleEditorHandleKeyPress: function(event) {
+ // Only remove a dynamic tag on delete key press if no textbox is focused:
+ if(event.keyCode == 46 && !this.ruleEditorIsTextBoxFocused()) {
+ this.ruleEditorRemove();
+ }
+ },
+
+ ruleEditorFinalize: function() {
+ this.currentRuleField = null;
+ },
+
+ tagEditorInitialize: function() {
+ // Save the reference to the Autofill Forms preferences branch:
+ this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+ // Add existing tags to the list:
+ for(var i=0; i<this.getDynamicTags().length; i++) {
+ // Catch if the number of tags doesn't match the number of tag codes:
+ try {
+ this.tagEditorAdd(this.getDynamicTags()[i],this.getDynamicTagCodes()[i])
+ } catch(e) {
+ this.log(e);
+ }
+ }
+ },
+
+ tagEditorSave: function() {
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+ var textboxes;
+
+ var dynamicTags = new Array();
+ var dynamicTagCodes = new Array();
+
+ // Go through the richlistbox items:
+ for(var i=0; i<richlistitems.length; i++) {
+ textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+ // Add the dynamic tags and their associated tag codes to the lists:
+ if (textboxes[0].value != '' && textboxes[1].value != '') {
+ dynamicTags.push(this.makeSafe(textboxes[0].value));
+ dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+ }
+ }
+ // Save the lists in the preferences:
+ this.setDynamicTags(dynamicTags);
+ this.setDynamicTagCodes(dynamicTagCodes);
+ }
+ return true;
+ },
+
+ tagEditorAdd: function(tag, tagCode) {
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ var richlistitem,textbox;
+
+ richlistitem = document.createElement('richlistitem');
+
+ // Create the tag textbox:
+ textbox = document.createElement('textbox');
+ textbox.setAttribute('class','tag');
+ if(tag != null)
+ textbox.setAttribute('value',tag);
+ richlistitem.appendChild(textbox);
+
+ // Create the tagCode textbox:
+ textbox = document.createElement('textbox');
+ textbox.setAttribute('class','tagCode');
+ textbox.setAttribute('flex','1');
+ if(tagCode != null)
+ textbox.setAttribute('value',tagCode);
+ richlistitem.appendChild(textbox);
+
+ richlistbox.appendChild(richlistitem);
+ }
+ },
+
+ tagEditorRemove: function(index) {
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+ // Confirmation dialog:
+ if(!this.getPrompts().confirm(
+ null,
+ this.getStringBundle().getString('removeDynamicTagTitle'),
+ this.getStringBundle().getString('removeDynamicTagText')
+ )
+ ) {
+ return;
+ }
+ }
+ if(index)
+ richlistbox.selectedIndex = index;
+ if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
+ {
+ richlistbox.removeChild(richlistbox.selectedItem);
+ }
+ }
+ },
+
+ tagEditorValidate: function(index) {
+ var richlistbox = document.getElementById('tagList');
+ if(richlistbox) {
+ if(index)
+ richlistbox.selectedIndex = index;
+ if(richlistbox.selectedItem) {
+ var tagCode = richlistbox.selectedItem.lastChild.value;
+ var validationResultTextBox = document.getElementById('validationResultTextBox');
+ try {
+ validationResultTextBox.removeAttribute('style');
+ // We use eval() here without restrictions - the given tagCode must be trusted:
+ validationResultTextBox.value = eval(tagCode);
+ } catch(e) {
+ validationResultTextBox.setAttribute('style', 'color:red;');
+ validationResultTextBox.value = e;
+ }
+ }
+ }
+ },
+
+ tagEditorIsTextBoxFocused: function() {
+ return this.tagEditorTextBoxFocused;
+ },
+
+ tagEditorFocus: function() {
+ var focusedElement = document.commandDispatcher.focusedElement;
+
+ // Monitor if a textbox is focused:
+ if(!this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
+ this.tagEditorTextBoxFocused = true;
+ } else if(this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
+ this.tagEditorTextBoxFocused = false;
+ }
+ },
+
+ tagEditorHandleKeyPress: function(event) {
+ // Only remove a dynamic tag on delete key press if no textbox is focused:
+ if(event.keyCode == 46 && !this.tagEditorIsTextBoxFocused()) {
+ this.tagEditorRemove();
+ }
+ },
+
+ tagEditorFinalize: function() {
+ },
+
+ openHelp: function(topic) {
+ if(!topic) {
+ topic = '';
+ }
+ var url = this.autofillFormsPrefs.getCharPref('helpURL').replace(/\[TOPIC\]$/, topic);
+ this.openNewTab(url, true);
+ },
+
+ openNewTab: function(url, focus) {
+ var helpTab = this.getBrowser().addTab(url);
+ if(focus) {
+ this.getBrowser().selectedTab = helpTab;
+ this.getWindowMediator().getMostRecentWindow('navigator:browser').focus();
+ }
+ },
+
+ addLeadingZeros: function(number, length) {
+ number = number.toString();
+ while(number.length < length) {
+ number = '0'+number;
+ }
+ return number;
+ },
+
+ escapeRegExp: function(str) {
+ if (!arguments.callee.regExp) {
+ var specials = new Array(
+ '^', '$', '*', '+', '?', '.', '|', '/',
+ '(', ')', '[', ']', '{', '}', '\\'
+ );
+ arguments.callee.regExp = new RegExp(
+ '(\\' + specials.join('|\\') + ')', 'g'
+ );
+ }
+ return str.replace(arguments.callee.regExp, '\\$1');
+ },
+
+ getClipboardText: function() {
+ var clipboardText = null;
+ var clip = Components.classes['@mozilla.org/widget/clipboard;1']
+ .getService(Components.interfaces.nsIClipboard);
+ if(!clip) {
+ return null;
+ }
+
+ var trans = Components.classes['@mozilla.org/widget/transferable;1']
+ .createInstance(Components.interfaces.nsITransferable);
+ if(!trans) {
+ return null;
+ }
+
+ trans.addDataFlavor('text/unicode');
+
+ clip.getData(trans, clip.kGlobalClipboard);
+
+ var str = new Object();
+ var strLength = new Object();
+
+ trans.getTransferData('text/unicode', str, strLength);
+
+ if(str) {
+ str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
+ }
+ if(str) {
+ clipboardText = str.data.substring(0, strLength.value / 2);
+ }
+
+ return clipboardText
+ },
+
+ getMasterSecurityDevice: function() {
+ return Components.classes['@mozilla.org/security/pk11tokendb;1']
+ .getService(Components.interfaces.nsIPK11TokenDB);
+ },
+
+ log: function(aMessage, aSourceName, aSourceLine, aLineNumber, aColumnNumber, aFlags, aCategory) {
+ var consoleService = Components.classes['@mozilla.org/consoleservice;1']
+ .getService(Components.interfaces.nsIConsoleService);
+ if(aSourceName != 'undefined') {
+ var scriptError = Components.classes["@mozilla.org/scripterror;1"]
+ .createInstance(Components.interfaces.nsIScriptError);
+ scriptError.init(
+ aMessage,
+ aSourceName,
+ aSourceLine,
+ aLineNumber,
+ aColumnNumber,
+ aFlags,
+ aCategory
+ );
+ consoleService.logMessage(scriptError);
+ } else {
+ consoleService.logStringMessage(aMessage);
+ }
+ },
+
+ finalizeToolbarButtonStatus: function() {
+ var autofillFormsButton = document.getElementById('autofillFormsButton');
+ var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
+ if(!autofillFormsButton && !hideToolbarButton) {
+ // If the toolbar button icon has been removed from the toolbar by drag&drop
+ // enable the hideToolbarButton setting:
+ this.autofillFormsPrefs.setBoolPref('hideToolbarButton', true);
+ } else if(autofillFormsButton && !autofillFormsButton.getAttribute('hidden')) {
+ // If the toolbar button icon has been added to the toolbar by drag&drop
+ // disable the hideToolbarButton setting:
+ this.autofillFormsPrefs.setBoolPref('hideToolbarButton', false);
+ }
+ },
+
+ finalize: function() {
+ this.finalizeToolbarButtonStatus();
+
+ // Remove the content area context menu listener:
+ var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
+ if(contentAreaContextMenu) {
+ contentAreaContextMenu.removeEventListener(
+ 'popupshowing',
+ this.contentAreaContextMenuEventListener,
+ false
+ );
+ }
+
+ // Remove the preferences Observer:
+ this.autofillFormsPrefs.removeObserver('', this);
+ }
+
+}
diff --git a/chrome/content/autofillFormsOptions.js b/chrome/content/autofillFormsOptions.js
new file mode 100644
index 0000000..ea1c679
--- /dev/null
+++ b/chrome/content/autofillFormsOptions.js
@@ -0,0 +1,10 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+window.addEventListener('load', function() { autofillForms.optionsInitialize(); }, false);
+window.addEventListener('unload', function() { autofillForms.optionsFinalize(); }, false);
diff --git a/chrome/content/autofillFormsOptions.xul b/chrome/content/autofillFormsOptions.xul
new file mode 100644
index 0000000..89ea3df
--- /dev/null
+++ b/chrome/content/autofillFormsOptions.xul
@@ -0,0 +1,620 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://autofillForms/skin/autofillFormsOptions.css" type="text/css"?>
+<!DOCTYPE overlay SYSTEM "chrome://autofillForms/locale/autofillForms.dtd">
+<prefwindow xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="autofillFormsPrefs"
+ title="&options.title;"
+ width="650"
+ buttons="accept,cancel,help,extra1"
+ buttonlabelextra1="&resetallprofiles.label;"
+ ondialogextra1="autofillForms.resetAllProfiles();"
+ ondialoghelp="autofillForms.openHelp(event.target.currentPane.helpTopic);"
+ persist="screenX screenY width height sizemode">
+ <prefpane
+ id="autofillFormsPrefPaneSimple"
+ label="&prefpanesimplelabel;"
+ flex="1"
+ helpTopic="Simple Editor">
+ <preferences>
+ </preferences>
+ <vbox flex="1">
+ <hbox align="center">
+ <menulist id="simpleInterfaceProfileMenuList" oncommand="autofillForms.setProfileIndex(this.selectedIndex);"/>
+ <spacer flex="1"/>
+ </hbox>
+ <separator class="thin"/>
+ <vbox flex="1" id="simpleInterfaceRowsContainer" style="overflow:auto;max-height:450px;">
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows id="simpleInterfaceRows"></rows>
+ </grid>
+ </vbox>
+ </vbox>
+ </prefpane>
+ <prefpane
+ id="autofillFormsPrefPaneProfiles"
+ label="&prefpaneprofileslabel;"
+ flex="1"
+ helpTopic="Profiles">
+ <preferences>
+ <preference id="autoSelectBestProfile" name="extensions.autofillForms at blueimp.net.autoSelectBestProfile" type="bool"/>
+ <preference id="enableGlobalProfile" name="extensions.autofillForms at blueimp.net.enableGlobalProfile" type="bool"/>
+ </preferences>
+ <tabbox flex="1">
+ <tabs>
+ <tab label="&prefpaneprofileslabel;"/>
+ <tab label="&prefpaneadvancedlabel;"/>
+ </tabs>
+ <tabpanels flex="1">
+ <vbox flex="1">
+ <grid flex="1">
+ <rows>
+ <row align="center" flex="1"/>
+ <separator class="thin"/>
+ <row align="center"/>
+ </rows>
+ <columns>
+ <column flex="1">
+ <tree id="profilesTree" seltype="single" flex="1" enableColumnDrag="true" onkeypress="autofillForms.profilesTreeHandleKeyPress(event)" onselect="autofillForms.selectedProfile(event);">
+ <treecols>
+ <treecol id="profilesTreeColName" label="&profilename.label;" flex="1" persist="width ordinal hidden" onclick="autofillForms.sortProfiles(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="profilesTreeColSiteRule" label="&profilesiterule.label;" flex="1" persist="width ordinal hidden" hidden="false" onclick="autofillForms.sortProfiles(event);"/>
+ </treecols>
+ <treechildren id="profilesTreeChildren" />
+ </tree>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&profilename.label;:"/>
+ <textbox id="profileLabelTextBox" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="&profilesiterule.label;:"/>
+ <textbox id="profileSiteRuleTextBox2" flex="1" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
+ </row>
+ </rows>
+ </grid>
+ </column>
+ <column>
+ <vbox>
+ <button align="left" id="buttonMoveUpProfile" class="move up" disabled="true" label="&moveup.label;" accesskey="&moveup.accesskey;" oncommand="autofillForms.moveUpProfile(event);"/>
+ <button align="left" id="buttonMoveDownProfile" class="move down" disabled="true" label="&movedown.label;" accesskey="&movedown.accesskey;" oncommand="autofillForms.moveDownProfile(event);"/>
+ <button label="&add.label;" accesskey="&add.accesskey;" oncommand="autofillForms.addProfile(document.getElementById('profileLabelTextBox').value);"/>
+ <button label="&remove.label;" accesskey="&remove.accesskey;" oncommand="autofillForms.removeProfile(event);"/>
+ </vbox>
+ <vbox>
+ <button id="buttonApplyProfile" label="&apply.label;" oncommand="autofillForms.changeProfileLabel(document.getElementById('profileLabelTextBox').value);"/>
+ <button label="&ruleeditorbutton.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsRuleEditor.xul', document.getElementById('profileSiteRuleTextBox2'));"/>
+ </vbox>
+ </column>
+ </columns>
+ </grid>
+ <separator class="thin"/>
+ <separator class="groove"/>
+ <separator class="thin"/>
+ <groupbox>
+ <caption label="&profileimportexport.label;"/>
+ <hbox>
+ <button label="&profileimportbutton.label;" oncommand="autofillForms.importProfile();"/>
+ <button label="&profileexportallbutton.label;" oncommand="autofillForms.exportAllProfiles();"/>
+ <button label="&profileexportbutton.label;" oncommand="autofillForms.exportProfile();"/>
+ <spacer flex="1"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+ <vbox flex="1" style="">
+ <checkbox label="&autoselectbestprofile.label;" preference="autoSelectBestProfile"/>
+ <separator class="thin"/>
+ <hbox align="center">
+ <checkbox label="&enableglobalprofile.label;" preference="enableGlobalProfile"/>
+ <spacer flex="1"/>
+ <menulist id="globalProfileMenuList" oncommand="autofillForms.setGlobalProfileIndex(this.selectedIndex);"/>
+ </hbox>
+ <separator class="thin"/>
+ <hbox align="center">
+ <label control="contextMenuProfileMenuList" value="&formfieldscontextmenu.label;"/>
+ <spacer flex="1"/>
+ <menulist id="contextMenuProfileMenuList" oncommand="autofillForms.setFormFieldsContextMenuProfileIndex(this.selectedIndex-3);">
+ <menupopup>
+ <menuitem label="&formfieldscontextmenuitemallprofiles.label;"/>
+ <menuitem label="&formfieldscontextmenuitemactiveprofile.label;"/>
+ <menuseparator/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ </vbox>
+ </tabpanels>
+ </tabbox>
+ </prefpane>
+ <prefpane
+ id="autofillFormsPrefPaneMain"
+ label="&prefpanemainlabel;"
+ flex="1"
+ helpTopic="Advanced Editor">
+ <preferences>
+ </preferences>
+ <vbox flex="1" id="autofillFormsPrefPaneMainBox" style="">
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&profile.label;"/>
+ <hbox align="center">
+ <menulist id="profilesMenuList" editable="true" flex="1" oncommand="autofillForms.setProfileIndex(this.selectedIndex);"/>
+ <button id="buttonApplyProfile" label="&apply.label;" oncommand="autofillForms.changeProfileLabel(document.getElementById('profilesMenuList').inputField.value);"/>
+ <button id="buttonAddProfile" label="&add.label;" oncommand="autofillForms.addProfile(document.getElementById('profilesMenuList').inputField.value);"/>
+ <button id="buttonRemoveProfile" label="&remove.label;" oncommand="autofillForms.removeProfile(event);"/>
+ </hbox>
+ </row>
+ <row align="center">
+ <label value="&profilesiterule.label;:"/>
+ <hbox align="center">
+ <textbox id="profileSiteRuleTextBox" flex="1" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
+ <button label="&ruleeditorbutton.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsRuleEditor.xul', document.getElementById('profileSiteRuleTextBox'));"/>
+ </hbox>
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <tree id="fieldRulesTree" seltype="multiple" flex="1" editable="true" enableColumnDrag="true" onkeypress="autofillForms.handleKeyPress(event)" onselect="autofillForms.selectedFieldRule(event);">
+ <treecols>
+ <treecol id="fieldRuleName" label="&fieldrulename.label;" flex="1" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="fieldRuleValue" label="&fieldrulevalue.label;" flex="2" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="fieldRuleFieldRule" hidden="true" label="&fieldrulefieldrule.label;" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="fieldRuleSiteRule" hidden="true" label="&fieldrulesiterule.label;" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="fieldRuleOverwrite" label="&fieldruleoverwrite.label;" type="checkbox" editable="true" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="fieldRuleEnabled" label="&fieldruleenabled.label;" type="checkbox" editable="true" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+ </treecols>
+ <treechildren id="fieldRulesTreeChildren" />
+ </tree>
+ <separator class="thin"/>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label control="fieldRuleNameTextBox" value="&fieldrulename.label;:"/>
+ <textbox id="fieldRuleNameTextBox" onchange="autofillForms.applyFieldRule(event);"/>
+ <button align="left" id="buttonMoveUpFieldRule" class="move up" disabled="true" label="&moveup.label;" accesskey="&moveup.accesskey;" oncommand="autofillForms.moveUpFieldRule(event);"/>
+ </row>
+ <row align="center">
+ <label control="fieldRuleValueTextBox" value="&fieldrulevalue.label;:"/>
+ <textbox id="fieldRuleValueTextBox" onchange="autofillForms.applyFieldRule(event);" oninput="this.value=autofillForms.replaceControlCharacters(this.value)" newlines="pasteintact"/>
+ <button align="left" id="buttonMoveDownFieldRule" class="move down" disabled="true" label="&movedown.label;" accesskey="&movedown.accesskey;" oncommand="autofillForms.moveDownFieldRule(event);"/>
+ </row>
+ <row align="center">
+ <label control="fieldRuleFieldRuleTextBox" value="&fieldrulefieldrule.label;:"/>
+ <textbox id="fieldRuleFieldRuleTextBox" onchange="autofillForms.applyFieldRule(event);"/>
+ <button id="buttonEditFieldRule" label="&ruleeditorbutton.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsRuleEditor.xul', document.getElementById('fieldRuleFieldRuleTextBox'));"/>
+ </row>
+ <row align="center">
+ <label control="fieldRuleSiteRuleTextBox" value="&fieldrulesiterule.label;:"/>
+ <textbox id="fieldRuleSiteRuleTextBox" onchange="autofillForms.applyFieldRule(event);"/>
+ <button id="buttonEditSiteRule" label="&ruleeditorbutton.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsRuleEditor.xul', document.getElementById('fieldRuleSiteRuleTextBox'));"/>
+ </row>
+ <row align="center">
+ <spacer/>
+ <hbox>
+ <button id="buttonAddFieldRule" label="&add.label;" accesskey="&add.accesskey;" oncommand="autofillForms.addFieldRule(event);"/>
+ <button id="buttonRemoveFieldRule" disabled="true" label="&remove.label;" accesskey="&remove.accesskey;" oncommand="autofillForms.removeFieldRule(event);"/>
+ </hbox>
+ <spacer/>
+ </row>
+ </rows>
+ </grid>
+ </vbox>
+ </prefpane>
+ <prefpane
+ id="autofillFormsPrefPaneAdvanced"
+ label="&prefpaneadvancedlabel;"
+ flex="1"
+ helpTopic="Settings">
+ <preferences>
+ <preference id="storeEncrypted" name="extensions.autofillForms at blueimp.net.storeEncrypted" type="bool"/>
+ <preference id="enableDynamicTags" name="extensions.autofillForms at blueimp.net.enableDynamicTags" type="bool"/>
+ <preference id="ignoreDisabledRulesOnAutofill" name="extensions.autofillForms at blueimp.net.ignoreDisabledRulesOnAutofill" type="bool"/>
+ <preference id="ignoreDisabledFields" name="extensions.autofillForms at blueimp.net.ignoreDisabledFields" type="bool"/>
+ <preference id="focusLastFormElementMatch" name="extensions.autofillForms at blueimp.net.focusLastFormElementMatch" type="bool"/>
+ <preference id="matchAgainstLabels" name="extensions.autofillForms at blueimp.net.matchAgainstLabels" type="bool"/>
+ <preference id="labelsStrictMode" name="extensions.autofillForms at blueimp.net.labelsStrictMode" type="bool"/>
+ <preference id="disableAlternatives" name="extensions.autofillForms at blueimp.net.disableAlternatives" type="bool"/>
+ <preference id="rememberAlternativesIndex" name="extensions.autofillForms at blueimp.net.rememberAlternativesIndex" type="bool"/>
+ <preference id="matchAgainstPositions" name="extensions.autofillForms at blueimp.net.matchAgainstPositions" type="bool"/>
+ <preference id="callOnChangeAfterFillingFields" name="extensions.autofillForms at blueimp.net.callOnChangeAfterFillingFields" type="bool"/>
+ <preference id="positionsIdentifier" name="extensions.autofillForms at blueimp.net.positionsIdentifier" type="unichar"/>
+ <preference id="placeholderLineBreak" name="extensions.autofillForms at blueimp.net.placeholderLineBreak" type="unichar"/>
+ <preference id="placeholderTab" name="extensions.autofillForms at blueimp.net.placeholderTab" type="unichar"/>
+ <preference id="useConfigDirectory" name="extensions.autofillForms at blueimp.net.useConfigDirectory" type="bool"/>
+ </preferences>
+ <tabbox flex="1">
+ <tabs>
+ <tab label="&prefpanemainlabel;"/>
+ <tab label="&prefpaneadvancedlabel;"/>
+ </tabs>
+ <tabpanels flex="1">
+ <vbox flex="1">
+ <groupbox>
+ <caption label="&securitycaption.label;"/>
+ <checkbox label="&storeencrypted.label;" preference="storeEncrypted"/>
+ </groupbox>
+ <separator class="thin"/>
+ <groupbox flex="1">
+ <caption label="&miscellaneous.label;"/>
+ <vbox flex="1" style="overflow:auto;">
+ <hbox align="center">
+ <checkbox label="&tagsenable.label;" preference="enableDynamicTags"/>
+ <spacer flex="1"/>
+ <button id="buttonEditTags" label="&tagsedit.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsTagEditor.xul', null);"/>
+ </hbox>
+ <checkbox label="&ignoredisabledrulesonautofill.label;" preference="ignoreDisabledRulesOnAutofill"/>
+ <checkbox label="&ignoredisabledfields.label;" preference="ignoreDisabledFields"/>
+ <checkbox label="&matchagainstlabels.label;" preference="matchAgainstLabels"/>
+ <checkbox label="&identifylabelsinstrictmode.label;" preference="labelsStrictMode"/>
+ <checkbox label="&disablealternatives.label;" preference="disableAlternatives"/>
+ <checkbox label="&rememberalternativesindex.label;" preference="rememberAlternativesIndex"/>
+ <checkbox label="&focuslastformelementmatch.label;" preference="focusLastFormElementMatch"/>
+ <checkbox label="&callonchangeafterfillingfields.label;" preference="callOnChangeAfterFillingFields"/>
+ <hbox align="center">
+ <checkbox label="&matchagainstpositions.label;" preference="matchAgainstPositions"/>
+ <spacer flex="1"/>
+ <textbox id="positionsIdentifierTextbox" preference="positionsIdentifier" class="placeholderTextbox"/>
+ </hbox>
+ <hbox align="center">
+ <label control="placeholderLineBreakTextbox" value="&placeholderlinebreak.label;"/>
+ <spacer flex="1"/>
+ <textbox id="placeholderLineBreakTextbox" preference="placeholderLineBreak" class="placeholderTextbox"/>
+ </hbox>
+ <hbox align="center">
+ <label control="placeholderTabTextbox" value="&placeholdertab.label;"/>
+ <spacer flex="1"/>
+ <textbox id="placeholderTabTextbox" preference="placeholderTab" class="placeholderTextbox"/>
+ </hbox>
+ </vbox>
+ </groupbox>
+ <separator class="thin"/>
+ <groupbox>
+ <caption label="&tagimportexport.label;"/>
+ <hbox>
+ <button label="&tagimportbutton.label;" oncommand="autofillForms.importDynamicTagsFromSettings();"/>
+ <button label="&tagexportbutton.label;" oncommand="autofillForms.exportDynamicTagsFromSettings();"/>
+ <spacer flex="1"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+ <vbox flex="1">
+ <groupbox>
+ <caption label="&storagelocationcaption.label;"/>
+ <checkbox label="&useconfigdirectory.label;" preference="useConfigDirectory"/>
+ <hbox>
+ <textbox id="configDirectoryTextBox" readonly="true" flex="1" />
+ <button label="&browsedir.label;" icon="open" oncommand="autofillForms.setConfigDirectory(document.getElementById('configDirectoryTextBox'));"/>
+ <button label="&resetdir.label;" icon="clear" oncommand="autofillForms.resetConfigDirectory(document.getElementById('configDirectoryTextBox'));"/>
+ </hbox>
+ <hbox>
+ <button label="&opendir.label;" icon="open" oncommand="autofillForms.openConfigDirectory();"/>
+ <spacer flex="1"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+ </tabpanels>
+ </tabbox>
+ </prefpane>
+ <prefpane
+ id="autofillFormsPrefPaneGUI"
+ label="&prefpaneguilabel;"
+ flex="1"
+ helpTopic="Interface">
+ <preferences>
+ <preference id="hideStatusbarIcon" name="extensions.autofillForms at blueimp.net.hideStatusbarIcon" type="bool"/>
+ <preference id="hideContextMenuItem" name="extensions.autofillForms at blueimp.net.hideContextMenuItem" type="bool"/>
+ <preference id="hideFormFieldsContextMenu" name="extensions.autofillForms at blueimp.net.hideFormFieldsContextMenu" type="bool"/>
+ <preference id="hideToolbarButton" name="extensions.autofillForms at blueimp.net.hideToolbarButton" type="bool"/>
+ <preference id="hideToolbarButtonMenu" name="extensions.autofillForms at blueimp.net.hideToolbarButtonMenu" type="bool"/>
+ <preference id="enableConfirmationDialogs" name="extensions.autofillForms at blueimp.net.enableConfirmationDialogs" type="bool"/>
+ <preference id="highlightStyleMatch" name="extensions.autofillForms at blueimp.net.highlightStyleMatch" type="unichar"/>
+ <preference id="highlightStyleNoMatch" name="extensions.autofillForms at blueimp.net.highlightStyleNoMatch" type="unichar"/>
+ <preference id="formDetailsStyle" name="extensions.autofillForms at blueimp.net.formDetailsStyle" type="unichar"/>
+ </preferences>
+ <tabbox flex="1">
+ <tabs>
+ <tab label="&viewcaption.label;"/>
+ <tab label="&shortcutscaption.label;"/>
+ <tab label="&mousebuttonscaption.label;"/>
+ </tabs>
+ <tabpanels flex="1">
+ <vbox flex="1" style="">
+ <checkbox label="&hidetoolbarbutton.label;" preference="hideToolbarButton"/>
+ <checkbox label="&hidetoolbarbuttonmenu.label;" preference="hideToolbarButtonMenu"/>
+ <checkbox label="&hidestatusbaricon.label;" preference="hideStatusbarIcon"/>
+ <checkbox label="&hidecontextmenuitem.label;" preference="hideContextMenuItem"/>
+ <checkbox label="&hideformfieldscontextmenu.label;" preference="hideFormFieldsContextMenu"/>
+ <checkbox label="&enableconfirmationdialogs.label;" preference="enableConfirmationDialogs"/>
+ <separator class="thin"/>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1" minwidth="200"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label control="highlightStyleMatchTextbox" value="&highlightstylematch.label;"/>
+ <textbox id="highlightStyleMatchTextbox" preference="highlightStyleMatch"/>
+ </row>
+ <row align="center">
+ <label control="highlightStyleNoMatchTextbox" value="&highlightstylenomatch.label;"/>
+ <textbox id="highlightStyleNoMatchTextbox" preference="highlightStyleNoMatch"/>
+ </row>
+ <row align="center">
+ <label control="formDetailsStyle" value="&formdetailsstyle.label;"/>
+ <textbox id="formDetailsStyle" preference="formDetailsStyle"/>
+ </row>
+ </rows>
+ </grid>
+ </vbox>
+ <vbox flex="1" style="">
+ <grid>
+ <columns>
+ <column class="shortCutsLabelColumn"/>
+ <column class="shortCutsKeyColumn" flex="1"/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <description control="shortcut">&shortcutfilloutforms.label;</description>
+ <textbox
+ id="shortcut"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcut');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcut');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutSubmit">&shortcutfilloutandsubmitforms.label;</description>
+ <textbox
+ id="shortcutSubmit"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutSubmit');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutSubmit');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutAllTabs">&shortcutfilloutformsonalltabs.label;</description>
+ <textbox
+ id="shortcutAllTabs"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutAllTabs');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutAllTabs');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutFromProfileSelection">&shortcutfilloutformsfromprofileselection.label;</description>
+ <textbox
+ id="shortcutFromProfileSelection"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutFromProfileSelection');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutFromProfileSelection');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutProfile">&shortcutprofileswitcher.label;</description>
+ <textbox
+ id="shortcutProfile"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutProfile');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutProfile');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutSettings">&shortcutsettings.label;</description>
+ <textbox
+ id="shortcutSettings"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutSettings');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutSettings');"
+ />
+ </row>
+ <row align="center">
+ <description control="shortcutDisplayFormDetails">&shortcutdisplayformdetails.label;</description>
+ <textbox
+ id="shortcutDisplayFormDetails"
+ class="shortcutTextbox"
+ readonly="true"
+ onkeypress="autofillForms.applyShortcut(event, 'shortcutDisplayFormDetails');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableShortcut(event, 'shortcutDisplayFormDetails');"
+ />
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <description class="shortcutInfo">&shortcutinfo.label;</description>
+ </vbox>
+ <vbox flex="1" style="">
+ <grid>
+ <columns>
+ <column class="shortCutsLabelColumn"/>
+ <column class="shortCutsKeyColumn" flex="1"/>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <description control="mouseShortcut">&shortcutfilloutforms.label;</description>
+ <textbox
+ id="mouseShortcut"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcut');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcut');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutSubmit">&shortcutfilloutandsubmitforms.label;</description>
+ <textbox
+ id="mouseShortcutSubmit"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutSubmit');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutSubmit');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutAllTabs">&shortcutfilloutformsonalltabs.label;</description>
+ <textbox
+ id="mouseShortcutAllTabs"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutAllTabs');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutAllTabs');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutFromProfileSelection">&shortcutfilloutformsfromprofileselection.label;</description>
+ <textbox
+ id="mouseShortcutFromProfileSelection"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutFromProfileSelection');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutFromProfileSelection');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutProfile">&shortcutprofileswitcher.label;</description>
+ <textbox
+ id="mouseShortcutProfile"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutProfile');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutProfile');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutSettings">&shortcutsettings.label;</description>
+ <textbox
+ id="mouseShortcutSettings"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutSettings');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutSettings');"
+ />
+ </row>
+ <row align="center">
+ <description control="mouseShortcutDisplayFormDetails">&shortcutdisplayformdetails.label;</description>
+ <textbox
+ id="mouseShortcutDisplayFormDetails"
+ class="mouseShortcutTextbox"
+ readonly="true"
+ />
+ <button
+ label="&mousebuttonclick.label;"
+ onclick="autofillForms.applyMouseButton(event, 'mouseShortcutDisplayFormDetails');"
+ />
+ <button
+ label="&disable.label;"
+ oncommand="autofillForms.disableMouseButton(event, 'mouseShortcutDisplayFormDetails');"
+ />
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <description class="shortcutInfo">&mouseshortcutinfo.label;</description>
+ </vbox>
+ </tabpanels>
+ </tabbox>
+ </prefpane>
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillForms.js"
+ />
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillFormsOptions.js"
+ />
+ <stringbundleset id="stringbundleset">
+ <stringbundle
+ id="autofillFormsStringBundle"
+ src="chrome://autofillForms/locale/autofillForms.properties"
+ />
+ </stringbundleset>
+</prefwindow>
diff --git a/chrome/content/autofillFormsOverlay.js b/chrome/content/autofillFormsOverlay.js
new file mode 100644
index 0000000..08becc3
--- /dev/null
+++ b/chrome/content/autofillFormsOverlay.js
@@ -0,0 +1,10 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+window.addEventListener('load', function() { autofillForms.initialize(); }, false);
+window.addEventListener('unload', function() { autofillForms.finalize(); }, false);
diff --git a/chrome/content/autofillFormsOverlay.xul b/chrome/content/autofillFormsOverlay.xul
new file mode 100644
index 0000000..179c261
--- /dev/null
+++ b/chrome/content/autofillFormsOverlay.xul
@@ -0,0 +1,183 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://autofillForms/skin/autofillForms.css" type="text/css"?>
+<!DOCTYPE overlay SYSTEM "chrome://autofillForms/locale/autofillForms.dtd">
+<overlay id="autofillForms" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillForms.js"
+ />
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillFormsOverlay.js"
+ />
+ <stringbundleset id="stringbundleset">
+ <stringbundle
+ id="autofillFormsStringBundle"
+ src="chrome://autofillForms/locale/autofillForms.properties"
+ />
+ </stringbundleset>
+ <window id="main-window">
+ <popupset id="autofillFormsPopUpSet">
+ <tooltip
+ id="autofillFormsTooltip"
+ onpopupshowing="autofillForms.tooltip(event);"
+ orient="vertical"
+ />
+ <menupopup id="autofillFormsPopupMenu" position="after_start">
+ <menu
+ id="autofillFormsPopupProfileMenuItem"
+ label="&profilemenuitem.label;"
+ class="menu-iconic autofillFormsProfileIcon">
+ <menupopup onpopupshowing="if(event.target == this) autofillForms.initProfilesPopupMenu(event);"/>
+ </menu>
+ <menuitem
+ id="autofillFormsPopupSettingsMenuItem"
+ label="&settingsmenuitem.label;"
+ class="menuitem-iconic autofillFormsSettingsIcon"
+ oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');"
+ />
+ <menuitem
+ id="autofillFormsPopupHelpMenuItem"
+ label="&helpmenuitem.label;"
+ class="menuitem-iconic autofillFormsHelpIcon"
+ oncommand="autofillForms.openHelp();"
+ />
+ </menupopup>
+ <menupopup
+ id="autofillFormsProfileSelectionPopup"
+ position="after_start"
+ />
+ </popupset>
+ </window>
+ <commandset id="mainCommandSet">
+ <command
+ id="autofillForms"
+ oncommand="autofillForms.fillForms();"
+ />
+ <command
+ id="autofillFormsSubmit"
+ oncommand="autofillForms.fillForms(null, null, true);"
+ />
+ <command
+ id="autofillFormsAllTabs"
+ oncommand="autofillForms.fillForms(null, null, null, true);"
+ />
+ <command
+ id="autofillFormsFromProfileSelection"
+ oncommand="autofillForms.profileSelectionFormFillPrompt(event);"
+ />
+ <command
+ id="autofillFormsProfile"
+ oncommand="autofillForms.showProfileSwitcher(event);"
+ />
+ <command
+ id="autofillFormsSettings"
+ oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');"
+ />
+ <command
+ id="autofillFormsDisplayFormDetails"
+ oncommand="autofillForms.displayFormDetails();"
+ />
+ </commandset>
+ <statusbar id="status-bar">
+ <statusbarpanel
+ id="autofillFormsPanelIcon"
+ class="statusbarpanel-menu-iconic autofillFormsIcon"
+ onclick="autofillForms.clickHandler(event);"
+ context="autofillFormsPopupMenu"
+ tooltip="autofillFormsTooltip"
+ hidden="true"
+ />
+ </statusbar>
+ <toolbarpalette id="BrowserToolbarPalette">
+ <toolbarbutton
+ id="autofillFormsButton"
+ class="toolbarbutton-1 autofillFormsButton"
+ label="&toolbarbutton.label;"
+ tooltip="autofillFormsTooltip"
+ oncommand="if(event.target == this) autofillForms.commandHandler(event);"
+ onclick="autofillForms.clickHandler(event);"
+ context="autofillFormsPopupMenu"
+ type="menu-button">
+ <menupopup id="autofillFormsButtonMenu" position="after_start">
+ <menu
+ id="autofillFormsButtonProfileMenuItem"
+ label="&profilemenuitem.label;"
+ class="menu-iconic autofillFormsProfileIcon">
+ <menupopup onpopupshowing="if(event.target == this) autofillForms.initProfilesPopupMenu(event);"/>
+ </menu>
+ <menuitem
+ id="autofillFormsButtonSettingsMenuItem"
+ label="&settingsmenuitem.label;"
+ class="menuitem-iconic autofillFormsSettingsIcon"
+ oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');"
+ />
+ <menuitem
+ id="autofillFormsButtonHelpMenuItem"
+ label="&helpmenuitem.label;"
+ class="menuitem-iconic autofillFormsHelpIcon"
+ oncommand="autofillForms.openHelp();"
+ />
+ </menupopup>
+ </toolbarbutton>
+ </toolbarpalette>
+ <popup id="contentAreaContextMenu">
+ <menuseparator
+ id="autofillFormsContextMenuSeparator2"
+ insertafter="context-selectall"
+ />
+ <menuitem
+ id="autofillFormsDisplayFormDetailsContextMenuItem"
+ label="&formdetails.label;"
+ insertafter="context-selectall"
+ oncommand="autofillForms.displayFormDetails();"
+ />
+ <menuitem
+ id="autofillFormsAddFormAsProfileContextMenuItem"
+ label="&addformasprofilecontextmenuitem.label;"
+ accesskey="&addformasprofilecontextmenuitem.accesskey;"
+ insertafter="context-selectall"
+ oncommand="autofillForms.addFormAsProfile(event);"
+ />
+ <menuitem
+ id="autofillFormsAddRuleContextMenuItem"
+ label="&addrulecontextmenuitem.label;"
+ accesskey="&addrulecontextmenuitem.accesskey;"
+ insertafter="context-selectall"
+ oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');"
+ />
+ <menu
+ id="autofillFormsManualFillContextMenu"
+ label="&manualfillcontextmenu.label;"
+ accesskey="&manualfillcontextmenu.accesskey;"
+ insertafter="context-selectall"
+ class="menu-iconic autofillFormsIcon">
+ <menupopup
+ onpopupshowing="if(event.target == this) autofillForms.initManualFillContextMenu(event);"
+ />
+ </menu>
+ <menuitem
+ id="autofillFormsContextMenuItem"
+ label="&autofillformscontextmenuitem.label;"
+ accesskey="&autofillformscontextmenuitem.accesskey;"
+ insertafter="context-selectall"
+ class="menuitem-iconic autofillFormsIcon"
+ oncommand="autofillForms.fillForms();"
+ />
+ <menu
+ id="autofillFormsContextMenu"
+ label="&autofillformscontextmenuitem.label;"
+ accesskey="&autofillformscontextmenuitem.accesskey;"
+ insertafter="context-selectall"
+ class="menu-iconic autofillFormsIcon"
+ hidden="true">
+ <menupopup
+ onpopupshowing="autofillForms.prepareProfileSelectionFormFillMenu(this);"
+ />
+ </menu>
+ <menuseparator
+ id="autofillFormsContextMenuSeparator1"
+ insertafter="context-selectall"
+ />
+ </popup>
+</overlay>
\ No newline at end of file
diff --git a/chrome/content/autofillFormsRuleEditor.js b/chrome/content/autofillFormsRuleEditor.js
new file mode 100644
index 0000000..d447e58
--- /dev/null
+++ b/chrome/content/autofillFormsRuleEditor.js
@@ -0,0 +1,11 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+window.addEventListener('load', function() { autofillForms.ruleEditorInitialize(); }, false);
+window.addEventListener('unload', function() { autofillForms.ruleEditorFinalize(); }, false);
+window.addEventListener('focus', function() { autofillForms.ruleEditorFocus(); }, true);
diff --git a/chrome/content/autofillFormsRuleEditor.xul b/chrome/content/autofillFormsRuleEditor.xul
new file mode 100644
index 0000000..ea88adc
--- /dev/null
+++ b/chrome/content/autofillFormsRuleEditor.xul
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://autofillForms/skin/autofillFormsRuleEditor.css" type="text/css"?>
+<!DOCTYPE overlay SYSTEM "chrome://autofillForms/locale/autofillForms.dtd">
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="autofillFormsRuleEditor"
+ title="&ruleeditor.title;"
+ buttons="accept,cancel,help"
+ ondialogaccept="autofillForms.ruleEditorSave();"
+ ondialogcancel="return true;"
+ ondialoghelp="autofillForms.openHelp('Rule Editor');"
+ persist="screenX screenY width height sizemode"
+ width="370"
+ height="370">
+ <vbox flex="1">
+ <label>&ruleeditorinfo.label;</label>
+ <separator class="thin"/>
+ <label control="ruleElementsList" >&ruleeditorcondition.label;</label>
+ <separator class="thin"/>
+ <richlistbox id="ruleElementsList" flex="1" onkeypress="autofillForms.ruleEditorHandleKeyPress(event)"/>
+ <separator class="thin"/>
+ <hbox>
+ <button id="buttonAddRuleElement" label="&add.label;" accesskey="&add.accesskey;" oncommand="autofillForms.ruleEditorAdd(null, null);"/>
+ <button id="buttonRemoveRuleElement" label="&remove.label;" accesskey="&remove.accesskey;" oncommand="autofillForms.ruleEditorRemove(null);"/>
+ </hbox>
+ </vbox>
+ <separator class="thin"/>
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillForms.js"
+ />
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillFormsRuleEditor.js"
+ />
+ <stringbundleset id="stringbundleset">
+ <stringbundle
+ id="autofillFormsStringBundle"
+ src="chrome://autofillForms/locale/autofillForms.properties"
+ />
+ </stringbundleset>
+</dialog>
\ No newline at end of file
diff --git a/chrome/content/autofillFormsTagEditor.js b/chrome/content/autofillFormsTagEditor.js
new file mode 100644
index 0000000..d22adb6
--- /dev/null
+++ b/chrome/content/autofillFormsTagEditor.js
@@ -0,0 +1,11 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+window.addEventListener('load', function() { autofillForms.tagEditorInitialize(); }, false);
+window.addEventListener('unload', function() { autofillForms.tagEditorFinalize(); }, false);
+window.addEventListener('focus', function() { autofillForms.tagEditorFocus(); }, true);
diff --git a/chrome/content/autofillFormsTagEditor.xul b/chrome/content/autofillFormsTagEditor.xul
new file mode 100644
index 0000000..de4df65
--- /dev/null
+++ b/chrome/content/autofillFormsTagEditor.xul
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://autofillForms/skin/autofillFormsTagEditor.css" type="text/css"?>
+<!DOCTYPE overlay SYSTEM "chrome://autofillForms/locale/autofillForms.dtd">
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="autofillFormsTagEditor"
+ title="&tageditor.title;"
+ buttons="accept,cancel,help"
+ ondialogaccept="autofillForms.tagEditorSave();"
+ ondialogcancel="return true;"
+ ondialoghelp="autofillForms.openHelp('Dynamic Tags');"
+ persist="screenX screenY width height sizemode"
+ width="525"
+ height="400">
+ <vbox flex="1">
+ <richlistbox id="tagList" flex="1" onkeypress="autofillForms.tagEditorHandleKeyPress(event)"/>
+ <separator class="thin"/>
+ <hbox>
+ <button id="buttonAddTag" label="&add.label;" accesskey="&add.accesskey;" oncommand="autofillForms.tagEditorAdd(null, null);"/>
+ <button id="buttonRemoveTag" label="&remove.label;" accesskey="&remove.accesskey;" oncommand="autofillForms.tagEditorRemove(null);"/>
+ <button id="buttonValidateTagCode" label="&validate.label;" accesskey="&validate.accesskey;" oncommand="autofillForms.tagEditorValidate(null);"/>
+ <textbox id="validationResultTextBox" flex="1"/>
+ </hbox>
+ <separator class="thin"/>
+ <separator class="groove"/>
+ <separator class="thin"/>
+ <groupbox>
+ <caption label="&tagimportexport.label;"/>
+ <hbox>
+ <button label="&tagimportbutton.label;" oncommand="autofillForms.importDynamicTagsFromTagEditor();"/>
+ <button label="&tagexportbutton.label;" oncommand="autofillForms.exportDynamicTagsFromTagEditor();"/>
+ <spacer flex="1"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+ <separator class="thin"/>
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillForms.js"
+ />
+ <script
+ type="application/x-javascript"
+ src="chrome://autofillForms/content/autofillFormsTagEditor.js"
+ />
+ <stringbundleset id="stringbundleset">
+ <stringbundle
+ id="autofillFormsStringBundle"
+ src="chrome://autofillForms/locale/autofillForms.properties"
+ />
+ </stringbundleset>
+</dialog>
+
diff --git a/chrome/content/inject.js b/chrome/content/inject.js
new file mode 100644
index 0000000..52e226a
--- /dev/null
+++ b/chrome/content/inject.js
@@ -0,0 +1,24 @@
+/* globals addMessageListener, content */
+'use strict';
+
+addMessageListener('click', function () {
+ var elems = content.document.querySelectorAll('[data-aff-click=true]');
+ [].forEach.call(elems, function (elem) {
+ elem.removeAttribute('data-aff-click');
+ elem.click();
+ });
+});
+addMessageListener('submit', function () {
+ var elems = content.document.querySelectorAll('[data-aff-submit=true]');
+ [].forEach.call(elems, function (elem) {
+ elem.removeAttribute('data-aff-submit');
+ elem.submit();
+ });
+});
+addMessageListener('focus', function () {
+ var elems = content.document.querySelectorAll('[data-aff-focus=true]');
+ [].forEach.call(elems, function (elem) {
+ elem.removeAttribute('data-aff-focus');
+ elem.focus();
+ });
+});
diff --git a/chrome/locale/cs-CZ/autofillForms.dtd b/chrome/locale/cs-CZ/autofillForms.dtd
new file mode 100644
index 0000000..5e1f6dc
--- /dev/null
+++ b/chrome/locale/cs-CZ/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Přepínač profilů">
+<!ENTITY settingsmenuitem.label "Nastavení">
+<!ENTITY helpmenuitem.label "Nápověda">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Vyplnit toto pole">
+<!ENTITY manualfillcontextmenu.accesskey "V">
+<!ENTITY addrulecontextmenuitem.label "Přidat do Autofill Forms pravidlo pro toto pole...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Přidat kompletní formulář jako profil Autofill Forms...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "k">
+<!ENTITY options.title "Nastavení Autofill Forms">
+<!ENTITY prefpanesimplelabel "Jednoduché">
+<!ENTITY prefpanemainlabel "Hlavní">
+<!ENTITY prefpaneprofileslabel "Profily">
+<!ENTITY prefpaneadvancedlabel "Pokročilé">
+<!ENTITY prefpaneguilabel "Rozhraní">
+<!ENTITY resetallprofiles.label "Resetovat všechny profily">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Pravidlo stránky">
+<!ENTITY profilename.label "Jméno">
+<!ENTITY fieldrulename.label "Jméno">
+<!ENTITY fieldrulevalue.label "Hodnota">
+<!ENTITY fieldrulesiterule.label "Pravidlo stránky">
+<!ENTITY fieldrulefieldrule.label "Pravidlo pole">
+<!ENTITY fieldruleoverwrite.label "Přepsat">
+<!ENTITY fieldruleenabled.label "Zapnuto">
+<!ENTITY apply.label "Použít">
+<!ENTITY apply.accesskey "P">
+<!ENTITY add.label "Přidat">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Odstranit">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Posunout nahoru">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Posunout dolů">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Vypnout">
+<!ENTITY validate.label "Zkontrolovat platnost">
+<!ENTITY validate.accesskey "t">
+<!ENTITY securitycaption.label "Bezpečnost">
+<!ENTITY storeencrypted.label "Ukládat pravidla formulářů zašifrovaná">
+<!ENTITY storagelocationcaption.label "Umístění úložiště">
+<!ENTITY useconfigdirectory.label "Ukládat pravidla pole formuláře do vlastního konfiguračního adresáře">
+<!ENTITY browsedir.label "Procházet...">
+<!ENTITY resetdir.label "Resetovat">
+<!ENTITY opendir.label "Otevřít">
+<!ENTITY shortcutscaption.label "Klávesové zkratky">
+<!ENTITY shortcutfilloutforms.label "Vyplnit formuláře:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Vyplnit a odeslat formuláře:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Vyplnit formuláře ve všech panelech:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Vyplnit formuláře z výběru profilu:">
+<!ENTITY shortcutprofileswitcher.label "Přepínač profilů:">
+<!ENTITY shortcutsettings.label "Nastavení:">
+<!ENTITY shortcutdisplayformdetails.label "Zobrazit detaily formuláře:">
+<!ENTITY shortcutinfo.label "Nové nastavení klávesových zkratek se projeví až v novém okně Firefoxu.">
+<!ENTITY mousebuttonscaption.label "Tlačítka myši">
+<!ENTITY mousebuttonclick.label "Klepnout">
+<!ENTITY mouseshortcutinfo.label "Tlačítka myši se použijí na klepnutí na tlačítko v nástrojové liště nebo ikonu ve stavovém řádku.">
+<!ENTITY viewcaption.label "Zobrazení">
+<!ENTITY hidestatusbaricon.label "Skyrý ikonu ve stavovém řádku">
+<!ENTITY hidecontextmenuitem.label "Skrýt položku v místní nabídce">
+<!ENTITY hideformfieldscontextmenu.label "Skrýt místní nabídku vyplnění polí formuláře">
+<!ENTITY hidetoolbarbutton.label "Skrýt tlačítko v nástrojové liště">
+<!ENTITY hidetoolbarbuttonmenu.label "Skrýt nabídku tlačítka v nástrojové liště">
+<!ENTITY enableconfirmationdialogs.label "Zapnout potvrzovací dialogová okna">
+<!ENTITY highlightstylematch.label "Kaskádové styly pro automaticky doplněná pole formuláře:">
+<!ENTITY highlightstylenomatch.label "Kaskádové styly pro automaticky nedoplňovaná pole formuláře:">
+<!ENTITY formdetailsstyle.label "Kaskádové styly pro detail formuláře:">
+<!ENTITY miscellaneous.label "Různé">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignorovat vypnutá pravidla při automatickém doplnění formulářů">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Zaměřit se na poslední odpovídající pole formuláře">
+<!ENTITY autoselectbestprofile.label "Automaticky zvolit pro vás nejlepší profil">
+<!ENTITY matchagainstlabels.label "Souhlasící pravidla pro pole formuláře označit dodatečně">
+<!ENTITY identifylabelsinstrictmode.label "Identifikovat označení pole formuláře podle striktních pravidel">
+<!ENTITY matchagainstpositions.label "Povolit souhlasení pravidel polí formuláře podle pozice">
+<!ENTITY rememberalternativesindex.label "Použít alternativní rejstřík pro následující výběry">
+<!ENTITY placeholderlinebreak.label "Zachování rozložení řádku (mezer) v textových oblastech:">
+<!ENTITY placeholdertab.label "Zachování rozložení pro vstup tabulátoru:">
+<!ENTITY enableglobalprofile.label "Zapnout globální profil:">
+<!ENTITY formfieldscontextmenu.label "Zobrazit v polích formuláře místní nabídku:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Všechny profily">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Aktivní profil">
+<!ENTITY profileimportexport.label "Importovat/Exportovat profil">
+<!ENTITY profileimportbutton.label "Importovat profil...">
+<!ENTITY profileexportbutton.label "Exportovat současný profil...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Zobrazit detaily formuláře">
+<!ENTITY ruleeditorbutton.label "Editor pravidel...">
+<!ENTITY ruleeditor.title "Editor pravidel">
+<!ENTITY ruleeditorinfo.label "Podmínky nejsou spojené dohromady (NEBO jsou ve vztahu) - musí se rovnat pouze jedna z nich.">
+<!ENTITY ruleeditorcondition.label "Hledaný řetězec...">
+<!ENTITY tagsenable.label "Zapnout dynamické tagy">
+<!ENTITY tagsedit.label "Upravit dynamické tagy...">
+<!ENTITY tageditor.title "Editor dynamických tagů">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/cs-CZ/autofillForms.properties b/chrome/locale/cs-CZ/autofillForms.properties
new file mode 100644
index 0000000..5032817
--- /dev/null
+++ b/chrome/locale/cs-CZ/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Doplňte údaje do webových formulářů pouhým stisknutím klávesové zkratky
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Uživatelské%20jméno (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nOslovení (?:prefix%5Cw*name)%7C(?:name%5Cw*prefix)%7C(?:title) (?:) true true\nKřestní%20jméno (?:first%5Cw*name)%7C(?:name%5Cw*first) (?:) true true\n2.%20Jméno (?:middle%5Cw*name)%7C(?:name%5Cw*middle) (?:) true true\nPříjmení (?:last%5Cw*name)%7C(?:name%5Cw*last) (?:) true true\nPřídomek (?:suffix%5Cw*name)%7C(?:name%5Cw*suffix) (?:) [...]
+extensions.autofillForms at blueimp.net.profileLabels=Výchozí
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Vyplnit formuláře
+tooltipSubmit=Vyplnit a odeslat formuláře
+tooltipAllTabs=Vyplnit formuláře ve všech panelech
+tooltipFromProfileSelection=Vyplnit formuláře z výběru profilu
+tooltipProfile=Přepínač profilů
+tooltipSettings=Nastavení
+tooltipDisplayFormDetails=Zobrazit detaily formuláře
+currentProfileLabel=Současný profil:
+profileSelectionWindowTitle=Přepnout profil
+profileSelectionFormFillTitle=Vyplnit formuláře
+profileSelectionPrompt=Zvolit profil:
+contextMenuMore=Více...
+invalidRegExpTitle=Nesprávný výraz
+invalidRegExpText=Vložený výraz není platný:
+containsRuleType=obsahuje
+beginsWithRuleType=začíná na
+endsWithRuleType=končí na
+equalsRuleType=rovná se
+alternativesSelectionWindowTitle=Zvolit jiné
+alternativesSelectionPrompt=Zvolit jiné:
+importProfile=Importovat profil
+exportProfile=Exportovat profil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Odstranit profil
+removeProfileText=Skutečně chcete odstranit profil?
+removeFieldRulesTitle=Odstranit pravidla pole
+removeFieldRulesText=Opravdu mám smazat vybraná pravidla pole?
+sortFieldRulesTitle=Seřadit pravidla pole
+sortFieldRulesText=Opravdu chcete nastavit nové uspořádání pravidel pole?
+removeRuleConditionTitle=Odstranit podmínku pole
+removeRuleConditionText=Opravdu chcete odstranit vybranou podmínku pole?
+removeDynamicTagTitle=Odstranit dynamický tag
+removeDynamicTagText=Opravdu chcete odstranit vybraný dynamický tag?
+resetAllProfilesTitle=Resetovat všechny profily
+resetAllProfilesText=Opravdu chcete resetovat všechny profily?
+selectConfigDirectory=Zvolit adresář s konfigurací
+newConfigDirectoryNotEmptyTitle=Adresář není prázdný
+newConfigDirectoryNotEmptyText=Nový adresář s konfigurací není prázdný. Chcete přepsat existující konfigurační soubory?
+importFromConfigDirectoryTitle=Importovat z adresáře s konfigurací
+importFromConfigDirectoryText=Chcete přepsat profily daty z adresáře s konfigurací?
+command=Příkaz
+mousebutton=Tlačítko myši
+mousebutton0=Levé tlačítko myši
+mousebutton1=Prostřední tlačítko myši
+mousebutton2=Pravé tlačítko myši
+keyboardShortcut=Klávesová zkratka
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Zrušit
+VK_HELP=Nápověda
+VK_BACK=Zpět
+VK_TAB=Tab
+VK_CLEAR=Vyčistit
+VK_RETURN=Návrat
+VK_ENTER=Enter
+VK_PAUSE=Pauza
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Mezerník
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Doleva
+VK_UP=Nahoru
+VK_RIGHT=Doprava
+VK_DOWN=Dolů
+VK_PRINTSCREEN=Print Screen
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/de-DE/autofillForms.dtd b/chrome/locale/de-DE/autofillForms.dtd
new file mode 100644
index 0000000..676e2a1
--- /dev/null
+++ b/chrome/locale/de-DE/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profil Wechsel">
+<!ENTITY settingsmenuitem.label "Einstellungen">
+<!ENTITY helpmenuitem.label "Hilfe">
+<!ENTITY autofillformscontextmenuitem.label "Formulare automatisch ausfüllen">
+<!ENTITY autofillformscontextmenuitem.accesskey "f">
+<!ENTITY manualfillcontextmenu.label "Dieses Feld ausfüllen">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Eine Regel für dieses Feld erstellen...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "Das komplette Formular als Profil übernehmen...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Autofill Forms - Einstellungen">
+<!ENTITY prefpanesimplelabel "Einfach">
+<!ENTITY prefpanemainlabel "Allgemein">
+<!ENTITY prefpaneprofileslabel "Profile">
+<!ENTITY prefpaneadvancedlabel "Erweitert">
+<!ENTITY prefpaneguilabel "Oberfläche">
+<!ENTITY resetallprofiles.label "Alle Profile zurücksetzen">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Seitenregel">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Name">
+<!ENTITY fieldrulevalue.label "Wert">
+<!ENTITY fieldrulesiterule.label "Seitenregel">
+<!ENTITY fieldrulefieldrule.label "Feldregel">
+<!ENTITY fieldruleoverwrite.label "Überschreiben">
+<!ENTITY fieldruleenabled.label "Aktiviert">
+<!ENTITY apply.label "Übernehmen">
+<!ENTITY apply.accesskey "n">
+<!ENTITY add.label "Hinzufügen">
+<!ENTITY add.accesskey "z">
+<!ENTITY remove.label "Entfernen">
+<!ENTITY remove.accesskey "e">
+<!ENTITY moveup.label "Nach oben">
+<!ENTITY moveup.accesskey "o">
+<!ENTITY movedown.label "Nach unten">
+<!ENTITY movedown.accesskey "u">
+<!ENTITY disable.label "Deaktivieren">
+<!ENTITY validate.label "Validieren">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Sicherheit">
+<!ENTITY storeencrypted.label "Formularfeld-Regeln verschlüsselt speichern">
+<!ENTITY storagelocationcaption.label "Speicherort">
+<!ENTITY useconfigdirectory.label "Formularfeld-Regeln in einem eigenen Konfigurationsverzeichnis speichern">
+<!ENTITY browsedir.label "Durchsuchen...">
+<!ENTITY resetdir.label "Zurücksetzen">
+<!ENTITY opendir.label "Öffnen">
+<!ENTITY shortcutscaption.label "Tastaturkürzel">
+<!ENTITY shortcutfilloutforms.label "Formulare ausfüllen:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Formulare ausfüllen und abschicken:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Formulare auf allen Browser-Tabs ausfüllen:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Formulare aus Profil-Auswahl ausfüllen:">
+<!ENTITY shortcutprofileswitcher.label "Profil wechseln:">
+<!ENTITY shortcutsettings.label "Einstellungen:">
+<!ENTITY shortcutdisplayformdetails.label "Formular-Details anzeigen:">
+<!ENTITY shortcutinfo.label "Eine Änderung des Tastaturkürzels wird erst in einem neuen Firefox-Fenster wirksam.">
+<!ENTITY mousebuttonscaption.label "Maustasten">
+<!ENTITY mousebuttonclick.label "Klick">
+<!ENTITY mouseshortcutinfo.label "Maustasten betreffen Klicks auf die Symbolleistenschaltfäche oder das Statusleisten-Symbol.">
+<!ENTITY viewcaption.label "Ansicht">
+<!ENTITY hidestatusbaricon.label "Statusleisten-Symbol ausblenden">
+<!ENTITY hidecontextmenuitem.label "Kontextmenüeintrag ausblenden">
+<!ENTITY hideformfieldscontextmenu.label "Kontextmenü für Formularfelder ausblenden">
+<!ENTITY hidetoolbarbutton.label "Symbolleistenschaltfläche ausblenden">
+<!ENTITY hidetoolbarbuttonmenu.label "Symbolleistenschaltflächen-Menü ausblenden">
+<!ENTITY enableconfirmationdialogs.label "Bestätigungsdialoge anzeigen">
+<!ENTITY highlightstylematch.label "CSS-Stil für ausgefüllte Formularfelder:">
+<!ENTITY highlightstylenomatch.label "CSS-Stil für nicht ausgefüllte Formularfelder:">
+<!ENTITY formdetailsstyle.label "CSS-Stil für Formular-Details:">
+<!ENTITY miscellaneous.label "Verschiedenes">
+<!ENTITY ignoredisabledrulesonautofill.label "Deaktivierte Regeln beim automatischen Ausfüllen von Formularen ignorieren">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Den Fokus auf das letzte ausgefüllte Formularelement setzen">
+<!ENTITY autoselectbestprofile.label "Automatisch das am besten passende Profil auswählen">
+<!ENTITY matchagainstlabels.label "Regeln zusätzlich auf die Beschriftung der Formularfelder anwenden">
+<!ENTITY identifylabelsinstrictmode.label "Beschriftungen der Formularfelder im strikten Modus ermitteln">
+<!ENTITY matchagainstpositions.label "Erlaube Regeln um Formularfelder nach Position auszuwählen">
+<!ENTITY rememberalternativesindex.label "Die Nummer der gewählten Alternative für nachfolgende Auswahlen verwenden">
+<!ENTITY placeholderlinebreak.label "Platzhalter für Zeilenumbrüche in mehrzeiligen Eingabefeldern:">
+<!ENTITY placeholdertab.label "Platzhalter für Tabulator Eingaben:">
+<!ENTITY enableglobalprofile.label "Globales Profil aktivieren:">
+<!ENTITY formfieldscontextmenu.label "Im Formularfeld-Kontextmenü anzeigen:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Alle Profile">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Aktives Profil">
+<!ENTITY profileimportexport.label "Profil Import / Export">
+<!ENTITY profileimportbutton.label "Profil Importieren...">
+<!ENTITY profileexportbutton.label "Aktuelles Profil Exportieren...">
+<!ENTITY profileexportallbutton.label "Alle Profile Exportieren...">
+<!ENTITY formdetails.label "Formular-Details anzeigen">
+<!ENTITY ruleeditorbutton.label "Regel-Editor...">
+<!ENTITY ruleeditor.title "Regel-Editor">
+<!ENTITY ruleeditorinfo.label "Die Bedingungen werden disjunktiv verknüpft (ODER-Verknüpfungen) - nur eine davon muss erfüllt werden.">
+<!ENTITY ruleeditorcondition.label "Die gesuchte Zeichenkette ...">
+<!ENTITY tagsenable.label "Dynamische Tags aktivieren">
+<!ENTITY tagsedit.label "Dynamische Tags editieren...">
+<!ENTITY tageditor.title "Dynamische Tags - Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/de-DE/autofillForms.properties b/chrome/locale/de-DE/autofillForms.properties
new file mode 100644
index 0000000..24d24eb
--- /dev/null
+++ b/chrome/locale/de-DE/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Web-Formulare automatisch ausfüllen
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Benutzername (?:(?:user)%7C(?:login)%7C(?:benutzer))(?!%5Cw*pass) (?:) true true\nE-mail mail (?:) true true\nAnrede (?:prefix%5Cw*name)%7C(?:name%5Cw*prefix)%7C(?:title)%7C(?:titel)%7C(?:anrede) (?:) true true\nVorname (?:first%5Cw*name)%7C(?:name%5Cw*first)%7C(?:vorname) (?:) true true\n2.%20Vorname (?:middle%5Cw*name)%7C(?:name%5Cw*middle)%7C(?:vorname%5Cw*2) (?:) true true\nNachname (?:last%5Cw*name)%7C(?:name%5Cw*last)%7C(?:nachn [...]
+extensions.autofillForms at blueimp.net.profileLabels=Standard
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Formulare ausfüllen
+tooltipSubmit=Formulare ausfüllen und abschicken
+tooltipAllTabs=Formulare auf allen Browser-Tabs ausfüllen
+tooltipFromProfileSelection=Formulare aus Profil-Auswahl ausfüllen
+tooltipProfile=Profil wechseln
+tooltipSettings=Einstellungen
+tooltipDisplayFormDetails=Formular-Details anzeigen
+currentProfileLabel=Aktuelles Profil:
+profileSelectionWindowTitle=Profil wechseln
+profileSelectionFormFillTitle=Formulare ausfüllen
+profileSelectionPrompt=Profil wählen:
+contextMenuMore=Mehr...
+invalidRegExpTitle=Ungültiger regulärer Ausdruck
+invalidRegExpText=Der eingegebene reguläre Ausdruck ist nicht gültig:
+containsRuleType=enthält
+beginsWithRuleType=beginnt mit
+endsWithRuleType=endet mit
+equalsRuleType=ist
+alternativesSelectionWindowTitle=Alternative auswählen
+alternativesSelectionPrompt=Alternative auswählen:
+importProfile=Profil Importieren
+exportProfile=Profil Exportieren
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Profil entfernen
+removeProfileText=Wirklich das aktuelle Profil löschen?
+removeFieldRulesTitle=Feldregeln entfernen
+removeFieldRulesText=Wirklich die ausgewählten Feldregeln entfernen?
+sortFieldRulesTitle=Feldregeln sortieren
+sortFieldRulesText=Wirklich eine neue Reihenfolge für die Feldregeln festlegen?
+removeRuleConditionTitle=Regelbedingung entfernen
+removeRuleConditionText=Wirklich die ausgewählte Regelbedingung entfernen?
+removeDynamicTagTitle=Dynamisches Tag entfernen
+removeDynamicTagText=Wirklich das ausgewählte Dynamische Tag entfernen?
+resetAllProfilesTitle=Alle Profile zurücksetzen
+resetAllProfilesText=Wirklich alle Profile zurücksetzen?
+selectConfigDirectory=Konfigurationsverzeichnis auswählen
+newConfigDirectoryNotEmptyTitle=Verzeichnis nicht leer
+newConfigDirectoryNotEmptyText=Das neue Konfigurationsverzeichnis ist nicht leer. Sollen vorhandene Konfigurationsdateien überschrieben werden?
+importFromConfigDirectoryTitle=Import aus dem Konfigurationsverzeichnis
+importFromConfigDirectoryText=Sollen die Profile mit den Daten aus dem Konfigurationsverzeichnis überschrieben werden?
+command=Befehl
+mousebutton=Maustaste
+mousebutton0=Linke Maustaste
+mousebutton1=Mittlere Maustaste
+mousebutton2=Rechte Maustaste
+keyboardShortcut=Tastaturkürzel
+alt=Alt
+control=Strg
+meta=Cmd
+shift=Umschalt
+VK_CANCEL=Abbr
+VK_HELP=Hilfe
+VK_BACK=Zurück
+VK_TAB=Tab
+VK_CLEAR=Leeren
+VK_RETURN=Eingabe
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Feststell
+VK_ESCAPE=Esc
+VK_SPACE=Leertaste
+VK_PAGE_UP=Bild hoch
+VK_PAGE_DOWN=Bild runter
+VK_END=Ende
+VK_HOME=Pos 1
+VK_LEFT=Links
+VK_UP=Hoch
+VK_RIGHT=Rechts
+VK_DOWN=Runter
+VK_PRINTSCREEN=Druck
+VK_INSERT=Einfg
+VK_DELETE=Entf
+VK_NUM_LOCK=Num
+VK_SCROLL_LOCK=Rollen
diff --git a/chrome/locale/el-GR/autofillForms.dtd b/chrome/locale/el-GR/autofillForms.dtd
new file mode 100644
index 0000000..ccb527d
--- /dev/null
+++ b/chrome/locale/el-GR/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Αυτόματη Συμπλήρωση Φορμών">
+<!ENTITY profilemenuitem.label "Αλλαγή Προφίλ">
+<!ENTITY settingsmenuitem.label "Ρυθμίσεις">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Ρυθμίσεις Αυτόματης Συμπλήρωσης Φορμών">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Βασικό">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Για προχωρημένους">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Προφίλ:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Όνομα">
+<!ENTITY fieldrulevalue.label "Τιμή">
+<!ENTITY fieldrulesiterule.label "Κανόνας ιστοσελίδας">
+<!ENTITY fieldrulefieldrule.label "Κανόνας πεδίου">
+<!ENTITY fieldruleoverwrite.label "Αντικατάσταση">
+<!ENTITY fieldruleenabled.label "Ενεργοποιημένο">
+<!ENTITY apply.label "Εφαρμογή">
+<!ENTITY apply.accesskey "φ">
+<!ENTITY add.label "Προσθήκη">
+<!ENTITY add.accesskey "Π">
+<!ENTITY remove.label "Αφαίρεση">
+<!ENTITY remove.accesskey "ρ">
+<!ENTITY moveup.label "Μετακίνηση Πάνω">
+<!ENTITY moveup.accesskey "Π">
+<!ENTITY movedown.label "Μετακίνηση Κάτω">
+<!ENTITY movedown.accesskey "Κ">
+<!ENTITY disable.label "Απενεργοποίηση">
+<!ENTITY validate.label "Επικύρωση">
+<!ENTITY validate.accesskey "ω">
+<!ENTITY securitycaption.label "Ασφάλεια">
+<!ENTITY storeencrypted.label "Κρυπτογραφημένη αποθήκευση των κανόνων των πεδίων">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Συντομεύσεις πληκτρολογίου">
+<!ENTITY shortcutfilloutforms.label "Συμπλήρωση φορμών:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Αλλαγή Προφίλ:">
+<!ENTITY shortcutsettings.label "Ρυθμίσεις:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Οι αλλαγές των συντομεύσεων πληκτρολογίου θα ισχύσουν από το επόμενο άνοιγμα παραθύρου του Firefox.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Διάφορα">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Χρήση των του επιλεγμένου καταλόγου εναλλακτικών για διαδοχικές επιλογές">
+<!ENTITY placeholderlinebreak.label "Σύμβολο για αλλαγή σειράς σε περιοχές κειμένου:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Ενεργοποίηση Παγκόσμιου Προφίλ:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Εισαγωγή / Εξαγωγή Προφίλ">
+<!ENTITY profileimportbutton.label "Εισαγωγή Προφίλ...">
+<!ENTITY profileexportbutton.label "Εξαγωγή τρέχοντος Προφίλ...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Εμφάνιση Λεπτομερειών Φόρμας">
+<!ENTITY ruleeditorbutton.label "Επεξεργαστής Κανόνων...">
+<!ENTITY ruleeditor.title "Επεξεργαστής Κανόνων">
+<!ENTITY ruleeditorinfo.label "Οι συνθήκες είναι συνδεδεμένες μαζί ως διαζεύξεις (σχέσεις με διαζεύκτικό)">
+<!ENTITY ruleeditorcondition.label "Η φράση προς αναζήτηση...">
+<!ENTITY tagsenable.label "Ενεργοποίηση δυναμικών ετικετών">
+<!ENTITY tagsedit.label "Επεξεργασία δυναμικών ετικετών">
+<!ENTITY tageditor.title "Επεξεργαστής Δυναμικών Ετικετών">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/el-GR/autofillForms.properties b/chrome/locale/el-GR/autofillForms.properties
new file mode 100644
index 0000000..121378b
--- /dev/null
+++ b/chrome/locale/el-GR/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Αυτόματη συμπλήρωση ηλεκτρονικών φορμών
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Προεπιλογή
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Τρέχον προφίλ:
+profileSelectionWindowTitle=Αλλαγή Προφίλ
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Επιλογή Προφίλ:
+contextMenuMore=More...
+invalidRegExpTitle=Μη έγκυρη φράση
+invalidRegExpText=Η εισαγμένη φράση δεν είναι έγκυρη:
+containsRuleType=περιέχει
+beginsWithRuleType=ξεκινάει με
+endsWithRuleType=τελειώνει σε
+equalsRuleType=ισούται με
+alternativesSelectionWindowTitle=Εναλλακτική επιλογή
+alternativesSelectionPrompt=Εναλλακτική επιλογή:
+importProfile=Εισαγωγή Προφίλ
+exportProfile=Εξαγωγή Προφίλ
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Αφαίρεση προφίλ
+removeProfileText=Διαγραφή του τρέχοντος προφίλ;
+removeFieldRulesTitle=Αφαίρεση κανόνων πεδίου
+removeFieldRulesText=Διαγραφή των επιλεγμένων κανόνων πεδίου;
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Αφαίρεση συνθήκης κανόνα
+removeRuleConditionText=Διαγραφή της επιλεγμένης συνθήκης κανόνα;
+removeDynamicTagTitle=Αφαίρεση δυναμικής ετικέτας
+removeDynamicTagText=Διαγραφή της επιλεγμένης δυναμικής ετικέτας;
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Ακύρωση
+VK_HELP=Βοήθεια
+VK_BACK=Πίσω
+VK_TAB=Tab
+VK_CLEAR=Καθαρισμός
+VK_RETURN=Επιστροφή
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Διάστημα
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Αριστερό βέλος
+VK_UP=Πάνω βέλος
+VK_RIGHT=Δεξιό βέλος
+VK_DOWN=Κάτω βέλος
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/en-US/autofillForms.dtd b/chrome/locale/en-US/autofillForms.dtd
new file mode 100644
index 0000000..8bbc3d9
--- /dev/null
+++ b/chrome/locale/en-US/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profile Switcher">
+<!ENTITY settingsmenuitem.label "Settings">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add a rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Autofill Forms settings">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Advanced">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profile:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Name">
+<!ENTITY fieldrulevalue.label "Value">
+<!ENTITY fieldrulesiterule.label "Site rule">
+<!ENTITY fieldrulefieldrule.label "Field rule">
+<!ENTITY fieldruleoverwrite.label "Overwrite">
+<!ENTITY fieldruleenabled.label "Enabled">
+<!ENTITY apply.label "Apply">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Add">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Remove">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Move Up">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Move Down">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Disable">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Security">
+<!ENTITY storeencrypted.label "Store form field rules encrypted">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Keyboard shortcuts">
+<!ENTITY shortcutfilloutforms.label "Fill out forms:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profile Switcher:">
+<!ENTITY shortcutsettings.label "Settings:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Keyboard shortcut changes only take effect in a new Firefox window.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profile Import / Export">
+<!ENTITY profileimportbutton.label "Import Profile(s)...">
+<!ENTITY profileexportbutton.label "Export current Profile...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Rule Editor...">
+<!ENTITY ruleeditor.title "Rule Editor">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/en-US/autofillForms.properties b/chrome/locale/en-US/autofillForms.properties
new file mode 100644
index 0000000..b4cf2ed
--- /dev/null
+++ b/chrome/locale/en-US/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Fill out web forms automatically
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Default
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Current profile:
+profileSelectionWindowTitle=Switch Profile
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Select Profile:
+contextMenuMore=More...
+invalidRegExpTitle=Invalid regular expression
+invalidRegExpText=The entered regular expression is not valid:
+containsRuleType=contains
+beginsWithRuleType=begins with
+endsWithRuleType=ends with
+equalsRuleType=equals
+alternativesSelectionWindowTitle=Select alternative
+alternativesSelectionPrompt=Select alternative:
+importProfile=Import Profile
+exportProfile=Export Profile
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancel
+VK_HELP=Help
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/es-ES/autofillForms.dtd b/chrome/locale/es-ES/autofillForms.dtd
new file mode 100644
index 0000000..9e523f6
--- /dev/null
+++ b/chrome/locale/es-ES/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Intercambio de Perfil">
+<!ENTITY settingsmenuitem.label "Ajustes">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Ajustes de Autofill Forms">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Principal">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Avanzado">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Perfil:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Nombre">
+<!ENTITY fieldrulevalue.label "Valor">
+<!ENTITY fieldrulesiterule.label "Regla de sitio">
+<!ENTITY fieldrulefieldrule.label "Regla de campo">
+<!ENTITY fieldruleoverwrite.label "Sobreescribir">
+<!ENTITY fieldruleenabled.label "Activar">
+<!ENTITY apply.label "Aplicar">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Añadir">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Remover">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Hacia Arriba">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Hacia Abajo">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Desactivar">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Seguridad">
+<!ENTITY storeencrypted.label "Guardar campos encriptados">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Atajos de teclado">
+<!ENTITY shortcutfilloutforms.label "Rellenar formularios:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Intercambio de Perfil">
+<!ENTITY shortcutsettings.label "Ajustes:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Los cambios en los atajos de teclado solo toman efecto en una nueva ventana de Firefox.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscelaneo">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use el indice de alternativas para las selecciones subsecuentes">
+<!ENTITY placeholderlinebreak.label "Parámetro para la inserción de saltos de linea en el texto:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Importar/Exportar Perfil">
+<!ENTITY profileimportbutton.label "Importar Perfil...">
+<!ENTITY profileexportbutton.label "Exportar perfil actual...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Mostrar detalles de formulario">
+<!ENTITY ruleeditorbutton.label "Editor de reglas...">
+<!ENTITY ruleeditor.title "Editor de reglas">
+<!ENTITY ruleeditorinfo.label "La condiciones se encuentran relacionadas entre sí de manera disyuntiva, solo una de ellas debe encajar.">
+<!ENTITY ruleeditorcondition.label "El termino buscado...">
+<!ENTITY tagsenable.label "Activar etiquetas dinámicas">
+<!ENTITY tagsedit.label "Editar etiquetas dinámicas...">
+<!ENTITY tageditor.title "Editor de etiquetas dinamicas">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/es-ES/autofillForms.properties b/chrome/locale/es-ES/autofillForms.properties
new file mode 100644
index 0000000..50e5f45
--- /dev/null
+++ b/chrome/locale/es-ES/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Rellena formularios web automáticamente
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Por Defecto
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Perfil actual:
+profileSelectionWindowTitle=Cambiar Perfil
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Seleccionar Perfil:
+contextMenuMore=More...
+invalidRegExpTitle=Expresión regular inválida
+invalidRegExpText=La expresión regular ingresada es inválida:
+containsRuleType=contiene
+beginsWithRuleType=empieza en
+endsWithRuleType=termina en
+equalsRuleType=igual a
+alternativesSelectionWindowTitle=Seleccionar alternativa:
+alternativesSelectionPrompt=Seleccionar alternativa:
+importProfile=Importar Perfil
+exportProfile=Exportar Perfil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Eliminar perfil
+removeProfileText=Realmente deseas eliminar el perfil actual?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Meta
+shift=Shift
+VK_CANCEL=Cancelar
+VK_HELP=Ayuda
+VK_BACK=Atras
+VK_TAB=Tab
+VK_CLEAR=Borrar
+VK_RETURN=Atras
+VK_ENTER=Entrar
+VK_PAUSE=Pausar
+VK_CAPS_LOCK=Bloq. Mayus
+VK_ESCAPE=Esc
+VK_SPACE=Espacio
+VK_PAGE_UP=Re. Pág.
+VK_PAGE_DOWN=Av. Pág
+VK_END=Fin
+VK_HOME=Inicio
+VK_LEFT=Izquierda
+VK_UP=Arriba
+VK_RIGHT=Derecha
+VK_DOWN=Abajo
+VK_PRINTSCREEN=Imprimir pantalla
+VK_INSERT=Insertar
+VK_DELETE=Eliminar
+VK_NUM_LOCK=Bloq. Num
+VK_SCROLL_LOCK=Bloq. Scroll
diff --git a/chrome/locale/fi-FI/autofillForms.dtd b/chrome/locale/fi-FI/autofillForms.dtd
new file mode 100644
index 0000000..d307c3e
--- /dev/null
+++ b/chrome/locale/fi-FI/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Täytä lomake automaattisesti">
+<!ENTITY profilemenuitem.label "Profiilinvaihtaja">
+<!ENTITY settingsmenuitem.label "Asetukset">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Autofill Forms asetukset">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Yleiset">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Lisäasetukset">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profiili:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Nimi">
+<!ENTITY fieldrulevalue.label "Arvo">
+<!ENTITY fieldrulesiterule.label "Sivun sääntö">
+<!ENTITY fieldrulefieldrule.label "Kentän sääntö">
+<!ENTITY fieldruleoverwrite.label "Korvaa">
+<!ENTITY fieldruleenabled.label "Käytössä">
+<!ENTITY apply.label "Käytä">
+<!ENTITY apply.accesskey "k">
+<!ENTITY add.label "Lisää">
+<!ENTITY add.accesskey "ä">
+<!ENTITY remove.label "Poista">
+<!ENTITY remove.accesskey "p">
+<!ENTITY moveup.label "Siirrä ylös">
+<!ENTITY moveup.accesskey "y">
+<!ENTITY movedown.label "Siirrä alas">
+<!ENTITY movedown.accesskey "a">
+<!ENTITY disable.label "Poista käytöstä">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Turvallisuus">
+<!ENTITY storeencrypted.label "Säilytä lomakkeen kenttien säännöt salattuna">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Näppäimistön pikanäppäimet">
+<!ENTITY shortcutfilloutforms.label "Täytä lomakkeet:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profiilinvaihtaja:">
+<!ENTITY shortcutsettings.label "Asetukset:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Näppäimistön pikanäppäimet tulevat voimaan uusissa Firefox-ikkunoissa.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Muuta">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profiilin Tuonti / Vienti">
+<!ENTITY profileimportbutton.label "Tuo profiili...">
+<!ENTITY profileexportbutton.label "Vie nykyinen profiili...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Näytä lomakkeen tiedot">
+<!ENTITY ruleeditorbutton.label "Sääntömuokkain">
+<!ENTITY ruleeditor.title "Sääntömuokkain">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "Etsitty merkkijono ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/fi-FI/autofillForms.properties b/chrome/locale/fi-FI/autofillForms.properties
new file mode 100644
index 0000000..b4a900d
--- /dev/null
+++ b/chrome/locale/fi-FI/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Täytä Internet-lomakkeet automaattisesti
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Oletus
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Nykyinen profiili:
+profileSelectionWindowTitle=Vaihda profiili
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Valitse profiili
+contextMenuMore=More...
+invalidRegExpTitle=Virheellinen säännöllinen lauseke
+invalidRegExpText=Kirjoitettu säännöllinen lauseke on virheellinen
+containsRuleType=sisältää
+beginsWithRuleType=alkaa
+endsWithRuleType=loppuu
+equalsRuleType=on yhtä kuin
+alternativesSelectionWindowTitle=Valitse vaihtoehto
+alternativesSelectionPrompt=Valitse vaihtoehto:
+importProfile=Tuo profiili
+exportProfile=Vie profiili
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Vaihtonäppäin
+VK_CANCEL=Peruuta
+VK_HELP=Ohje
+VK_BACK=Edellinen
+VK_TAB=Sarkain
+VK_CLEAR=Tyhjennä
+VK_RETURN=Paluu
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Välilyönti
+VK_PAGE_UP=Page Up
+VK_PAGE_DOWN=Pade Down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Vasen
+VK_UP=Ylös
+VK_RIGHT=Oikea
+VK_DOWN=Alas
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/fr-FR/autofillForms.dtd b/chrome/locale/fr-FR/autofillForms.dtd
new file mode 100644
index 0000000..c2356e2
--- /dev/null
+++ b/chrome/locale/fr-FR/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Changement de profil">
+<!ENTITY settingsmenuitem.label "Paramètres">
+<!ENTITY helpmenuitem.label "Aide">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Remplir ce champ">
+<!ENTITY manualfillcontextmenu.accesskey "r">
+<!ENTITY addrulecontextmenuitem.label "Ajouter une règle Autofill Forms pour ce champ…">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Ajouter un formulaire complété en tant que profil d'Autofill Forms…">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Options de Autofill Forms">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Général">
+<!ENTITY prefpaneprofileslabel "Profils">
+<!ENTITY prefpaneadvancedlabel "Avancé">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Réinitialiser tous les profils">
+<!ENTITY profile.label "Profil :">
+<!ENTITY profilesiterule.label "Règle du site">
+<!ENTITY profilename.label "Nom">
+<!ENTITY fieldrulename.label "Nom">
+<!ENTITY fieldrulevalue.label "Valeur">
+<!ENTITY fieldrulesiterule.label "Site">
+<!ENTITY fieldrulefieldrule.label "Champ">
+<!ENTITY fieldruleoverwrite.label "Écraser">
+<!ENTITY fieldruleenabled.label "Activé">
+<!ENTITY apply.label "Appliquer">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Ajouter">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Supprimer">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Monter">
+<!ENTITY moveup.accesskey "o">
+<!ENTITY movedown.label "Descendre">
+<!ENTITY movedown.accesskey "e">
+<!ENTITY disable.label "Désactiver">
+<!ENTITY validate.label "Valider">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Sécurité">
+<!ENTITY storeencrypted.label "Chiffrer les règles de filtration stockées">
+<!ENTITY storagelocationcaption.label "Emplacement de stockage">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Naviguer…">
+<!ENTITY resetdir.label "Réinitialiser">
+<!ENTITY opendir.label "Ouvrir">
+<!ENTITY shortcutscaption.label "Raccourcis clavier">
+<!ENTITY shortcutfilloutforms.label "Remplir les formulaires :">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Changement de profil :">
+<!ENTITY shortcutsettings.label "Paramètres :">
+<!ENTITY shortcutdisplayformdetails.label "Affichage des détails du formulaire :">
+<!ENTITY shortcutinfo.label "Toute modification de raccourci clavier ne prendra effet que dans une nouvelle fenêtre de Firefox.">
+<!ENTITY mousebuttonscaption.label "Boutons de la souris">
+<!ENTITY mousebuttonclick.label "Clic">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "Affichage">
+<!ENTITY hidestatusbaricon.label "Cacher l'icône dans la barre d'état">
+<!ENTITY hidecontextmenuitem.label "Cacher l'élément du menu contextuel">
+<!ENTITY hideformfieldscontextmenu.label "Cacher le menu contextuel des champs de formulaire">
+<!ENTITY hidetoolbarbutton.label "Masquer le bouton de la barre d'outils">
+<!ENTITY hidetoolbarbuttonmenu.label "Masquer le menu du bouton de la barre d'outils">
+<!ENTITY enableconfirmationdialogs.label "Activer les fenêtres de confirmation">
+<!ENTITY highlightstylematch.label "Feuille de style pour les champs remplis automatiquement :">
+<!ENTITY highlightstylenomatch.label "Feuille de style pour les champs non remplis automatiquement :">
+<!ENTITY formdetailsstyle.label "Feuille de style pour les détails du formulaire :">
+<!ENTITY miscellaneous.label "Divers">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Placer le curseur dans le dernier champ rempli">
+<!ENTITY autoselectbestprofile.label "Sélectionner automatiquement le profil correspondant le mieux">
+<!ENTITY matchagainstlabels.label "Faire correspondre les règles avec les noms des champs supplémentaires du formulaire">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Utiliser le système des alternatives, pour des ensembles de valeurs">
+<!ENTITY placeholderlinebreak.label "Balise correspondant aux sauts de ligne dans les zones de texte :">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Activer le profil global :">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Tous les profils">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Profil actif">
+<!ENTITY profileimportexport.label "Import / export de profil">
+<!ENTITY profileimportbutton.label "Importer des profils…">
+<!ENTITY profileexportbutton.label "Exporter le profil en cours…">
+<!ENTITY profileexportallbutton.label "Exporter tous les Profils…">
+<!ENTITY formdetails.label "Détails du formulaire">
+<!ENTITY ruleeditorbutton.label "Éditeur de règles…">
+<!ENTITY ruleeditor.title "Éditeur de règles">
+<!ENTITY ruleeditorinfo.label "Les conditions sont liées entre elles par disjonction (relation « ou ») : au moins une d'entre elles doit correspondre.">
+<!ENTITY ruleeditorcondition.label "La chaîne recherchée…">
+<!ENTITY tagsenable.label "Activer les balises dynamiques">
+<!ENTITY tagsedit.label "Éditer les balises dynamiques…">
+<!ENTITY tageditor.title "Éditeur de balises dynamiques">
+<!ENTITY tagimportexport.label "Import / Export de balises dynamiques">
+<!ENTITY tagimportbutton.label "Importer les balises...">
+<!ENTITY tagexportbutton.label "Exporter les balises...">
+<!ENTITY disablealternatives.label "Désactiver les alternatives (utiliser la première cible)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/fr-FR/autofillForms.properties b/chrome/locale/fr-FR/autofillForms.properties
new file mode 100644
index 0000000..738d9de
--- /dev/null
+++ b/chrome/locale/fr-FR/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Remplissage automatique de formulaires Web
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Nom d'utilisateur (?:(?:user)|(?:login)|(?:utilisateur))(?!\\w*pass) (?:) true true\nCourriel (?:mail)|(?:courriel) (?:) true true\nTitre (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title)|(?:titre) (?:) true true\nPrénom (?:first\\w*name)|(?:name\\w*first)|(?:prenom) (?:) true true\nAutre prénom (?:middle\\w*name)|(?:name\\w*middle)|(?:autre\\w*prenom) (?:) true true\nNom de famille (?:last\\w*name)|(?:name\\w*last)|(?:nom\\w*famille) ( [...]
+extensions.autofillForms at blueimp.net.profileLabels=Par défaut
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Remplir les formulaires
+tooltipSubmit=Remplir et soumettre les formulaires
+tooltipAllTabs=Remplir les formulaires dans tous les onglets
+tooltipFromProfileSelection=Remplir les formulaires à partir de la sélection du profil
+tooltipProfile=Gestionnaire de profils
+tooltipSettings=Paramètres
+tooltipDisplayFormDetails=Afficher les détails du formulaire
+currentProfileLabel=Profil actuel :
+profileSelectionWindowTitle=Changer de profil
+profileSelectionFormFillTitle=Remplir les formulaires
+profileSelectionPrompt=Sélectionner le profil :
+contextMenuMore=Plus…
+invalidRegExpTitle=Expression régulière non valide
+invalidRegExpText=L'expression régulière que vous avez entrée n'est pas valable :
+containsRuleType=contient
+beginsWithRuleType=commence par
+endsWithRuleType=finit par
+equalsRuleType=vaut exactement
+alternativesSelectionWindowTitle=Sélectionner une alternative
+alternativesSelectionPrompt=Sélectionnez une alternative :
+importProfile=Importer un profil
+exportProfile=Exporter le profil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Supprimer le profil
+removeProfileText=Voulez-vous vraiment supprimer le profil en cours ?
+removeFieldRulesTitle=Supprimer des règles
+removeFieldRulesText=Voulez-vous vraiment supprimer la ou les règles sélectionnées ?
+sortFieldRulesTitle=Trier les règles
+sortFieldRulesText=Voulez-vous vraiment réorganiser les règles ?
+removeRuleConditionTitle=Supprimer des conditions
+removeRuleConditionText=Voulez-vous vraiment supprimer la ou les conditions sélectionnées ?
+removeDynamicTagTitle=Enlever la balise dynamique
+removeDynamicTagText=Voulez-vous vraiment effacer la ou les balises dynamiques sélectionnées ?
+resetAllProfilesTitle=Réinitialiser tous les profils
+resetAllProfilesText=Voulez-vous vraiment réinitialiser tous les profils ?
+selectConfigDirectory=Choisir le dossier de configuration
+newConfigDirectoryNotEmptyTitle=Dossier non vide
+newConfigDirectoryNotEmptyText=Le nouveau dossier de configuration n'est pas vide. Voulez-vous écraser les fichiers de configuration existants ?
+importFromConfigDirectoryTitle=Importer depuis le dossier de configuration
+importFromConfigDirectoryText=Voulez-vous écraser les profils en utilisant les données du dossier de configuration ?
+command=Commande
+mousebutton=Bouton de souris
+mousebutton0=Bouton gauche de la souris
+mousebutton1=Bouton central de la souris
+mousebutton2=Bouton droit de la souris
+keyboardShortcut=Raccourci clavier
+alt=Alt
+control=Ctrl
+meta=Méta
+shift=Maj
+VK_CANCEL=Annuler
+VK_HELP=Aide
+VK_BACK=Retour
+VK_TAB=Tab
+VK_CLEAR=Effacer
+VK_RETURN=Entrée
+VK_ENTER=Entrée
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Verr. maj.
+VK_ESCAPE=Échap
+VK_SPACE=Espace
+VK_PAGE_UP=Page préc.
+VK_PAGE_DOWN=Page suiv.
+VK_END=Fin
+VK_HOME=Début
+VK_LEFT=Gauche
+VK_UP=Haut
+VK_RIGHT=Droite
+VK_DOWN=Bas
+VK_PRINTSCREEN=Impr. écran
+VK_INSERT=Inser.
+VK_DELETE=Suppr.
+VK_NUM_LOCK=Verr. num.
+VK_SCROLL_LOCK=Arrêt défil.
diff --git a/chrome/locale/he-IL/autofillForms.dtd b/chrome/locale/he-IL/autofillForms.dtd
new file mode 100644
index 0000000..a552065
--- /dev/null
+++ b/chrome/locale/he-IL/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profile Switcher">
+<!ENTITY settingsmenuitem.label "Settings">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Autofill Forms settings">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Advanced">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profile:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Name">
+<!ENTITY fieldrulevalue.label "Value">
+<!ENTITY fieldrulesiterule.label "Site rule">
+<!ENTITY fieldrulefieldrule.label "Field rule">
+<!ENTITY fieldruleoverwrite.label "Overwrite">
+<!ENTITY fieldruleenabled.label "Enabled">
+<!ENTITY apply.label "Apply">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Add">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Remove">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Move Up">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Move Down">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Disable">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Security">
+<!ENTITY storeencrypted.label "Store form field rules encrypted">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Keyboard shortcuts">
+<!ENTITY shortcutfilloutforms.label "Fill out forms:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profile Switcher:">
+<!ENTITY shortcutsettings.label "Settings:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Keyboard shortcut changes only take effect in a new Firefox window.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profile Import / Export">
+<!ENTITY profileimportbutton.label "Import Profile(s)...">
+<!ENTITY profileexportbutton.label "Export current Profile...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Rule Editor...">
+<!ENTITY ruleeditor.title "Rule Editor">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/he-IL/autofillForms.properties b/chrome/locale/he-IL/autofillForms.properties
new file mode 100644
index 0000000..84edd6b
--- /dev/null
+++ b/chrome/locale/he-IL/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=מלא את השדות אוטומטית
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=ברירת מחדל
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Current profile:החלף משתמש
+profileSelectionWindowTitle=החלף משתמש
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=פתח עזרה
+contextMenuMore=More...
+invalidRegExpTitle=Invalid regular expression
+invalidRegExpText=The entered regular expression is not valid:
+containsRuleType=contains
+beginsWithRuleType=begins with
+endsWithRuleType=ends with
+equalsRuleType=equals
+alternativesSelectionWindowTitle=Select alternative
+alternativesSelectionPrompt=Select alternative:
+importProfile=Import Profile
+exportProfile=Export Profile
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancel
+VK_HELP=Help
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/hr-HR/autofillForms.dtd b/chrome/locale/hr-HR/autofillForms.dtd
new file mode 100644
index 0000000..f5e1fc3
--- /dev/null
+++ b/chrome/locale/hr-HR/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profile Switcher">
+<!ENTITY settingsmenuitem.label "Settings">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Autofill Forms postavke">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Advanced">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profile:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Ime">
+<!ENTITY fieldrulevalue.label "Vrijednost">
+<!ENTITY fieldrulesiterule.label "Pravilo stanice">
+<!ENTITY fieldrulefieldrule.label "Pravilo polja">
+<!ENTITY fieldruleoverwrite.label "Prepiši">
+<!ENTITY fieldruleenabled.label "Omogućeno">
+<!ENTITY apply.label "Primijeni">
+<!ENTITY apply.accesskey "r">
+<!ENTITY add.label "Dodaj">
+<!ENTITY add.accesskey "D">
+<!ENTITY remove.label "Ukloni">
+<!ENTITY remove.accesskey "U">
+<!ENTITY moveup.label "Pomakni gore">
+<!ENTITY moveup.accesskey "g">
+<!ENTITY movedown.label "Pomakni dolje">
+<!ENTITY movedown.accesskey "l">
+<!ENTITY disable.label "Onemogući">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Security">
+<!ENTITY storeencrypted.label "Pravila polja obrazaca spremi šifrirano">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Keyboard shortcuts">
+<!ENTITY shortcutfilloutforms.label "Fill out forms:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profile Switcher:">
+<!ENTITY shortcutsettings.label "Settings:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Promjene tipkovničke kratice će se primijeniti tek u novom Firefox prozoru.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profile Import / Export">
+<!ENTITY profileimportbutton.label "Import Profile(s)...">
+<!ENTITY profileexportbutton.label "Export current Profile...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Rule Editor...">
+<!ENTITY ruleeditor.title "Rule Editor">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/hr-HR/autofillForms.properties b/chrome/locale/hr-HR/autofillForms.properties
new file mode 100644
index 0000000..7435ec1
--- /dev/null
+++ b/chrome/locale/hr-HR/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Automatski popunite web obrasce
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Default
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Current profile:
+profileSelectionWindowTitle=Switch Profile
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Select Profile:
+contextMenuMore=More...
+invalidRegExpTitle=Neispravni regularni izraz
+invalidRegExpText=Uneseni regularni izraz nije valjan:
+containsRuleType=contains
+beginsWithRuleType=begins with
+endsWithRuleType=ends with
+equalsRuleType=equals
+alternativesSelectionWindowTitle=Select alternative
+alternativesSelectionPrompt=Select alternative:
+importProfile=Import Profile
+exportProfile=Export Profile
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Meta
+shift=Shift
+VK_CANCEL=Odustani
+VK_HELP=Pomoć
+VK_BACK=Natrag
+VK_TAB=Tab
+VK_CLEAR=Očisti
+VK_RETURN=Vrati
+VK_ENTER=Enter
+VK_PAUSE=Pauza
+VK_CAPS_LOCK=Velika slova
+VK_ESCAPE=Esc
+VK_SPACE=Razmaknica
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Lijevo
+VK_UP=Gore
+VK_RIGHT=Desno
+VK_DOWN=Dolje
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/hu-HU/autofillForms.dtd b/chrome/locale/hu-HU/autofillForms.dtd
new file mode 100644
index 0000000..d6357d8
--- /dev/null
+++ b/chrome/locale/hu-HU/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profil váltása">
+<!ENTITY settingsmenuitem.label "Beállítások">
+<!ENTITY helpmenuitem.label "Súgó">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Mező kitöltése">
+<!ENTITY manualfillcontextmenu.accesskey "e">
+<!ENTITY addrulecontextmenuitem.label "Autofill Forms mezőszabály hozzáadása...">
+<!ENTITY addrulecontextmenuitem.accesskey "h">
+<!ENTITY addformasprofilecontextmenuitem.label "Teljes űrlap hozzáadása mint Autofill Forms profil...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Autofill Forms beállítások">
+<!ENTITY prefpanesimplelabel "Egyszerű">
+<!ENTITY prefpanemainlabel "Általános">
+<!ENTITY prefpaneprofileslabel "Profilok">
+<!ENTITY prefpaneadvancedlabel "Haladó">
+<!ENTITY prefpaneguilabel "Kezelőfelület">
+<!ENTITY resetallprofiles.label "Profilok alapértékeinek visszaállítása">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Weboldal szabály">
+<!ENTITY profilename.label "Név">
+<!ENTITY fieldrulename.label "Név">
+<!ENTITY fieldrulevalue.label "Érték">
+<!ENTITY fieldrulesiterule.label "Weboldal szabály">
+<!ENTITY fieldrulefieldrule.label "Mező szabály">
+<!ENTITY fieldruleoverwrite.label "Felülír">
+<!ENTITY fieldruleenabled.label "Aktív">
+<!ENTITY apply.label "Alkalmaz">
+<!ENTITY apply.accesskey "A">
+<!ENTITY add.label "Hozzáadás">
+<!ENTITY add.accesskey "H">
+<!ENTITY remove.label "Eltávolítás">
+<!ENTITY remove.accesskey "E">
+<!ENTITY moveup.label "Felfelé">
+<!ENTITY moveup.accesskey "F">
+<!ENTITY movedown.label "Lefelé">
+<!ENTITY movedown.accesskey "L">
+<!ENTITY disable.label "Letiltás">
+<!ENTITY validate.label "Érvényesítés">
+<!ENTITY validate.accesskey "r">
+<!ENTITY securitycaption.label "Biztonság">
+<!ENTITY storeencrypted.label "Űrlapszabályok titkosított mentése">
+<!ENTITY storagelocationcaption.label "Tárolóhely">
+<!ENTITY useconfigdirectory.label "Űrlapmezőszabályok tárolása egy konfigurációs mappában">
+<!ENTITY browsedir.label "Tallózás...">
+<!ENTITY resetdir.label "Alaphelyzet">
+<!ENTITY opendir.label "Megnyitás">
+<!ENTITY shortcutscaption.label "Gyorsbillentyűk">
+<!ENTITY shortcutfilloutforms.label "Űrlapon kívüli tartalom:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Űrlapok kitöltése és küldése:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Űrlapok kitöltése minden lapon:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Űrlapok kitöltése a kiválasztott profilokban:">
+<!ENTITY shortcutprofileswitcher.label "Profil váltása:">
+<!ENTITY shortcutsettings.label "Beállítások:">
+<!ENTITY shortcutdisplayformdetails.label "Űrlaprészletek megjelenítése:">
+<!ENTITY shortcutinfo.label "A megváltoztatott gyorsbillentyűk csak új Firefox ablakban lesznek érvényesek.">
+<!ENTITY mousebuttonscaption.label "Egérgombok">
+<!ENTITY mousebuttonclick.label "Kattintás">
+<!ENTITY mouseshortcutinfo.label "Egérgombok alkalmazása az eszköztár és állapotsor kattintásakor.">
+<!ENTITY viewcaption.label "Nézet">
+<!ENTITY hidestatusbaricon.label "Állapotsor ikon elrejtése">
+<!ENTITY hidecontextmenuitem.label "Elrejtés a helyi menüben">
+<!ENTITY hideformfieldscontextmenu.label "Űrlapmezők helyi menüjének elrejtése">
+<!ENTITY hidetoolbarbutton.label "Eszköztár gomb elrejtése">
+<!ENTITY hidetoolbarbuttonmenu.label "Eszköztár gomb menüjének elrejtése">
+<!ENTITY enableconfirmationdialogs.label "Megerősítő ablakok megjelenítése">
+<!ENTITY highlightstylematch.label "Az automatikusan kitöltött űrlapmezők stíluslapja:">
+<!ENTITY highlightstylenomatch.label "A nem automatikusan kitöltött űrlapmezők stíluslapja:">
+<!ENTITY formdetailsstyle.label "Űrlaprészletek stíluslapja:">
+<!ENTITY miscellaneous.label "Vegyes">
+<!ENTITY ignoredisabledrulesonautofill.label "Letiltott szabályok mellőzése űrlapok automatikus kitöltésekor">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Az utolsó találat előtérbe hozása">
+<!ENTITY autoselectbestprofile.label "A legmegfelelőbb profil automatikus kiválasztása">
+<!ENTITY matchagainstlabels.label "Szabályok további egyeztetése az űrlapmező címkéivel">
+<!ENTITY identifylabelsinstrictmode.label "Űrlapmezők címkéinek azonosítása szigorú módban">
+<!ENTITY matchagainstpositions.label "A szabályok kereshetnek űrlapmezőt pozíció szerint">
+<!ENTITY rememberalternativesindex.label "Alternatív jegyzék használata a további kiválasztásokhoz">
+<!ENTITY placeholderlinebreak.label "Szóközök megtartása a szövegmezőkben:">
+<!ENTITY placeholdertab.label "Szóközök megtartása a tabulátoroknál:">
+<!ENTITY enableglobalprofile.label "Globális profil engedélyezése:">
+<!ENTITY formfieldscontextmenu.label "Helyi menü megjelenítése az űrlapmezőkben:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Minden profil">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Aktív profil">
+<!ENTITY profileimportexport.label "Profil importálása/exportálása">
+<!ENTITY profileimportbutton.label "Profil importálása...">
+<!ENTITY profileexportbutton.label "Jelenlegi profil exportálása...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Űrlaprészletek megjelenítése">
+<!ENTITY ruleeditorbutton.label "Szabályszerkesztő...">
+<!ENTITY ruleeditor.title "Szabályszerkesztő">
+<!ENTITY ruleeditorinfo.label "A feltételek VAGY relációval kapcsolódnak egymáshoz - elegendő, ha egy érvényes közülük.">
+<!ENTITY ruleeditorcondition.label "Keresett szöveg ...">
+<!ENTITY tagsenable.label "Dinamikus címkék engedélyezése">
+<!ENTITY tagsedit.label "Dinamikus címkék szerkesztése...">
+<!ENTITY tageditor.title "Dinamikus címke szerkesztő">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/hu-HU/autofillForms.properties b/chrome/locale/hu-HU/autofillForms.properties
new file mode 100644
index 0000000..6348326
--- /dev/null
+++ b/chrome/locale/hu-HU/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Űrlapadatok automatikus kitöltése
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Felhasználónév (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nNév előtag (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nKeresztnév (?:first\\w*name)|(?:name\\w*first) (?:) true true\nKözépső név (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nVezetéknév (?:last\\w*name)|(?:name\\w*last) (?:) true true\nNév utótag (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Teljes) név [...]
+extensions.autofillForms at blueimp.net.profileLabels=Alapértelmezett
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Űrlapok kitöltése
+tooltipSubmit=Űrlapok kitöltése és küldése
+tooltipAllTabs=Űrlapok kitöltése minden lapon
+tooltipFromProfileSelection=Űrlapok kitöltése a kiválasztott profilokban
+tooltipProfile=Profil váltása
+tooltipSettings=Beállítások
+tooltipDisplayFormDetails=Űrlaprészletek megjelenításe
+currentProfileLabel=Jelenlegi profil:
+profileSelectionWindowTitle=Profil váltása
+profileSelectionFormFillTitle=Űrlapok kitöltése
+profileSelectionPrompt=Profil kiválasztása:
+contextMenuMore=Több...
+invalidRegExpTitle=Helytelen kifejezés
+invalidRegExpText=A beírt kifejezés helytelen:
+containsRuleType=tartalmazza
+beginsWithRuleType=kezdődik
+endsWithRuleType=végződik
+equalsRuleType=egyenlő
+alternativesSelectionWindowTitle=Alternatív kiválasztása
+alternativesSelectionPrompt=Alternatív kiválasztása:
+importProfile=Profil importálása
+exportProfile=Profil exportálása
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Profil eltávolítása
+removeProfileText=Valóban eltávolítja a jelenlegi profilt?
+removeFieldRulesTitle=Mezőszabályok eltávolítása
+removeFieldRulesText=Valóban eltávolítja a kiválasztott mezőszabályokat?
+sortFieldRulesTitle=Mezőszabályok rendezése
+sortFieldRulesText=Valóban módosítja a mezőszabályok rendezését?
+removeRuleConditionTitle=Szabályfeltételek eltávolítása
+removeRuleConditionText=Valóban eltávolítja a kiválasztott szabályfeltételeket?
+removeDynamicTagTitle=Dinamikus címke eltávolítása
+removeDynamicTagText=Valóban eltávolítja a kiválasztott dinamikus címkéket?
+resetAllProfilesTitle=Profilok alapértékeinek visszaállítása
+resetAllProfilesText=Valóban visszaállítja az összes profil alapértékeit?
+selectConfigDirectory=Konfigurációs mappa kiválasztása
+newConfigDirectoryNotEmptyTitle=A mappa nem üres
+newConfigDirectoryNotEmptyText=Az új konfigurációs mappa nem üres. Kívánja felülírni a már létező fájlokat?
+importFromConfigDirectoryTitle=Importálás a konfigurációs mappából
+importFromConfigDirectoryText=Kívánja felülírni a profilokat a konfigurációs mappa adataival?
+command=Parancs
+mousebutton=Egérgomb
+mousebutton0=Bal egérgomb
+mousebutton1=Középső egérgomb
+mousebutton2=Jobb egérgomb
+keyboardShortcut=Billentyűkombináció
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Mégse
+VK_HELP=Súgó
+VK_BACK=Vissza
+VK_TAB=Tab
+VK_CLEAR=Tisztít
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Szünet
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/it-IT/autofillForms.dtd b/chrome/locale/it-IT/autofillForms.dtd
new file mode 100644
index 0000000..cd3c255
--- /dev/null
+++ b/chrome/locale/it-IT/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Selettore dei profili">
+<!ENTITY settingsmenuitem.label "Impostazioni">
+<!ENTITY helpmenuitem.label "Guida">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "t">
+<!ENTITY manualfillcontextmenu.label "Compila questo campo">
+<!ENTITY manualfillcontextmenu.accesskey "o">
+<!ENTITY addrulecontextmenuitem.label "Aggiungi una regola di Autofill Forms per questo campo...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Aggiungi modulo completo ai profili di Autofill Forms...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "m">
+<!ENTITY options.title "Impostazioni di Autofill Forms">
+<!ENTITY prefpanesimplelabel "Semplici">
+<!ENTITY prefpanemainlabel "Principali">
+<!ENTITY prefpaneprofileslabel "Profili">
+<!ENTITY prefpaneadvancedlabel "Avanzate">
+<!ENTITY prefpaneguilabel "Interfaccia">
+<!ENTITY resetallprofiles.label "Reimposta tutti i profili">
+<!ENTITY profile.label "Profilo:">
+<!ENTITY profilesiterule.label "Regola per il sito">
+<!ENTITY profilename.label "Nome">
+<!ENTITY fieldrulename.label "Nome">
+<!ENTITY fieldrulevalue.label "Valore">
+<!ENTITY fieldrulesiterule.label "Regola per il sito">
+<!ENTITY fieldrulefieldrule.label "Regola per il campo">
+<!ENTITY fieldruleoverwrite.label "Sovrascrivi">
+<!ENTITY fieldruleenabled.label "Attiva">
+<!ENTITY apply.label "Applica">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Aggiungi">
+<!ENTITY add.accesskey "g">
+<!ENTITY remove.label "Rimuovi">
+<!ENTITY remove.accesskey "R">
+<!ENTITY moveup.label "Sposta in alto">
+<!ENTITY moveup.accesskey "a">
+<!ENTITY movedown.label "Sposta in basso">
+<!ENTITY movedown.accesskey "b">
+<!ENTITY disable.label "Disattiva">
+<!ENTITY validate.label "Valida">
+<!ENTITY validate.accesskey "V">
+<!ENTITY securitycaption.label "Sicurezza">
+<!ENTITY storeencrypted.label "Memorizza regola di campo in forma cifrata">
+<!ENTITY storagelocationcaption.label "Cartella di memorizzazione">
+<!ENTITY useconfigdirectory.label "Memorizza le regole dei campi in una cartella di configurazione personalizzata">
+<!ENTITY browsedir.label "Sfoglia...">
+<!ENTITY resetdir.label "Reimposta">
+<!ENTITY opendir.label "Apri">
+<!ENTITY shortcutscaption.label "Scorciatoie da tastiera">
+<!ENTITY shortcutfilloutforms.label "Compila il modulo:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Compila e invia il modulo:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Compila i moduli di tutte le schede">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Compila i moduli selezionando un profilo:">
+<!ENTITY shortcutprofileswitcher.label "Selettore dei profili:">
+<!ENTITY shortcutsettings.label "Impostazioni:">
+<!ENTITY shortcutdisplayformdetails.label "Visualizza dettagli modulo:">
+<!ENTITY shortcutinfo.label "Le modifiche alle scorciatoie da tastiera avranno effetto solo nelle nuove finestre di Firefox.">
+<!ENTITY mousebuttonscaption.label "Pulsante del mouse">
+<!ENTITY mousebuttonclick.label "Clic">
+<!ENTITY mouseshortcutinfo.label "I pulsanti del mouse sono attivi soltanto sul pulsante nella barra degli strumenti o sull'icona nella barra di stato.">
+<!ENTITY viewcaption.label "Visualizzazione">
+<!ENTITY hidestatusbaricon.label "Non visualizzare l'icona nella barra di stato">
+<!ENTITY hidecontextmenuitem.label "Non visualizzare la voce nel menu contestuale">
+<!ENTITY hideformfieldscontextmenu.label "Non visualizzare la voce nel menu contestuale dei campi dei moduli">
+<!ENTITY hidetoolbarbutton.label "Non visualizzare il pulsante nella barra degli strumenti">
+<!ENTITY hidetoolbarbuttonmenu.label "Non visualizzare il menu relativo al pulsante nella barra degli strumenti">
+<!ENTITY enableconfirmationdialogs.label "Visualizza finestre di conferma">
+<!ENTITY highlightstylematch.label "Stile dei CSS per i campi compilati automaticamente:">
+<!ENTITY highlightstylenomatch.label "Stile dei CSS per i campi non compilati automaticamente:">
+<!ENTITY formdetailsstyle.label "Stile dei CSS per i dettagli del modulo:">
+<!ENTITY miscellaneous.label "Varie">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignora le regole disattivate quando viene compilato automaticamente un modulo">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Posiziona il cursore sull'ultimo campo di modulo verificato come esatto">
+<!ENTITY autoselectbestprofile.label "Seleziona automaticamente il profilo più adatto">
+<!ENTITY matchagainstlabels.label "Confronta le regole anche con le etichette dei moduli">
+<!ENTITY identifylabelsinstrictmode.label "Identifica le etichette dei campi del modulo in modalità Strict">
+<!ENTITY matchagainstpositions.label "Permetti alle regole di trovare le corrispondenza con i campi del modulo in base alla posizione">
+<!ENTITY rememberalternativesindex.label "Utilizza l'indice dell'alternativa selezionata per le scelte successive">
+<!ENTITY placeholderlinebreak.label "Segnaposto per interruzione riga nelle caselle di testo:">
+<!ENTITY placeholdertab.label "Segnaposto per carattere di tabulazione:">
+<!ENTITY enableglobalprofile.label "Attiva profilo generale">
+<!ENTITY formfieldscontextmenu.label "Visualizza nel menu contestuale dei campi dei moduli:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "tutti i profili">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "solo il profilo attivo">
+<!ENTITY profileimportexport.label "Importazione / Esportazione profilo">
+<!ENTITY profileimportbutton.label "Importa profilo...">
+<!ENTITY profileexportbutton.label "Esporta il profilo corrente...">
+<!ENTITY profileexportallbutton.label "Esporta tutti i profili...">
+<!ENTITY formdetails.label "Mostra dettagli del modulo">
+<!ENTITY ruleeditorbutton.label "Editor delle regole...">
+<!ENTITY ruleeditor.title "Editor delle regole">
+<!ENTITY ruleeditorinfo.label "Le condizioni sono unite insieme come disgiunzioni (relazioni di OR) - almeno una fra esse deve corrispondere.">
+<!ENTITY ruleeditorcondition.label "La stringa ricercata...">
+<!ENTITY tagsenable.label "Attiva etichette dinamiche">
+<!ENTITY tagsedit.label "Modifica etichette dinamiche...">
+<!ENTITY tageditor.title "Editor etichette dinamiche">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/it-IT/autofillForms.properties b/chrome/locale/it-IT/autofillForms.properties
new file mode 100644
index 0000000..229a10b
--- /dev/null
+++ b/chrome/locale/it-IT/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Permette di compilare automaticamente i moduli contenuti nelle pagine web
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Nome%20utente (?:(?:user)%7C(?:login))(?!%5Cw*pass) (?:) true true\nE-mail mail (?:) true true\nTitolo (?:prefix%5Cw*name)%7C(?:name%5Cw*prefix)%7C(?:title) (?:) true true\nNome (?:first%5Cw*name)%7C(?:name%5Cw*first) (?:) true true\nPrefisso (?:middle%5Cw*name)%7C(?:name%5Cw*middle) (?:) true true\nCognome (?:last%5Cw*name)%7C(?:name%5Cw*last) (?:) true true\nSuffisso (?:suffix%5Cw*name)%7C(?:name%5Cw*suffix) (?:) true true\nNome%20 [...]
+extensions.autofillForms at blueimp.net.profileLabels=Predefinito
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Compila i moduli
+tooltipSubmit=Compila e invia i moduli
+tooltipAllTabs=Compila i moduli di tutte le schede
+tooltipFromProfileSelection=Compila i moduli selezionando un profilo
+tooltipProfile=Selettore dei profili
+tooltipSettings=Impostazioni
+tooltipDisplayFormDetails=Visualizza dettagli modulo
+currentProfileLabel=Profilo corrente:
+profileSelectionWindowTitle=Cambia profilo
+profileSelectionFormFillTitle=Compila i moduli
+profileSelectionPrompt=Seleziona profilo:
+contextMenuMore=Altre voci...
+invalidRegExpTitle=Espressione regolare non valida
+invalidRegExpText=L'espressione regolare inserita non è valida:
+containsRuleType=contiene
+beginsWithRuleType=inizia per
+endsWithRuleType=termina con
+equalsRuleType=è uguale
+alternativesSelectionWindowTitle=Seleziona alternativo
+alternativesSelectionPrompt=Seleziona alternativo:
+importProfile=Importa profilo
+exportProfile=Esporta profilo
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Elimina profilo
+removeProfileText=Cancellare il profilo corrente?
+removeFieldRulesTitle=Rimuovi le regole per il campo
+removeFieldRulesText=Eliminare le regole per il campo selezionato?
+sortFieldRulesTitle=Ordina le regole di campo
+sortFieldRulesText=Impostare un nuovo ordine per le regole di campo?
+removeRuleConditionTitle=Rimuovi la regola per la condizione
+removeRuleConditionText=Eliminare la regola per la condizione selezionata?
+removeDynamicTagTitle=Rimuovi etichetta dinamica
+removeDynamicTagText=Eliminare l'etichetta dinamica selezionata?
+resetAllProfilesTitle=Reimposta tutti i profili
+resetAllProfilesText=Reimpostare tutti i profili?
+selectConfigDirectory=Seleziona la cartella di configurazione
+newConfigDirectoryNotEmptyTitle=Cartella non vuota
+newConfigDirectoryNotEmptyText=La nuova cartella di configurazione non è vuota. Sovrascrivere i file di configurazione preesistenti?
+importFromConfigDirectoryTitle=Importazione da cartella di configurazione
+importFromConfigDirectoryText=Sovrascrivere i profili con i dati contenuti nella cartella di configurazione?
+command=Comando
+mousebutton=Tasto del mouse
+mousebutton0=Tasto sinistro del mouse
+mousebutton1=Tasto centrale del mouse
+mousebutton2=Tasto destro del mouse
+keyboardShortcut=Scorciatoia da tastiera
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Maiusc
+VK_CANCEL=Annulla
+VK_HELP=Guida
+VK_BACK=Indietro
+VK_TAB=Tab
+VK_CLEAR=Cancella
+VK_RETURN=Invio
+VK_ENTER=Invio
+VK_PAUSE=Pausa
+VK_CAPS_LOCK=Bloc Maiusc
+VK_ESCAPE=Esc
+VK_SPACE=Barra spaziatrice
+VK_PAGE_UP=PgSu
+VK_PAGE_DOWN=PgGiù
+VK_END=Fine
+VK_HOME=Home
+VK_LEFT=Sinistra
+VK_UP=Su
+VK_RIGHT=Destra
+VK_DOWN=Giù
+VK_PRINTSCREEN=Stamp
+VK_INSERT=Ins
+VK_DELETE=Canc
+VK_NUM_LOCK=Bloc Num
+VK_SCROLL_LOCK=Bloc Scorr
diff --git a/chrome/locale/nl-NL/autofillForms.dtd b/chrome/locale/nl-NL/autofillForms.dtd
new file mode 100644
index 0000000..e9831b5
--- /dev/null
+++ b/chrome/locale/nl-NL/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profiel wisselen">
+<!ENTITY settingsmenuitem.label "Instellingen">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Formulieren automatisch invullen">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Dit veld invullen">
+<!ENTITY manualfillcontextmenu.accesskey "u">
+<!ENTITY addrulecontextmenuitem.label "Een Autofill Forms-regel voor dit veld toevoegen...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Volledig formulier als Autofill Forms-profiel toevoegen...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "V">
+<!ENTITY options.title "Autofill Forms instellingen">
+<!ENTITY prefpanesimplelabel "Eenvoudig">
+<!ENTITY prefpanemainlabel "Hoofdvenster">
+<!ENTITY prefpaneprofileslabel "Profielen">
+<!ENTITY prefpaneadvancedlabel "Geavanceerd">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Alle profielen opnieuw instellen">
+<!ENTITY profile.label "Profiel:">
+<!ENTITY profilesiterule.label "Siteregel">
+<!ENTITY profilename.label "Naam">
+<!ENTITY fieldrulename.label "Naam">
+<!ENTITY fieldrulevalue.label "Waarde">
+<!ENTITY fieldrulesiterule.label "Siteregel">
+<!ENTITY fieldrulefieldrule.label "Veldregel">
+<!ENTITY fieldruleoverwrite.label "Overschrijven">
+<!ENTITY fieldruleenabled.label "Ingeschakeld">
+<!ENTITY apply.label "Toepassen">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Toevoegen">
+<!ENTITY add.accesskey "v">
+<!ENTITY remove.label "Verwijderen">
+<!ENTITY remove.accesskey "w">
+<!ENTITY moveup.label "Omhoog">
+<!ENTITY moveup.accesskey "h">
+<!ENTITY movedown.label "Omlaag">
+<!ENTITY movedown.accesskey "l">
+<!ENTITY disable.label "Uitschakelen">
+<!ENTITY validate.label "Valideren">
+<!ENTITY validate.accesskey "a">
+<!ENTITY securitycaption.label "Beveiliging">
+<!ENTITY storeencrypted.label "Formulierveldregels versleuteld opslaan">
+<!ENTITY storagelocationcaption.label "Opslaglocatie">
+<!ENTITY useconfigdirectory.label "Formulierveldregels opslaan in een aangepaste map voor instellingen">
+<!ENTITY browsedir.label "Bladeren...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Openen">
+<!ENTITY shortcutscaption.label "Sneltoetsen">
+<!ENTITY shortcutfilloutforms.label "Formulieren invullen:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Formulieren invullen en indienen:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Formulieren op alle tabbladen invullen:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Formulieren van profielselectie invullen:">
+<!ENTITY shortcutprofileswitcher.label "Profiel wisselen:">
+<!ENTITY shortcutsettings.label "Instellingen:">
+<!ENTITY shortcutdisplayformdetails.label "Formulierdetails weergeven:">
+<!ENTITY shortcutinfo.label "Wijzigingen van de sneltoets worden pas van kracht in een nieuw Firefoxvenster.">
+<!ENTITY mousebuttonscaption.label "Muisknoppen">
+<!ENTITY mousebuttonclick.label "Klik">
+<!ENTITY mouseshortcutinfo.label "Muisknoppen zijn van toepassing op aanklikken van de werkbalkknop of het statusbalkpictogram.">
+<!ENTITY viewcaption.label "Beeld">
+<!ENTITY hidestatusbaricon.label "Statusbalkpictogram verbergen">
+<!ENTITY hidecontextmenuitem.label "Contextmenu-onderdeel verbergen">
+<!ENTITY hideformfieldscontextmenu.label "Contextmenu van formuliervelden verbergen">
+<!ENTITY hidetoolbarbutton.label "Werkbalkknop verbergen">
+<!ENTITY hidetoolbarbuttonmenu.label "Werkbalkknopmenu verbergen">
+<!ENTITY enableconfirmationdialogs.label "Bevestigingsdialogen inschakelen">
+<!ENTITY highlightstylematch.label "CSS stijl voor automatisch ingevulde formuliervelden:">
+<!ENTITY highlightstylenomatch.label "CSS stijl voor niet automatisch ingevulde formuliervelden:">
+<!ENTITY formdetailsstyle.label "CSS-stijl voor formulierdetails:">
+<!ENTITY miscellaneous.label "Diversen">
+<!ENTITY ignoredisabledrulesonautofill.label "Uitgeschakelde regels negeren bij automatisch invullen van formulieren">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Focussen op laatste gematchte formulierveld">
+<!ENTITY autoselectbestprofile.label "Automatisch het best passende profiel selecteren">
+<!ENTITY matchagainstlabels.label "Regels aanvullend matchen tegen formulierveldlabels">
+<!ENTITY identifylabelsinstrictmode.label "Formulierveldlabels in strikte modus identificeren">
+<!ENTITY matchagainstpositions.label "Regels toestaan formuliervelden te matchen op positie">
+<!ENTITY rememberalternativesindex.label "Index van geselecteerde alternatieven gebruiken voor volgende selecties">
+<!ENTITY placeholderlinebreak.label "Plaatshouder voor regelafbrekingen in tekstvelden:">
+<!ENTITY placeholdertab.label "Plaatshouder voor tabinvoer:">
+<!ENTITY enableglobalprofile.label "Algemeen profiel inschakelen:">
+<!ENTITY formfieldscontextmenu.label "In contextmenu van formuliervelden weergeven:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Alle profielen">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Actief profiel">
+<!ENTITY profileimportexport.label "Profiel importeren/exporteren">
+<!ENTITY profileimportbutton.label "Profiel importeren...">
+<!ENTITY profileexportbutton.label "Huidig profiel exporteren...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Formulierdetails weergeven">
+<!ENTITY ruleeditorbutton.label "Regel bewerken...">
+<!ENTITY ruleeditor.title "Regel bewerken">
+<!ENTITY ruleeditorinfo.label "De condities zijn als separate voorwaarden (OR relaties) gedefinieerd - er hoeft er maar één te matchen.">
+<!ENTITY ruleeditorcondition.label "Het gezochte tekstgedeelte...">
+<!ENTITY tagsenable.label "Dynamische labels inschakelen">
+<!ENTITY tagsedit.label "Dynamische labels bewerken...">
+<!ENTITY tageditor.title "Dynamische labels bewerken">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/nl-NL/autofillForms.properties b/chrome/locale/nl-NL/autofillForms.properties
new file mode 100644
index 0000000..eba134d
--- /dev/null
+++ b/chrome/locale/nl-NL/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Vult webformulieren automatisch in
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Gebruikersnaam (?:(?:user)%7C(?:login))(?!%5Cw*pass) (?:) true true\nE-mailadres mail (?:) true true\nTitel (?:prefix%5Cw*name)%7C(?:name%5Cw*prefix)%7C(?:title) (?:) true true\nVoornaam (?:first%5Cw*name)%7C(?:name%5Cw*first) (?:) true true\nMiddelste%20naam (?:middle%5Cw*name)%7C(?:name%5Cw*middle) (?:) true true\nAchternaam (?:last%5Cw*name)%7C(?:name%5Cw*last) (?:) true true\nNaam%20suffix (?:suffix%5Cw*name)%7C(?:name%5Cw*suffix [...]
+extensions.autofillForms at blueimp.net.profileLabels=Standaard
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Formulieren invullen
+tooltipSubmit=Formulieren invullen en indienen
+tooltipAllTabs=Formulieren op alle tabbladen invullen
+tooltipFromProfileSelection=Formulieren van profielselectie invullen
+tooltipProfile=Profiel wisselen
+tooltipSettings=Instellingen
+tooltipDisplayFormDetails=Formulierdetails weergeven
+currentProfileLabel=Huidig profiel:
+profileSelectionWindowTitle=Profiel wisselen
+profileSelectionFormFillTitle=Formulieren invullen
+profileSelectionPrompt=Profiel selecteren:
+contextMenuMore=Meer...
+invalidRegExpTitle=Ongeldige reguliere expressie
+invalidRegExpText=De ingevoerde reguliere expressie is niet geldig:
+containsRuleType=bevat
+beginsWithRuleType=begint met
+endsWithRuleType=eindigt op
+equalsRuleType=is gelijk aan
+alternativesSelectionWindowTitle=Alternatief selecteren
+alternativesSelectionPrompt=Selecteer alternatief:
+importProfile=Profiel importeren
+exportProfile=Profiel exporteren
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Profiel verwijderen
+removeProfileText=Huidig profiel daadwerkelijk verwijderen?
+removeFieldRulesTitle=Veldregels verwijderen
+removeFieldRulesText=Geselecteerde veldregels daadwerkelijk verwijderen?
+sortFieldRulesTitle=Veldregels sorteren
+sortFieldRulesText=Nieuwe volgorde voor veldregels instellen?
+removeRuleConditionTitle=Regelconditie verwijderen
+removeRuleConditionText=Geselecteerde regelconditie daadwerkelijk verwijderen?
+removeDynamicTagTitle=Dynamisch label verwijderen
+removeDynamicTagText=Geselecteerd dynamisch label daadwerkelijk verwijderen?
+resetAllProfilesTitle=Alle profielen opnieuw instellen
+resetAllProfilesText=Alle profielen opnieuw instellen?
+selectConfigDirectory=Map voor instellingen selecteren
+newConfigDirectoryNotEmptyTitle=Map is niet leeg
+newConfigDirectoryNotEmptyText=De nieuwe map voor instellingen is niet leeg. Wilt u bestaande configuratiebestanden overschrijven?
+importFromConfigDirectoryTitle=Importeren uit map voor instellingen
+importFromConfigDirectoryText=Wilt u de profielen overschrijven met de gegevens uit de map voor instellingen?
+command=Opdracht
+mousebutton=Muisknop
+mousebutton0=Linkermuisknop
+mousebutton1=Middelste muisknop
+mousebutton2=Rechtermuisknop
+keyboardShortcut=Sneltoets
+alt=Alt
+control=Ctrl
+meta=Meta
+shift=Shift
+VK_CANCEL=Annuleren
+VK_HELP=Help
+VK_BACK=Backspace
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=CapsLock
+VK_ESCAPE=Esc
+VK_SPACE=Spatie
+VK_PAGE_UP=Page Up
+VK_PAGE_DOWN=Page Down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Links
+VK_UP=Omhoog
+VK_RIGHT=Rechts
+VK_DOWN=Omlaag
+VK_PRINTSCREEN=PrtScn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=ScrLk
diff --git a/chrome/locale/pl-PL/autofillForms.dtd b/chrome/locale/pl-PL/autofillForms.dtd
new file mode 100644
index 0000000..836e255
--- /dev/null
+++ b/chrome/locale/pl-PL/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Wypełnianie formularzy">
+<!ENTITY profilemenuitem.label "Zmień profil">
+<!ENTITY settingsmenuitem.label "Ustawienia">
+<!ENTITY helpmenuitem.label "Pomoc">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Wypełnij to pole">
+<!ENTITY manualfillcontextmenu.accesskey "W">
+<!ENTITY addrulecontextmenuitem.label "Dodaj regułę wypełniania dla tego pola">
+<!ENTITY addrulecontextmenuitem.accesskey "O">
+<!ENTITY addformasprofilecontextmenuitem.label "Dodaj formularz jako profil Autofill Forms...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "F">
+<!ENTITY options.title "Autofill Forms - ustawienia">
+<!ENTITY prefpanesimplelabel "Podstawowe">
+<!ENTITY prefpanemainlabel "Ogólne">
+<!ENTITY prefpaneprofileslabel "Profile">
+<!ENTITY prefpaneadvancedlabel "Zaawansowane">
+<!ENTITY prefpaneguilabel "Interfejs">
+<!ENTITY resetallprofiles.label "Resetuj wszystkie profile">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Reguły witryny">
+<!ENTITY profilename.label "Nazwa">
+<!ENTITY fieldrulename.label "Nazwa">
+<!ENTITY fieldrulevalue.label "Wartość">
+<!ENTITY fieldrulesiterule.label "Reguły witryny">
+<!ENTITY fieldrulefieldrule.label "Reguły pola">
+<!ENTITY fieldruleoverwrite.label "Nadpisz">
+<!ENTITY fieldruleenabled.label "Aktywna">
+<!ENTITY apply.label "Zastosuj">
+<!ENTITY apply.accesskey "Z">
+<!ENTITY add.label "Dodaj">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Usuń">
+<!ENTITY remove.accesskey "U">
+<!ENTITY moveup.label "W górę">
+<!ENTITY moveup.accesskey "g">
+<!ENTITY movedown.label "W dół">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Wyłącz">
+<!ENTITY validate.label "Sprawdź">
+<!ENTITY validate.accesskey "S">
+<!ENTITY securitycaption.label "Bezpieczeństwo">
+<!ENTITY storeencrypted.label "Przechowuj dane formularzy w formie zakodowanej">
+<!ENTITY storagelocationcaption.label "lokalizacja">
+<!ENTITY useconfigdirectory.label "Przechowuj reguły pól formularzy w katalogu konfiguracyjnym">
+<!ENTITY browsedir.label "Przeglądaj">
+<!ENTITY resetdir.label "Resetuj">
+<!ENTITY opendir.label "Otwórz">
+<!ENTITY shortcutscaption.label "Skróty klawiaturowe">
+<!ENTITY shortcutfilloutforms.label "Wypełnianie formularzy:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Wypełnij i wyślij formularze:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Wypełnij formularze we wszystkich kartach:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Wypełnij formularze danymi z wybranego profilu:">
+<!ENTITY shortcutprofileswitcher.label "Zmiana profilu:">
+<!ENTITY shortcutsettings.label "Ustawienia:">
+<!ENTITY shortcutdisplayformdetails.label "Wyświetlaj szczegóły formularza:">
+<!ENTITY shortcutinfo.label "Nowe skróty klawiaturowe będą działały w nowych oknach">
+<!ENTITY mousebuttonscaption.label "Przyciski myszy">
+<!ENTITY mousebuttonclick.label "Kliknięcie">
+<!ENTITY mouseshortcutinfo.label "Kliknięcia przyciskami myszy przypisane do przycisków paska narzędzi lub paska stanu">
+<!ENTITY viewcaption.label "Widok">
+<!ENTITY hidestatusbaricon.label "Nie wyświetlaj ikony na pasku stanu">
+<!ENTITY hidecontextmenuitem.label "Nie wyświetlaj w menu kontekstowym">
+<!ENTITY hideformfieldscontextmenu.label "Nie wyświetlaj w menu kontekstowym pól">
+<!ENTITY hidetoolbarbutton.label "Nie wyświetlaj przycisku na pasku narzędzi">
+<!ENTITY hidetoolbarbuttonmenu.label "Nie wyświetlaj menu przycisku narzędziowego">
+<!ENTITY enableconfirmationdialogs.label "Włącz potwierdzanie dialogów">
+<!ENTITY highlightstylematch.label "Styl CSS dla automatycznie wypełnianych pól formularza:">
+<!ENTITY highlightstylenomatch.label "Styl CSS dla niewypełnianych automatycznie pól formularza:">
+<!ENTITY formdetailsstyle.label "Styl CSS dla formularza:">
+<!ENTITY miscellaneous.label "Różne">
+<!ENTITY ignoredisabledrulesonautofill.label "Podczas wypełniania automatycznego pomijaj wyłączone reguły">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Uaktywnij ostatnie pasujące pole formularza">
+<!ENTITY autoselectbestprofile.label "Automatycznie wybierz najlepiej pasujący profil">
+<!ENTITY matchagainstlabels.label "Dopasuj dane do etykiet pól formularza">
+<!ENTITY identifylabelsinstrictmode.label "Identyfikuj etykiety pól formularza dokładnie">
+<!ENTITY matchagainstpositions.label "Zezwalaj regułom do dopasowywania pól formularza wg pozycji">
+<!ENTITY rememberalternativesindex.label "Użyj wybranego alternatywnego indeksu dla następnych wyborów">
+<!ENTITY placeholderlinebreak.label "Znacznik łamania linii w polach tekstowych:">
+<!ENTITY placeholdertab.label "Zamiennik dla tabulatora">
+<!ENTITY enableglobalprofile.label "Włącz globalny profil:">
+<!ENTITY formfieldscontextmenu.label "Wyświetlaj w polach formularza menu kontekstowe">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Wszystkie profile">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Aktywny profil">
+<!ENTITY profileimportexport.label "Import/Eksport profilu">
+<!ENTITY profileimportbutton.label "Importuj profil">
+<!ENTITY profileexportbutton.label "Eksportuj profil">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Wyświetl szczegóły w formularzu">
+<!ENTITY ruleeditorbutton.label "Edytor reguł">
+<!ENTITY ruleeditor.title "Edytor reguł">
+<!ENTITY ruleeditorinfo.label "Reguły są łączone razem ale rozdzielone warunkiem "OR" - tylko jedna z nich musi pasować">
+<!ENTITY ruleeditorcondition.label "Szukany ciąg znaków ...">
+<!ENTITY tagsenable.label "Włącz dynamiczne znaczniki">
+<!ENTITY tagsedit.label "Edytuj dynamiczne znaczniki">
+<!ENTITY tageditor.title "Edytor dynamicznych znaczników">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/pl-PL/autofillForms.properties b/chrome/locale/pl-PL/autofillForms.properties
new file mode 100644
index 0000000..c5d2349
--- /dev/null
+++ b/chrome/locale/pl-PL/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Wypełnia automatycznie formularze na stronach internetowych
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Nazwa użytkownika (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nAdres e-mail mail (?:) true true\nTytuł (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nImię (?:first\\w*name)|(?:name\\w*first) (?:) true true\nDrugie imię (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nNazwisko (?:last\\w*name)|(?:name\\w*last) (?:) true true\nSufix nazwiska (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\nImię i nazwis [...]
+extensions.autofillForms at blueimp.net.profileLabels=Domyślny
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Wypełnij formularze
+tooltipSubmit=Wypełnij i wyślij formularze
+tooltipAllTabs=Wypełnij formularze we wszystkich kartach
+tooltipFromProfileSelection=Wypełnij formularze z profilu
+tooltipProfile=Przełącznik profili
+tooltipSettings=Ustawienia
+tooltipDisplayFormDetails=Wyświetla szczegóły formularza
+currentProfileLabel=Aktywny profil:
+profileSelectionWindowTitle=Zmiana profilu
+profileSelectionFormFillTitle=Wypełnij formularze
+profileSelectionPrompt=Wybierz profil:
+contextMenuMore=Więcej...
+invalidRegExpTitle=Nieprawidłowe wyrażenie regularne
+invalidRegExpText=Wprowadzone wyrażenie regularne jest nieprawidłowe
+containsRuleType=zawiera
+beginsWithRuleType=zaczyna się od
+endsWithRuleType=kończy się na
+equalsRuleType=równa się
+alternativesSelectionWindowTitle=Wybierz alternatywne
+alternativesSelectionPrompt=Wybierz alternatywne
+importProfile=Importuj profil
+exportProfile=Eksportuj profil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Usuń profil
+removeProfileText=Czy na pewno chcesz usunąć ten profil?
+removeFieldRulesTitle=Usuń dane pola
+removeFieldRulesText=Czy na pewno chcesz usunąć dane wybranego pola?
+sortFieldRulesTitle=Sortuj dane pola
+sortFieldRulesText=Czy na pewno chcesz określić nową kolejność danych pola?
+removeRuleConditionTitle=Usuń składniki reguły
+removeRuleConditionText=Czy na pewno chcesz usunąć składniki wybranej reguły?
+removeDynamicTagTitle=Usuń dynamiczny znacznik
+removeDynamicTagText=Czy na pewno chcesz usunąć dynamiczny znacznik?
+resetAllProfilesTitle=Resetuj wszystkie profile
+resetAllProfilesText=Czy na pewno chcesz zresetować wszystkie profile?
+selectConfigDirectory=Wybierz katalog konfiguracyjny
+newConfigDirectoryNotEmptyTitle=Katalog nie jest pusty
+newConfigDirectoryNotEmptyText=Nowy katalog konfiguracyjny nie jest pusty. Czy chcesz zastąpić istniejące pliki konfiguracyjne?
+importFromConfigDirectoryTitle=Import z katalogu konfiguracyjnego
+importFromConfigDirectoryText=Czy chcesz zastąpić istniejące profile danymi z katalogu konfiguracyjnego?
+command=Command
+mousebutton=Przycisk myszy
+mousebutton0=Lewy przycisk myszy
+mousebutton1=Środkowy przycisk myszy
+mousebutton2=Prawy przycisk myszy
+keyboardShortcut=Skróty klawiaturowe
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancel
+VK_HELP=Help
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=PrtScr
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/pt-BR/autofillForms.dtd b/chrome/locale/pt-BR/autofillForms.dtd
new file mode 100644
index 0000000..5c79888
--- /dev/null
+++ b/chrome/locale/pt-BR/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profile Switcher">
+<!ENTITY settingsmenuitem.label "Configurações">
+<!ENTITY helpmenuitem.label "Ajuda">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add a rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Autofill Forms settings">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Advanced">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profile:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Name">
+<!ENTITY fieldrulevalue.label "Valor">
+<!ENTITY fieldrulesiterule.label "Site rule">
+<!ENTITY fieldrulefieldrule.label "Field rule">
+<!ENTITY fieldruleoverwrite.label "Sobrescrever">
+<!ENTITY fieldruleenabled.label "Ativado">
+<!ENTITY apply.label "Aplicar">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Adicionar">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Remover">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Para cima">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Para baixo">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Desativar">
+<!ENTITY validate.label "Validar">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Segurança">
+<!ENTITY storeencrypted.label "Store form field rules encrypted">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Navegar...">
+<!ENTITY resetdir.label "Reiniciar">
+<!ENTITY opendir.label "Abrir">
+<!ENTITY shortcutscaption.label "Keyboard shortcuts">
+<!ENTITY shortcutfilloutforms.label "Fill out forms:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profile Switcher:">
+<!ENTITY shortcutsettings.label "Configurações:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Keyboard shortcut changes only take effect in a new Firefox window.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Clique">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules also against form field labels">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Todos os perfis">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Perfil ativo">
+<!ENTITY profileimportexport.label "Importar / Exportar Perfil">
+<!ENTITY profileimportbutton.label "Importar Perfil...">
+<!ENTITY profileexportbutton.label "Exportar Perfil atual...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Editor de Regra...">
+<!ENTITY ruleeditor.title "Editor de Regra">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/pt-BR/autofillForms.properties b/chrome/locale/pt-BR/autofillForms.properties
new file mode 100644
index 0000000..45f3226
--- /dev/null
+++ b/chrome/locale/pt-BR/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Preencha automaticamente formulários da web
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=ctrl+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=ctrl+alt+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Default
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Preencher formulários
+tooltipSubmit=Preencher e enviar formulários
+tooltipAllTabs=Preencher formulários em todas as abas
+tooltipFromProfileSelection=Preencher formulários do perfil selecionado
+tooltipProfile=Gerenciar Perfis
+tooltipSettings=Configurações
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Perfil atual
+profileSelectionWindowTitle=Alterar Perfil
+profileSelectionFormFillTitle=Preencher formulários
+profileSelectionPrompt=Selecionar Perfil:
+contextMenuMore=Mais...
+invalidRegExpTitle=Expressão regular inválida
+invalidRegExpText=The entered regular expression is not valid:
+containsRuleType=contém
+beginsWithRuleType=começa com
+endsWithRuleType=termina em
+equalsRuleType=igual
+alternativesSelectionWindowTitle=Selecionar alternativa
+alternativesSelectionPrompt=Selecione a alternativa:
+importProfile=Importar Perfil
+exportProfile=Exportar Perfil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remover Perfil
+removeProfileText=Deseja realmente remover o perfil atual?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Comando
+mousebutton=Botão do Mouse
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancelar
+VK_HELP=Ajuda
+VK_BACK=Voltar
+VK_TAB=Tab
+VK_CLEAR=Limpar
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pausar
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Espaço
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Esquerda
+VK_UP=Cima
+VK_RIGHT=Direita
+VK_DOWN=Baixo
+VK_PRINTSCREEN=Print Screen
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/ro-RO/autofillForms.dtd b/chrome/locale/ro-RO/autofillForms.dtd
new file mode 100644
index 0000000..b4736c8
--- /dev/null
+++ b/chrome/locale/ro-RO/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Comutator profile">
+<!ENTITY settingsmenuitem.label "Configurare">
+<!ENTITY helpmenuitem.label "Ajutor">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Completează acest câmp…">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add a rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Autofill Forms settings">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Advanced">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reiniţializează toate profilele">
+<!ENTITY profile.label "Profile:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Name">
+<!ENTITY fieldrulevalue.label "Value">
+<!ENTITY fieldrulesiterule.label "Site rule">
+<!ENTITY fieldrulefieldrule.label "Field rule">
+<!ENTITY fieldruleoverwrite.label "Overwrite">
+<!ENTITY fieldruleenabled.label "Enabled">
+<!ENTITY apply.label "Apply">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Add">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Remove">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Move Up">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Move Down">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Disable">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Security">
+<!ENTITY storeencrypted.label "Store form field rules encrypted">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Keyboard shortcuts">
+<!ENTITY shortcutfilloutforms.label "Fill out forms:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profile Switcher:">
+<!ENTITY shortcutsettings.label "Settings:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Keyboard shortcut changes only take effect in a new Firefox window.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profile Import / Export">
+<!ENTITY profileimportbutton.label "Import Profile(s)...">
+<!ENTITY profileexportbutton.label "Export current Profile...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Rule Editor...">
+<!ENTITY ruleeditor.title "Rule Editor">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/ro-RO/autofillForms.properties b/chrome/locale/ro-RO/autofillForms.properties
new file mode 100644
index 0000000..9a52c47
--- /dev/null
+++ b/chrome/locale/ro-RO/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Completează formularele automat
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Default
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Completează formularele
+tooltipSubmit=Completează şi trimite formularele
+tooltipAllTabs=Completează formularele din toate filele
+tooltipFromProfileSelection=Completează formularele din profilul selectat??
+tooltipProfile=Comutator profile
+tooltipSettings=Configuraţii
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Profilul curent:
+profileSelectionWindowTitle=Comută profilele
+profileSelectionFormFillTitle=Completează formularele
+profileSelectionPrompt=Selectează profilul:
+contextMenuMore=Mai mult…
+invalidRegExpTitle=Expresie regulată incorectă
+invalidRegExpText=Expresia regulată introdusă este incorectă:
+containsRuleType=conţine
+beginsWithRuleType=începe cu
+endsWithRuleType=se termină cu
+equalsRuleType=egal cu
+alternativesSelectionWindowTitle=Select alternative
+alternativesSelectionPrompt=Select alternative:
+importProfile=Import Profile
+exportProfile=Export Profile
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancel
+VK_HELP=Help
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/ru-RU/autofillForms.dtd b/chrome/locale/ru-RU/autofillForms.dtd
new file mode 100644
index 0000000..1e56e86
--- /dev/null
+++ b/chrome/locale/ru-RU/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Автозаполнение форм">
+<!ENTITY profilemenuitem.label "Менеджер профилей">
+<!ENTITY settingsmenuitem.label "Настройки">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Настройки «Autofill Forms»">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Основные">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Дополнительно">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Профиль:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Имя">
+<!ENTITY fieldrulevalue.label "Значение">
+<!ENTITY fieldrulesiterule.label "Правило для сайта">
+<!ENTITY fieldrulefieldrule.label "Правило для поля">
+<!ENTITY fieldruleoverwrite.label "Перезаписать">
+<!ENTITY fieldruleenabled.label "Использовать">
+<!ENTITY apply.label "Применить">
+<!ENTITY apply.accesskey "и">
+<!ENTITY add.label "Добавить">
+<!ENTITY add.accesskey "о">
+<!ENTITY remove.label "Удалить">
+<!ENTITY remove.accesskey "ь">
+<!ENTITY moveup.label "Выше">
+<!ENTITY moveup.accesskey "ы">
+<!ENTITY movedown.label "Ниже">
+<!ENTITY movedown.accesskey "е">
+<!ENTITY disable.label "Отключить">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Безопасность">
+<!ENTITY storeencrypted.label "Хранить зашифрованными правила полей форм">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Клавиатурные сокращения">
+<!ENTITY shortcutfilloutforms.label "Заполнять формы:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Менеджер профилей:">
+<!ENTITY shortcutsettings.label "Настройки:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Новое клавиатурное сочетание вступит в силу только в новом окне Firefox.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Miscellaneous">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Импорт / Экспорт профилей">
+<!ENTITY profileimportbutton.label "Импортировать профиль...">
+<!ENTITY profileexportbutton.label "Экспортировать текущий профиль...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Отображать подробности форм">
+<!ENTITY ruleeditorbutton.label "Редактор правил...">
+<!ENTITY ruleeditor.title "Редактор правил">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "Искомая строка ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/ru-RU/autofillForms.properties b/chrome/locale/ru-RU/autofillForms.properties
new file mode 100644
index 0000000..8f0cafe
--- /dev/null
+++ b/chrome/locale/ru-RU/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Заполняет веб-формы автоматически
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=По умолчанию
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Текущий профиль:
+profileSelectionWindowTitle=Смена профиля
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Выберите профиль:
+contextMenuMore=More...
+invalidRegExpTitle=Неверное регулярное выражение
+invalidRegExpText=Введённое регулярное выражение недействительно:
+containsRuleType=содержит
+beginsWithRuleType=начинается с
+endsWithRuleType=заканчивается
+equalsRuleType=равно
+alternativesSelectionWindowTitle=Select alternative
+alternativesSelectionPrompt=Select alternative:
+importProfile=Импорт профиля
+exportProfile=Экспорт профиля
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Remove profile
+removeProfileText=Really delete the current profile?
+removeFieldRulesTitle=Remove field rules
+removeFieldRulesText=Really delete the selected field rules?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Remove dynamic tag
+removeDynamicTagText=Really delete the selected dynamic tag?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Cancel
+VK_HELP=Help
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=Clear
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/sk-SK/autofillForms.dtd b/chrome/locale/sk-SK/autofillForms.dtd
new file mode 100644
index 0000000..d06f076
--- /dev/null
+++ b/chrome/locale/sk-SK/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Automaticky vyplniť formuláre">
+<!ENTITY profilemenuitem.label "Prepnutie profilu">
+<!ENTITY settingsmenuitem.label "Nastavenia">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Nastavenia automatického vypĺňania formulárov">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Hlavné">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Rozšírené">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Názov">
+<!ENTITY fieldrulevalue.label "Hodnota">
+<!ENTITY fieldrulesiterule.label "Pravidlo pre stránku">
+<!ENTITY fieldrulefieldrule.label "Pravidlo pre pole">
+<!ENTITY fieldruleoverwrite.label "Prepísať">
+<!ENTITY fieldruleenabled.label "Povolené">
+<!ENTITY apply.label "Použiť">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Pridať">
+<!ENTITY add.accesskey "r">
+<!ENTITY remove.label "Odstrániť">
+<!ENTITY remove.accesskey "o">
+<!ENTITY moveup.label "Posunúť nahor">
+<!ENTITY moveup.accesskey "h">
+<!ENTITY movedown.label "Posunúť nadol">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Zakázať">
+<!ENTITY validate.label "Overiť">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Bezpečnosť">
+<!ENTITY storeencrypted.label "Ukladať pravidlá pre polia nešifrované">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Klávesové skratky">
+<!ENTITY shortcutfilloutforms.label "Vyplniť formuláre:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Prepnúť profil:">
+<!ENTITY shortcutsettings.label "Nastavenia:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Zmena klávesových skratiek nastane až v novom okne Firefoxu.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Rôzne">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Enable Global Profile:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profile Import / Export">
+<!ENTITY profileimportbutton.label "Import Profile(s)...">
+<!ENTITY profileexportbutton.label "Export current Profile...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Display Form Details">
+<!ENTITY ruleeditorbutton.label "Rule Editor...">
+<!ENTITY ruleeditor.title "Rule Editor">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Enable dynamic tags">
+<!ENTITY tagsedit.label "Edit dynamic tags...">
+<!ENTITY tageditor.title "Dynamic Tag Editor">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/sk-SK/autofillForms.properties b/chrome/locale/sk-SK/autofillForms.properties
new file mode 100644
index 0000000..2a0e359
--- /dev/null
+++ b/chrome/locale/sk-SK/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Automaticky vyplní formuláre na internete
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Predvolené
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Aktuálny profil:
+profileSelectionWindowTitle=Prepnutie profilu
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Vybrať profil:
+contextMenuMore=More...
+invalidRegExpTitle=Neplatný regulárny výraz
+invalidRegExpText=Zadaný regulárny výraz je neplatný:
+containsRuleType=obsahuje
+beginsWithRuleType=začína s
+endsWithRuleType=končí s
+equalsRuleType=rovná sa
+alternativesSelectionWindowTitle=Voľba alternatívy
+alternativesSelectionPrompt=Zvoľte alternatívu:
+importProfile=Importovať profil
+exportProfile=Exportovať profil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Odstrániť profil
+removeProfileText=Naozaj odstrániť aktuálny profil?
+removeFieldRulesTitle=Odstránenie previdiel pre polia
+removeFieldRulesText=Naozaj odstrániť zvolené pravidlá pre polia?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Odstránenie podmienky pre pravidlo
+removeRuleConditionText=Naozaj odstrániť zvolenú podmienku pre pravidlo?
+removeDynamicTagTitle=Odstránenie dynamického popisu
+removeDynamicTagText=Naozaj odstrániť zvolený dynamický popis?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Zrušiť
+VK_HELP=Pomoc
+VK_BACK=Späť
+VK_TAB=Tab
+VK_CLEAR=Vymazať
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pozastaviť
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Medzerník
+VK_PAGE_UP=Page Up
+VK_PAGE_DOWN=Page Down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Šípka vľavo
+VK_UP=Šípka hore
+VK_RIGHT=Šípka vpravo
+VK_DOWN=Šípka dole
+VK_PRINTSCREEN=Print Screen
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/sv-SE/autofillForms.dtd b/chrome/locale/sv-SE/autofillForms.dtd
new file mode 100644
index 0000000..d57b26d
--- /dev/null
+++ b/chrome/locale/sv-SE/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Fyll in formulär automatisk">
+<!ENTITY profilemenuitem.label "Byta Profil">
+<!ENTITY settingsmenuitem.label "Inställningar">
+<!ENTITY helpmenuitem.label "Hjälp">
+<!ENTITY autofillformscontextmenuitem.label "Fyll in formulär automatisk">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fyll in detta fält">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Lägg till en regel för detta fält...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "Lägg till färdig formulär som profil">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "Fyll in formulär automatiska inställningar">
+<!ENTITY prefpanesimplelabel "Simpel">
+<!ENTITY prefpanemainlabel "Main">
+<!ENTITY prefpaneprofileslabel "Profiler">
+<!ENTITY prefpaneadvancedlabel "Avancerat">
+<!ENTITY prefpaneguilabel "Gränssnitt">
+<!ENTITY resetallprofiles.label "Ställa om alla profiler">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Hemsida regel">
+<!ENTITY profilename.label "Namn">
+<!ENTITY fieldrulename.label "Namn">
+<!ENTITY fieldrulevalue.label "Värde">
+<!ENTITY fieldrulesiterule.label "Hemsida regel">
+<!ENTITY fieldrulefieldrule.label "Fält regel">
+<!ENTITY fieldruleoverwrite.label "Skriva över">
+<!ENTITY fieldruleenabled.label "Aktiverad">
+<!ENTITY apply.label "Verkställa">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "Lägg till">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "Radera">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "Flytta upp">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Flytta ner">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "Inaktivera">
+<!ENTITY validate.label "Validate">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Säkerhet">
+<!ENTITY storeencrypted.label "Lagra formulär fält regler krypterat">
+<!ENTITY storagelocationcaption.label "Lagrings plats">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Bläddra...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Öppna">
+<!ENTITY shortcutscaption.label "Tangentbords genvägar">
+<!ENTITY shortcutfilloutforms.label "Fyll in formulär:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Byta profil:">
+<!ENTITY shortcutsettings.label "Inställningar:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Tangentbords genvägar ändringar tar endast effekt i en ny Firefox fönster.">
+<!ENTITY mousebuttonscaption.label "Mus knappar">
+<!ENTITY mousebuttonclick.label "Klicka">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "Visa">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Övrigt">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules also against form field labels">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Use selected alternatives index for subsequent selections">
+<!ENTITY placeholderlinebreak.label "Placeholder for line breaks in textareas:">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Aktivera global profil:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "Alla profiler">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Aktivera profil">
+<!ENTITY profileimportexport.label "Profil import/export">
+<!ENTITY profileimportbutton.label "Importera profil...">
+<!ENTITY profileexportbutton.label "Exportera aktuella profil...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Visa formulär detaljer">
+<!ENTITY ruleeditorbutton.label "Regel redigerare...">
+<!ENTITY ruleeditor.title "Regel redigerare">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "The searched string ...">
+<!ENTITY tagsenable.label "Aktivera dynamiska taggar">
+<!ENTITY tagsedit.label "Ändra dynamiska taggar...">
+<!ENTITY tageditor.title "Redigera dynamiska taggar">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/sv-SE/autofillForms.properties b/chrome/locale/sv-SE/autofillForms.properties
new file mode 100644
index 0000000..2ded8fc
--- /dev/null
+++ b/chrome/locale/sv-SE/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Fyll in webbformulär automatiskt
+extensions.autofillForms at blueimp.net.shortcut=alt+j
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=ctrl+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=ctrl+alt+shift+j
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Förvalt
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fyll formulär
+tooltipSubmit=Fyll in och välj formulär
+tooltipAllTabs=Fyll in formulär på alla tabbar
+tooltipFromProfileSelection=Fyll in formulär från profil urval
+tooltipProfile=Byta profil
+tooltipSettings=Inställningar
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Nuvarande profil:
+profileSelectionWindowTitle=Byta Profil
+profileSelectionFormFillTitle=Fyll in formulär
+profileSelectionPrompt=Välj profil:
+contextMenuMore=Mer...
+invalidRegExpTitle=Invalid regular expression
+invalidRegExpText=The entered regular expression is not valid:
+containsRuleType=innehåller
+beginsWithRuleType=börjar med
+endsWithRuleType=slutar med
+equalsRuleType=lika med
+alternativesSelectionWindowTitle=Välj alternativ
+alternativesSelectionPrompt=Välj alternativ:
+importProfile=Importera profil
+exportProfile=Exportera profil
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Radera profil
+removeProfileText=Är du säker på att radera aktuella profilen?
+removeFieldRulesTitle=Radera fält regler
+removeFieldRulesText=Verkligen radera valda fält regler?
+sortFieldRulesTitle=Sortera fält regler
+sortFieldRulesText=Är du säker på att sätta en ny ordning på fält reglerna?
+removeRuleConditionTitle=Remove rule condition
+removeRuleConditionText=Really delete the selected rule condition?
+removeDynamicTagTitle=Radera dynamik tagg
+removeDynamicTagText=Verkligen radera valda dynamiska tagg?
+resetAllProfilesTitle=Omställa alla profiler
+resetAllProfilesText=Är du säker på att omställa alla profiler?
+selectConfigDirectory=Välj config katalog
+newConfigDirectoryNotEmptyTitle=Katalogen är inte tom
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Importera från config katalogen
+importFromConfigDirectoryText=Vill du skriva över profiler med data från config katalogen?
+command=Kommando
+mousebutton=Musknapp
+mousebutton0=Vänster musknapp
+mousebutton1=Mitten musknapp
+mousebutton2=Höger musknapp
+keyboardShortcut=Tangentbord genväg
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Avbryt
+VK_HELP=Hjälp
+VK_BACK=Bak
+VK_TAB=Tab
+VK_CLEAR=Rensa
+VK_RETURN=Tillbaka
+VK_ENTER=Enter
+VK_PAUSE=Paus
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Mellanslag
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Vänster
+VK_UP=Upp
+VK_RIGHT=Höger
+VK_DOWN=Ner
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Instert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/tr-TR/autofillForms.dtd b/chrome/locale/tr-TR/autofillForms.dtd
new file mode 100644
index 0000000..52070ad
--- /dev/null
+++ b/chrome/locale/tr-TR/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "Profil Değiştir">
+<!ENTITY settingsmenuitem.label "Ayarlar">
+<!ENTITY helpmenuitem.label "Help">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "Fill out this field">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "Add an Autofill Forms Rule for this field...">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "Add complete form as Autofill Forms profile...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "c">
+<!ENTITY options.title "Autofill Forms ayarları">
+<!ENTITY prefpanesimplelabel "Simple">
+<!ENTITY prefpanemainlabel "Ana Menü">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "Gelişmiş">
+<!ENTITY prefpaneguilabel "Interface">
+<!ENTITY resetallprofiles.label "Reset all profiles">
+<!ENTITY profile.label "Profil:">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "Ad">
+<!ENTITY fieldrulevalue.label "Değer">
+<!ENTITY fieldrulesiterule.label "Site kuralı">
+<!ENTITY fieldrulefieldrule.label "Değer kuralı">
+<!ENTITY fieldruleoverwrite.label "Üzerine Yaz">
+<!ENTITY fieldruleenabled.label "Etkin">
+<!ENTITY apply.label "Uygula">
+<!ENTITY apply.accesskey "g">
+<!ENTITY add.label "Ekle">
+<!ENTITY add.accesskey "e">
+<!ENTITY remove.label "Kaldır">
+<!ENTITY remove.accesskey "ı">
+<!ENTITY moveup.label "Yukarı Taşı">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "Aşağı Taşı">
+<!ENTITY movedown.accesskey "ş">
+<!ENTITY disable.label "Devre dışı">
+<!ENTITY validate.label "Doğrula">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "Güvenlik">
+<!ENTITY storeencrypted.label "Form değer kurallarını şifrele">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "Klavye kısayolları">
+<!ENTITY shortcutfilloutforms.label "Formları doldur:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "Profil Değiştir:">
+<!ENTITY shortcutsettings.label "Ayarlar:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "Klavye kısayol değişiklikleri sadece yeni Firefox penceresinde uygulanır.">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "View">
+<!ENTITY hidestatusbaricon.label "Hide statusbar icon">
+<!ENTITY hidecontextmenuitem.label "Hide context menu item">
+<!ENTITY hideformfieldscontextmenu.label "Hide form fields context menu">
+<!ENTITY hidetoolbarbutton.label "Hide toolbar button">
+<!ENTITY hidetoolbarbuttonmenu.label "Hide toolbar button menu">
+<!ENTITY enableconfirmationdialogs.label "Enable confirmation dialogs">
+<!ENTITY highlightstylematch.label "CSS Style for autofilled form fields:">
+<!ENTITY highlightstylenomatch.label "CSS Style for not autofilled form fields:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "Çeşitli">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "Set focus on last matched form field">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "Sonraki seçimlerde alternatif olarak seçilenleri kullan">
+<!ENTITY placeholderlinebreak.label "Metin alanlarında satır atlamaları için tutucu kullan">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "Genel Profil Etkin:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "Profil Al / Ver">
+<!ENTITY profileimportbutton.label "Profil Al...">
+<!ENTITY profileexportbutton.label "Geçerli Profili Ver...">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "Form Ayrıntılarını Göster">
+<!ENTITY ruleeditorbutton.label "Kural Düzenleyici...">
+<!ENTITY ruleeditor.title "Kural Düzenleyici">
+<!ENTITY ruleeditorinfo.label "The conditions are linked together as disjunctions (OR relations) - only one of them must match.">
+<!ENTITY ruleeditorcondition.label "Aranan dizi...">
+<!ENTITY tagsenable.label "Dinamik etiketler etkin">
+<!ENTITY tagsedit.label "Dinamik etiketleri düzenle...">
+<!ENTITY tageditor.title "Dinamik Etiket Düzenleyici">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/tr-TR/autofillForms.properties b/chrome/locale/tr-TR/autofillForms.properties
new file mode 100644
index 0000000..1966b5e
--- /dev/null
+++ b/chrome/locale/tr-TR/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=Web formlarını otomatik doldur
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=Varsayılan
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=Geçerli profil:
+profileSelectionWindowTitle=Profil Değiştir
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=Profil Seç
+contextMenuMore=More...
+invalidRegExpTitle=Hatalı ifade
+invalidRegExpText=Girilen ifade geçerli değil:
+containsRuleType=içeriyor
+beginsWithRuleType=ile başlıyor
+endsWithRuleType=ile bitiyor
+equalsRuleType=eşitlikler
+alternativesSelectionWindowTitle=Alternatif seç
+alternativesSelectionPrompt=Alternatif seç:
+importProfile=Profil Al
+exportProfile=Profili Ver
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=Profil kaldır
+removeProfileText=Geçerli profili gerçekten silecek misiniz?
+removeFieldRulesTitle=Kuralları kaldır
+removeFieldRulesText=Seçili kuralları kaldırmak istiyor musunuz?
+sortFieldRulesTitle=Sort field rules
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=Kural koşulunu kaldır
+removeRuleConditionText=Seçili kural koşulunu kaldırmak istiyor musunuz?
+removeDynamicTagTitle=Dinamik etiketi kaldır
+removeDynamicTagText=Seçili dinamik etiketi kaldırmak istiyor musunuz?
+resetAllProfilesTitle=Reset all profiles
+resetAllProfilesText=Really reset all profiles?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=Alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=Vazgeç
+VK_HELP=Yardım
+VK_BACK=Geri
+VK_TAB=Tab
+VK_CLEAR=Temizle
+VK_RETURN=Return
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Sol
+VK_UP=Yukarı
+VK_RIGHT=Sağ
+VK_DOWN=Aşağı
+VK_PRINTSCREEN=Print Scrn
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/zh-CN/autofillForms.dtd b/chrome/locale/zh-CN/autofillForms.dtd
new file mode 100644
index 0000000..2f02399
--- /dev/null
+++ b/chrome/locale/zh-CN/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "身份信息切换">
+<!ENTITY settingsmenuitem.label "设置">
+<!ENTITY helpmenuitem.label "帮助">
+<!ENTITY autofillformscontextmenuitem.label "自动赶写表单">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "填写该域">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "为此域添加一个Autofill Forms规则">
+<!ENTITY addrulecontextmenuitem.accesskey "f">
+<!ENTITY addformasprofilecontextmenuitem.label "将完整的表单作为 Autofill Forms 的选项文件...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "C">
+<!ENTITY options.title "Autofill Forms 设置">
+<!ENTITY prefpanesimplelabel "简单">
+<!ENTITY prefpanemainlabel "基本">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "高级">
+<!ENTITY prefpaneguilabel "界面">
+<!ENTITY resetallprofiles.label "重置所有选项">
+<!ENTITY profile.label "身份信息">
+<!ENTITY profilesiterule.label "Site rule">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "名称">
+<!ENTITY fieldrulevalue.label "值">
+<!ENTITY fieldrulesiterule.label "站点规则">
+<!ENTITY fieldrulefieldrule.label "填写规则">
+<!ENTITY fieldruleoverwrite.label "改写">
+<!ENTITY fieldruleenabled.label "启动">
+<!ENTITY apply.label "应用">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "添加">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "删除">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "向上移动">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "向下移动">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "禁用">
+<!ENTITY validate.label "验证">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "安全">
+<!ENTITY storeencrypted.label "保存加密后的表单填写规则">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "快捷键">
+<!ENTITY shortcutfilloutforms.label "填写表单:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "身份信息切换:">
+<!ENTITY shortcutsettings.label "设置:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "快捷键变更仅在新的Firefox窗口有效">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "查看">
+<!ENTITY hidestatusbaricon.label "隐藏状态栏图标">
+<!ENTITY hidecontextmenuitem.label "隐藏右键菜单项目">
+<!ENTITY hideformfieldscontextmenu.label "隐藏表单区域右键菜单">
+<!ENTITY hidetoolbarbutton.label "隐藏工具栏按钮">
+<!ENTITY hidetoolbarbuttonmenu.label "隐藏工具栏按钮菜单">
+<!ENTITY enableconfirmationdialogs.label "启用确认对话框">
+<!ENTITY highlightstylematch.label "自动填写表单域的CSS样式">
+<!ENTITY highlightstylenomatch.label "非自动填写表单域的CSS样式">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "杂项">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "在最后一个符合的表单域中设置焦点">
+<!ENTITY autoselectbestprofile.label "Automatically select the best matching profile">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "将所选的选项作为以后的选择">
+<!ENTITY placeholderlinebreak.label "文本区域换行占位符">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "启动全局选项">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "身份信息导入/导出">
+<!ENTITY profileimportbutton.label "导入身份信息...">
+<!ENTITY profileexportbutton.label "导出当前身份信息">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "显示表单详细情况">
+<!ENTITY ruleeditorbutton.label "规则编辑器...">
+<!ENTITY ruleeditor.title "规则编辑器">
+<!ENTITY ruleeditorinfo.label "这些条件是如同分离(或相关)地联系在一起——他们中只有一个必须匹配">
+<!ENTITY ruleeditorcondition.label "搜索到的字串...">
+<!ENTITY tagsenable.label "启用动态标签">
+<!ENTITY tagsedit.label "编辑动态标签...">
+<!ENTITY tageditor.title "动态标签编辑器">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/zh-CN/autofillForms.properties b/chrome/locale/zh-CN/autofillForms.properties
new file mode 100644
index 0000000..68efb85
--- /dev/null
+++ b/chrome/locale/zh-CN/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=自动填写表单
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=默认
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=当前身份信息
+profileSelectionWindowTitle=更换身份信息
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=选择身份信息
+contextMenuMore=More...
+invalidRegExpTitle=不合法的正则表达式
+invalidRegExpText=输入的正则表达式不合法
+containsRuleType=包含
+beginsWithRuleType=开始于
+endsWithRuleType=结束于
+equalsRuleType=等于
+alternativesSelectionWindowTitle=选择选项
+alternativesSelectionPrompt=选择选项:
+importProfile=导入身份信息
+exportProfile=导出身份信息
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=移除身份信息
+removeProfileText=您真的要删除当前的身份信息?
+removeFieldRulesTitle=移除区域规则
+removeFieldRulesText=真的要删除选定的区域规则么?
+sortFieldRulesTitle=区域规则排序
+sortFieldRulesText=真的要给这些区域规则排序么?
+removeRuleConditionTitle=删除条件状态
+removeRuleConditionText=真的删除这些条件状态么?
+removeDynamicTagTitle=删除动态标签
+removeDynamicTagText=真的删除这些动态标签么?
+resetAllProfilesTitle=重置所有选项
+resetAllProfilesText=真的重置所有选项么?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=取消
+VK_HELP=帮助
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=清除
+VK_RETURN=返回
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=Caps Lock
+VK_ESCAPE=Esc
+VK_SPACE=Space
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Screen
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/locale/zh-TW/autofillForms.dtd b/chrome/locale/zh-TW/autofillForms.dtd
new file mode 100644
index 0000000..cbccdd5
--- /dev/null
+++ b/chrome/locale/zh-TW/autofillForms.dtd
@@ -0,0 +1,102 @@
+<!ENTITY toolbarbutton.label "Autofill Forms">
+<!ENTITY profilemenuitem.label "設定檔切換">
+<!ENTITY settingsmenuitem.label "設置">
+<!ENTITY helpmenuitem.label "說明">
+<!ENTITY autofillformscontextmenuitem.label "Autofill Forms">
+<!ENTITY autofillformscontextmenuitem.accesskey "u">
+<!ENTITY manualfillcontextmenu.label "填寫這個欄位">
+<!ENTITY manualfillcontextmenu.accesskey "f">
+<!ENTITY addrulecontextmenuitem.label "新增這個欄位到 Autofill Forms 規則...">
+<!ENTITY addrulecontextmenuitem.accesskey "r">
+<!ENTITY addformasprofilecontextmenuitem.label "增加完成表單到設定檔中...">
+<!ENTITY addformasprofilecontextmenuitem.accesskey "p">
+<!ENTITY options.title "自動填寫表單設定">
+<!ENTITY prefpanesimplelabel "範例">
+<!ENTITY prefpanemainlabel "基本">
+<!ENTITY prefpaneprofileslabel "Profiles">
+<!ENTITY prefpaneadvancedlabel "進階">
+<!ENTITY prefpaneguilabel "操作介面">
+<!ENTITY resetallprofiles.label "重置全部設定檔">
+<!ENTITY profile.label "設定檔">
+<!ENTITY profilesiterule.label "網址規則">
+<!ENTITY profilename.label "Name">
+<!ENTITY fieldrulename.label "名稱">
+<!ENTITY fieldrulevalue.label "值">
+<!ENTITY fieldrulesiterule.label "站台規則">
+<!ENTITY fieldrulefieldrule.label "填寫規則">
+<!ENTITY fieldruleoverwrite.label "改寫">
+<!ENTITY fieldruleenabled.label "啟動">
+<!ENTITY apply.label "套用">
+<!ENTITY apply.accesskey "p">
+<!ENTITY add.label "新增">
+<!ENTITY add.accesskey "a">
+<!ENTITY remove.label "刪除">
+<!ENTITY remove.accesskey "r">
+<!ENTITY moveup.label "上移">
+<!ENTITY moveup.accesskey "u">
+<!ENTITY movedown.label "下移">
+<!ENTITY movedown.accesskey "d">
+<!ENTITY disable.label "禁用">
+<!ENTITY validate.label "生效">
+<!ENTITY validate.accesskey "v">
+<!ENTITY securitycaption.label "安全">
+<!ENTITY storeencrypted.label "保存加密後的表單填寫規則">
+<!ENTITY storagelocationcaption.label "Storage location">
+<!ENTITY useconfigdirectory.label "Store form field rules in a custom config directory">
+<!ENTITY browsedir.label "Browse...">
+<!ENTITY resetdir.label "Reset">
+<!ENTITY opendir.label "Open">
+<!ENTITY shortcutscaption.label "快速鍵">
+<!ENTITY shortcutfilloutforms.label "填寫表單:">
+<!ENTITY shortcutfilloutandsubmitforms.label "Fill out and submit forms:">
+<!ENTITY shortcutfilloutformsonalltabs.label "Fill out forms on all tabs:">
+<!ENTITY shortcutfilloutformsfromprofileselection.label "Fill out forms from profile selection:">
+<!ENTITY shortcutprofileswitcher.label "設定檔切換:">
+<!ENTITY shortcutsettings.label "設定:">
+<!ENTITY shortcutdisplayformdetails.label "Display Form Details:">
+<!ENTITY shortcutinfo.label "快速鍵變更僅在新的Firefox視窗有效">
+<!ENTITY mousebuttonscaption.label "Mouse buttons">
+<!ENTITY mousebuttonclick.label "Click">
+<!ENTITY mouseshortcutinfo.label "Mouse buttons apply to toolbar button or statusbar icon clicks.">
+<!ENTITY viewcaption.label "檢視">
+<!ENTITY hidestatusbaricon.label "隱藏狀態列圖示">
+<!ENTITY hidecontextmenuitem.label "隱藏內容選單項目">
+<!ENTITY hideformfieldscontextmenu.label "隱藏表單欄位內容選單">
+<!ENTITY hidetoolbarbutton.label "隱藏工具列按鈕">
+<!ENTITY hidetoolbarbuttonmenu.label "隱藏工具列按鈕選單">
+<!ENTITY enableconfirmationdialogs.label "啟用確認對話框">
+<!ENTITY highlightstylematch.label "使用自動填寫表單的 CSS 樣式欄位:">
+<!ENTITY highlightstylenomatch.label "不使用自動填寫表單的 CSS 樣式欄位:">
+<!ENTITY formdetailsstyle.label "CSS Style for form details:">
+<!ENTITY miscellaneous.label "其他">
+<!ENTITY ignoredisabledrulesonautofill.label "Ignore disabled rules when filling out forms automatically">
+<!ENTITY ignoredisabledfields.label "Ignore disabled fields">
+<!ENTITY focuslastformelementmatch.label "設定游標移到最後吻合的欄位上">
+<!ENTITY autoselectbestprofile.label "自動選擇最適合的 Profile 資訊">
+<!ENTITY matchagainstlabels.label "Match rules against form field labels additionally">
+<!ENTITY identifylabelsinstrictmode.label "Identify form field labels in strict mode">
+<!ENTITY matchagainstpositions.label "Allow rules to match form fields by position">
+<!ENTITY rememberalternativesindex.label "將所選的選項作為以後的選擇">
+<!ENTITY placeholderlinebreak.label "文本區域換行佔位符">
+<!ENTITY placeholdertab.label "Placeholder for tabulator input:">
+<!ENTITY enableglobalprofile.label "啟動通用設定:">
+<!ENTITY formfieldscontextmenu.label "Show in form fields context menu:">
+<!ENTITY formfieldscontextmenuitemallprofiles.label "All profiles">
+<!ENTITY formfieldscontextmenuitemactiveprofile.label "Active profile">
+<!ENTITY profileimportexport.label "設定檔匯入/匯出">
+<!ENTITY profileimportbutton.label "匯入設定檔...">
+<!ENTITY profileexportbutton.label "匯出目前設定檔">
+<!ENTITY profileexportallbutton.label "Export all Profiles...">
+<!ENTITY formdetails.label "顯示表單詳細情況">
+<!ENTITY ruleeditorbutton.label "規則編輯器...">
+<!ENTITY ruleeditor.title "規則編輯器">
+<!ENTITY ruleeditorinfo.label "這些條件是如同分離(或相關)地聯繫在一起——他們中只有一個必須匹配">
+<!ENTITY ruleeditorcondition.label "搜索到的字串...">
+<!ENTITY tagsenable.label "啟用動態標籤">
+<!ENTITY tagsedit.label "編輯動態標籤...">
+<!ENTITY tageditor.title "動態標籤編輯器">
+<!ENTITY tagimportexport.label "Dynamic tags Import / Export">
+<!ENTITY tagimportbutton.label "Import Tags...">
+<!ENTITY tagexportbutton.label "Export Tags...">
+<!ENTITY disablealternatives.label "Disable alternatives (always use first match)">
+<!ENTITY callonchangeafterfillingfields.label "Trigger onchange events after filling out fields">
diff --git a/chrome/locale/zh-TW/autofillForms.properties b/chrome/locale/zh-TW/autofillForms.properties
new file mode 100644
index 0000000..4d9a03d
--- /dev/null
+++ b/chrome/locale/zh-TW/autofillForms.properties
@@ -0,0 +1,88 @@
+extensions.autofillForms at blueimp.net.description=自動填寫表單
+extensions.autofillForms at blueimp.net.shortcut=alt+J
+extensions.autofillForms at blueimp.net.shortcutSubmit=
+extensions.autofillForms at blueimp.net.shortcutAllTabs=
+extensions.autofillForms at blueimp.net.shortcutFromProfileSelection=
+extensions.autofillForms at blueimp.net.shortcutProfile=control+alt+J
+extensions.autofillForms at blueimp.net.shortcutSettings=control+alt+shift+J
+extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails=
+extensions.autofillForms at blueimp.net.fieldRules=Username (?:(?:user)|(?:login))(?!\\w*pass) (?:) true true\nE-mail mail (?:) true true\nTitle (?:prefix\\w*name)|(?:name\\w*prefix)|(?:title) (?:) true true\nFirst name (?:first\\w*name)|(?:name\\w*first) (?:) true true\nMiddle name (?:middle\\w*name)|(?:name\\w*middle) (?:) true true\nLast name (?:last\\w*name)|(?:name\\w*last) (?:) true true\nName suffix (?:suffix\\w*name)|(?:name\\w*suffix) (?:) true true\n(Full) name name (?:) t [...]
+extensions.autofillForms at blueimp.net.profileLabels=預設
+extensions.autofillForms at blueimp.net.dynamicTags=<datetime> <useragent> <langcode> <resolution> <clipboard>
+extensions.autofillForms at blueimp.net.dynamicTagCodes=new Date().toLocaleString() navigator.userAgent navigator.language screen.width+'x'+screen.height this.getClipboardText()
+extensions.autofillForms at blueimp.net.regExpPasswordLabel=(?:pass)
+tooltip=Fill out forms
+tooltipSubmit=Fill out and submit forms
+tooltipAllTabs=Fill out forms on all tabs
+tooltipFromProfileSelection=Fill out forms from profile selection
+tooltipProfile=Profile Switcher
+tooltipSettings=Settings
+tooltipDisplayFormDetails=Display Form Details
+currentProfileLabel=目前設定檔
+profileSelectionWindowTitle=變更設定檔
+profileSelectionFormFillTitle=Fill out forms
+profileSelectionPrompt=選擇設定檔
+contextMenuMore=More...
+invalidRegExpTitle=不合法的正規表示法
+invalidRegExpText=輸入的正規表示法不合法
+containsRuleType=包含
+beginsWithRuleType=開始於
+endsWithRuleType=結束於
+equalsRuleType=等於
+alternativesSelectionWindowTitle=選擇選項
+alternativesSelectionPrompt=選擇選項:
+importProfile=匯入設定檔
+exportProfile=匯出設定檔
+importDynamicTags=Import Dynamic Tags
+exportDynamicTags=Export Dynamic Tags
+removeProfileTitle=移除設定檔
+removeProfileText=您真的要刪除目前的設定檔?
+removeFieldRulesTitle=移除欄位規則
+removeFieldRulesText=您真的要刪除所選擇的欄位規則?
+sortFieldRulesTitle=排序欄位規則
+sortFieldRulesText=Really set a new order for the field rules?
+removeRuleConditionTitle=移除規則條件
+removeRuleConditionText=您真的要刪除所選擇的規則條件?
+removeDynamicTagTitle=移除動態標籤
+removeDynamicTagText=您真的要刪除所選擇的動態標籤?
+resetAllProfilesTitle=重置所有設定檔
+resetAllProfilesText=您真的要重置所有設定檔?
+selectConfigDirectory=Select config directory
+newConfigDirectoryNotEmptyTitle=Directory not empty
+newConfigDirectoryNotEmptyText=The new config directory is not empty. Do you want to overwrite existing config files?
+importFromConfigDirectoryTitle=Import from config directory
+importFromConfigDirectoryText=Do you want to overwrite the profiles with the data from the config directory?
+command=Command
+mousebutton=Mouse Button
+mousebutton0=Left Mouse Button
+mousebutton1=Middle Mouse Button
+mousebutton2=Right Mouse Button
+keyboardShortcut=Keyboard Shortcut
+alt=alt
+control=Ctrl
+meta=Cmd
+shift=Shift
+VK_CANCEL=取消
+VK_HELP=幫助
+VK_BACK=Back
+VK_TAB=Tab
+VK_CLEAR=清除
+VK_RETURN=返回
+VK_ENTER=Enter
+VK_PAUSE=Pause
+VK_CAPS_LOCK=大寫
+VK_ESCAPE=Esc
+VK_SPACE=空白
+VK_PAGE_UP=Page up
+VK_PAGE_DOWN=Page down
+VK_END=End
+VK_HOME=Home
+VK_LEFT=Left
+VK_UP=Up
+VK_RIGHT=Right
+VK_DOWN=Down
+VK_PRINTSCREEN=Print Screen
+VK_INSERT=Insert
+VK_DELETE=Delete
+VK_NUM_LOCK=Num Lock
+VK_SCROLL_LOCK=Scroll Lock
diff --git a/chrome/skin/arrows.png b/chrome/skin/arrows.png
new file mode 100644
index 0000000..47ced03
Binary files /dev/null and b/chrome/skin/arrows.png differ
diff --git a/chrome/skin/autofillForms.css b/chrome/skin/autofillForms.css
new file mode 100644
index 0000000..5d4678d
--- /dev/null
+++ b/chrome/skin/autofillForms.css
@@ -0,0 +1,59 @@
+#autofillFormsButton,
+.autofillFormsButton {
+ list-style-image: url("pencil.png");
+}
+toolbar[iconsize="small"] #autofillFormsButton,
+toolbar[iconsize="small"] .autofillFormsButton,
+.autofillFormsIcon {
+ list-style-image: url("pencil-small.png");
+}
+#autofillFormsButton[cui-areatype="menu-panel"],
+toolbarpaletteitem[place="palette"] > #autofillFormsButton {
+ list-style-image: url("pencil-big.png");
+}
+/** Retina Display **/
+ at media (min-resolution: 2dppx) {
+ toolbar[iconsize="small"] #autofillFormsButton,
+ toolbar[iconsize="small"] .autofillFormsButton,
+ .autofillFormsIcon {
+ list-style-image: url("pencil-big.png");
+ }
+}
+
+
+.autofillFormsProfileIcon {
+ list-style-image: url("profile-small.png");
+}
+.autofillFormsSettingsIcon {
+ list-style-image: url("settings-small.png");
+}
+.autofillFormsHelpIcon {
+ list-style-image: url("help-small.png");
+}
+
+statusbarpanel.autofillFormsIcon {
+ cursor: pointer;
+}
+
+#autofillFormsTooltipCurrentProfile {
+ margin-bottom:10px;
+}
+#autofillFormsTooltipCurrentProfileCaption {
+}
+#autofillFormsTooltipCurrentProfileLabel {
+ font-weight: bold;
+}
+#autofillFormsTooltipGrid {
+}
+.autofillFormsTooltipGridHeader {
+ font-weight:bold;
+ margin-bottom:5px;
+}
+.autofillFormsTooltipGridCommand {
+}
+.autofillFormsTooltipGridMouseButton {
+ font-style:italic;
+}
+.autofillFormsTooltipGridKeyboardShortcut {
+ font-family:monospace;
+}
diff --git a/chrome/skin/autofillFormsMac.css b/chrome/skin/autofillFormsMac.css
new file mode 100644
index 0000000..d2288c5
--- /dev/null
+++ b/chrome/skin/autofillFormsMac.css
@@ -0,0 +1,13 @@
+toolbar[iconsize="small"] #autofillFormsButton,
+toolbar[iconsize="small"] .autofillFormsButton,
+#autofillFormsButton,
+.autofillFormsButton {
+ list-style-image: url("pencil-small.png");
+}
+
+toolbar[iconsize="small"] #autofillFormsButton:hover:active,
+toolbar[iconsize="small"] .autofillFormsButton:hover:active,
+#autofillFormsButton:hover:active,
+.autofillFormsButton:hover:active {
+ list-style-image: url("pencil-small.png");
+}
\ No newline at end of file
diff --git a/chrome/skin/autofillFormsOptions.css b/chrome/skin/autofillFormsOptions.css
new file mode 100644
index 0000000..48b294c
--- /dev/null
+++ b/chrome/skin/autofillFormsOptions.css
@@ -0,0 +1,84 @@
+ at import url(chrome://global/skin/);
+
+#simpleInterfaceRowsContainer {
+ overflow:auto;
+}
+
+#autofillFormsPrefPaneMainBox {
+ margin-bottom:5px;
+}
+
+#fieldRulesTree {
+ min-height:100px;
+}
+#profilesTree {
+ min-height:100px;
+}
+
+treechildren::-moz-tree-checkbox {
+ /* unchecked checkbox treecells */
+ list-style-image: none;
+}
+treechildren::-moz-tree-checkbox(checked) {
+ /* checked checkbox treecells*/
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-checkbox(disabled) {
+ /* disabled checkbox treecells */
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+button.move {
+ list-style-image: url("arrows.png");
+}
+
+button.up {
+ -moz-image-region: rect( 16px 32px 32px 16px);
+}
+button.up[disabled="true"] {
+ -moz-image-region: rect( 0px 32px 16px 16px);
+}
+
+button.down {
+ -moz-image-region: rect( 16px 16px 32px 0px);
+}
+button.down[disabled="true"] {
+ -moz-image-region: rect( 0px 16px 16px 0px);
+}
+
+.placeholderTextbox {
+ width:100px;
+}
+
+.shortCutsLabelColumn {
+ max-width:170px;
+}
+.shortCutsKeyColumn {
+ min-width:200px;
+}
+
+.shortcutTextbox {
+ font-family:monospace;
+}
+.mouseShortcutTextbox {
+}
+
+#autofillFormsPrefs radio[pane] {
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+}
+
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneSimple"] {
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneMain"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneProfiles"] {
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneAdvanced"] {
+ -moz-image-region: rect(0px, 224px, 32px, 192px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneGUI"] {
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
diff --git a/chrome/skin/autofillFormsOptions1.5.css b/chrome/skin/autofillFormsOptions1.5.css
new file mode 100644
index 0000000..0fe8d37
--- /dev/null
+++ b/chrome/skin/autofillFormsOptions1.5.css
@@ -0,0 +1,10 @@
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneProfiles"] {
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneAdvanced"] {
+ -moz-image-region: rect(0px, 160px, 32px, 128px);
+}
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneGUI"] {
+ -moz-image-region: rect(0px, 192px, 32px, 160px);
+}
\ No newline at end of file
diff --git a/chrome/skin/autofillFormsOptions2.css b/chrome/skin/autofillFormsOptions2.css
new file mode 100644
index 0000000..b043577
--- /dev/null
+++ b/chrome/skin/autofillFormsOptions2.css
@@ -0,0 +1,4 @@
+#autofillFormsPrefs radio[pane="autofillFormsPrefPaneProfiles"] {
+ list-style-image: url("chrome://mozapps/skin/extensions/viewButtons.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
\ No newline at end of file
diff --git a/chrome/skin/autofillFormsRuleEditor.css b/chrome/skin/autofillFormsRuleEditor.css
new file mode 100644
index 0000000..be8569d
--- /dev/null
+++ b/chrome/skin/autofillFormsRuleEditor.css
@@ -0,0 +1 @@
+ at import url(chrome://global/skin/);
\ No newline at end of file
diff --git a/chrome/skin/autofillFormsTagEditor.css b/chrome/skin/autofillFormsTagEditor.css
new file mode 100644
index 0000000..be8569d
--- /dev/null
+++ b/chrome/skin/autofillFormsTagEditor.css
@@ -0,0 +1 @@
+ at import url(chrome://global/skin/);
\ No newline at end of file
diff --git a/chrome/skin/help-small.png b/chrome/skin/help-small.png
new file mode 100644
index 0000000..916200c
Binary files /dev/null and b/chrome/skin/help-small.png differ
diff --git a/chrome/skin/icon.png b/chrome/skin/icon.png
new file mode 100644
index 0000000..ebb0ec7
Binary files /dev/null and b/chrome/skin/icon.png differ
diff --git a/chrome/skin/pencil-active-mac.png b/chrome/skin/pencil-active-mac.png
new file mode 100644
index 0000000..25f479b
Binary files /dev/null and b/chrome/skin/pencil-active-mac.png differ
diff --git a/chrome/skin/pencil-big.png b/chrome/skin/pencil-big.png
new file mode 100644
index 0000000..ebb0ec7
Binary files /dev/null and b/chrome/skin/pencil-big.png differ
diff --git a/chrome/skin/pencil-mac.png b/chrome/skin/pencil-mac.png
new file mode 100644
index 0000000..7789ec2
Binary files /dev/null and b/chrome/skin/pencil-mac.png differ
diff --git a/chrome/skin/pencil-small.png b/chrome/skin/pencil-small.png
new file mode 100644
index 0000000..34afe66
Binary files /dev/null and b/chrome/skin/pencil-small.png differ
diff --git a/chrome/skin/pencil.png b/chrome/skin/pencil.png
new file mode 100644
index 0000000..26117a7
Binary files /dev/null and b/chrome/skin/pencil.png differ
diff --git a/chrome/skin/profile-small.png b/chrome/skin/profile-small.png
new file mode 100644
index 0000000..1ff6094
Binary files /dev/null and b/chrome/skin/profile-small.png differ
diff --git a/chrome/skin/settings-small.png b/chrome/skin/settings-small.png
new file mode 100644
index 0000000..0cf9a7f
Binary files /dev/null and b/chrome/skin/settings-small.png differ
diff --git a/defaults/preferences/autofillForms.js b/defaults/preferences/autofillForms.js
new file mode 100644
index 0000000..a6dbf2e
--- /dev/null
+++ b/defaults/preferences/autofillForms.js
@@ -0,0 +1,55 @@
+pref('extensions.autofillForms at blueimp.net.description', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcut', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutSubmit', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutAllTabs', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutFromProfileSelection', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutProfile', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutSettings', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.shortcutDisplayFormDetails', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.mouseShortcut', 'mousebutton0');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutSubmit', 'control+mousebutton0');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutAllTabs', 'control+mousebutton1');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutFromProfileSelection', 'mousebutton1');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutProfile', '');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutSettings', '');
+pref('extensions.autofillForms at blueimp.net.mouseShortcutDisplayFormDetails', '');
+pref('extensions.autofillForms at blueimp.net.fieldRules', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.profileLabels', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.dynamicTags', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.dynamicTagCodes', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.regExpPasswordLabel', 'chrome://autofillForms/locale/autofillForms.properties');
+pref('extensions.autofillForms at blueimp.net.regExpFormFieldTypes', '^(?:(?:text(?:area)?)|(?:select-(?:(?:one)|(?:multiple)))|(?:checkbox)|(?:radio)|(?:email)|(?:url)|(?:password)|(?:file))$');
+pref('extensions.autofillForms at blueimp.net.enableDynamicTags', false);
+pref('extensions.autofillForms at blueimp.net.profileIndex', 0);
+pref('extensions.autofillForms at blueimp.net.storeEncrypted', false);
+pref('extensions.autofillForms at blueimp.net.formDetailsStyle', 'color:#000; background-color:#FFFF00; border:1px solid #000;');
+pref('extensions.autofillForms at blueimp.net.rememberAlternativesIndex', true);
+pref('extensions.autofillForms at blueimp.net.placeholderLineBreak', '<br>');
+pref('extensions.autofillForms at blueimp.net.placeholderTab', ' ');
+pref('extensions.autofillForms at blueimp.net.highlightStyleMatch', '');
+pref('extensions.autofillForms at blueimp.net.highlightStyleNoMatch', '');
+pref('extensions.autofillForms at blueimp.net.enableGlobalProfile', false);
+pref('extensions.autofillForms at blueimp.net.globalProfileIndex', 0);
+pref('extensions.autofillForms at blueimp.net.formFieldsContextMenuProfileIndex', -3);
+pref('extensions.autofillForms at blueimp.net.ignoreDisabledRulesOnAutofill', true);
+pref('extensions.autofillForms at blueimp.net.ignoreDisabledFields', true);
+pref('extensions.autofillForms at blueimp.net.disableAlternatives', false);
+pref('extensions.autofillForms at blueimp.net.callOnChangeAfterFillingFields', false);
+pref('extensions.autofillForms at blueimp.net.enableConfirmationDialogs', true);
+pref('extensions.autofillForms at blueimp.net.matchAgainstLabels', true);
+pref('extensions.autofillForms at blueimp.net.labelsStrictMode', true);
+pref('extensions.autofillForms at blueimp.net.matchAgainstPositions', false);
+pref('extensions.autofillForms at blueimp.net.positionsIdentifier', '#');
+pref('extensions.autofillForms at blueimp.net.focusLastFormElementMatch', true);
+pref('extensions.autofillForms at blueimp.net.hideStatusbarIcon', true);
+pref('extensions.autofillForms at blueimp.net.hideContextMenuItem', false);
+pref('extensions.autofillForms at blueimp.net.hideFormFieldsContextMenu', false);
+pref('extensions.autofillForms at blueimp.net.hideToolbarButton', false);
+pref('extensions.autofillForms at blueimp.net.hideToolbarButtonMenu', false);
+pref('extensions.autofillForms at blueimp.net.configDirectory', '');
+pref('extensions.autofillForms at blueimp.net.useConfigDirectory', false);
+pref('extensions.autofillForms at blueimp.net.profileSiteRules', '(?:)');
+pref('extensions.autofillForms at blueimp.net.autoSelectBestProfile', true);
+pref('extensions.autofillForms at blueimp.net.helpURL', 'http://firefox.add0n.com/autofill-forms.html');
+pref("extensions.autofillForms at blueimp.net.version", "");
+pref("extensions.autofillForms at blueimp.net.post_install_url", "http://firefox.add0n.com/autofill-forms.html");
diff --git a/install.rdf b/install.rdf
new file mode 100644
index 0000000..184797d
--- /dev/null
+++ b/install.rdf
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding='utf-8'?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>autofillForms at blueimp.net</em:id>
+ <em:name>Autofill Forms</em:name>
+ <em:creator>Sebastian Tschan</em:creator>
+ <em:contributor>Sarah Avilov</em:contributor>
+ <em:description>Fill out web forms automatically</em:description>
+ <em:iconURL>chrome://autofillForms/skin/icon.png</em:iconURL>
+ <em:optionsURL>chrome://autofillForms/content/autofillFormsOptions.xul</em:optionsURL>
+ <em:homepageURL>http://firefox.add0n.com/autofill-forms.html</em:homepageURL>
+ <em:version>1.0.4</em:version>
+ <em:type>2</em:type>
+ <em:targetApplication>
+ <Description>
+ <!-- Firefox -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>17.0</em:minVersion>
+ <em:maxVersion>35.0</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- Midbrowser -->
+ <em:id>{aa5ca914-c309-495d-91cf-3141bbb04115}</em:id>
+ <em:minVersion>0.2</em:minVersion>
+ <em:maxVersion>2.0.0.6</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:translator>PetrTwo (Czech)</em:translator>
+ <em:translator>Oliver Roth (German)</em:translator>
+ <em:translator>Koumen (Greek)</em:translator>
+ <em:translator>jesuspportillo (Spanish)</em:translator>
+ <em:translator>Unknown (Finnish)</em:translator>
+ <em:translator>myahoo (French)</em:translator>
+ <em:translator>YuvalSht (Hebrew)</em:translator>
+ <em:translator>Mikes Kaszmán István (Hungarian)</em:translator>
+ <em:translator>Underpass (Italian)</em:translator>
+ <em:translator>gonzalopirobutirro (Italian)</em:translator>
+ <em:translator>Godai71 (Italian)</em:translator>
+ <em:translator>markh (Dutch)</em:translator>
+ <em:translator>teo (Polish)</em:translator>
+ <em:translator>Alberto Eidh (Portuguese - Brazilian)</em:translator>
+ <em:translator>x10firefox (Romanian)</em:translator>
+ <em:translator>Unknown (Russian)</em:translator>
+ <em:translator>Umut (Swedish)</em:translator>
+ <em:translator>ch0ze (Slovak)</em:translator>
+ <em:translator>KenanBalamir (Turkish)</em:translator>
+ <em:translator>simophin (Chinese - Simplified)</em:translator>
+ <em:translator>Lu Ming-Tse (呂明澤) (Chinese - Traditional)</em:translator>
+ </Description>
+</RDF>
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..8594347
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,2 @@
+zip -9 -r aff.xpi chrome defaults install.rdf chrome.manifest
+wget --post-file=aff.xpi http://localhost:8888/
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/autofill-forms.git
More information about the Pkg-mozext-commits
mailing list