Talk about add-ons and extension development.
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 17th, 2020, 8:29 am
Greetings! Here's the scoop: I'm trying to call "browser.management" in an autoconfig script, and can't identify the correct Code Module to bring into context. "ReferenceError: browser is not defined" at the Browser Console is getting quite tiresome... The listing of potential candidates (per https://developer.mozilla.org/en-US/doc ... de_modules ) includes: AddonManager.jsm AddonRepository.jsm Assert.jsm BookmarkHTMLUtils.jsm ctypes.jsm CustomizableUI.jsm DeferredTask.jsm Dict.jsm DownloadLastDir.jsm Downloads.jsm FileUtils.jsm Geometry.jsm HTTP.jsm JNI.jsm ISO8601DateUtils.jsm Log.jsm (formerly log4moz) NetUtil.jsm openLocationLastURL.jsm OSFile.jsm PerfMeasurement.jsm PluralForm.jsm PopupNotifications.jsm Promise.jsm PromiseWorker.jsm Services.jsm source-editor.jsm Sqlite.jsm Task.jsm Timer.jsm Webapps.jsm WebRequest.jsm XPCOMUtils.jsm In light of the foregoing, which of these many candidates might allow me to successfully scope "browser" in my script? And, for the record, is there some place to look which has a complete listing of the contents of these modules (and "@mozilla.org/..." of "Components.classes" fame)??? Thanks! 
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 17th, 2020, 11:45 am
morat to the rescue, again  Thanks for unraveling a bit more of this puzzle here... That said, what might the correct syntax look like for a successful import? This: - Code: Select all
Components.utils.import("resource://gre/modules/management.jsm");
& this: - Code: Select all
Components.classes["@mozilla.org/management;1"].getService(Components.interfaces.nsISomeBranch);
aren't going to work.  Can't help but wish there was a well-cataloged online repository for this kind of info!
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 17th, 2020, 4:53 pm
Thanks so much, morat, but this is what I want to import into my autoconfig script scheme: https://developer.mozilla.org/en-US/doc ... managementI want to explore/use the functions which the "management" API provides: With the management API you can: *get information about installed add-ons *enable/disable add-ons *uninstall add-ons *find out which permission warnings are given for particular add-ons or manifests *get notifications of add-ons being installed, uninstalled, enabled, or disabled.
And this way of doing the "import" into my autoconfig script, - Code: Select all
Components.utils.import("resource://gre/modules/management.jsm");
...doesn't work (of course); and I can't seem to be able to figure the situation out by rummaging through everything in omni.ja  Just need to know what the formatting/syntax would look like to bring this to life 
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 18th, 2020, 9:24 am
morat, Looking over this thread again, it seems as though I missed some of what you were getting across. Overtired, I guess... If I now understand the gist of this all correctly, it appears that a generic import for overall "management" functionality into an autoconfig script is not really possible. And, parsing the "management.json" and "ext-management.js" code into intelligible chunks per function is well beyond the pale for my level of mastery at this stage  I'll rummage about and see if there's a more "accessible" way of achieving my purposes; and get back if another question arises  Have a great weekend --
morat
Posts: 4197Joined: February 3rd, 2009, 6:29 pm
Posted July 18th, 2020, 9:58 am
You need to know how to do asynchronous programming to use the AddonManager object. These code snippets work in the browser console. Instructions: * open about:config page * set devtools.chrome.enabled preference to true * open browser console i.e. tools > web developer > browser console * copy and paste code into browser console command line* press enter to run - Code: Select all
(function () { function resolveAfter2Seconds() { return new Promise(function (resolve) { setTimeout(function () { resolve("resolved"); }, 2000); }); } async function example() { console.log("calling"); var result = await resolveAfter2Seconds(); console.log(result); } example(); })();
- Code: Select all
(function () { async function test() { var addons = await AddonManager.getAddonsByTypes(["extension"]); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { console.log("Name: " + addon.name + ", Id: " + addon.id + ", Disabled: " + addon.userDisabled); console.log(addon); } }); } test(); })();
Async function http://developer.mozilla.org/docs/Web/J ... c_functionAddonManager http://developer.mozilla.org/docs/Mozil ... donManagerhttp://developer.mozilla.org/docs/Mozil ... ager/AddonYou can use the addon.userDisabled property to disable addons.
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 18th, 2020, 12:36 pm
Thank you, morat, once again for your generous assistance. I guess I'll wind up getting a knack for this after all  Duties call me away for a bit now, but I will dig into this with purpose soon... Until next time, Cheers!
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 20th, 2020, 9:55 am
Hi there, morat. Back again after digging in to the syntax for a bit  In that venture, I wanted to start by running and experimenting with your code samples. So, I took this first example from your last post and just ran it: - Code: Select all
(function () { function resolveAfter2Seconds() { return new Promise(function (resolve) { setTimeout(function () { resolve("resolved"); }, 2000); }); } async function example() { console.log("calling"); var result = await resolveAfter2Seconds(); console.log(result); } example(); })();
Looks like it did what it was supposed to, with a few errors. Here's what the console returned: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 uncaught exception: Error in asyncStorage.setItem(): calling debugger eval code:8:13 undefined resolved debugger eval code:10:13
Upon running your next example, - Code: Select all
(function () { async function test() { var addons = await AddonManager.getAddonsByTypes(["extension"]); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { console.log("Name: " + addon.name + ", Id: " + addon.id + ", Disabled: " + addon.userDisabled); console.log(addon); } }); } test(); })();
The console returned: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 uncaught exception: Error in asyncStorage.setItem(): undefined Name: {extension 1}, Id: {id 1}, Disabled: true debugger eval code:6:17 Object { } debugger eval code:7:17 Name: {extension 2}, Id: {id 2}, Disabled: false debugger eval code:6:17 Object { } debugger eval code:7:17 Name: {extension 3}, Id: {id 3}, Disabled: false debugger eval code:6:17 Object { } debugger eval code:7:17 Name: {extension 4}, Id: {id 4}, Disabled: false debugger eval code:6:17 Object { } debugger eval code:7:17
Similar errors, but ran OK! Since you mentioned the the addon.userDisabled property, I thought I'd give this a quick run to do something practical. Here's what I came up with: - Code: Select all
(function () { async function test() { var addons = await AddonManager.getAddonsByTypes(["extension"]); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { addon.userDisabled = true; console.log("Name: " + addon.name + ", Id: " + addon.id + ", Disabled: " + addon.userDisabled); console.log(addon); } }); } test(); })();
It's just your previous (working) example with a sandwiched "userDisabled" call  No dice with "userDisabled". The console burped back: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 IndexedDB UnknownErr: ActorsParent.cpp:4588 uncaught exception: Error in asyncStorage.setItem(): undefined Name: {extension 1}, Id: {id 1}, Disabled: false debugger eval code:7:17 Object { } debugger eval code:8:17 Name: {extension 2}, Id: {id 2}, Disabled: false debugger eval code:7:17 Object { } debugger eval code:8:17 Name: {extension 3}, Id: {id 3}, Disabled: false debugger eval code:7:17 Object { } debugger eval code:8:17 Name: {extension 4}, Id: {id 4}, Disabled: false debugger eval code:7:17 Object { }
Not to be dissuaded from another go, I scratched my head a couple of times, dug around, and came up with this variant -- not expecting too much: - Code: Select all
(function () { async function test() { let addons = AddonManager.getAddonsByTypes(); addons.forEach((addon) => { AddonManager.addon.userDisabled(addon.id, true); }); } test(); })();
And I got what I expected! Here's the console's eulogy: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 undefined uncaught exception: Error in asyncStorage.setItem(): TypeError: addons.forEach is not a function debugger eval code:4:12
Seeing how that wasn't bearing the fruit generally hoped for, I decided to look about and find pre-fabbed operational code with "userDisabled" functionality here-and-there. This looked nifty: - Code: Select all
Cu.import('resource://gre/modules/AddonManager.jsm'); AddonManager.getAddonByID('{extension id 4}', function(addon) { if (addon.userDisabled) { //enable it addon.userDisabled = false; } else { //disable it addon.userDisabled = true; } });
The console disgreed: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 Promise { <state>: "pending" }
uncaught exception: Error in asyncStorage.setItem():
( source: https://stackoverflow.com/questions/266 ... fox-addons ) One more try, this one from MDN directly: - Code: Select all
Components.utils.import("resource://gre/modules/AddonManager.jsm");
let addonIDs = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED); if (addonIDs.length > 0) { // addonIDs is now an array of the add-on IDs that have been disabled alert("Note: " + addonIDs.length + " add-ons have been disabled."); }
Console: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 IndexedDB UnknownErr: ActorsParent.cpp:4588 NonSyntacticVariablesObject { gStrictCompatibility: false, gFinalShutdownBarrier: {…}, gCheckCompatibility: true, EXPORTED_SYMBOLS: (3) […], formatter: {…}, gUpdateEnabled: false, gBeforeShutdownBarrier: {…}, PREF_EM_CHECK_COMPATIBILITY: "extensions.checkCompatibility.68.10", gStartupComplete: true, AddonManagerInternal: {…}, … }
uncaught exception: Error in asyncStorage.setItem():
( source: https://developer.mozilla.org/en-US/doc ... on_Manager ) Now I'm totally confused: It seems as though anything which runs, throws numerous errors; and, that which should certainly run (public code from MDN and stackoverflow), does nothing but tank completely out... Thanks again -- EDIT: Code transcription error...
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 20th, 2020, 1:27 pm
One more from the mother wit, just for luck: - Code: Select all
(function () { var addons = AddonManager.getAllAddons(); addons.forEach(function () { addon.userDisabled(true); } ); })();
Output: IndexedDB UnknownErr: ActorsParent.cpp:4588 IndexedDB UnknownErr: ActorsParent.cpp:13188 TypeError: addons.forEach is not a function debugger eval code:3:12 uncaught exception: Error in asyncStorage.setItem():
??? Edit: Syntax...
morat
Posts: 4197Joined: February 3rd, 2009, 6:29 pm
Posted July 20th, 2020, 7:16 pm
I'm not seeing those errors. The problem may be a corrupted profile. IndexedDB UnknownErr: ActorsParent.cpp http://bugzilla.mozilla.org/show_bug.cgi?id=1362878http://bugzilla.mozilla.org/show_bug.cgi?id=1362878#c18The getAllAddons is an asynchronous method that returns a Promise object. - Code: Select all
(async function () { var addons = await AddonManager.getAllAddons(); addons.forEach(function (addon) { console.log(addon.id, addon.type, addon.hidden, addon.isSystem); }); })();
- Code: Select all
(function () { AddonManager.getAllAddons().then(function (addons) { addons.forEach(function (addon) { console.log(addon.id, addon.type, addon.hidden, addon.isSystem); }); }); })();
Promise http://developer.mozilla.org/docs/Web/J ... ts/Promise
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 21st, 2020, 8:37 am
Thanks, morat, for coming back... Ran everything on another identity, and some of the issues seemed to clear. However, the console returns, NS_NOINTERFACE: Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsISupports.QueryInterface] stack-trace-collector.js:84 Promise { <state>: "pending" }
-- or -- uncaught exception: Error in asyncStorage.setItem(): Promise { <state>: "pending" }
...when running this directly in the console: - Code: Select all
(async function () { var addons = await AddonManager.getAllAddons(); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { addon.userDisabled = true; } }); })();
Of course, the code does nothing  Finally, when attempting to import AddonManager.jsm within an autoconfig setup, - Code: Select all
Components.utils.import("resource://gre/modules/AddonManager.jsm");
...the console returns at browser startup: NS_ERROR_NOT_INITIALIZED: AddonManager is not initialized AddonManager.jsm:2912
Is this all essentially hopeless? Thanks again --
morat
Posts: 4197Joined: February 3rd, 2009, 6:29 pm
Posted July 21st, 2020, 10:23 am
Well I think you should give up. The userChrome.js hacks are for advanced users and legacy docs are not updated since legacy extensions are obsolete. morat wrote:You can use the addon.userDisabled property to disable addons.
Sorry, that's wrong. I tested all the code I posted, but I didn't test the userDisabled property. I had to examine the source to figure out the legacy code. - Code: Select all
// disable all non-hidden non-system extensions // open about:addons to see status change
(async function () { var addons = await AddonManager.getAddonsByTypes(["extension"]); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { console.log("Name: " + addon.name + ", Id: " + addon.id); // addon.userDisabled = true; // fails addon.disable(); } }); })();
Last edited by morat on July 23rd, 2020, 8:44 am, edited 1 time in total.
AlbertG
Posts: 57Joined: April 12th, 2006, 2:44 pm
Posted July 21st, 2020, 11:55 am
Well, nuts... For the record, your new code did run as anticipated from the console. And, calling "addon.enable();" has the expected inverse effect on the installed Add-on collection. However, running the code from an auticonfig setting with - Code: Select all
Components.utils.import("resource://gre/modules/AddonManager.jsm");
returns the inescapable NS_ERROR_NOT_INITIALIZED: AddonManager is not initialized AddonManager.jsm:2912
...so I guess this type of thing has been essentially removed from the roster of goodies for this type of scripting. Here's hoping some of the foregoing will be of use to others in their efforts  Thanks again, and have a great day!
morat
Posts: 4197Joined: February 3rd, 2009, 6:29 pm
Posted July 21st, 2020, 2:18 pm
morat wrote:The window.AddonManager object is already available in the browser.xhtml window. (no need to import)
Here is a toggle addons button. First click disable addons. Second click enable addons. * <profile directory>\chrome\ToggleAddonsFirefoxButton_Movable.uc.js - Code: Select all
(function () { if (location != "chrome://browser/content/browser.xul" && location != "chrome://browser/content/browser.xhtml") return;
/* CustomizableUI http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm/API-provided_widgets */
try { CustomizableUI.createWidget({ id: "__unique_identifier_toggle_addons_button", // should match id below type: "button", defaultArea: CustomizableUI.AREA_MENUBAR, // defaultArea: CustomizableUI.AREA_NAVBAR, label: "Toggle Addons", tooltiptext: "Toggle Addons" + "\n" + "\n" + "L: enable or disable addons" + "\n" + "R: open button context popup", onCommand: function (aEvent) { var win = aEvent.target.ownerDocument.defaultView; var uid = "__unique_identifier_toggle_addons_boolean"; if (typeof win[uid] == "undefined") win[uid] = true; else delete win[uid]; async function toggleAddons() { var addons = await AddonManager.getAddonsByTypes(["extension"]); addons.forEach(function (addon) { if (addon.hidden == false && addon.isSystem == false) { if (win[uid]) addon.disable(); else addon.enable(); } }); } toggleAddons(); }, }); } catch (e) { Components.utils.reportError(e); // [check] Show Content Messages };
var ios = Components.classes["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]. getService(Components.interfaces.nsIStyleSheetService); var dataUrl = "chrome://mozapps/skin/extensions/extension.svg"; var css = "#__unique_identifier_toggle_addons_button {"; css += 'list-style-image: url("' + dataUrl + '") !important;'; css += "-moz-image-region: auto !important;"; css += "fill: #0a84ff !important;"; css += "}"; var uri = ios.newURI("data:text/css," + encodeURIComponent(css), null, null); if (!sss.sheetRegistered(uri, sss.USER_SHEET)) { sss.loadAndRegisterSheet(uri, sss.USER_SHEET); } })();
Okay. I'm done here. AlbertG wrote:Thanks again, and have a great day!
You're welcome.
Return to Extension Development
Who is online
Users browsing this forum: No registered users and 1 guest
|