toolkit/content/browser-child.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 let Cc = Components.classes;
     6 let Ci = Components.interfaces;
     7 let Cu = Components.utils;
     9 Cu.import("resource://gre/modules/Services.jsm");
    10 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
    11 Cu.import("resource://gre/modules/RemoteAddonsChild.jsm");
    12 Cu.import("resource://gre/modules/Timer.jsm");
    14 let SyncHandler = {
    15   init: function() {
    16     sendAsyncMessage("SetSyncHandler", {}, {handler: this});
    17   },
    19   getFocusedElementAndWindow: function() {
    20     let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
    22     let focusedWindow = {};
    23     let elt = fm.getFocusedElementForWindow(content, true, focusedWindow);
    24     return [elt, focusedWindow.value];
    25   },
    26 };
    28 SyncHandler.init();
    30 let WebProgressListener = {
    31   init: function() {
    32     let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
    33                               .getInterface(Ci.nsIWebProgress);
    34     webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL);
    35   },
    37   _requestSpec: function (aRequest) {
    38     if (!aRequest || !(aRequest instanceof Ci.nsIChannel))
    39       return null;
    40     return aRequest.QueryInterface(Ci.nsIChannel).URI.spec;
    41   },
    43   _setupJSON: function setupJSON(aWebProgress, aRequest) {
    44     return {
    45       isTopLevel: aWebProgress.isTopLevel,
    46       isLoadingDocument: aWebProgress.isLoadingDocument,
    47       requestURI: this._requestSpec(aRequest),
    48       loadType: aWebProgress.loadType,
    49       documentContentType: content.document && content.document.contentType
    50     };
    51   },
    53   _setupObjects: function setupObjects(aWebProgress) {
    54     return {
    55       contentWindow: content,
    56       // DOMWindow is not necessarily the content-window with subframes.
    57       DOMWindow: aWebProgress.DOMWindow
    58     };
    59   },
    61   onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
    62     let json = this._setupJSON(aWebProgress, aRequest);
    63     let objects = this._setupObjects(aWebProgress);
    65     json.stateFlags = aStateFlags;
    66     json.status = aStatus;
    68     sendAsyncMessage("Content:StateChange", json, objects);
    69   },
    71   onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
    72   },
    74   onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
    75     let json = this._setupJSON(aWebProgress, aRequest);
    76     let objects = this._setupObjects(aWebProgress);
    78     json.location = aLocationURI ? aLocationURI.spec : "";
    79     json.flags = aFlags;
    81     if (json.isTopLevel) {
    82       json.canGoBack = docShell.canGoBack;
    83       json.canGoForward = docShell.canGoForward;
    84       json.documentURI = content.document.documentURIObject.spec;
    85       json.charset = content.document.characterSet;
    86     }
    88     sendAsyncMessage("Content:LocationChange", json, objects);
    89   },
    91   onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
    92     let json = this._setupJSON(aWebProgress, aRequest);
    93     let objects = this._setupObjects(aWebProgress);
    95     json.status = aStatus;
    96     json.message = aMessage;
    98     sendAsyncMessage("Content:StatusChange", json, objects);
    99   },
   101   onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) {
   102     let json = this._setupJSON(aWebProgress, aRequest);
   103     let objects = this._setupObjects(aWebProgress);
   105     json.state = aState;
   106     json.status = SecurityUI.getSSLStatusAsString();
   108     sendAsyncMessage("Content:SecurityChange", json, objects);
   109   },
   111   QueryInterface: function QueryInterface(aIID) {
   112     if (aIID.equals(Ci.nsIWebProgressListener) ||
   113         aIID.equals(Ci.nsISupportsWeakReference) ||
   114         aIID.equals(Ci.nsISupports)) {
   115         return this;
   116     }
   118     throw Components.results.NS_ERROR_NO_INTERFACE;
   119   }
   120 };
   122 WebProgressListener.init();
   124 let WebNavigation =  {
   125   _webNavigation: docShell.QueryInterface(Ci.nsIWebNavigation),
   127   init: function() {
   128     addMessageListener("WebNavigation:GoBack", this);
   129     addMessageListener("WebNavigation:GoForward", this);
   130     addMessageListener("WebNavigation:GotoIndex", this);
   131     addMessageListener("WebNavigation:LoadURI", this);
   132     addMessageListener("WebNavigation:Reload", this);
   133     addMessageListener("WebNavigation:Stop", this);
   135     // Send a CPOW for the sessionHistory object.
   136     let history = this._webNavigation.sessionHistory;
   137     sendAsyncMessage("WebNavigation:setHistory", {}, {history: history});
   138   },
   140   receiveMessage: function(message) {
   141     switch (message.name) {
   142       case "WebNavigation:GoBack":
   143         this.goBack();
   144         break;
   145       case "WebNavigation:GoForward":
   146         this.goForward();
   147         break;
   148       case "WebNavigation:GotoIndex":
   149         this.gotoIndex(message.data.index);
   150         break;
   151       case "WebNavigation:LoadURI":
   152         this.loadURI(message.data.uri, message.data.flags);
   153         break;
   154       case "WebNavigation:Reload":
   155         this.reload(message.data.flags);
   156         break;
   157       case "WebNavigation:Stop":
   158         this.stop(message.data.flags);
   159         break;
   160     }
   161   },
   163   goBack: function() {
   164     if (this._webNavigation.canGoBack)
   165       this._webNavigation.goBack();
   166   },
   168   goForward: function() {
   169     if (this._webNavigation.canGoForward)
   170       this._webNavigation.goForward();
   171   },
   173   gotoIndex: function(index) {
   174     this._webNavigation.gotoIndex(index);
   175   },
   177   loadURI: function(uri, flags) {
   178     this._webNavigation.loadURI(uri, flags, null, null, null);
   179   },
   181   reload: function(flags) {
   182     this._webNavigation.reload(flags);
   183   },
   185   stop: function(flags) {
   186     this._webNavigation.stop(flags);
   187   }
   188 };
   190 WebNavigation.init();
   192 let SecurityUI = {
   193   getSSLStatusAsString: function() {
   194     let status = docShell.securityUI.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
   196     if (status) {
   197       let helper = Cc["@mozilla.org/network/serialization-helper;1"]
   198                       .getService(Ci.nsISerializationHelper);
   200       status.QueryInterface(Ci.nsISerializable);
   201       return helper.serializeToString(status);
   202     }
   204     return null;
   205   }
   206 };
   208 let ControllerCommands = {
   209   init: function () {
   210     addMessageListener("ControllerCommands:Do", this);
   211   },
   213   receiveMessage: function(message) {
   214     switch(message.name) {
   215       case "ControllerCommands:Do":
   216         if (docShell.isCommandEnabled(message.data))
   217           docShell.doCommand(message.data);
   218         break;
   219     }
   220   }
   221 }
   223 ControllerCommands.init()
   225 addEventListener("DOMTitleChanged", function (aEvent) {
   226   let document = content.document;
   227   switch (aEvent.type) {
   228   case "DOMTitleChanged":
   229     if (!aEvent.isTrusted || aEvent.target.defaultView != content)
   230       return;
   232     sendAsyncMessage("DOMTitleChanged", { title: document.title });
   233     break;
   234   }
   235 }, false);
   237 addEventListener("DOMWindowClose", function (aEvent) {
   238   if (!aEvent.isTrusted)
   239     return;
   240   sendAsyncMessage("DOMWindowClose");
   241   aEvent.preventDefault();
   242 }, false);
   244 addEventListener("ImageContentLoaded", function (aEvent) {
   245   if (content.document instanceof Ci.nsIImageDocument) {
   246     let req = content.document.imageRequest;
   247     if (!req.image)
   248       return;
   249     sendAsyncMessage("ImageDocumentLoaded", { width: req.image.width,
   250                                               height: req.image.height });
   251   }
   252 }, false);
   254 let DocumentObserver = {
   255   init: function() {
   256     Services.obs.addObserver(this, "document-element-inserted", false);
   257     addEventListener("unload", () => {
   258       Services.obs.removeObserver(this, "document-element-inserted");
   259     });
   260   },
   262   observe: function(aSubject, aTopic, aData) {
   263     if (aSubject == content.document) {
   264       sendAsyncMessage("DocumentInserted", {synthetic: aSubject.mozSyntheticDocument});
   265     }
   266   },
   267 };
   268 DocumentObserver.init();
   270 const ZoomManager = {
   271   get fullZoom() {
   272     return this._cache.fullZoom;
   273   },
   275   get textZoom() {
   276     return this._cache.textZoom;
   277   },
   279   set fullZoom(value) {
   280     this._cache.fullZoom = value;
   281     this._markupViewer.fullZoom = value;
   282   },
   284   set textZoom(value) {
   285     this._cache.textZoom = value;
   286     this._markupViewer.textZoom = value;
   287   },
   289   refreshFullZoom: function() {
   290     return this._refreshZoomValue('fullZoom');
   291   },
   293   refreshTextZoom: function() {
   294     return this._refreshZoomValue('textZoom');
   295   },
   297   /**
   298    * Retrieves specified zoom property value from markupViewer and refreshes
   299    * cache if needed.
   300    * @param valueName Either 'fullZoom' or 'textZoom'.
   301    * @returns Returns true if cached value was actually refreshed.
   302    * @private
   303    */
   304   _refreshZoomValue: function(valueName) {
   305     let actualZoomValue = this._markupViewer[valueName];
   306     if (actualZoomValue != this._cache[valueName]) {
   307       this._cache[valueName] = actualZoomValue;
   308       return true;
   309     }
   310     return false;
   311   },
   313   get _markupViewer() {
   314     return docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
   315   },
   317   _cache: {
   318     fullZoom: NaN,
   319     textZoom: NaN
   320   }
   321 };
   323 addMessageListener("FullZoom", function (aMessage) {
   324   ZoomManager.fullZoom = aMessage.data.value;
   325 });
   327 addMessageListener("TextZoom", function (aMessage) {
   328   ZoomManager.textZoom = aMessage.data.value;
   329 });
   331 addEventListener("FullZoomChange", function () {
   332   if (ZoomManager.refreshFullZoom()) {
   333     sendAsyncMessage("FullZoomChange", { value:  ZoomManager.fullZoom});
   334   }
   335 }, false);
   337 addEventListener("TextZoomChange", function (aEvent) {
   338   if (ZoomManager.refreshTextZoom()) {
   339     sendAsyncMessage("TextZoomChange", { value:  ZoomManager.textZoom});
   340   }
   341 }, false);
   343 RemoteAddonsChild.init(this);
   345 addMessageListener("NetworkPrioritizer:AdjustPriority", (msg) => {
   346   let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
   347   let loadGroup = webNav.QueryInterface(Ci.nsIDocumentLoader)
   348                         .loadGroup.QueryInterface(Ci.nsISupportsPriority);
   349   loadGroup.adjustPriority(msg.data.adjustment);
   350 });
   352 let AutoCompletePopup = {
   353   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
   355   init: function() {
   356     // Hook up the form fill autocomplete controller.
   357     let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
   358                        .getService(Ci.nsIFormFillController);
   360     controller.attachToBrowser(docShell, this.QueryInterface(Ci.nsIAutoCompletePopup));
   362     this._input = null;
   363     this._popupOpen = false;
   365     addMessageListener("FormAutoComplete:HandleEnter", message => {
   366       this.selectedIndex = message.data.selectedIndex;
   368       let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
   369                   getService(Components.interfaces.nsIAutoCompleteController);
   370       controller.handleEnter(message.data.isPopupSelection);
   371     });
   372   },
   374   get input () { return this._input; },
   375   get overrideValue () { return null; },
   376   set selectedIndex (index) { },
   377   get selectedIndex () {
   378     // selectedIndex getter must be synchronous because we need the
   379     // correct value when the controller is in controller::HandleEnter.
   380     // We can't easily just let the parent inform us the new value every
   381     // time it changes because not every action that can change the
   382     // selectedIndex is trivial to catch (e.g. moving the mouse over the
   383     // list).
   384     return sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
   385   },
   386   get popupOpen () {
   387     return this._popupOpen;
   388   },
   390   openAutocompletePopup: function (input, element) {
   391     this._input = input;
   392     this._popupOpen = true;
   393   },
   395   closePopup: function () {
   396     this._popupOpen = false;
   397     sendAsyncMessage("FormAutoComplete:ClosePopup", {});
   398   },
   400   invalidate: function () {
   401   },
   403   selectBy: function(reverse, page) {
   404     this._index = sendSyncMessage("FormAutoComplete:SelectBy", {
   405       reverse: reverse,
   406       page: page
   407     });
   408   }
   409 }
   411 let [initData] = sendSyncMessage("Browser:Init");
   412 docShell.useGlobalHistory = initData.useGlobalHistory;
   413 if (initData.initPopup) {
   414   setTimeout(function() AutoCompletePopup.init(), 0);
   415 }

mercurial