MozillaZine

Dev : Tips : Disable XUL cache

From MozillaZine Knowledge Base

(Difference between revisions)
Revision as of 22:35, 22 November 2004
Asqueella (Talk | contribs)
(reaarrange sections)
<-- Previous diff
Revision as of 22:48, 22 November 2004
Asqueella (Talk | contribs)
(rearrange, fix a typo, add a link to installed-chrome tutorial at xulplanet)
Next diff -->
Line 3: Line 3:
'''nglayout.debug.disable_xul_cache''' is a Mozilla [[Editing configuration|preference]] useful for extension developers. Basically when it is set to '''false''' (which is default), Mozilla caches chrome XUL and JavaScript (and more) in a file named XUL.mfl or similarly. Therefore, when making changes to your extension, you have to restart Mozilla in order to get new version used. As it is very inconvenient, many extension developers set this pref to '''true'''. '''nglayout.debug.disable_xul_cache''' is a Mozilla [[Editing configuration|preference]] useful for extension developers. Basically when it is set to '''false''' (which is default), Mozilla caches chrome XUL and JavaScript (and more) in a file named XUL.mfl or similarly. Therefore, when making changes to your extension, you have to restart Mozilla in order to get new version used. As it is very inconvenient, many extension developers set this pref to '''true'''.
-However even when '''nglayout.debug.disable_xul_cache''' is set to '''false''', Mozilla forbids rewriting *.jar files that contain installed extensions. To overcome this, and to avoid having to repack every change you make, you can unpack the JAR file you want to edit and make it permanent by updating chrome.rdf to point to the unpacked files instead of the JAR:+==Getting rid of JARs==
- +However even when '''nglayout.debug.disable_xul_cache''' is set to '''true''', Mozilla forbids rewriting *.jar files containing installed extensions. To overcome this and to avoid having to repackage every change you make, you can:
-===Using chrome.rdf===+*Package your extension to use plain directories instead of a single JAR (before installing) - easiest.
-We assume that the extension is installed in profile in this section. For global installation see next section.+*Unarchive the JAR file you want to edit and make it permanent by updating chrome.rdf to point to the unpacked files instead of the JAR (after installing)
- +*Use installed-chrome.txt to add your files to chrome, see [http://xulplanet.com/tutorials/xulapp/newpackage.html] ''(not sure if it works in Firefox)''
-'''''Important!! Backup your profile before editing chrome.rdf!'''''+
-<ol><li>Unpack the JAR file you have, say <tt>Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\my-ext.jar</tt> to the same directory. You will get (at least) <tt>Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\content</tt> directory.</li>+
-<li>In <tt>Profiles\default\chrome\chrome.rdf</tt> look for ''my-ext.jar!'' and delete it. For example replace this line+
-<pre>c:baseURL="jar:file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/my-ext.jar!/content/my-ext/"</pre>+
-with this:+
-<pre>c:baseURL="file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/content/my-ext/"</pre>+
-Note, that you should also delete ''jar:'' at the beginning of the path.</li></ol>+
===Changing install.rdf=== ===Changing install.rdf===
Line 33: Line 26:
to demonstrate this technique. to demonstrate this technique.
-===Using installed-chrome.txt===+ 
-''Write me!''+===Editing chrome.rdf===
-{{msg:stub}}+We assume that the extension is installed in profile in this section.
 + 
 +'''''Important!! Backup your profile before editing chrome.rdf!'''''
 +<ol><li>Unpack the JAR file you have, say <tt>Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\my-ext.jar</tt> to the same directory. You will get (at least) <tt>Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\content</tt> directory.</li>
 +<li>In <tt>Profiles\default\chrome\chrome.rdf</tt> look for ''my-ext.jar!'' and delete it. For example replace this line
 +<pre>c:baseURL="jar:file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/my-ext.jar!/content/my-ext/"</pre>
 +with this:
 +<pre>c:baseURL="file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/content/my-ext/"</pre>
 +Note, that you should also delete ''jar:'' at the beginning of the path.</li></ol>
 + 
==The overlay problem== ==The overlay problem==

Revision as of 22:48, 22 November 2004

Contents

nglayout.debug.disable_xul_cache

nglayout.debug.disable_xul_cache is a Mozilla preference useful for extension developers. Basically when it is set to false (which is default), Mozilla caches chrome XUL and JavaScript (and more) in a file named XUL.mfl or similarly. Therefore, when making changes to your extension, you have to restart Mozilla in order to get new version used. As it is very inconvenient, many extension developers set this pref to true.

Getting rid of JARs

However even when nglayout.debug.disable_xul_cache is set to true, Mozilla forbids rewriting *.jar files containing installed extensions. To overcome this and to avoid having to repackage every change you make, you can:

  • Package your extension to use plain directories instead of a single JAR (before installing) - easiest.
  • Unarchive the JAR file you want to edit and make it permanent by updating chrome.rdf to point to the unpacked files instead of the JAR (after installing)
  • Use installed-chrome.txt to add your files to chrome, see [1] (not sure if it works in Firefox)

Changing install.rdf

Perhaps you would like to package your extension as a series of directories, rather than a jar file. This would allow, for example, an XPI that could be easily edited and perhaps checked back into a repository (e.g. a developer version).

Change the install.rdf from:

<Description about="urn:mozilla:extension:file:myextension.jar">

to:

<Description about="urn:mozilla:extension:file:myextension">

An example of this technique is available. Also, myk is planning to update his tinderstatus extension to demonstrate this technique.


Editing chrome.rdf

We assume that the extension is installed in profile in this section.

Important!! Backup your profile before editing chrome.rdf!

  1. Unpack the JAR file you have, say Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\my-ext.jar to the same directory. You will get (at least) Profiles\default\extensions\{YOUR-EXTENSION'S-GUID}\content directory.
  2. In Profiles\default\chrome\chrome.rdf look for my-ext.jar! and delete it. For example replace this line
    c:baseURL="jar:file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/my-ext.jar!/content/my-ext/"

    with this:

    c:baseURL="file:///D:/Firefox/Profiles/default/extensions/{GUID}/chrome/content/my-ext/"
    Note, that you should also delete jar: at the beginning of the path.


The overlay problem

There is still another issue to be solved: a javascript that's called from the overlay. The steps above help you test scripts that are not part of the overlay, like your settings dialog. But they can't help you test the overlay scripts because Firefox caches those.

The solution is to have the overlay script load its code from an external file, which is reloaded and re-evaluated constantly. Here's an example:

var TheExt = {

	//aFuncCall is a string to be evaluated as a function call
	inject : function (aFuncCall) {
                var codeFileName =  "injected.js";

		// Get profile directory
		var file = Components.classes["@mozilla.org/file/directory_service;1"].
		createInstance(Components.interfaces.nsIProperties).
		get("ProfD", Components.interfaces.nsIFile);

		// Get the file with the code
		file.append(codeFileName);
		if (!file.exists()) {
			dump ("Error: " + file.path + "does not exist.\n");
			reutrn;
		}

		// Read the file into code
		var code = "";
		var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
			.createInstance(Components.interfaces.nsIFileInputStream);
		var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
			.createInstance(Components.interfaces.nsIScriptableInputStream);
		fstream.init(file, 1, 0, false);
		sstream.init(fstream);
		code += sstream.read(-1);
		sstream.close();
		fstream.close();
		
		// Run the code
		eval(code);	
		eval(aFuncCall);	
	},
	
	doAction : function() {
		this.inject("doAction()");
	}
}

dump ("Testing the extension.\n");
TheExt.doAction();

The file injected.js simply looks like this:

function doAction() {
	dump ("Action!\n")
}

You can add as many functions as you want. inject() evaluates all the functions in the file, but only executes the aFuncCall parameter.