Skip to content
This repository
Browse code

*** empty log message ***

  • Loading branch information...
commit 141315d8728bf78f829e4d2611bf82d74ec8c220 1 parent 8083f08
aboodman authored December 06, 2004
BIN  downloads/greasemonkey.xpi
Binary file not shown
0  src/content/linkify.user.js → downloads/linkify.user.js
File renamed without changes
11  downloads/ununderline.user.js
... ...
@@ -0,0 +1,11 @@
  1
+// ==UserScript==
  2
+// @description		Converts underlined text to italics, making it more distinguishable from a hyperlink.
  3
+// ==/UserScript==
  4
+
  5
+(function () {
  6
+	var ss = document.createElement("style");
  7
+	var t = document.createTextNode("u { text-decoration:none!important; font-style:italic!important; }");
  8
+    var root = (document.getElementsByTagName("head")[0] || document.getElementsByTagName("body")[0]);
  9
+	ss.appendChild(t);
  10
+	root.appendChild(ss);
  11
+})();
373  src/content/greasemonkey.js
... ...
@@ -1,373 +0,0 @@
1  
-const GUID = "{e4a8a97b-f2ed-450b-b12d-ee082ba24781}";
2  
-const NAMESPACE = "http://youngpup.net/greasemonkey";
3  
-
4  
-function Config() {
5  
-	this.onload = null;
6  
-	this.scripts = null;
7  
-
8  
-	this.find = function(namespace, name) {
9  
-		namespace = namespace.toLowerCase();
10  
-		name = name.toLowerCase();
11  
-
12  
-		for (var i = 0, script = null; (script = this.scripts[i]); i++) {
13  
-			if (script.namespace.toLowerCase() == namespace && script.name.toLowerCase() == name) {
14  
-				return i;
15  
-			}
16  
-		}
17  
-
18  
-		return -1;
19  
-	}
20  
-	
21  
-	this.load = function() {
22  
-		var doc = document.implementation.createDocument("", "", null);
23  
-		doc.async = false;
24  
-		doc.load(getScriptChrome("config.xml"));
25  
-
26  
-		var nodes = document.evaluate("/UserScriptConfig/Script", doc, null, 0, null);
27  
-
28  
-		this.scripts = [];
29  
-
30  
-		for (var node = null; (node = nodes.iterateNext()); ) {
31  
-			var script = new Script();
32  
-
33  
-			for (var i = 0, childNode = null; (childNode = node.childNodes[i]); i++) {
34  
-				if (childNode.nodeName == "Include") {
35  
-					script.includes.push(childNode.firstChild.nodeValue);
36  
-				}
37  
-				else if (childNode.nodeName == "Exclude") {
38  
-					script.excludes.push(childNode.firstChild.nodeValue);
39  
-				}
40  
-			}
41  
-
42  
-			script.id = node.getAttribute("id");
43  
-			script.name = node.getAttribute("name");
44  
-			script.namespace = node.getAttribute("namespace");
45  
-			script.description = node.getAttribute("description");
46  
-			script.enabled = node.getAttribute("enabled") == true.toString();
47  
-
48  
-			this.scripts.push(script);
49  
-		}
50  
-	}
51  
-
52  
-	this.save = function() {
53  
-		var doc = document.implementation.createDocument("", "UserScriptConfig", null);
54  
-		
55  
-		for (var i = 0, scriptObj = null; (scriptObj = this.scripts[i]); i++) {
56  
-			var scriptNode = doc.createElement("Script");
57  
-
58  
-			for (var j = 0; j < scriptObj.includes.length; j++) {
59  
-				var includeNode = doc.createElement("Include");
60  
-				includeNode.appendChild(doc.createTextNode(scriptObj.includes[j]));
61  
-				scriptNode.appendChild(doc.createTextNode("\n\t\t"));
62  
-				scriptNode.appendChild(includeNode);
63  
-			}
64  
-
65  
-			for (var j = 0; j < scriptObj.excludes.length; j++) {
66  
-				var excludeNode = doc.createElement("Exclude");
67  
-				excludeNode.appendChild(doc.createTextNode(scriptObj.excludes[j]));
68  
-				scriptNode.appendChild(doc.createTextNode("\n\t\t"));
69  
-				scriptNode.appendChild(excludeNode);
70  
-			}
71  
-
72  
-			scriptNode.appendChild(doc.createTextNode("\n\t"));
73  
-
74  
-			scriptNode.setAttribute("id", scriptObj.id);
75  
-			scriptNode.setAttribute("name", scriptObj.name);
76  
-			scriptNode.setAttribute("namespace", scriptObj.namespace);
77  
-			scriptNode.setAttribute("description", scriptObj.description);
78  
-			scriptNode.setAttribute("enabled", scriptObj.enabled);
79  
-
80  
-			doc.firstChild.appendChild(doc.createTextNode("\n\t"));
81  
-			doc.firstChild.appendChild(scriptNode);
82  
-		}
83  
-
84  
-		doc.firstChild.appendChild(doc.createTextNode("\n"))
85  
-
86  
-		var configStream = getWriteStream("config.xml");
87  
-		new XMLSerializer().serializeToStream(doc, configStream, "utf-8");
88  
-		configStream.close();
89  
-	}
90  
-}
91  
-
92  
-function Script() {
93  
-	this.name = null;
94  
-	this.namespace = null;
95  
-	this.description = null;
96  
-	this.enabled = true;
97  
-	this.includes = [];
98  
-	this.excludes = [];
99  
-}
100  
-
101  
-function ScriptDownloader(url) {
102  
-	var dm = Components.classes["@mozilla.org/download-manager;1"].getService(Components.interfaces.nsIDownloadManager)
103  
-	var ioservice = Components.classes["@mozilla.org/network/io-service;1"].getService();
104  
-	var sourceUri = ioservice.newURI(url, null, null);
105  
-	var targetFile = getTempFile();
106  
-	var targetUri = ioservice.newFileURI(targetFile)
107  
-	var persist = makeWebBrowserPersist();	
108  
-	var sysListener = null;
109  
-	var download = null;
110  
-	var self = this;
111  
-	var timerId = null;
112  
-
113  
-	this.start = function() {
114  
-		try {
115  
-			dm.addDownload(0, sourceUri, targetUri, parseScriptName(sourceUri), null, null, null, persist)
116  
-			dm.open(window._content, targetFile.path)
117  
-
118  
-			download = dm.getDownload(targetFile.path);
119  
-			download.persist = persist;
120  
-
121  
-			persist.saveURI(sourceUri, null, null, null, null, targetFile);
122  
-
123  
-			// this seems like a huge hack, but it was actually the most reliable
124  
-			// way I could find to determine when downloading is complete
125  
-			timerId = window.setInterval(checkLoad, 200);
126  
-		}
127  
-		catch (e) {
128  
-			handleErrors(e);
129  
-		}
130  
-	}
131  
-
132  
-	function checkLoad() {
133  
-		// if the download is complete, stop.
134  
-		if (download.percentComplete == 100) {
135  
-			window.clearInterval(timerId);
136  
-			handleLoad();
137  
-		}
138  
-		// if not complete yet, double-check that somebody hasn't cancelled it
139  
-		else if (dm.getDownload(targetFile.path) == null) {
140  
-			// the download is no longer active
141  
-			window.clearInterval(timerId);
142  
-			return;
143  
-		}
144  
-		// otherwise, do nothing. downloading continues.
145  
-	}
146  
-
147  
-	function handleLoad() {
148  
-		closeDownloadManager();
149  
-
150  
-		// validate that we downloaded ok
151  
-		if (!targetFile.exists() || targetFile.fileSize == 0) {
152  
-			alert("The file does not exist or was removed.");
153  
-			return;
154  
-		}
155  
-
156  
-		// initialize a new script object
157  
-		var script = new Script();
158  
-		script.id = targetFile.leafName;
159  
-		script.enabled = true;
160  
-		script.includes = [];
161  
-		script.excludes = [];
162  
-
163  
-		// crack open the file so we can look for metadata in the comments
164  
-		var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
165  
-						.createInstance(Components.interfaces.nsIFileInputStream);
166  
-
167  
-		fileStream.init(targetFile, 1, 0, false);
168  
-
169  
-		// read one line at a time looking for start meta delimiter or EOF
170  
-		var lineStream = fileStream.QueryInterface(Components.interfaces.nsILineInputStream);
171  
-		var result = {};
172  
-		var foundMeta = false;
173  
-
174  
-		while (lineStream.readLine(result)) {
175  
-			if (result.value.indexOf("// ==UserScript==") == 0) {
176  
-				foundMeta = true;
177  
-				break;
178  
-			}
179  
-		}
180  
-
181  
-		// gather up meta lines
182  
-		if (foundMeta) {
183  
-			while (lineStream.readLine(result)) {
184  
-				if (result.value.indexOf("// ==/UserScript==") == 0) {
185  
-					break;
186  
-				}
187  
-
188  
-				var match = result.value.match(/\/\/ \@(\S+)\s+([^\n]+)/);
189  
-				if (match != null) {
190  
-					switch (match[1]) {
191  
-						case "name":
192  
-						case "namespace":
193  
-						case "description":
194  
-							script[match[1]] = match[2];
195  
-							break;
196  
-						case "includes":
197  
-						case "excludes":
198  
-							script[match[1]].push(match[2]);
199  
-							break;
200  
-					}
201  
-				}
202  
-			}
203  
-		}
204  
-
205  
-		fileStream.close();
206  
-
207  
-		// if no meta info, default to reasonable values
208  
-		if (script.name == null) {
209  
-			script.name = parseScriptName(sourceUri);
210  
-		}
211  
-
212  
-		if (script.namespace == null) {
213  
-			script.namespace = sourceUri.host;
214  
-		}
215  
-
216  
-		if (script.includes.length == 0) {
217  
-			script.includes.push("*");
218  
-		}
219  
-
220  
-		// open install dialog
221  
-		var result = {};
222  
-		window.openDialog("chrome://greasemonkey/content/install.xul", 
223  
-			"manager", "resizable,centerscreen,modal", script, targetFile, result);
224  
-
225  
-		closeDownloadManager();
226  
-
227  
-		if (result.value) {
228  
-			alert("Success! Refresh page to see changes.");
229  
-		}
230  
-	}
231  
-
232  
-	function handleErrors(e) {
233  
-		//todo: need to handle this somehow. perhaps nsIUriChecker?
234  
-		//if (e.name == "NS_ERROR_FILE_NOT_FOUND") {
235  
-		//	alert("User script could not be found. Please check the name and try again.");
236  
-		//	window.status = defaultStatus;
237  
-		//}
238  
-		//else {
239  
-			alert("Could not download user script\n\n" + e.toString());
240  
-		//}
241  
-	}
242  
-
243  
-	function closeDownloadManager() {
244  
-		var wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator); 
245  
-		var en = wm.getEnumerator(""); 
246  
-		var n = 0; 
247  
-		var dlm = null;
248  
-		
249  
-		while (en.hasMoreElements()) { 
250  
-			var w = en.getNext(); 
251  
-
252  
-			if (w.location.href == "chrome://mozapps/content/downloads/downloads.xul") {
253  
-				dlm = w;
254  
-				break;
255  
-			}
256  
-		}
257  
-
258  
-		if (dlm != null) {
259  
-			dlm.close();
260  
-		}
261  
-	}
262  
-}
263  
-
264  
-function parseScriptName(sourceUri) {
265  
-	var name = sourceUri.spec;
266  
-	name = name.substring(0, name.indexOf(".user.js"));
267  
-	name = name.substring(name.lastIndexOf("/") + 1);
268  
-	return name;
269  
-}
270  
-
271  
-function getTempFile() {
272  
-	var file = Components.classes["@mozilla.org/file/directory_service;1"]
273  
-				.getService(Components.interfaces.nsIProperties)
274  
-				.get("TmpD", Components.interfaces.nsILocalFile);
275  
-
276  
-	file.append(new Date().getTime());
277  
-
278  
-	return file;
279  
-}
280  
-
281  
-function getWriteStream(fileName) {
282  
-	var file = getScriptFile(fileName);
283  
-	var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
284  
-		.createInstance(Components.interfaces.nsIFileOutputStream);
285  
-
286  
-	stream.init(file, 0x02 | 0x08 | 0x20, 420, 0);
287  
-
288  
-	return stream;
289  
-}
290  
-
291  
-function getScriptChrome(fileName) {
292  
-	return "chrome://greasemonkey/content/scripts/" + fileName;
293  
-}
294  
-
295  
-function getScriptFile(fileName) {
296  
-	var file = getScriptDir();
297  
-	file.append(fileName);
298  
-	return file;
299  
-}
300  
-
301  
-function getScriptDir() {
302  
-	var file = Components.classes["@mozilla.org/file/directory_service;1"]
303  
-				.getService(Components.interfaces.nsIProperties)
304  
-				.get("ProfD", Components.interfaces.nsILocalFile);
305  
-
306  
-	file.append("extensions");
307  
-	file.append(GUID);
308  
-	file.append("chrome");
309  
-	file.append("greasemonkey");
310  
-	file.append("content");
311  
-	file.append("scripts");
312  
-
313  
-	return file;
314  
-}
315  
-
316  
-// Converts a pattern in this programs simple notation to a regular expression.
317  
-// thanks AdBlock! http://www.mozdev.org/source/browse/adblock/adblock/
318  
-function convert2RegExp( pattern ) {
319  
-	s = new String(pattern);
320  
-	res = new String("^");
321  
-	
322  
-	for (var i = 0 ; i < s.length ; i++) {
323  
-		switch(s[i]) {
324  
-			case '*' : 
325  
-				res += ".*";
326  
-				break;
327  
-				
328  
-			case '.' : 
329  
-			case '?' :
330  
-			case '^' : 
331  
-			case '$' : 
332  
-			case '+' :
333  
-			case '{' :
334  
-			case '[' : 
335  
-			case '|' :
336  
-			case '(' : 
337  
-			case ')' :
338  
-			case ']' :
339  
-				res += "\\" + s[i];
340  
-				break;
341  
-			
342  
-			case '\\' :
343  
-				res += "\\\\";
344  
-				break;
345  
-			
346  
-			case ' ' :
347  
-				// Remove spaces from URLs.
348  
-				break;
349  
-			
350  
-			default :			
351  
-				res += s[i];
352  
-				break;
353  
-		}
354  
-	}
355  
-
356  
-	return new RegExp(res + '$', "i");
357  
-}
358  
-
359  
-function dbg(o) {
360  
-	var s = "";
361  
-	var i = 0;
362  
-
363  
-	for (var p in o) {
364  
-		s += p + ":" + o[p] + "\n";
365  
-
366  
-		if (++i % 15 == 0) {
367  
-			alert(s);
368  
-			s = "";
369  
-		}
370  
-	}
371  
-
372  
-	alert(s);
373  
-}
4  src/content/test.html
@@ -4,8 +4,8 @@
4 4
     <p>This is a test page. Use the links below to install the two test user scripts.
5 5
 
6 6
     <p>
7  
-      <a href="ununderline.user.js">un-underline</a><br>
8  
-      <a href="linkify.user.js">linkify</a><br>
  7
+      <a href="http://downloads.mozdev.org/greasemonkey/ununderline.user.js">un-underline</a><br>
  8
+      <a href="http://downloads.mozdev.org/greasemonkey/linkify.user.js">linkify</a><br>
9 9
 
10 10
     <p>Watch, astounded, as the text below changes before your eyes.
11 11
     
59  www/authoring.html
... ...
@@ -0,0 +1,59 @@
  1
+<!-- MAIN CONTENT -->
  2
+<h5 class="page-header"><a id="content" name="content">Writing User Scripts</a></h5>
  3
+
  4
+<p>User scripts are just plain 'ol DHTML javascripts with a *.user.js file extension. Thus, any <a href="http://www.amazon.com/exec/obidos/tg/detail/-/1565923928/103-6951853-4103063?v=glance">book</a> or <a href="http://www.google.com/search?q=dhtml+tutorial">online reference</a> for writing DHTML applies equally to writing user scripts.</p>
  5
+
  6
+<h6>Metadata</h6>
  7
+<p>Optionally, you can throw a tiny bit of metadata into a user script in a javascript code comment with this format:</p>
  8
+<pre>// ==UserScript==
  9
+// @name          My Cool User Script
  10
+// @namespace     http://youngpup.net/userscripts
  11
+// @description	  Does things that no other user script can do.
  12
+// @include       http://youngpup.net/*
  13
+// @include       http://www.youngpup.net/*
  14
+// @exclude       http://www.youngpup.net/2001/ypsimplescroll
  15
+// ==/UserScript==</pre>
  16
+<p>
  17
+  <table border="1">
  18
+    <thead>
  19
+      <tr>
  20
+        <th>Property</th>
  21
+        <th>Description</th>
  22
+        <th>Default</th>
  23
+      </tr>
  24
+    </thead>
  25
+    <tbody>
  26
+      <tr>
  27
+        <td>@name</td>
  28
+        <td>A friendly name for the script.</td>
  29
+        <td>The script's filename without the extension.</td>
  30
+      </tr>
  31
+      <tr>
  32
+        <td>@namespace</td>
  33
+        <td>A scope within which @name should be unique.</td>
  34
+        <td>The domain of the script's file.</td>
  35
+      </tr>
  36
+      <tr>
  37
+        <td>@description</td>
  38
+        <td>A, uhm, description.</td>
  39
+        <td>none</td>
  40
+      </tr>
  41
+      <tr>
  42
+        <td>@include</td>
  43
+        <td>A url to include the script with. There can be more than one.</td>
  44
+        <td>*</td>
  45
+      </tr>
  46
+      <tr>
  47
+        <td>@exclude</td>
  48
+        <td>A url to explicitly exclude the script from. There can be more than one.</td>
  49
+        <td>none</td>
  50
+      </tr>
  51
+    </tbody>
  52
+  </table>
  53
+</p>
  54
+
  55
+<h6>Tips</h6>
  56
+<ul>
  57
+  <li>User scripts are injected into the document after the DOM is fully loaded, but before onload occurs. This means that your scripts can begin immediately and don't need to wait for onload.</li>
  58
+  <li>Mozilla has a bunch of advanced features that you can take advantage of to make your job easier. These typically aren't practical for DHTML authors because they don't exist in any other browser, but since your user scripts will only run on firefox, you're free to use such goodies as <a href="http://www-jcsu.jesus.cam.ac.uk/~jg307/mozilla/xpath-tutorial.html">xpath</a> support (for HTML as well as XHTML), <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html">treewalkers</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html">mutation events</a>, <a href="http://xulplanet.com/references/objref/XMLHttpRequest.html">xmlhttp</a>, etc.</li>
  59
+</ul>
BIN  www/context.gif
10  www/index.html
@@ -32,8 +32,16 @@ <h5 class="infoHeader">Other Stuff</h5>
32 32
   <li><a href="scripts/jslinkfixer">Route around common and annoying website bugs</a></li>
33 33
 </ul>
34 34
 
  35
+<br><br>
  36
+
  37
+<p><a href="http://downloads.mozdev.org/greasemonkey/greasemonkey.xpi">Click Here to Install Grease Monkey</a></p>
  38
+
35 39
 <!--<p>Here are <a href="scripts">some other scripts</a> I've written or been made aware of. However, it's probably best to consult Google for a complete and current list.</p>-->
36 40
 
  41
+<br><br>
  42
+
37 43
 <p>Grease Monkey was heavily inspired by Adrian Holovaty's <a href="http://holovaty.com/blog/archive/2004/07/19/2210">site-specific extension for All Music Guide</a> and the conversation which ensued after he published it. There were tons of sites I wanted to create SSE's for, but fully-fledged firefox extensions proved too cumbersome. I wanted it to be as easy to create an SSE as it is to write DHTML.</p>
38 44
 
39  
-<p>Also muchos gustos to <a href="http://stilleye.com/">David Schontzler</a> who helped with the original idea as well as later refinements.</p>
  45
+<p>Also muchos gustos to <a href="http://stilleye.com/">David Schontzler</a> who helped with the original idea as well as later refinements.</p>
  46
+
  47
+<br><br><br>
BIN  www/manage.jpg
17  www/project_nav.html
... ...
@@ -1,30 +1,17 @@
1 1
 <h1 class="project-name" id="content">greasemonkey</h1>
2 2
 
3 3
 <table id="project-navigation">
4  
-
5  
-<!--
6  
-  <tbody id="sub-projects" class="project-navigations">
7  
-  <tr>
8  
-  <th scope="row">subprojects:</th>
9  
-  <td class="navigation-list">  
10  
-  <a class="first-item" href="/subprojectdir/index.html">subproject name</a>
11  
-  <a href="/subprojectpage.html">subproject name</a>
12  
-  </td>
13  
-  </tr>
14  
-  </tbody>
15  
--->
16  
-
17 4
   <tbody id="resources" class="project-navigations">
18 5
   <tr>
19 6
   <th scope="row">resources:</th>
20 7
   <td class="navigation-list">
21 8
   <a class="first-item" href="/index.html">Home</a>
  9
+  <a href="/using.html">Using Grease Monkey</a>
  10
+  <a href="/authoring.html">Writing User Scripts</a>
22 11
   <a href="/list.html">Mailing List</a>
23  
-  <a href="/installation.html">Installation</a>
24 12
   <a href="/source.html">Source Code</a>
25 13
   <a href="/members.html">Members</a>
26 14
   <a href="/bugs.html">Bugs</a>
27  
-  <a href="/screenshots.html">Screenshots</a>
28 15
   </td>
29 16
   </tr>
30 17
   </tbody>
BIN  www/tools.gif
12  www/using.html
... ...
@@ -0,0 +1,12 @@
  1
+<!-- MAIN CONTENT -->
  2
+<h5 class="page-header"><a id="content" name="content">Using Grease Monkey</a></h5>
  3
+
  4
+<h6>Installing Scripts</h6>
  5
+<p>You can install scripts by right-clicking on links to them and selecting "Install User Script...". Or, you can select the same option under the tools menu while viewing the contents of a user script file.</p>
  6
+
  7
+<p><img align="left" hspace="10" src="context.gif" width="333" height="216" border="2" alt="You can install a user script from the context menu on it's hyperlink." /><img align="left" hspace="10" src="tools.gif" width="392" height="216" border="2" alt="You can also install by accessing the tools menu while viewing the contents of a user script." /></p>
  8
+
  9
+<h6 style="clear:both">Script Configuration</h6>
  10
+<p>Each user script will be automatically included with one or more web pages. You can fine-tune which pages will be affected when you install or by going to Tools > Manage User Scripts.</p>
  11
+
  12
+<p><img src="manage.jpg" width="591" height="525" alt="You can manage which pages a script is associated with by going to Tools > Manage User Scripts" /></p>

0 notes on commit 141315d

Please sign in to comment.
Something went wrong with that request. Please try again.