Add files via upload
This commit is contained in:
parent
09cf837da5
commit
1f31c2b875
7610
JS/drpy2.js
7610
JS/drpy2.js
File diff suppressed because one or more lines are too long
6090
JS/drpy2.min.js
vendored
6090
JS/drpy2.min.js
vendored
File diff suppressed because it is too large
Load Diff
504
JS/jinja.min.js
vendored
Normal file
504
JS/jinja.min.js
vendored
Normal file
@ -0,0 +1,504 @@
|
||||
(function(global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.jinja = {}))
|
||||
})(this, function(jinja) {
|
||||
"use strict";
|
||||
var STRINGS = /'(\\.|[^'])*'|"(\\.|[^"'"])*"/g;
|
||||
var IDENTS_AND_NUMS = /([$_a-z][$\w]*)|([+-]?\d+(\.\d+)?)/g;
|
||||
var NUMBER = /^[+-]?\d+(\.\d+)?$/;
|
||||
var NON_PRIMITIVES = /\[[@#~](,[@#~])*\]|\[\]|\{([@i]:[@#~])(,[@i]:[@#~])*\}|\{\}/g;
|
||||
var IDENTIFIERS = /[$_a-z][$\w]*/gi;
|
||||
var VARIABLES = /i(\.i|\[[@#i]\])*/g;
|
||||
var ACCESSOR = /(\.i|\[[@#i]\])/g;
|
||||
var OPERATORS = /(===?|!==?|>=?|<=?|&&|\|\||[+\-\*\/%])/g;
|
||||
var EOPS = /(^|[^$\w])(and|or|not|is|isnot)([^$\w]|$)/g;
|
||||
var LEADING_SPACE = /^\s+/;
|
||||
var TRAILING_SPACE = /\s+$/;
|
||||
var START_TOKEN = /\{\{\{|\{\{|\{%|\{#/;
|
||||
var TAGS = {
|
||||
"{{{": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}\}/,
|
||||
"{{": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}/,
|
||||
"{%": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?%\}/,
|
||||
"{#": /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?#\}/
|
||||
};
|
||||
var delimeters = {
|
||||
"{%": "directive",
|
||||
"{{": "output",
|
||||
"{#": "comment"
|
||||
};
|
||||
var operators = {
|
||||
and: "&&",
|
||||
or: "||",
|
||||
not: "!",
|
||||
is: "==",
|
||||
isnot: "!="
|
||||
};
|
||||
var constants = {
|
||||
true: true,
|
||||
false: false,
|
||||
null: null
|
||||
};
|
||||
|
||||
function Parser() {
|
||||
this.nest = [];
|
||||
this.compiled = [];
|
||||
this.childBlocks = 0;
|
||||
this.parentBlocks = 0;
|
||||
this.isSilent = false
|
||||
}
|
||||
Parser.prototype.push = function(line) {
|
||||
if (!this.isSilent) {
|
||||
this.compiled.push(line)
|
||||
}
|
||||
};
|
||||
Parser.prototype.parse = function(src) {
|
||||
this.tokenize(src);
|
||||
return this.compiled
|
||||
};
|
||||
Parser.prototype.tokenize = function(src) {
|
||||
var lastEnd = 0,
|
||||
parser = this,
|
||||
trimLeading = false;
|
||||
matchAll(src, START_TOKEN, function(open, index, src) {
|
||||
var match = src.slice(index + open.length).match(TAGS[open]);
|
||||
match = match ? match[0] : "";
|
||||
var simplified = match.replace(STRINGS, "@");
|
||||
if (!match || ~simplified.indexOf(open)) {
|
||||
return index + 1
|
||||
}
|
||||
var inner = match.slice(0, 0 - open.length);
|
||||
if (inner.charAt(0) === "-") var wsCollapseLeft = true;
|
||||
if (inner.slice(-1) === "-") var wsCollapseRight = true;
|
||||
inner = inner.replace(/^-|-$/g, "").trim();
|
||||
if (parser.rawMode && open + inner !== "{%endraw") {
|
||||
return index + 1
|
||||
}
|
||||
var text = src.slice(lastEnd, index);
|
||||
lastEnd = index + open.length + match.length;
|
||||
if (trimLeading) text = trimLeft(text);
|
||||
if (wsCollapseLeft) text = trimRight(text);
|
||||
if (wsCollapseRight) trimLeading = true;
|
||||
if (open === "{{{") {
|
||||
open = "{{";
|
||||
inner += "|safe"
|
||||
}
|
||||
parser.textHandler(text);
|
||||
parser.tokenHandler(open, inner)
|
||||
});
|
||||
var text = src.slice(lastEnd);
|
||||
if (trimLeading) text = trimLeft(text);
|
||||
this.textHandler(text)
|
||||
};
|
||||
Parser.prototype.textHandler = function(text) {
|
||||
this.push("write(" + JSON.stringify(text) + ");")
|
||||
};
|
||||
Parser.prototype.tokenHandler = function(open, inner) {
|
||||
var type = delimeters[open];
|
||||
if (type === "directive") {
|
||||
this.compileTag(inner)
|
||||
} else if (type === "output") {
|
||||
var extracted = this.extractEnt(inner, STRINGS, "@");
|
||||
extracted.src = extracted.src.replace(/\|\|/g, "~").split("|");
|
||||
extracted.src = extracted.src.map(function(part) {
|
||||
return part.split("~").join("||")
|
||||
});
|
||||
var parts = this.injectEnt(extracted, "@");
|
||||
if (parts.length > 1) {
|
||||
var filters = parts.slice(1).map(this.parseFilter.bind(this));
|
||||
this.push("filter(" + this.parseExpr(parts[0]) + "," + filters.join(",") + ");")
|
||||
} else {
|
||||
this.push("filter(" + this.parseExpr(parts[0]) + ");")
|
||||
}
|
||||
}
|
||||
};
|
||||
Parser.prototype.compileTag = function(str) {
|
||||
var directive = str.split(" ")[0];
|
||||
var handler = tagHandlers[directive];
|
||||
if (!handler) {
|
||||
throw new Error("Invalid tag: " + str)
|
||||
}
|
||||
handler.call(this, str.slice(directive.length).trim())
|
||||
};
|
||||
Parser.prototype.parseFilter = function(src) {
|
||||
src = src.trim();
|
||||
var match = src.match(/[:(]/);
|
||||
var i = match ? match.index : -1;
|
||||
if (i < 0) return JSON.stringify([src]);
|
||||
var name = src.slice(0, i);
|
||||
var args = src.charAt(i) === ":" ? src.slice(i + 1) : src.slice(i + 1, -1);
|
||||
args = this.parseExpr(args, {
|
||||
terms: true
|
||||
});
|
||||
return "[" + JSON.stringify(name) + "," + args + "]"
|
||||
};
|
||||
Parser.prototype.extractEnt = function(src, regex, placeholder) {
|
||||
var subs = [],
|
||||
isFunc = typeof placeholder == "function";
|
||||
src = src.replace(regex, function(str) {
|
||||
var replacement = isFunc ? placeholder(str) : placeholder;
|
||||
if (replacement) {
|
||||
subs.push(str);
|
||||
return replacement
|
||||
}
|
||||
return str
|
||||
});
|
||||
return {
|
||||
src: src,
|
||||
subs: subs
|
||||
}
|
||||
};
|
||||
Parser.prototype.injectEnt = function(extracted, placeholder) {
|
||||
var src = extracted.src,
|
||||
subs = extracted.subs,
|
||||
isArr = Array.isArray(src);
|
||||
var arr = isArr ? src : [src];
|
||||
var re = new RegExp("[" + placeholder + "]", "g"),
|
||||
i = 0;
|
||||
arr.forEach(function(src, index) {
|
||||
arr[index] = src.replace(re, function() {
|
||||
return subs[i++]
|
||||
})
|
||||
});
|
||||
return isArr ? arr : arr[0]
|
||||
};
|
||||
Parser.prototype.replaceComplex = function(s) {
|
||||
var parsed = this.extractEnt(s, /i(\.i|\[[@#i]\])+/g, "v");
|
||||
parsed.src = parsed.src.replace(NON_PRIMITIVES, "~");
|
||||
return this.injectEnt(parsed, "v")
|
||||
};
|
||||
Parser.prototype.parseExpr = function(src, opts) {
|
||||
opts = opts || {};
|
||||
var parsed1 = this.extractEnt(src, STRINGS, "@");
|
||||
parsed1.src = parsed1.src.replace(EOPS, function(s, before, op, after) {
|
||||
return op in operators ? before + operators[op] + after : s
|
||||
});
|
||||
var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function(s) {
|
||||
return s in constants || NUMBER.test(s) ? "#" : null
|
||||
});
|
||||
var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, "i");
|
||||
parsed3.src = parsed3.src.replace(/\s+/g, "");
|
||||
var simplified = parsed3.src;
|
||||
while (simplified !== (simplified = this.replaceComplex(simplified)));
|
||||
while (simplified !== (simplified = simplified.replace(/i(\.i|\[[@#i]\])+/, "v")));
|
||||
simplified = simplified.replace(/[iv]\[v?\]/g, "x");
|
||||
simplified = simplified.replace(/[@#~v]/g, "i");
|
||||
simplified = simplified.replace(OPERATORS, "%");
|
||||
simplified = simplified.replace(/!+[i]/g, "i");
|
||||
var terms = opts.terms ? simplified.split(",") : [simplified];
|
||||
terms.forEach(function(term) {
|
||||
while (term !== (term = term.replace(/\(i(%i)*\)/g, "i")));
|
||||
if (!term.match(/^i(%i)*/)) {
|
||||
throw new Error("Invalid expression: " + src + " " + term)
|
||||
}
|
||||
});
|
||||
parsed3.src = parsed3.src.replace(VARIABLES, this.parseVar.bind(this));
|
||||
parsed2.src = this.injectEnt(parsed3, "i");
|
||||
parsed1.src = this.injectEnt(parsed2, "#");
|
||||
return this.injectEnt(parsed1, "@")
|
||||
};
|
||||
Parser.prototype.parseVar = function(src) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var str = args.pop(),
|
||||
index = args.pop();
|
||||
if (src === "i" && str.charAt(index + 1) === ":") {
|
||||
return '"i"'
|
||||
}
|
||||
var parts = ['"i"'];
|
||||
src.replace(ACCESSOR, function(part) {
|
||||
if (part === ".i") {
|
||||
parts.push('"i"')
|
||||
} else if (part === "[i]") {
|
||||
parts.push('get("i")')
|
||||
} else {
|
||||
parts.push(part.slice(1, -1))
|
||||
}
|
||||
});
|
||||
return "get(" + parts.join(",") + ")"
|
||||
};
|
||||
Parser.prototype.escName = function(str) {
|
||||
return str.replace(/\W/g, function(s) {
|
||||
return "$" + s.charCodeAt(0).toString(16)
|
||||
})
|
||||
};
|
||||
Parser.prototype.parseQuoted = function(str) {
|
||||
if (str.charAt(0) === "'") {
|
||||
str = str.slice(1, -1).replace(/\\.|"/, function(s) {
|
||||
if (s === "\\'") return "'";
|
||||
return s.charAt(0) === "\\" ? s : "\\" + s
|
||||
});
|
||||
str = '"' + str + '"'
|
||||
}
|
||||
return JSON.parse(str)
|
||||
};
|
||||
var tagHandlers = {
|
||||
if: function(expr) {
|
||||
this.push("if (" + this.parseExpr(expr) + ") {");
|
||||
this.nest.unshift("if")
|
||||
},
|
||||
else: function() {
|
||||
if (this.nest[0] === "for") {
|
||||
this.push("}, function() {")
|
||||
} else {
|
||||
this.push("} else {")
|
||||
}
|
||||
},
|
||||
elseif: function(expr) {
|
||||
this.push("} else if (" + this.parseExpr(expr) + ") {")
|
||||
},
|
||||
endif: function() {
|
||||
this.nest.shift();
|
||||
this.push("}")
|
||||
},
|
||||
for: function(str) {
|
||||
var i = str.indexOf(" in ");
|
||||
var name = str.slice(0, i).trim();
|
||||
var expr = str.slice(i + 4).trim();
|
||||
this.push("each(" + this.parseExpr(expr) + "," + JSON.stringify(name) + ",function() {");
|
||||
this.nest.unshift("for")
|
||||
},
|
||||
endfor: function() {
|
||||
this.nest.shift();
|
||||
this.push("});")
|
||||
},
|
||||
raw: function() {
|
||||
this.rawMode = true
|
||||
},
|
||||
endraw: function() {
|
||||
this.rawMode = false
|
||||
},
|
||||
set: function(stmt) {
|
||||
var i = stmt.indexOf("=");
|
||||
var name = stmt.slice(0, i).trim();
|
||||
var expr = stmt.slice(i + 1).trim();
|
||||
this.push("set(" + JSON.stringify(name) + "," + this.parseExpr(expr) + ");")
|
||||
},
|
||||
block: function(name) {
|
||||
if (this.isParent) {
|
||||
++this.parentBlocks;
|
||||
var blockName = "block_" + (this.escName(name) || this.parentBlocks);
|
||||
this.push("block(typeof " + blockName + ' == "function" ? ' + blockName + " : function() {")
|
||||
} else if (this.hasParent) {
|
||||
this.isSilent = false;
|
||||
++this.childBlocks;
|
||||
blockName = "block_" + (this.escName(name) || this.childBlocks);
|
||||
this.push("function " + blockName + "() {")
|
||||
}
|
||||
this.nest.unshift("block")
|
||||
},
|
||||
endblock: function() {
|
||||
this.nest.shift();
|
||||
if (this.isParent) {
|
||||
this.push("});")
|
||||
} else if (this.hasParent) {
|
||||
this.push("}");
|
||||
this.isSilent = true
|
||||
}
|
||||
},
|
||||
extends: function(name) {
|
||||
name = this.parseQuoted(name);
|
||||
var parentSrc = this.readTemplateFile(name);
|
||||
this.isParent = true;
|
||||
this.tokenize(parentSrc);
|
||||
this.isParent = false;
|
||||
this.hasParent = true;
|
||||
this.isSilent = true
|
||||
},
|
||||
include: function(name) {
|
||||
name = this.parseQuoted(name);
|
||||
var incSrc = this.readTemplateFile(name);
|
||||
this.isInclude = true;
|
||||
this.tokenize(incSrc);
|
||||
this.isInclude = false
|
||||
}
|
||||
};
|
||||
tagHandlers.assign = tagHandlers.set;
|
||||
tagHandlers.elif = tagHandlers.elseif;
|
||||
var getRuntime = function runtime(data, opts) {
|
||||
var defaults = {
|
||||
autoEscape: "toJson"
|
||||
};
|
||||
var _toString = Object.prototype.toString;
|
||||
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var getKeys = Object.keys || function(obj) {
|
||||
var keys = [];
|
||||
for (var n in obj)
|
||||
if (_hasOwnProperty.call(obj, n)) keys.push(n);
|
||||
return keys
|
||||
};
|
||||
var isArray = Array.isArray || function(obj) {
|
||||
return _toString.call(obj) === "[object Array]"
|
||||
};
|
||||
var create = Object.create || function(obj) {
|
||||
function F() {}
|
||||
F.prototype = obj;
|
||||
return new F
|
||||
};
|
||||
var toString = function(val) {
|
||||
if (val == null) return "";
|
||||
return typeof val.toString == "function" ? val.toString() : _toString.call(val)
|
||||
};
|
||||
var extend = function(dest, src) {
|
||||
var keys = getKeys(src);
|
||||
for (var i = 0, len = keys.length; i < len; i++) {
|
||||
var key = keys[i];
|
||||
dest[key] = src[key]
|
||||
}
|
||||
return dest
|
||||
};
|
||||
var get = function() {
|
||||
var val, n = arguments[0],
|
||||
c = stack.length;
|
||||
while (c--) {
|
||||
val = stack[c][n];
|
||||
if (typeof val != "undefined") break
|
||||
}
|
||||
for (var i = 1, len = arguments.length; i < len; i++) {
|
||||
if (val == null) continue;
|
||||
n = arguments[i];
|
||||
val = _hasOwnProperty.call(val, n) ? val[n] : typeof val._get == "function" ? val[n] = val._get(n) : null
|
||||
}
|
||||
return val == null ? "" : val
|
||||
};
|
||||
var set = function(n, val) {
|
||||
stack[stack.length - 1][n] = val
|
||||
};
|
||||
var push = function(ctx) {
|
||||
stack.push(ctx || {})
|
||||
};
|
||||
var pop = function() {
|
||||
stack.pop()
|
||||
};
|
||||
var write = function(str) {
|
||||
output.push(str)
|
||||
};
|
||||
var filter = function(val) {
|
||||
for (var i = 1, len = arguments.length; i < len; i++) {
|
||||
var arr = arguments[i],
|
||||
name = arr[0],
|
||||
filter = filters[name];
|
||||
if (filter) {
|
||||
arr[0] = val;
|
||||
val = filter.apply(data, arr)
|
||||
} else {
|
||||
throw new Error("Invalid filter: " + name)
|
||||
}
|
||||
}
|
||||
if (opts.autoEscape && name !== opts.autoEscape && name !== "safe") {
|
||||
val = filters[opts.autoEscape].call(data, val)
|
||||
}
|
||||
output.push(val)
|
||||
};
|
||||
var each = function(obj, loopvar, fn1, fn2) {
|
||||
if (obj == null) return;
|
||||
var arr = isArray(obj) ? obj : getKeys(obj),
|
||||
len = arr.length;
|
||||
var ctx = {
|
||||
loop: {
|
||||
length: len,
|
||||
first: arr[0],
|
||||
last: arr[len - 1]
|
||||
}
|
||||
};
|
||||
push(ctx);
|
||||
for (var i = 0; i < len; i++) {
|
||||
extend(ctx.loop, {
|
||||
index: i + 1,
|
||||
index0: i
|
||||
});
|
||||
fn1(ctx[loopvar] = arr[i])
|
||||
}
|
||||
if (len === 0 && fn2) fn2();
|
||||
pop()
|
||||
};
|
||||
var block = function(fn) {
|
||||
push();
|
||||
fn();
|
||||
pop()
|
||||
};
|
||||
var render = function() {
|
||||
return output.join("")
|
||||
};
|
||||
data = data || {};
|
||||
opts = extend(defaults, opts || {});
|
||||
var filters = extend({
|
||||
html: function(val) {
|
||||
return toString(val).split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""")
|
||||
},
|
||||
safe: function(val) {
|
||||
return val
|
||||
},
|
||||
toJson: function(val) {
|
||||
if (typeof val === "object") {
|
||||
return JSON.stringify(val)
|
||||
}
|
||||
return toString(val)
|
||||
}
|
||||
}, opts.filters || {});
|
||||
var stack = [create(data || {})],
|
||||
output = [];
|
||||
return {
|
||||
get: get,
|
||||
set: set,
|
||||
push: push,
|
||||
pop: pop,
|
||||
write: write,
|
||||
filter: filter,
|
||||
each: each,
|
||||
block: block,
|
||||
render: render
|
||||
}
|
||||
};
|
||||
var runtime;
|
||||
jinja.compile = function(markup, opts) {
|
||||
opts = opts || {};
|
||||
var parser = new Parser;
|
||||
parser.readTemplateFile = this.readTemplateFile;
|
||||
var code = [];
|
||||
code.push("function render($) {");
|
||||
code.push("var get = $.get, set = $.set, push = $.push, pop = $.pop, write = $.write, filter = $.filter, each = $.each, block = $.block;");
|
||||
code.push.apply(code, parser.parse(markup));
|
||||
code.push("return $.render();");
|
||||
code.push("}");
|
||||
code = code.join("\n");
|
||||
if (opts.runtime === false) {
|
||||
var fn = new Function("data", "options", "return (" + code + ")(runtime(data, options))")
|
||||
} else {
|
||||
runtime = runtime || (runtime = getRuntime.toString());
|
||||
fn = new Function("data", "options", "return (" + code + ")((" + runtime + ")(data, options))")
|
||||
}
|
||||
return {
|
||||
render: fn
|
||||
}
|
||||
};
|
||||
jinja.render = function(markup, data, opts) {
|
||||
var tmpl = jinja.compile(markup);
|
||||
return tmpl.render(data, opts)
|
||||
};
|
||||
jinja.templateFiles = [];
|
||||
jinja.readTemplateFile = function(name) {
|
||||
var templateFiles = this.templateFiles || [];
|
||||
var templateFile = templateFiles[name];
|
||||
if (templateFile == null) {
|
||||
throw new Error("Template file not found: " + name)
|
||||
}
|
||||
return templateFile
|
||||
};
|
||||
|
||||
function trimLeft(str) {
|
||||
return str.replace(LEADING_SPACE, "")
|
||||
}
|
||||
|
||||
function trimRight(str) {
|
||||
return str.replace(TRAILING_SPACE, "")
|
||||
}
|
||||
|
||||
function matchAll(str, reg, fn) {
|
||||
reg = new RegExp(reg.source, "g" + (reg.ignoreCase ? "i" : "") + (reg.multiline ? "m" : ""));
|
||||
var match;
|
||||
while (match = reg.exec(str)) {
|
||||
var result = fn(match[0], match.index, str);
|
||||
if (typeof result == "number") {
|
||||
reg.lastIndex = result
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user