Bug 1256652 - [webext] Add webNavigation form_submit transitions implementation and test case. r=krizsa
MozReview-Commit-ID: GiMnQpCpHHm
--- a/toolkit/components/extensions/test/mochitest/file_WebNavigation_page1.html
+++ b/toolkit/components/extensions/test/mochitest/file_WebNavigation_page1.html
@@ -1,9 +1,12 @@
<!DOCTYPE HTML>
<html>
<body>
<iframe src="file_WebNavigation_page2.html" width="200" height="200"></iframe>
+<form>
+</form>
+
</body>
</html>
--- a/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html
@@ -163,16 +163,33 @@ add_task(function* webnav_transitions_pr
if (found) {
is(found.details.transitionType, "auto_subframe",
"Got the expected 'auto_subframe' transitionType in the OnCommitted event");
ok(Array.isArray(found.details.transitionQualifiers),
"transitionQualifiers found in the OnCommitted events");
}
+ // transitionType: form_submit
+ received = [];
+ yield loadAndWait(win, "onCompleted", URL, () => {
+ win.document.querySelector("form").submit();
+ });
+
+ found = received.find((data) => (data.event == "onCommitted" && data.url == URL));
+
+ ok(found, "Got the onCommitted event");
+
+ if (found) {
+ is(found.details.transitionType, "form_submit",
+ "Got the expected 'form_submit' transitionType in the OnCommitted event");
+ ok(Array.isArray(found.details.transitionQualifiers),
+ "transitionQualifiers found in the OnCommitted events");
+ }
+
// transitionQualifier: server_redirect
received = [];
yield loadAndWait(win, "onCompleted", REDIRECTED, () => { win.location = REDIRECT; });
found = received.find((data) => (data.event == "onCommitted" && data.url == REDIRECTED));
ok(found, "Got the onCommitted event");
--- a/toolkit/modules/addons/WebNavigationContent.js
+++ b/toolkit/modules/addons/WebNavigationContent.js
@@ -18,16 +18,45 @@ function loadListener(event) {
sendAsyncMessage("Extension:DOMContentLoaded", {windowId, parentWindowId, url});
}
addEventListener("DOMContentLoaded", loadListener);
addMessageListener("Extension:DisableWebNavigation", () => {
removeEventListener("DOMContentLoaded", loadListener);
});
+var FormSubmitListener = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsIFormSubmitObserver,
+ Ci.nsISupportsWeakReference]),
+ init() {
+ this.formSubmitWindows = new WeakSet();
+ Services.obs.addObserver(FormSubmitListener, "earlyformsubmit", false);
+ },
+
+ uninit() {
+ Services.obs.removeObserver(FormSubmitListener, "earlyformsubmit", false);
+ this.formSubmitWindows = new WeakSet();
+ },
+
+ notify: function(form, window, actionURI) {
+ try {
+ this.formSubmitWindows.add(window);
+ } catch (e) {
+ Cu.reportError("Error in FormSubmitListener.notify");
+ }
+ },
+
+ hasAndForget: function(window) {
+ let has = this.formSubmitWindows.has(window);
+ this.formSubmitWindows.delete(window);
+ return has;
+ },
+};
+
var WebProgressListener = {
init: function() {
// This WeakMap (DOMWindow -> nsIURI) keeps track of the pathname and hash
// of the previous location for all the existent docShells.
this.previousURIMap = new WeakMap();
// Populate the above previousURIMap by iterating over the docShells tree.
for (let currentDocShell of WebNavigationFrames.iterateDocShellTree(docShell)) {
@@ -120,31 +149,31 @@ var WebProgressListener = {
status,
stateFlags,
};
sendAsyncMessage("Extension:StateChange", data);
},
sendDocumentChange({webProgress, locationURI, request}) {
- let {loadType} = webProgress;
- let frameTransitionData = this.getFrameTransitionData({loadType, request});
+ let {loadType, DOMWindow} = webProgress;
+ let frameTransitionData = this.getFrameTransitionData({loadType, request, DOMWindow});
let data = {
frameTransitionData,
location: locationURI ? locationURI.spec : "",
windowId: webProgress.DOMWindowID,
parentWindowId: WebNavigationFrames.getParentWindowId(webProgress.DOMWindow),
};
sendAsyncMessage("Extension:DocumentChange", data);
},
sendHistoryChange({webProgress, previousURI, locationURI, request}) {
- let {loadType} = webProgress;
+ let {loadType, DOMWindow} = webProgress;
let isHistoryStateUpdated = false;
let isReferenceFragmentUpdated = false;
let pathChanged = !(previousURI && locationURI.equalsExceptRef(previousURI));
let hashChanged = !(previousURI && previousURI.ref == locationURI.ref);
// When the location changes but the document is the same:
@@ -158,60 +187,67 @@ var WebProgressListener = {
isReferenceFragmentUpdated = true;
} else if (loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE) {
isHistoryStateUpdated = true;
} else if (loadType & Ci.nsIDocShell.LOAD_CMD_HISTORY) {
isHistoryStateUpdated = true;
}
if (isHistoryStateUpdated || isReferenceFragmentUpdated) {
- let frameTransitionData = this.getFrameTransitionData({loadType, request});
+ let frameTransitionData = this.getFrameTransitionData({loadType, request, DOMWindow});
let data = {
frameTransitionData,
isHistoryStateUpdated, isReferenceFragmentUpdated,
location: locationURI ? locationURI.spec : "",
windowId: webProgress.DOMWindowID,
parentWindowId: WebNavigationFrames.getParentWindowId(webProgress.DOMWindow),
};
sendAsyncMessage("Extension:HistoryChange", data);
}
},
- getFrameTransitionData({loadType, request}) {
+ getFrameTransitionData({loadType, request, DOMWindow}) {
let frameTransitionData = {};
if (loadType & Ci.nsIDocShell.LOAD_CMD_HISTORY) {
frameTransitionData.forward_back = true;
}
if (loadType & Ci.nsIDocShell.LOAD_CMD_RELOAD) {
frameTransitionData.reload = true;
}
if (request instanceof Ci.nsIChannel) {
if (request.loadInfo.redirectChain.length) {
frameTransitionData.server_redirect = true;
}
}
+ if (FormSubmitListener.hasAndForget(DOMWindow)) {
+ frameTransitionData.form_submit = true;
+ }
+
+
return frameTransitionData;
},
-
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
};
var disabled = false;
WebProgressListener.init();
+FormSubmitListener.init();
addEventListener("unload", () => {
if (!disabled) {
disabled = true;
WebProgressListener.uninit();
+ FormSubmitListener.uninit();
}
});
addMessageListener("Extension:DisableWebNavigation", () => {
if (!disabled) {
disabled = true;
WebProgressListener.uninit();
+ FormSubmitListener.uninit();
}
});