summaryrefslogtreecommitdiffstats
path: root/components/sessionstore/DocumentUtils.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'components/sessionstore/DocumentUtils.jsm')
-rw-r--r--components/sessionstore/DocumentUtils.jsm230
1 files changed, 0 insertions, 230 deletions
diff --git a/components/sessionstore/DocumentUtils.jsm b/components/sessionstore/DocumentUtils.jsm
deleted file mode 100644
index 6b3f729..0000000
--- a/components/sessionstore/DocumentUtils.jsm
+++ /dev/null
@@ -1,230 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-this.EXPORTED_SYMBOLS = [ "DocumentUtils" ];
-
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/sessionstore/XPathGenerator.jsm");
-
-this.DocumentUtils = {
- /**
- * Obtain form data for a DOMDocument instance.
- *
- * The returned object has 2 keys, "id" and "xpath". Each key holds an object
- * which further defines form data.
- *
- * The "id" object maps element IDs to values. The "xpath" object maps the
- * XPath of an element to its value.
- *
- * @param aDocument
- * DOMDocument instance to obtain form data for.
- * @return object
- * Form data encoded in an object.
- */
- getFormData: function DocumentUtils_getFormData(aDocument) {
- let formNodes = aDocument.evaluate(
- XPathGenerator.restorableFormNodes,
- aDocument,
- XPathGenerator.resolveNS,
- Ci.nsIDOMXPathResult.UNORDERED_NODE_ITERATOR_TYPE, null
- );
-
- let node;
- let ret = {id: {}, xpath: {}};
-
- // Limit the number of XPath expressions for performance reasons. See
- // bug 477564.
- const MAX_TRAVERSED_XPATHS = 100;
- let generatedCount = 0;
-
- while (node = formNodes.iterateNext()) {
- let nId = node.id;
- let hasDefaultValue = true;
- let value;
-
- // Only generate a limited number of XPath expressions for perf reasons
- // (cf. bug 477564)
- if (!nId && generatedCount > MAX_TRAVERSED_XPATHS) {
- continue;
- }
-
- if (node instanceof Ci.nsIDOMHTMLInputElement ||
- node instanceof Ci.nsIDOMHTMLTextAreaElement) {
- switch (node.type) {
- case "checkbox":
- case "radio":
- value = node.checked;
- hasDefaultValue = value == node.defaultChecked;
- break;
- case "file":
- value = { type: "file", fileList: node.mozGetFileNameArray() };
- hasDefaultValue = !value.fileList.length;
- break;
- default: // text, textarea
- value = node.value;
- hasDefaultValue = value == node.defaultValue;
- break;
- }
- } else if (!node.multiple) {
- // <select>s without the multiple attribute are hard to determine the
- // default value, so assume we don't have the default.
- hasDefaultValue = false;
- value = { selectedIndex: node.selectedIndex, value: node.value };
- } else {
- // <select>s with the multiple attribute are easier to determine the
- // default value since each <option> has a defaultSelected
- let options = Array.map(node.options, function(aOpt, aIx) {
- let oSelected = aOpt.selected;
- hasDefaultValue = hasDefaultValue && (oSelected == aOpt.defaultSelected);
- return oSelected ? aOpt.value : -1;
- });
- value = options.filter(function(aIx) aIx !== -1);
- }
-
- // In order to reduce XPath generation (which is slow), we only save data
- // for form fields that have been changed. (cf. bug 537289)
- if (!hasDefaultValue) {
- if (nId) {
- ret.id[nId] = value;
- } else {
- generatedCount++;
- ret.xpath[XPathGenerator.generate(node)] = value;
- }
- }
- }
-
- return ret;
- },
-
- /**
- * Merges form data on a document from previously obtained data.
- *
- * This is the inverse of getFormData(). The data argument is the same object
- * type which is returned by getFormData(): an object containing the keys
- * "id" and "xpath" which are each objects mapping element identifiers to
- * form values.
- *
- * Where the document has existing form data for an element, the value
- * will be replaced. Where the document has a form element but no matching
- * data in the passed object, the element is untouched.
- *
- * @param aDocument
- * DOMDocument instance to which to restore form data.
- * @param aData
- * Object defining form data.
- */
- mergeFormData: function DocumentUtils_mergeFormData(aDocument, aData) {
- if ("xpath" in aData) {
- for each (let [xpath, value] in Iterator(aData.xpath)) {
- let node = XPathGenerator.resolve(aDocument, xpath);
-
- if (node) {
- this.restoreFormValue(node, value, aDocument);
- }
- }
- }
-
- if ("id" in aData) {
- for each (let [id, value] in Iterator(aData.id)) {
- let node = aDocument.getElementById(id);
-
- if (node) {
- this.restoreFormValue(node, value, aDocument);
- }
- }
- }
- },
-
- /**
- * Low-level function to restore a form value to a DOMNode.
- *
- * If you want a higher-level interface, see mergeFormData().
- *
- * When the value is changed, the function will fire the appropriate DOM
- * events.
- *
- * @param aNode
- * DOMNode to set form value on.
- * @param aValue
- * Value to set form element to.
- * @param aDocument [optional]
- * DOMDocument node belongs to. If not defined, node.ownerDocument
- * is used.
- */
- restoreFormValue: function DocumentUtils_restoreFormValue(aNode, aValue, aDocument) {
- aDocument = aDocument || aNode.ownerDocument;
-
- let eventType;
-
- if (typeof aValue == "string" && aNode.type != "file") {
- // Don't dispatch an input event if there is no change.
- if (aNode.value == aValue) {
- return;
- }
-
- aNode.value = aValue;
- eventType = "input";
- } else if (typeof aValue == "boolean") {
- // Don't dispatch a change event for no change.
- if (aNode.checked == aValue) {
- return;
- }
-
- aNode.checked = aValue;
- eventType = "change";
- } else if (typeof aValue == "number") {
- // handle select backwards compatibility, example { "#id" : index }
- // We saved the value blindly since selects take more work to determine
- // default values. So now we should check to avoid unnecessary events.
- if (aNode.selectedIndex == aValue) {
- return;
- }
-
- if (aValue < aNode.options.length) {
- aNode.selectedIndex = aValue;
- eventType = "change";
- }
- } else if (aValue && aValue.selectedIndex >= 0 && aValue.value) {
- // handle select new format
-
- // Don't dispatch a change event for no change
- if (aNode.options[aNode.selectedIndex].value == aValue.value) {
- return;
- }
-
- // find first option with matching aValue if possible
- for (let i = 0; i < aNode.options.length; i++) {
- if (aNode.options[i].value == aValue.value) {
- aNode.selectedIndex = i;
- break;
- }
- }
- eventType = "change";
- } else if (aValue && aValue.fileList && aValue.type == "file" &&
- aNode.type == "file") {
- aNode.mozSetFileNameArray(aValue.fileList, aValue.fileList.length);
- eventType = "input";
- } else if (aValue && typeof aValue.indexOf == "function" && aNode.options) {
- Array.forEach(aNode.options, function(opt, index) {
- // don't worry about malformed options with same values
- opt.selected = aValue.indexOf(opt.value) > -1;
-
- // Only fire the event here if this wasn't selected by default
- if (!opt.defaultSelected) {
- eventType = "change";
- }
- });
- }
-
- // Fire events for this node if applicable
- if (eventType) {
- let event = aDocument.createEvent("UIEvents");
- event.initUIEvent(eventType, true, true, aDocument.defaultView, 0);
- aNode.dispatchEvent(event);
- }
- }
-};