diff --git a/.gitignore b/.gitignore
index b84f6673..fe09d16d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,8 @@ LOCAL.*
REMOTE.*
build
*.DS_Store
+*.py
+*.rb
+*.sh
+node_modules
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..6b59763c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# About
+
+Scriptish is a userscript manager for Firefox, forked from Greasemonkey.
+
+
+# Requirements
+
+* Using Scriptish: Firefox 4+
+* Building an XPI: Unix shell
+
+
+# Links
+
+* [Website](http://scriptish.org)
+* [Blog](http://scriptish.org/blog)
+* [Addons.Mozilla.Org (AMO)](https://addons.mozilla.org/en-US/firefox/addon/scriptish)
+* [Userscripts](http://userscripts.org)
+* [Wiki](http://github.com/scriptish/scriptish/wiki)
+* [Issues](http://github.com/scriptish/scriptish/issues)
+* [Google Group](http://groups.google.com/group/scriptish)
+* [Source Code](http://github.com/scriptish/scriptish)
diff --git a/README.txt b/README.txt
deleted file mode 100644
index b25d50d1..00000000
--- a/README.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Scriptish is a userscript manager for Firefox, forked from Greasemonkey.
-
-
-Requirements
-----------
-
-* Using Scriptish: Firefox 4.0b5pre or higher
-* Building an XPI: Unix shell
-* Playing w/ code: Git
-
-
-Links
-----------
-
-* Addons.Mozilla.Org (AMO): https://addons.mozilla.org/en-US/firefox/addon/scriptish
-* Userscripts: http://userscripts.org
-* Wiki: http://github.com/erikvold/scriptish/wiki
-* Issues: http://github.com/erikvold/scriptish/issues
-* Google Group: http://groups.google.com/group/scriptish
-* Source Code: http://github.com/erikvold/scriptish
diff --git a/extension/chrome.manifest b/extension/chrome.manifest
index 96e57567..12355516 100644
--- a/extension/chrome.manifest
+++ b/extension/chrome.manifest
@@ -9,6 +9,7 @@ content scriptish content/
resource scriptish modules/
skin scriptish classic/1.0 skin/
style chrome://global/content/customizeToolbar.xul chrome://scriptish/skin/browser.css
+style chrome://global/content/customizeToolbar.xul chrome://scriptish/content/third-party/firebug/startButton.css
overlay chrome://browser/content/browser.xul chrome://scriptish/content/browser.xul
overlay chrome://browser/content/scratchpad.xul chrome://scriptish/content/scratchpad.xul
diff --git a/extension/content/aboutScriptish.html b/extension/content/aboutScriptish.html
index fcec647e..39ecaf7d 100644
--- a/extension/content/aboutScriptish.html
+++ b/extension/content/aboutScriptish.html
@@ -32,7 +32,7 @@
About:Scriptish
- Check out the Scriptish wiki
+
Check out the Scriptish wiki
to learn about Scriptish and how to use it.
There are many resources from which you can obtain users scripts, most notably userscripts.org.
Please be careful when installing user scripts, as they can introduce significant security and privacy issues.
@@ -45,9 +45,9 @@
Help Out
There are many ways you can help out with Scriptish:
diff --git a/extension/content/addonstab.xul b/extension/content/addonstab.xul
index a1fa7820..3fc3f1c6 100644
--- a/extension/content/addonstab.xul
+++ b/extension/content/addonstab.xul
@@ -3,6 +3,9 @@
+
+
+
" + file.path, true);
+ + tempFile.path + " --> " + file.path);
file.remove(true);
tempFile.moveTo(file.parent, file.leafName);
@@ -686,6 +698,7 @@ Script.prototype = {
this._name = newScript._name;
this._namespace = newScript._namespace;
this.author = newScript._author;
+ this._developers = newScript._developers;
this._contributors = newScript._contributors;
this._description = newScript._description;
this._jsversion = newScript._jsversion;
@@ -739,7 +752,6 @@ Script.prototype = {
},
toJSON: function() ({
- contributors: this._contributors,
domains: this.domains,
includes: this._includes.patterns,
excludes: this._excludes.patterns,
@@ -763,6 +775,8 @@ Script.prototype = {
name: this.name,
namespace: this.namespace,
author: this._author,
+ developers: this._developers,
+ contributors: this._contributors,
blocklistState: this.blocklistState,
description: this._description,
version: this._version,
@@ -907,6 +921,10 @@ Script.parse = function Script_parse(aConfig, aSource, aURI, aUpdateScript) {
script.author = value;
continue;
}
+ // nobreak
+ case "developer":
+ script.addDeveloper(value);
+ continue;
case "contributor":
script.addContributor(value);
continue;
@@ -1134,7 +1152,10 @@ Script.loadFromJSON = function(aConfig, aSkeleton) {
script._noframes = aSkeleton.noframes;
script.domains = aSkeleton.domains;
- aSkeleton.contributors.forEach(script.addContributor.bind(script));
+ if (aSkeleton.developers)
+ aSkeleton.developers.forEach(script.addDeveloper.bind(script));
+ if (aSkeleton.contributors)
+ aSkeleton.contributors.forEach(script.addContributor.bind(script));
script.addInclude(aSkeleton.includes);
script.addExclude(aSkeleton.excludes);
script.addInclude(aSkeleton.user_includes, true);
diff --git a/extension/modules/script/scriptdependency.js b/extension/modules/script/scriptdependency.js
index 6b72998b..94e9fef4 100644
--- a/extension/modules/script/scriptdependency.js
+++ b/extension/modules/script/scriptdependency.js
@@ -52,7 +52,7 @@ ScriptDependency.prototype = {
this._filename = file.leafName;
Scriptish_log(Scriptish_stringBundle("moving.dependency") + " "
- + this._tempFile.path + " --> " + file.path, true);
+ + this._tempFile.path + " --> " + file.path);
file.remove(true);
this._tempFile.moveTo(file.parent, file.leafName);
diff --git a/extension/modules/script/scriptdownloader.js b/extension/modules/script/scriptdownloader.js
index 76d1c10f..1332fee3 100644
--- a/extension/modules/script/scriptdownloader.js
+++ b/extension/modules/script/scriptdownloader.js
@@ -53,6 +53,9 @@ ScriptDownloader.prototype.startDownload = function(bypassCache) {
req.channel.notificationCallbacks =
new BadCertHandler(!Scriptish_prefRoot.getValue("update.requireBuiltInCerts"));
}
+ if (req.channel instanceof Ci.nsIHttpChannelInternal) {
+ req.channel.forceAllowThirdPartyCookie = true;
+ }
req.onerror = this.handleErr.bind(this);
req.onreadystatechange = this.chkContentTypeB4DL.bind(this);
req.onload = this.handleScriptDownloadComplete.bind(this);
@@ -201,6 +204,9 @@ ScriptDownloader.prototype.downloadNextDependency = function() {
}
var sourceChannel = Services.io.newChannelFromURI(sourceUri);
+ if (sourceChannel instanceof Ci.nsIHttpChannelInternal) {
+ sourceChannel.forceAllowThirdPartyCookie = true;
+ }
sourceChannel.notificationCallbacks = (this.secure)
? new BadCertHandler(!Scriptish_prefRoot.getValue("update.requireBuiltInCerts"))
: new NotificationCallbacks();
diff --git a/extension/modules/third-party/regexpmerger.js b/extension/modules/third-party/regexpmerger.js
index 0150663b..5918eea0 100644
--- a/extension/modules/third-party/regexpmerger.js
+++ b/extension/modules/third-party/regexpmerger.js
@@ -39,6 +39,18 @@
const EXPORTED_SYMBOLS = ['merge'];
+const REG_TAINTED = /\\[ux]?\d/;
+const REG_TAINTED_ESCAPES = /\\\\/g;
+
+function tainted_filter(r) {
+ // No negative lookbehind in js :p
+ if (REG_TAINTED.test(r.replace(REG_TAINTED_ESCAPES, ""))) {
+ this.push(r);
+ return false;
+ }
+ return true;
+}
+
/**
* Array filter function to create an unique array
* @usage arr.filter(unique_filter, Object.create(null));
@@ -316,6 +328,16 @@ function mergePatterns(patterns, low, high, prefix) {
return patterns.sort();
}
+function merge_finish_map(e) "(?:" + e + ")";
+
+function merge_finish(patterns, tainted) {
+ patterns = patterns.concat(tainted);
+ if (patterns.length < 2) {
+ return patterns[0];
+ }
+ return patterns.map(merge_finish_map).join("|");
+}
+
/**
* Merge patterns with optimizations (prefixes)
* @param {Array} patterns Patterns to merge
@@ -332,6 +354,11 @@ function merge(patterns) {
return patterns[0];
}
+ // Remove tainted patterns for now
+ let tainted = [];
+ patterns = patterns.filter(tainted_filter, tainted);
+
+
// split patterns into pieces by top-level alternates
let newpatterns = [];
for (let [,p] in Iterator(patterns)) {
@@ -339,7 +366,7 @@ function merge(patterns) {
}
patterns = newpatterns.filter(unique_filter, Object.create(null));
if (patterns.length < 2) {
- return patterns[0];
+ return merge_finish(patterns, tainted);
}
// Good to go
@@ -357,10 +384,10 @@ function merge(patterns) {
let len = patterns.length;
if (len == 1) {
// already merged into a single pattern
- return patterns[0];
+ return merge_finish(patterns, tainted);
}
// not yet a single pattern (i.e. not all patterns shared a common prefix)
// merge without a prefix to get single pattern
- return mergePatterns(patterns, 0, len, "")[0];
+ return merge_finish(mergePatterns(patterns, 0, len, ""), tainted);
}
diff --git a/extension/modules/utils/PatternCollection.js b/extension/modules/utils/PatternCollection.js
index 503ec75c..bccb926a 100644
--- a/extension/modules/utils/PatternCollection.js
+++ b/extension/modules/utils/PatternCollection.js
@@ -6,17 +6,6 @@ Components.utils.import("resource://scriptish/utils/Scriptish_getTLDURL.js");
Components.utils.import("resource://scriptish/utils/Scriptish_mergeRegExps.js");
const FAKE_REGEXP = {test: function() false};
-const REG_TAINTED = /\\[ux]?\d/;
-const REG_TAINTED_ESCAPES = /\\\\/g;
-
-function tainted_filter(r) {
- // No negative lookbehind in js :p
- if (REG_TAINTED.test(r.source.replace(REG_TAINTED_ESCAPES, ""))) {
- this.push(r);
- return false;
- }
- return true;
-}
function merge(regs, flags) {
if (!regs.length) {
@@ -25,25 +14,7 @@ function merge(regs, flags) {
// that will always test |true|
return FAKE_REGEXP;
}
-
- // Split the regs into "tainted" ones and those we can merge
- // Tainted:
- // - contains back refs /(["']).+?\1/
- // - contains string escapes /\x00\u0000/
- let tainted = [];
- regs = regs.filter(tainted_filter, tainted);
-
- // merge what we can
- regs = Scriptish_mergeRegExps(regs, flags);
-
- if (tainted.length) {
- // we need to test regs individually
- tainted.unshift(regs);
- return {test: function(s) tainted.some(function(r) r.test(s))};
- }
-
- // no tainted regs
- return regs;
+ return Scriptish_mergeRegExps(regs, flags);
}
function PatternCollection() {
diff --git a/extension/modules/utils/Scriptish_getEditor.js b/extension/modules/utils/Scriptish_getEditor.js
index a7e128e5..be810b42 100644
--- a/extension/modules/utils/Scriptish_getEditor.js
+++ b/extension/modules/utils/Scriptish_getEditor.js
@@ -32,25 +32,22 @@ const Scriptish_getEditor = function(parentWindow, change) {
while (true) {
Scriptish_log("Asking user to choose editor...");
var nsIFilePicker = Ci.nsIFilePicker;
- var filePicker = Instances.fp;
- filePicker.init(
+ var fp = Instances.fp;
+ fp.init(
parentWindow,
Scriptish_stringBundle("editor.prompt"),
nsIFilePicker.modeOpen);
- filePicker.appendFilters(nsIFilePicker.filterApplication);
- filePicker.appendFilters(nsIFilePicker.filterAll);
+ fp.appendFilters(nsIFilePicker.filterApplication);
+ fp.appendFilters(nsIFilePicker.filterAll);
- if (filePicker.show() != nsIFilePicker.returnOK) {
- // The user canceled, return null.
- Scriptish_log("User canceled file picker dialog");
+ if (fp.show() != nsIFilePicker.returnOK)
return null;
- }
- Scriptish_log("User selected: " + filePicker.file.path);
+ Scriptish_log("User selected: " + fp.file.path);
- if (filePicker.file.exists() && filePicker.file.isExecutable()) {
- Scriptish_prefRoot.setValue("editor", filePicker.file.path);
- return filePicker.file;
+ if (fp.file.exists() && fp.file.isExecutable()) {
+ Scriptish_prefRoot.setValue("editor", fp.file.path);
+ return fp.file;
} else {
Scriptish_alert(Scriptish_stringBundle("editor.pleasePickExecutable"));
}
diff --git a/extension/skin/browser.css b/extension/skin/browser.css
index 4ac1913e..21178da1 100644
--- a/extension/skin/browser.css
+++ b/extension/skin/browser.css
@@ -1,5 +1,6 @@
#scriptish-button {
-moz-box-orient: horizontal;
+ -moz-binding: url("chrome://scriptish/content/third-party/firebug/startButton.xml#scriptish-button");
list-style-image: url("chrome://scriptish/skin/scriptish24.png");
}
diff --git a/sync-locales.js b/sync-locales.js
new file mode 100644
index 00000000..da32291e
--- /dev/null
+++ b/sync-locales.js
@@ -0,0 +1,77 @@
+#!/usr/bin/env node
+
+var path = require("path");
+var glob = require("glob").glob;
+var globSync = require("glob").globSync;
+var fs = require("fs");
+
+
+function Properties(file) {
+ this.file = file;
+ this.items = {};
+ var self = this;
+
+ // store the keys/values
+ var data = fs.readFileSync(file, "utf-8");
+ var list = data.match(/[^\n]*(\n|$)/g);
+
+ for (var i = list.length - 1; ~i; i--) {
+ var m = list[i].match(/(^[^#=]*)=([^\n]*)(\n|$)/, "");
+ if (!m) continue;
+ self.items[m[1]] = m[2];
+ }
+}
+
+Properties.prototype.merge = function(rhs) {
+ // remove the obsolete keys
+ for (var key in this.items)
+ if (!rhs.items[key])
+ delete this.items[key];
+
+ // add new keys
+ for (var key in rhs.items)
+ if (!this.items[key])
+ this.items[key] = "";
+};
+
+Properties.prototype.save = function() {
+ var keys = [], newStr = [], self = this;
+ for (var key in this.items) {
+ keys.push(key);
+ }
+
+ keys.sort(function(a, b) {
+ return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1;
+ });
+ for (var i = 0, e = keys.length; i < e; i++) {
+ newStr.push(keys[i] + "=" + this.items[keys[i]]);
+ }
+ newStr = newStr.join("\n") + "\n";
+ fs.writeFile(self.file, newStr, "utf-8", function(e) {
+ if (e) throw e;
+ });
+};
+
+function process_properties(base, files) {
+ base = new Properties(base);
+
+ for (var i = files.length - 1, file; ~i; i--) {
+ file = files[i];
+ if (file == base.file)
+ continue
+ console.log(file);
+ file = new Properties(file);
+ file.merge(base);
+ file.save();
+ }
+}
+
+glob("extension/locale/en-US/*.properties", function(e, m) {
+ if (e) throw e;
+ m.forEach(function(f) {
+ var fn = f.match(/[^\\\/\.]*.properties$/)[0];
+ var files = globSync("extension/locale/*/" + fn);
+ process_properties(f, files);
+ });
+})
+
diff --git a/sync-locales.py b/sync-locales.py
index 4573f42e..803f1dd9 100644
--- a/sync-locales.py
+++ b/sync-locales.py
@@ -18,7 +18,7 @@ def __init__(self, file):
line = line.strip()
if line.startswith("#"):
continue
- key, value = line.split("=", 2)
+ key, value = line.split("=", 1)
self._items[key] = value
def merge(self, rhs):
@@ -30,7 +30,7 @@ def merge(self, rhs):
# add new keys
for k in rhs._items.keys():
if not k in self._items:
- self._items[key] = ""
+ self._items[k] = ""
def save(self):
with copen(self.file, "wb", encoding="utf-8") as op:
diff --git a/test.js b/test.js
new file mode 100644
index 00000000..aec1d32a
--- /dev/null
+++ b/test.js
@@ -0,0 +1,45 @@
+#!/usr/bin/env node
+
+var exec = require('child_process').exec;
+
+var debug = ("debug" == process.argv[2]);
+
+exec("./build.sh test", function() {
+ console.log("Running mozmill tests...");
+ if (debug) {
+ exec("mozmill -t tests/mozmill-tests -a scriptish-test.xpi --show-all", doAsycTests.bind(null, 0));
+ } else {
+ exec("mozmill -t tests/mozmill-tests -a scriptish-test.xpi", doAsycTests.bind(null, 0));
+ }
+});
+
+function dumpResults(e, out) {
+ if (out) console.log(out);
+}
+
+function doAsycTests(step, e, out) {
+ dumpResults(e, out);
+ step = step || 0;
+ switch (step) {
+ case 4:
+ console.log("Running mozmill-restart tests...");
+ if (debug) {
+ exec("mozmill-restart -t tests/mozmill-tests/tests/restartTests -a scriptish-test.xpi --show-all", dumpResults);
+ } else {
+ exec("mozmill-restart -t tests/mozmill-tests/tests/restartTests -a scriptish-test.xpi", dumpResults);
+ }
+ return;
+ case 0:
+ console.log("Starting restart tests in 10 secs... (Press ctrl+z to cancel)");
+ return setTimeout(doAsycTests.bind(null, ++step), 7000);
+ case 1:
+ console.log("Starting restart tests in 3 secs...");
+ return setTimeout(doAsycTests.bind(null, ++step), 1000);
+ case 2:
+ console.log("Starting restart tests in 2 secs...");
+ return setTimeout(doAsycTests.bind(null, ++step), 1000);
+ case 3:
+ console.log("Starting restart tests in 1 secs...");
+ return setTimeout(doAsycTests.bind(null, ++step), 1000);
+ }
+}
diff --git a/test.sh b/test.sh
deleted file mode 100755
index cfe9b9f0..00000000
--- a/test.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-./build.sh test
-echo "Running mozmill tests..."
-if [ "debug" == "$1" ]; then
- mozmill -t tests/mozmill-tests -a scriptish-test.xpi --show-all
-else
- mozmill -t tests/mozmill-tests -a scriptish-test.xpi
-fi
-
-echo "Starting restart tests in 10 secs... (Press ctrl+z to cancel)"
-sleep 7
-echo "Starting restart tests in 3 secs..."
-sleep 1
-echo "Starting restart tests in 2 secs..."
-sleep 1
-echo "Starting restart tests in 1 secs..."
-sleep 1
-echo "Running mozmill-restart tests..."
-
-if [ "debug" == "$1" ]; then
- mozmill-restart -t tests/mozmill-tests/tests/restartTests -a scriptish-test.xpi --show-all
-else
- mozmill-restart -t tests/mozmill-tests/tests/restartTests -a scriptish-test.xpi
-fi