/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* 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/. */
"use strict";
var USERSCRIPT_PREFNAME = "extensions.webextensions.userScripts.enabled"; var USERSCRIPT_DISABLED_ERRORMSG = `userScripts APIs are currently experimental and must be enabled with the ${USERSCRIPT_PREFNAME} preference.`;
var { DefaultMap, ExtensionError, getUniqueId } = ExtensionUtils;
/** * Represents a registered userScript in the child extension process. * * @param {ExtensionPageContextChild} context * The extension context which has registered the user script. * @param {string} scriptId * An unique id that represents the registered user script * (generated and used internally to identify it across the different processes).
*/ class UserScriptChild {
constructor({ context, scriptId, onScriptUnregister }) { this.context = context; this.scriptId = scriptId; this.onScriptUnregister = onScriptUnregister; this.unregistered = false;
}
// Returns the object with the "unregister" method for the legacy // MV2-only userScripts.register() method. return {
unregister: () => { return context.wrapPromise(this.unregister());
},
};
}
}
this.userScripts = classextends ExtensionAPI {
getAPI(context) { if (context.extension.manifestVersion !== 2) { // MV2 needs special argument processing, MV3 does not. return {};
} // Cache of the script code already converted into blob urls: // Map<textHash, blobURLs> const blobURLsByHash = new Map();
// Keep track of the userScript that are sharing the same blob urls, // so that we can revoke any blob url that is not used by a registered // userScripts: // Map<blobURL, Set<scriptId>> const userScriptsByBlobURL = new DefaultMap(() => new Set());
function revokeBlobURLs(scriptId, options) {
let revokedUrls = new Set();
for (let url of options.js) { if (userScriptsByBlobURL.has(url)) {
let scriptIds = userScriptsByBlobURL.get(url);
scriptIds.delete(scriptId);
// Remove all the removed urls from the map of known computed hashes. for (let [hash, url] of blobURLsByHash) { if (revokedUrls.has(url)) {
blobURLsByHash.delete(hash);
}
}
}
// Convert a script code string into a blob URL (and use a cached one // if the script hash is already associated to a blob URL). const getBlobURL = async (text, scriptId) => { // Compute the hash of the js code string and reuse the blob url if we already have // for the same hash. const buffer = await crypto.subtle.digest( "SHA-1", new TextEncoder().encode(text)
); const hash = String.fromCharCode(...new Uint16Array(buffer));
let blobURL = blobURLsByHash.get(hash);
if (blobURL) {
userScriptsByBlobURL.get(blobURL).add(scriptId); return blobURL;
}
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.