lib/terminus/public/pathology.js in terminus-0.4.0 vs lib/terminus/public/pathology.js in terminus-0.5.0
- old
+ new
@@ -3,24 +3,24 @@
result = result || new Pathology.XPathResult(resultType);
var expression = Pathology.XPathParser.parse(xpathExpression);
expression.evaluate(context, context, resultType, result);
return result;
},
-
+
atomize: function(expression, context, root) {
var result = expression.evaluate(context, root);
if (result && result.atomize) result = result.atomize();
return result;
},
-
+
array: function(list) {
if (!list) return [];
var array = [], i = list.length;
while (i--) array[i] = list[i];
return array;
},
-
+
indexOf: function(list, item) {
if (list.indexOf) return list.indexOf(item);
for (var i = 0, n = list.length; i < n; i++) {
if (list[i] === item) return i;
}
@@ -83,21 +83,21 @@
};
Pathology.XPathResult.prototype.makeString = function() {
var first = this._nodes[0];
if (!first) return '';
-
+
switch (first.nodeType) {
case XPathResult.STRING_TYPE:
return this.atomize();
-
+
case XPathResult.BOOLEAN_TYPE:
var parts = [];
for (var i = 0, n = this._nodes.length; i < n; i++)
parts.push(this._nodes[i].nodeValue);
return parts.join('');
-
+
default:
var result = document.evaluate('//text()', first, null, XPathResult.ANY_TYPE, null);
return result.makeString();
}
};
@@ -110,47 +110,47 @@
if (destination[key] !== source[key])
destination[key] = source[key];
}
return destination;
};
-
+
var find = function (root, objectName) {
var parts = objectName.split('.'),
part;
-
+
while (part = parts.shift()) {
root = root[part];
if (root === undefined)
throw new Error('Cannot find object named ' + objectName);
}
return root;
};
-
+
var formatError = function (error) {
var lines = error.input.split(/\n/g),
lineNo = 0,
offset = 0;
-
+
while (offset < error.offset + 1) {
offset += lines[lineNo].length + 1;
lineNo += 1;
}
var message = 'Line ' + lineNo + ': expected ' + error.expected + '\n',
line = lines[lineNo - 1];
-
+
message += line + '\n';
offset -= line.length + 1;
-
+
while (offset < error.offset) {
message += ' ';
offset += 1;
}
return message + '^';
};
-
+
var Grammar = {
- __consume__union_expression: function(input) {
+ __consume__union_expression: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["union_expression"] = this._nodeCache["union_expression"] || {};
var cached = this._nodeCache["union_expression"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -285,11 +285,11 @@
} else {
address0 = null;
}
return this._nodeCache["union_expression"][index0] = address0;
},
- __consume__location_path: function(input) {
+ __consume__location_path: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["location_path"] = this._nodeCache["location_path"] || {};
var cached = this._nodeCache["location_path"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -348,11 +348,11 @@
} else {
address0 = null;
}
return this._nodeCache["location_path"][index0] = address0;
},
- __consume__location_step: function(input) {
+ __consume__location_step: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["location_step"] = this._nodeCache["location_step"] || {};
var cached = this._nodeCache["location_step"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -555,11 +555,11 @@
} else {
address0 = null;
}
return this._nodeCache["location_step"][index0] = address0;
},
- __consume__axis: function(input) {
+ __consume__axis: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["axis"] = this._nodeCache["axis"] || {};
var cached = this._nodeCache["axis"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -677,11 +677,11 @@
this._offset = index1;
}
}
return this._nodeCache["axis"][index0] = address0;
},
- __consume__axis_shorthand: function(input) {
+ __consume__axis_shorthand: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["axis_shorthand"] = this._nodeCache["axis_shorthand"] || {};
var cached = this._nodeCache["axis_shorthand"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -808,11 +808,11 @@
}
}
}
return this._nodeCache["axis_shorthand"][index0] = address0;
},
- __consume__node_test: function(input) {
+ __consume__node_test: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["node_test"] = this._nodeCache["node_test"] || {};
var cached = this._nodeCache["node_test"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -902,11 +902,11 @@
} else {
address0 = null;
}
return this._nodeCache["node_test"][index0] = address0;
},
- __consume__node_condition: function(input) {
+ __consume__node_condition: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["node_condition"] = this._nodeCache["node_condition"] || {};
var cached = this._nodeCache["node_condition"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1014,11 +1014,11 @@
} else {
address0 = null;
}
return this._nodeCache["node_condition"][index0] = address0;
},
- __consume__node_name: function(input) {
+ __consume__node_name: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["node_name"] = this._nodeCache["node_name"] || {};
var cached = this._nodeCache["node_name"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1070,11 +1070,11 @@
} else {
address0 = null;
}
return this._nodeCache["node_name"][index0] = address0;
},
- __consume__subscript: function(input) {
+ __consume__subscript: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["subscript"] = this._nodeCache["subscript"] || {};
var cached = this._nodeCache["subscript"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1191,11 +1191,11 @@
} else {
address0 = null;
}
return this._nodeCache["subscript"][index0] = address0;
},
- __consume__node_predicate: function(input) {
+ __consume__node_predicate: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["node_predicate"] = this._nodeCache["node_predicate"] || {};
var cached = this._nodeCache["node_predicate"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1314,11 +1314,11 @@
} else {
address0 = null;
}
return this._nodeCache["node_predicate"][index0] = address0;
},
- __consume__expression: function(input) {
+ __consume__expression: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["expression"] = this._nodeCache["expression"] || {};
var cached = this._nodeCache["expression"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1345,11 +1345,11 @@
}
}
}
return this._nodeCache["expression"][index0] = address0;
},
- __consume__or_expression: function(input) {
+ __consume__or_expression: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["or_expression"] = this._nodeCache["or_expression"] || {};
var cached = this._nodeCache["or_expression"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1432,11 +1432,11 @@
this._offset = index1;
}
}
return this._nodeCache["or_expression"][index0] = address0;
},
- __consume__and_expression: function(input) {
+ __consume__and_expression: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["and_expression"] = this._nodeCache["and_expression"] || {};
var cached = this._nodeCache["and_expression"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1519,11 +1519,11 @@
this._offset = index1;
}
}
return this._nodeCache["and_expression"][index0] = address0;
},
- __consume__comparison: function(input) {
+ __consume__comparison: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["comparison"] = this._nodeCache["comparison"] || {};
var cached = this._nodeCache["comparison"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1582,11 +1582,11 @@
this._offset = index1;
}
}
return this._nodeCache["comparison"][index0] = address0;
},
- __consume__comparator: function(input) {
+ __consume__comparator: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["comparator"] = this._nodeCache["comparator"] || {};
var cached = this._nodeCache["comparator"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1653,11 +1653,11 @@
this._offset = index1;
}
}
return this._nodeCache["comparator"][index0] = address0;
},
- __consume__atom: function(input) {
+ __consume__atom: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["atom"] = this._nodeCache["atom"] || {};
var cached = this._nodeCache["atom"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1806,11 +1806,11 @@
} else {
address0 = null;
}
return this._nodeCache["atom"][index0] = address0;
},
- __consume__value: function(input) {
+ __consume__value: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["value"] = this._nodeCache["value"] || {};
var cached = this._nodeCache["value"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1832,11 +1832,11 @@
}
}
}
return this._nodeCache["value"][index0] = address0;
},
- __consume__function_call: function(input) {
+ __consume__function_call: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["function_call"] = this._nodeCache["function_call"] || {};
var cached = this._nodeCache["function_call"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1943,11 +1943,11 @@
} else {
address0 = null;
}
return this._nodeCache["function_call"][index0] = address0;
},
- __consume__function_name: function(input) {
+ __consume__function_name: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["function_name"] = this._nodeCache["function_name"] || {};
var cached = this._nodeCache["function_name"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -1999,11 +1999,11 @@
} else {
address0 = null;
}
return this._nodeCache["function_name"][index0] = address0;
},
- __consume__function_args: function(input) {
+ __consume__function_args: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["function_args"] = this._nodeCache["function_args"] || {};
var cached = this._nodeCache["function_args"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -2130,11 +2130,11 @@
}
this._offset += 0;
}
return this._nodeCache["function_args"][index0] = address0;
},
- __consume__integer: function(input) {
+ __consume__integer: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["integer"] = this._nodeCache["integer"] || {};
var cached = this._nodeCache["integer"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -2241,11 +2241,11 @@
} else {
address0 = null;
}
return this._nodeCache["integer"][index0] = address0;
},
- __consume__string: function(input) {
+ __consume__string: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["string"] = this._nodeCache["string"] || {};
var cached = this._nodeCache["string"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -2720,11 +2720,11 @@
this._offset = index1;
}
}
return this._nodeCache["string"][index0] = address0;
},
- __consume__space: function(input) {
+ __consume__space: function() {
var address0 = null, index0 = this._offset;
this._nodeCache["space"] = this._nodeCache["space"] || {};
var cached = this._nodeCache["space"][index0];
if (cached) {
this._offset += cached.textValue.length;
@@ -2777,17 +2777,17 @@
address0 = null;
}
return this._nodeCache["space"][index0] = address0;
}
};
-
+
var Parser = function(input) {
this._input = input;
this._offset = 0;
this._nodeCache = {};
};
-
+
Parser.prototype.parse = function() {
var result = this.__consume__union_expression();
if (result && this._offset === this._input.length) {
return result;
}
@@ -2796,39 +2796,39 @@
}
var message = formatError(this.error);
var error = new Error(message);
throw error;
};
-
+
Parser.parse = function(input) {
var parser = new Parser(input);
return parser.parse();
};
-
+
extend(Parser.prototype, Grammar);
-
+
var SyntaxNode = function(textValue, offset, elements, properties) {
this.textValue = textValue;
this.offset = offset;
this.elements = elements || [];
if (!properties) return;
for (var key in properties) this[key] = properties[key];
};
-
+
SyntaxNode.prototype.forEach = function(block, context) {
for (var i = 0, n = this.elements.length; i < n; i++) {
block.call(context, this.elements[i], i);
}
};
-
+
Parser.SyntaxNode = SyntaxNode;
-
+
if (typeof require === "function" && typeof exports === "object") {
exports.Grammar = Grammar;
exports.Parser = Parser;
exports.parse = Parser.parse;
-
+
if (typeof Pathology !== "undefined") {
Pathology.XPath = Grammar;
Pathology.XPathParser = Parser;
Pathology.XPathParser.formatError = formatError;
}
@@ -2864,55 +2864,55 @@
Pathology.Axis.prototype.walk = function(context, block, scope) {
var children = context.childNodes,
attributes = Pathology.array(context.attributes),
sibling;
-
+
if (context.checked)
attributes.push({ nodeName: 'checked',
nodeValue: true,
nodeType: XPathResult.STRING_TYPE
});
-
+
if (context.selected)
attributes.push({ nodeName: 'selected',
nodeValue: true,
nodeType: XPathResult.STRING_TYPE
});
-
+
switch (this.name) {
case 'attribute':
for (var i = 0, n = attributes.length; i < n; i++) {
block.call(scope, attributes[i]);
}
break;
-
+
case 'child':
for (var i = 0, n = children.length; i < n; i++) {
block.call(scope, children[i]);
}
break;
-
+
case 'descendant-or-self':
block.call(scope, context);
for (var i = 0, n = children.length; i < n; i++) {
this.walk(children[i], block, scope);
}
break;
-
+
case 'following-sibling':
sibling = context.nextSibling;
while (sibling) {
block.call(scope, sibling);
sibling = sibling.nextSibling;
}
break;
-
+
case 'parent':
block.call(scope, context.parentNode);
break;
-
+
case 'self':
block.call(scope, context);
break;
}
};
@@ -2922,16 +2922,16 @@
'..': 'parent',
'.' : 'self',
'/' : 'descendant-or-self',
'' : 'child'
};
-
+
Pathology.Axis.fromAST = function(node) {
var name = node.axis_name
? node.axis_name.textValue
: node.textValue;
-
+
return new this(this.SHORTHANDS[name] || name);
};
Pathology.XPathParser.Comparison = {
@@ -2941,22 +2941,22 @@
left = this.left.evaluate(context, root),
right = Pathology.atomize(this.right, context, root),
viable = false,
array = (right instanceof Array),
node;
-
+
if (left._nodes) {
for (var i = 0, n = left._nodes.length; i < n; i++) {
node = left._nodes[i];
if (comparator === '=') {
viable = viable || (array ? Pathology.indexOf(right, node.nodeValue) >= 0 : (node.nodeValue === right || node.innerHTML === right));
} else if (comparator === '!=') {
viable = viable || (array ? Pathology.indexOf(right, node.nodeValue) < 0 : (node.nodeValue !== right && node.innerHTML !== right));
}
}
return viable;
-
+
} else {
switch (comparator) {
case '=': return array ? Pathology.indexOf(right, left.nodeValue) >= 0 : left == right;
case '!=': return array ? Pathology.indexOf(right, node.nodeValue) < 0 : left != right;
}
@@ -2967,65 +2967,65 @@
Pathology.XPathParser.FunctionCall = {
getArguments: function(context, root) {
var args = [],
rest = this.function_args.rest;
-
+
if (this.function_args.first && this.function_args.first.evaluate) {
args.push(this.function_args.first.evaluate(context, root));
}
if (rest) {
for (var i = 0, n = rest.elements.length; i < n; i++)
args.push(rest.elements[i].expression.evaluate(context, root));
}
return args;
},
-
+
evaluate: function(context, root) {
var args = this.getArguments(context, root),
proc = this.REGISTER[this.function_name.textValue];
-
+
return proc.apply(context, args);
},
-
+
REGISTER: {
'concat': function() {
var string = '';
for (var i = 0, n = arguments.length; i < n; i++)
string += arguments[i].makeString ? arguments[i].makeString() : arguments[i];
return string;
},
-
+
'contains': function(haystack, needle) {
if (!haystack) return false;
if (haystack.makeString) haystack = haystack.makeString();
-
+
return haystack.toString().indexOf(needle) >= 0;
},
-
+
'normalize-space': function(string) {
if (string.makeString) string = string.makeString();
-
+
return string.toString().replace(/^\s*/g, '')
.replace(/\s*$/g, '')
.replace(/\s+/g, ' ');
},
-
+
'name': function() {
return this.nodeName.toLowerCase();
},
-
+
'not': function(value) {
if (value && value.atomize) value = value.atomize();
if (typeof value === 'string') return false;
return !value;
},
-
+
'string': function(value) {
return value.atomize().innerText;
},
-
+
'text': function() {
return document.evaluate('/text()', this, null, XPathResult.ANY_TYPE, null);
}
}
};
@@ -3035,51 +3035,51 @@
eachStep: function(block, scope) {
var list = [this.head].concat(this.rest.elements);
for (var i = 0, n = list.length; i < n; i++)
block.call(scope, list[i]);
},
-
+
evaluate: function(context, root, resultType, result) {
result = result || new Pathology.XPathResult(XPathResult.ANY_TYPE);
resultType = resultType || XPathResult.ANY_TYPE;
-
+
var intermediate = new Pathology.XPathResult(resultType),
startNode = this.head.isRelative() ? context : root,
steps = [this.head].concat(this.rest.elements),
step,
nextStage,
i, j, n, m;
-
+
intermediate.push(startNode);
-
+
for (i = 0, n = steps.length; i < n; i++) {
step = steps[i];
nextStage = new Pathology.XPathResult(resultType);
for (j = 0, m = intermediate._nodes.length; j < m; j++) {
step.evaluate(intermediate._nodes[j], root, resultType, nextStage);
}
intermediate = nextStage;
}
-
+
for (i = 0, n = intermediate._nodes.length; i < n; i++)
result.push(intermediate._nodes[i]);
-
+
return result;
}
};
Pathology.XPathParser.LocationStep = {
isRelative: function() {
return this.elements[0].textValue !== '/';
},
-
+
evaluate: function(context, root, resultType, result) {
var axis = this.selector.axis,
test = this.selector.test,
levels = [[]];
-
+
Pathology.Axis.fromAST(axis).walk(context, function(node) {
if (!test || !test.evaluate) return result.push(node);
test.evaluate(node, this.predicates, root, resultType, levels, result);
}, this);
}
@@ -3088,11 +3088,11 @@
Pathology.XPathParser.NodeTest = {
evaluate: function(context, predicates, root, resultType, levels, result) {
var name = this.elements[0].condition_name,
tagName = tagName = this.elements[0].textValue.toLowerCase();
-
+
var first = {
expression: {
evaluate: function() {
if (name && name.textValue === 'node') {
return true;
@@ -3109,29 +3109,29 @@
return true;
}
},
subscript: this.subscript
};
-
+
predicates = [first].concat(predicates.elements);
var accepted, predicate;
-
+
for (var i = 0, n = predicates.length; i < n; i++) {
levels[i] = levels[i] || [];
predicate = predicates[i];
-
+
accepted = Pathology.atomize(predicate.expression, context, root);
if (typeof accepted === 'string') accepted = true;
if (!accepted) return;
-
+
levels[i].push(context);
-
+
if (predicate.subscript.integer) {
if (predicate.subscript.integer.evaluate() !== levels[i].length) return;
}
}
-
+
result.push(context);
}
};
@@ -3159,16 +3159,16 @@
Pathology.XPathParser.Union = {
evaluate: function(context, root, resultType, result) {
result = result || new Pathology.XPathResult(XPathResult.ANY_TYPE);
resultType = resultType || XPathResult.ANY_TYPE;
-
+
this.head.evaluate(context, root, resultType, result);
-
+
var sections = this.rest.elements;
for (var i = 0, n = sections.length; i < n; i++)
sections[i].location_path.evaluate(context, root, resultType, result);
-
+
return result;
}
};