[SOLVED]Firefox and autoconfig
-
- Posts: 6
- Joined: January 4th, 2018, 7:16 am
[SOLVED]Firefox and autoconfig
Prior to release of Firefox Quantum, i used source code of Mike Kaply's CCK wizard to build custom autoconfig as part of customized installer, with some additional code examples from net i adapted for personal use.
Problem is that i downloaded FF version 69.0 and some functions no longer work or are not recognized.
Are there API docs that are up to date, as most examples on MXR, developer.mozilla.org and StackOverflow appear to be obsolete ?
Note that this may be of interest to people dealing with enterprise deployment (as autoconfig is originally intended for them).
Problem is that i downloaded FF version 69.0 and some functions no longer work or are not recognized.
Are there API docs that are up to date, as most examples on MXR, developer.mozilla.org and StackOverflow appear to be obsolete ?
Note that this may be of interest to people dealing with enterprise deployment (as autoconfig is originally intended for them).
Last edited by dweller on September 20th, 2019, 1:46 pm, edited 1 time in total.
-
- Posts: 6421
- Joined: February 3rd, 2009, 6:29 pm
Re: Firefox and autoconfig
Can you post the code? Perhaps, someone can offer fixes.
The problem is AFAIK Firefox devs don't document changes for legacy addon devs anymore.
Firefox developer release notes
http://developer.mozilla.org/docs/Mozil ... x/Releases
I have found that the Thunderbird addons guide to be useful in updating my Fx userChrome.js hacks.
Addons Guide for Thunderbird 57 to Thunderbird 60
http://wiki.mozilla.org/Thunderbird/Add-ons_Guide_57
Addons Guide for Thunderbird 63 and beyond
http://wiki.mozilla.org/Thunderbird/Add-ons_Guide_63
Changes in Thunderbird 61-68
http://developer.thunderbird.net/add-ons/updates/tb68
Changes in Thunderbird 69-70
http://developer.thunderbird.net/add-ons/updates/tb76
In Firefox 69, I had the following problems with my Fx userChrome.js hacks.
Firefox 68 uses the chrome://browser/content/browser.xul url.
Firefox 69 uses the chrome://browser/content/browser.xhtml url.
I fixed a button with the following substitute.
Find what: createElement(
Replace with: createXULElement(
I fixed another button using the Services.prompt.select method by removing the array length param.
nsIPromptService
http://dxr.mozilla.org/mozilla-release/ ... ervice.idl
http://dxr.mozilla.org/mozilla-release/ ... ersion.txt
The problem is AFAIK Firefox devs don't document changes for legacy addon devs anymore.
Firefox developer release notes
http://developer.mozilla.org/docs/Mozil ... x/Releases
I have found that the Thunderbird addons guide to be useful in updating my Fx userChrome.js hacks.
Addons Guide for Thunderbird 57 to Thunderbird 60
http://wiki.mozilla.org/Thunderbird/Add-ons_Guide_57
Addons Guide for Thunderbird 63 and beyond
http://wiki.mozilla.org/Thunderbird/Add-ons_Guide_63
Changes in Thunderbird 61-68
http://developer.thunderbird.net/add-ons/updates/tb68
Changes in Thunderbird 69-70
http://developer.thunderbird.net/add-ons/updates/tb76
In Firefox 69, I had the following problems with my Fx userChrome.js hacks.
Firefox 68 uses the chrome://browser/content/browser.xul url.
Firefox 69 uses the chrome://browser/content/browser.xhtml url.
I fixed a button with the following substitute.
Find what: createElement(
Replace with: createXULElement(
I fixed another button using the Services.prompt.select method by removing the array length param.
nsIPromptService
http://dxr.mozilla.org/mozilla-release/ ... ervice.idl
http://dxr.mozilla.org/mozilla-release/ ... ersion.txt
-
- Posts: 6
- Joined: January 4th, 2018, 7:16 am
Re: Firefox and autoconfig
Here is the code i'm trying to port from older pre-Quantum releases :
bootstrap for main setup "\Mozilla Firefox\browser\defaults\preferences\autoconfig.js" :
main setup file in install root (this is supposed to be the final structure) "\Mozilla Firefox\firefox_setup.js" :
Note that :
- debugging is performed by running FF and watching for errors in browser console
- i tried importing Task.jsm but that is no longer available, luckily i was able to replace it with async/await
- FF complains that "removeFolderChildren is not a function" and similar for history service query SetFolders() (example taken from mozilla guides/docs)
- observer function is kind of working but the DOM url "chrome://browser/content/browser.xul" is no longer detected, i could only find "chrome://browser/content/commonDialog.xul", so all UI customizations can't be executed
- this setup is intended for one-time customization (look near the end of code, it removes itself leaving user in full control)
- since i added extensions to setup i also added widgets for each extension. before, names of widgets could be found using DOM inspector but that package appears to be dead
- since apparently API docs lag badly behind releases and examples do not cover all topics, i was heavily relying on Mike Kaply's CCK wizard to build my code, but that is no longer current
bootstrap for main setup "\Mozilla Firefox\browser\defaults\preferences\autoconfig.js" :
Code: Select all
//
pref("general.config.obscure_value", 0);
pref("general.config.filename", "firefox_setup.js");
pref("general.config.sandbox_enabled", false);
Code: Select all
//
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import ("resource:///modules/CustomizableUI.jsm");
Cu.import ("resource://gre/modules/FileUtils.jsm");
Cu.import ("resource://gre/modules/Sqlite.jsm");
Cu.import ("resource://gre/modules/Services.jsm");
Cu.import ("resource://gre/modules/PlacesUtils.jsm");
Cu.import ("resource://gre/modules/Bookmarks.jsm");
const alert = Services.prompt.alert;
const prefs = Services.prefs;
var NavigationBookmarks = Cc ["@mozilla.org/browser/nav-bookmarks-service;1"].getService (Ci.nsINavBookmarksService);
var History = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
var FileOutStream = Cc ["@mozilla.org/network/file-output-stream;1"].createInstance (Ci.nsIFileOutputStream);
var HandlerService = Cc ["@mozilla.org/uriloader/handler-service;1"].getService (Ci.nsIHandlerService);
var MimeService = Cc ["@mozilla.org/mime;1"].getService (Ci.nsIMIMEService);
var pdfMIMEInfo = MimeService.getFromTypeAndExtension ("application/pdf", "");
var ObserverService = Cc ["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
pdfMIMEInfo.alwaysAskBeforeHandling = true;
HandlerService.store (pdfMIMEInfo);
async function removeAllTrustedSites()
{
var conn = await Sqlite.openConnection ({ path: "permissions.sqlite", sharedMemoryCache: false });
await conn.execute ("UPDATE moz_perms SET permission = 0 WHERE type = \"install\"");
await conn.execute ("UPDATE moz_perms SET permission = 0 WHERE type = \"install\"");
await conn.close();
}
removeAllTrustedSites();
prefs.setIntPref ("browser.link.open_newwindow.restriction", 0);
prefs.setIntPref ("browser.link.open_newwindow", 3);
prefs.setBoolPref ("browser.search.geoSpecificDefaults", false);
prefs.setCharPref ("browser.search.defaultenginename", "Google");
prefs.setCharPref ("browser.search.defaultenginename.US", "Google");
prefs.setBoolPref ("browser.download.useDownloadDir", false);
prefs.setIntPref ("browser.startup.page", 3);
prefs.setBoolPref ("browser.tabs.warnOnClose" , false);
prefs.setBoolPref ("browser.tabs.closeWindowWithLastTab", false);
prefs.setBoolPref ("browser.tabs.animate", false);
prefs.setBoolPref ("browser.panorama.animate_zoom", false);
prefs.setBoolPref ("browser.fullscreen.animateUp", false);
prefs.setBoolPref ("browser.search.openintab", true);
prefs.setIntPref ("layout.spellcheckDefault", 0);
prefs.setBoolPref ("media.peerconnection.enabled", false);
prefs.setBoolPref ("browser.search.showOneOffButtons", false);
prefs.setBoolPref ("dom.disable_window_move_resize", false);
prefs.setBoolPref ("dom.disable_window_flip", true);
prefs.setBoolPref ("dom.event.contextmenu.enabled", true);
prefs.setBoolPref ("browser.tabs.drawInTitlebar", false);
prefs.setBoolPref ("browser.download.autohideButton", false);
var autoconfigFile = FileUtils.getFile ("CurProcD", ["defaults","preferences", "autoconfig.js"], false, false);
var setupFirefoxFile = FileUtils.getDir ("CurProcD", [""], false, false).parent;
setupFirefoxFile.append ("firefox_setup.js");
function ClearAllWidgetsFromArea (targetArea)
{
var i = 0;
do
{
var widgets = CustomizableUI.getWidgetIdsInArea (targetArea);
if (CustomizableUI.isWidgetRemovable (widgets [i]))
{
CustomizableUI.removeWidgetFromArea (widgets [i]);
i = 0;
}
else i ++;
}
while (i < CustomizableUI.getWidgetIdsInArea (targetArea).length);
}
function AddWidgetsToArea (targetArea, widgets)
{
for (var i = 0; i < widgets.length; i ++)
CustomizableUI.addWidgetToArea (widgets [i], targetArea);
}
var observer =
{
observe: function (subject, topic, data)
{
if (topic == "chrome-document-global-created")
{
var win = subject.QueryInterface (Ci.nsIDOMWindow);
win.addEventListener ("load", function (event)
{
win.removeEventListener ("load", arguments.callee, false);
var doc = event.target;
var url = doc.location.href.split ("?")[0].split ("#")[0];
if (url == "chrome://browser/content/browser.xul")
{
var domwin = subject.QueryInterface (Ci.nsIInterfaceRequestor).getInterface (Ci.nsIDOMWindow);
var menubarHidden = domwin.document.getElementById ("toolbar-menubar").getAttribute ("autohide");
if (menubarHidden == "true") CustomizableUI.setToolbarVisibility ("toolbar-menubar", "true");
var personalbarHidden = domwin.document.getElementById ("PersonalToolbar").getAttribute ("collapsed");
if (personalbarHidden == "true") CustomizableUI.setToolbarVisibility ("PersonalToolbar", "true");
NavigationBookmarks.removeFolderChildren (NavigationBookmarks.toolbarFolder);
var bookmarksToAdd = [["about:permissions","Permissions"],
["about:config","Configuration"],
["about:support","Support"]];
for (var i = 0; i < bookmarksToAdd.length; i ++)
NavigationBookmarks.insertBookmark (NavigationBookmarks.toolbarFolder,
Services.io.newURI (bookmarksToAdd [i][0], null, null),
NavigationBookmarks.DEFAULT_INDEX, bookmarksToAdd [i][1]);
ClearAllWidgetsFromArea ("PersonalToolbar");
AddWidgetsToArea ("PersonalToolbar",["_nonexistent_button_"]);
AddWidgetsToArea ("PersonalToolbar",
["personal-bookmarks", //bookmarks
"home-button", // home button
"downloads-button", // downloads
"bookmarks-menu-button", // bookmarks menu
]);
CustomizableUI.removeWidgetFromArea (widgets [0]);
ClearAllWidgetsFromArea ("nav-bar");
AddWidgetsToArea ("nav-bar",
["stop-reload-button",
"zoom-controls",
"search-container"
]);
FileOutStream.init (autoconfigFile, -1, -1, false);
FileOutStream.write ("", 0);
FileOutStream.close ();
FileOutStream.init (setupFirefoxFile, -1, -1, false);
FileOutStream.write ("", 0);
FileOutStream.close ();
}//if url == chrome browser ...
}, false);//addEventListener
}//if topic == chrome document ...
}//observe()
}//var observer
ObserverService.addObserver (observer, "chrome-document-global-created", false);
- debugging is performed by running FF and watching for errors in browser console
- i tried importing Task.jsm but that is no longer available, luckily i was able to replace it with async/await
- FF complains that "removeFolderChildren is not a function" and similar for history service query SetFolders() (example taken from mozilla guides/docs)
- observer function is kind of working but the DOM url "chrome://browser/content/browser.xul" is no longer detected, i could only find "chrome://browser/content/commonDialog.xul", so all UI customizations can't be executed
- this setup is intended for one-time customization (look near the end of code, it removes itself leaving user in full control)
- since i added extensions to setup i also added widgets for each extension. before, names of widgets could be found using DOM inspector but that package appears to be dead
- since apparently API docs lag badly behind releases and examples do not cover all topics, i was heavily relying on Mike Kaply's CCK wizard to build my code, but that is no longer current
-
- Posts: 6421
- Joined: February 3rd, 2009, 6:29 pm
Re: Firefox and autoconfig
Are you running the script in Linux?
Windows uses the \Mozilla Firefox\defaults\pref\autoconfig.js path.
Linux uses the \Mozilla Firefox\browser\defaults\preferences\autoconfig.js path, AFAIK.
Deploying Firefox in an enterprise environment (before Firefox 60 ESR)
http://developer.mozilla.org/docs/Mozil ... _before_60
Maybe you can use the PlacesUtils.bookmarks.eraseEverything method instead of the nsINavBookmarksService.removeFolderChildren method, then recreate the default bookmarks in the "Mozilla Firefox" folder.
nsINavBookmarksService
http://developer.mozilla.org/docs/Mozil ... rksService
removeFolderChildren and eraseEverything
http://dxr.mozilla.org/mozilla-esr52/se ... LUtils.jsm
http://dxr.mozilla.org/mozilla-release/ ... LUtils.jsm
http://dxr.mozilla.org/mozilla-release/ ... kmarks.jsm
I got the script working with Firefox Portable 69 in Windows.
* C:\FirefoxPortable\App\Firefox\defaults\pref\autoconfig.js
* C:\FirefoxPortable\App\Firefox\mozilla.cfg
Try using the Browser Toolbox instead of DOM inspector.
* set devtools.chrome.enabled pref to true
* set devtools.debugger.remote-enabled pref to true
Browser Toolbox
http://developer.mozilla.org/docs/Tools/Browser_Toolbox
How do we get DOM info for userChrome in 57+
http://forums.mozillazine.org/viewtopic.php?p=14772138
P.S.
I like using the "browser-delayed-startup-finished" topic instead of the "chrome-document-global-created" topic.
Observer Notifications
http://developer.mozilla.org/docs/Mozil ... ifications
Windows uses the \Mozilla Firefox\defaults\pref\autoconfig.js path.
Linux uses the \Mozilla Firefox\browser\defaults\preferences\autoconfig.js path, AFAIK.
Deploying Firefox in an enterprise environment (before Firefox 60 ESR)
http://developer.mozilla.org/docs/Mozil ... _before_60
Maybe you can use the PlacesUtils.bookmarks.eraseEverything method instead of the nsINavBookmarksService.removeFolderChildren method, then recreate the default bookmarks in the "Mozilla Firefox" folder.
Code: Select all
- NavigationBookmarks.removeFolderChildren(NavigationBookmarks.toolbarFolder);
+ async function eraseEverything() {
+ await PlacesUtils.bookmarks.eraseEverything();
+ ...
+ }
+ eraseEverything();
http://developer.mozilla.org/docs/Mozil ... rksService
removeFolderChildren and eraseEverything
http://dxr.mozilla.org/mozilla-esr52/se ... LUtils.jsm
http://dxr.mozilla.org/mozilla-release/ ... LUtils.jsm
http://dxr.mozilla.org/mozilla-release/ ... kmarks.jsm
I got the script working with Firefox Portable 69 in Windows.
* C:\FirefoxPortable\App\Firefox\defaults\pref\autoconfig.js
Code: Select all
// autoconfig.js file needs to start with a comment line
pref("general.config.sandbox_enabled", false);
pref("general.config.filename", "mozilla.cfg");
pref("general.config.obscure_value", 0);
Code: Select all
// mozilla.cfg file needs to start with a comment line
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import ("resource:///modules/CustomizableUI.jsm");
Cu.import ("resource://gre/modules/FileUtils.jsm");
Cu.import ("resource://gre/modules/Sqlite.jsm");
Cu.import ("resource://gre/modules/Services.jsm");
Cu.import ("resource://gre/modules/PlacesUtils.jsm");
Cu.import ("resource://gre/modules/Bookmarks.jsm");
const alert = Services.prompt.alert;
const prefs = Services.prefs;
var NavigationBookmarks = Cc ["@mozilla.org/browser/nav-bookmarks-service;1"].getService (Ci.nsINavBookmarksService);
var History = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
var FileOutStream = Cc ["@mozilla.org/network/file-output-stream;1"].createInstance (Ci.nsIFileOutputStream);
var HandlerService = Cc ["@mozilla.org/uriloader/handler-service;1"].getService (Ci.nsIHandlerService);
var MimeService = Cc ["@mozilla.org/mime;1"].getService (Ci.nsIMIMEService);
var pdfMIMEInfo = MimeService.getFromTypeAndExtension ("application/pdf", "");
var ObserverService = Cc ["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
pdfMIMEInfo.alwaysAskBeforeHandling = true;
HandlerService.store (pdfMIMEInfo);
async function removeAllTrustedSites()
{
var conn = await Sqlite.openConnection ({ path: "permissions.sqlite", sharedMemoryCache: false });
await conn.execute ("UPDATE moz_perms SET permission = 0 WHERE type = \"install\"");
await conn.execute ("UPDATE moz_perms SET permission = 0 WHERE type = \"install\"");
await conn.close();
}
removeAllTrustedSites();
prefs.setIntPref ("browser.link.open_newwindow.restriction", 0);
prefs.setIntPref ("browser.link.open_newwindow", 3);
prefs.setBoolPref ("browser.search.geoSpecificDefaults", false);
prefs.setCharPref ("browser.search.defaultenginename", "Google");
prefs.setCharPref ("browser.search.defaultenginename.US", "Google");
prefs.setBoolPref ("browser.download.useDownloadDir", false);
prefs.setIntPref ("browser.startup.page", 3);
prefs.setBoolPref ("browser.tabs.warnOnClose" , false);
prefs.setBoolPref ("browser.tabs.closeWindowWithLastTab", false);
prefs.setBoolPref ("browser.tabs.animate", false);
prefs.setBoolPref ("browser.panorama.animate_zoom", false);
prefs.setBoolPref ("browser.fullscreen.animateUp", false);
prefs.setBoolPref ("browser.search.openintab", true);
prefs.setIntPref ("layout.spellcheckDefault", 0);
prefs.setBoolPref ("media.peerconnection.enabled", false);
prefs.setBoolPref ("browser.search.showOneOffButtons", false);
prefs.setBoolPref ("dom.disable_window_move_resize", false);
prefs.setBoolPref ("dom.disable_window_flip", true);
prefs.setBoolPref ("dom.event.contextmenu.enabled", true);
prefs.setBoolPref ("browser.tabs.drawInTitlebar", false);
prefs.setBoolPref ("browser.download.autohideButton", false);
var autoconfigFile = FileUtils.getFile ("PrfDef", ["autoconfig.js"], false, false);
var setupFirefoxFile = FileUtils.getFile ("GreD", ["mozilla.cfg"], false, false);
function ClearAllWidgetsFromArea (targetArea)
{
var i = 0;
do
{
var widgets = CustomizableUI.getWidgetIdsInArea (targetArea);
if (CustomizableUI.isWidgetRemovable (widgets [i]))
{
CustomizableUI.removeWidgetFromArea (widgets [i]);
i = 0;
}
else i ++;
}
while (i < CustomizableUI.getWidgetIdsInArea (targetArea).length);
}
function AddWidgetsToArea (targetArea, widgets)
{
for (var i = 0; i < widgets.length; i ++)
CustomizableUI.addWidgetToArea (widgets [i], targetArea);
}
var observer =
{
observe: function (subject, topic, data)
{
if (topic == "chrome-document-global-created")
{
var win = subject.QueryInterface (Ci.nsIDOMWindow);
win.addEventListener ("load", function (event)
{
win.removeEventListener ("load", arguments.callee, false);
var doc = event.target;
var url = doc.location.href.split ("?")[0].split ("#")[0];
if (url == "chrome://browser/content/browser.xul" || // fx 68 uses browser.xul
url == "chrome://browser/content/browser.xhtml") // fx 69 uses browser.xhtml
{
var domwin = subject.QueryInterface (Ci.nsIInterfaceRequestor).getInterface (Ci.nsIDOMWindow);
var menubarHidden = domwin.document.getElementById ("toolbar-menubar").getAttribute ("autohide");
if (menubarHidden == "true") CustomizableUI.setToolbarVisibility ("toolbar-menubar", "true");
var personalbarHidden = domwin.document.getElementById ("PersonalToolbar").getAttribute ("collapsed");
if (personalbarHidden == "true") CustomizableUI.setToolbarVisibility ("PersonalToolbar", "true");
// NavigationBookmarks.removeFolderChildren (NavigationBookmarks.toolbarFolder); // removeFolderChildren obsolete
win.setTimeout(function () {
async function eraseEverything()
{
await PlacesUtils.bookmarks.eraseEverything();
var bookmarksToAdd = [["about:permissions","Permissions"],
["about:config","Configuration"],
["about:support","Support"]];
for (var i = 0; i < bookmarksToAdd.length; i ++)
NavigationBookmarks.insertBookmark (NavigationBookmarks.toolbarFolder,
Services.io.newURI (bookmarksToAdd [i][0], null, null),
NavigationBookmarks.DEFAULT_INDEX, bookmarksToAdd [i][1]);
ClearAllWidgetsFromArea ("PersonalToolbar");
// AddWidgetsToArea ("PersonalToolbar",["_nonexistent_button_"]); // button does not exist
AddWidgetsToArea ("PersonalToolbar",
["personal-bookmarks", // personal bookmarks item
"home-button", // home button
"downloads-button", // downloads button
"bookmarks-menu-button", // bookmarks menu button
]);
// CustomizableUI.removeWidgetFromArea (widgets [0]); // widgets is not defined
ClearAllWidgetsFromArea ("nav-bar");
AddWidgetsToArea ("nav-bar",
["stop-reload-button",
"zoom-controls",
"search-container",
]);
FileOutStream.init (autoconfigFile, -1, -1, false);
FileOutStream.write ("", 0);
FileOutStream.close ();
FileOutStream.init (setupFirefoxFile, -1, -1, false);
FileOutStream.write ("", 0);
FileOutStream.close ();
}
eraseEverything();
}, 3000);
}//if url == chrome browser ...
}, false);//addEventListener
}//if topic == chrome document ...
}//observe()
}//var observer
ObserverService.addObserver (observer, "chrome-document-global-created", false);
* set devtools.chrome.enabled pref to true
* set devtools.debugger.remote-enabled pref to true
Browser Toolbox
http://developer.mozilla.org/docs/Tools/Browser_Toolbox
How do we get DOM info for userChrome in 57+
http://forums.mozillazine.org/viewtopic.php?p=14772138
P.S.
I like using the "browser-delayed-startup-finished" topic instead of the "chrome-document-global-created" topic.
Code: Select all
// mozilla.cfg file needs to start with a comment line
Components.utils.import("resource://gre/modules/Services.jsm");
Services.obs.addObserver(function (aSubject, aTopic, aData) {
Services.obs.removeObserver(arguments.callee, "browser-delayed-startup-finished");
Services.console.logStringMessage("example");
var chromeWindow = aSubject;
chromeWindow.setTimeout(function () {
Services.prompt.alert(chromeWindow, "example", "test");
}, 1000);
}, "browser-delayed-startup-finished", false);
http://developer.mozilla.org/docs/Mozil ... ifications
-
- Posts: 6
- Joined: January 4th, 2018, 7:16 am
Re: Firefox and autoconfig
Huge thanks !
I'm using this on Windows machine. I wasn't aware of above mentioned docs / addons. Javascript can be unforgiving if there are no proper docs.
Indeed i too managed later to capture DOM url "chrome://browser/content/browser.xhtml" so it is confirmed from my side.
Also i followed a Browser Toolbox guide on how to enable new DOM inspector and it worked only because of keyboard shortcut (i haven't found any menus described on that page).
The Browser Console helped also with some sort of code-completion (first ever i saw for FF-related javascript), pitty it has no in / out parameter help (even though i can click on error line and open function in relevant .js file).
I'll post more info as i dig around API.
I'm using this on Windows machine. I wasn't aware of above mentioned docs / addons. Javascript can be unforgiving if there are no proper docs.
Indeed i too managed later to capture DOM url "chrome://browser/content/browser.xhtml" so it is confirmed from my side.
Also i followed a Browser Toolbox guide on how to enable new DOM inspector and it worked only because of keyboard shortcut (i haven't found any menus described on that page).
The Browser Console helped also with some sort of code-completion (first ever i saw for FF-related javascript), pitty it has no in / out parameter help (even though i can click on error line and open function in relevant .js file).
I'll post more info as i dig around API.
-
- Posts: 6421
- Joined: February 3rd, 2009, 6:29 pm
Re: Firefox and autoconfig
Here is a simple way to import bookmarks from a personal bookmarks.html file. (test code in console)morat wrote:recreate the default bookmarks in the "Mozilla Firefox" folder
Code: Select all
(function () {
var { BookmarkHTMLUtils } = ChromeUtils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
BookmarkHTMLUtils.importFromURL("file:///C:/bookmarks.html");
})();
http://developer.mozilla.org/docs/Tools ... mmand_line
Default bookmarks
view-source:chrome://browser/locale/bookmarks.html
-
- Posts: 6
- Joined: January 4th, 2018, 7:16 am
Re: Firefox and autoconfig
Ok more data.
I tried to use PlacesUtils.bookmarks.eraseEverything() but it runs asynchronously, so after it starts, all bookmarks that are added after calling the function are erased as well (i could see on FF startup bookmarks being added and then blink out of existence). Even "await" wasn't able to sequentially execute the function.
I'd be thankful if a promise/then() example wrapper for PlacesUtils.bookmarks.eraseEverything() is provided.
As for importing bookmarks, i want to keep customization in smallest number of files, so i'm trying to avoid adding yet another file just for bookmarks.
As for adding observer with topic "browser-delayed-startup-finished", it worked great ! I was able to remove event listener since topic itself guaranteed all UI elements are present before manipulating them.
I'm able to run much simpler code :
Also, no "subject.QueryInterface (Ci.nsIInterfaceRequestor).getInterface (Ci.nsIDOMWindow)" shenanigans needed. ![Smile :)](./images/smilies/icon_smile.gif)
I tried to use PlacesUtils.bookmarks.eraseEverything() but it runs asynchronously, so after it starts, all bookmarks that are added after calling the function are erased as well (i could see on FF startup bookmarks being added and then blink out of existence). Even "await" wasn't able to sequentially execute the function.
I'd be thankful if a promise/then() example wrapper for PlacesUtils.bookmarks.eraseEverything() is provided.
As for importing bookmarks, i want to keep customization in smallest number of files, so i'm trying to avoid adding yet another file just for bookmarks.
As for adding observer with topic "browser-delayed-startup-finished", it worked great ! I was able to remove event listener since topic itself guaranteed all UI elements are present before manipulating them.
I'm able to run much simpler code :
Code: Select all
var win = subject.QueryInterface (Ci.nsIDOMWindow);
win.document.getElementById ("PersonalToolbar").setAttribute ("collapsed", false);
win.document.getElementById ("toolbar-menubar").setAttribute ("autohide", false);
![Smile :)](./images/smilies/icon_smile.gif)
-
- Posts: 6421
- Joined: February 3rd, 2009, 6:29 pm
Re: Firefox and autoconfig
You could run code similar to the WebExtensions browser.bookmarks.getChildren method and WebExtensions browser.bookmarks.remove method to remove the children in the bookmarks toolbar folder. (test code in console)
note: read code from bottom to top, top is a big snippet from ext-bookmarks.js
WebExtensions browser.bookmarks
http://developer.mozilla.org/docs/Mozil ... /bookmarks
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
WebExtensions browser.bookmarks.getChildren
http://developer.mozilla.org/docs/Mozil ... etChildren
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
WebExtensions browser.bookmarks.remove
http://developer.mozilla.org/docs/Mozil ... rks/remove
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
Code: Select all
(function () {
// begin code from ext-bookmarks.js
const { TYPE_BOOKMARK, TYPE_FOLDER, TYPE_SEPARATOR } = PlacesUtils.bookmarks;
const BOOKMARKS_TYPES_TO_API_TYPES_MAP = new Map([
[TYPE_BOOKMARK, "bookmark"],
[TYPE_FOLDER, "folder"],
[TYPE_SEPARATOR, "separator"],
]);
const BOOKMARK_SEPERATOR_URL = "data:";
function getUrl(type, url) {
switch (type) {
case TYPE_BOOKMARK:
return url;
case TYPE_SEPARATOR:
return BOOKMARK_SEPERATOR_URL;
default:
return undefined;
}
}
const getTree = (rootGuid, onlyChildren) => {
function convert(node, parent) {
let treenode = {
id: node.guid,
title: PlacesUtils.bookmarks.getLocalizedTitle(node) || "",
index: node.index,
dateAdded: node.dateAdded / 1000,
type: BOOKMARKS_TYPES_TO_API_TYPES_MAP.get(node.typeCode),
url: getUrl(node.typeCode, node.uri),
};
if (parent && node.guid != PlacesUtils.bookmarks.rootGuid) {
treenode.parentId = parent.guid;
}
if (node.typeCode == TYPE_FOLDER) {
treenode.dateGroupModified = node.lastModified / 1000;
if (!onlyChildren) {
treenode.children = node.children
? node.children.map(child => convert(child, node))
: [];
}
}
return treenode;
}
return PlacesUtils.promiseBookmarksTree(rootGuid)
.then(root => {
if (onlyChildren) {
let children = root.children || [];
return children.map(child => convert(child, root));
}
let treenode = convert(root, null);
treenode.parentId = root.parentGuid;
// It seems like the array always just contains the root node.
return [treenode];
})
.catch(e => Promise.reject({ message: e.message }));
};
// end code from ext-bookmarks.js
var placesRoot = PlacesUtils.bookmarks.rootGuid;
var bookmarksMenuFolder = PlacesUtils.bookmarks.menuGuid;
var unfiledBookmarksFolder = PlacesUtils.bookmarks.unfiledGuid;
var toolbarFolder = PlacesUtils.bookmarks.toolbarGuid;
// similar to WebExtensions browser.bookmarks.getChildren method
getTree(toolbarFolder, true).then(function (children) {
for (child of children) {
console.log(child);
// similar to WebExtensions browser.bookmarks.remove method
PlacesUtils.bookmarks.remove({guid: child.id});
}
});
})();
WebExtensions browser.bookmarks
http://developer.mozilla.org/docs/Mozil ... /bookmarks
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
WebExtensions browser.bookmarks.getChildren
http://developer.mozilla.org/docs/Mozil ... etChildren
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
WebExtensions browser.bookmarks.remove
http://developer.mozilla.org/docs/Mozil ... rks/remove
http://dxr.mozilla.org/mozilla-release/ ... okmarks.js
-
- Posts: 6
- Joined: January 4th, 2018, 7:16 am
Re: [SOLVED]Firefox and autoconfig
I finally found an example to utilise Promise and fortunately code required to run it is simple for my use-case, which is to remove all existing bookmarks after fresh FF install and then adding my own. It is sufficient for my intended one-time setup. Program flow is preserved.
Code copied from https://developer.mozilla.org/en-US/doc ... ts/Promise .
Code copied from https://developer.mozilla.org/en-US/doc ... ts/Promise .
Code: Select all
const Cu = Components.utils;
const Ci = Components.interfaces;
const Cc = Components.classes;
Cu.import ("resource://gre/modules/PlacesUtils.jsm");
var NavigationBookmarks = Cc ["@mozilla.org/browser/nav-bookmarks-service;1"].getService (Ci.nsINavBookmarksService);
//here it is !
var doErase = Promise.resolve(PlacesUtils.bookmarks.eraseEverything());
doErase.then(function(value)
{
var bookmarksToAdd =
[
["about:permissions","Permissions"],
["about:config","Configuration"],
["about:support","Support"]
];
for (var i = 0; i < bookmarksToAdd.length; i ++)
NavigationBookmarks.insertBookmark (NavigationBookmarks.toolbarFolder,
Services.io.newURI (bookmarksToAdd [i][0], null, null),
NavigationBookmarks.DEFAULT_INDEX, bookmarksToAdd [i][1]);
});