browser/devtools/framework/sidebar.js

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: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 const {Cu} = require("chrome");
     9 Cu.import("resource://gre/modules/Services.jsm");
    11 var {Promise: promise} = require("resource://gre/modules/Promise.jsm");
    12 var EventEmitter = require("devtools/toolkit/event-emitter");
    13 var Telemetry = require("devtools/shared/telemetry");
    15 const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    17 /**
    18  * ToolSidebar provides methods to register tabs in the sidebar.
    19  * It's assumed that the sidebar contains a xul:tabbox.
    20  *
    21  * @param {Node} tabbox
    22  *  <tabbox> node;
    23  * @param {ToolPanel} panel
    24  *  Related ToolPanel instance;
    25  * @param {String} uid
    26  *  Unique ID
    27  * @param {Boolean} showTabstripe
    28  *  Show the tabs.
    29  */
    30 function ToolSidebar(tabbox, panel, uid, showTabstripe=true)
    31 {
    32   EventEmitter.decorate(this);
    34   this._tabbox = tabbox;
    35   this._uid = uid;
    36   this._panelDoc = this._tabbox.ownerDocument;
    37   this._toolPanel = panel;
    39   try {
    40     this._width = Services.prefs.getIntPref("devtools.toolsidebar-width." + this._uid);
    41   } catch(e) {}
    43   this._telemetry = new Telemetry();
    45   this._tabbox.tabpanels.addEventListener("select", this, true);
    47   this._tabs = new Map();
    49   if (!showTabstripe) {
    50     this._tabbox.setAttribute("hidetabs", "true");
    51   }
    52 }
    54 exports.ToolSidebar = ToolSidebar;
    56 ToolSidebar.prototype = {
    57   /**
    58    * Register a tab. A tab is a document.
    59    * The document must have a title, which will be used as the name of the tab.
    60    *
    61    * @param {string} tab uniq id
    62    * @param {string} url
    63    */
    64   addTab: function ToolSidebar_addTab(id, url, selected=false) {
    65     let iframe = this._panelDoc.createElementNS(XULNS, "iframe");
    66     iframe.className = "iframe-" + id;
    67     iframe.setAttribute("flex", "1");
    68     iframe.setAttribute("src", url);
    69     iframe.tooltip = "aHTMLTooltip";
    71     let tab = this._tabbox.tabs.appendItem();
    72     tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
    74     let onIFrameLoaded = function() {
    75       tab.setAttribute("label", iframe.contentDocument.title);
    76       iframe.removeEventListener("load", onIFrameLoaded, true);
    77       if ("setPanel" in iframe.contentWindow) {
    78         iframe.contentWindow.setPanel(this._toolPanel, iframe);
    79       }
    80       this.emit(id + "-ready");
    81     }.bind(this);
    83     iframe.addEventListener("load", onIFrameLoaded, true);
    85     let tabpanel = this._panelDoc.createElementNS(XULNS, "tabpanel");
    86     tabpanel.setAttribute("id", "sidebar-panel-" + id);
    87     tabpanel.appendChild(iframe);
    88     this._tabbox.tabpanels.appendChild(tabpanel);
    90     this._tooltip = this._panelDoc.createElementNS(XULNS, "tooltip");
    91     this._tooltip.id = "aHTMLTooltip";
    92     tabpanel.appendChild(this._tooltip);
    93     this._tooltip.page = true;
    95     tab.linkedPanel = "sidebar-panel-" + id;
    97     // We store the index of this tab.
    98     this._tabs.set(id, tab);
   100     if (selected) {
   101       // For some reason I don't understand, if we call this.select in this
   102       // event loop (after inserting the tab), the tab will never get the
   103       // the "selected" attribute set to true.
   104       this._panelDoc.defaultView.setTimeout(function() {
   105         this.select(id);
   106       }.bind(this), 10);
   107     }
   109     this.emit("new-tab-registered", id);
   110   },
   112   /**
   113    * Select a specific tab.
   114    */
   115   select: function ToolSidebar_select(id) {
   116     let tab = this._tabs.get(id);
   117     if (tab) {
   118       this._tabbox.selectedTab = tab;
   119     }
   120   },
   122   /**
   123    * Return the id of the selected tab.
   124    */
   125   getCurrentTabID: function ToolSidebar_getCurrentTabID() {
   126     let currentID = null;
   127     for (let [id, tab] of this._tabs) {
   128       if (this._tabbox.tabs.selectedItem == tab) {
   129         currentID = id;
   130         break;
   131       }
   132     }
   133     return currentID;
   134   },
   136   /**
   137    * Returns the requested tab based on the id.
   138    *
   139    * @param String id
   140    *        unique id of the requested tab.
   141    */
   142   getTab: function ToolSidebar_getTab(id) {
   143     return this._tabbox.tabpanels.querySelector("#sidebar-panel-" + id);
   144   },
   146   /**
   147    * Event handler.
   148    */
   149   handleEvent: function ToolSidebar_eventHandler(event) {
   150     if (event.type == "select") {
   151       if (this._currentTool == this.getCurrentTabID()) {
   152         // Tool hasn't changed.
   153         return;
   154       }
   156       let previousTool = this._currentTool;
   157       this._currentTool = this.getCurrentTabID();
   158       if (previousTool) {
   159         this._telemetry.toolClosed(previousTool);
   160         this.emit(previousTool + "-unselected");
   161       }
   163       this._telemetry.toolOpened(this._currentTool);
   164       this.emit(this._currentTool + "-selected");
   165       this.emit("select", this._currentTool);
   166     }
   167   },
   169   /**
   170    * Toggle sidebar's visibility state.
   171    */
   172   toggle: function ToolSidebar_toggle() {
   173     if (this._tabbox.hasAttribute("hidden")) {
   174       this.show();
   175     } else {
   176       this.hide();
   177     }
   178   },
   180   /**
   181    * Show the sidebar.
   182    */
   183   show: function ToolSidebar_show() {
   184     if (this._width) {
   185       this._tabbox.width = this._width;
   186     }
   187     this._tabbox.removeAttribute("hidden");
   188   },
   190   /**
   191    * Show the sidebar.
   192    */
   193   hide: function ToolSidebar_hide() {
   194     Services.prefs.setIntPref("devtools.toolsidebar-width." + this._uid, this._tabbox.width);
   195     this._tabbox.setAttribute("hidden", "true");
   196   },
   198   /**
   199    * Return the window containing the tab content.
   200    */
   201   getWindowForTab: function ToolSidebar_getWindowForTab(id) {
   202     if (!this._tabs.has(id)) {
   203       return null;
   204     }
   206     let panel = this._panelDoc.getElementById(this._tabs.get(id).linkedPanel);
   207     return panel.firstChild.contentWindow;
   208   },
   210   /**
   211    * Clean-up.
   212    */
   213   destroy: function ToolSidebar_destroy() {
   214     if (this._destroyed) {
   215       return promise.resolve(null);
   216     }
   217     this._destroyed = true;
   219     Services.prefs.setIntPref("devtools.toolsidebar-width." + this._uid, this._tabbox.width);
   221     this._tabbox.tabpanels.removeEventListener("select", this, true);
   223     while (this._tabbox.tabpanels.hasChildNodes()) {
   224       this._tabbox.tabpanels.removeChild(this._tabbox.tabpanels.firstChild);
   225     }
   227     while (this._tabbox.tabs.hasChildNodes()) {
   228       this._tabbox.tabs.removeChild(this._tabbox.tabs.firstChild);
   229     }
   231     if (this._currentTool) {
   232       this._telemetry.toolClosed(this._currentTool);
   233     }
   235     this._tabs = null;
   236     this._tabbox = null;
   237     this._panelDoc = null;
   238     this._toolPanel = null;
   240     return promise.resolve(null);
   241   },
   242 }

mercurial