mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 02:54:11 +08:00
feat: new expression parser for xml bindings (#9729)
This commit is contained in:

committed by
Nathan Walker

parent
a518249958
commit
90ceed15d3
@ -1,19 +0,0 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,24 +0,0 @@
|
||||
**Esprima** ([esprima.org](http://esprima.org), BSD license) is a high performance,
|
||||
standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)
|
||||
parser written in ECMAScript (also popularly known as
|
||||
[JavaScript](http://en.wikipedia.org/wiki/JavaScript).
|
||||
Esprima is created and maintained by [Ariya Hidayat](http://twitter.com/ariyahidayat),
|
||||
with the help of [many contributors](https://github.com/ariya/esprima/contributors).
|
||||
|
||||
### Features
|
||||
|
||||
- Full support for ECMAScript 5.1 ([ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm))
|
||||
- Sensible [syntax tree format](http://esprima.org/doc/index.html#ast) compatible with Mozilla
|
||||
[Parser AST](https://web.archive.org/web/20201119095346/https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API)
|
||||
- Optional tracking of syntax node location (index-based and line-column)
|
||||
- Heavily tested (> 700 [unit tests](http://esprima.org/test/) with [full code coverage](http://esprima.org/test/coverage.html))
|
||||
- [Partial support](http://esprima.org/doc/es6.html) for ECMAScript 6
|
||||
|
||||
Esprima serves as a **building block** for some JavaScript
|
||||
language tools, from [code instrumentation](http://esprima.org/demo/functiontrace.html)
|
||||
to [editor autocompletion](http://esprima.org/demo/autocomplete.html).
|
||||
|
||||
Esprima runs on many popular web browsers, as well as other ECMAScript platforms such as
|
||||
[Rhino](https://github.com/mozilla/rhino), [Nashorn](http://openjdk.java.net/projects/nashorn/), and [Node.js](https://npmjs.org/package/esprima).
|
||||
|
||||
For more information, check the web site [esprima.org](http://esprima.org).
|
266
packages/core/js-libs/esprima/esprima.d.ts
vendored
266
packages/core/js-libs/esprima/esprima.d.ts
vendored
@ -1,266 +0,0 @@
|
||||
/* tslint:disable */
|
||||
|
||||
// Type definitions for Esprima v1.2.0
|
||||
// Project: http://esprima.org
|
||||
// Definitions by: teppeis <https://github.com/teppeis/>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
export const version: string;
|
||||
export function parse(code: string, options?: Options): Syntax.Program;
|
||||
export function tokenize(code: string, options?: Options): Array<Token>;
|
||||
|
||||
export interface Token {
|
||||
type: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
loc?: boolean
|
||||
range?: boolean
|
||||
raw?: boolean
|
||||
tokens?: boolean
|
||||
comment?: boolean
|
||||
attachComment?: boolean
|
||||
tolerant?: boolean
|
||||
source?: boolean
|
||||
}
|
||||
|
||||
export namespace Syntax {
|
||||
// Node
|
||||
interface Node {
|
||||
type: string
|
||||
loc?: LineLocation
|
||||
range?: number[]
|
||||
leadingComments?: Comment[]
|
||||
trailingComments?: Comment[]
|
||||
}
|
||||
interface LineLocation {
|
||||
start: Position
|
||||
end: Position
|
||||
}
|
||||
interface Position {
|
||||
line: number
|
||||
column: number
|
||||
}
|
||||
|
||||
// Comment
|
||||
interface Comment extends Node {
|
||||
value: string
|
||||
}
|
||||
|
||||
// Program
|
||||
interface Program extends Node {
|
||||
body: SomeStatement[]
|
||||
comments?: Comment[]
|
||||
}
|
||||
|
||||
// Function
|
||||
interface Function extends Node {
|
||||
id: Identifier // | null
|
||||
params: Identifier[]
|
||||
defaults: SomeExpression[]
|
||||
rest: Identifier // | null
|
||||
body: BlockStatementOrExpression
|
||||
generator: boolean
|
||||
expression: boolean
|
||||
}
|
||||
interface BlockStatementOrExpression extends Array<SomeStatement>, BlockStatement, SomeExpression {
|
||||
body: BlockStatementOrExpression
|
||||
}
|
||||
|
||||
// Statement
|
||||
type Statement = Node
|
||||
type EmptyStatement = Statement
|
||||
interface BlockStatement extends Statement {
|
||||
body: SomeStatement[]
|
||||
}
|
||||
interface ExpressionStatement extends Statement {
|
||||
expression: SomeExpression
|
||||
}
|
||||
interface IfStatement extends Statement {
|
||||
test: SomeExpression
|
||||
consequent: SomeStatement
|
||||
alternate: SomeStatement
|
||||
}
|
||||
interface LabeledStatement extends Statement {
|
||||
label: Identifier
|
||||
body: SomeStatement
|
||||
}
|
||||
interface BreakStatement extends Statement {
|
||||
label: Identifier // | null
|
||||
}
|
||||
interface ContinueStatement extends Statement {
|
||||
label: Identifier // | null
|
||||
}
|
||||
interface WithStatement extends Statement {
|
||||
object: SomeExpression
|
||||
body: SomeStatement
|
||||
}
|
||||
interface SwitchStatement extends Statement {
|
||||
discriminant: SomeExpression
|
||||
cases: SwitchCase[]
|
||||
lexical: boolean
|
||||
}
|
||||
interface ReturnStatement extends Statement {
|
||||
argument: SomeExpression // | null
|
||||
}
|
||||
interface ThrowStatement extends Statement {
|
||||
argument: SomeExpression
|
||||
}
|
||||
interface TryStatement extends Statement {
|
||||
block: BlockStatement
|
||||
handler: CatchClause // | null
|
||||
guardedHandlers: CatchClause[]
|
||||
finalizer: BlockStatement // | null
|
||||
}
|
||||
interface WhileStatement extends Statement {
|
||||
test: SomeExpression
|
||||
body: SomeStatement
|
||||
}
|
||||
interface DoWhileStatement extends Statement {
|
||||
body: SomeStatement
|
||||
test: SomeExpression
|
||||
}
|
||||
interface ForStatement extends Statement {
|
||||
init: VariableDeclaratorOrExpression // | null
|
||||
test: SomeExpression // | null
|
||||
update: SomeExpression // | null
|
||||
body: SomeStatement
|
||||
}
|
||||
interface ForInStatement extends Statement {
|
||||
left: VariableDeclaratorOrExpression
|
||||
right: SomeExpression
|
||||
body: SomeStatement
|
||||
each: boolean
|
||||
}
|
||||
interface VariableDeclaratorOrExpression extends VariableDeclarator, SomeExpression {
|
||||
}
|
||||
type DebuggerStatement = Statement
|
||||
interface SomeStatement extends
|
||||
EmptyStatement, ExpressionStatement, BlockStatement, IfStatement,
|
||||
LabeledStatement, BreakStatement, ContinueStatement, WithStatement,
|
||||
SwitchStatement, ReturnStatement, ThrowStatement, TryStatement,
|
||||
WhileStatement, DoWhileStatement, ForStatement, ForInStatement, DebuggerStatement {
|
||||
body: SomeStatementOrList
|
||||
}
|
||||
interface SomeStatementOrList extends Array<SomeStatement>, SomeStatement {
|
||||
}
|
||||
|
||||
// Declration
|
||||
type Declration = Statement
|
||||
interface FunctionDeclration extends Declration {
|
||||
id: Identifier
|
||||
params: Identifier[] // Pattern
|
||||
defaults: SomeExpression[]
|
||||
rest: Identifier
|
||||
body: BlockStatementOrExpression
|
||||
generator: boolean
|
||||
expression: boolean
|
||||
}
|
||||
interface VariableDeclaration extends Declration {
|
||||
declarations: VariableDeclarator[]
|
||||
kind: string // "var" | "let" | "const"
|
||||
}
|
||||
interface VariableDeclarator extends Node {
|
||||
id: Identifier // Pattern
|
||||
init: SomeExpression
|
||||
}
|
||||
|
||||
// Expression
|
||||
type Expression = Node
|
||||
interface SomeExpression extends
|
||||
ThisExpression, ArrayExpression, ObjectExpression, FunctionExpression,
|
||||
ArrowFunctionExpression, SequenceExpression, UnaryExpression, BinaryExpression,
|
||||
AssignmentExpression, UpdateExpression, LogicalExpression, ConditionalExpression,
|
||||
NewExpression, CallExpression, MemberExpression {
|
||||
}
|
||||
type ThisExpression = Expression
|
||||
interface ArrayExpression extends Expression {
|
||||
elements: SomeExpression[] // [ Expression | null ]
|
||||
}
|
||||
interface ObjectExpression extends Expression {
|
||||
properties: Property[]
|
||||
}
|
||||
interface Property extends Node {
|
||||
key: LiteralOrIdentifier // Literal | Identifier
|
||||
value: SomeExpression
|
||||
kind: string // "init" | "get" | "set"
|
||||
}
|
||||
interface LiteralOrIdentifier extends Literal, Identifier {
|
||||
}
|
||||
interface FunctionExpression extends Function, Expression {
|
||||
}
|
||||
interface ArrowFunctionExpression extends Function, Expression {
|
||||
}
|
||||
interface SequenceExpression extends Expression {
|
||||
expressions: SomeExpression[]
|
||||
}
|
||||
interface UnaryExpression extends Expression {
|
||||
operator: string // UnaryOperator
|
||||
prefix: boolean
|
||||
argument: SomeExpression
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
operator: string // BinaryOperator
|
||||
left: SomeExpression
|
||||
right: SomeExpression
|
||||
}
|
||||
interface AssignmentExpression extends Expression {
|
||||
operator: string // AssignmentOperator
|
||||
left: SomeExpression
|
||||
right: SomeExpression
|
||||
}
|
||||
interface UpdateExpression extends Expression {
|
||||
operator: string // UpdateOperator
|
||||
argument: SomeExpression
|
||||
prefix: boolean
|
||||
}
|
||||
interface LogicalExpression extends Expression {
|
||||
operator: string // LogicalOperator
|
||||
left: SomeExpression
|
||||
right: SomeExpression
|
||||
}
|
||||
interface ConditionalExpression extends Expression {
|
||||
test: SomeExpression
|
||||
alternate: SomeExpression
|
||||
consequent: SomeExpression
|
||||
}
|
||||
interface NewExpression extends Expression {
|
||||
callee: SomeExpression
|
||||
arguments: SomeExpression[]
|
||||
}
|
||||
interface CallExpression extends Expression {
|
||||
callee: SomeExpression
|
||||
arguments: SomeExpression[]
|
||||
}
|
||||
interface MemberExpression extends Expression {
|
||||
object: SomeExpression
|
||||
property: IdentifierOrExpression // Identifier | Expression
|
||||
computed: boolean
|
||||
}
|
||||
interface IdentifierOrExpression extends Identifier, SomeExpression {
|
||||
}
|
||||
|
||||
// Pattern
|
||||
// interface Pattern extends Node {
|
||||
// }
|
||||
|
||||
// Clauses
|
||||
interface SwitchCase extends Node {
|
||||
test: SomeExpression
|
||||
consequent: SomeStatement[]
|
||||
}
|
||||
interface CatchClause extends Node {
|
||||
param: Identifier // Pattern
|
||||
guard: SomeExpression
|
||||
body: BlockStatement
|
||||
}
|
||||
|
||||
// Misc
|
||||
interface Identifier extends Node, Expression { // | Pattern
|
||||
name: string
|
||||
}
|
||||
interface Literal extends Node, Expression {
|
||||
value: any // string | boolean | null | number | RegExp
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
||||
{
|
||||
"name": "esprima",
|
||||
"description": "ECMAScript parsing infrastructure for multipurpose analysis",
|
||||
"homepage": "http://esprima.org",
|
||||
"main": "esprima",
|
||||
"sideEffects": false,
|
||||
"types": "esprima.d.ts",
|
||||
"bin": {
|
||||
"esparse": "./bin/esparse.js",
|
||||
"esvalidate": "./bin/esvalidate.js"
|
||||
},
|
||||
"version": "2.0.0-dev",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
},
|
||||
"author": {
|
||||
"name": "Ariya Hidayat",
|
||||
"email": "ariya.hidayat@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Ariya Hidayat",
|
||||
"email": "ariya.hidayat@gmail.com",
|
||||
"web": "http://ariya.ofilabs.com"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ariya/esprima.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://issues.esprima.org"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD",
|
||||
"url": "https://github.com/ariya/esprima/raw/master/LICENSE.BSD"
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"jslint": "~0.1.9",
|
||||
"eslint": "~5.16.0",
|
||||
"jscs": "~1.2.4",
|
||||
"istanbul": "~0.2.6",
|
||||
"complexity-report": "~0.6.1",
|
||||
"regenerate": "~0.6.2",
|
||||
"unicode-7.0.0": "~0.1.5",
|
||||
"json-diff": "~0.3.1",
|
||||
"optimist": "~0.6.0"
|
||||
},
|
||||
"keywords": [
|
||||
"ast",
|
||||
"ecmascript",
|
||||
"javascript",
|
||||
"parser",
|
||||
"syntax"
|
||||
],
|
||||
"scripts": {
|
||||
"generate-regex": "node tools/generate-identifier-regex.js",
|
||||
"test": "npm run-script lint && node test/run.js && npm run-script coverage && npm run-script complexity",
|
||||
"lint": "npm run-script check-version && npm run-script eslint && npm run-script jscs && npm run-script jslint",
|
||||
"check-version": "node tools/check-version.js",
|
||||
"eslint": "node node_modules/eslint/bin/eslint.js esprima.js",
|
||||
"jscs": "node node_modules/jscs/bin/jscs esprima.js",
|
||||
"jslint": "node node_modules/jslint/bin/jslint.js esprima.js",
|
||||
"coverage": "npm run-script analyze-coverage && npm run-script check-coverage",
|
||||
"analyze-coverage": "node node_modules/istanbul/lib/cli.js cover test/runner.js",
|
||||
"check-coverage": "node node_modules/istanbul/lib/cli.js check-coverage --statement 100 --branch 100 --function 100",
|
||||
"complexity": "npm run-script analyze-complexity && npm run-script check-complexity",
|
||||
"analyze-complexity": "node tools/list-complexity.js",
|
||||
"check-complexity": "node node_modules/complexity-report/src/cli.js --maxcc 15 --silent -l -w esprima.js",
|
||||
"benchmark": "node test/benchmarks.js",
|
||||
"benchmark-quick": "node test/benchmarks.js quick"
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2014 The Polymer Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"sideEffects": false,
|
||||
"name": "polymer-expressions",
|
||||
"main": "polymer-expressions",
|
||||
"types": "polymer-expressions.d.ts"
|
||||
}
|
@ -1,393 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function detectEval() {
|
||||
// Don't test for eval if we're running in a Chrome App environment.
|
||||
// We check for APIs set that only exist in a Chrome App context.
|
||||
if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Firefox OS Apps do not allow eval. This feature detection is very hacky
|
||||
// but even if some other platform adds support for this function this code
|
||||
// will continue to work.
|
||||
if (typeof navigator != 'undefined' && navigator.getDeviceStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var f = new Function('', 'return true;');
|
||||
return f();
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var hasEval = detectEval();
|
||||
|
||||
function isIndex(s) {
|
||||
return +s === s >>> 0 && s !== '';
|
||||
}
|
||||
|
||||
function toNumber(s) {
|
||||
return +s;
|
||||
}
|
||||
|
||||
function isObject(obj) {
|
||||
return obj === Object(obj);
|
||||
}
|
||||
|
||||
var numberIsNaN = Number.isNaN || function (value) {
|
||||
return typeof value === 'number' && isNaN(value);
|
||||
}
|
||||
|
||||
function areSameValue(left, right) {
|
||||
if (left === right)
|
||||
return left !== 0 || 1 / left === 1 / right;
|
||||
if (numberIsNaN(left) && numberIsNaN(right))
|
||||
return true;
|
||||
|
||||
return left !== left && right !== right;
|
||||
}
|
||||
|
||||
var createObject = ('__proto__' in {}) ?
|
||||
function (obj) { return obj; } :
|
||||
function (obj) {
|
||||
var proto = obj.__proto__;
|
||||
if (!proto)
|
||||
return obj;
|
||||
var newObject = Object.create(proto);
|
||||
Object.getOwnPropertyNames(obj).forEach(function (name) {
|
||||
Object.defineProperty(newObject, name,
|
||||
Object.getOwnPropertyDescriptor(obj, name));
|
||||
});
|
||||
return newObject;
|
||||
};
|
||||
|
||||
var identStart = '[\$_a-zA-Z]';
|
||||
var identPart = '[\$_a-zA-Z0-9]';
|
||||
var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
|
||||
|
||||
function getPathCharType(char) {
|
||||
if (char === undefined)
|
||||
return 'eof';
|
||||
|
||||
var code = char.charCodeAt(0);
|
||||
|
||||
switch (code) {
|
||||
case 0x5B: // [
|
||||
case 0x5D: // ]
|
||||
case 0x2E: // .
|
||||
case 0x22: // "
|
||||
case 0x27: // '
|
||||
case 0x30: // 0
|
||||
return char;
|
||||
|
||||
case 0x5F: // _
|
||||
case 0x24: // $
|
||||
return 'ident';
|
||||
|
||||
case 0x20: // Space
|
||||
case 0x09: // Tab
|
||||
case 0x0A: // Newline
|
||||
case 0x0D: // Return
|
||||
case 0xA0: // No-break space
|
||||
case 0xFEFF: // Byte Order Mark
|
||||
case 0x2028: // Line Separator
|
||||
case 0x2029: // Paragraph Separator
|
||||
return 'ws';
|
||||
}
|
||||
|
||||
// a-z, A-Z
|
||||
if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
|
||||
return 'ident';
|
||||
|
||||
// 1-9
|
||||
if (0x31 <= code && code <= 0x39)
|
||||
return 'number';
|
||||
|
||||
return 'else';
|
||||
}
|
||||
|
||||
var pathStateMachine = {
|
||||
'beforePath': {
|
||||
'ws': ['beforePath'],
|
||||
'ident': ['inIdent', 'append'],
|
||||
'[': ['beforeElement'],
|
||||
'eof': ['afterPath']
|
||||
},
|
||||
|
||||
'inPath': {
|
||||
'ws': ['inPath'],
|
||||
'.': ['beforeIdent'],
|
||||
'[': ['beforeElement'],
|
||||
'eof': ['afterPath']
|
||||
},
|
||||
|
||||
'beforeIdent': {
|
||||
'ws': ['beforeIdent'],
|
||||
'ident': ['inIdent', 'append']
|
||||
},
|
||||
|
||||
'inIdent': {
|
||||
'ident': ['inIdent', 'append'],
|
||||
'0': ['inIdent', 'append'],
|
||||
'number': ['inIdent', 'append'],
|
||||
'ws': ['inPath', 'push'],
|
||||
'.': ['beforeIdent', 'push'],
|
||||
'[': ['beforeElement', 'push'],
|
||||
'eof': ['afterPath', 'push']
|
||||
},
|
||||
|
||||
'beforeElement': {
|
||||
'ws': ['beforeElement'],
|
||||
'0': ['afterZero', 'append'],
|
||||
'number': ['inIndex', 'append'],
|
||||
"'": ['inSingleQuote', 'append', ''],
|
||||
'"': ['inDoubleQuote', 'append', '']
|
||||
},
|
||||
|
||||
'afterZero': {
|
||||
'ws': ['afterElement', 'push'],
|
||||
']': ['inPath', 'push']
|
||||
},
|
||||
|
||||
'inIndex': {
|
||||
'0': ['inIndex', 'append'],
|
||||
'number': ['inIndex', 'append'],
|
||||
'ws': ['afterElement'],
|
||||
']': ['inPath', 'push']
|
||||
},
|
||||
|
||||
'inSingleQuote': {
|
||||
"'": ['afterElement'],
|
||||
'eof': ['error'],
|
||||
'else': ['inSingleQuote', 'append']
|
||||
},
|
||||
|
||||
'inDoubleQuote': {
|
||||
'"': ['afterElement'],
|
||||
'eof': ['error'],
|
||||
'else': ['inDoubleQuote', 'append']
|
||||
},
|
||||
|
||||
'afterElement': {
|
||||
'ws': ['afterElement'],
|
||||
']': ['inPath', 'push']
|
||||
}
|
||||
}
|
||||
|
||||
function noop() { }
|
||||
|
||||
function parsePath(path) {
|
||||
var keys = [];
|
||||
var index = -1;
|
||||
var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
|
||||
|
||||
var actions = {
|
||||
push: function () {
|
||||
if (key === undefined)
|
||||
return;
|
||||
|
||||
keys.push(key);
|
||||
key = undefined;
|
||||
},
|
||||
|
||||
append: function () {
|
||||
if (key === undefined)
|
||||
key = newChar
|
||||
else
|
||||
key += newChar;
|
||||
}
|
||||
};
|
||||
|
||||
function maybeUnescapeQuote() {
|
||||
if (index >= path.length)
|
||||
return;
|
||||
|
||||
var nextChar = path[index + 1];
|
||||
if ((mode == 'inSingleQuote' && nextChar == "'") ||
|
||||
(mode == 'inDoubleQuote' && nextChar == '"')) {
|
||||
index++;
|
||||
newChar = nextChar;
|
||||
actions.append();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
while (mode) {
|
||||
index++;
|
||||
c = path[index];
|
||||
|
||||
if (c == '\\' && maybeUnescapeQuote(mode))
|
||||
continue;
|
||||
|
||||
type = getPathCharType(c);
|
||||
typeMap = pathStateMachine[mode];
|
||||
transition = typeMap[type] || typeMap['else'] || 'error';
|
||||
|
||||
if (transition == 'error')
|
||||
return; // parse error;
|
||||
|
||||
mode = transition[0];
|
||||
action = actions[transition[1]] || noop;
|
||||
newChar = transition[2] === undefined ? c : transition[2];
|
||||
action();
|
||||
|
||||
if (mode === 'afterPath') {
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
return; // parse error
|
||||
}
|
||||
|
||||
function isIdent(s) {
|
||||
return identRegExp.test(s);
|
||||
}
|
||||
|
||||
var constructorIsPrivate = {};
|
||||
|
||||
function Path(parts, privateToken) {
|
||||
if (privateToken !== constructorIsPrivate)
|
||||
throw Error('Use Path.get to retrieve path objects');
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
this.push(String(parts[i]));
|
||||
}
|
||||
|
||||
if (hasEval && this.length) {
|
||||
this.getValueFrom = this.compiledGetValueFromFn();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(rafaelw): Make simple LRU cache
|
||||
var pathCache = {};
|
||||
|
||||
function getPath(pathString) {
|
||||
if (pathString instanceof Path)
|
||||
return pathString;
|
||||
|
||||
if (pathString == null || pathString.length == 0)
|
||||
pathString = '';
|
||||
|
||||
if (typeof pathString != 'string') {
|
||||
if (isIndex(pathString.length)) {
|
||||
// Constructed with array-like (pre-parsed) keys
|
||||
return new Path(pathString, constructorIsPrivate);
|
||||
}
|
||||
|
||||
pathString = String(pathString);
|
||||
}
|
||||
|
||||
var path = pathCache[pathString];
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
var parts = parsePath(pathString);
|
||||
if (!parts)
|
||||
return invalidPath;
|
||||
|
||||
var path = new Path(parts, constructorIsPrivate);
|
||||
pathCache[pathString] = path;
|
||||
return path;
|
||||
}
|
||||
|
||||
Path.get = getPath;
|
||||
|
||||
function formatAccessor(key) {
|
||||
if (isIndex(key)) {
|
||||
return '[' + key + ']';
|
||||
} else {
|
||||
return '["' + key.replace(/"/g, '\\"') + '"]';
|
||||
}
|
||||
}
|
||||
|
||||
Path.prototype = createObject({
|
||||
__proto__: [],
|
||||
valid: true,
|
||||
|
||||
toString: function () {
|
||||
var pathString = '';
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
var key = this[i];
|
||||
if (isIdent(key)) {
|
||||
pathString += i ? '.' + key : key;
|
||||
} else {
|
||||
pathString += formatAccessor(key);
|
||||
}
|
||||
}
|
||||
|
||||
return pathString;
|
||||
},
|
||||
|
||||
getValueFrom: function (obj, directObserver) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (obj == null)
|
||||
return;
|
||||
obj = obj[this[i]];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
iterateObjects: function (obj, observe) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (i)
|
||||
obj = obj[this[i - 1]];
|
||||
if (!isObject(obj))
|
||||
return;
|
||||
observe(obj, this[i]);
|
||||
}
|
||||
},
|
||||
|
||||
compiledGetValueFromFn: function () {
|
||||
var str = '';
|
||||
var pathString = 'obj';
|
||||
str += 'if (obj != null';
|
||||
var i = 0;
|
||||
var key;
|
||||
for (; i < (this.length - 1) ; i++) {
|
||||
key = this[i];
|
||||
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
||||
str += ' &&\n ' + pathString + ' != null';
|
||||
}
|
||||
str += ')\n';
|
||||
|
||||
var key = this[i];
|
||||
pathString += isIdent(key) ? '.' + key : formatAccessor(key);
|
||||
|
||||
str += ' return ' + pathString + ';\nelse\n return undefined;';
|
||||
return new Function('obj', str);
|
||||
},
|
||||
|
||||
setValueFrom: function (obj, value) {
|
||||
if (!this.length)
|
||||
return false;
|
||||
|
||||
for (var i = 0; i < this.length - 1; i++) {
|
||||
if (!isObject(obj))
|
||||
return false;
|
||||
obj = obj[this[i]];
|
||||
}
|
||||
|
||||
if (!isObject(obj))
|
||||
return false;
|
||||
|
||||
obj[this[i]] = value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
var invalidPath = new Path('', constructorIsPrivate);
|
||||
invalidPath.valid = false;
|
||||
invalidPath.getValueFrom = invalidPath.setValueFrom = function () { };
|
||||
|
||||
exports.Path = Path;
|
@ -1,14 +0,0 @@
|
||||
//@private
|
||||
export class PolymerExpressions {
|
||||
static getExpression(expression: string): Expression;
|
||||
}
|
||||
|
||||
export class Expression {
|
||||
/**
|
||||
* Evaluates a value for an expression.
|
||||
* @param model - Context of the expression.
|
||||
* @param isBackConvert - Denotes if the convertion is forward (from model to ui) or back (ui to model).
|
||||
* @param changedModel - A property bag which contains all changed properties (in case of two way binding).
|
||||
*/
|
||||
getValue(model, isBackConvert, changedModel);
|
||||
}
|
@ -1,541 +0,0 @@
|
||||
// Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
// This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
// The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
// The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
// Code distributed by Google as part of the polymer project is also
|
||||
// subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
|
||||
// Hack to resolve https://github.com/webpack/enhanced-resolve/issues/197 .
|
||||
// This issue causes an require like this (`../esprima`) to be resolved to (`esprima`) by the Angular webpack plugin
|
||||
var esprima = require("../../js-libs/esprima").esprima;
|
||||
|
||||
var Path = require("./path-parser").Path;
|
||||
|
||||
(function (global) {
|
||||
'use strict';
|
||||
|
||||
// TODO(rafaelw): Implement simple LRU.
|
||||
var expressionParseCache = Object.create(null);
|
||||
|
||||
function getExpression(expressionText) {
|
||||
var expression = expressionParseCache[expressionText];
|
||||
if (!expression) {
|
||||
var delegate = new ASTDelegate();
|
||||
esprima.parse(expressionText, delegate);
|
||||
expression = new Expression(delegate);
|
||||
expressionParseCache[expressionText] = expression;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
function Literal(value) {
|
||||
this.value = value;
|
||||
this.valueFn_ = undefined;
|
||||
}
|
||||
|
||||
Literal.prototype = {
|
||||
valueFn: function () {
|
||||
if (!this.valueFn_) {
|
||||
var value = this.value;
|
||||
this.valueFn_ = function () {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return this.valueFn_;
|
||||
}
|
||||
}
|
||||
|
||||
function IdentPath(name) {
|
||||
this.name = name;
|
||||
this.path = Path.get(name);
|
||||
}
|
||||
|
||||
IdentPath.prototype = {
|
||||
valueFn: function () {
|
||||
if (!this.valueFn_) {
|
||||
var name = this.name;
|
||||
var path = this.path;
|
||||
this.valueFn_ = function (model, observer, changedModel) {
|
||||
if (observer)
|
||||
observer.addPath(model, path);
|
||||
|
||||
if (changedModel) {
|
||||
var result = path.getValueFrom(changedModel);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return path.getValueFrom(model);
|
||||
}
|
||||
}
|
||||
|
||||
return this.valueFn_;
|
||||
},
|
||||
|
||||
setValue: function (model, newValue) {
|
||||
if (this.path.length == 1) {
|
||||
model = findScope(model, this.path[0]);
|
||||
}
|
||||
|
||||
return this.path.setValueFrom(model, newValue);
|
||||
}
|
||||
};
|
||||
|
||||
function MemberExpression(object, property, accessor) {
|
||||
this.computed = accessor == '[';
|
||||
|
||||
this.dynamicDeps = typeof object == 'function' ||
|
||||
object.dynamicDeps ||
|
||||
(this.computed && !(property instanceof Literal));
|
||||
|
||||
this.simplePath =
|
||||
!this.dynamicDeps &&
|
||||
(property instanceof IdentPath || property instanceof Literal) &&
|
||||
(object instanceof MemberExpression || object instanceof IdentPath);
|
||||
|
||||
this.object = this.simplePath ? object : getFn(object);
|
||||
this.property = !this.computed || this.simplePath ?
|
||||
property : getFn(property);
|
||||
}
|
||||
|
||||
MemberExpression.prototype = {
|
||||
get fullPath() {
|
||||
if (!this.fullPath_) {
|
||||
|
||||
var parts = this.object instanceof MemberExpression ?
|
||||
this.object.fullPath.slice() : [this.object.name];
|
||||
parts.push(this.property instanceof IdentPath ?
|
||||
this.property.name : this.property.value);
|
||||
this.fullPath_ = Path.get(parts);
|
||||
}
|
||||
|
||||
return this.fullPath_;
|
||||
},
|
||||
|
||||
valueFn: function () {
|
||||
if (!this.valueFn_) {
|
||||
var object = this.object;
|
||||
|
||||
if (this.simplePath) {
|
||||
var path = this.fullPath;
|
||||
|
||||
this.valueFn_ = function (model, observer) {
|
||||
if (observer)
|
||||
observer.addPath(model, path);
|
||||
|
||||
return path.getValueFrom(model);
|
||||
};
|
||||
} else if (!this.computed) {
|
||||
var path = Path.get(this.property.name);
|
||||
|
||||
this.valueFn_ = function (model, observer, filterRegistry) {
|
||||
var context = object(model, observer, filterRegistry);
|
||||
|
||||
if (observer)
|
||||
observer.addPath(context, path);
|
||||
|
||||
return path.getValueFrom(context);
|
||||
}
|
||||
} else {
|
||||
// Computed property.
|
||||
var property = this.property;
|
||||
|
||||
this.valueFn_ = function (model, observer, filterRegistry) {
|
||||
var context = object(model, observer, filterRegistry);
|
||||
var propName = property(model, observer, filterRegistry);
|
||||
if (observer)
|
||||
observer.addPath(context, [propName]);
|
||||
|
||||
return context ? context[propName] : undefined;
|
||||
};
|
||||
}
|
||||
}
|
||||
return this.valueFn_;
|
||||
},
|
||||
|
||||
setValue: function (model, newValue) {
|
||||
if (this.simplePath) {
|
||||
this.fullPath.setValueFrom(model, newValue);
|
||||
return newValue;
|
||||
}
|
||||
|
||||
var object = this.object(model);
|
||||
var propName = this.property instanceof IdentPath ? this.property.name :
|
||||
this.property(model);
|
||||
return object[propName] = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
function Filter(name, args) {
|
||||
this.name = name;
|
||||
this.args = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
this.args[i] = getFn(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Filter.prototype = {
|
||||
transform: function (model, observer, filterRegistry, toModelDirection,
|
||||
initialArgs) {
|
||||
var fn = filterRegistry[this.name];
|
||||
var context = model;
|
||||
if (fn) {
|
||||
context = undefined;
|
||||
} else {
|
||||
fn = context[this.name];
|
||||
if (!fn) {
|
||||
console.error('Cannot find function or filter: ' + this.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If toModelDirection is falsey, then the "normal" (dom-bound) direction
|
||||
// is used. Otherwise, it looks for a 'toModel' property function on the
|
||||
// object.
|
||||
if (toModelDirection) {
|
||||
fn = fn.toModel;
|
||||
} else if (typeof fn.toView == 'function') {
|
||||
fn = fn.toView;
|
||||
}
|
||||
|
||||
if (typeof fn != 'function') {
|
||||
console.error('Cannot find function or filter: ' + this.name);
|
||||
return;
|
||||
}
|
||||
|
||||
var args = initialArgs || [];
|
||||
for (var i = 0; i < this.args.length; i++) {
|
||||
args.push(getFn(this.args[i])(model, observer, filterRegistry));
|
||||
}
|
||||
|
||||
return fn.apply(context, args);
|
||||
}
|
||||
};
|
||||
|
||||
function notImplemented() { throw Error('Not Implemented'); }
|
||||
|
||||
var unaryOperators = {
|
||||
'+': function (v) { return +v; },
|
||||
'-': function (v) { return -v; },
|
||||
'!': function (v) { return !v; }
|
||||
};
|
||||
|
||||
var binaryOperators = {
|
||||
'+': function (l, r) { return l + r; },
|
||||
'-': function (l, r) { return l - r; },
|
||||
'*': function (l, r) { return l * r; },
|
||||
'/': function (l, r) { return l / r; },
|
||||
'%': function (l, r) { return l % r; },
|
||||
'<': function (l, r) { return l < r; },
|
||||
'>': function (l, r) { return l > r; },
|
||||
'<=': function (l, r) { return l <= r; },
|
||||
'>=': function (l, r) { return l >= r; },
|
||||
'==': function (l, r) { return l == r; },
|
||||
'!=': function (l, r) { return l != r; },
|
||||
'===': function (l, r) { return l === r; },
|
||||
'!==': function (l, r) { return l !== r; },
|
||||
'&&': function (l, r) { return l && r; },
|
||||
'||': function (l, r) { return l || r; },
|
||||
};
|
||||
|
||||
function getFn(arg) {
|
||||
return typeof arg == 'function' ? arg : arg.valueFn();
|
||||
}
|
||||
|
||||
function ASTDelegate() {
|
||||
this.expression = null;
|
||||
this.filters = [];
|
||||
this.deps = {};
|
||||
this.currentPath = undefined;
|
||||
this.scopeIdent = undefined;
|
||||
this.indexIdent = undefined;
|
||||
this.dynamicDeps = false;
|
||||
}
|
||||
|
||||
ASTDelegate.prototype = {
|
||||
createUnaryExpression: function (op, argument) {
|
||||
if (!unaryOperators[op])
|
||||
throw Error('Disallowed operator: ' + op);
|
||||
|
||||
argument = getFn(argument);
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
return unaryOperators[op](argument(model, observer, filterRegistry));
|
||||
};
|
||||
},
|
||||
|
||||
createBinaryExpression: function (op, left, right) {
|
||||
if (!binaryOperators[op])
|
||||
throw Error('Disallowed operator: ' + op);
|
||||
|
||||
left = getFn(left);
|
||||
right = getFn(right);
|
||||
|
||||
switch (op) {
|
||||
case '||':
|
||||
this.dynamicDeps = true;
|
||||
return function (model, observer, filterRegistry) {
|
||||
return left(model, observer, filterRegistry) ||
|
||||
right(model, observer, filterRegistry);
|
||||
};
|
||||
case '&&':
|
||||
this.dynamicDeps = true;
|
||||
return function (model, observer, filterRegistry) {
|
||||
return left(model, observer, filterRegistry) &&
|
||||
right(model, observer, filterRegistry);
|
||||
};
|
||||
}
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
return binaryOperators[op](left(model, observer, filterRegistry),
|
||||
right(model, observer, filterRegistry));
|
||||
};
|
||||
},
|
||||
|
||||
createConditionalExpression: function (test, consequent, alternate) {
|
||||
test = getFn(test);
|
||||
consequent = getFn(consequent);
|
||||
alternate = getFn(alternate);
|
||||
|
||||
this.dynamicDeps = true;
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
return test(model, observer, filterRegistry) ?
|
||||
consequent(model, observer, filterRegistry) :
|
||||
alternate(model, observer, filterRegistry);
|
||||
}
|
||||
},
|
||||
|
||||
createIdentifier: function (name) {
|
||||
var ident = new IdentPath(name);
|
||||
ident.type = 'Identifier';
|
||||
return ident;
|
||||
},
|
||||
|
||||
createMemberExpression: function (accessor, object, property) {
|
||||
var ex = new MemberExpression(object, property, accessor);
|
||||
if (ex.dynamicDeps)
|
||||
this.dynamicDeps = true;
|
||||
return ex;
|
||||
},
|
||||
|
||||
createCallExpression: function (expression, args) {
|
||||
if (!(expression instanceof IdentPath))
|
||||
throw Error('Only identifier function invocations are allowed');
|
||||
|
||||
var filter = new Filter(expression.name, args);
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
return filter.transform(model, observer, filterRegistry, false);
|
||||
};
|
||||
},
|
||||
|
||||
createLiteral: function (token) {
|
||||
return new Literal(token.value);
|
||||
},
|
||||
|
||||
createArrayExpression: function (elements) {
|
||||
for (var i = 0; i < elements.length; i++)
|
||||
elements[i] = getFn(elements[i]);
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
var arr = []
|
||||
for (var i = 0; i < elements.length; i++)
|
||||
arr.push(elements[i](model, observer, filterRegistry));
|
||||
return arr;
|
||||
}
|
||||
},
|
||||
|
||||
createProperty: function (kind, key, value) {
|
||||
return {
|
||||
key: key instanceof IdentPath ? key.name : key.value,
|
||||
value: value
|
||||
};
|
||||
},
|
||||
|
||||
createObjectExpression: function (properties) {
|
||||
for (var i = 0; i < properties.length; i++)
|
||||
properties[i].value = getFn(properties[i].value);
|
||||
|
||||
return function (model, observer, filterRegistry) {
|
||||
var obj = {};
|
||||
for (var i = 0; i < properties.length; i++)
|
||||
obj[properties[i].key] =
|
||||
properties[i].value(model, observer, filterRegistry);
|
||||
return obj;
|
||||
}
|
||||
},
|
||||
|
||||
createFilter: function (name, args) {
|
||||
this.filters.push(new Filter(name, args));
|
||||
},
|
||||
|
||||
createAsExpression: function (expression, scopeIdent) {
|
||||
this.expression = expression;
|
||||
this.scopeIdent = scopeIdent;
|
||||
},
|
||||
|
||||
createInExpression: function (scopeIdent, indexIdent, expression) {
|
||||
this.expression = expression;
|
||||
this.scopeIdent = scopeIdent;
|
||||
this.indexIdent = indexIdent;
|
||||
},
|
||||
|
||||
createTopLevel: function (expression) {
|
||||
this.expression = expression;
|
||||
},
|
||||
|
||||
createThisExpression: notImplemented
|
||||
}
|
||||
|
||||
function Expression(delegate) {
|
||||
this.scopeIdent = delegate.scopeIdent;
|
||||
this.indexIdent = delegate.indexIdent;
|
||||
|
||||
if (!delegate.expression)
|
||||
throw Error('No expression found.');
|
||||
|
||||
this.expression = delegate.expression;
|
||||
getFn(this.expression); // forces enumeration of path dependencies
|
||||
|
||||
this.filters = delegate.filters;
|
||||
this.dynamicDeps = delegate.dynamicDeps;
|
||||
}
|
||||
|
||||
Expression.prototype = {
|
||||
getValue: function (model, isBackConvert, changedModel, observer) {
|
||||
var value = getFn(this.expression)(model.context, observer, changedModel);
|
||||
for (var i = 0; i < this.filters.length; i++) {
|
||||
value = this.filters[i].transform(model.context, observer, model.context, isBackConvert, [value]);
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
setValue: function (model, newValue, filterRegistry) {
|
||||
var count = this.filters ? this.filters.length : 0;
|
||||
while (count-- > 0) {
|
||||
newValue = this.filters[count].transform(model, undefined,
|
||||
filterRegistry, true, [newValue]);
|
||||
}
|
||||
|
||||
if (this.expression.setValue)
|
||||
return this.expression.setValue(model, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a style property name to a css property name. For example:
|
||||
* "WebkitUserSelect" to "-webkit-user-select"
|
||||
*/
|
||||
function convertStylePropertyName(name) {
|
||||
return String(name).replace(/[A-Z]/g, function (c) {
|
||||
return '-' + c.toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
var parentScopeName = '@' + Math.random().toString(36).slice(2);
|
||||
|
||||
// Single ident paths must bind directly to the appropriate scope object.
|
||||
// I.e. Pushed values in two-bindings need to be assigned to the actual model
|
||||
// object.
|
||||
function findScope(model, prop) {
|
||||
while (model[parentScopeName] &&
|
||||
!Object.prototype.hasOwnProperty.call(model, prop)) {
|
||||
model = model[parentScopeName];
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
function isLiteralExpression(pathString) {
|
||||
switch (pathString) {
|
||||
case '':
|
||||
return false;
|
||||
|
||||
case 'false':
|
||||
case 'null':
|
||||
case 'true':
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isNaN(Number(pathString)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
function PolymerExpressions() { }
|
||||
|
||||
PolymerExpressions.prototype = {
|
||||
// "built-in" filters
|
||||
styleObject: function (value) {
|
||||
var parts = [];
|
||||
for (var key in value) {
|
||||
parts.push(convertStylePropertyName(key) + ': ' + value[key]);
|
||||
}
|
||||
return parts.join('; ');
|
||||
},
|
||||
|
||||
tokenList: function (value) {
|
||||
var tokens = [];
|
||||
for (var key in value) {
|
||||
if (value[key])
|
||||
tokens.push(key);
|
||||
}
|
||||
return tokens.join(' ');
|
||||
},
|
||||
|
||||
// binding delegate API
|
||||
prepareInstancePositionChanged: function (template) {
|
||||
var indexIdent = template.polymerExpressionIndexIdent_;
|
||||
if (!indexIdent)
|
||||
return;
|
||||
|
||||
return function (templateInstance, index) {
|
||||
templateInstance.model[indexIdent] = index;
|
||||
};
|
||||
},
|
||||
|
||||
prepareInstanceModel: function (template) {
|
||||
var scopeName = template.polymerExpressionScopeIdent_;
|
||||
if (!scopeName)
|
||||
return;
|
||||
|
||||
var parentScope = template.templateInstance ?
|
||||
template.templateInstance.model :
|
||||
template.model;
|
||||
|
||||
var indexName = template.polymerExpressionIndexIdent_;
|
||||
|
||||
return function (model) {
|
||||
return createScopeObject(parentScope, model, scopeName, indexName);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var createScopeObject = ('__proto__' in {}) ?
|
||||
function (parentScope, model, scopeName, indexName) {
|
||||
var scope = {};
|
||||
scope[scopeName] = model;
|
||||
scope[indexName] = undefined;
|
||||
scope[parentScopeName] = parentScope;
|
||||
scope.__proto__ = parentScope;
|
||||
return scope;
|
||||
} :
|
||||
function (parentScope, model, scopeName, indexName) {
|
||||
var scope = Object.create(parentScope);
|
||||
Object.defineProperty(scope, scopeName,
|
||||
{ value: model, configurable: true, writable: true });
|
||||
Object.defineProperty(scope, indexName,
|
||||
{ value: undefined, configurable: true, writable: true });
|
||||
Object.defineProperty(scope, parentScopeName,
|
||||
{ value: parentScope, configurable: true, writable: true });
|
||||
return scope;
|
||||
};
|
||||
|
||||
global.PolymerExpressions = PolymerExpressions;
|
||||
PolymerExpressions.getExpression = getExpression;
|
||||
})(module.exports);
|
Reference in New Issue
Block a user