forked from mirrors/gecko-dev
This patch was autogenerated by my decomponents.py
It covers almost every file with the extension js, jsm, html, py,
xhtml, or xul.
It removes blank lines after removed lines, when the removed lines are
preceded by either blank lines or the start of a new block. The "start
of a new block" is defined fairly hackily: either the line starts with
//, ends with */, ends with {, <![CDATA[, """ or '''. The first two
cover comments, the third one covers JS, the fourth covers JS embedded
in XUL, and the final two cover JS embedded in Python. This also
applies if the removed line was the first line of the file.
It covers the pattern matching cases like "var {classes: Cc,
interfaces: Ci, utils: Cu, results: Cr} = Components;". It'll remove
the entire thing if they are all either Ci, Cr, Cc or Cu, or it will
remove the appropriate ones and leave the residue behind. If there's
only one behind, then it will turn it into a normal, non-pattern
matching variable definition. (For instance, "const { classes: Cc,
Constructor: CC, interfaces: Ci, utils: Cu } = Components" becomes
"const CC = Components.Constructor".)
MozReview-Commit-ID: DeSHcClQ7cG
--HG--
extra : rebase_source : d9c41878036c1ef7766ef5e91a7005025bc1d72b
156 lines
5.4 KiB
JavaScript
156 lines
5.4 KiB
JavaScript
/* 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/. */
|
|
|
|
const Cm = Components.manager;
|
|
Cm.QueryInterface(Ci.nsIServiceManager);
|
|
|
|
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
|
|
|
let firstPaintNotification = "widget-first-paint";
|
|
// widget-first-paint fires much later than expected on Linux.
|
|
if (AppConstants.platform == "linux")
|
|
firstPaintNotification = "xul-window-visible";
|
|
|
|
let win, canvas;
|
|
let paints = [];
|
|
let afterPaintListener = () => {
|
|
let width, height;
|
|
canvas.width = width = win.innerWidth;
|
|
canvas.height = height = win.innerHeight;
|
|
if (width < 1 || height < 1)
|
|
return;
|
|
let ctx = canvas.getContext("2d", {alpha: false, willReadFrequently: true});
|
|
|
|
ctx.drawWindow(win, 0, 0, width, height, "white",
|
|
ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_VIEW |
|
|
ctx.DRAWWINDOW_ASYNC_DECODE_IMAGES |
|
|
ctx.DRAWWINDOW_USE_WIDGET_LAYERS);
|
|
paints.push({data: ctx.getImageData(0, 0, width, height).data,
|
|
width, height});
|
|
};
|
|
|
|
/**
|
|
* The startupRecorder component observes notifications at various stages of
|
|
* startup and records the set of JS components and modules that were already
|
|
* loaded at each of these points.
|
|
* The records are meant to be used by startup tests in
|
|
* browser/base/content/test/performance
|
|
* This component only exists in nightly and debug builds, it doesn't ship in
|
|
* our release builds.
|
|
*/
|
|
function startupRecorder() {
|
|
this.wrappedJSObject = this;
|
|
this.loader = Cc["@mozilla.org/moz/jsloader;1"].getService(Ci.xpcIJSModuleLoader);
|
|
this.data = {
|
|
images: {
|
|
"image-drawing": new Set(),
|
|
"image-loading": new Set(),
|
|
},
|
|
code: {}
|
|
};
|
|
this.done = new Promise(resolve => { this._resolve = resolve; });
|
|
}
|
|
startupRecorder.prototype = {
|
|
classID: Components.ID("{11c095b2-e42e-4bdf-9dd0-aed87595f6a4}"),
|
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
|
|
|
record(name) {
|
|
if (!Services.prefs.getBoolPref("browser.startup.record", false))
|
|
return;
|
|
|
|
this.data.code[name] = {
|
|
components: this.loader.loadedComponents(),
|
|
modules: this.loader.loadedModules(),
|
|
services: Object.keys(Cc).filter(c => {
|
|
try {
|
|
return Cm.isServiceInstantiatedByContractID(c, Ci.nsISupports);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
})
|
|
};
|
|
},
|
|
|
|
observe(subject, topic, data) {
|
|
|
|
if (topic == "app-startup") {
|
|
// We can't ensure our observer will be called first or last, so the list of
|
|
// topics we observe here should avoid the topics used to trigger things
|
|
// during startup (eg. the topics observed by nsBrowserGlue.js).
|
|
let topics = [
|
|
"profile-do-change", // This catches stuff loaded during app-startup
|
|
"toplevel-window-ready", // Catches stuff from final-ui-startup
|
|
"image-loading",
|
|
"image-drawing",
|
|
firstPaintNotification,
|
|
"sessionstore-windows-restored",
|
|
];
|
|
for (let t of topics)
|
|
Services.obs.addObserver(this, t);
|
|
return;
|
|
}
|
|
|
|
if (topic == "image-drawing" || topic == "image-loading") {
|
|
this.data.images[topic].add(data);
|
|
return;
|
|
}
|
|
|
|
Services.obs.removeObserver(this, topic);
|
|
|
|
if (topic == firstPaintNotification &&
|
|
Services.prefs.getBoolPref("browser.startup.record", false)) {
|
|
win = Services.wm.getMostRecentWindow("navigator:browser");
|
|
canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml",
|
|
"canvas");
|
|
canvas.mozOpaque = true;
|
|
afterPaintListener();
|
|
win.addEventListener("MozAfterPaint", afterPaintListener);
|
|
}
|
|
|
|
if (topic == "sessionstore-windows-restored") {
|
|
if (!Services.prefs.getBoolPref("browser.startup.record", false)) {
|
|
this._resolve();
|
|
this._resolve = null;
|
|
return;
|
|
}
|
|
|
|
// We use idleDispatchToMainThread here to record the set of
|
|
// loaded scripts after we are fully done with startup and ready
|
|
// to react to user events.
|
|
Services.tm.dispatchToMainThread(
|
|
this.record.bind(this, "before handling user events"));
|
|
|
|
// 10 is an arbitrary value here, it needs to be at least 2 to avoid
|
|
// races with code initializing itself using idle callbacks.
|
|
(function waitForIdle(callback, count = 10) {
|
|
if (count)
|
|
Services.tm.idleDispatchToMainThread(() => waitForIdle(callback, count - 1));
|
|
else
|
|
callback();
|
|
})(() => {
|
|
this.record("before becoming idle");
|
|
Services.obs.removeObserver(this, "image-drawing");
|
|
Services.obs.removeObserver(this, "image-loading");
|
|
win.removeEventListener("MozAfterPaint", afterPaintListener);
|
|
win = null;
|
|
this.data.frames = paints;
|
|
paints = null;
|
|
this._resolve();
|
|
this._resolve = null;
|
|
});
|
|
} else {
|
|
const topicsToNames = {
|
|
"profile-do-change": "before profile selection",
|
|
"toplevel-window-ready": "before opening first browser window",
|
|
};
|
|
topicsToNames[firstPaintNotification] = "before first paint";
|
|
this.record(topicsToNames[topic]);
|
|
}
|
|
}
|
|
};
|
|
|
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([startupRecorder]);
|