Infocatcher / Custom_Buttons

Buttons for Custom Buttons extension for Firefox (and other Gecko-based applications)
38 stars 11 forks source link

How you can install custombuttons? #49

Closed sdavidg closed 4 years ago

sdavidg commented 4 years ago

I'm using ChromeJS with https://github.com/xiaoxiaoflood/firefox-scripts but I've seen that uses elements of the old extension, you can tell me how you can install the new Firefox?

Thank you

Infocatcher commented 4 years ago

There is fixed/updated versions by Dumby from forum.mozilla-russia.org. Not so trivial to find…

Required general.config.filename trick:

%Firefox_install_directory%\defaults\pref\config-prefs.js:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "config.js");
pref("general.config.sandbox_enabled", false);

%Firefox_install_directory%\config.js: (https://forum.mozilla-russia.org/viewtopic.php?pid=780458#p780458)

//
try {(nsvo => {
    var o = Cu.getGlobalForObject(nsvo).Object, {freeze} = o, NEW;
    o.freeze = obj => {
        if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm")
            return freeze(obj);
        obj.MOZ_REQUIRE_SIGNING = false;
        if ((NEW = "MOZ_ALLOW_ADDON_SIDELOAD" in obj))
            lockPref("extensions.experiments.enabled", true);
        else
            obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true,
            lockPref("extensions.legacy.enabled", true);

        return (o.freeze = freeze)(obj);
    }
    lockPref("xpinstall.signatures.required", false);
    lockPref("extensions.langpacks.signatures.required", false);

    nsvo = Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {});
    var shouldVerify = nsvo.shouldVerifySignedState;
    nsvo.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);

    if (NEW) nsvo.XPIDatabase.isDisabledLegacy = () => false;
})(
    "permitCPOWsInScope" in Cu
        ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu
);}
catch(ex) {Cu.reportError(ex);}

//
try {({
    ids: [
        "custombuttons@xsms.org",
    ],
    init(xrt) {
        if (xrt.inSafeMode) return;
        Cu.import("resource://gre/modules/addons/XPIProvider.jsm", this);
        var load = async file => {
            var rootURI = this.XPIInternal.getURIForResourceInFile(file, "");
            Cu.import(rootURI.resolve("startup.jsm"), {}).start(rootURI);
        }
        var proto = this.XPIInternal.BootstrapScope.prototype;
        var func = proto._beforeCallBootstrapMethod;

        proto._beforeCallBootstrapMethod = () => {
            proto._beforeCallBootstrapMethod = func;
            for(var addon of this.XPIInternal.XPIStates.enabledAddons())
                this.ids.includes(addon.id) && !addon.loader && load(addon.file);
        }
    }
}).init(Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime));}
catch(ex) {Cu.reportError(ex);}

Then install custom_buttons-0.0.7.0.0.16-fx-paxmod.xpi, restart required (https://forum.mozilla-russia.org/viewtopic.php?pid=783406#p783406)

Or also add bootstrap-loader.js content at the end of %Firefox_install_directory%\config.js file: (https://forum.mozilla-russia.org/viewtopic.php?pid=771479#p771479)

//
try {
    Cu.createDocumentEncoder && Cc["@mozilla.org/moz/jssubscript-loader;1"]
        .getService(Ci.mozIJSSubScriptLoader).loadSubScript(String.raw`
            data:,var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");%0Avar {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");%0A%0Athis.lazyModules = {%0A%09OS: "resource://gre/modules/osfile.jsm",%0A%09Services: "resource://gre/modules/Services.jsm",%0A%09ConsoleAPI: "resource://gre/modules/Console.jsm",%0A%09Blocklist: "resource://gre/modules/Blocklist.jsm",%0A%09AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm"%0A};%0Aif ("@mozilla.org/intl/domlocalization;1" in Cc)%0A%09this.lazyModules.RDFDataSource = "resource://gre/modules/addons/RDFDataSource.jsm";%0Aelse%0A%09// Firefox 67+%0A%09// Bug 1523194 - Remove XPIDL for DOMLocalization and use do_ImportModule instead%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1523194%0A%09//%0A%09// Bug 857458 - Remove support for update.rdf%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=857458%0A%0A%09XPCOMUtils.defineLazyGetter(this, "RDFDataSource", () => {%0A%09%09var obs = {};%0A%09%09var scs = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService);%0A%09%09var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);%0A%09%09var sl =  Cc["@mozilla.org/network/stream-loader;1"].createInstance(Ci.nsIStreamLoader);%0A%0A%09%09var gzip = "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";%0A%09%09sis.data = atob(gzip);%0A%09%09obs.onStreamComplete = (a, b, c, d, result) => Cu.evalInSandbox(String.fromCharCode(...result), this);%0A%09%09sl.init(obs);%0A%09%09var converter = scs.asyncConvertData("gzip", "uncompressed", sl, null);%0A%09%09converter.onStartRequest(null, null);%0A%0A%09%09var args = [null, null, sis, 0, sis.data.length];%0A%09%09// Bug 1525319 - Investigate if we can remove Context argument from Channel methods (Firefox 67+)%0A%09%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1525319%0A%09%09if (converter.onDataAvailable.length == 4) args.shift();%0A%09%09converter.onDataAvailable(...args);%0A%0A%09%09converter.onStopRequest(null, null, null);%0A%0A%09%09return RDFDataSource;%0A%09});%0AXPCOMUtils.defineLazyModuleGetters(this, this.lazyModules);%0Adelete this.lazyModules;%0A%0AXPCOMUtils.defineLazyGetter(this, "BOOTSTRAP_REASONS", () =>%0A%09ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {})%0A%09%09.XPIProvider.BOOTSTRAP_REASONS%0A);%0AXPCOMUtils.defineLazyGetter(this, "logger", () =>%0A%09ChromeUtils.import("resource://gre/modules/Log.jsm", {})%0A%09%09.Log.repository.getLogger("addons.bootstrap")%0A);%0A%0A%0A// RDFManifestConverter.jsm%0Aconst RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";%0A%0Afunction EM_R(aProperty) {%0A%09return %60http://www.mozilla.org/2004/em-rdf%23%24{aProperty}%60;%0A}%0Afunction getValue(literal) {%0A%09return literal && literal.getValue();%0A}%0Afunction getProperty(resource, property) {%0A%09return getValue(resource.getProperty(EM_R(property)));%0A}%0A%0Aclass Manifest {%0A%09constructor(ds) {%0A%09%09this.ds = ds;%0A%09}%0A%09static loadFromString(text) {%0A%09%09return new this(RDFDataSource.loadFromString(text));%0A%09}%0A%09static loadFromBuffer(buffer) {%0A%09%09return new this(RDFDataSource.loadFromBuffer(buffer));%0A%09}%0A%09static async loadFromFile(uri) {%0A%09%09return new this(await RDFDataSource.loadFromFile(uri));%0A%09}%0A}%0A%0Aclass InstallRDF extends Manifest {%0A%09_readProps(source, obj, props) {%0A%09%09for (let prop of props) {%0A%09%09%09let val = getProperty(source, prop);%0A%09%09%09if (val != null) {%0A%09%09%09%09obj[prop] = val;%0A%09%09%09}%0A%09%09}%0A%09}%0A%09_readArrayProp(source, obj, prop, target, decode = getValue) {%0A%09%09let result = Array.from(%0A%09%09%09source.getObjects(EM_R(prop)), target => decode(target)%0A%09%09);%0A%09%09if (result.length) {%0A%09%09%09obj[target] = result;%0A%09%09}%0A%09}%0A%09_readArrayProps(source, obj, props, decode = getValue) {%0A%09%09for (let [prop, target] of Object.entries(props)) {%0A%09%09%09this._readArrayProp(source, obj, prop, target, decode);%0A%09%09}%0A%09}%0A%09_readLocaleStrings(source, obj) {%0A%09%09this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]);%0A%09%09this._readArrayProps(source, obj, {%0A%09%09%09locale: "locales",%0A%09%09%09developer: "developers",%0A%09%09%09translator: "translators",%0A%09%09%09contributor: "contributors",%0A%09%09});%0A%09}%0A%09decode() {%0A%09%09let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT);%0A%09%09let result = {};%0A%0A%09%09let props = [%0A%09%09%09"id", "version", "type", "updateURL", "optionsURL",%0A%09%09%09"optionsType", "aboutURL", "iconURL",%0A%09%09%09"bootstrap", "unpack", "strictCompatibility"%0A%09%09];%0A%09%09this._readProps(root, result, props);%0A%0A%09%09let decodeTargetApplication = source => {%0A%09%09%09let app = {maxVersion: "*"};%0A%09%09%09this._readProps(source, app, ["id", "minVersion"]);%0A%09%09%09return app;%0A%09%09};%0A%0A%09%09let decodeLocale = source => {%0A%09%09%09let localized = {};%0A%09%09%09this._readLocaleStrings(source, localized);%0A%09%09%09return localized;%0A%09%09};%0A%0A%09%09this._readLocaleStrings(root, result);%0A%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetPlatform": "targetPlatforms"}%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetApplication": "targetApplications"}, decodeTargetApplication%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"localized": "localized"}, decodeLocale%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"dependency": "dependencies"}, source => getProperty(source, "id")%0A%09%09);%0A%09%09return result;%0A%09}%0A}%0A// fim RDFManifestConverter.jsm%0A%0A%0A// BootstrapLoader.jsm%0A/**%0A * Valid IDs fit this pattern.%0A */%0Avar gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;%0A%0A// Properties that exist in the install manifest%0Aconst PROP_METADATA%09= [%0A%09"id", "version", "type", "internalName", "updateURL",%0A%09"optionsURL", "optionsType", "aboutURL", "iconURL"%0A];%0Aconst PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];%0Aconst PROP_LOCALE_MULTI%09= ["developers", "translators", "contributors"];%0A%0A// Map new string type identifiers to old style nsIUpdateItem types.%0A// Retired values:%0A// 32 = multipackage xpi file%0A// 8 = locale%0A// 256 = apiextension%0A// 128 = experiment%0A// theme = 4%0Aconst TYPES = {%0A%09extension: 2,%0A%09dictionary: 64,%0A};%0A%0Aconst COMPATIBLE_BY_DEFAULT_TYPES = {%0A%09extension: true,%0A%09dictionary: true,%0A};%0A%0Aconst hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);%0A%0Afunction isXPI(filename) {%0A%09let ext = filename.slice(-4).toLowerCase();%0A%09return ext === ".xpi" || ext === ".zip";%0A}%0A%0A/**%0A * Gets an nsIURI for a file within another file, either a directory or an XPI%0A * file. If aFile is a directory then this will return a file: URI, if it is an%0A * XPI file then it will return a jar: URI.%0A *%0A * @param {nsIFile} aFile%0A *%09%09The file containing the resources, must be either a directory or an XPI file%0A *%0A * @param {string} aPath%0A *%09%09The path to find the resource at, "/" separated. If aPath is empty%0A *%09%09then the uri to the root of the contained files will be returned%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI pointing at the resource%0A */%0Afunction getURIForResourceInFile(aFile, aPath) {%0A%09if (!isXPI(aFile.leafName)) {%0A%09%09let resource = aFile.clone();%0A%09%09if (aPath)%0A%09%09%09aPath.split("/").forEach(part => resource.append(part));%0A%0A%09%09return Services.io.newFileURI(resource);%0A%09}%0A%09return buildJarURI(aFile, aPath);%0A}%0A%0A/**%0A * Creates a jar: URI for a file inside a ZIP file.%0A *%0A * @param {nsIFile} aJarfile%0A *%09%09The ZIP file as an nsIFile%0A *%0A * @param {string} aPath%0A *%09%09The path inside the ZIP file%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI for the file%0A */%0Afunction buildJarURI(aJarfile, aPath) {%0A%09let uri = Services.io.newFileURI(aJarfile);%0A%09uri = "jar:" + uri.spec + "!/" + aPath;%0A%09return Services.io.newURI(uri);%0A}%0A%0Avar BootstrapLoader = {%0A%09name: "bootstrap",%0A%09manifestFile: "install.rdf",%0A%09async loadManifest(pkg) {%0A%09%09/**%0A%09%09 * Reads locale properties from either the main install manifest root%0A%09%09 * or an em:localized section in the install manifest.%0A%09%09 *%0A%09%09 * @param {Object} aSource%0A%09%09 *%09%09The resource to read the properties from.%0A%09%09 *%0A%09%09 * @param {boolean} isDefault%0A%09%09 *%09%09True if the locale is to be read from the main install manifest root%0A%09%09 *%0A%09%09 * @param {string[]} aSeenLocales%0A%09%09 *%09%09An array of locale names already seen for this install manifest.%0A%09%09 *%09%09Any locale names seen as a part of this function will be added to this array%0A%09%09 *%0A%09%09 * @returns {Object}%0A%09%09 *%09%09An object containing the locale properties%0A%09%09 */%0A%09%09function readLocale(aSource, isDefault, aSeenLocales) {%0A%09%09%09let locale = {};%0A%09%09%09if (!isDefault) {%0A%09%09%09%09locale.locales = [];%0A%09%09%09%09for (let localeName of aSource.locales || []) {%0A%09%09%09%09%09if (!localeName) {%0A%09%09%09%09%09%09logger.warn("Ignoring empty locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09if (aSeenLocales.includes(localeName)) {%0A%09%09%09%09%09%09logger.warn("Ignoring duplicate locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09aSeenLocales.push(localeName);%0A%09%09%09%09%09locale.locales.push(localeName);%0A%09%09%09%09}%0A%0A%09%09%09%09if (locale.locales.length == 0) {%0A%09%09%09%09%09logger.warn("Ignoring localized properties with no listed locales");%0A%09%09%09%09%09return null;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) {%0A%09%09%09%09if (hasOwnProperty(aSource, prop)) {%0A%09%09%09%09%09locale[prop] = aSource[prop];%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09return locale;%0A%09%09}%0A%0A%09%09let manifestData = await pkg.readString("install.rdf");%0A%09%09let manifest = InstallRDF.loadFromString(manifestData).decode();%0A%0A%09%09let addon = new AddonInternal();%0A%09%09for (let prop of PROP_METADATA) {%0A%09%09%09if (hasOwnProperty(manifest, prop)) {%0A%09%09%09%09addon[prop] = manifest[prop];%0A%09%09%09}%0A%09%09}%0A%09%09if (!addon.type) {%0A%09%09%09addon.type = "extension";%0A%09%09} else {%0A%09%09%09let type = addon.type;%0A%09%09%09addon.type = null;%0A%09%09%09for (let name in TYPES) {%0A%09%09%09%09if (TYPES[name] == type) {%0A%09%09%09%09%09addon.type = name;%0A%09%09%09%09%09break;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09}%0A%09%09if (!(addon.type in TYPES))%0A%09%09%09throw new Error("Install manifest specifies unknown type: " + addon.type);%0A%0A%09%09if (!addon.id)%0A%09%09%09throw new Error("No ID in install manifest");%0A%09%09if (!gIDTest.test(addon.id))%0A%09%09%09throw new Error("Illegal add-on ID " + addon.id);%0A%09%09if (!addon.version)%0A%09%09%09throw new Error("No version in install manifest");%0A%0A%09%09addon.strictCompatibility =%0A%09%09%09!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||%0A%09%09%09"strictCompatibility" in manifest && manifest.strictCompatibility == "true";%0A%0A%09%09// Only read these properties for extensions.%0A%09%09if (addon.type == "extension") {%0A%09%09%09if (manifest.bootstrap != "true") {%0A%09%09%09%09throw new Error("Non-restartless extensions no longer supported");%0A%09%09%09}%0A%09%09%09if (%0A%09%09%09%09addon.optionsType &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_BROWSER &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_TAB%0A%09%09%09) {%0A%09%09%09%09throw new Error("Install manifest specifies unknown optionsType: " + addon.optionsType);%0A%09%09%09}%0A%09%09} else {%0A%09%09%09// Convert legacy dictionaries into a format the WebExtension%0A%09%09%09// dictionary loader can process.%0A%09%09%09if (addon.type === "dictionary") {%0A%09%09%09%09addon.loader = null;%0A%09%09%09%09let dictionaries = {};%0A%09%09%09%09await pkg.iterFiles(({path}) => {%0A%09%09%09%09%09let match = /^dictionaries\/([^\/]+)\.dic$/.exec(path);%0A%09%09%09%09%09if (match) {%0A%09%09%09%09%09%09let lang = match[1].replace(/_/g, "-");%0A%09%09%09%09%09%09dictionaries[lang] = match[0];%0A%09%09%09%09%09}%0A%09%09%09%09});%0A%09%09%09%09addon.startupData = {dictionaries};%0A%09%09%09}%0A%0A%09%09%09// Only extensions are allowed to provide an optionsURL, optionsType,%0A%09%09%09// optionsBrowserStyle, or aboutURL. For all other types they are silently ignored%0A%09%09%09addon.aboutURL = null;%0A%09%09%09addon.optionsBrowserStyle = null;%0A%09%09%09addon.optionsType = null;%0A%09%09%09addon.optionsURL = null;%0A%09%09}%0A%0A%09%09addon.defaultLocale = readLocale(manifest, true);%0A%09%09let defaultLocaleEntries = Object.entries(addon.defaultLocale);%0A%0A%09%09let seenLocales = [];%0A%09%09addon.locales = [];%0A%09%09for (let localeData of manifest.localized || []) {%0A%09%09%09let locale = readLocale(localeData, false, seenLocales);%0A%09%09%09if (locale) {%0A%09%09%09%09for(let [key, val] of defaultLocaleEntries)%0A%09%09%09%09%09key in locale || Reflect.set(locale, key, val);%0A%09%09%09%09addon.locales.push(locale);%0A%09%09%09}%0A%09%09}%0A%0A%09%09addon.dependencies = Object.freeze(%0A%09%09%09"dependencies" in manifest ? Array.from(new Set(manifest.dependencies)) : []%0A%09%09);%0A%0A%09%09let seenApplications = [];%0A%09%09addon.targetApplications = [];%0A%09%09for (let targetApp of manifest.targetApplications || []) {%0A%09%09%09if (!targetApp.id || !targetApp.minVersion || !targetApp.maxVersion) {%0A%09%09%09%09logger.warn("Ignoring invalid targetApplication entry in install manifest");%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09if (seenApplications.includes(targetApp.id)) {%0A%09%09%09%09logger.warn(%0A%09%09%09%09%09"Ignoring duplicate targetApplication entry for " + targetApp.id + " in install manifest"%0A%09%09%09%09);%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09seenApplications.push(targetApp.id);%0A%09%09%09addon.targetApplications.push(targetApp);%0A%09%09}%0A%0A%09%09// Note that we don't need to check for duplicate targetPlatform entries since%0A%09%09// the RDF service coalesces them for us.%0A%09%09addon.targetPlatforms = [];%0A%09%09for (let targetPlatform of manifest.targetPlatforms || []) {%0A%09%09%09let platform = {%0A%09%09%09%09os: null,%0A%09%09%09%09abi: null,%0A%09%09%09};%0A%0A%09%09%09let pos = targetPlatform.indexOf("_");%0A%09%09%09if (pos != -1) {%0A%09%09%09%09platform.os = targetPlatform.substring(0, pos);%0A%09%09%09%09platform.abi = targetPlatform.substring(pos + 1);%0A%09%09%09} else {%0A%09%09%09%09platform.os = targetPlatform;%0A%09%09%09}%0A%09%09%09addon.targetPlatforms.push(platform);%0A%09%09}%0A%0A%09%09addon.userDisabled = false;%0A%09%09addon.softDisabled = addon.blocklistState == Blocklist.STATE_SOFTBLOCKED;%0A%09%09addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;%0A%0A%09%09addon.userPermissions = null;%0A%0A%09%09addon.icons = {};%0A%09%09if (await pkg.hasResource("icon.png")) {%0A%09%09%09addon.icons[32] = "icon.png";%0A%09%09%09addon.icons[48] = "icon.png";%0A%09%09}%0A%0A%09%09if (await pkg.hasResource("icon64.png")) {%0A%09%09%09addon.icons[64] = "icon64.png";%0A%09%09}%0A%0A%09%09return addon;%0A%09},%0A%0A%09// Bug 1512436 - Add new install location for built in search web extensions (Firefox 67+)%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1512436%0A%09// https://hg.mozilla.org/mozilla-central/diff/e3e75697e98c/toolkit/mozapps/extensions/internal/XPIProvider.jsm%23l1.396%0A%09//loadScope(addon, file) {%0A%09loadScope(addon, file = addon.file || addon._sourceBundle) {%0A%0A%09%09let uri = getURIForResourceInFile(file, "bootstrap.js").spec;%0A%09%09let principal = Services.scriptSecurityManager.getSystemPrincipal();%0A%0A%09%09let sandbox = new Cu.Sandbox(principal, {%0A%09%09%09sandboxName: uri,%0A%09%09%09addonId: addon.id,%0A%09%09%09wantGlobalProperties: ["ChromeUtils"],%0A%09%09%09metadata: { addonID: addon.id, URI: uri },%0A%09%09});%0A%0A%09%09try {%0A%09%09%09Object.assign(sandbox, BOOTSTRAP_REASONS);%0A%0A%09%09%09XPCOMUtils.defineLazyGetter(%0A%09%09%09%09sandbox, "console", () => new ConsoleAPI({ consoleID: %60addon/%24{addon.id}%60 })%0A%09%09%09);%0A%09%09%09Services.scriptloader.loadSubScript(uri, sandbox);%0A%0A%09%09} catch (e) {%0A%09%09%09logger.warn(%60Error loading bootstrap.js for %24{addon.id}%60, e);%0A%09%09}%0A%0A%09%09function findMethod(name) {%0A%09%09%09if (sandbox.name) {%0A%09%09%09%09return sandbox.name;%0A%09%09%09}%0A%09%09%09try {%0A%09%09%09%09let method = Cu.evalInSandbox(name, sandbox);%0A%09%09%09%09return method;%0A%09%09%09} catch (err) { }%0A%0A%09%09%09return () => {%0A%09%09%09%09logger.warn(%60Add-on %24{addon.id} is missing bootstrap method %24{name}%60);%0A%09%09%09};%0A%09%09}%0A%0A%09%09let install = findMethod("install");%0A%09%09let uninstall = findMethod("uninstall");%0A%09%09let startup = findMethod("startup");%0A%09%09let shutdown = findMethod("shutdown");%0A%0A%09%09return {%0A%09%09%09install: (...args) => install(...args),%0A%0A%09%09%09// https://github.com/xiaoxiaoflood/firefox-scripts/commit/b509dd0089dc7245e9797e0068b8fcff6ae3c776%0A%09%09%09//uninstall: (...args) => uninstall(...args),%0A%09%09%09uninstall(...args) {%0A%09%09%09%09var res = uninstall(...args);%0A%09%09%09%09// Forget any cached files we might've had from this extension.%0A%09%09%09%09Services.obs.notifyObservers(null, "startupcache-invalidate");%0A%09%09%09%09return res;%0A%09%09%09},%0A%0A%09%09%09startup(...args) {%0A%09%09%09%09if (addon.type == "extension") {%0A%09%09%09%09%09logger.debug(%60Registering manifest for %24{file.path}\n%60);%0A%09%09%09%09%09Components.manager.addBootstrappedManifestLocation(file);%0A%09%09%09%09}%0A%09%09%09%09return startup(...args);%0A%09%09%09},%0A%0A%09%09%09shutdown(data, reason) {%0A%09%09%09%09try {%0A%09%09%09%09%09return shutdown(data, reason);%0A%09%09%09%09} catch (err) {%0A%09%09%09%09%09throw err;%0A%09%09%09%09} finally {%0A%09%09%09%09%09if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {%0A%09%09%09%09%09%09logger.debug(%60Removing manifest for %24{file.path}\n%60);%0A%09%09%09%09%09%09Components.manager.removeBootstrappedManifestLocation(file);%0A%09%09%09%09%09}%0A%09%09%09%09}%0A%09%09%09},%0A%09%09};%0A%09},%0A};%0A// fim BootstrapLoader.jsm%0A%0A%0AAddonManager.addExternalExtensionLoader(BootstrapLoader);%0AObject.defineProperty(%0A%09AddonInternal.prototype,%0A%09"providesUpdatesSecurely",%0A%09{enumerable: true, value: true}%0A);%0A
        `.trim(), new Cu.Sandbox(Cu.getObjectPrincipal(this), {wantGlobalProperties: ["ChromeUtils", "atob"]}));
} catch(ex) {Cu.reportError(ex);}

and then install custom_buttons-0.0.7.0.0.16-fx-bootstrap.xpi, restart required (and some other bootstrap.js-based XUL addons, but most of them will be broken…)

Infocatcher commented 4 years ago

custom_buttons-0.0.7.0.0.16-fx-paxmod.xpi.zip custom_buttons-0.0.7.0.0.16-fx-bootstrap.xpi.zip (should be renamed: .xpi.zip)

sdavidg commented 4 years ago

Thank you very much for your help!!!!! It works perfectly, although the buttons with menus do not work properly (I gonna rewrite the code again )

One more thing, I have some very simple buttons that interact with the content of the page, for example:

var pageSource = "view-source:"+content.location;
gBrowser.selectedTab = gBrowser.addTab(pageSource);

but content, the window of the web page, is always null, do you know how I can get it?

Thanks

Infocatcher commented 4 years ago

although the buttons with menus do not work properly

At least required something like

-document.createElement("menupopup")
+//document.createXULElement("menupopup") // Backward-incompatible
+document.createElementNS(xulns /* "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" */, "menupopup")

Simple content access is gone, now should be used frame scripts… :( For content.location case:

var pageSource = "view-source:"+gBrowser.currentURI.spec;
//gBrowser.selectedTab = gBrowser.addTrustedTab(pageSource); // Backward-incompatible
gBrowser.selectedTab = gBrowser.addTab(pageSource, {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
sdavidg commented 4 years ago

Again, thank you very much