/* 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/. */
// If we don't stub these functions out, React throws warnings in the console // upon being loaded.
let window = self;
window.requestAnimationFrame = () => {};
window.cancelAnimationFrame = () => {};
// ChromeUtils is defined inside of a Worker, but we don't want the // activity-stream.bundle.js to detect it when loading, since that results // in it attempting to import JSMs on load, which is not allowed in // a Worker. So we temporarily clear ChromeUtils so that activity-stream.bundle.js // thinks its being loaded in content scope. // // eslint-disable-next-line no-implicit-globals, no-global-assign
ChromeUtils = undefined;
let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
let Agent = {
_templates: null,
/** * Synchronously loads the template files off of the file * system, and returns them as an object. If the Worker has loaded * these templates before, a cached copy of the templates is returned * instead. * * @return Object * An object with the following properties: * * pageTemplate (String): * The template for the document markup. * * scriptTempate (String): * The template for the script.
*/
getOrCreateTemplates() { if (this._templates) { returnthis._templates;
}
const templateResources = new Map([
["pageTemplate", PAGE_TEMPLATE_RESOURCE_PATH],
["scriptTemplate", SCRIPT_TEMPLATE_RESOURCE_PATH],
]);
this._templates = {};
for (let [templateName, path] of templateResources) { const xhr = new XMLHttpRequest(); // Using a synchronous XHR in a worker is fine.
xhr.open("GET", path, false);
xhr.responseType = "text";
xhr.send(null); this._templates[templateName] = xhr.responseText;
}
returnthis._templates;
},
/** * Constructs the cached about:home document using ReactDOMServer. This will * be called when "construct" messages are sent to this PromiseWorker. * * @param state (Object) * The most recent Activity Stream Redux state. * @return Object * An object with the following properties: * * page (String): * The generated markup for the document. * * script (String): * The generated script for the document.
*/
construct(state) { // If anything in this function throws an exception, PromiseWorker // runs the risk of leaving the Promise associated with this method // forever unresolved. This is particularly bad when this method is // called via AsyncShutdown, since the forever unresolved Promise can // result in a AsyncShutdown timeout crash. // // To help ensure that no matter what, the Promise resolves with something, // we wrap the whole operation in a try/catch. try { returnthis._construct(state);
} catch (e) {
console.error("about:home startup cache construction failed:", e); return { page: null, script: null };
}
},
/** * Internal method that actually does the work of constructing the cached * about:home document using ReactDOMServer. This should be called from * `construct` only. * * @param state (Object) * The most recent Activity Stream Redux state. * @return Object * An object with the following properties: * * page (String): * The generated markup for the document. * * script (String): * The generated script for the document.
*/
_construct(state) {
state.App.isForStartupCache = true;
// ReactDOMServer.renderToString expects a Redux store to pull // the state from, so we mock out a minimal store implementation.
let fakeStore = {
getState() { return state;
},
dispatch() {},
};
let { pageTemplate, scriptTemplate } = this.getOrCreateTemplates();
let cacheTime = new Date().toUTCString();
let page = pageTemplate
.replace("{{ MARKUP }}", markup)
.replace("{{ CACHE_TIME }}", cacheTime);
let script = scriptTemplate.replace( "{{ STATE }}",
JSON.stringify(state, null, "\t")
);
return { page, script };
},
};
// This boilerplate connects the PromiseWorker to the Agent so // that messages from the main thread map to methods on the // Agent.
let worker = new PromiseWorker.AbstractWorker();
worker.dispatch = function (method, args = []) { return Agent[method](...args);
};
worker.postMessage = function (result, ...transfers) {
self.postMessage(result, ...transfers);
};
worker.close = function () {
self.close();
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.