UNPKG

slimerjs-firefox

Version:

This repo includes slimerjs as well as downloads a local copy of Firefox.

179 lines (152 loc) 6.5 kB
const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://slimerjs/slUtils.jsm"); const IDS = Ci.nsIDocShell; const IWN = Ci.nsIWebNavigation; function makeLoadFlag(type, flags) { return type | (flags << 16);} const LOAD_LINK = makeLoadFlag(IDS.LOAD_CMD_NORMAL, IWN.LOAD_FLAGS_IS_LINK); const LOAD_HISTORY = makeLoadFlag(IDS.LOAD_CMD_HISTORY, IWN.LOAD_FLAGS_NONE); function Navigation() { } Navigation.prototype = { classID : Components.ID("{5a5f9d66-53b5-4541-8225-cae868541bc2}"), classDescription: "Navigation manager for SlimerJS", QueryInterface : XPCOMUtils.generateQI([Ci.nsIContentPolicy]), // short shouldLoad(in unsigned long aContentType, in nsIURI aContentLocation, // in nsIURI aRequestOrigin, in nsISupports aContext, // in ACString aMimeTypeGuess, in nsISupports aExtra, in nsIPrincipal aRequestPrincipal); shouldLoad : function(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { let result = Ci.nsIContentPolicy.ACCEPT; // ignore content that is not a document if (Ci.nsIContentPolicy.TYPE_DOCUMENT != aContentType && Ci.nsIContentPolicy.TYPE_SUBDOCUMENT != aContentType) { return result; } // ignore content that is loaded from chrome, about, resource protocols etc.. if (aContentLocation.scheme != 'http' && aContentLocation.scheme != 'https' && aContentLocation.scheme != 'ftp' && aContentLocation.scheme != 'file' ){ return result; } //------ retrieve the corresponding webpage object let [webpage, navtype] = this._findWebpage(aContext); if (!webpage) return result; // call the navigationRequest callback webpage.navigationRequested(aContentLocation.spec, navtype, !webpage.navigationLocked, (Ci.nsIContentPolicy.TYPE_DOCUMENT == aContentType)); // if the navigation request is blocked, refuse the content if (webpage.navigationLocked) { result = Ci.nsIContentPolicy.REJECT_REQUEST; } return result; }, // short shouldProcess(in unsigned long aContentType, in nsIURI aContentLocation, // in nsIURI aRequestOrigin, in nsISupports aContext, // in ACString aMimeType, in nsISupports aExtra, in nsIPrincipal aRequestPrincipal); shouldProcess : function(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeType, aExtra) { return Ci.nsIContentPolicy.ACCEPT; }, /** * @param mixed aContext it could be * - the element that own the content (<browser>, <iframe>...) * - or the window * - or the document (of the content ?). */ _findWebpage : function(aContext) { // this function mimic NS_CP_GetDocShellFromContext if (!aContext) { return [null, null]; } // in the case where we receive a DOM element: this is can be a xul <browser> // for top window or an html <(i)frame> ... try { let node = aContext.QueryInterface(Ci.nsIDOMElement); let docshell = this._getDocShell(node.contentWindow); if (node.localName != 'browser') { // this is an html frame : retrieve the corresponding browser node = docshell.chromeEventHandler; if (!node) { return [null, null]; } docshell = node.docShell; } let navType = this._getNavType(docshell); return [(node.webpage?node.webpage: null), navType]; } catch(e){} // in the case where we receive a window // FIXME do we receive always a chrome window? try { aContext = aContext.QueryInterface(Ci.nsIDOMWindow); if (aContext instanceof Ci.nsIDOMChromeWindow) { let browser = aContext.document.getElementById('webpage'); if (browser) { let navType = this._getNavType(browser.docShell); return [browser.webpage, navType]; } return [null, null]; } else { return this._getWebpageAndNavType(aContext); } } catch(e){} // in the case where we receive a document let doc; try { doc = aContext.QueryInterface(Ci.nsIDOMDocument); return this._getWebPageAndNavType(doc.defaultView); } catch(e){} return [null, null]; }, _getDocShell : function(contentWindow) { try { return contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(IWN) .QueryInterface(IDS) } catch(e) { return null; } }, _getWebPageAndNavType : function (contentWindow) { let dc = this._getDocShell(contentWindow); if (dc) return [this._getWebPage(dc), this._getNavType(dc)]; return [null, null] }, _getWebPage : function(docshell) { return slUtils.getWebpageFromDocShell(docshell); }, _getNavType : function(docshell) { let navType = "Undefined"; // FIXME it seems that the loadType on the docshell is not updated // at this time, and we have the value of the previous loading. // so the value of navtype is not correct. We should not use it :-/ /*dump("loadType="+docshell.loadType+"\n") if (docshell.loadType & IDS.LOAD_CMD_RELOAD) { navType = "Reload"; } else if (docshell.loadType & IDS.LOAD_CMD_HISTORY ||docshell.loadType & IDS.LOAD_CMD_PUSHSTATE) { navType = "BackOrForward"; } else if (docshell.loadType == LOAD_LINK) { navType = "LinkClicked"; } else if (docshell.loadType & IDS.LOAD_CMD_NORMAL) { navType = "Other" }*/ //FIXME: "FormSubmitted" "FormResubmitted" return navType; } } this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Navigation]);