Skip to content

Instantly share code, notes, and snippets.

@caisui
Created August 2, 2014 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caisui/993c9b1bfed1cf4d96b8 to your computer and use it in GitHub Desktop.
Save caisui/993c9b1bfed1cf4d96b8 to your computer and use it in GitHub Desktop.
diff --git a/common/content/javascript.js b/common/content/javascript.js
index 5d18212..4d9d789 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -637,8 +637,10 @@ const JavaScript = Module("javascript", {
options.add(["inspectcontentobjects"],
"Allow completion of JavaScript objects coming from web content. POSSIBLY INSECURE!",
"boolean", false);
- options.add(["expandtemplate"],
- "Expand TemplateLiteral",
- "boolean", !("XMLList" in window));
+ if (liberator.has("notemplate")) {
+ options.add(["expandtemplate"],
+ "Expand TemplateLiteral",
+ "boolean", !("XMLList" in window));
+ }
}
})
diff --git a/common/content/liberator-overlay.js b/common/content/liberator-overlay.js
index d21cef6..2a24405 100644
--- a/common/content/liberator-overlay.js
+++ b/common/content/liberator-overlay.js
@@ -5,7 +5,8 @@
(function () {
const modules = {};
- const BASE = "liberator://template/chrome://liberator/content/"
+ const templateString = Cu.import("resource://liberator/CheckTemplate.jsm", {}).supported;
+ const BASE = templateString ? "chrome://liberator/content/" : "liberator://template/chrome://liberator/content/";
modules.modules = modules;
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 1661bb8..36340de 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -70,7 +70,11 @@ const Liberator = Module("liberator", {
config.features.add(platform);
if (/^Win(32|64)$/.test(platform))
config.features.add('Windows');
-
+
+ if (!Cu.import("resource://liberator/CheckTemplate.jsm", {}).supported) {
+ config.features.add("notemplate");
+ }
+
if (AddonManager) {
let self = this;
self._extensions = [];
@@ -332,7 +336,7 @@ const Liberator = Module("liberator", {
* should be loaded.
*/
loadScript: function (uri, context) {
- if (options.expandtemplate) {
+ if (this.has("notemplate") && options.expandtemplate) {
var prefix = "liberator://template/";
if (uri.lastIndexOf(prefix, 0) === -1)
uri = prefix + uri;
@@ -345,7 +349,7 @@ const Liberator = Module("liberator", {
if (!context)
context = userContext;
- if (options.expandtemplate) {
+ if (this.has("notemplate") && options.expandtemplate) {
var obj = new Object;
Cu.import("resource://liberator/template.js", obj);
str = obj.convert(str);
diff --git a/common/modules/CheckTemplate.jsm b/common/modules/CheckTemplate.jsm
new file mode 100644
index 0000000..171cacb
--- /dev/null
+++ b/common/modules/CheckTemplate.jsm
@@ -0,0 +1,8 @@
+// vim:ft=javascript:
+
+this.EXPORTED_SYMBOLS = ["supported"];
+try {
+ var supported = eval("((a,b)=>a.raw)`${1}`.length==2");
+} catch (ex) {
+ supported = false;
+}
diff --git a/common/modules/template-tag.js b/common/modules/template-tag.js
index 1926150..979ea52 100644
--- a/common/modules/template-tag.js
+++ b/common/modules/template-tag.js
@@ -1,5 +1,5 @@
// vim: set fdm=marker:
-var EXPORTED_SYMBOLS = ["raw", "safehtml", "tmpl", "xml", "e4x", "cooked"];
+var EXPORTED_SYMBOLS = ["raw", "safehtml", "xml", "e4x", "cooked"];
// {{{ escape function
//var obj1 = {};
@@ -60,315 +60,7 @@ function TemplateXML(s) {this.value = s;}
TemplateXML.prototype = new TemplateSupportsXML;
TemplateXML.prototype.toString = function () this.value;
-function TemplateTmpl(s) {this.value = s;} //{{{
-TemplateTmpl.prototype = new TemplateSupportsXML;
-TemplateTmpl.prototype.toString = function () this.value;
-TemplateTmpl.prototype.toXMLString = function () {
- var str = this.value;
- const whiteSpace = /^\s*/y;
- const tagToken = /^([^`"',\s\[\]\{\}\(\)]+)\s*(\[)?/y;
- const attrToken = /^\s*([^\s=]+)\s*=\s*(\S)/y;
- const attrSep = /^\s*(\s|])/y;
- const STATE = 0, NAME = 1, OPEN = 2;
- const TAG = {}, ROOT = {}, GROUP = {};
- var offset = 0;
- var start = 0;
- var res = "";
- var stack = [];
- var depth = 0;
- var state = [ROOT];
- var m;
- label_root: while (1) {
- whiteSpace.lastIndex = offset;
- m = whiteSpace.exec(str);
- if (!m) throw SyntaxError("ws");
- offset = whiteSpace.lastIndex;
- c = str[offset++];
- if (!c) break;
- switch (c) {
- case "{":
- if (state[STATE] === TAG && state[OPEN]) {
- res += ">";
- state[OPEN] = false;
- }
- start = offset;
- while (c = str[offset++]) {
- if (c === "\\") {
- res += str.substring(start, offset - 1);
- start = offset++;
- }
- else if (c === "}") {
- res += escapeHTML(str.substring(start, offset - 1));
- continue label_root;
- }
- }
- throw SyntaxError("text");
- case "`":
- if (state[STATE] === TAG && state[OPEN]) {
- res += ">";
- state[OPEN] = false;
- }
- start = offset;
- while (c = str[offset++]) {
- if (c === "\\") {
- res += str.substring(start, offset - 1);
- start = offset++;
- } else if (c === "`") {
- res += str.substring(start, offset - 1);
- continue label_root;
- }
- }
- throw SyntaxError("xml");
- case "(":
- if (state[STATE] === TAG && state[OPEN]) {
- res += ">";
- state[OPEN] = false;
- }
- stack[depth++] = state;
- state = [GROUP];
- break;
- case ")":
- do {
- switch (state[STATE]) {
- case TAG:
- if (state[OPEN]) {
- res += "/>";
- state[OPEN] = false;
- } else {
- res += "</" + state[NAME] + ">";
- }
- break;
- case GROUP:
- state = stack[--depth];
- continue label_root;
- case ROOT:
- throw SyntaxError(")");
- }
- } while (state = stack[--depth]);
- throw SyntaxError(")");
- case ",":
- do {
- switch (state[STATE]) {
- case TAG:
- if (state[OPEN]) {
- res += "/>";
- state[OPEN] = false;
- } else {
- res += "</" + state[NAME] + ">";
- }
- break;
- case GROUP:
- case ROOT:
- continue label_root;
- }
- } while (state = stack[--depth]);
- throw SyntaxError(")");
- default:
- if (state[STATE] === TAG && state[OPEN]) {
- res += ">";
- state[OPEN] = false;
- }
- tagToken.lastIndex = offset - 1;
- m = tagToken.exec(str);
- if (!m) throw SyntaxError("tag");
- offset = tagToken.lastIndex;
- res += "<" + m[1];
- stack[depth++] = state;
- state = [TAG, m[1], true];
- if (m[2]) {
- label_attr: while (1) {
- attrToken.lastIndex = offset;
- m = attrToken.exec(str);
- if (!m) throw new SyntaxError("attr");
- offset = attrToken.lastIndex;
- res += " " + m[1] + "=";
- start = offset;
- close = m[2];
- while (c = str[offset++]) {
- if (c === close) {
- res += close + str.substring(start, offset - 1) + close;
- attrSep.lastIndex = offset;
- m = attrSep.exec(str);
- if (!m) throw SyntaxError("attr sep");
- offset = attrSep.lastIndex;
- if (m[1] === "]") {
- break label_attr;
- }
- continue label_attr;
- }
- }
- }
- }
- break;
- }
- }
- if (state[STATE] === TAG) res += state[OPEN] ? "/>" : "</" + state[NAME] + ">";
- while (state = stack[--depth]) {
- if (state[STATE] === TAG)
- res += "</" + state[NAME] + ">";
- }
- return res;
-};//}}}
-
-function templateTmpl(portion, args) // {{{
-{
- var res = "";
-
- const BODY = {}, ATTR1 = {}, ATTR2 = {}, TEXT = {}, XML = {};
-
- var c;
- var raw = portion.raw;
- var i = 0, j = args.length;
-
- var depth = 0;
-
- var state = BODY, offset = 0;
- var str = raw[0], arg = args[0];
- var res = str;
- label_root: while (1) {
- switch(state) {
- case BODY:
- while (c = str[offset++]) {
- switch (c) {
- case "[":
- state = ATTR1;
- continue label_root;
- case "`":
- state = XML;
- continue label_root;
- case "{":
- state = TEXT;
- continue label_root;
- case "(":
- depth++;
- break;
- case ")":
- if (--depth < 0) throw SyntaxError("depth");
- break;
- }
- }
- if (i >= j) break label_root;
- else if (typeof arg === "xml") {
- res += "`" + arg.toXMLString().replace(/([\\`])/g, "\\$1", "g") + "`";
- } else if (arg instanceof TemplateTmpl) {
- res += "(" + arg.value + ")";
- } else if (arg instanceof TemplateXML) {
- res += "`" + arg.value.replace(/([\\`])/g, "\\$1", "g") + "`";
- } else {
- res += "{" + String.replace(arg, /([\\}])/g, "\\$1") + "}";
- }
- break;
- case ATTR1:
- while (c = str[offset++]) {
- if (c === "=") {
- state = ATTR2;
- continue label_root;
- } else if (c === "]") {
- state = BODY;
- continue label_root;
- }
- }
- if (i >= j) throw SyntaxError("attr left");
- arg = String(arg);
- if (/[=\[\]!"#$%&']/.test(arg)) throw SyntaxError("substitude:" + i);
- res += arg;
- break;
- case ATTR2:
- c1 = str[offset++];
- if (!c1) {
- if (i >= j) throw SyntaxError("attr right");
- arg = String(arg);
- res += '"' + String.replace(arg, /"/g, '\\"', "g") + '"';
- state = ATTR1;
- break;
- }
- else if (c1 === "{") c1 = "}";
- while (c = str[offset++]) {
- if (c === "\\") offset++;
- else if (c === c1) {
- state = ATTR1;
- continue label_root;
- }
- }
- // do not support attribute's value nesting
- throw SyntaxError("attr2");
- break;
- case TEXT:
- while (c = str[offset++]) {
- if (c === "\\") offset++;
- else if (c === "}") {
- state = BODY;
- continue label_root;
- }
- }
- if (i >= j) throw SyntaxError("text");
- arg = String(arg);
- res += '{' + String.replace(arg, /}/g, '\\}', "g") + '}';
- break;
- case XML:
- while (c = str[offset++]) {
- if (c === "\\") offset++;
- else if (c === "`") {
- state = BODY;
- continue label_root;
- }
- }
- // do not support xml nesting
- throw SyntaxError("xml");
- break;
- default:
- throw SyntaxError("unknown state");
- }
-
- str = raw[++i];
- arg = args[i];
- res += str;
- offset = 0;
- }
- if (depth !== 0) throw SyntaxError("depth");
- return new TemplateTmpl(res);
-}
-
-// xxx: no check
-templateTmpl.raw = function templateTmplRaw(portion, args) {
- return new TemplateTmpl(templateRaw(portion, args));
-};
-templateTmpl.map = function templateTmplMap(data, fn) {
- var val, res = "";
- for (var i = 0, j = data.length; i < j; i++) {
- val = fn(data[i]);
- if (val instanceof TemplateTmpl)
- res += "(" + val.value + ")";
- else if (typeof val === "xml")
- res += encodeTmplXml(val.toXMLString());
- else if (val instanceof TemplateXML)
- res += encodeTmplXml(val.value);
- else
- res += encodeTmplText(val);
- }
- return new TemplateTmpl(res);
-};
-templateTmpl.is = function is(obj) {
- return obj instanceof TemplateTmpl;
-};
-templateTmpl.isEmpty = function isEmpty() {
- return (value instanceof TemplateXML || value instanceof TemplateTmpl) && value.value === "";
-};
-templateTmpl["+="] = function (self, value) {
- if (!(self instanceof TemplateTmpl)) throw SyntaxError();
- else if (value instanceof TemplateTmpl)
- self.value += "(" + value.value + ")";
- else if (value instanceof TemplateXML)
- self.value += "`" + value.value.replace(/`/g, "\\`") + "`";
- else if (typeof value === "xml")
- self.value += "`" + value.toXMLString().replace(/`/g, "\\`") + "`";
- else
- self.value = "{" + String(value).replace(/}/g, "\\}") + "}";
- return self;
-};
-//}}}
-
-function templateXML(portion, args) // {{{
+function templateXML(portion, ...args) // {{{
{
var res = "";
@@ -420,7 +112,7 @@ function templateXML(portion, args) // {{{
}
}
if (i >= j) break label_root;
- else if (arg instanceof TemplateTmpl || typeof arg === "xml") {
+ else if (typeof arg === "xml") {
res += arg.toXMLString();
} else if (arg instanceof TemplateXML) {
res += arg.value;
@@ -521,7 +213,7 @@ templateXML.map = function templateXmlMap(data, fn) {
var val, res = "";
for (var i = 0, j = data.length; i < j; i++) {
val = fn(data[i]);
- if (val instanceof TemplateTmpl || typeof val === "xml")
+ if (typeof val === "xml")
res += val.toXMLString();
else if (val instanceof TemplateXML)
res += val.value;
@@ -546,8 +238,6 @@ templateXML.cdata = function templateXmlCDATA(portion, args) {
};
templateXML["+="] = function (self, value) {
if (!(self instanceof TemplateXML)) throw SyntaxError();
- else if (value instanceof TemplateTmpl)
- self.value += value.toXMLString();
else if (value instanceof TemplateXML)
self.value += value.value;
else if (typeof value === "xml")
@@ -560,11 +250,11 @@ templateXML.is = function is(obj) {
return obj instanceof TemplateXML;
};
templateXML.isEmpty = function (value) {
- return (value instanceof TemplateXML || value instanceof TemplateTmpl) && value.value === "";
+ return (value instanceof TemplateXML) && value.value === "";
};
//}}}
-function templateRaw(portion, args) {
+function templateRaw(portion, ...args) {
var raw = portion.raw;
var i = 0, j = args.length, res = raw[0];
while (i < j) {
@@ -574,7 +264,7 @@ function templateRaw(portion, args) {
return res;
}
-function templateCooked(portion, args) {
+function templateCooked(portion, ...args) {
var str = portion.cooked;
var i = 0, j = args.length, res = str[0];
while (i < j) {
@@ -584,7 +274,7 @@ function templateCooked(portion, args) {
return res;
}
-function templateSafeHtml(portion, args) {
+function templateSafeHtml(portion, ...args) {
var raw = portion.raw;
var i = 0, j = args.length, res = raw[0];
while (i < j) {
@@ -611,9 +301,7 @@ templateE4X.cdata = function cdata(portion, args) {
};
templateE4X["+"] = function operatorPlus(lhs, rhs) {
function toE4X(a) {
- if (a instanceof TemplateTmpl)
- return new XMLList(a.toXMLString());
- else if (a instanceof TemplateXML)
+ if (a instanceof TemplateXML)
return new XMLList(a.toString());
else
return a;
@@ -622,9 +310,7 @@ templateE4X["+"] = function operatorPlus(lhs, rhs) {
};
// xxx: xml object to E4X
templateE4X.cast = function cast(obj) {
- if (obj instanceof TemplateTmpl)
- return new XMLList(obj.toXMLString());
- else if (obj instanceof TemplateXML)
+ if (obj instanceof TemplateXML)
return new XMLList(obj.value);
else
return obj;
@@ -636,7 +322,6 @@ templateE4X["+="] = function (self, value) {
};
//}}}
-var tmpl = templateTmpl;
var xml = templateXML;
var e4x = templateE4X;
var raw = templateRaw;
diff --git a/common/modules/template.js b/common/modules/template.js
index 76dfacb..2822e7a 100644
--- a/common/modules/template.js
+++ b/common/modules/template.js
@@ -154,7 +154,7 @@ function convert(str, options) {
'({\
raw: ["' + raw.join('", "') + '"],\
cooked: ["' + cooked.join('", "') + '"]' +
-'}, [' + substitude + '])';
+'}, ...[' + substitude + '])';
} else {
// default handler
@@ -372,7 +372,7 @@ cooked: ["' + cooked.join('", "') + '"]' +
args.push("`" + res + rest + "`");
res = "";
}
- rest = tag + "(({raw: [" + raw.join(", ") + "]}), [" + args.join(", ") + "])";
+ rest = tag + "(({raw: [" + raw.join(", ") + "]}), ...[" + args.join(", ") + "])";
break;
}
}
@@ -381,7 +381,7 @@ cooked: ["' + cooked.join('", "') + '"]' +
let [,,tag, raw, args] = state;
raw = raw.map(function (r) '"' + r.replace(reRawEscape, fnRawEscape) + '"');
args.push(rest);
- rest = tag + "(({raw: [" + raw.join(", ") + "]}), [" + args.join(", ") + "])";
+ rest = tag + "(({raw: [" + raw.join(", ") + "]}), ...[" + args.join(", ") + "])";
}
}
return res + rest;
@caisui
Copy link
Author

caisui commented Aug 2, 2014

手動で、liberatorCache を 削除して下さい

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment