Created
August 2, 2014 12:16
-
-
Save caisui/993c9b1bfed1cf4d96b8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
手動で、liberatorCache を 削除して下さい