Bug 1358415: Don't trigger reflow just to compute tab geometry. r=aswan

MozReview-Commit-ID: DnFSbDfOskT

--HG--
extra : rebase_source : e6829657b250fa8ec893b3e73b7d9956dfe34424
extra : amend_source : f20cfab374b29b7d3475579a0fe5e11ab2e6dcb4
This commit is contained in:
Kris Maglione 2017-04-21 13:22:34 -07:00
Родитель d66d8cc636
Коммит f5b580e5e9
3 изменённых файлов: 47 добавлений и 10 удалений

Просмотреть файл

@ -112,7 +112,7 @@ this.tabs = class extends ExtensionAPI {
onCreated: new SingletonEventManager(context, "tabs.onCreated", fire => {
let listener = (eventName, event) => {
fire.async(tabManager.convert(event.nativeTab));
fire.async(tabManager.convert(event.nativeTab, event.currentTab));
};
tabTracker.on("tab-created", listener);
@ -360,6 +360,7 @@ this.tabs = class extends ExtensionAPI {
options.disallowInheritPrincipal = true;
tabListener.initTabReady();
let currentTab = window.gBrowser.selectedTab;
let nativeTab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL, options);
let active = true;
@ -394,7 +395,7 @@ this.tabs = class extends ExtensionAPI {
tabListener.initializingTabs.add(nativeTab);
}
return tabManager.convert(nativeTab);
return tabManager.convert(nativeTab, currentTab);
});
},

Просмотреть файл

@ -238,13 +238,18 @@ class TabTracker extends TabTrackerBase {
});
}
// Save the current tab, since the newly-created tab will likely be
// active by the time the promise below resolves and the event is
// dispatched.
let currentTab = nativeTab.ownerGlobal.gBrowser.selectedTab;
// We need to delay sending this event until the next tick, since the
// tab does not have its final index when the TabOpen event is dispatched.
Promise.resolve().then(() => {
if (event.detail.adoptedTab) {
this.emitAttached(event.originalTarget);
} else {
this.emitCreated(event.originalTarget);
this.emitCreated(event.originalTarget, currentTab);
}
});
break;
@ -389,10 +394,12 @@ class TabTracker extends TabTrackerBase {
*
* @param {NativeTab} nativeTab
* The tab element which is being created.
* @param {NativeTab} [currentTab]
* The tab element for the currently active tab.
* @private
*/
emitCreated(nativeTab) {
this.emit("tab-created", {nativeTab});
emitCreated(nativeTab, currentTab) {
this.emit("tab-created", {nativeTab, currentTab});
}
/**
@ -479,12 +486,18 @@ class Tab extends TabBase {
return this.nativeTab.linkedBrowser;
}
get frameLoader() {
// If we don't have a frameLoader yet, just return a dummy with no width and
// height.
return super.frameLoader || {lazyWidth: 0, lazyHeight: 0};
}
get cookieStoreId() {
return getCookieStoreIdForTab(this, this.nativeTab);
}
get height() {
return this.browser.clientHeight;
return this.frameLoader.lazyHeight;
}
get index() {
@ -525,7 +538,7 @@ class Tab extends TabBase {
}
get width() {
return this.browser.clientWidth;
return this.frameLoader.lazyWidth;
}
get window() {

Просмотреть файл

@ -284,6 +284,15 @@ class TabBase {
throw new Error("Not implemented");
}
/**
* @property {nsIFrameLoader} browser
* Returns the frameloader for the given tab.
* @readonly
*/
get frameLoader() {
return this.browser.frameLoader;
}
/**
* @property {string} cookieStoreId
* Returns the cookie store identifier for the given tab.
@ -454,9 +463,12 @@ class TabBase {
* of its properties which the extension is permitted to access, in the format
* requried to be returned by WebExtension APIs.
*
* @param {Tab} [fallbackTab]
* A tab to retrieve geometry data from if the lazy geometry data for
* this tab hasn't been initialized yet.
* @returns {object}
*/
convert() {
convert(fallbackTab = null) {
let result = {
id: this.id,
index: this.index,
@ -472,6 +484,13 @@ class TabBase {
mutedInfo: this.mutedInfo,
};
// If the tab has not been fully layed-out yet, fallback to the geometry
// from a different tab (usually the currently active tab).
if (fallbackTab && (!result.width || !result.height)) {
result.width = fallbackTab.width;
result.height = fallbackTab.height;
}
if (this.extension.hasPermission("cookies")) {
result.cookieStoreId = this.cookieStoreId;
}
@ -1632,11 +1651,15 @@ class TabManagerBase {
*
* @param {NativeTab} nativeTab
* The native tab to convert.
* @param {NativeTab} [fallbackTab]
* A tab to retrieve geometry data from if the lazy geometry data for
* this tab hasn't been initialized yet.
*
* @returns {Object}
*/
convert(nativeTab) {
return this.getWrapper(nativeTab).convert();
convert(nativeTab, fallbackTab = null) {
return this.getWrapper(nativeTab)
.convert(fallbackTab && this.getWrapper(fallbackTab));
}
// The JSDoc validator does not support @returns tags in abstract functions or