browser/devtools/shared/FloatingScrollbars.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 "use strict";
     7 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
     9 this.EXPORTED_SYMBOLS = [ "switchToFloatingScrollbars", "switchToNativeScrollbars" ];
    11 Cu.import("resource://gre/modules/Services.jsm");
    13 let URL = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars.css", null, null);
    15 let trackedTabs = new WeakMap();
    17 /**
    18  * Switch to floating scrollbars, à la mobile.
    19  *
    20  * @param aTab the targeted tab.
    21  *
    22  */
    23 this.switchToFloatingScrollbars = function switchToFloatingScrollbars(aTab) {
    24   let mgr = trackedTabs.get(aTab);
    25   if (!mgr) {
    26     mgr = new ScrollbarManager(aTab);
    27   }
    28   mgr.switchToFloating();
    29 }
    31 /**
    32  * Switch to original native scrollbars.
    33  *
    34  * @param aTab the targeted tab.
    35  *
    36  */
    37 this.switchToNativeScrollbars = function switchToNativeScrollbars(aTab) {
    38   let mgr = trackedTabs.get(aTab);
    39   if (mgr) {
    40     mgr.reset();
    41   }
    42 }
    44 function ScrollbarManager(aTab) {
    45   trackedTabs.set(aTab, this);
    47   this.attachedTab = aTab;
    48   this.attachedBrowser = aTab.linkedBrowser;
    50   this.reset = this.reset.bind(this);
    51   this.switchToFloating = this.switchToFloating.bind(this);
    53   this.attachedTab.addEventListener("TabClose", this.reset, true);
    54   this.attachedBrowser.addEventListener("DOMContentLoaded", this.switchToFloating, true);
    55 }
    57 ScrollbarManager.prototype = {
    58   get win() {
    59     return this.attachedBrowser.contentWindow;
    60   },
    62   /*
    63    * Change the look of the scrollbars.
    64    */
    65   switchToFloating: function() {
    66     let windows = this.getInnerWindows(this.win);
    67     windows.forEach(this.injectStyleSheet);
    68     this.forceStyle();
    69   },
    72   /*
    73    * Reset the look of the scrollbars.
    74    */
    75   reset: function() {
    76     let windows = this.getInnerWindows(this.win);
    77     windows.forEach(this.removeStyleSheet);
    78     this.forceStyle(this.attachedBrowser);
    79     this.attachedBrowser.removeEventListener("DOMContentLoaded", this.switchToFloating, true);
    80     this.attachedTab.removeEventListener("TabClose", this.reset, true);
    81     trackedTabs.delete(this.attachedTab);
    82   },
    84   /*
    85    * Toggle the display property of the window to force the style to be applied.
    86    */
    87   forceStyle: function() {
    88     let parentWindow = this.attachedBrowser.ownerDocument.defaultView;
    89     let display = parentWindow.getComputedStyle(this.attachedBrowser).display; // Save display value
    90     this.attachedBrowser.style.display = "none";
    91     parentWindow.getComputedStyle(this.attachedBrowser).display; // Flush
    92     this.attachedBrowser.style.display = display; // Restore
    93   },
    95   /*
    96    * return all the window objects present in the hiearchy of a window.
    97    */
    98   getInnerWindows: function(win) {
    99     let iframes = win.document.querySelectorAll("iframe");
   100     let innerWindows = [];
   101     for (let iframe of iframes) {
   102       innerWindows = innerWindows.concat(this.getInnerWindows(iframe.contentWindow));
   103     }
   104     return [win].concat(innerWindows);
   105   },
   107   /*
   108    * Append the new scrollbar style.
   109    */
   110   injectStyleSheet: function(win) {
   111     let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
   112     try {
   113       winUtils.loadSheet(URL, win.AGENT_SHEET);
   114     }catch(e) {}
   115   },
   117   /*
   118    * Remove the injected stylesheet.
   119    */
   120   removeStyleSheet: function(win) {
   121     let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
   122     try {
   123       winUtils.removeSheet(URL, win.AGENT_SHEET);
   124     }catch(e) {}
   125   },
   126 }

mercurial