mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Backed out changeset f55ff90f2b6f (bug 1044736)
This commit is contained in:
parent
00d6e9f501
commit
b2fad0e589
@ -8,10 +8,122 @@ const {utils: Cu, interfaces: Ci} = Components;
|
|||||||
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/BrowserElementParent.jsm");
|
|
||||||
|
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
|
||||||
|
const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "BrowserElementParentBuilder",
|
||||||
|
"resource://gre/modules/BrowserElementParent.jsm",
|
||||||
|
"BrowserElementParentBuilder");
|
||||||
|
|
||||||
|
function debug(msg) {
|
||||||
|
//dump("BrowserElementParent.js - " + msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BrowserElementParent implements one half of <iframe mozbrowser>. (The other
|
* BrowserElementParent implements one half of <iframe mozbrowser>. (The other
|
||||||
* half is, unsurprisingly, BrowserElementChild.)
|
* half is, unsurprisingly, BrowserElementChild.)
|
||||||
|
*
|
||||||
|
* BrowserElementParentFactory detects when we create a windows or docshell
|
||||||
|
* contained inside a <iframe mozbrowser> and creates a BrowserElementParent
|
||||||
|
* object for that window.
|
||||||
|
*
|
||||||
|
* It creates a BrowserElementParent that injects script to listen for
|
||||||
|
* certain event.
|
||||||
*/
|
*/
|
||||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParent]);
|
|
||||||
|
function BrowserElementParentFactory() {
|
||||||
|
this._initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserElementParentFactory.prototype = {
|
||||||
|
classID: Components.ID("{ddeafdac-cb39-47c4-9cb8-c9027ee36d26}"),
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||||
|
Ci.nsISupportsWeakReference]),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on app startup, and also when the browser frames enabled pref is
|
||||||
|
* changed.
|
||||||
|
*/
|
||||||
|
_init: function() {
|
||||||
|
if (this._initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the pref is disabled, do nothing except wait for the pref to change.
|
||||||
|
// (This is important for tests, if nothing else.)
|
||||||
|
if (!this._browserFramesPrefEnabled()) {
|
||||||
|
Services.prefs.addObserver(BROWSER_FRAMES_ENABLED_PREF, this, /* ownsWeak = */ true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("_init");
|
||||||
|
this._initialized = true;
|
||||||
|
|
||||||
|
// Maps frame elements to BrowserElementParent objects. We never look up
|
||||||
|
// anything in this map; the purpose is to keep the BrowserElementParent
|
||||||
|
// alive for as long as its frame element lives.
|
||||||
|
this._bepMap = new WeakMap();
|
||||||
|
|
||||||
|
Services.obs.addObserver(this, 'remote-browser-pending', /* ownsWeak = */ true);
|
||||||
|
Services.obs.addObserver(this, 'inprocess-browser-shown', /* ownsWeak = */ true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_browserFramesPrefEnabled: function() {
|
||||||
|
try {
|
||||||
|
return Services.prefs.getBoolPref(BROWSER_FRAMES_ENABLED_PREF);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_observeInProcessBrowserFrameShown: function(frameLoader) {
|
||||||
|
// Ignore notifications that aren't from a BrowserOrApp
|
||||||
|
if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug("In-process browser frame shown " + frameLoader);
|
||||||
|
this._createBrowserElementParent(frameLoader,
|
||||||
|
/* hasRemoteFrame = */ false,
|
||||||
|
/* pending frame */ false);
|
||||||
|
},
|
||||||
|
|
||||||
|
_observeRemoteBrowserFramePending: function(frameLoader) {
|
||||||
|
// Ignore notifications that aren't from a BrowserOrApp
|
||||||
|
if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug("Remote browser frame shown " + frameLoader);
|
||||||
|
this._createBrowserElementParent(frameLoader,
|
||||||
|
/* hasRemoteFrame = */ true,
|
||||||
|
/* pending frame */ true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_createBrowserElementParent: function(frameLoader, hasRemoteFrame, isPendingFrame) {
|
||||||
|
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||||
|
this._bepMap.set(frameElement, BrowserElementParentBuilder.create(
|
||||||
|
frameLoader, hasRemoteFrame, isPendingFrame));
|
||||||
|
},
|
||||||
|
|
||||||
|
observe: function(subject, topic, data) {
|
||||||
|
switch(topic) {
|
||||||
|
case 'app-startup':
|
||||||
|
this._init();
|
||||||
|
break;
|
||||||
|
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
|
||||||
|
if (data == BROWSER_FRAMES_ENABLED_PREF) {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'remote-browser-pending':
|
||||||
|
this._observeRemoteBrowserFramePending(subject);
|
||||||
|
break;
|
||||||
|
case 'inprocess-browser-shown':
|
||||||
|
this._observeInProcessBrowserFrameShown(subject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParentFactory]);
|
||||||
|
@ -14,7 +14,7 @@ let Cr = Components.results;
|
|||||||
* appropriate action here in the parent.
|
* appropriate action here in the parent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["BrowserElementParent"];
|
this.EXPORTED_SYMBOLS = ["BrowserElementParentBuilder"];
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
@ -25,8 +25,10 @@ XPCOMUtils.defineLazyGetter(this, "DOMApplicationRegistry", function () {
|
|||||||
return DOMApplicationRegistry;
|
return DOMApplicationRegistry;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TOUCH_EVENTS_ENABLED_PREF = "dom.w3c_touch_events.enabled";
|
||||||
|
|
||||||
function debug(msg) {
|
function debug(msg) {
|
||||||
//dump("BrowserElementParent - " + msg + "\n");
|
//dump("BrowserElementParent.jsm - " + msg + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIntPref(prefName, def) {
|
function getIntPref(prefName, def) {
|
||||||
@ -57,83 +59,138 @@ function visibilityChangeHandler(e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function defineNoReturnMethod(fn) {
|
this.BrowserElementParentBuilder = {
|
||||||
return function method() {
|
create: function create(frameLoader, hasRemoteFrame, isPendingFrame) {
|
||||||
if (!this._domRequestReady) {
|
return new BrowserElementParent(frameLoader, hasRemoteFrame);
|
||||||
// Remote browser haven't been created, we just queue the API call.
|
}
|
||||||
let args = Array.slice(arguments);
|
|
||||||
args.unshift(this);
|
|
||||||
this._pendingAPICalls.push(method.bind.apply(fn, args));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._isAlive()) {
|
|
||||||
fn.apply(this, arguments);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function defineDOMRequestMethod(msgName) {
|
function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
|
||||||
return function() {
|
debug("Creating new BrowserElementParent object for " + frameLoader);
|
||||||
return this._sendDOMRequest(msgName);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function BrowserElementParent() {
|
|
||||||
debug("Creating new BrowserElementParent object");
|
|
||||||
this._domRequestCounter = 0;
|
this._domRequestCounter = 0;
|
||||||
this._domRequestReady = false;
|
this._domRequestReady = false;
|
||||||
this._pendingAPICalls = [];
|
this._pendingAPICalls = [];
|
||||||
this._pendingDOMRequests = {};
|
this._pendingDOMRequests = {};
|
||||||
this._pendingSetInputMethodActive = [];
|
this._pendingSetInputMethodActive = [];
|
||||||
|
this._hasRemoteFrame = hasRemoteFrame;
|
||||||
this._nextPaintListeners = [];
|
this._nextPaintListeners = [];
|
||||||
|
|
||||||
|
this._frameLoader = frameLoader;
|
||||||
|
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||||
|
let self = this;
|
||||||
|
if (!this._frameElement) {
|
||||||
|
debug("No frame element?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Services.obs.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
|
Services.obs.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
|
||||||
Services.obs.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
|
Services.obs.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
|
||||||
Services.obs.addObserver(this, 'copypaste-docommand', /* ownsWeak = */ true);
|
Services.obs.addObserver(this, 'copypaste-docommand', /* ownsWeak = */ true);
|
||||||
|
|
||||||
|
let defineMethod = function(name, fn) {
|
||||||
|
XPCNativeWrapper.unwrap(self._frameElement)[name] = Cu.exportFunction(function() {
|
||||||
|
if (self._isAlive()) {
|
||||||
|
return fn.apply(self, arguments);
|
||||||
|
}
|
||||||
|
}, self._frameElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
let defineNoReturnMethod = function(name, fn) {
|
||||||
|
XPCNativeWrapper.unwrap(self._frameElement)[name] = Cu.exportFunction(function method() {
|
||||||
|
if (!self._domRequestReady) {
|
||||||
|
// Remote browser haven't been created, we just queue the API call.
|
||||||
|
let args = Array.slice(arguments);
|
||||||
|
args.unshift(self);
|
||||||
|
self._pendingAPICalls.push(method.bind.apply(fn, args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self._isAlive()) {
|
||||||
|
fn.apply(self, arguments);
|
||||||
|
}
|
||||||
|
}, self._frameElement);
|
||||||
|
};
|
||||||
|
|
||||||
|
let defineDOMRequestMethod = function(domName, msgName) {
|
||||||
|
XPCNativeWrapper.unwrap(self._frameElement)[domName] = Cu.exportFunction(function() {
|
||||||
|
return self._sendDOMRequest(msgName);
|
||||||
|
}, self._frameElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define methods on the frame element.
|
||||||
|
defineNoReturnMethod('setVisible', this._setVisible);
|
||||||
|
defineDOMRequestMethod('getVisible', 'get-visible');
|
||||||
|
|
||||||
|
// Not expose security sensitive browser API for widgets
|
||||||
|
if (!this._frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsWidget) {
|
||||||
|
defineNoReturnMethod('sendMouseEvent', this._sendMouseEvent);
|
||||||
|
|
||||||
|
// 0 = disabled, 1 = enabled, 2 - auto detect
|
||||||
|
if (getIntPref(TOUCH_EVENTS_ENABLED_PREF, 0) != 0) {
|
||||||
|
defineNoReturnMethod('sendTouchEvent', this._sendTouchEvent);
|
||||||
|
}
|
||||||
|
defineNoReturnMethod('goBack', this._goBack);
|
||||||
|
defineNoReturnMethod('goForward', this._goForward);
|
||||||
|
defineNoReturnMethod('reload', this._reload);
|
||||||
|
defineNoReturnMethod('stop', this._stop);
|
||||||
|
defineMethod('download', this._download);
|
||||||
|
defineDOMRequestMethod('purgeHistory', 'purge-history');
|
||||||
|
defineMethod('getScreenshot', this._getScreenshot);
|
||||||
|
defineNoReturnMethod('zoom', this._zoom);
|
||||||
|
|
||||||
|
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||||
|
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||||
|
defineDOMRequestMethod('getContentDimensions', 'get-contentdimensions');
|
||||||
|
}
|
||||||
|
|
||||||
|
defineMethod('addNextPaintListener', this._addNextPaintListener);
|
||||||
|
defineMethod('removeNextPaintListener', this._removeNextPaintListener);
|
||||||
|
defineNoReturnMethod('setActive', this._setActive);
|
||||||
|
defineMethod('getActive', 'this._getActive');
|
||||||
|
|
||||||
|
let principal = this._frameElement.ownerDocument.nodePrincipal;
|
||||||
|
let perm = Services.perms
|
||||||
|
.testExactPermissionFromPrincipal(principal, "input-manage");
|
||||||
|
if (perm === Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
|
defineMethod('setInputMethodActive', this._setInputMethodActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen to visibilitychange on the iframe's owner window, and forward
|
||||||
|
// changes down to the child. We want to do this while registering as few
|
||||||
|
// visibilitychange listeners on _window as possible, because such a listener
|
||||||
|
// may live longer than this BrowserElementParent object.
|
||||||
|
//
|
||||||
|
// To accomplish this, we register just one listener on the window, and have
|
||||||
|
// it reference a WeakMap whose keys are all the BrowserElementParent objects
|
||||||
|
// on the window. Then when the listener fires, we iterate over the
|
||||||
|
// WeakMap's keys (which we can do, because we're chrome) to notify the
|
||||||
|
// BrowserElementParents.
|
||||||
|
if (!this._window._browserElementParents) {
|
||||||
|
this._window._browserElementParents = new WeakMap();
|
||||||
|
this._window.addEventListener('visibilitychange',
|
||||||
|
visibilityChangeHandler,
|
||||||
|
/* useCapture = */ false,
|
||||||
|
/* wantsUntrusted = */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._window._browserElementParents.set(this, null);
|
||||||
|
|
||||||
|
// Insert ourself into the prompt service.
|
||||||
|
BrowserElementPromptService.mapFrameToBrowserElementParent(this._frameElement, this);
|
||||||
|
if (!isPendingFrame) {
|
||||||
|
this._setupMessageListener();
|
||||||
|
this._registerAppManifest();
|
||||||
|
} else {
|
||||||
|
// if we are a pending frame, we setup message manager after
|
||||||
|
// observing remote-browser-frame-shown
|
||||||
|
Services.obs.addObserver(this, 'remote-browser-frame-shown', /* ownsWeak = */ true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserElementParent.prototype = {
|
BrowserElementParent.prototype = {
|
||||||
|
|
||||||
classDescription: "BrowserElementAPI implementation",
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||||
classID: Components.ID("{9f171ac4-0939-4ef8-b360-3408aedc3060}"),
|
|
||||||
contractID: "@mozilla.org/dom/browser-element-api;1",
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserElementAPI,
|
|
||||||
Ci.nsIObserver,
|
|
||||||
Ci.nsISupportsWeakReference]),
|
Ci.nsISupportsWeakReference]),
|
||||||
|
|
||||||
setFrameLoader: function(frameLoader) {
|
|
||||||
this._frameLoader = frameLoader;
|
|
||||||
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
|
||||||
if (!this._frameElement) {
|
|
||||||
debug("No frame element?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Listen to visibilitychange on the iframe's owner window, and forward
|
|
||||||
// changes down to the child. We want to do this while registering as few
|
|
||||||
// visibilitychange listeners on _window as possible, because such a listener
|
|
||||||
// may live longer than this BrowserElementParent object.
|
|
||||||
//
|
|
||||||
// To accomplish this, we register just one listener on the window, and have
|
|
||||||
// it reference a WeakMap whose keys are all the BrowserElementParent objects
|
|
||||||
// on the window. Then when the listener fires, we iterate over the
|
|
||||||
// WeakMap's keys (which we can do, because we're chrome) to notify the
|
|
||||||
// BrowserElementParents.
|
|
||||||
if (!this._window._browserElementParents) {
|
|
||||||
this._window._browserElementParents = new WeakMap();
|
|
||||||
this._window.addEventListener('visibilitychange',
|
|
||||||
visibilityChangeHandler,
|
|
||||||
/* useCapture = */ false,
|
|
||||||
/* wantsUntrusted = */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._window._browserElementParents.set(this, null);
|
|
||||||
|
|
||||||
// Insert ourself into the prompt service.
|
|
||||||
BrowserElementPromptService.mapFrameToBrowserElementParent(this._frameElement, this);
|
|
||||||
this._setupMessageListener();
|
|
||||||
this._registerAppManifest();
|
|
||||||
},
|
|
||||||
|
|
||||||
_runPendingAPICall: function() {
|
_runPendingAPICall: function() {
|
||||||
if (!this._pendingAPICalls) {
|
if (!this._pendingAPICalls) {
|
||||||
return;
|
return;
|
||||||
@ -535,27 +592,20 @@ BrowserElementParent.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisible: defineNoReturnMethod(function(visible) {
|
_setVisible: function(visible) {
|
||||||
this._sendAsyncMsg('set-visible', {visible: visible});
|
this._sendAsyncMsg('set-visible', {visible: visible});
|
||||||
this._frameLoader.visible = visible;
|
this._frameLoader.visible = visible;
|
||||||
}),
|
},
|
||||||
|
|
||||||
getVisible: defineDOMRequestMethod('get-visible'),
|
_setActive: function(active) {
|
||||||
|
|
||||||
setActive: defineNoReturnMethod(function(active) {
|
|
||||||
this._frameLoader.visible = active;
|
this._frameLoader.visible = active;
|
||||||
}),
|
},
|
||||||
|
|
||||||
getActive: function() {
|
|
||||||
if (!this._isAlive()) {
|
|
||||||
throw Components.Exception("Dead content process",
|
|
||||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_getActive: function() {
|
||||||
return this._frameLoader.visible;
|
return this._frameLoader.visible;
|
||||||
},
|
},
|
||||||
|
|
||||||
sendMouseEvent: defineNoReturnMethod(function(type, x, y, button, clickCount, modifiers) {
|
_sendMouseEvent: function(type, x, y, button, clickCount, modifiers) {
|
||||||
this._sendAsyncMsg("send-mouse-event", {
|
this._sendAsyncMsg("send-mouse-event", {
|
||||||
"type": type,
|
"type": type,
|
||||||
"x": x,
|
"x": x,
|
||||||
@ -564,11 +614,11 @@ BrowserElementParent.prototype = {
|
|||||||
"clickCount": clickCount,
|
"clickCount": clickCount,
|
||||||
"modifiers": modifiers
|
"modifiers": modifiers
|
||||||
});
|
});
|
||||||
}),
|
},
|
||||||
|
|
||||||
sendTouchEvent: defineNoReturnMethod(function(type, identifiers, touchesX, touchesY,
|
_sendTouchEvent: function(type, identifiers, touchesX, touchesY,
|
||||||
radiisX, radiisY, rotationAngles, forces,
|
radiisX, radiisY, rotationAngles, forces,
|
||||||
count, modifiers) {
|
count, modifiers) {
|
||||||
|
|
||||||
let tabParent = this._frameLoader.tabParent;
|
let tabParent = this._frameLoader.tabParent;
|
||||||
if (tabParent && tabParent.useAsyncPanZoom) {
|
if (tabParent && tabParent.useAsyncPanZoom) {
|
||||||
@ -596,45 +646,35 @@ BrowserElementParent.prototype = {
|
|||||||
"modifiers": modifiers
|
"modifiers": modifiers
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
|
|
||||||
getCanGoBack: defineDOMRequestMethod('get-can-go-back'),
|
_goBack: function() {
|
||||||
getCanGoForward: defineDOMRequestMethod('get-can-go-forward'),
|
|
||||||
getContentDimensions: defineDOMRequestMethod('get-contentdimensions'),
|
|
||||||
|
|
||||||
goBack: defineNoReturnMethod(function() {
|
|
||||||
this._sendAsyncMsg('go-back');
|
this._sendAsyncMsg('go-back');
|
||||||
}),
|
},
|
||||||
|
|
||||||
goForward: defineNoReturnMethod(function() {
|
_goForward: function() {
|
||||||
this._sendAsyncMsg('go-forward');
|
this._sendAsyncMsg('go-forward');
|
||||||
}),
|
},
|
||||||
|
|
||||||
reload: defineNoReturnMethod(function(hardReload) {
|
_reload: function(hardReload) {
|
||||||
this._sendAsyncMsg('reload', {hardReload: hardReload});
|
this._sendAsyncMsg('reload', {hardReload: hardReload});
|
||||||
}),
|
},
|
||||||
|
|
||||||
stop: defineNoReturnMethod(function() {
|
_stop: function() {
|
||||||
this._sendAsyncMsg('stop');
|
this._sendAsyncMsg('stop');
|
||||||
}),
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The valid range of zoom scale is defined in preference "zoom.maxPercent" and "zoom.minPercent".
|
* The valid range of zoom scale is defined in preference "zoom.maxPercent" and "zoom.minPercent".
|
||||||
*/
|
*/
|
||||||
zoom: defineNoReturnMethod(function(zoom) {
|
_zoom: function(zoom) {
|
||||||
zoom *= 100;
|
zoom *= 100;
|
||||||
zoom = Math.min(getIntPref("zoom.maxPercent", 300), zoom);
|
zoom = Math.min(getIntPref("zoom.maxPercent", 300), zoom);
|
||||||
zoom = Math.max(getIntPref("zoom.minPercent", 50), zoom);
|
zoom = Math.max(getIntPref("zoom.minPercent", 50), zoom);
|
||||||
this._sendAsyncMsg('zoom', {zoom: zoom / 100.0});
|
this._sendAsyncMsg('zoom', {zoom: zoom / 100.0});
|
||||||
}),
|
},
|
||||||
|
|
||||||
purgeHistory: defineDOMRequestMethod('purge-history'),
|
_download: function(_url, _options) {
|
||||||
|
|
||||||
|
|
||||||
download: function(_url, _options) {
|
|
||||||
if (!this._isAlive()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let ioService =
|
let ioService =
|
||||||
Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
|
Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
|
||||||
let uri = ioService.newURI(_url, null, null);
|
let uri = ioService.newURI(_url, null, null);
|
||||||
@ -754,12 +794,7 @@ BrowserElementParent.prototype = {
|
|||||||
return req;
|
return req;
|
||||||
},
|
},
|
||||||
|
|
||||||
getScreenshot: function(_width, _height, _mimeType) {
|
_getScreenshot: function(_width, _height, _mimeType) {
|
||||||
if (!this._isAlive()) {
|
|
||||||
throw Components.Exception("Dead content process",
|
|
||||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
let width = parseInt(_width);
|
let width = parseInt(_width);
|
||||||
let height = parseInt(_height);
|
let height = parseInt(_height);
|
||||||
let mimeType = (typeof _mimeType === 'string') ?
|
let mimeType = (typeof _mimeType === 'string') ?
|
||||||
@ -779,18 +814,16 @@ BrowserElementParent.prototype = {
|
|||||||
this._nextPaintListeners = [];
|
this._nextPaintListeners = [];
|
||||||
for (let listener of listeners) {
|
for (let listener of listeners) {
|
||||||
try {
|
try {
|
||||||
listener.recvNextPaint();
|
listener();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If a listener throws we'll continue.
|
// If a listener throws we'll continue.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addNextPaintListener: function(listener) {
|
_addNextPaintListener: function(listener) {
|
||||||
if (!this._isAlive()) {
|
if (typeof listener != 'function')
|
||||||
throw Components.Exception("Dead content process",
|
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
|
||||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
let run = function() {
|
let run = function() {
|
||||||
@ -804,11 +837,9 @@ BrowserElementParent.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeNextPaintListener: function(listener) {
|
_removeNextPaintListener: function(listener) {
|
||||||
if (!this._isAlive()) {
|
if (typeof listener != 'function')
|
||||||
throw Components.Exception("Dead content process",
|
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
|
||||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
let run = function() {
|
let run = function() {
|
||||||
@ -829,12 +860,7 @@ BrowserElementParent.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setInputMethodActive: function(isActive) {
|
_setInputMethodActive: function(isActive) {
|
||||||
if (!this._isAlive()) {
|
|
||||||
throw Components.Exception("Dead content process",
|
|
||||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof isActive !== 'boolean') {
|
if (typeof isActive !== 'boolean') {
|
||||||
throw Components.Exception("Invalid argument",
|
throw Components.Exception("Invalid argument",
|
||||||
Cr.NS_ERROR_INVALID_ARG);
|
Cr.NS_ERROR_INVALID_ARG);
|
||||||
@ -896,10 +922,18 @@ BrowserElementParent.prototype = {
|
|||||||
case 'ask-children-to-exit-fullscreen':
|
case 'ask-children-to-exit-fullscreen':
|
||||||
if (this._isAlive() &&
|
if (this._isAlive() &&
|
||||||
this._frameElement.ownerDocument == subject &&
|
this._frameElement.ownerDocument == subject &&
|
||||||
this._frameLoader.QueryInterface(Ci.nsIFrameLoader).tabParent) {
|
this._hasRemoteFrame) {
|
||||||
this._sendAsyncMsg('exit-fullscreen');
|
this._sendAsyncMsg('exit-fullscreen');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'remote-browser-frame-shown':
|
||||||
|
if (this._frameLoader == subject) {
|
||||||
|
if (!this._mm) {
|
||||||
|
this._setupMessageListener();
|
||||||
|
this._registerAppManifest();
|
||||||
|
}
|
||||||
|
Services.obs.removeObserver(this, 'remote-browser-frame-shown');
|
||||||
|
}
|
||||||
case 'copypaste-docommand':
|
case 'copypaste-docommand':
|
||||||
if (this._isAlive() && this._frameElement.isEqualNode(subject.wrappedJSObject)) {
|
if (this._isAlive() && this._frameElement.isEqualNode(subject.wrappedJSObject)) {
|
||||||
this._sendAsyncMsg('do-command', { command: data });
|
this._sendAsyncMsg('do-command', { command: data });
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
component {9f171ac4-0939-4ef8-b360-3408aedc3060} BrowserElementParent.js
|
component {ddeafdac-cb39-47c4-9cb8-c9027ee36d26} BrowserElementParent.js
|
||||||
contract @mozilla.org/dom/browser-element-api;1 {9f171ac4-0939-4ef8-b360-3408aedc3060}
|
contract @mozilla.org/browser-element-parent-factory;1 {ddeafdac-cb39-47c4-9cb8-c9027ee36d26}
|
||||||
|
category app-startup BrowserElementParentFactory service,@mozilla.org/browser-element-parent-factory;1
|
||||||
|
Loading…
Reference in New Issue
Block a user