aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js')
-rw-r--r--tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js369
1 files changed, 0 insertions, 369 deletions
diff --git a/tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js b/tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js
deleted file mode 100644
index 1365c02..0000000
--- a/tools/addon-sdk-1.5/packages/addon-kit/lib/panel.js
+++ /dev/null
@@ -1,369 +0,0 @@
-/* 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";
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The panel module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps ",
- "for more information."
- ].join(""));
-}
-
-const { Cc, Ci } = require("chrome");
-
-const { validateOptions: valid } = require("api-utils/api-utils");
-const { Symbiont } = require("api-utils/content");
-const { EventEmitter } = require('api-utils/events');
-const timer = require("api-utils/timer");
-const runtime = require("api-utils/runtime");
-
-const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
- getService(Ci.nsIWindowMediator);
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- ON_SHOW = 'popupshown',
- ON_HIDE = 'popuphidden',
- validNumber = { is: ['number', 'undefined', 'null'] };
-
-/**
- * Emits show and hide events.
- */
-const Panel = Symbiont.resolve({
- constructor: '_init',
- _onInit: '_onSymbiontInit',
- destroy: '_symbiontDestructor',
- _documentUnload: '_workerDocumentUnload'
-}).compose({
- _frame: Symbiont.required,
- _init: Symbiont.required,
- _onSymbiontInit: Symbiont.required,
- _symbiontDestructor: Symbiont.required,
- _emit: Symbiont.required,
- _asyncEmit: Symbiont.required,
- on: Symbiont.required,
- removeListener: Symbiont.required,
-
- _inited: false,
-
- /**
- * If set to `true` frame loaders between xul panel frame and
- * hidden frame are swapped. If set to `false` frame loaders are
- * set back to normal. Setting the value that was already set will
- * have no effect.
- */
- set _frameLoadersSwapped(value) {
- if (this.__frameLoadersSwapped == value) return;
- this._frame.QueryInterface(Ci.nsIFrameLoaderOwner)
- .swapFrameLoaders(this._viewFrame);
- this.__frameLoadersSwapped = value;
- },
- __frameLoadersSwapped: false,
-
- constructor: function Panel(options) {
- this._onShow = this._onShow.bind(this);
- this._onHide = this._onHide.bind(this);
- this.on('inited', this._onSymbiontInit.bind(this));
-
- options = options || {};
- if ('onShow' in options)
- this.on('show', options.onShow);
- if ('onHide' in options)
- this.on('hide', options.onHide);
- if ('width' in options)
- this.width = options.width;
- if ('height' in options)
- this.height = options.height;
- if ('contentURL' in options)
- this.contentURL = options.contentURL;
-
- this._init(options);
- },
- _destructor: function _destructor() {
- this.hide();
- this._removeAllListeners('show');
- // defer cleanup to be performed after panel gets hidden
- this._xulPanel = null;
- this._symbiontDestructor(this);
- this._removeAllListeners();
- },
- destroy: function destroy() {
- this._destructor();
- },
- /* Public API: Panel.width */
- get width() this._width,
- set width(value)
- this._width = valid({ $: value }, { $: validNumber }).$ || this._width,
- _width: 320,
- /* Public API: Panel.height */
- get height() this._height,
- set height(value)
- this._height = valid({ $: value }, { $: validNumber }).$ || this._height,
- _height: 240,
-
- /* Public API: Panel.isShowing */
- get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
-
- /* Public API: Panel.show */
- show: function show(anchor) {
- anchor = anchor || null;
- let document = getWindow(anchor).document;
- let xulPanel = this._xulPanel;
- if (!xulPanel) {
- xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
- xulPanel.setAttribute("type", "arrow");
-
- // One anonymous node has a big padding that doesn't work well with
- // Jetpack, as we would like to display an iframe that completely fills
- // the panel.
- // -> Use a XBL wrapper with inner stylesheet to remove this padding.
- let css = ".panel-inner-arrowcontent, .panel-arrowcontent {padding: 0;}";
- let originalXBL = "chrome://global/content/bindings/popup.xml#arrowpanel";
- let binding =
- '<bindings xmlns="http://www.mozilla.org/xbl">' +
- '<binding id="id" extends="' + originalXBL + '">' +
- '<resources>' +
- '<stylesheet src="data:text/css,' +
- document.defaultView.encodeURIComponent(css) + '"/>' +
- '</resources>' +
- '</binding>' +
- '</bindings>';
- xulPanel.style.MozBinding = 'url("data:text/xml,' +
- document.defaultView.encodeURIComponent(binding) + '")';
-
- let frame = document.createElementNS(XUL_NS, 'iframe');
- frame.setAttribute('type', 'content');
- frame.setAttribute('flex', '1');
- frame.setAttribute('transparent', 'transparent');
- if (runtime.OS === "Darwin") {
- frame.style.borderRadius = "6px";
- frame.style.padding = "1px";
- }
-
- // Load an empty document in order to have an immediatly loaded iframe,
- // so swapFrameLoaders is going to work without having to wait for load.
- frame.setAttribute("src","data:,");
-
- xulPanel.appendChild(frame);
- document.getElementById("mainPopupSet").appendChild(xulPanel);
- }
- let { width, height } = this, x, y, position;
-
- if (!anchor) {
- // Open the popup in the middle of the window.
- x = document.documentElement.clientWidth / 2 - width / 2;
- y = document.documentElement.clientHeight / 2 - height / 2;
- position = null;
- }
- else {
- // Open the popup by the anchor.
- let rect = anchor.getBoundingClientRect();
-
- let window = anchor.ownerDocument.defaultView;
-
- let zoom = window.mozScreenPixelsPerCSSPixel;
- let screenX = rect.left + window.mozInnerScreenX * zoom;
- let screenY = rect.top + window.mozInnerScreenY * zoom;
-
- // Set up the vertical position of the popup relative to the anchor
- // (always display the arrow on anchor center)
- let horizontal, vertical;
- if (screenY > window.screen.availHeight / 2 + height)
- vertical = "top";
- else
- vertical = "bottom";
-
- if (screenY > window.screen.availWidth / 2 + width)
- horizontal = "left";
- else
- horizontal = "right";
-
- let verticalInverse = vertical == "top" ? "bottom" : "top";
- position = vertical + "center " + verticalInverse + horizontal;
-
- // Allow panel to flip itself if the panel can't be displayed at the
- // specified position (useful if we compute a bad position or if the
- // user moves the window and panel remains visible)
- xulPanel.setAttribute("flip","both");
- }
-
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
-
- // Wait for the XBL binding to be constructed
- function waitForBinding() {
- if (!xulPanel.openPopup) {
- timer.setTimeout(waitForBinding, 50);
- return;
- }
- xulPanel.openPopup(anchor, position, x, y);
- }
- waitForBinding();
-
- return this._public;
- },
- /* Public API: Panel.hide */
- hide: function hide() {
- // The popuphiding handler takes care of swapping back the frame loaders
- // and removing the XUL panel from the application window, we just have to
- // trigger it by hiding the popup.
- // XXX Sometimes I get "TypeError: xulPanel.hidePopup is not a function"
- // when quitting the host application while a panel is visible. To suppress
- // them, this now checks for "hidePopup" in xulPanel before calling it.
- // It's not clear if there's an actual issue or the error is just normal.
- let xulPanel = this._xulPanel;
- if (xulPanel && "hidePopup" in xulPanel)
- xulPanel.hidePopup();
- return this._public;
- },
-
- /* Public API: Panel.resize */
- resize: function resize(width, height) {
- this.width = width;
- this.height = height;
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- let xulPanel = this._xulPanel;
- if (xulPanel) {
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
- }
- },
-
- // While the panel is visible, this is the XUL <panel> we use to display it.
- // Otherwise, it's null.
- get _xulPanel() this.__xulPanel,
- set _xulPanel(value) {
- let xulPanel = this.__xulPanel;
- if (value === xulPanel) return;
- if (xulPanel) {
- xulPanel.removeEventListener(ON_HIDE, this._onHide, false);
- xulPanel.removeEventListener(ON_SHOW, this._onShow, false);
- xulPanel.parentNode.removeChild(xulPanel);
- }
- if (value) {
- value.addEventListener(ON_HIDE, this._onHide, false);
- value.addEventListener(ON_SHOW, this._onShow, false);
- }
- this.__xulPanel = value;
- },
- __xulPanel: null,
- get _viewFrame() this.__xulPanel.children[0],
- /**
- * When the XUL panel becomes hidden, we swap frame loaders back to move
- * the content of the panel to the hidden frame & remove panel element.
- */
- _onHide: function _onHide() {
- try {
- this._frameLoadersSwapped = false;
- this._xulPanel = null;
- this._emit('hide');
- } catch(e) {
- this._emit('error', e);
- }
- },
- /**
- * When the XUL panel becomes shown, we swap frame loaders between panel
- * frame and hidden frame to preserve state of the content dom.
- */
- _onShow: function _onShow() {
- try {
- if (!this._inited) { // defer if not initialized yet
- this.on('inited', this._onShow.bind(this));
- } else {
- this._frameLoadersSwapped = true;
-
- // Retrieve computed text color style in order to apply to the iframe
- // document. As MacOS background is dark gray, we need to use skin's
- // text color.
- let win = this._xulPanel.ownerDocument.defaultView;
- let node = win.document.getAnonymousElementByAttribute(this._xulPanel,
- "class", "panel-inner-arrowcontent");
- let textColor = win.getComputedStyle(node).getPropertyValue("color");
- let doc = this._xulPanel.firstChild.contentDocument;
- let style = doc.createElement("style");
- style.textContent = "body { color: " + textColor + "; }";
- let container = doc.head ? doc.head : doc.documentElement;
-
- if (container.firstChild)
- container.insertBefore(style, container.firstChild);
- else
- container.appendChild(style);
-
- this._emit('show');
- }
- } catch(e) {
- this._emit('error', e);
- }
- },
- /**
- * Notification that panel was fully initialized.
- */
- _onInit: function _onInit() {
- this._inited = true;
-
- // Avoid panel document from resizing the browser window
- // New platform capability added through bug 635673
- if ("allowWindowControl" in this._frame.docShell)
- this._frame.docShell.allowWindowControl = false;
-
- // perform all deferred tasks like initSymbiont, show, hide ...
- // TODO: We're publicly exposing a private event here; this
- // 'inited' event should really be made private, somehow.
- this._emit('inited');
- },
-
- // Catch document unload event in order to rebind load event listener with
- // Symbiont._initFrame if Worker._documentUnload destroyed the worker
- _documentUnload: function(subject, topic, data) {
- if (this._workerDocumentUnload(subject, topic, data)) {
- this._initFrame(this._frame);
- return true;
- }
- return false;
- }
-});
-exports.Panel = function(options) Panel(options)
-exports.Panel.prototype = Panel.prototype;
-
-function getWindow(anchor) {
- let window;
-
- if (anchor) {
- let anchorWindow = anchor.ownerDocument.defaultView.top;
- let anchorDocument = anchorWindow.document;
-
- let enumerator = windowMediator.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let enumWindow = enumerator.getNext();
-
- // Check if the anchor is in this browser window.
- if (enumWindow == anchorWindow) {
- window = anchorWindow;
- break;
- }
-
- // Check if the anchor is in a browser tab in this browser window.
- let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
- if (browser) {
- window = enumWindow;
- break;
- }
-
- // Look in other subdocuments (sidebar, etc.)?
- }
- }
-
- // If we didn't find the anchor's window (or we have no anchor),
- // return the most recent browser window.
- if (!window)
- window = windowMediator.getMostRecentWindow("navigator:browser");
-
- return window;
-}
-