Bug 561728 - Port Bug 537289 [Only save form data for fields that aren't the default value] to SeaMonkey. r=Neil, sr=Neil
This commit is contained in:
Родитель
26e845985d
Коммит
e68356739c
|
@ -1462,25 +1462,60 @@ SessionStoreService.prototype = {
|
|||
|
||||
let data = {};
|
||||
do {
|
||||
let nId = node.id;
|
||||
let hasDefaultValue = true;
|
||||
let value;
|
||||
|
||||
// Only generate a limited number of XPath expressions for perf reasons (cf. bug 477564)
|
||||
if (!node.id && ++generatedCount > MAX_GENERATED_XPATHS)
|
||||
if (!nId && generatedCount > MAX_GENERATED_XPATHS)
|
||||
continue;
|
||||
|
||||
let id = node.id ? "#" + node.id : XPathHelper.generate(node);
|
||||
if (node instanceof Components.interfaces.nsIDOMHTMLInputElement) {
|
||||
if (node.type != "file")
|
||||
data[id] = node.type == "checkbox" || node.type == "radio" ? node.checked : node.value;
|
||||
else
|
||||
data[id] = { type: "file", fileList: node.mozGetFileNameArray() };
|
||||
if (node instanceof Components.interfaces.nsIDOMHTMLInputElement ||
|
||||
node instanceof Components.interfaces.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 = node.selectedIndex;
|
||||
}
|
||||
else if (node instanceof Components.interfaces.nsIDOMHTMLTextAreaElement)
|
||||
data[id] = node.value;
|
||||
else if (!node.multiple)
|
||||
data[id] = node.selectedIndex;
|
||||
else {
|
||||
let options = Array.map(node.options, function(aOpt, aIx) aOpt.selected ? aIx : -1);
|
||||
data[id] = options.filter(function(aIx) aIx >= 0);
|
||||
// <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 ? aIx : -1;
|
||||
});
|
||||
value = options.filter(function(aIx) aIx >= 0);
|
||||
}
|
||||
// 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) {
|
||||
data["#" + nId] = value;
|
||||
}
|
||||
else {
|
||||
generatedCount++;
|
||||
data[XPathHelper.generate(node)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
} while ((node = formNodes.iterateNext()));
|
||||
|
||||
return data;
|
||||
|
|
|
@ -50,34 +50,36 @@ function test() {
|
|||
|
||||
let testURL = "chrome://mochikit/content/browser/" +
|
||||
"suite/common/tests/browser/browser_456342_sample.xhtml";
|
||||
let tabbrowser = getBrowser();
|
||||
let tab2 = tabbrowser.addTab("about:");
|
||||
let tab = tabbrowser.addTab(testURL);
|
||||
let browser = tab2.linkedBrowser;
|
||||
browser.addEventListener("load", function(aEvent) {
|
||||
let tab = getBrowser().addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
browser.addEventListener("pageshow", function(aEvent) {
|
||||
browser.removeEventListener("pageshow", arguments.callee, true);
|
||||
let undoItems = JSON.parse(ss.getClosedTabData(window));
|
||||
let savedFormData = undoItems[0].state.entries[0].formdata;
|
||||
|
||||
let countGood = 0, countBad = 0;
|
||||
for each (let value in savedFormData) {
|
||||
if (value == "save me")
|
||||
countGood++;
|
||||
else
|
||||
countBad++;
|
||||
}
|
||||
|
||||
is(countGood, 4, "Saved text for non-standard input fields");
|
||||
is(countBad, 0, "Didn't save text for ignored field types");
|
||||
|
||||
// clean up
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.privacy_level"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
tabbrowser.removeTab(tab2);
|
||||
finish();
|
||||
}, true);
|
||||
tabbrowser.removeTab(tab);
|
||||
|
||||
let expectedValue = "try to save me";
|
||||
// Since bug 537289 we only save non-default values, so we need to set each
|
||||
// form field's value after load.
|
||||
let formEls = aEvent.originalTarget.forms[0].elements;
|
||||
for (let i = 0; i < formEls.length; i++)
|
||||
formEls[i].value = expectedValue;
|
||||
|
||||
getBrowser().removeTab(tab);
|
||||
|
||||
let undoItems = JSON.parse(ss.getClosedTabData(window));
|
||||
let savedFormData = undoItems[0].state.entries[0].formdata;
|
||||
|
||||
let countGood = 0, countBad = 0;
|
||||
for each (let value in savedFormData) {
|
||||
if (value == expectedValue)
|
||||
countGood++;
|
||||
else
|
||||
countBad++;
|
||||
}
|
||||
|
||||
is(countGood, 4, "Saved text for non-standard input fields");
|
||||
is(countBad, 0, "Didn't save text for ignored field types");
|
||||
|
||||
// clean up
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.privacy_level"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
finish();
|
||||
}, true);
|
||||
}
|
||||
|
|
|
@ -5,22 +5,24 @@
|
|||
<head><title>Test for bug 456342</title></head>
|
||||
|
||||
<body>
|
||||
<form>
|
||||
<h3>Non-standard <input>s</h3>
|
||||
<p>Search <input type="search" value="save me" id="searchTerm"/></p>
|
||||
<p>Image Search: <input type="image search" value="save me" /></p>
|
||||
<p>Autocomplete: <input type="autocomplete" value="save me" name="fill-in"/></p>
|
||||
<p>Mistyped: <input type="txet" value="save me" name="mistyped"/></p>
|
||||
<p>Search <input type="search" id="searchTerm"/></p>
|
||||
<p>Image Search: <input type="image search" /></p>
|
||||
<p>Autocomplete: <input type="autocomplete" name="fill-in"/></p>
|
||||
<p>Mistyped: <input type="txet" name="mistyped"/></p>
|
||||
|
||||
<h3>Ignored types</h3>
|
||||
<input type="hidden" value="don't save" name="hideme"/>
|
||||
<input type="HIDDEN" value="don't save" name="hideme2"/>
|
||||
<input type="submit" value="don't save" name="submit"/>
|
||||
<input type="reset" value="don't save" name="reset"/>
|
||||
<input type="image" value="don't save" name="image"/>
|
||||
<input type="button" value="don't save" name="button"/>
|
||||
<input type="password" value="don't save" name="password"/>
|
||||
<input type="PassWord" value="don't save" name="password2"/>
|
||||
<input type="PASSWORD" value="don't save" name="password3"/>
|
||||
<input type="hidden" name="hideme"/>
|
||||
<input type="HIDDEN" name="hideme2"/>
|
||||
<input type="submit" name="submit"/>
|
||||
<input type="reset" name="reset"/>
|
||||
<input type="image" name="image"/>
|
||||
<input type="button" name="button"/>
|
||||
<input type="password" name="password"/>
|
||||
<input type="PassWord" name="password2"/>
|
||||
<input type="PASSWORD" name="password3"/>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
Загрузка…
Ссылка в новой задаче