Fabien Cazenave <kaze@kompozer.net>
Update by Laurent Jouanneau <laurent@xulfr.org>
Windows "C:\%ProgramFiles%\Mozilla Firefox\firefox.exe" Windows (64bit) "C:\%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe" MacOS X /Applications/Firefox.app/Contents/MacOS/firefox-bin Linux /usr/bin/firefox -no-remote -profile ~/.xul
<firefox> -no-remote -profile C:\[…]\_xul
-CreateProfile profilename
<firefox> -no-remote -CreateProfile dev
-P dev
<firefox> -no-remote -P dev
xxxxxxxx.default/ chrome/ extensions/ comete@mozilla.org/ <-- your futur extension firebug@software.joehewitt.com/ inspector@mozilla.org/ compreg.dat extensions.cache prefs.js <-- your preferences
Add these prefs with about:config:
javascript.options.showInConsole = true
nglayout.debug.disable_xul_cache = true
nglayout.debug.disable_xul_fastload = true (for Gecko 2.0 / Firefox 4+)
browser.dom.window.dump.enabled = true
javascript.options.strict = true
extensions.logging.enabled = true
Alternative: add these lines to %profile%/prefs.js
user_pref("browser.dom.window.dump.enabled", true); user_pref("extensions.logging.enabled", true); user_pref("javascript.options.strict", true); user_pref("javascript.options.showInConsole", true); user_pref("nglayout.debug.disable_xul_cache", true); user_pref("nglayout.debug.disable_xul_fastload", true);
warning: don't touch %profile%/prefs.js while Firefox is running!
More details on MDN: Setting up an extension development environment.
chrome://[package_name]/[part]/[file.xul]
chrome://browser/content/
content [package] [location]
content comete chrome/content/
content branding jar:browser.jar!/content/branding/ xpcnativewrappers=yes content browser jar:browser.jar!/content/browser/ xpcnativewrappers=yes contentaccessible=yes overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul overlay chrome://global/content/console.xul chrome://browser/content/jsConsoleOverlay.xul overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul overlay chrome://mozapps/content/downloads/downloads.xul chrome://browser/content/downloadManagerOverlay.xul overlay chrome://mozapps/content/extensions/extensions.xul chrome://browser/content/extensionsManagerOverlay.xul overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul override chrome://global/content/license.html chrome://browser/content/license.html style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
browser.jar content/ browser/ browser.xul browser.js -- other browser XUL and JS files go here -- bookmarks/ -- bookmarks files go here -- preferences/ -- preferences files go here --
classic.jar skin/ classic/ browser/ browser.css -- other browser skin files go here -- global/ -- global skin files go here --
en-US.jar
example:
exampleExt.xpi: chrome/ content/ locales/ skin/ components/ components/cmdline.js modules/ myJSmodule.js defaults/ preferences/*.js chrome.manifest install.rdf
install.rdf stores the extension’s metadata:
<?xml version="1.0"?> <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description about="urn:mozilla:install-manifest"> <em:id>inspector@mozilla.org</em:id> <em:version>2.0.4</em:version> <em:targetApplication> <!-- Firefox --> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>3.0a1</em:minVersion> <em:maxVersion>3.7a1pre</em:maxVersion> </Description> </em:targetApplication> <em:targetApplication> <!-- Thunderbird --> <Description> <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id> <em:minVersion>3.0a1pre</em:minVersion> <em:maxVersion>3.1a1pre</em:maxVersion> </Description> </em:targetApplication> <!-- front-end metadata --> <em:name>DOM Inspector</em:name> <em:description>Inspects the structure and properties of a window and its contents.</em:description> <em:creator>mozilla.org</em:creator> <em:homepageURL>http://www.mozilla.org/projects/inspector/</em:homepageURL> </Description> </RDF>
startup()
, shutdown()
, install()
, uninstall()
<em:bootstrap>true</em:bootstrap>
myApp/ chrome/ content/ main.xul locale/ skin/ defaults/ preferences/ prefs.js application.ini chrome.manifest
pref("toolkit.defaultChromeURI", "chrome://myapp/content/main.xul");
xulrunner application.inior with Firefox:
firefox -app application.ini
[App] Vendor=MIAGE Evry Name=CoMETE Version=0.1 BuildID=20101207 Copyright=Copyleft MIAGE Evry ID=comete@mozilla.org [Gecko] MinVersion=1.8 MaxVersion=2.0.* [XRE] EnableExtensionManager=1 EnableProfileMigrator=0
file:///[…]/chrome/content/browser.xul
Now let’s “proxy” this archive to get a chrome URL:
Windows C:\full\path\to\comete@mozilla.org\ Mac/Linux /full/path/to/comete@mozilla.org/
chrome://comete/content/browser.xul
Congrats: you’ve just turned a XUL page into an extension! :-)
Overlays are XUL files used to describe extra content in the UI.
… <menupopup id="menu_FilePopup"> <menuitem label="New"/> <menuitem label="Open"/> <menuitem label="Save"/> <menuitem label="Close"/> </menupopup> …
<?xml version="1.0"?> <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <menupopup id="menu_FilePopup"> <menuitem label="Quit"/> </menupopup> </overlay>
… <menupopup id="menu_FilePopup"> <menuitem label="New"/> <menuitem label="Open"/> <menuitem label="Save"/> <menuitem label="Close"/> <menuitem label="Quit"/> </menupopup> …
when designing an extension, there are three main places where you’d be likely to add a button:
<toolbarpalette id="BrowserToolbarPalette"> <toolbarbutton […] /> </toolbarpalette>
<statusbar id="status-bar"> <statusbarpanel> <toolbarbutton […] /> </statusbarpanel> </statusbar>
Use DOM Inspector to inspect the browser UI:
chrome://browser/content/
and find where you can attach overlays.
By default, overlaid elements are put at the end of the parent container.
These three attributes can help:
Note #1: the values of insertbefore and insertafter can be comma-separated lists
⇒ the first matching id in the list is used to determine the position.
Note #2: overlays can also be used to remove elements
e.g. to remove the “about” menu entry:
<menupopup id="help-popup"> <menuitem removeelement="true" id="help-about"> </menupopup>
3 main reasons to use an overlay:
3 ways to load an overlay:
<?xul-overlay href="chrome://component/content/componentOverlay.xul"?>
overlay chrome://URI-to-be-overlaid chrome://overlay-URI
document.loadOverlay(url, observer);
accesskey
, containing the letteraccesskey="A"
== ALT+A
<menu label="test" accesskey="t">
<keyset> <key id="sample-key" modifiers="shift" key="R"/> </keyset>
keycode
attribute, instead of key
: the key code (VK_*). ex: VK_F5, VK_ENTER, VK_A (list of code)<menu label="test" key="sample-key" accesskey="t">
var win = window.open(url, name, features);
var dlg = window.openDialog(url, name, features, param1, param2, ...);
var arg1 = window.arguments[0]
var retVals = { address: null, delivery: null }; openDialog("mydialog.xul", "dlg", "modal", "pizza", 6.98, retVals);In the dialog:
var ret = window.arguments[2]; ret.address='avenue des champs';
to fire the table.xul window, add:
…and register the overlay properly.
Bonuses: