diff options
author | Matt A. Tobin <email@mattatobin.com> | 2018-02-09 06:46:43 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2018-02-09 06:46:43 -0500 |
commit | ac46df8daea09899ce30dc8fd70986e258c746bf (patch) | |
tree | 2750d3125fc253fd5b0671e4bd268eff1fd97296 /addon-sdk/source/lib/sdk/window | |
parent | 8cecf8d5208f3945b35f879bba3015bb1a11bec6 (diff) | |
download | UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.gz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.lz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.xz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.zip |
Move Add-on SDK source to toolkit/jetpack
Diffstat (limited to 'addon-sdk/source/lib/sdk/window')
-rw-r--r-- | addon-sdk/source/lib/sdk/window/browser.js | 54 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/window/events.js | 68 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/window/helpers.js | 81 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/window/namespace.js | 6 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/window/utils.js | 460 |
5 files changed, 0 insertions, 669 deletions
diff --git a/addon-sdk/source/lib/sdk/window/browser.js b/addon-sdk/source/lib/sdk/window/browser.js deleted file mode 100644 index 380b5a486..000000000 --- a/addon-sdk/source/lib/sdk/window/browser.js +++ /dev/null @@ -1,54 +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'; - -const { Class } = require('../core/heritage'); -const { windowNS } = require('./namespace'); -const { on, off, once } = require('../event/core'); -const { method } = require('../lang/functional'); -const { getWindowTitle } = require('./utils'); -const unload = require('../system/unload'); -const { EventTarget } = require('../event/target'); -const { isPrivate } = require('../private-browsing/utils'); -const { isWindowPrivate, isFocused } = require('../window/utils'); -const { viewFor } = require('../view/core'); - -const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("sdk/tabs") instead'; - -const BrowserWindow = Class({ - initialize: function initialize(options) { - EventTarget.prototype.initialize.call(this, options); - windowNS(this).window = options.window; - }, - activate: function activate() { - // TODO - return null; - }, - close: function() { - throw new Error(ERR_FENNEC_MSG); - return null; - }, - get title() { - return getWindowTitle(windowNS(this).window); - }, - // NOTE: Fennec only has one window, which is assumed below - // TODO: remove assumption below - // NOTE: tabs requires windows - get tabs() { - return require('../tabs'); - }, - get activeTab() { - return require('../tabs').activeTab; - }, - on: method(on), - removeListener: method(off), - once: method(once) -}); -exports.BrowserWindow = BrowserWindow; - -const getWindowView = window => windowNS(window).window; - -viewFor.define(BrowserWindow, getWindowView); -isPrivate.define(BrowserWindow, (window) => isWindowPrivate(viewFor(window).window)); -isFocused.define(BrowserWindow, (window) => isFocused(viewFor(window).window)); diff --git a/addon-sdk/source/lib/sdk/window/events.js b/addon-sdk/source/lib/sdk/window/events.js deleted file mode 100644 index b1d3a1f3e..000000000 --- a/addon-sdk/source/lib/sdk/window/events.js +++ /dev/null @@ -1,68 +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"; - -module.metadata = { - "stability": "unstable" -}; - -const { Ci, Cu } = require("chrome"); -const { observe } = require("../event/chrome"); -const { open } = require("../event/dom"); -const { windows } = require("../window/utils"); -const { filter, merge, map, expand } = require("../event/utils"); - -function documentMatches(weakWindow, event) { - let window = weakWindow.get(); - return window && event.target === window.document; -} - -function makeStrictDocumentFilter(window) { - // Note: Do not define a closure within this function. Otherwise - // you may leak the window argument. - let weak = Cu.getWeakReference(window); - return documentMatches.bind(null, weak); -} - -function toEventWithDefaultViewTarget({type, target}) { - return { type: type, target: target.defaultView } -} - -// Function registers single shot event listeners for relevant window events -// that forward events to exported event stream. -function eventsFor(window) { - // NOTE: Do no use pass a closure from this function into a stream - // transform function. You will capture the window in the - // closure and leak the window until the event stream is - // completely closed. - let interactive = open(window, "DOMContentLoaded", { capture: true }); - let complete = open(window, "load", { capture: true }); - let states = merge([interactive, complete]); - let changes = filter(states, makeStrictDocumentFilter(window)); - return map(changes, toEventWithDefaultViewTarget); -} - -// Create our event channels. We do this in a separate function to -// minimize the chance of leaking intermediate objects on the global. -function makeEvents() { - // In addition to observing windows that are open we also observe windows - // that are already already opened in case they're in process of loading. - var opened = windows(null, { includePrivate: true }); - var currentEvents = merge(opened.map(eventsFor)); - - // Register system event listeners for top level window open / close. - function rename({type, target, data}) { - return { type: rename[type], target: target, data: data } - } - rename.domwindowopened = "open"; - rename.domwindowclosed = "close"; - - var openEvents = map(observe("domwindowopened"), rename); - var closeEvents = map(observe("domwindowclosed"), rename); - var futureEvents = expand(openEvents, ({target}) => eventsFor(target)); - - return merge([currentEvents, futureEvents, openEvents, closeEvents]); -} - -exports.events = makeEvents(); diff --git a/addon-sdk/source/lib/sdk/window/helpers.js b/addon-sdk/source/lib/sdk/window/helpers.js deleted file mode 100644 index 56cfcaba7..000000000 --- a/addon-sdk/source/lib/sdk/window/helpers.js +++ /dev/null @@ -1,81 +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'; - -const { defer, all } = require('../core/promise'); -const events = require('../system/events'); -const { open: openWindow, onFocus, getToplevelWindow, - isInteractive, isStartupFinished, getOuterId } = require('./utils'); -const { Ci } = require("chrome"); - -function open(uri, options) { - return promise(openWindow.apply(null, arguments), 'load').then(focus); -} -exports.open = open; - -function close(window) { - let deferred = defer(); - let toplevelWindow = getToplevelWindow(window); - let outerId = getOuterId(toplevelWindow); - events.on("outer-window-destroyed", function onclose({subject}) { - let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; - if (id == outerId) { - events.off("outer-window-destroyed", onclose); - deferred.resolve(); - } - }, true); - window.close(); - return deferred.promise; -} -exports.close = close; - -function focus(window) { - let p = onFocus(window); - window.focus(); - return p; -} -exports.focus = focus; - -function ready(window) { - let { promise: result, resolve } = defer(); - - if (isInteractive(window)) - resolve(window); - else - resolve(promise(window, 'DOMContentLoaded')); - - return result; -} -exports.ready = ready; - -function startup(window) { - let { promise: result, resolve } = defer(); - - if (isStartupFinished(window)) { - resolve(window); - } else { - events.on("browser-delayed-startup-finished", function listener({subject}) { - if (subject === window) { - events.off("browser-delayed-startup-finished", listener); - resolve(window); - } - }); - } - - return result; -} -exports.startup = startup; - -function promise(target, evt, capture) { - let deferred = defer(); - capture = !!capture; - - target.addEventListener(evt, function eventHandler() { - target.removeEventListener(evt, eventHandler, capture); - deferred.resolve(target); - }, capture); - - return deferred.promise; -} -exports.promise = promise; diff --git a/addon-sdk/source/lib/sdk/window/namespace.js b/addon-sdk/source/lib/sdk/window/namespace.js deleted file mode 100644 index b486f888d..000000000 --- a/addon-sdk/source/lib/sdk/window/namespace.js +++ /dev/null @@ -1,6 +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"; - -exports.windowNS = require('../core/namespace').ns(); diff --git a/addon-sdk/source/lib/sdk/window/utils.js b/addon-sdk/source/lib/sdk/window/utils.js deleted file mode 100644 index db91a0fed..000000000 --- a/addon-sdk/source/lib/sdk/window/utils.js +++ /dev/null @@ -1,460 +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'; - -module.metadata = { - 'stability': 'unstable' -}; - -const { Cc, Ci } = require('chrome'); -const array = require('../util/array'); -const { defer } = require('sdk/core/promise'); -const { dispatcher } = require("../util/dispatcher"); - -const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1']. - getService(Ci.nsIWindowWatcher); -const appShellService = Cc['@mozilla.org/appshell/appShellService;1']. - getService(Ci.nsIAppShellService); -const WM = Cc['@mozilla.org/appshell/window-mediator;1']. - getService(Ci.nsIWindowMediator); -const io = Cc['@mozilla.org/network/io-service;1']. - getService(Ci.nsIIOService); -const FM = Cc["@mozilla.org/focus-manager;1"]. - getService(Ci.nsIFocusManager); - -const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; - -const prefs = require("../preferences/service"); -const BROWSER = 'navigator:browser', - URI_BROWSER = prefs.get('browser.chromeURL', null), - NAME = '_blank', - FEATURES = 'chrome,all,dialog=no,non-private'; - -function isWindowPrivate(win) { - if (!win) - return false; - - // if the pbService is undefined, the PrivateBrowsingUtils.jsm is available, - // and the app is Firefox, then assume per-window private browsing is - // enabled. - try { - return win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsILoadContext) - .usePrivateBrowsing; - } - catch(e) {} - - // Sometimes the input is not a nsIDOMWindow.. but it is still a winodw. - try { - return !!win.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing; - } - catch (e) {} - - return false; -} -exports.isWindowPrivate = isWindowPrivate; - -function getMostRecentBrowserWindow() { - return getMostRecentWindow(BROWSER); -} -exports.getMostRecentBrowserWindow = getMostRecentBrowserWindow; - -function getHiddenWindow() { - return appShellService.hiddenDOMWindow; -} -exports.getHiddenWindow = getHiddenWindow; - -function getMostRecentWindow(type) { - return WM.getMostRecentWindow(type); -} -exports.getMostRecentWindow = getMostRecentWindow; - -/** - * Returns the ID of the window's current inner window. - */ -function getInnerId(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; -}; -exports.getInnerId = getInnerId; - -/** - * Returns the ID of the window's outer window. - */ -function getOuterId(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindowUtils).outerWindowID; -}; -exports.getOuterId = getOuterId; - -/** - * Returns window by the outer window id. - */ -const getByOuterId = WM.getOuterWindowWithId; -exports.getByOuterId = getByOuterId; - -const getByInnerId = WM.getCurrentInnerWindowWithId; -exports.getByInnerId = getByInnerId; - -/** - * Returns `nsIXULWindow` for the given `nsIDOMWindow`. - */ -function getXULWindow(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIWebNavigation). - QueryInterface(Ci.nsIDocShellTreeItem). - treeOwner.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIXULWindow); -}; -exports.getXULWindow = getXULWindow; - -function getDOMWindow(xulWindow) { - return xulWindow.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindow); -} -exports.getDOMWindow = getDOMWindow; - -/** - * Returns `nsIBaseWindow` for the given `nsIDOMWindow`. - */ -function getBaseWindow(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIWebNavigation). - QueryInterface(Ci.nsIDocShell). - QueryInterface(Ci.nsIDocShellTreeItem). - treeOwner. - QueryInterface(Ci.nsIBaseWindow); -} -exports.getBaseWindow = getBaseWindow; - -/** - * Returns the `nsIDOMWindow` toplevel window for any child/inner window - */ -function getToplevelWindow(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); -} -exports.getToplevelWindow = getToplevelWindow; - -function getWindowDocShell(window) { - return window.gBrowser.docShell; -} -exports.getWindowDocShell = getWindowDocShell; - -function getWindowLoadingContext(window) { - return getWindowDocShell(window). - QueryInterface(Ci.nsILoadContext); -} -exports.getWindowLoadingContext = getWindowLoadingContext; - -const isTopLevel = window => window && getToplevelWindow(window) === window; -exports.isTopLevel = isTopLevel; - -/** - * Takes hash of options and serializes it to a features string that - * can be used passed to `window.open`. For more details on features string see: - * https://developer.mozilla.org/en/DOM/window.open#Position_and_size_features - */ -function serializeFeatures(options) { - return Object.keys(options).reduce(function(result, name) { - let value = options[name]; - - // the chrome and private features are special - if ((name == 'private' || name == 'chrome' || name == 'all')) - return result + ((value === true) ? ',' + name : ''); - - return result + ',' + name + '=' + - (value === true ? 'yes' : value === false ? 'no' : value); - }, '').substr(1); -} - -/** - * Opens a top level window and returns it's `nsIDOMWindow` representation. - * @params {String} uri - * URI of the document to be loaded into window. - * @params {nsIDOMWindow} options.parent - * Used as parent for the created window. - * @params {String} options.name - * Optional name that is assigned to the window. - * @params {Object} options.features - * Map of key, values like: `{ width: 10, height: 15, chrome: true, private: true }`. - */ -function open(uri, options) { - uri = uri || URI_BROWSER; - options = options || {}; - - if (!uri) - throw new Error('browser.chromeURL is undefined, please provide an explicit uri'); - - if (['chrome', 'resource', 'data'].indexOf(io.newURI(uri, null, null).scheme) < 0) - throw new Error('only chrome, resource and data uris are allowed'); - - let newWindow = windowWatcher. - openWindow(options.parent || null, - uri, - options.name || null, - options.features ? serializeFeatures(options.features) : null, - options.args || null); - - return newWindow; -} -exports.open = open; - -function onFocus(window) { - let { resolve, promise } = defer(); - - if (isFocused(window)) { - resolve(window); - } - else { - window.addEventListener("focus", function focusListener() { - window.removeEventListener("focus", focusListener, true); - resolve(window); - }, true); - } - - return promise; -} -exports.onFocus = onFocus; - -var isFocused = dispatcher("window-isFocused"); -isFocused.when(x => x instanceof Ci.nsIDOMWindow, (window) => { - const FM = Cc["@mozilla.org/focus-manager;1"]. - getService(Ci.nsIFocusManager); - - let childTargetWindow = {}; - FM.getFocusedElementForWindow(window, true, childTargetWindow); - childTargetWindow = childTargetWindow.value; - - let focusedChildWindow = {}; - if (FM.activeWindow) { - FM.getFocusedElementForWindow(FM.activeWindow, true, focusedChildWindow); - focusedChildWindow = focusedChildWindow.value; - } - - return (focusedChildWindow === childTargetWindow); -}); -exports.isFocused = isFocused; - -/** - * Opens a top level window and returns it's `nsIDOMWindow` representation. - * Same as `open` but with more features - * @param {Object} options - * - */ -function openDialog(options) { - options = options || {}; - - let features = options.features || FEATURES; - let featureAry = features.toLowerCase().split(','); - - if (!!options.private) { - // add private flag if private window is desired - if (!array.has(featureAry, 'private')) { - featureAry.push('private'); - } - - // remove the non-private flag ig a private window is desired - let nonPrivateIndex = featureAry.indexOf('non-private'); - if (nonPrivateIndex >= 0) { - featureAry.splice(nonPrivateIndex, 1); - } - - features = featureAry.join(','); - } - - let browser = getMostRecentBrowserWindow(); - - // if there is no browser then do nothing - if (!browser) - return undefined; - - let newWindow = browser.openDialog.apply( - browser, - array.flatten([ - options.url || URI_BROWSER, - options.name || NAME, - features, - options.args || null - ]) - ); - - return newWindow; -} -exports.openDialog = openDialog; - -/** - * Returns an array of all currently opened windows. - * Note that these windows may still be loading. - */ -function windows(type, options) { - options = options || {}; - let list = []; - let winEnum = WM.getEnumerator(type); - while (winEnum.hasMoreElements()) { - let window = winEnum.getNext().QueryInterface(Ci.nsIDOMWindow); - // Only add non-private windows when pb permission isn't set, - // unless an option forces the addition of them. - if (!window.closed && (options.includePrivate || !isWindowPrivate(window))) { - list.push(window); - } - } - return list; -} -exports.windows = windows; - -/** - * Check if the given window is interactive. - * i.e. if its "DOMContentLoaded" event has already been fired. - * @params {nsIDOMWindow} window - */ -const isInteractive = window => - window.document.readyState === "interactive" || - isDocumentLoaded(window) || - // XUL documents stays '"uninitialized"' until it's `readyState` becomes - // `"complete"`. - isXULDocumentWindow(window) && window.document.readyState === "interactive"; -exports.isInteractive = isInteractive; - -/** - * Check if the given browser window has finished the startup. - * @params {nsIDOMWindow} window - */ -const isStartupFinished = (window) => - isBrowser(window) && - window.gBrowserInit && - window.gBrowserInit.delayedStartupFinished; - -exports.isStartupFinished = isStartupFinished; - -const isXULDocumentWindow = ({document}) => - document.documentElement && - document.documentElement.namespaceURI === XUL_NS; - -/** - * Check if the given window is completely loaded. - * i.e. if its "load" event has already been fired and all possible DOM content - * is done loading (the whole DOM document, images content, ...) - * @params {nsIDOMWindow} window - */ -function isDocumentLoaded(window) { - return window.document.readyState == "complete"; -} -exports.isDocumentLoaded = isDocumentLoaded; - -function isBrowser(window) { - try { - return window.document.documentElement.getAttribute("windowtype") === BROWSER; - } - catch (e) {} - return false; -}; -exports.isBrowser = isBrowser; - -function getWindowTitle(window) { - return window && window.document ? window.document.title : null; -} -exports.getWindowTitle = getWindowTitle; - -function isXULBrowser(window) { - return !!(isBrowser(window) && window.XULBrowserWindow); -} -exports.isXULBrowser = isXULBrowser; - -/** - * Returns the most recent focused window - */ -function getFocusedWindow() { - let window = WM.getMostRecentWindow(BROWSER); - - return window ? window.document.commandDispatcher.focusedWindow : null; -} -exports.getFocusedWindow = getFocusedWindow; - -/** - * Returns the focused browser window if any, or the most recent one. - * Opening new window, updates most recent window, but focus window - * changes later; so most recent window and focused window are not always - * the same. - */ -function getFocusedBrowser() { - let window = FM.activeWindow; - return isBrowser(window) ? window : getMostRecentBrowserWindow() -} -exports.getFocusedBrowser = getFocusedBrowser; - -/** - * Returns the focused element in the most recent focused window - */ -function getFocusedElement() { - let window = WM.getMostRecentWindow(BROWSER); - - return window ? window.document.commandDispatcher.focusedElement : null; -} -exports.getFocusedElement = getFocusedElement; - -function getFrames(window) { - return Array.slice(window.frames).reduce(function(frames, frame) { - return frames.concat(frame, getFrames(frame)); - }, []); -} -exports.getFrames = getFrames; - -function getScreenPixelsPerCSSPixel(window) { - return window.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindowUtils).screenPixelsPerCSSPixel; -} -exports.getScreenPixelsPerCSSPixel = getScreenPixelsPerCSSPixel; - -function getOwnerBrowserWindow(node) { - /** - Takes DOM node and returns browser window that contains it. - **/ - let window = getToplevelWindow(node.ownerDocument.defaultView); - // If anchored window is browser then it's target browser window. - return isBrowser(window) ? window : null; -} -exports.getOwnerBrowserWindow = getOwnerBrowserWindow; - -function getParentWindow(window) { - try { - return window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem).parent - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); - } - catch (e) {} - return null; -} -exports.getParentWindow = getParentWindow; - - -function getParentFrame(window) { - try { - return window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem).parent - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); - } - catch (e) {} - return null; -} -exports.getParentWindow = getParentWindow; - -// The element in which the window is embedded, or `null` -// if the window is top-level. Similar to `window.frameElement` -// but can cross chrome-content boundries. -const getFrameElement = target => - (target instanceof Ci.nsIDOMDocument ? target.defaultView : target). - QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindowUtils). - containerElement; -exports.getFrameElement = getFrameElement; |