mirror of
https://github.com/sstent/node.git
synced 2026-01-27 23:51:45 +00:00
updated app
This commit is contained in:
269
first-project/node_modules/derby/lib/viewPath.js
generated
vendored
Normal file
269
first-project/node_modules/derby/lib/viewPath.js
generated
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
var lookup = require('racer/lib/path').lookup
|
||||
, trimLeading = require('html-util').trimLeading;
|
||||
|
||||
exports.wrapRemainder = wrapRemainder;
|
||||
exports.extractPlaceholder = extractPlaceholder;
|
||||
exports.pathFnArgs = pathFnArgs;
|
||||
exports.ctxPath = ctxPath;
|
||||
exports.dataValue = dataValue;
|
||||
exports.setBoundFn = setBoundFn;
|
||||
|
||||
function wrapRemainder(tagName, remainder) {
|
||||
if (!remainder) return false;
|
||||
return !(new RegExp('^<\/' + tagName, 'i')).test(remainder);
|
||||
}
|
||||
|
||||
var openPlaceholder = /^([\s\S]*?)(\{{1,3})([\s\S]*)/
|
||||
, placeholderContent = /^\s*([\#\/]?)(?:(else\sif|if|else|unless|each|with|unescaped)(?!\())?\s*([^\s(>]*(?:\s*\([\s\S]*\))?)(?:\s+as\s+:([^\s>]+))?/;
|
||||
|
||||
function extractPlaceholder(text) {
|
||||
var match = openPlaceholder.exec(text);
|
||||
if (!match) return;
|
||||
var pre = match[1]
|
||||
, open = match[2]
|
||||
, remainder = match[3]
|
||||
, openLen = open.length
|
||||
, bound = openLen === 1
|
||||
, macro = openLen === 3
|
||||
, end = matchBraces(remainder, openLen, 0, '{', '}')
|
||||
, endInner = end - openLen
|
||||
, inner = remainder.slice(0, endInner)
|
||||
, post = remainder.slice(end)
|
||||
, content = placeholderContent.exec(inner)
|
||||
, escaped, name, type;
|
||||
if (!content) return;
|
||||
type = content[2];
|
||||
escaped = true;
|
||||
if (type === 'unescaped') {
|
||||
escaped = false;
|
||||
type = '';
|
||||
}
|
||||
name = content[3];
|
||||
if (bound) name = name.replace(/\bthis\b/, '.');
|
||||
if (macro && name === 'content') escaped = false;
|
||||
return {
|
||||
pre: trimLeading(pre)
|
||||
, post: trimLeading(post)
|
||||
, bound: bound
|
||||
, macro: macro
|
||||
, hash: content[1]
|
||||
, escaped: escaped
|
||||
, type: type
|
||||
, name: name
|
||||
, alias: content[4]
|
||||
};
|
||||
}
|
||||
|
||||
function matchBraces(text, num, i, openChar, closeChar) {
|
||||
var close, hasClose, hasOpen, open;
|
||||
i++;
|
||||
while (num) {
|
||||
close = text.indexOf(closeChar, i);
|
||||
open = text.indexOf(openChar, i);
|
||||
hasClose = ~close;
|
||||
hasOpen = ~open;
|
||||
if (hasClose && (!hasOpen || (close < open))) {
|
||||
i = close + 1;
|
||||
num--;
|
||||
continue;
|
||||
} else if (hasOpen) {
|
||||
i = open + 1;
|
||||
num++;
|
||||
continue;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
var fnCall = /^([^(]+)\s*\(\s*([\s\S]*?)\s*\)\s*$/
|
||||
, argSeparator = /\s*([,(])\s*/g
|
||||
, notSeparator = /[^,\s]/g
|
||||
, notPathArg = /(?:^['"\d\-[{])|(?:^null$)|(?:^true$)|(?:^false$)/;
|
||||
|
||||
function fnArgs(inner) {
|
||||
var args = []
|
||||
, lastIndex = 0
|
||||
, match, end, last;
|
||||
while (match = argSeparator.exec(inner)) {
|
||||
if (match[1] === '(') {
|
||||
end = matchBraces(inner, 1, argSeparator.lastIndex, '(', ')');
|
||||
args.push(inner.slice(lastIndex, end));
|
||||
notSeparator.lastIndex = end;
|
||||
lastIndex = argSeparator.lastIndex =
|
||||
notSeparator.test(inner) ? notSeparator.lastIndex - 1 : end;
|
||||
continue;
|
||||
}
|
||||
args.push(inner.slice(lastIndex, match.index));
|
||||
lastIndex = argSeparator.lastIndex;
|
||||
}
|
||||
last = inner.slice(lastIndex);
|
||||
if (last) args.push(last);
|
||||
return args;
|
||||
}
|
||||
|
||||
function fnCallError(name) {
|
||||
throw new Error('malformed view function call: ' + name);
|
||||
}
|
||||
|
||||
function fnArgValue(view, ctx, model, name, macro, arg) {
|
||||
if (arg === 'null') return null;
|
||||
if (arg === 'true') return true;
|
||||
if (arg === 'false') return false;
|
||||
var firstChar = arg.charAt(0)
|
||||
, match;
|
||||
if (firstChar === "'") {
|
||||
match = /^'(.*)'$/.exec(arg) || fnCallError(name);
|
||||
return match[1];
|
||||
}
|
||||
if (firstChar === '"') {
|
||||
match = /^"(.*)"$/.exec(arg) || fnCallError(name);
|
||||
return match[1];
|
||||
}
|
||||
if (/^[\d\-]/.test(firstChar) && !isNaN(arg)) {
|
||||
return +arg;
|
||||
}
|
||||
if (firstChar === '[' || firstChar === '{') {
|
||||
throw new Error('object literals not supported in view function call: ' + name);
|
||||
}
|
||||
return dataValue(view, ctx, model, arg, macro);
|
||||
}
|
||||
|
||||
function fnValue(view, ctx, model, name, macro) {
|
||||
var match = fnCall.exec(name) || fnCallError(name)
|
||||
, fnName = match[1]
|
||||
, args = fnArgs(match[2])
|
||||
, fn, fnName, i;
|
||||
for (i = args.length; i--;) {
|
||||
args[i] = fnArgValue(view, ctx, model, name, macro, args[i]);
|
||||
}
|
||||
if (!(fn = view.getFns[fnName])) {
|
||||
throw new Error('view function "' + fnName + '" not found for call: ' + name);
|
||||
}
|
||||
return fn.apply(null, args);
|
||||
}
|
||||
|
||||
function pathFnArgs(name, paths) {
|
||||
var match = fnCall.exec(name) || fnCallError(name)
|
||||
, args = fnArgs(match[2])
|
||||
, i, arg;
|
||||
if (paths == null) paths = [];
|
||||
for (i = args.length; i--;) {
|
||||
arg = args[i];
|
||||
if (notPathArg.test(arg)) continue;
|
||||
if (~arg.indexOf('(')) {
|
||||
pathFnArgs(arg, paths);
|
||||
continue;
|
||||
}
|
||||
paths.push(arg);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
function macroName(ctx, name, noReplace) {
|
||||
var macroCtx = ctx.$macroCtx
|
||||
, path = ctxPath(macroCtx, name, false, noReplace)
|
||||
, segments = path.split('.')
|
||||
, base = segments[0].toLowerCase()
|
||||
, remainder = segments[1]
|
||||
, value = lookup(base, macroCtx)
|
||||
, macroVar = value && value.$macroVar;
|
||||
if (!macroVar) return remainder ? base + '.' + remainder : base;
|
||||
return remainder ?
|
||||
(/\.+/.test(macroVar) ? macroVar.slice(1) : macroVar) + '.' + remainder :
|
||||
macroVar;
|
||||
}
|
||||
|
||||
function ctxPath(ctx, name, macro, noReplace) {
|
||||
if (macro) name = macroName(ctx, name, noReplace);
|
||||
|
||||
var firstChar = name.charAt(0)
|
||||
, i, aliasName, firstChar, indices;
|
||||
if (firstChar === ':') {
|
||||
if (~(i = name.indexOf('.'))) {
|
||||
aliasName = name.slice(1, i);
|
||||
name = name.slice(i);
|
||||
} else {
|
||||
aliasName = name.slice(1);
|
||||
name = '';
|
||||
}
|
||||
i = ctx.$depth - ctx.$aliases[aliasName];
|
||||
if (i !== i) throw new Error("Can't find alias for " + aliasName);
|
||||
} else if (firstChar === '.') {
|
||||
i = 0;
|
||||
while (name.charAt(i) === '.') {
|
||||
i++;
|
||||
}
|
||||
name = i === name.length ? '' : name.slice(i - 1);
|
||||
}
|
||||
if (i && (name = ctx.$paths[i - 1] + name) && !noReplace) {
|
||||
indices = ctx.$indices;
|
||||
i = indices.length;
|
||||
name = name.replace(/\$#/g, function() {
|
||||
return indices[--i];
|
||||
});
|
||||
}
|
||||
return name.replace(/\[([^\]]+)\]/g, function(match, name) {
|
||||
return lookup(name, ctx);
|
||||
});
|
||||
}
|
||||
|
||||
function dataValue(view, ctx, model, name, macro) {
|
||||
var path, value;
|
||||
if (~name.indexOf('(')) {
|
||||
return fnValue(view, ctx, model, name, macro);
|
||||
}
|
||||
if (macro) {
|
||||
// Get macro content sections
|
||||
value = lookup(name.toLowerCase(), ctx.$macroCtx);
|
||||
if (value && !value.$macroVar) {
|
||||
return typeof value === 'function' ? value(ctx, model) : value;
|
||||
}
|
||||
}
|
||||
path = ctxPath(ctx, name, macro);
|
||||
value = lookup(path, ctx);
|
||||
if (value !== void 0) return value;
|
||||
value = model.get(path);
|
||||
return value !== void 0 ? value : model[path];
|
||||
}
|
||||
|
||||
function setBoundFn(view, ctx, model, name, value) {
|
||||
var match = fnCall.exec(name) || fnCallError(name)
|
||||
, fnName = match[1]
|
||||
, args = fnArgs(match[2])
|
||||
, get = view.getFns[fnName]
|
||||
, set = view.setFns[fnName]
|
||||
, macro = false
|
||||
, numInputs = set.length - 1
|
||||
, arg, i, inputs, out, path, len;
|
||||
|
||||
if (!(get && set)) {
|
||||
throw new Error('view function "' + fnName + '" not found for binding to: ' + name);
|
||||
}
|
||||
|
||||
if (numInputs) {
|
||||
inputs = [value];
|
||||
i = 0;
|
||||
while (i < numInputs) {
|
||||
inputs.push(fnArgValue(view, ctx, model, name, macro, args[i++]));
|
||||
}
|
||||
out = set.apply(null, inputs);
|
||||
} else {
|
||||
out = set(value);
|
||||
}
|
||||
if (!out) return;
|
||||
|
||||
for (i = 0, len = out.length; i < len; i++) {
|
||||
value = out[i];
|
||||
arg = args[i + numInputs];
|
||||
if (~arg.indexOf('(')) {
|
||||
setBoundFn(view, ctx, model, arg, value);
|
||||
continue;
|
||||
}
|
||||
if (value === void 0 || notPathArg.test(arg)) continue;
|
||||
path = ctxPath(ctx, arg);
|
||||
if (model.get(path) === value) continue;
|
||||
model.set(path, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user