зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1310049 - Refactor FormLikeFactory to its own module for use by Form Autofill. r=steveck
This introduces LoginFormFactory which wraps FormLikeFactory for use with login-specific contexts. MozReview-Commit-ID: 6rPz5JOy3Yp --HG-- rename : toolkit/components/passwordmgr/LoginManagerContent.jsm => toolkit/modules/FormLikeFactory.jsm extra : rebase_source : b2a28803def0dce3de4a01db5bdbc3217c5d0f83
This commit is contained in:
Родитель
d9a7400119
Коммит
e911e68e21
|
@ -24,7 +24,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "ContentLinkHandler",
|
|||
"resource:///modules/ContentLinkHandler.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent",
|
||||
"resource://gre/modules/LoginManagerContent.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormLikeFactory",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginFormFactory",
|
||||
"resource://gre/modules/LoginManagerContent.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils",
|
||||
"resource://gre/modules/InsecurePasswordUtils.jsm");
|
||||
|
@ -65,12 +65,12 @@ addMessageListener("RemoteLogins:fillForm", function(message) {
|
|||
});
|
||||
addEventListener("DOMFormHasPassword", function(event) {
|
||||
LoginManagerContent.onDOMFormHasPassword(event, content);
|
||||
let formLike = FormLikeFactory.createFromForm(event.target);
|
||||
let formLike = LoginFormFactory.createFromForm(event.target);
|
||||
InsecurePasswordUtils.checkForInsecurePasswords(formLike);
|
||||
});
|
||||
addEventListener("DOMInputPasswordAdded", function(event) {
|
||||
LoginManagerContent.onDOMInputPasswordAdded(event, content);
|
||||
let formLike = FormLikeFactory.createFromField(event.target);
|
||||
let formLike = LoginFormFactory.createFromField(event.target);
|
||||
InsecurePasswordUtils.checkForInsecurePasswords(formLike);
|
||||
});
|
||||
addEventListener("pageshow", function(event) {
|
||||
|
|
|
@ -43,7 +43,7 @@ this.InsecurePasswordUtils = {
|
|||
* or on insecure web pages. If insecure password fields are present,
|
||||
* a log message is sent to the web console to warn developers.
|
||||
*
|
||||
* @param {FormLike} aForm A form-like object. @See {FormLikeFactory}
|
||||
* @param {FormLike} aForm A form-like object. @See {LoginFormFactory}
|
||||
*/
|
||||
checkForInsecurePasswords(aForm) {
|
||||
if (this._formRootsWarned.has(aForm.rootElement) ||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "LoginManagerContent",
|
||||
"FormLikeFactory",
|
||||
"LoginFormFactory",
|
||||
"UserAutoCompleteResult" ];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
||||
|
@ -17,6 +17,8 @@ Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormLikeFactory",
|
||||
"resource://gre/modules/FormLikeFactory.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginRecipesContent",
|
||||
"resource://gre/modules/LoginRecipes.jsm");
|
||||
|
||||
|
@ -49,7 +51,7 @@ var observer = {
|
|||
// can grab form data before it might be modified (see bug 257781).
|
||||
|
||||
try {
|
||||
let formLike = FormLikeFactory.createFromForm(formElement);
|
||||
let formLike = LoginFormFactory.createFromForm(formElement);
|
||||
LoginManagerContent._onFormSubmit(formLike);
|
||||
} catch (e) {
|
||||
log("Caught error in onFormSubmit(", e.lineNumber, "):", e.message);
|
||||
|
@ -144,7 +146,7 @@ var LoginManagerContent = {
|
|||
* WeakMap of the root element of a FormLike to the FormLike representing its fields.
|
||||
*
|
||||
* This is used to be able to lookup an existing FormLike for a given root element since multiple
|
||||
* calls to FormLikeFactory won't give the exact same object. When batching fills we don't always
|
||||
* calls to LoginFormFactory won't give the exact same object. When batching fills we don't always
|
||||
* want to use the most recent list of elements for a FormLike since we may end up doing multiple
|
||||
* fills for the same set of elements when a field gets added between arming and running the
|
||||
* DeferredTask.
|
||||
|
@ -284,7 +286,7 @@ var LoginManagerContent = {
|
|||
_autoCompleteSearchAsync(aSearchString, aPreviousResult,
|
||||
aElement, aRect) {
|
||||
let doc = aElement.ownerDocument;
|
||||
let form = FormLikeFactory.createFromField(aElement);
|
||||
let form = LoginFormFactory.createFromField(aElement);
|
||||
let win = doc.defaultView;
|
||||
|
||||
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
|
||||
|
@ -338,7 +340,7 @@ var LoginManagerContent = {
|
|||
}
|
||||
|
||||
let form = event.target;
|
||||
let formLike = FormLikeFactory.createFromForm(form);
|
||||
let formLike = LoginFormFactory.createFromForm(form);
|
||||
log("onDOMFormHasPassword:", form, formLike);
|
||||
this._fetchLoginsFromParentAndFillForm(formLike, window);
|
||||
},
|
||||
|
@ -358,7 +360,7 @@ var LoginManagerContent = {
|
|||
// Capture within a <form> but without a submit event is bug 1287202.
|
||||
this.setupProgressListener(window);
|
||||
|
||||
let formLike = FormLikeFactory.createFromField(pwField);
|
||||
let formLike = LoginFormFactory.createFromField(pwField);
|
||||
log("onDOMInputPasswordAdded:", pwField, formLike);
|
||||
|
||||
let deferredTask = this._deferredPasswordAddedTasksByRootElement.get(formLike.rootElement);
|
||||
|
@ -508,7 +510,7 @@ var LoginManagerContent = {
|
|||
inputElement,
|
||||
};
|
||||
|
||||
let form = FormLikeFactory.createFromField(inputElement);
|
||||
let form = LoginFormFactory.createFromField(inputElement);
|
||||
if (inputElement.type == "password") {
|
||||
clobberUsername = false;
|
||||
}
|
||||
|
@ -543,7 +545,7 @@ var LoginManagerContent = {
|
|||
if (!LoginHelper.isUsernameFieldType(acInputField))
|
||||
return;
|
||||
|
||||
var acForm = FormLikeFactory.createFromField(acInputField);
|
||||
var acForm = LoginFormFactory.createFromField(acInputField);
|
||||
if (!acForm)
|
||||
return;
|
||||
|
||||
|
@ -649,7 +651,7 @@ var LoginManagerContent = {
|
|||
);
|
||||
if (pwOverrideField) {
|
||||
// The field from the password override may be in a different FormLike.
|
||||
let formLike = FormLikeFactory.createFromField(pwOverrideField);
|
||||
let formLike = LoginFormFactory.createFromField(pwOverrideField);
|
||||
pwFields = [{
|
||||
index : [...formLike.elements].indexOf(pwOverrideField),
|
||||
element : pwOverrideField,
|
||||
|
@ -1134,7 +1136,7 @@ var LoginManagerContent = {
|
|||
!aField.ownerDocument) {
|
||||
return null;
|
||||
}
|
||||
let form = FormLikeFactory.createFromField(aField);
|
||||
let form = LoginFormFactory.createFromField(aField);
|
||||
|
||||
let doc = aField.ownerDocument;
|
||||
let messageManager = messageManagerFromWindow(doc.defaultView);
|
||||
|
@ -1299,35 +1301,17 @@ UserAutoCompleteResult.prototype = {
|
|||
* A factory to generate FormLike objects that represent a set of login fields
|
||||
* which aren't necessarily marked up with a <form> element.
|
||||
*/
|
||||
var FormLikeFactory = {
|
||||
_propsFromForm: [
|
||||
"autocomplete",
|
||||
"ownerDocument",
|
||||
],
|
||||
|
||||
var LoginFormFactory = {
|
||||
/**
|
||||
* Create a FormLike object from a <form>.
|
||||
* Create a LoginForm object from a <form>.
|
||||
*
|
||||
* @param {HTMLFormElement} aForm
|
||||
* @return {FormLike}
|
||||
* @return {LoginForm}
|
||||
* @throws Error if aForm isn't an HTMLFormElement
|
||||
*/
|
||||
createFromForm(aForm) {
|
||||
if (!(aForm instanceof Ci.nsIDOMHTMLFormElement)) {
|
||||
throw new Error("createFromForm: aForm must be a nsIDOMHTMLFormElement");
|
||||
}
|
||||
|
||||
let formLike = {
|
||||
action: LoginUtils._getActionOrigin(aForm),
|
||||
elements: [...aForm.elements],
|
||||
rootElement: aForm,
|
||||
};
|
||||
|
||||
for (let prop of this._propsFromForm) {
|
||||
formLike[prop] = aForm[prop];
|
||||
}
|
||||
|
||||
this._addToJSONProperty(formLike);
|
||||
let formLike = FormLikeFactory.createFromForm(aForm);
|
||||
formLike.action = LoginUtils._getActionOrigin(aForm);
|
||||
|
||||
let state = LoginManagerContent.stateForDocument(formLike.ownerDocument);
|
||||
state.loginFormRootElements.add(formLike.rootElement);
|
||||
|
@ -1338,19 +1322,19 @@ var FormLikeFactory = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Create a FormLike object from a password or username field.
|
||||
* Create a LoginForm object from a password or username field.
|
||||
*
|
||||
* If the field is in a <form>, construct the FormLike from the form.
|
||||
* Otherwise, create a FormLike with a rootElement (wrapper) according to
|
||||
* heuristics. Currently all <input> not in a <form> are one FormLike but this
|
||||
* If the field is in a <form>, construct the LoginForm from the form.
|
||||
* Otherwise, create a LoginForm with a rootElement (wrapper) according to
|
||||
* heuristics. Currently all <input> not in a <form> are one LoginForm but this
|
||||
* shouldn't be relied upon as the heuristics may change to detect multiple
|
||||
* "forms" (e.g. registration and login) on one page with a <form>.
|
||||
*
|
||||
* Note that two FormLikes created from the same field won't return the same FormLike object.
|
||||
* Use the `rootElement` property on the FormLike as a key instead.
|
||||
* Note that two LoginForms created from the same field won't return the same LoginForm object.
|
||||
* Use the `rootElement` property on the LoginForm as a key instead.
|
||||
*
|
||||
* @param {HTMLInputElement} aField - a password or username field in a document
|
||||
* @return {FormLike}
|
||||
* @return {LoginForm}
|
||||
* @throws Error if aField isn't a password or username field in a document
|
||||
*/
|
||||
createFromField(aField) {
|
||||
|
@ -1364,23 +1348,9 @@ var FormLikeFactory = {
|
|||
return this.createFromForm(aField.form);
|
||||
}
|
||||
|
||||
let doc = aField.ownerDocument;
|
||||
log("Created non-form FormLike for rootElement:", doc.documentElement);
|
||||
let elements = [];
|
||||
for (let el of doc.documentElement.querySelectorAll("input")) {
|
||||
if (!el.form) {
|
||||
elements.push(el);
|
||||
}
|
||||
}
|
||||
let formLike = {
|
||||
action: LoginUtils._getPasswordOrigin(doc.baseURI),
|
||||
autocomplete: "on",
|
||||
// Exclude elements inside the rootElement that are already in a <form> as
|
||||
// they will be handled by their own FormLike.
|
||||
elements,
|
||||
ownerDocument: doc,
|
||||
rootElement: doc.documentElement,
|
||||
};
|
||||
let formLike = FormLikeFactory.createFromField(aField);
|
||||
formLike.action = LoginUtils._getPasswordOrigin(aField.ownerDocument.baseURI);
|
||||
log("Created non-form FormLike for rootElement:", aField.ownerDocument.documentElement);
|
||||
|
||||
let state = LoginManagerContent.stateForDocument(formLike.ownerDocument);
|
||||
state.loginFormRootElements.add(formLike.rootElement);
|
||||
|
@ -1389,59 +1359,6 @@ var FormLikeFactory = {
|
|||
|
||||
LoginManagerContent._formLikeByRootElement.set(formLike.rootElement, formLike);
|
||||
|
||||
this._addToJSONProperty(formLike);
|
||||
return formLike;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a `toJSON` property to a FormLike so logging which ends up going
|
||||
* through dump doesn't include usless garbage from DOM objects.
|
||||
*/
|
||||
_addToJSONProperty(aFormLike) {
|
||||
function prettyElementOutput(aElement) {
|
||||
let idText = aElement.id ? "#" + aElement.id : "";
|
||||
let classText = "";
|
||||
for (let className of aElement.classList) {
|
||||
classText += "." + className;
|
||||
}
|
||||
return `<${aElement.nodeName + idText + classText}>`;
|
||||
}
|
||||
|
||||
Object.defineProperty(aFormLike, "toJSON", {
|
||||
value: () => {
|
||||
let cleansed = {};
|
||||
for (let key of Object.keys(aFormLike)) {
|
||||
let value = aFormLike[key];
|
||||
let cleansedValue = value;
|
||||
|
||||
switch (key) {
|
||||
case "elements": {
|
||||
cleansedValue = [];
|
||||
for (let element of value) {
|
||||
cleansedValue.push(prettyElementOutput(element));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ownerDocument": {
|
||||
cleansedValue = {
|
||||
location: {
|
||||
href: value.location.href,
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
case "rootElement": {
|
||||
cleansedValue = prettyElementOutput(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleansed[key] = cleansedValue;
|
||||
}
|
||||
return cleansed;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<body>
|
||||
<script type="application/javascript;version=1.8">
|
||||
const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm");
|
||||
const { LoginManagerContent, FormLikeFactory } = LMCBackstagePass;
|
||||
const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass;
|
||||
|
||||
let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js"));
|
||||
|
||||
|
@ -143,7 +143,7 @@ add_task(function* test() {
|
|||
frameDoc.documentElement.innerHTML = tc.document;
|
||||
let inputForFormLike = frameDoc.querySelectorAll("input")[tc.inputIndexForFormLike];
|
||||
|
||||
let formLike = FormLikeFactory.createFromField(inputForFormLike);
|
||||
let formLike = LoginFormFactory.createFromField(inputForFormLike);
|
||||
|
||||
info("Calling _onFormSubmit with FormLike");
|
||||
let processedPromise = getSubmitMessage();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<body>
|
||||
<script type="application/javascript;version=1.8">
|
||||
const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm");
|
||||
const { LoginManagerContent, FormLikeFactory } = LMCBackstagePass;
|
||||
const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass;
|
||||
|
||||
let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js"));
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<body>
|
||||
<script type="application/javascript;version=1.8">
|
||||
const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm");
|
||||
const { LoginManagerContent, FormLikeFactory } = LMCBackstagePass;
|
||||
const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass;
|
||||
|
||||
SimpleTest.requestFlakyTimeout("Testing that a message doesn't arrive");
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
Cu.importGlobalProperties(["URL"]);
|
||||
|
||||
const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm");
|
||||
const { LoginManagerContent, FormLikeFactory } = LMCBackstagePass;
|
||||
const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass;
|
||||
const TESTCASES = [
|
||||
{
|
||||
description: "1 password field outside of a <form>",
|
||||
|
@ -123,7 +123,7 @@ for (let tc of TESTCASES) {
|
|||
let input = document.querySelector("input");
|
||||
MockDocument.mockOwnerDocumentProperty(input, document, "http://localhost:8080/test/");
|
||||
|
||||
let formLike = FormLikeFactory.createFromField(input);
|
||||
let formLike = LoginFormFactory.createFromField(input);
|
||||
|
||||
let actual = LoginManagerContent._getFormFields(formLike,
|
||||
testcase.skipEmptyFields,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Test for LoginManagerContent._getPasswordFields using FormLikeFactory.
|
||||
* Test for LoginManagerContent._getPasswordFields using LoginFormFactory.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm");
|
||||
const { LoginManagerContent, FormLikeFactory } = LMCBackstagePass;
|
||||
const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass;
|
||||
const TESTCASES = [
|
||||
{
|
||||
description: "Empty document",
|
||||
|
@ -97,7 +97,7 @@ for (let tc of TESTCASES) {
|
|||
|
||||
let mapRootElementToFormLike = new Map();
|
||||
for (let input of document.querySelectorAll("input")) {
|
||||
let formLike = FormLikeFactory.createFromField(input);
|
||||
let formLike = LoginFormFactory.createFromField(input);
|
||||
let existingFormLike = mapRootElementToFormLike.get(formLike.rootElement);
|
||||
if (!existingFormLike) {
|
||||
mapRootElementToFormLike.set(formLike.rootElement, formLike);
|
||||
|
@ -119,7 +119,7 @@ for (let tc of TESTCASES) {
|
|||
testcase.skipEmptyFields);
|
||||
|
||||
if (formLikeFromInput.rootElement instanceof Ci.nsIDOMHTMLFormElement) {
|
||||
let formLikeFromForm = FormLikeFactory.createFromForm(formLikeFromInput.rootElement);
|
||||
let formLikeFromForm = LoginFormFactory.createFromForm(formLikeFromInput.rootElement);
|
||||
do_print("Checking that the FormLike created for the <form> matches" +
|
||||
" the one from a password field");
|
||||
formLikeEqual(formLikeFromInput, formLikeFromForm);
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["FormLikeFactory"];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
||||
|
||||
/**
|
||||
* A factory to generate FormLike objects that represent a set of related fields
|
||||
* which aren't necessarily marked up with a <form> element. FormLike's emulate
|
||||
* the properties of an HTMLFormElement which are relevant to form tasks.
|
||||
*/
|
||||
let FormLikeFactory = {
|
||||
_propsFromForm: [
|
||||
"action",
|
||||
"autocomplete",
|
||||
"ownerDocument",
|
||||
],
|
||||
|
||||
/**
|
||||
* Create a FormLike object from a <form>.
|
||||
*
|
||||
* @param {HTMLFormElement} aForm
|
||||
* @return {FormLike}
|
||||
* @throws Error if aForm isn't an HTMLFormElement
|
||||
*/
|
||||
createFromForm(aForm) {
|
||||
if (!(aForm instanceof Ci.nsIDOMHTMLFormElement)) {
|
||||
throw new Error("createFromForm: aForm must be a nsIDOMHTMLFormElement");
|
||||
}
|
||||
|
||||
let formLike = {
|
||||
elements: [...aForm.elements],
|
||||
rootElement: aForm,
|
||||
};
|
||||
|
||||
for (let prop of this._propsFromForm) {
|
||||
formLike[prop] = aForm[prop];
|
||||
}
|
||||
|
||||
this._addToJSONProperty(formLike);
|
||||
|
||||
return formLike;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a FormLike object from an <input> in a document.
|
||||
*
|
||||
* If the field is in a <form>, construct the FormLike from the form.
|
||||
* Otherwise, create a FormLike with a rootElement (wrapper) according to
|
||||
* heuristics. Currently all <input> not in a <form> are one FormLike but this
|
||||
* shouldn't be relied upon as the heuristics may change to detect multiple
|
||||
* "forms" (e.g. registration and login) on one page with a <form>.
|
||||
*
|
||||
* Note that two FormLikes created from the same field won't return the same FormLike object.
|
||||
* Use the `rootElement` property on the FormLike as a key instead.
|
||||
*
|
||||
* @param {HTMLInputElement} aField - a field in a document
|
||||
* @return {FormLike}
|
||||
* @throws Error if aField isn't a password or username field in a document
|
||||
*/
|
||||
createFromField(aField) {
|
||||
if (!(aField instanceof Ci.nsIDOMHTMLInputElement) ||
|
||||
!aField.ownerDocument) {
|
||||
throw new Error("createFromField requires a field in a document");
|
||||
}
|
||||
|
||||
if (aField.form) {
|
||||
return this.createFromForm(aField.form);
|
||||
}
|
||||
|
||||
let doc = aField.ownerDocument;
|
||||
let elements = [];
|
||||
for (let el of doc.documentElement.querySelectorAll("input")) {
|
||||
if (!el.form) {
|
||||
elements.push(el);
|
||||
}
|
||||
}
|
||||
let formLike = {
|
||||
action: doc.baseURI,
|
||||
autocomplete: "on",
|
||||
// Exclude elements inside the rootElement that are already in a <form> as
|
||||
// they will be handled by their own FormLike.
|
||||
elements,
|
||||
ownerDocument: doc,
|
||||
rootElement: doc.documentElement,
|
||||
};
|
||||
|
||||
this._addToJSONProperty(formLike);
|
||||
return formLike;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a `toJSON` property to a FormLike so logging which ends up going
|
||||
* through dump doesn't include usless garbage from DOM objects.
|
||||
*/
|
||||
_addToJSONProperty(aFormLike) {
|
||||
function prettyElementOutput(aElement) {
|
||||
let idText = aElement.id ? "#" + aElement.id : "";
|
||||
let classText = "";
|
||||
for (let className of aElement.classList) {
|
||||
classText += "." + className;
|
||||
}
|
||||
return `<${aElement.nodeName + idText + classText}>`;
|
||||
}
|
||||
|
||||
Object.defineProperty(aFormLike, "toJSON", {
|
||||
value: () => {
|
||||
let cleansed = {};
|
||||
for (let key of Object.keys(aFormLike)) {
|
||||
let value = aFormLike[key];
|
||||
let cleansedValue = value;
|
||||
|
||||
switch (key) {
|
||||
case "elements": {
|
||||
cleansedValue = [];
|
||||
for (let element of value) {
|
||||
cleansedValue.push(prettyElementOutput(element));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ownerDocument": {
|
||||
cleansedValue = {
|
||||
location: {
|
||||
href: value.location.href,
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
case "rootElement": {
|
||||
cleansedValue = prettyElementOutput(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleansed[key] = cleansedValue;
|
||||
}
|
||||
return cleansed;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
|
@ -43,6 +43,7 @@ EXTRA_JS_MODULES += [
|
|||
'Finder.jsm',
|
||||
'FinderHighlighter.jsm',
|
||||
'FinderIterator.jsm',
|
||||
'FormLikeFactory.jsm',
|
||||
'Geometry.jsm',
|
||||
'GMPInstallManager.jsm',
|
||||
'GMPUtils.jsm',
|
||||
|
|
Загрузка…
Ссылка в новой задаче