diff options
Diffstat (limited to 'toolkit/jetpack/sdk/ui/sidebar/view.js')
-rw-r--r-- | toolkit/jetpack/sdk/ui/sidebar/view.js | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/toolkit/jetpack/sdk/ui/sidebar/view.js b/toolkit/jetpack/sdk/ui/sidebar/view.js new file mode 100644 index 000000000..c91e69d3d --- /dev/null +++ b/toolkit/jetpack/sdk/ui/sidebar/view.js @@ -0,0 +1,214 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +module.metadata = { + 'stability': 'unstable', + 'engines': { + 'Firefox': '*' + } +}; + +const { models, buttons, views, viewsFor, modelFor } = require('./namespace'); +const { isBrowser, getMostRecentBrowserWindow, windows, isWindowPrivate } = require('../../window/utils'); +const { setStateFor } = require('../state'); +const { defer } = require('../../core/promise'); +const { isPrivateBrowsingSupported, data } = require('../../self'); + +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; +const WEB_PANEL_BROWSER_ID = 'web-panels-browser'; + +const resolveURL = (url) => url ? data.url(url) : url; + +function create(window, details) { + let id = makeID(details.id); + let { document } = window; + + if (document.getElementById(id)) + throw new Error('The ID "' + details.id + '" seems already used.'); + + let menuitem = document.createElementNS(XUL_NS, 'menuitem'); + menuitem.setAttribute('id', id); + menuitem.setAttribute('label', details.title); + menuitem.setAttribute('sidebarurl', resolveURL(details.sidebarurl)); + menuitem.setAttribute('checked', 'false'); + menuitem.setAttribute('type', 'checkbox'); + menuitem.setAttribute('group', 'sidebar'); + menuitem.setAttribute('autoCheck', 'false'); + + document.getElementById('viewSidebarMenu').appendChild(menuitem); + + return menuitem; +} +exports.create = create; + +function dispose(menuitem) { + menuitem.parentNode.removeChild(menuitem); +} +exports.dispose = dispose; + +function updateTitle(sidebar, title) { + let button = buttons.get(sidebar); + + for (let window of windows(null, { includePrivate: true })) { + let { document } = window; + + // update the button + if (button) { + setStateFor(button, window, { label: title }); + } + + // update the menuitem + let mi = document.getElementById(makeID(sidebar.id)); + if (mi) { + mi.setAttribute('label', title) + } + + // update sidebar, if showing + if (isSidebarShowing(window, sidebar)) { + document.getElementById('sidebar-title').setAttribute('value', title); + } + } +} +exports.updateTitle = updateTitle; + +function updateURL(sidebar, url) { + let eleID = makeID(sidebar.id); + + url = resolveURL(url); + + for (let window of windows(null, { includePrivate: true })) { + // update the menuitem + let mi = window.document.getElementById(eleID); + if (mi) { + mi.setAttribute('sidebarurl', url) + } + + // update sidebar, if showing + if (isSidebarShowing(window, sidebar)) { + showSidebar(window, sidebar, url); + } + } +} +exports.updateURL = updateURL; + +function isSidebarShowing(window, sidebar) { + let win = window || getMostRecentBrowserWindow(); + + // make sure there is a window + if (!win) { + return false; + } + + // make sure there is a sidebar for the window + let sb = win.document.getElementById('sidebar'); + let sidebarTitle = win.document.getElementById('sidebar-title'); + if (!(sb && sidebarTitle)) { + return false; + } + + // checks if the sidebar box is hidden + let sbb = win.document.getElementById('sidebar-box'); + if (!sbb || sbb.hidden) { + return false; + } + + if (sidebarTitle.value == modelFor(sidebar).title) { + let url = resolveURL(modelFor(sidebar).url); + + // checks if the sidebar is loading + if (win.gWebPanelURI == url) { + return true; + } + + // checks if the sidebar loaded already + let ele = sb.contentDocument && sb.contentDocument.getElementById(WEB_PANEL_BROWSER_ID); + if (!ele) { + return false; + } + + if (ele.getAttribute('cachedurl') == url) { + return true; + } + + if (ele && ele.contentWindow && ele.contentWindow.location == url) { + return true; + } + } + + // default + return false; +} +exports.isSidebarShowing = isSidebarShowing; + +function showSidebar(window, sidebar, newURL) { + window = window || getMostRecentBrowserWindow(); + + let { promise, resolve, reject } = defer(); + let model = modelFor(sidebar); + + if (!newURL && isSidebarShowing(window, sidebar)) { + resolve({}); + } + else if (!isPrivateBrowsingSupported && isWindowPrivate(window)) { + reject(Error('You cannot show a sidebar on private windows')); + } + else { + sidebar.once('show', resolve); + + let menuitem = window.document.getElementById(makeID(model.id)); + menuitem.setAttribute('checked', true); + + window.openWebPanel(model.title, resolveURL(newURL || model.url)); + } + + return promise; +} +exports.showSidebar = showSidebar; + + +function hideSidebar(window, sidebar) { + window = window || getMostRecentBrowserWindow(); + + let { promise, resolve, reject } = defer(); + + if (!isSidebarShowing(window, sidebar)) { + reject(Error('The sidebar is already hidden')); + } + else { + sidebar.once('hide', resolve); + + // Below was taken from http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#4775 + // the code for window.todggleSideBar().. + let { document } = window; + let sidebarEle = document.getElementById('sidebar'); + let sidebarTitle = document.getElementById('sidebar-title'); + let sidebarBox = document.getElementById('sidebar-box'); + let sidebarSplitter = document.getElementById('sidebar-splitter'); + let commandID = sidebarBox.getAttribute('sidebarcommand'); + let sidebarBroadcaster = document.getElementById(commandID); + + sidebarBox.hidden = true; + sidebarSplitter.hidden = true; + + sidebarEle.setAttribute('src', 'about:blank'); + //sidebarEle.docShell.createAboutBlankContentViewer(null); + + sidebarBroadcaster.removeAttribute('checked'); + sidebarBox.setAttribute('sidebarcommand', ''); + sidebarTitle.value = ''; + sidebarBox.hidden = true; + sidebarSplitter.hidden = true; + + // TODO: perhaps this isn't necessary if the window is not most recent? + window.gBrowser.selectedBrowser.focus(); + } + + return promise; +} +exports.hideSidebar = hideSidebar; + +function makeID(id) { + return 'jetpack-sidebar-' + id; +} |