Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #865 from erikvold/stabilization
Browse files Browse the repository at this point in the history
Bug 841823: Stabilization branch updates for minimal support of per window private browsing. r=me
  • Loading branch information
KWierso committed Mar 18, 2013
2 parents b2e31f9 + 2f4a772 commit 9bb245f
Show file tree
Hide file tree
Showing 26 changed files with 1,223 additions and 199 deletions.
6 changes: 4 additions & 2 deletions data/test-iframe.js
@@ -1,9 +1,11 @@

var count = 0
var count = 0;

setTimeout(function() {
window.addEventListener("message", function(msg) {
if (++count > 1) self.postMessage(msg.data);
if (++count > 1) {
self.postMessage(msg.data);
}
else msg.source.postMessage(msg.data, '*');
});

Expand Down
8 changes: 7 additions & 1 deletion lib/sdk/content/symbiont.js
Expand Up @@ -15,6 +15,7 @@ const hiddenFrames = require('../frame/hidden-frame');
const observers = require('../deprecated/observer-service');
const unload = require('../system/unload');
const { getDocShell } = require("../frame/utils");
const { ignoreWindow } = require('../private-browsing/utils');

const assetsURI = require('../self').data.url();

Expand Down Expand Up @@ -107,6 +108,7 @@ const Symbiont = Worker.resolve({
this._unregisterListener();

this._frame = frame;

getDocShell(frame).allowJavascript = this.allow.script;
frame.setAttribute("src", this._contentURL);

Expand Down Expand Up @@ -142,8 +144,12 @@ const Symbiont = Worker.resolve({
this._loadEvent = 'start';
observers.add('document-element-inserted',
this._loadListener = function onStart(doc) {

let window = doc.defaultView;

if (ignoreWindow(window)) {
return;
}

if (window && window == frame.contentWindow) {
self._unregisterListener();
self._onInit();
Expand Down
7 changes: 7 additions & 0 deletions lib/sdk/page-mod.js
Expand Up @@ -25,6 +25,7 @@ const { isBrowser, getFrames } = require('./window/utils');
const { getTabs, getTabContentWindow, getTabForContentWindow,
getURI: getTabURI } = require('./tabs/utils');
const { has, hasAny } = require('./util/array');
const { ignoreWindow } = require('sdk/private-browsing/utils');

const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].
getService(Ci.nsIStyleSheetService);
Expand Down Expand Up @@ -353,6 +354,12 @@ const PageModManager = Registry.resolve({
if (!getTabForContentWindow(window))
return;

// When the tab is private, only addons with 'private-browsing' flag in
// their package.json can apply content script to private documents
if (ignoreWindow(window)) {
return;
}

for (let rule in RULES)
if (RULES[rule].test(document.URL))
this._emit(rule, window);
Expand Down
67 changes: 20 additions & 47 deletions lib/sdk/panel.js
@@ -1,7 +1,6 @@
/* 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";

// The panel module currently supports only Firefox.
Expand All @@ -13,24 +12,26 @@ module.metadata = {
}
};

const { Cc, Ci } = require("chrome");

const { Ci } = require("chrome");
const { validateOptions: valid } = require('./deprecated/api-utils');
const { Symbiont } = require('./content/content');
const { EventEmitter } = require('./deprecated/events');
const timer = require('./timers');
const { setTimeout } = require('./timers');
const runtime = require('./system/runtime');
const { getMostRecentBrowserWindow } = require('./window/utils');
const { getDocShell } = require("./frame/utils");

const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
getService(Ci.nsIWindowMediator);
const { getWindow } = require('./panel/window');
const { isPrivateBrowsingSupported } = require('./self');
const { isWindowPBSupported } = require('./private-browsing/utils');

const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
ON_SHOW = 'popupshown',
ON_HIDE = 'popuphidden',
validNumber = { is: ['number', 'undefined', 'null'] };

if (isPrivateBrowsingSupported && isWindowPBSupported) {
throw Error('The panel module cannot be used with per-window private browsing at the moment, see Bug 816257');
}

/**
* Emits show and hide events.
*/
Expand Down Expand Up @@ -115,7 +116,15 @@ const Panel = Symbiont.resolve({
/* Public API: Panel.show */
show: function show(anchor) {
anchor = anchor || null;
let document = getWindow(anchor).document;
let anchorWindow = getWindow(anchor);

// If there is no open window, or the anchor is in a private window
// then we will not be able to display the panel
if (!anchorWindow) {
return;
}

let document = anchorWindow.document;
let xulPanel = this._xulPanel;
if (!xulPanel) {
xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
Expand Down Expand Up @@ -143,6 +152,7 @@ const Panel = Symbiont.resolve({
frame.setAttribute('type', 'content');
frame.setAttribute('flex', '1');
frame.setAttribute('transparent', 'transparent');

if (runtime.OS === "Darwin") {
frame.style.borderRadius = "6px";
frame.style.padding = "1px";
Expand Down Expand Up @@ -203,7 +213,7 @@ const Panel = Symbiont.resolve({
// Wait for the XBL binding to be constructed
function waitForBinding() {
if (!xulPanel.openPopup) {
timer.setTimeout(waitForBinding, 50);
setTimeout(waitForBinding, 50);
return;
}
xulPanel.openPopup(anchor, position, x, y);
Expand Down Expand Up @@ -363,40 +373,3 @@ const Panel = Symbiont.resolve({
});
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 = getMostRecentBrowserWindow();

return window;
}

51 changes: 51 additions & 0 deletions lib/sdk/panel/window.js
@@ -0,0 +1,51 @@
/* 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 { getMostRecentBrowserWindow, windows: getWindows } = require('../window/utils');
const { ignoreWindow } = require('../private-browsing/utils');
const { isPrivateBrowsingSupported } = require('../self');

function getWindow(anchor) {
let window;
let windows = getWindows("navigator:browser", {
includePrivate: isPrivateBrowsingSupported
});

if (anchor) {
let anchorWindow = anchor.ownerDocument.defaultView.top;
let anchorDocument = anchorWindow.document;

// loop thru supported windows
for each(let enumWindow in windows) {
// 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 = getMostRecentBrowserWindow();

// if the window is not supported, then it should be ignored
if (ignoreWindow(window)) {
return null;
}

return window;
}
exports.getWindow = getWindow;
13 changes: 12 additions & 1 deletion lib/sdk/private-browsing.js
Expand Up @@ -23,7 +23,7 @@ onStateChange('stop', function onStop() {
});

Object.defineProperty(exports, "isActive", {
get: deprecateFunction(getMode, 'require("private-browsing").isActive is deprecated.')
get: deprecateFunction(getMode, 'require("private-browsing").isActive is deprecated.')
});

exports.activate = function activate() setMode(true);
Expand All @@ -48,6 +48,17 @@ exports.isPrivate = function(thing) {
return true;
}

// does the thing have an associated tab?
// page-mod instances do..
if (thing.tab) {
let tabWindow = getOwnerWindow(thing.tab);
if (tabWindow) {
let isThingPrivate = isWindowPrivate(tabWindow);
if (isThingPrivate)
return isThingPrivate;
}
}

// can we find an associated window?
let window = getOwnerWindow(thing);
if (window)
Expand Down
43 changes: 37 additions & 6 deletions lib/sdk/selection.js
Expand Up @@ -18,10 +18,10 @@ const { Ci, Cc } = require("chrome"),
{ EventTarget } = require("./event/target"),
{ ns } = require("./core/namespace"),
{ when: unload } = require("./system/unload"),
{ ignoreWindow } = require('./private-browsing/utils'),
{ getTabs, getTabContentWindow, getTabForContentWindow,
getAllTabContentWindows } = require('./tabs/utils'),
{ getMostRecentBrowserWindow,
windows, getFocusedWindow, getFocusedElement } = require("./window/utils"),
winUtils = require("./window/utils"),
events = require("./system/events");

// The selection types
Expand Down Expand Up @@ -101,7 +101,10 @@ const selectionListener = {
*/
function iterator() {
let selection = getSelection(DOM);
let count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);
let count = 0;

if (selection)
count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);

for (let i = 0; i < count; i++) {
let sel = Selection(i);
Expand All @@ -116,6 +119,33 @@ const selectionIterator = obscure({
iterator: iterator // for....of
});

/**
* Returns the most recent focused window.
* if private browsing window is most recent and not supported,
* then ignore it and return `null`, because the focused window
* can't be targeted.
*/
function getFocusedWindow() {
let window = winUtils.getFocusedWindow();

return ignoreWindow(window) ? null : window;
}

/**
* Returns the focused element in the most recent focused window
* if private browsing window is most recent and not supported,
* then ignore it and return `null`, because the focused element
* can't be targeted.
*/
function getFocusedElement() {
let element = winUtils.getFocusedElement();

if (!element || ignoreWindow(element.ownerDocument.defaultView))
return null;

return element;
}

/**
* Returns the current selection from most recent content window. Depending on
* the specified |type|, the value returned can be a string of text, stringified
Expand Down Expand Up @@ -348,10 +378,11 @@ function removeSelectionListener(window) {
function onContent(event) {
let window = event.subject.defaultView;

// We are not interested in documents without valid defaultView (e.g. XML), or
// not in a tab (e.g. Panel).
if (window && getTabForContentWindow(window))
// We are not interested in documents without valid defaultView (e.g. XML)
// that aren't in a tab (e.g. Panel); or in private windows
if (window && getTabForContentWindow(window) && !ignoreWindow(window)) {
addSelectionListener(window);
}
}

// Adds Selection listener to new documents
Expand Down
5 changes: 4 additions & 1 deletion lib/sdk/tabs/common.js
Expand Up @@ -11,7 +11,10 @@ function Options(options) {

return validateOptions(options, {
url: { is: ["string"] },
inBackground: { is: ["undefined", "boolean"] },
inBackground: {
map: function(v) !!v,
is: ["undefined", "boolean"]
},
isPinned: { is: ["undefined", "boolean"] },
isPrivate: { is: ["undefined", "boolean"] },
onOpen: { is: ["undefined", "function"] },
Expand Down
28 changes: 26 additions & 2 deletions lib/sdk/tabs/helpers.js
Expand Up @@ -3,15 +3,39 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';

const { getTabForContentWindow } = require('./utils');
module.metadata = {
'stability': 'unstable'
};


// NOTE: This file should only export Tab instances


const { getTabForContentWindow, getTabForBrowser: getRawTabForBrowser } = require('./utils');
const { Tab } = require('./tab');
const { rawTabNS } = require('./namespace');

function getTabForWindow(win) {
let tab = getTabForContentWindow(win);
// We were unable to find the related tab!
if (!tab)
return null;

return Tab({ tab: tab });
return getTabForRawTab(tab) || Tab({ tab: tab });
}
exports.getTabForWindow = getTabForWindow;

// only works on fennec atm
function getTabForRawTab(rawTab) {
let tab = rawTabNS(rawTab).tab;
if (tab) {
return tab;
}
return null;
}
exports.getTabForRawTab = getTabForRawTab;

function getTabForBrowser(browser) {
return getTabForRawTab(getRawTabForBrowser(browser));
}
exports.getTabForBrowser = getTabForBrowser;
1 change: 1 addition & 0 deletions lib/sdk/tabs/namespace.js
Expand Up @@ -7,3 +7,4 @@ let { ns } = require('../core/namespace');

exports.tabsNS = ns();
exports.tabNS = ns();
exports.rawTabNS = ns();

0 comments on commit 9bb245f

Please sign in to comment.