toolkit/modules/RemoteWebProgress.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2 // This Source Code Form is subject to the terms of the Mozilla Public
     3 // License, v. 2.0. If a copy of the MPL was not distributed with this
     4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 this.EXPORTED_SYMBOLS = ["RemoteWebProgressManager"];
     8 const Ci = Components.interfaces;
     9 const Cc = Components.classes;
    10 const Cu = Components.utils;
    12 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    14 function newURI(spec)
    15 {
    16     return Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
    17                                                     .newURI(spec, null, null);
    18 }
    20 function RemoteWebProgressRequest(spec)
    21 {
    22   this.uri = newURI(spec);
    23 }
    25 RemoteWebProgressRequest.prototype = {
    26   QueryInterface : XPCOMUtils.generateQI([Ci.nsIChannel]),
    28   get URI() { return this.uri.clone(); }
    29 };
    31 function RemoteWebProgress(aManager, aIsTopLevel) {
    32   this._manager = aManager;
    34   this._isLoadingDocument = false;
    35   this._DOMWindow = null;
    36   this._isTopLevel = aIsTopLevel;
    37   this._loadType = 0;
    38 }
    40 RemoteWebProgress.prototype = {
    41   NOTIFY_STATE_REQUEST:  0x00000001,
    42   NOTIFY_STATE_DOCUMENT: 0x00000002,
    43   NOTIFY_STATE_NETWORK:  0x00000004,
    44   NOTIFY_STATE_WINDOW:   0x00000008,
    45   NOTIFY_STATE_ALL:      0x0000000f,
    46   NOTIFY_PROGRESS:       0x00000010,
    47   NOTIFY_STATUS:         0x00000020,
    48   NOTIFY_SECURITY:       0x00000040,
    49   NOTIFY_LOCATION:       0x00000080,
    50   NOTIFY_REFRESH:        0x00000100,
    51   NOTIFY_ALL:            0x000001ff,
    53   get isLoadingDocument() { return this._isLoadingDocument },
    54   get DOMWindow() { return this._DOMWindow; },
    55   get DOMWindowID() { return 0; },
    56   get isTopLevel() { return this._isTopLevel },
    57   get loadType() { return this._loadType; },
    59   addProgressListener: function (aListener) {
    60     this._manager.addProgressListener(aListener);
    61   },
    63   removeProgressListener: function (aListener) {
    64     this._manager.removeProgressListener(aListener);
    65   }
    66 };
    68 function RemoteWebProgressManager (aBrowser) {
    69   this._browser = aBrowser;
    70   this._topLevelWebProgress = new RemoteWebProgress(this, true);
    71   this._progressListeners = [];
    73   this._browser.messageManager.addMessageListener("Content:StateChange", this);
    74   this._browser.messageManager.addMessageListener("Content:LocationChange", this);
    75   this._browser.messageManager.addMessageListener("Content:SecurityChange", this);
    76   this._browser.messageManager.addMessageListener("Content:StatusChange", this);
    77 }
    79 RemoteWebProgressManager.prototype = {
    80   get topLevelWebProgress() {
    81     return this._topLevelWebProgress;
    82   },
    84   addProgressListener: function (aListener) {
    85     let listener = aListener.QueryInterface(Ci.nsIWebProgressListener);
    86     this._progressListeners.push(listener);
    87   },
    89   removeProgressListener: function (aListener) {
    90     this._progressListeners =
    91       this._progressListeners.filter(l => l != aListener);
    92   },
    94   _fixSSLStatusAndState: function (aStatus, aState) {
    95     let deserialized = null;
    96     if (aStatus) {
    97       let helper = Cc["@mozilla.org/network/serialization-helper;1"]
    98                     .getService(Components.interfaces.nsISerializationHelper);
   100       deserialized = helper.deserializeObject(aStatus)
   101       deserialized.QueryInterface(Ci.nsISSLStatus);
   102     }
   104     // We must check the Extended Validation (EV) state here, on the chrome
   105     // process, because NSS is needed for that determination.
   106     if (deserialized && deserialized.isExtendedValidation)
   107       aState |= Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
   109     return [deserialized, aState];
   110   },
   112   setCurrentURI: function (aURI) {
   113     // This function is simpler than nsDocShell::SetCurrentURI since
   114     // it doesn't have to deal with child docshells.
   115     let webNavigation = this._browser.webNavigation;
   116     webNavigation._currentURI = aURI;
   118     let webProgress = this.topLevelWebProgress;
   119     for (let p of this._progressListeners) {
   120       p.onLocationChange(webProgress, null, aURI);
   121     }
   122   },
   124   _callProgressListeners: function(methodName, ...args) {
   125     for (let p of this._progressListeners) {
   126       if (p[methodName]) {
   127         try {
   128           p[methodName].apply(p, args);
   129         } catch (ex) {
   130           Cu.reportError("RemoteWebProgress failed to call " + methodName + ": " + ex + "\n");
   131         }
   132       }
   133     }
   134   },
   136   receiveMessage: function (aMessage) {
   137     let json = aMessage.json;
   138     let objects = aMessage.objects;
   140     // The top-level WebProgress is always the same, but because we don't
   141     // really have a concept of subframes/content we always creat a new object
   142     // for those.
   143     let webProgress = json.isTopLevel ? this._topLevelWebProgress
   144                                       : new RemoteWebProgress(this, false);
   146     // The WebProgressRequest object however is always dynamic.
   147     let request = json.requestURI ? new RemoteWebProgressRequest(json.requestURI)
   148                                   : null;
   150     // Update the actual WebProgress fields.
   151     webProgress._isLoadingDocument = json.isLoadingDocument;
   152     webProgress._DOMWindow = objects.DOMWindow;
   153     webProgress._loadType = json.loadType;
   155     if (json.isTopLevel) {
   156       this._browser._contentWindow = objects.contentWindow;
   157       this._browser._documentContentType = json.documentContentType;
   158     }
   160     switch (aMessage.name) {
   161     case "Content:StateChange":
   162       this._callProgressListeners("onStateChange", webProgress, request, json.stateFlags, json.status);
   163       break;
   165     case "Content:LocationChange":
   166       let location = newURI(json.location);
   167       let flags = json.flags;
   169       if (json.isTopLevel) {
   170         this._browser.webNavigation._currentURI = location;
   171         this._browser.webNavigation.canGoBack = json.canGoBack;
   172         this._browser.webNavigation.canGoForward = json.canGoForward;
   173         this._browser._characterSet = json.charset;
   174         this._browser._documentURI = newURI(json.documentURI);
   175         this._browser._imageDocument = null;
   176       }
   178       this._callProgressListeners("onLocationChange", webProgress, request, location, flags);
   179       break;
   181     case "Content:SecurityChange":
   182       let [status, state] = this._fixSSLStatusAndState(json.status, json.state);
   184       if (json.isTopLevel) {
   185         // Invoking this getter triggers the generation of the underlying object,
   186         // which we need to access with ._securityUI, because .securityUI returns
   187         // a wrapper that makes _update inaccessible.
   188         void this._browser.securityUI;
   189         this._browser._securityUI._update(status, state);
   190       }
   192       this._callProgressListeners("onSecurityChange", webProgress, request, state);
   193       break;
   195     case "Content:StatusChange":
   196       this._callProgressListeners("onStatusChange", webProgress, request, json.status, json.message);
   197       break;
   198     }
   199   }
   200 };

mercurial