Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Bug 695143: Implement getTab and getBrowserWindow for getting high-level objects from low-level DOM windows. #880

Closed
wants to merge 3 commits into from

2 participants

@Mossop
Owner

No tests yet as I want to figure out if this is the API we're looking for. It implements getTab and getBrowserWindow in the low-level tabs/utils and window/utils modules then defines default implementations that accept an nsIDOMWindow and return the high level object for them. Works nicely but only issue is that window/utils has to require windows in order to ensure the default implementation is attached.

Does this look right to you @gozala?

@Mossop
Owner

Also added attempts to make getDOMWindow return the window for high-level tab and window objects, but it doesn't seem to work.

@Gozala
Owner

I thin this should mitigate issues with traits:

diff --git a/lib/sdk/tabs/tab-firefox.js b/lib/sdk/tabs/tab-firefox.js
index 5a8fbaa..93350ba 100644
--- a/lib/sdk/tabs/tab-firefox.js
+++ b/lib/sdk/tabs/tab-firefox.js
@@ -17,6 +17,8 @@ const viewNS = require('sdk/core/namespace').ns();
 // Array of the inner instances of all the wrapped tabs.
 const TABS = [];

+function getWindow() getOwnerWindow(this._window)
+
 /**
  * Trait used to create tab wrappers.
  */
@@ -36,6 +38,9 @@ const TabTrait = Trait.compose(EventEmitter, {
     this._tab = options.tab;
     // TODO: Remove this dependency
     let window = this.window = options.window || require('../windows').BrowserWindow({ window: getOwnerWindow(this._tab) });
+    let getTabDOMWindow = getDOMWindow.bind(this)
+    getDOMWindow.implement(this, getTabDOMWindow)
+    getDOMWindow.implement(this._public, getTabDOMWindow)

     // Setting event listener if was passed.
     for each (let type in EVENTS) {
@Gozala
Owner

To explain a little what happens here:

Traits are mess and outer API is actually this._public from the inner API. So this hack basically defines implementation on the instances of both representations on the instance itself. Unfortunately we can't really
use define since instanceof on trait instances is kind of broken.

@Mossop Mossop closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 20, 2013
  1. @Mossop

    Bug 695143: Implement getTab and getBrowserWindow for getting high-le…

    Mossop authored
    …vel objects from low-level DOM windows.
  2. @Mossop
  3. @Mossop

    Add some tests.

    Mossop authored
This page is out of date. Refresh to see the latest.
View
4 lib/sdk/deprecated/traits.js
@@ -115,9 +115,9 @@ function Composition(trait) {
return self._public;
}
defineProperties(Trait, {
- prototype: { value: freeze(create(TraitProto, {
+ prototype: { value: create(TraitProto, {
constructor: { value: constructor, writable: true }
- }))}, // writable is `true` to avoid getters in custom ES5
+ })}, // writable is `true` to avoid getters in custom ES5
displayName: { value: (trait.constructor || constructor).name },
compose: { value: compose, enumerable: true },
override: { value: override, enumerable: true },
View
19 lib/sdk/tabs/tab-firefox.js
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
+const { Ci } = require("chrome");
const { Trait } = require("../deprecated/traits");
const { EventEmitter } = require("../deprecated/events");
const { defer } = require("../lang/functional");
@@ -10,9 +11,10 @@ const { EVENTS } = require("./events");
const { getThumbnailURIForWindow } = require("../content/thumbnail");
const { getFaviconURIForLocation } = require("../io/data");
const { activateTab, getOwnerWindow, getBrowserForTab, getTabTitle, setTabTitle,
- getTabURL, setTabURL, getTabContentType, getTabId } = require('./utils');
+ getTabURL, setTabURL, getTabContentType, getTabId, getTab } = require('./utils');
const { getOwnerWindow: getPBOwnerWindow } = require('../private-browsing/window/utils');
const viewNS = require('sdk/core/namespace').ns();
+const { getDOMWindow } = require("sdk/window/utils");
// Array of the inner instances of all the wrapped tabs.
const TABS = [];
@@ -241,3 +243,18 @@ function Tab(options, existingOnly) {
}
Tab.prototype = TabTrait.prototype;
exports.Tab = Tab;
+
+getTab.define(function(obj) {
+ if (obj instanceof Ci.nsIDOMWindow) {
+ for (let tab of TABS) {
+ if (tab._browser.contentWindow == obj)
+ return tab;
+ }
+ }
+
+ return null;
+});
+
+getDOMWindow.define(TabTrait, function(tab) {
+ return tab._browser.contentWindow;
+});
View
2  lib/sdk/tabs/utils.js
@@ -16,6 +16,7 @@ const { Ci } = require('chrome');
const { defer } = require("../lang/functional");
const { windows, isBrowser } = require('../window/utils');
const { isPrivateBrowsingSupported } = require('../self');
+const { method } = require('method/core');
// Bug 834961: ignore private windows when they are not supported
function getWindows() windows(null, { includePrivate: isPrivateBrowsingSupported });
@@ -308,3 +309,4 @@ function getTabForBrowser(browser) {
}
exports.getTabForBrowser = getTabForBrowser;
+exports.getTab = method("getTab");
View
17 lib/sdk/window/utils.js
@@ -11,6 +11,7 @@ const { Cc, Ci } = require('chrome');
const array = require('../util/array');
const observers = require('../deprecated/observer-service');
const { defer } = require('sdk/core/promise');
+const { method } = require('method/core');
const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
getService(Ci.nsIWindowWatcher);
@@ -94,10 +95,16 @@ function getXULWindow(window) {
};
exports.getXULWindow = getXULWindow;
-function getDOMWindow(xulWindow) {
- return xulWindow.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindow);
-}
+let getDOMWindow = method("getDOMWindow");
+getDOMWindow.define(function (obj) {
+ if (obj instanceof Ci.nsIXULWindow) {
+ return xulWindow.QueryInterface(Ci.nsIInterfaceRequestor).
+ getInterface(Ci.nsIDOMWindow);
+ }
+
+ return null;
+})
+
exports.getDOMWindow = getDOMWindow;
/**
@@ -331,3 +338,5 @@ function getFrames(window) {
}, [])
}
exports.getFrames = getFrames;
+
+exports.getBrowserWindow = method("getBrowserWindow");
View
13 lib/sdk/windows/firefox.js
@@ -10,7 +10,7 @@ const { Cc, Ci, Cr } = require('chrome'),
{ WindowTabs, WindowTabTracker } = require('./tabs-firefox'),
{ WindowDom } = require('./dom'),
{ WindowLoader } = require('./loader'),
- { isBrowser, getWindowDocShell, windows: windowIterator } = require('../window/utils'),
+ { isBrowser, getWindowDocShell, windows: windowIterator, getBrowserWindow, getDOMWindow } = require('../window/utils'),
{ Options } = require('../tabs/common'),
apiUtils = require('../deprecated/api-utils'),
unload = require('../system/unload'),
@@ -122,6 +122,17 @@ function getRegisteredWindow(chromeWindow) {
return null;
}
+getBrowserWindow.define(function(obj) {
+ if (obj instanceof Ci.nsIDOMWindow)
+ return getRegisteredWindow(obj);
+
+ return null;
+});
+
+getDOMWindow.define(BrowserWindow, function(browserWindow) {
+ return browserWindow._window;
+});
+
/**
* Wrapper for `BrowserWindowTrait`. Creates new instance if wrapper for
* window doesn't exists yet. If wrapper already exists then returns it
View
21 test/test-window-utils.js
@@ -7,9 +7,10 @@ const windowUtils = require("sdk/deprecated/window-utils");
const timer = require("sdk/timers");
const { Cc, Ci } = require("chrome");
const { Loader } = require("sdk/test/loader");
-const { open, getFrames, getWindowTitle, onFocus } = require('sdk/window/utils');
+const { open, getFrames, getWindowTitle, onFocus, getDOMWindow, getMostRecentBrowserWindow, getBrowserWindow } = require('sdk/window/utils');
const { close } = require('sdk/window/helpers');
const { fromIterator: toArray } = require('sdk/util/array');
+const { browserWindows } = require('sdk/windows');
const WM = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
@@ -301,6 +302,24 @@ exports.testWindowIterator = function(assert, done) {
}, false);
};
+exports["test getBrowserWindow"] = function(assert) {
+ let window = browserWindows.activeWindow;
+ let chromeWindow = getMostRecentBrowserWindow();
+
+ assert.equal(getBrowserWindow(chromeWindow), window, "getBrowserWindow should have worked");
+}
+
+exports["test getDOMWindow"] = function(assert) {
+ let window = browserWindows.activeWindow;
+ let tab = window.tabs.activeTab;
+
+ let chromeWindow = getMostRecentBrowserWindow();
+ let contentWindow = chromeWindow.content;
+
+ assert.equal(getDOMWindow(window), chromeWindow, "getDOMWindow should have worked for a window");
+ assert.equal(getDOMWindow(tab), contentWindow, "getDOMWindow should have worked for a window");
+}
+
if (require("sdk/system/xul-app").is("Fennec")) {
module.exports = {
"test Unsupported Test": function UnsupportedTest (assert) {
Something went wrong with that request. Please try again.