mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 00:08:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
272
toolkit/modules/addons/WebNavigationContent.js
Normal file
272
toolkit/modules/addons/WebNavigationContent.js
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
"use strict";
|
||||
|
||||
/* globals docShell */
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebNavigationFrames",
|
||||
"resource://gre/modules/WebNavigationFrames.jsm");
|
||||
|
||||
function loadListener(event) {
|
||||
let document = event.target;
|
||||
let window = document.defaultView;
|
||||
let url = document.documentURI;
|
||||
let windowId = WebNavigationFrames.getWindowId(window);
|
||||
let parentWindowId = WebNavigationFrames.getParentWindowId(window);
|
||||
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)) {
|
||||
let win = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
let {currentURI} = currentDocShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
|
||||
this.previousURIMap.set(win, currentURI);
|
||||
}
|
||||
|
||||
// This WeakSet of DOMWindows keeps track of the attempted refresh.
|
||||
this.refreshAttemptedDOMWindows = new WeakSet();
|
||||
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW |
|
||||
Ci.nsIWebProgress.NOTIFY_REFRESH |
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION);
|
||||
},
|
||||
|
||||
uninit() {
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(this);
|
||||
},
|
||||
|
||||
onRefreshAttempted: function onRefreshAttempted(webProgress, URI, delay, sameURI) {
|
||||
this.refreshAttemptedDOMWindows.add(webProgress.DOMWindow);
|
||||
|
||||
// If this function doesn't return true, the attempted refresh will be blocked.
|
||||
return true;
|
||||
},
|
||||
|
||||
onStateChange: function onStateChange(webProgress, request, stateFlags, status) {
|
||||
let {originalURI, URI: locationURI} = request.QueryInterface(Ci.nsIChannel);
|
||||
|
||||
// Prevents "about", "chrome", "resource" and "moz-extension" URI schemes to be
|
||||
// reported with the resolved "file" or "jar" URIs. (see Bug 1246125 for rationale)
|
||||
if (locationURI.schemeIs("file") || locationURI.schemeIs("jar")) {
|
||||
let shouldUseOriginalURI = originalURI.schemeIs("about") ||
|
||||
originalURI.schemeIs("chrome") ||
|
||||
originalURI.schemeIs("resource") ||
|
||||
originalURI.schemeIs("moz-extension");
|
||||
|
||||
locationURI = shouldUseOriginalURI ? originalURI : locationURI;
|
||||
}
|
||||
|
||||
this.sendStateChange({webProgress, locationURI, stateFlags, status});
|
||||
|
||||
// Based on the docs of the webNavigation.onCommitted event, it should be raised when:
|
||||
// "The document might still be downloading, but at least part of
|
||||
// the document has been received"
|
||||
// and for some reason we don't fire onLocationChange for the
|
||||
// initial navigation of a sub-frame.
|
||||
// For the above two reasons, when the navigation event is related to
|
||||
// a sub-frame we process the document change here and
|
||||
// then send an "Extension:DocumentChange" message to the main process,
|
||||
// where it will be turned into a webNavigation.onCommitted event.
|
||||
// (see Bug 1264936 and Bug 125662 for rationale)
|
||||
if ((webProgress.DOMWindow.top != webProgress.DOMWindow) &&
|
||||
(stateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT)) {
|
||||
this.sendDocumentChange({webProgress, locationURI, request});
|
||||
}
|
||||
},
|
||||
|
||||
onLocationChange: function onLocationChange(webProgress, request, locationURI, flags) {
|
||||
let {DOMWindow} = webProgress;
|
||||
|
||||
// Get the previous URI loaded in the DOMWindow.
|
||||
let previousURI = this.previousURIMap.get(DOMWindow);
|
||||
|
||||
// Update the URI in the map with the new locationURI.
|
||||
this.previousURIMap.set(DOMWindow, locationURI);
|
||||
|
||||
let isSameDocument = (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT);
|
||||
|
||||
// When a frame navigation doesn't change the current loaded document
|
||||
// (which can be due to history.pushState/replaceState or to a changed hash in the url),
|
||||
// it is reported only to the onLocationChange, for this reason
|
||||
// we process the history change here and then we are going to send
|
||||
// an "Extension:HistoryChange" to the main process, where it will be turned
|
||||
// into a webNavigation.onHistoryStateUpdated/onReferenceFragmentUpdated event.
|
||||
if (isSameDocument) {
|
||||
this.sendHistoryChange({webProgress, previousURI, locationURI, request});
|
||||
} else if (webProgress.DOMWindow.top == webProgress.DOMWindow) {
|
||||
// We have to catch the document changes from top level frames here,
|
||||
// where we can detect the "server redirect" transition.
|
||||
// (see Bug 1264936 and Bug 125662 for rationale)
|
||||
this.sendDocumentChange({webProgress, locationURI, request});
|
||||
}
|
||||
},
|
||||
|
||||
sendStateChange({webProgress, locationURI, stateFlags, status}) {
|
||||
let data = {
|
||||
requestURL: locationURI.spec,
|
||||
windowId: webProgress.DOMWindowID,
|
||||
parentWindowId: WebNavigationFrames.getParentWindowId(webProgress.DOMWindow),
|
||||
status,
|
||||
stateFlags,
|
||||
};
|
||||
|
||||
sendAsyncMessage("Extension:StateChange", data);
|
||||
},
|
||||
|
||||
sendDocumentChange({webProgress, locationURI, 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, 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:
|
||||
// - path not changed and hash changed -> |onReferenceFragmentUpdated|
|
||||
// (even if it changed using |history.pushState|)
|
||||
// - path not changed and hash not changed -> |onHistoryStateUpdated|
|
||||
// (only if it changes using |history.pushState|)
|
||||
// - path changed -> |onHistoryStateUpdated|
|
||||
|
||||
if (!pathChanged && hashChanged) {
|
||||
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, 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, 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;
|
||||
}
|
||||
|
||||
if (this.refreshAttemptedDOMWindows.has(DOMWindow)) {
|
||||
this.refreshAttemptedDOMWindows.delete(DOMWindow);
|
||||
frameTransitionData.client_redirect = true;
|
||||
}
|
||||
|
||||
return frameTransitionData;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIWebProgressListener,
|
||||
Ci.nsIWebProgressListener2,
|
||||
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();
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue