Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

*** empty log message ***

  • Loading branch information...
commit 141315d8728bf78f829e4d2611bf82d74ec8c220 1 parent 8083f08
@aboodman aboodman authored
View
BIN  downloads/greasemonkey.xpi
Binary file not shown
View
0  src/content/linkify.user.js → downloads/linkify.user.js
File renamed without changes
View
11 downloads/ununderline.user.js
@@ -0,0 +1,11 @@
+// ==UserScript==
+// @description Converts underlined text to italics, making it more distinguishable from a hyperlink.
+// ==/UserScript==
+
+(function () {
+ var ss = document.createElement("style");
+ var t = document.createTextNode("u { text-decoration:none!important; font-style:italic!important; }");
+ var root = (document.getElementsByTagName("head")[0] || document.getElementsByTagName("body")[0]);
+ ss.appendChild(t);
+ root.appendChild(ss);
+})();
View
373 src/content/greasemonkey.js
@@ -1,373 +0,0 @@
-const GUID = "{e4a8a97b-f2ed-450b-b12d-ee082ba24781}";
-const NAMESPACE = "http://youngpup.net/greasemonkey";
-
-function Config() {
- this.onload = null;
- this.scripts = null;
-
- this.find = function(namespace, name) {
- namespace = namespace.toLowerCase();
- name = name.toLowerCase();
-
- for (var i = 0, script = null; (script = this.scripts[i]); i++) {
- if (script.namespace.toLowerCase() == namespace && script.name.toLowerCase() == name) {
- return i;
- }
- }
-
- return -1;
- }
-
- this.load = function() {
- var doc = document.implementation.createDocument("", "", null);
- doc.async = false;
- doc.load(getScriptChrome("config.xml"));
-
- var nodes = document.evaluate("/UserScriptConfig/Script", doc, null, 0, null);
-
- this.scripts = [];
-
- for (var node = null; (node = nodes.iterateNext()); ) {
- var script = new Script();
-
- for (var i = 0, childNode = null; (childNode = node.childNodes[i]); i++) {
- if (childNode.nodeName == "Include") {
- script.includes.push(childNode.firstChild.nodeValue);
- }
- else if (childNode.nodeName == "Exclude") {
- script.excludes.push(childNode.firstChild.nodeValue);
- }
- }
-
- script.id = node.getAttribute("id");
- script.name = node.getAttribute("name");
- script.namespace = node.getAttribute("namespace");
- script.description = node.getAttribute("description");
- script.enabled = node.getAttribute("enabled") == true.toString();
-
- this.scripts.push(script);
- }
- }
-
- this.save = function() {
- var doc = document.implementation.createDocument("", "UserScriptConfig", null);
-
- for (var i = 0, scriptObj = null; (scriptObj = this.scripts[i]); i++) {
- var scriptNode = doc.createElement("Script");
-
- for (var j = 0; j < scriptObj.includes.length; j++) {
- var includeNode = doc.createElement("Include");
- includeNode.appendChild(doc.createTextNode(scriptObj.includes[j]));
- scriptNode.appendChild(doc.createTextNode("\n\t\t"));
- scriptNode.appendChild(includeNode);
- }
-
- for (var j = 0; j < scriptObj.excludes.length; j++) {
- var excludeNode = doc.createElement("Exclude");
- excludeNode.appendChild(doc.createTextNode(scriptObj.excludes[j]));
- scriptNode.appendChild(doc.createTextNode("\n\t\t"));
- scriptNode.appendChild(excludeNode);
- }
-
- scriptNode.appendChild(doc.createTextNode("\n\t"));
-
- scriptNode.setAttribute("id", scriptObj.id);
- scriptNode.setAttribute("name", scriptObj.name);
- scriptNode.setAttribute("namespace", scriptObj.namespace);
- scriptNode.setAttribute("description", scriptObj.description);
- scriptNode.setAttribute("enabled", scriptObj.enabled);
-
- doc.firstChild.appendChild(doc.createTextNode("\n\t"));
- doc.firstChild.appendChild(scriptNode);
- }
-
- doc.firstChild.appendChild(doc.createTextNode("\n"))
-
- var configStream = getWriteStream("config.xml");
- new XMLSerializer().serializeToStream(doc, configStream, "utf-8");
- configStream.close();
- }
-}
-
-function Script() {
- this.name = null;
- this.namespace = null;
- this.description = null;
- this.enabled = true;
- this.includes = [];
- this.excludes = [];
-}
-
-function ScriptDownloader(url) {
- var dm = Components.classes["@mozilla.org/download-manager;1"].getService(Components.interfaces.nsIDownloadManager)
- var ioservice = Components.classes["@mozilla.org/network/io-service;1"].getService();
- var sourceUri = ioservice.newURI(url, null, null);
- var targetFile = getTempFile();
- var targetUri = ioservice.newFileURI(targetFile)
- var persist = makeWebBrowserPersist();
- var sysListener = null;
- var download = null;
- var self = this;
- var timerId = null;
-
- this.start = function() {
- try {
- dm.addDownload(0, sourceUri, targetUri, parseScriptName(sourceUri), null, null, null, persist)
- dm.open(window._content, targetFile.path)
-
- download = dm.getDownload(targetFile.path);
- download.persist = persist;
-
- persist.saveURI(sourceUri, null, null, null, null, targetFile);
-
- // this seems like a huge hack, but it was actually the most reliable
- // way I could find to determine when downloading is complete
- timerId = window.setInterval(checkLoad, 200);
- }
- catch (e) {
- handleErrors(e);
- }
- }
-
- function checkLoad() {
- // if the download is complete, stop.
- if (download.percentComplete == 100) {
- window.clearInterval(timerId);
- handleLoad();
- }
- // if not complete yet, double-check that somebody hasn't cancelled it
- else if (dm.getDownload(targetFile.path) == null) {
- // the download is no longer active
- window.clearInterval(timerId);
- return;
- }
- // otherwise, do nothing. downloading continues.
- }
-
- function handleLoad() {
- closeDownloadManager();
-
- // validate that we downloaded ok
- if (!targetFile.exists() || targetFile.fileSize == 0) {
- alert("The file does not exist or was removed.");
- return;
- }
-
- // initialize a new script object
- var script = new Script();
- script.id = targetFile.leafName;
- script.enabled = true;
- script.includes = [];
- script.excludes = [];
-
- // crack open the file so we can look for metadata in the comments
- var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Components.interfaces.nsIFileInputStream);
-
- fileStream.init(targetFile, 1, 0, false);
-
- // read one line at a time looking for start meta delimiter or EOF
- var lineStream = fileStream.QueryInterface(Components.interfaces.nsILineInputStream);
- var result = {};
- var foundMeta = false;
-
- while (lineStream.readLine(result)) {
- if (result.value.indexOf("// ==UserScript==") == 0) {
- foundMeta = true;
- break;
- }
- }
-
- // gather up meta lines
- if (foundMeta) {
- while (lineStream.readLine(result)) {
- if (result.value.indexOf("// ==/UserScript==") == 0) {
- break;
- }
-
- var match = result.value.match(/\/\/ \@(\S+)\s+([^\n]+)/);
- if (match != null) {
- switch (match[1]) {
- case "name":
- case "namespace":
- case "description":
- script[match[1]] = match[2];
- break;
- case "includes":
- case "excludes":
- script[match[1]].push(match[2]);
- break;
- }
- }
- }
- }
-
- fileStream.close();
-
- // if no meta info, default to reasonable values
- if (script.name == null) {
- script.name = parseScriptName(sourceUri);
- }
-
- if (script.namespace == null) {
- script.namespace = sourceUri.host;
- }
-
- if (script.includes.length == 0) {
- script.includes.push("*");
- }
-
- // open install dialog
- var result = {};
- window.openDialog("chrome://greasemonkey/content/install.xul",
- "manager", "resizable,centerscreen,modal", script, targetFile, result);
-
- closeDownloadManager();
-
- if (result.value) {
- alert("Success! Refresh page to see changes.");
- }
- }
-
- function handleErrors(e) {
- //todo: need to handle this somehow. perhaps nsIUriChecker?
- //if (e.name == "NS_ERROR_FILE_NOT_FOUND") {
- // alert("User script could not be found. Please check the name and try again.");
- // window.status = defaultStatus;
- //}
- //else {
- alert("Could not download user script\n\n" + e.toString());
- //}
- }
-
- function closeDownloadManager() {
- var wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
- var en = wm.getEnumerator("");
- var n = 0;
- var dlm = null;
-
- while (en.hasMoreElements()) {
- var w = en.getNext();
-
- if (w.location.href == "chrome://mozapps/content/downloads/downloads.xul") {
- dlm = w;
- break;
- }
- }
-
- if (dlm != null) {
- dlm.close();
- }
- }
-}
-
-function parseScriptName(sourceUri) {
- var name = sourceUri.spec;
- name = name.substring(0, name.indexOf(".user.js"));
- name = name.substring(name.lastIndexOf("/") + 1);
- return name;
-}
-
-function getTempFile() {
- var file = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("TmpD", Components.interfaces.nsILocalFile);
-
- file.append(new Date().getTime());
-
- return file;
-}
-
-function getWriteStream(fileName) {
- var file = getScriptFile(fileName);
- var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Components.interfaces.nsIFileOutputStream);
-
- stream.init(file, 0x02 | 0x08 | 0x20, 420, 0);
-
- return stream;
-}
-
-function getScriptChrome(fileName) {
- return "chrome://greasemonkey/content/scripts/" + fileName;
-}
-
-function getScriptFile(fileName) {
- var file = getScriptDir();
- file.append(fileName);
- return file;
-}
-
-function getScriptDir() {
- var file = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("ProfD", Components.interfaces.nsILocalFile);
-
- file.append("extensions");
- file.append(GUID);
- file.append("chrome");
- file.append("greasemonkey");
- file.append("content");
- file.append("scripts");
-
- return file;
-}
-
-// Converts a pattern in this programs simple notation to a regular expression.
-// thanks AdBlock! http://www.mozdev.org/source/browse/adblock/adblock/
-function convert2RegExp( pattern ) {
- s = new String(pattern);
- res = new String("^");
-
- for (var i = 0 ; i < s.length ; i++) {
- switch(s[i]) {
- case '*' :
- res += ".*";
- break;
-
- case '.' :
- case '?' :
- case '^' :
- case '$' :
- case '+' :
- case '{' :
- case '[' :
- case '|' :
- case '(' :
- case ')' :
- case ']' :
- res += "\\" + s[i];
- break;
-
- case '\\' :
- res += "\\\\";
- break;
-
- case ' ' :
- // Remove spaces from URLs.
- break;
-
- default :
- res += s[i];
- break;
- }
- }
-
- return new RegExp(res + '$', "i");
-}
-
-function dbg(o) {
- var s = "";
- var i = 0;
-
- for (var p in o) {
- s += p + ":" + o[p] + "\n";
-
- if (++i % 15 == 0) {
- alert(s);
- s = "";
- }
- }
-
- alert(s);
-}
View
4 src/content/test.html
@@ -4,8 +4,8 @@
<p>This is a test page. Use the links below to install the two test user scripts.
<p>
- <a href="ununderline.user.js">un-underline</a><br>
- <a href="linkify.user.js">linkify</a><br>
+ <a href="http://downloads.mozdev.org/greasemonkey/ununderline.user.js">un-underline</a><br>
+ <a href="http://downloads.mozdev.org/greasemonkey/linkify.user.js">linkify</a><br>
<p>Watch, astounded, as the text below changes before your eyes.
View
59 www/authoring.html
@@ -0,0 +1,59 @@
+<!-- MAIN CONTENT -->
+<h5 class="page-header"><a id="content" name="content">Writing User Scripts</a></h5>
+
+<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>
+
+<h6>Metadata</h6>
+<p>Optionally, you can throw a tiny bit of metadata into a user script in a javascript code comment with this format:</p>
+<pre>// ==UserScript==
+// @name My Cool User Script
+// @namespace http://youngpup.net/userscripts
+// @description Does things that no other user script can do.
+// @include http://youngpup.net/*
+// @include http://www.youngpup.net/*
+// @exclude http://www.youngpup.net/2001/ypsimplescroll
+// ==/UserScript==</pre>
+<p>
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Property</th>
+ <th>Description</th>
+ <th>Default</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>@name</td>
+ <td>A friendly name for the script.</td>
+ <td>The script's filename without the extension.</td>
+ </tr>
+ <tr>
+ <td>@namespace</td>
+ <td>A scope within which @name should be unique.</td>
+ <td>The domain of the script's file.</td>
+ </tr>
+ <tr>
+ <td>@description</td>
+ <td>A, uhm, description.</td>
+ <td>none</td>
+ </tr>
+ <tr>
+ <td>@include</td>
+ <td>A url to include the script with. There can be more than one.</td>
+ <td>*</td>
+ </tr>
+ <tr>
+ <td>@exclude</td>
+ <td>A url to explicitly exclude the script from. There can be more than one.</td>
+ <td>none</td>
+ </tr>
+ </tbody>
+ </table>
+</p>
+
+<h6>Tips</h6>
+<ul>
+ <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>
+ <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>
+</ul>
View
BIN  www/context.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
10 www/index.html
@@ -32,8 +32,16 @@ <h5 class="infoHeader">Other Stuff</h5>
<li><a href="scripts/jslinkfixer">Route around common and annoying website bugs</a></li>
</ul>
+<br><br>
+
+<p><a href="http://downloads.mozdev.org/greasemonkey/greasemonkey.xpi">Click Here to Install Grease Monkey</a></p>
+
<!--<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>-->
+<br><br>
+
<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>
-<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>
+<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>
+
+<br><br><br>
View
BIN  www/manage.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
17 www/project_nav.html
@@ -1,30 +1,17 @@
<h1 class="project-name" id="content">greasemonkey</h1>
<table id="project-navigation">
-
-<!--
- <tbody id="sub-projects" class="project-navigations">
- <tr>
- <th scope="row">subprojects:</th>
- <td class="navigation-list">
- <a class="first-item" href="/subprojectdir/index.html">subproject name</a>
- <a href="/subprojectpage.html">subproject name</a>
- </td>
- </tr>
- </tbody>
--->
-
<tbody id="resources" class="project-navigations">
<tr>
<th scope="row">resources:</th>
<td class="navigation-list">
<a class="first-item" href="/index.html">Home</a>
+ <a href="/using.html">Using Grease Monkey</a>
+ <a href="/authoring.html">Writing User Scripts</a>
<a href="/list.html">Mailing List</a>
- <a href="/installation.html">Installation</a>
<a href="/source.html">Source Code</a>
<a href="/members.html">Members</a>
<a href="/bugs.html">Bugs</a>
- <a href="/screenshots.html">Screenshots</a>
</td>
</tr>
</tbody>
View
BIN  www/tools.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
12 www/using.html
@@ -0,0 +1,12 @@
+<!-- MAIN CONTENT -->
+<h5 class="page-header"><a id="content" name="content">Using Grease Monkey</a></h5>
+
+<h6>Installing Scripts</h6>
+<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>
+
+<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>
+
+<h6 style="clear:both">Script Configuration</h6>
+<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>
+
+<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>
Please sign in to comment.
Something went wrong with that request. Please try again.