Bug 640136 - onchange & input events are not fired for all form elements on restore [r=dietrich]

--HG--
rename : browser/components/sessionstore/test/browser/browser_476161.js => browser/components/sessionstore/test/browser/browser_form_restore_events.js
rename : browser/components/sessionstore/test/browser/browser_476161_sample.html => browser/components/sessionstore/test/browser/browser_form_restore_events_sample.html
This commit is contained in:
Paul O’Shannessy 2011-11-08 15:23:42 -08:00
parent a2b8d791ce
commit adc68fc9f4
5 changed files with 175 additions and 48 deletions

View File

@ -3327,31 +3327,53 @@ SessionStoreService.prototype = {
if (!node)
continue;
let eventType;
let value = aData[key];
if (typeof value == "string" && node.type != "file") {
if (node.value == value)
continue; // don't dispatch an input event for no change
node.value = value;
let event = aDocument.createEvent("UIEvents");
event.initUIEvent("input", true, true, aDocument.defaultView, 0);
node.dispatchEvent(event);
eventType = "input";
}
else if (typeof value == "boolean")
else if (typeof value == "boolean") {
if (node.checked == value)
continue; // don't dispatch a change event for no change
node.checked = value;
else if (typeof value == "number")
eventType = "change";
}
else if (typeof value == "number") {
// We saved the value blindly since selects take more work to determine
// default values. So now we should check to avoid unnecessary events.
if (node.selectedIndex == value)
continue;
try {
node.selectedIndex = value;
eventType = "change";
} catch (ex) { /* throws for invalid indices */ }
else if (value && value.fileList && value.type == "file" && node.type == "file")
}
else if (value && value.fileList && value.type == "file" && node.type == "file") {
node.mozSetFileNameArray(value.fileList, value.fileList.length);
eventType = "input";
}
else if (value && typeof value.indexOf == "function" && node.options) {
Array.forEach(node.options, function(aOpt, aIx) {
aOpt.selected = value.indexOf(aIx) > -1;
// Only fire the event here if this wasn't selected by default
if (!aOpt.defaultSelected)
eventType = "change";
});
}
// NB: dispatching "change" events might have unintended side-effects
// Fire events for this node if applicable
if (eventType) {
let event = aDocument.createEvent("UIEvents");
event.initUIEvent(eventType, true, true, aDocument.defaultView, 0);
node.dispatchEvent(event);
}
}
}

View File

@ -50,6 +50,8 @@ include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = \
head.js \
browser_form_restore_events.js \
browser_form_restore_events_sample.html \
browser_248970_a.js \
browser_248970_b.js \
browser_248970_b_sample.html \
@ -98,8 +100,6 @@ _BROWSER_TEST_FILES = \
browser_465223.js \
browser_466937.js \
browser_466937_sample.html \
browser_476161.js \
browser_476161_sample.html \
browser_477657.js \
browser_480148.js \
browser_480893.js \

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<title>Test for bug 476161</title>
<script>
document.addEventListener("input", function(aEvent) {
var inputEl = aEvent.originalTarget;
var changedEl = document.getElementById("changed");
changedEl.textContent += " " + inputEl.id;
}, false);
</script>
<h3>Text fields with changed text</h3>
<input type="text" id="modify1">
<input type="text" id="modify2" value="preset value">
<h3>Text fields with unchanged text</h3>
<input type="text" id="unchanged1">
<input type="text" id="unchanged2" value="preset value">
<h3>Changed field IDs</h3>
<div id="changed"></div>

View File

@ -35,33 +35,64 @@
* ***** END LICENSE BLOCK ***** */
function test() {
/** Test for Bug 476161 **/
/** Originally a test for Bug 476161, but then expanded to include all input types in bug 640136 **/
waitForExplicitFinish();
let file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
let testURL = "http://mochi.test:8888/browser/" +
"browser/components/sessionstore/test/browser/browser_476161_sample.html";
"browser/components/sessionstore/test/browser/browser_form_restore_events_sample.html";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
doc.getElementById("modify1").value += Math.random();
doc.getElementById("modify2").value += " " + Date.now();
// text fields
doc.getElementById("modify01").value += Math.random();
doc.getElementById("modify02").value += " " + Date.now();
// textareas
doc.getElementById("modify03").value += Math.random();
doc.getElementById("modify04").value += " " + Date.now();
// file
doc.getElementById("modify05").value = file.path;
// select
doc.getElementById("modify06").selectedIndex = 1;
var multipleChange = doc.getElementById("modify07");
Array.forEach(multipleChange.options, function(option) option.selected = true);
// checkbox
doc.getElementById("modify08").checked = true;
doc.getElementById("modify09").checked = false;
// radio
// select one then another in the same group - only last one should get event on restore
doc.getElementById("modify10").checked = true;
doc.getElementById("modify11").checked = true;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
tab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
let doc = tab2.linkedBrowser.contentDocument;
let changed = doc.getElementById("changed").textContent.trim().split();
is(changed.sort().join(" "), "modify1 modify2",
"input events were only dispatched for modified text fields");
let inputFired = doc.getElementById("inputFired").textContent.trim().split();
let changeFired = doc.getElementById("changeFired").textContent.trim().split();
is(inputFired.sort().join(" "), "modify01 modify02 modify03 modify04 modify05",
"input events were only dispatched for modified input, textarea fields");
is(changeFired.sort().join(" "), "modify06 modify07 modify08 modify09 modify11",
"change events were only dispatched for modified select, checkbox, radio fields");
// clean up
gBrowser.removeTab(tab2);
gBrowser.removeTab(tab);
finish();
}, true);
}, true);

View File

@ -0,0 +1,98 @@
<!DOCTYPE html>
<title>Test for form restore events (originally bug 476161)</title>
<script>
document.addEventListener("input", function(aEvent) {
var inputEl = aEvent.originalTarget;
var changedEl = document.getElementById("inputFired");
changedEl.textContent += " " + inputEl.id;
}, false);
document.addEventListener("change", function(aEvent) {
var inputEl = aEvent.originalTarget;
var changedEl = document.getElementById("changeFired");
changedEl.textContent += " " + inputEl.id;
}, false);
</script>
<!-- input events -->
<h3>Text fields with changed text</h3>
<input type="text" id="modify1">
<input type="text" id="modify2" value="preset value">
<input type="text" id="modify01">
<input type="text" id="modify02" value="preset value">
<h3>Text fields with unchanged text</h3>
<input type="text" id="unchanged1">
<input type="text" id="unchanged2" value="preset value">
<input type="text" id="unchanged01">
<input type="text" id="unchanged02" value="preset value">
<h3>Textarea with changed text</h3>
<textarea id="modify03"></textarea>
<textarea id="modify04">preset value</textarea>
<h3>Textarea with unchanged text</h3>
<textarea id="unchanged03"></textarea>
<textarea id="unchanged04">preset value</textarea>
<h3>file field with changed value</h3>
<input type="file" id="modify05">
<h3>file field with unchanged value</h3>
<input type="file" id="unchanged05">
<!-- change events -->
<h3>Select menu with changed selection</h3>
<select id="modify06">
<option value="one">one</option>
<option value="two">two</option>
<option value="three">three</option>
</select>
<h3>Select menu with unchanged selection (change event still fires)</h3>
<select id="unchanged06">
<option value="one">one</option>
<option value="two" selected>two</option>
<option value="three">three</option>
</select>
<h3>Multiple Select menu with changed selection</h3>
<select id="modify07" multiple>
<option value="one">one</option>
<option value="two" selected>two</option>
<option value="three">three</option>
</select>
<h3>Select menu with unchanged selection</h3>
<select id="unchanged07" multiple>
<option value="one">one</option>
<option value="two" selected>two</option>
<option value="three" selected>three</option>
</select>
<h3>checkbox with changed value</h3>
<input type="checkbox" id="modify08">
<input type="checkbox" id="modify09" checked>
<h3>checkbox with unchanged value</h3>
<input type="checkbox" id="unchanged08">
<input type="checkbox" id="unchanged09" checked>
<h3>radio with changed value</h3>
<input type="radio" id="modify10" name="group">Radio 1</input>
<input type="radio" id="modify11" name="group">Radio 2</input>
<input type="radio" id="modify12" name="group" checked>Radio 3</input>
<h3>radio with unchanged value</h3>
<input type="radio" id="unchanged10" name="group2">Radio 4</input>
<input type="radio" id="unchanged11" name="group2">Radio 5</input>
<input type="radio" id="unchanged12" name="group2" checked>Radio 6</input>
<h3>Changed field IDs</h3>
<div id="changed"></div>
<div id="inputFired"></div>
<div id="changeFired"></div>