1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/ui/sidebar/view.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,208 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 +* License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +'use strict'; 1.8 + 1.9 +module.metadata = { 1.10 + 'stability': 'unstable', 1.11 + 'engines': { 1.12 + 'Firefox': '*' 1.13 + } 1.14 +}; 1.15 + 1.16 +const { models, buttons, views, viewsFor, modelFor } = require('./namespace'); 1.17 +const { isBrowser, getMostRecentBrowserWindow, windows, isWindowPrivate } = require('../../window/utils'); 1.18 +const { setStateFor } = require('../state'); 1.19 +const { defer } = require('../../core/promise'); 1.20 +const { isPrivateBrowsingSupported } = require('../../self'); 1.21 + 1.22 +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; 1.23 +const WEB_PANEL_BROWSER_ID = 'web-panels-browser'; 1.24 + 1.25 +function create(window, details) { 1.26 + let id = makeID(details.id); 1.27 + let { document } = window; 1.28 + 1.29 + if (document.getElementById(id)) 1.30 + throw new Error('The ID "' + details.id + '" seems already used.'); 1.31 + 1.32 + let menuitem = document.createElementNS(XUL_NS, 'menuitem'); 1.33 + menuitem.setAttribute('id', id); 1.34 + menuitem.setAttribute('label', details.title); 1.35 + menuitem.setAttribute('sidebarurl', details.sidebarurl); 1.36 + menuitem.setAttribute('checked', 'false'); 1.37 + menuitem.setAttribute('type', 'checkbox'); 1.38 + menuitem.setAttribute('group', 'sidebar'); 1.39 + menuitem.setAttribute('autoCheck', 'false'); 1.40 + 1.41 + document.getElementById('viewSidebarMenu').appendChild(menuitem); 1.42 + 1.43 + return menuitem; 1.44 +} 1.45 +exports.create = create; 1.46 + 1.47 +function dispose(menuitem) { 1.48 + menuitem.parentNode.removeChild(menuitem); 1.49 +} 1.50 +exports.dispose = dispose; 1.51 + 1.52 +function updateTitle(sidebar, title) { 1.53 + let button = buttons.get(sidebar); 1.54 + 1.55 + for (let window of windows(null, { includePrivate: true })) { 1.56 + let { document } = window; 1.57 + 1.58 + // update the button 1.59 + if (button) { 1.60 + setStateFor(button, window, { label: title }); 1.61 + } 1.62 + 1.63 + // update the menuitem 1.64 + let mi = document.getElementById(makeID(sidebar.id)); 1.65 + if (mi) { 1.66 + mi.setAttribute('label', title) 1.67 + } 1.68 + 1.69 + // update sidebar, if showing 1.70 + if (isSidebarShowing(window, sidebar)) { 1.71 + document.getElementById('sidebar-title').setAttribute('value', title); 1.72 + } 1.73 + } 1.74 +} 1.75 +exports.updateTitle = updateTitle; 1.76 + 1.77 +function updateURL(sidebar, url) { 1.78 + let eleID = makeID(sidebar.id); 1.79 + 1.80 + for (let window of windows(null, { includePrivate: true })) { 1.81 + // update the menuitem 1.82 + let mi = window.document.getElementById(eleID); 1.83 + if (mi) { 1.84 + mi.setAttribute('sidebarurl', url) 1.85 + } 1.86 + 1.87 + // update sidebar, if showing 1.88 + if (isSidebarShowing(window, sidebar)) { 1.89 + showSidebar(window, sidebar, url); 1.90 + } 1.91 + } 1.92 +} 1.93 +exports.updateURL = updateURL; 1.94 + 1.95 +function isSidebarShowing(window, sidebar) { 1.96 + let win = window || getMostRecentBrowserWindow(); 1.97 + 1.98 + // make sure there is a window 1.99 + if (!win) { 1.100 + return false; 1.101 + } 1.102 + 1.103 + // make sure there is a sidebar for the window 1.104 + let sb = win.document.getElementById('sidebar'); 1.105 + let sidebarTitle = win.document.getElementById('sidebar-title'); 1.106 + if (!(sb && sidebarTitle)) { 1.107 + return false; 1.108 + } 1.109 + 1.110 + // checks if the sidebar box is hidden 1.111 + let sbb = win.document.getElementById('sidebar-box'); 1.112 + if (!sbb || sbb.hidden) { 1.113 + return false; 1.114 + } 1.115 + 1.116 + if (sidebarTitle.value == modelFor(sidebar).title) { 1.117 + // checks if the sidebar is loading 1.118 + if (win.gWebPanelURI == modelFor(sidebar).url) { 1.119 + return true; 1.120 + } 1.121 + 1.122 + // checks if the sidebar loaded already 1.123 + let ele = sb.contentDocument && sb.contentDocument.getElementById(WEB_PANEL_BROWSER_ID); 1.124 + if (!ele) { 1.125 + return false; 1.126 + } 1.127 + 1.128 + if (ele.getAttribute('cachedurl') == modelFor(sidebar).url) { 1.129 + return true; 1.130 + } 1.131 + 1.132 + if (ele && ele.contentWindow && ele.contentWindow.location == modelFor(sidebar).url) { 1.133 + return true; 1.134 + } 1.135 + } 1.136 + 1.137 + // default 1.138 + return false; 1.139 +} 1.140 +exports.isSidebarShowing = isSidebarShowing; 1.141 + 1.142 +function showSidebar(window, sidebar, newURL) { 1.143 + window = window || getMostRecentBrowserWindow(); 1.144 + 1.145 + let { promise, resolve, reject } = defer(); 1.146 + let model = modelFor(sidebar); 1.147 + 1.148 + if (!newURL && isSidebarShowing(window, sidebar)) { 1.149 + resolve({}); 1.150 + } 1.151 + else if (!isPrivateBrowsingSupported && isWindowPrivate(window)) { 1.152 + reject(Error('You cannot show a sidebar on private windows')); 1.153 + } 1.154 + else { 1.155 + sidebar.once('show', resolve); 1.156 + 1.157 + let menuitem = window.document.getElementById(makeID(model.id)); 1.158 + menuitem.setAttribute('checked', true); 1.159 + 1.160 + window.openWebPanel(model.title, newURL || model.url); 1.161 + } 1.162 + 1.163 + return promise; 1.164 +} 1.165 +exports.showSidebar = showSidebar; 1.166 + 1.167 + 1.168 +function hideSidebar(window, sidebar) { 1.169 + window = window || getMostRecentBrowserWindow(); 1.170 + 1.171 + let { promise, resolve, reject } = defer(); 1.172 + 1.173 + if (!isSidebarShowing(window, sidebar)) { 1.174 + reject(Error('The sidebar is already hidden')); 1.175 + } 1.176 + else { 1.177 + sidebar.once('hide', resolve); 1.178 + 1.179 + // Below was taken from http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#4775 1.180 + // the code for window.todggleSideBar().. 1.181 + let { document } = window; 1.182 + let sidebarEle = document.getElementById('sidebar'); 1.183 + let sidebarTitle = document.getElementById('sidebar-title'); 1.184 + let sidebarBox = document.getElementById('sidebar-box'); 1.185 + let sidebarSplitter = document.getElementById('sidebar-splitter'); 1.186 + let commandID = sidebarBox.getAttribute('sidebarcommand'); 1.187 + let sidebarBroadcaster = document.getElementById(commandID); 1.188 + 1.189 + sidebarBox.hidden = true; 1.190 + sidebarSplitter.hidden = true; 1.191 + 1.192 + sidebarEle.setAttribute('src', 'about:blank'); 1.193 + //sidebarEle.docShell.createAboutBlankContentViewer(null); 1.194 + 1.195 + sidebarBroadcaster.removeAttribute('checked'); 1.196 + sidebarBox.setAttribute('sidebarcommand', ''); 1.197 + sidebarTitle.value = ''; 1.198 + sidebarBox.hidden = true; 1.199 + sidebarSplitter.hidden = true; 1.200 + 1.201 + // TODO: perhaps this isn't necessary if the window is not most recent? 1.202 + window.gBrowser.selectedBrowser.focus(); 1.203 + } 1.204 + 1.205 + return promise; 1.206 +} 1.207 +exports.hideSidebar = hideSidebar; 1.208 + 1.209 +function makeID(id) { 1.210 + return 'jetpack-sidebar-' + id; 1.211 +}