Bug 1339483: Fix tab frame lookup performance issues. r?Mossop
MozReview-Commit-ID: Fvx1J8bpzGg
--- a/addon-sdk/source/lib/sdk/remote/child.js
+++ b/addon-sdk/source/lib/sdk/remote/child.js
@@ -127,48 +127,52 @@ function makeFrameEventListener(frame, c
var FRAME_ID = 0;
var tabMap = new Map();
const Frame = Class({
implements: [ Disposable ],
extends: EventTarget,
setup: function(contentFrame) {
// This ID should be unique for this loader across all processes
- ns(this).id = runtime.processID + ":" + FRAME_ID++;
+ let priv = ns(this);
+
+ priv.id = runtime.processID + ":" + FRAME_ID++;
- ns(this).contentFrame = contentFrame;
- ns(this).messageManager = contentFrame;
- ns(this).domListeners = [];
+ priv.contentFrame = contentFrame;
+ priv.messageManager = contentFrame;
+ priv.domListeners = [];
tabMap.set(contentFrame.docShell, this);
- ns(this).messageReceived = messageReceived.bind(this);
- ns(this).messageManager.addMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
+ priv.messageReceived = messageReceived.bind(this);
+ priv.messageManager.addMessageListener('sdk/remote/frame/message', priv.messageReceived);
this.port = new EventTarget();
definePort(this, 'sdk/remote/frame/message');
- ns(this).messageManager.sendAsyncMessage('sdk/remote/frame/attach', {
+ priv.messageManager.sendAsyncMessage('sdk/remote/frame/attach', {
loaderID,
- frameID: ns(this).id,
+ frameID: priv.id,
processID: runtime.processID
});
frames.attachItem(this);
},
dispose: function() {
+ let priv = ns(this);
+
emit(this, 'detach', this);
- for (let listener of ns(this).domListeners)
- ns(this).contentFrame.removeEventListener(...listener.args);
+ for (let listener of priv.domListeners)
+ priv.contentFrame.removeEventListener(...listener.args);
- ns(this).messageManager.removeMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
- tabMap.delete(ns(this).contentFrame.docShell);
- ns(this).contentFrame = null;
+ priv.messageManager.removeMessageListener('sdk/remote/frame/message', priv.messageReceived);
+ tabMap.delete(priv.contentFrame.docShell);
+ priv.contentFrame = null;
},
get content() {
return ns(this).contentFrame.content;
},
get isTab() {
let docShell = ns(this).contentFrame.docShell;
@@ -186,33 +190,37 @@ const Frame = Class({
// And check we can find a tab for the browser element directly.
let browser = docShell.chromeEventHandler;
let tab = require('../tabs/utils').getTabForBrowser(browser);
return !!tab;
}
},
addEventListener: function(...args) {
+ let priv = ns(this);
+
let listener = listenerFor(...args);
- if (arrayContainsListener(ns(this).domListeners, listener))
+ if (arrayContainsListener(priv.domListeners, listener))
return;
listener.registeredCallback = makeFrameEventListener(this, listener.callback);
- ns(this).domListeners.push(listener);
- ns(this).contentFrame.addEventListener(...listener.args);
+ priv.domListeners.push(listener);
+ priv.contentFrame.addEventListener(...listener.args);
},
removeEventListener: function(...args) {
- let listener = getListenerFromArray(ns(this).domListeners, listenerFor(...args));
+ let priv = ns(this);
+
+ let listener = getListenerFromArray(priv.domListeners, listenerFor(...args));
if (!listener)
return;
- removeListenerFromArray(ns(this).domListeners, listener);
- ns(this).contentFrame.removeEventListener(...listener.args);
+ removeListenerFromArray(priv.domListeners, listener);
+ priv.contentFrame.removeEventListener(...listener.args);
}
});
const FrameList = Class({
implements: [ EventParent, Disposable ],
extends: EventTarget,
setup: function() {
EventParent.prototype.initialize.call(this);
@@ -228,22 +236,20 @@ const FrameList = Class({
dispose: function() {
// The only case where we get destroyed is when the loader is unloaded in
// which case each frame will clean up its own event listeners.
ns(this).domListeners = null;
},
getFrameForWindow: function(window) {
- for (let frame of this) {
- if (frame.content == window)
- return frame;
- }
+ let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDocShell);
- return null;
+ return tabMap.get(docShell) || null;
},
addEventListener: function(...args) {
let listener = listenerFor(...args);
if (arrayContainsListener(ns(this).domListeners, listener))
return;
ns(this).domListeners.push(listener);