From 9237b25de4219b4ca8f4ff99963e0c9fadbb35b1 Mon Sep 17 00:00:00 2001 From: Rob Eisenberg Date: Sat, 5 Sep 2015 00:41:10 -0400 Subject: [PATCH] chore(all): prepare release 0.15.0 --- bower.json | 8 +- config.js | 51 +- dist/amd/aurelia-templating-binding.d.ts | 6 +- dist/amd/aurelia-templating-binding.js | 189 +++--- dist/aurelia-templating-binding.d.ts | 6 +- dist/aurelia-templating-binding.js | 549 ------------------ dist/commonjs/aurelia-templating-binding.d.ts | 6 +- dist/commonjs/aurelia-templating-binding.js | 189 +++--- dist/es6/aurelia-templating-binding.d.ts | 6 +- dist/es6/aurelia-templating-binding.js | 348 ++++++----- dist/system/aurelia-templating-binding.d.ts | 6 +- dist/system/aurelia-templating-binding.js | 189 +++--- doc/CHANGELOG.md | 13 + package.json | 8 +- test/interpolation-binding.spec.js | 2 +- 15 files changed, 558 insertions(+), 1018 deletions(-) delete mode 100644 dist/aurelia-templating-binding.js diff --git a/bower.json b/bower.json index d163763..ac1fdfa 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "aurelia-templating-binding", - "version": "0.14.0", + "version": "0.15.0", "description": "An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.", "keywords": [ "aurelia", @@ -18,8 +18,8 @@ "url": "http://github.com/aurelia/templating-binding" }, "dependencies": { - "aurelia-binding": "^0.8.6", - "aurelia-logging": "^0.6.4", - "aurelia-templating": "^0.14.0" + "aurelia-binding": "^0.9.0", + "aurelia-logging": "^0.7.0", + "aurelia-templating": "^0.15.0" } } diff --git a/config.js b/config.js index 3566dd2..bf6bc28 100644 --- a/config.js +++ b/config.js @@ -14,42 +14,41 @@ System.config({ }, map: { - "aurelia-binding": "github:aurelia/binding@0.8.6", - "aurelia-logging": "github:aurelia/logging@0.6.4", - "aurelia-templating": "github:aurelia/templating@0.14.4", + "aurelia-binding": "github:aurelia/binding@0.9.0", + "aurelia-logging": "github:aurelia/logging@0.7.0", + "aurelia-templating": "github:aurelia/templating@0.15.0", "babel": "npm:babel-core@5.8.23", "babel-runtime": "npm:babel-runtime@5.8.20", "core-js": "npm:core-js@0.9.18", - "github:aurelia/binding@0.8.6": { - "aurelia-dependency-injection": "github:aurelia/dependency-injection@0.9.2", - "aurelia-metadata": "github:aurelia/metadata@0.7.3", - "aurelia-task-queue": "github:aurelia/task-queue@0.6.2", + "github:aurelia/binding@0.9.0": { + "aurelia-dependency-injection": "github:aurelia/dependency-injection@0.10.0", + "aurelia-metadata": "github:aurelia/metadata@0.8.0", + "aurelia-task-queue": "github:aurelia/task-queue@0.7.0", "core-js": "npm:core-js@0.9.18" }, - "github:aurelia/dependency-injection@0.9.2": { - "aurelia-logging": "github:aurelia/logging@0.6.4", - "aurelia-metadata": "github:aurelia/metadata@0.7.3", + "github:aurelia/dependency-injection@0.10.0": { + "aurelia-logging": "github:aurelia/logging@0.7.0", + "aurelia-metadata": "github:aurelia/metadata@0.8.0", "core-js": "npm:core-js@0.9.18" }, - "github:aurelia/loader@0.8.7": { - "aurelia-html-template-element": "github:aurelia/html-template-element@0.2.0", - "aurelia-metadata": "github:aurelia/metadata@0.7.3", - "aurelia-path": "github:aurelia/path@0.8.1", - "core-js": "npm:core-js@0.9.18", - "webcomponentsjs": "github:webcomponents/webcomponentsjs@0.6.3" + "github:aurelia/loader@0.9.0": { + "aurelia-html-template-element": "github:aurelia/html-template-element@0.3.0", + "aurelia-metadata": "github:aurelia/metadata@0.8.0", + "aurelia-path": "github:aurelia/path@0.9.0", + "core-js": "github:zloirock/core-js@0.8.4" }, - "github:aurelia/metadata@0.7.3": { + "github:aurelia/metadata@0.8.0": { "core-js": "npm:core-js@0.9.18" }, - "github:aurelia/templating@0.14.4": { - "aurelia-binding": "github:aurelia/binding@0.8.6", - "aurelia-dependency-injection": "github:aurelia/dependency-injection@0.9.2", - "aurelia-html-template-element": "github:aurelia/html-template-element@0.2.0", - "aurelia-loader": "github:aurelia/loader@0.8.7", - "aurelia-logging": "github:aurelia/logging@0.6.4", - "aurelia-metadata": "github:aurelia/metadata@0.7.3", - "aurelia-path": "github:aurelia/path@0.8.1", - "aurelia-task-queue": "github:aurelia/task-queue@0.6.2", + "github:aurelia/templating@0.15.0": { + "aurelia-binding": "github:aurelia/binding@0.9.0", + "aurelia-dependency-injection": "github:aurelia/dependency-injection@0.10.0", + "aurelia-html-template-element": "github:aurelia/html-template-element@0.3.0", + "aurelia-loader": "github:aurelia/loader@0.9.0", + "aurelia-logging": "github:aurelia/logging@0.7.0", + "aurelia-metadata": "github:aurelia/metadata@0.8.0", + "aurelia-path": "github:aurelia/path@0.9.0", + "aurelia-task-queue": "github:aurelia/task-queue@0.7.0", "core-js": "npm:core-js@0.9.18" }, "github:jspm/nodelibs-process@0.1.1": { diff --git a/dist/amd/aurelia-templating-binding.d.ts b/dist/amd/aurelia-templating-binding.d.ts index 1d6b5ce..14b1f16 100644 --- a/dist/amd/aurelia-templating-binding.d.ts +++ b/dist/amd/aurelia-templating-binding.d.ts @@ -1,7 +1,9 @@ declare module 'aurelia-templating-binding' { import * as LogManager from 'aurelia-logging'; - import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode } from 'aurelia-binding'; + import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression } from 'aurelia-binding'; import { BehaviorInstruction, BindingLanguage } from 'aurelia-templating'; + + /*eslint dot-notation:0*/ export class SyntaxInterpreter { static inject(): any; constructor(parser: any, observerLocator: any, eventManager: any); @@ -18,7 +20,7 @@ declare module 'aurelia-templating-binding' { static inject(): any; constructor(parser: any, observerLocator: any, syntaxInterpreter: any); inspectAttribute(resources: any, attrName: any, attrValue: any): any; - createAttributeInstruction(resources: any, element: any, info: any, existingInstruction: any): any; + createAttributeInstruction(resources: any, element: any, theInfo: any, existingInstruction: any): any; parseText(resources: any, value: any): any; parseContent(resources: any, attrName: any, attrValue: any): any; } diff --git a/dist/amd/aurelia-templating-binding.js b/dist/amd/aurelia-templating-binding.js index c78320f..36e51d4 100644 --- a/dist/amd/aurelia-templating-binding.js +++ b/dist/amd/aurelia-templating-binding.js @@ -30,9 +30,8 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], }; SyntaxInterpreter.prototype.handleUnknownCommand = function handleUnknownCommand(resources, element, info, existingInstruction) { - var attrName = info.attrName, - command = info.command; - + var attrName = info.attrName; + var command = info.command; var instruction = this.options(resources, element, info, existingInstruction); instruction.alteredAttr = true; @@ -48,8 +47,8 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], if (tagName === 'input') { return attrName === 'value' || attrName === 'checked' || attrName === 'files' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; - } else if (tagName == 'textarea' || tagName == 'select') { - return attrName == 'value' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; + } else if (tagName === 'textarea' || tagName === 'select') { + return attrName === 'value' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; } else if (attrName === 'textcontent' || attrName === 'innerhtml') { return element.contentEditable === 'true' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; } else if (attrName === 'scrolltop' || attrName === 'scrollleft') { @@ -84,14 +83,14 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], }; SyntaxInterpreter.prototype.options = function options(resources, element, info, existingInstruction) { - var instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName), - attrValue = info.attrValue, - language = this.language, - name = null, - target = '', - current, - i, - ii; + var instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName); + var attrValue = info.attrValue; + var language = this.language; + var name = null; + var target = ''; + var current = undefined; + var i = undefined; + var ii = undefined; for (i = 0, ii = attrValue.length; i < ii; ++i) { current = attrValue[i]; @@ -132,7 +131,12 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], exports.SyntaxInterpreter = SyntaxInterpreter; SyntaxInterpreter.prototype['for'] = function (resources, element, info, existingInstruction) { - var parts, keyValue, instruction, attrValue, isDestructuring; + var parts = undefined; + var keyValue = undefined; + var instruction = undefined; + var attrValue = undefined; + var isDestructuring = undefined; + attrValue = info.attrValue; isDestructuring = attrValue.match(/[[].+[\]]/); parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of '); @@ -180,8 +184,8 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], return instruction; }; - var info = {}, - logger = _aureliaLogging.getLogger('templating-binding'); + var info = {}; + var logger = _aureliaLogging.getLogger('templating-binding'); var TemplatingBindingLanguage = (function (_BindingLanguage) { _inherits(TemplatingBindingLanguage, _BindingLanguage); @@ -226,7 +230,7 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], info.defaultBindingMode = null; - if (parts.length == 2) { + if (parts.length === 2) { info.attrName = parts[0].trim(); info.attrValue = attrValue; info.command = parts[1].trim(); @@ -238,7 +242,7 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], } else { info.expression = null; } - } else if (attrName == 'ref') { + } else if (attrName === 'ref') { info.attrName = attrName; info.attrValue = attrValue; info.command = null; @@ -253,18 +257,18 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], return info; }; - TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, info, existingInstruction) { - var instruction; + TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, theInfo, existingInstruction) { + var instruction = undefined; - if (info.expression) { - if (info.attrName === 'ref') { - return info.expression; + if (theInfo.expression) { + if (theInfo.attrName === 'ref') { + return theInfo.expression; } - instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName); - instruction.attributes[info.attrName] = info.expression; - } else if (info.command) { - instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(theInfo.attrName); + instruction.attributes[theInfo.attrName] = theInfo.expression; + } else if (theInfo.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, theInfo, existingInstruction); } return instruction; @@ -275,15 +279,16 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], }; TemplatingBindingLanguage.prototype.parseContent = function parseContent(resources, attrName, attrValue) { - var i = attrValue.indexOf('${', 0), - ii = attrValue.length, - char, - pos = 0, - open = 0, - quote = null, - interpolationStart, - parts, - partIndex = 0; + var i = attrValue.indexOf('${', 0); + var ii = attrValue.length; + var char = undefined; + var pos = 0; + var open = 0; + var quote = null; + var interpolationStart = undefined; + var parts = undefined; + var partIndex = 0; + while (i >= 0 && i < ii - 2) { open = 1; interpolationStart = i; @@ -292,18 +297,19 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], do { char = attrValue[i]; i++; - switch (char) { - case "'": - case '"': - if (quote === null) { - quote = char; - } else if (quote === char) { - quote = null; - } - continue; - case '\\': - i++; - continue; + + if (char === "'" || char === '"') { + if (quote === null) { + quote = char; + } else if (quote === char) { + quote = null; + } + continue; + } + + if (char === '\\') { + i++; + continue; } if (quote !== null) { @@ -382,6 +388,7 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && targetProperty === 'textContent') { throw new Error('Interpolation binding cannot be used in the content of a textarea element. Use instead.'); } + this.observerLocator = observerLocator; this.parts = parts; this.targetProperty = observerLocator.getObserver(target, targetProperty); @@ -397,7 +404,7 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], InterpolationBinding.prototype.bind = function bind(source) { this.source = source; - if (this.mode == _aureliaBinding.bindingMode.oneWay) { + if (this.mode === _aureliaBinding.bindingMode.oneWay) { this.unbind(); this.connect(); this.setValue(); @@ -414,67 +421,72 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], InterpolationBinding.prototype.partChanged = function partChanged(newValue, oldValue, connecting) { var _this = this; - var map, info; + var map = undefined; + var data = undefined; + if (!connecting) { this.setValue(); } + if (oldValue instanceof Array) { map = this.arrayPartMap; - info = map ? map.get(oldValue) : null; - if (info) { - info.refs--; - if (info.refs === 0) { - info.dispose(); + data = map ? map.get(oldValue) : null; + if (data) { + data.refs--; + if (data.refs === 0) { + data.dispose(); map['delete'](oldValue); } } } + if (newValue instanceof Array) { map = this.arrayPartMap || (this.arrayPartMap = new Map()); - info = map.get(newValue); - if (!info) { - info = { + data = map.get(newValue); + if (!data) { + data = { refs: 0, dispose: this.observerLocator.getArrayObserver(newValue).subscribe(function () { return _this.setValue(); }) }; - map.set(newValue, info); + + map.set(newValue, data); } - info.refs++; + data.refs++; } }; InterpolationBinding.prototype.connect = function connect() { - var info, - parts = this.parts, - source = this.source, - toDispose = this.toDispose = [], - partChanged = this.partChanged.bind(this), - i, - ii; + var result = undefined; + var parts = this.parts; + var source = this.source; + var toDispose = this.toDispose = []; + var partChanged = this.partChanged.bind(this); + var i = undefined; + var ii = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { - if (i % 2 === 0) {} else { - info = parts[i].connect(this, source); - if (info.observer) { - toDispose.push(info.observer.subscribe(partChanged)); - } - if (info.value instanceof Array) { - partChanged(info.value, undefined, true); - } + if (i % 2 !== 0) { + result = parts[i].connect(this, source); + if (result.observer) { + toDispose.push(result.observer.subscribe(partChanged)); + } + if (result.value instanceof Array) { + partChanged(result.value, undefined, true); } + } } }; InterpolationBinding.prototype.interpolate = function interpolate() { - var value = '', - parts = this.parts, - source = this.source, - valueConverterLookupFunction = this.valueConverterLookupFunction, - i, - ii, - temp; + var value = ''; + var parts = this.parts; + var source = this.source; + var valueConverterLookupFunction = this.valueConverterLookupFunction; + var i = undefined; + var ii = undefined; + var temp = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { if (i % 2 === 0) { @@ -489,10 +501,10 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], }; InterpolationBinding.prototype.unbind = function unbind() { - var i, - ii, - toDispose = this.toDispose, - map = this.arrayPartMap; + var i = undefined; + var ii = undefined; + var toDispose = this.toDispose; + var map = this.arrayPartMap; if (toDispose) { for (i = 0, ii = toDispose.length; i < ii; ++i) { @@ -515,6 +527,7 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], toDispose.dispose(); } + map.clear(); } @@ -525,8 +538,8 @@ define(['exports', 'aurelia-logging', 'aurelia-binding', 'aurelia-templating'], })(); function configure(config) { - var instance, - getInstance = function getInstance(c) { + var instance = undefined; + var getInstance = function getInstance(c) { return instance || (instance = c.invoke(TemplatingBindingLanguage)); }; diff --git a/dist/aurelia-templating-binding.d.ts b/dist/aurelia-templating-binding.d.ts index 1d6b5ce..14b1f16 100644 --- a/dist/aurelia-templating-binding.d.ts +++ b/dist/aurelia-templating-binding.d.ts @@ -1,7 +1,9 @@ declare module 'aurelia-templating-binding' { import * as LogManager from 'aurelia-logging'; - import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode } from 'aurelia-binding'; + import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression } from 'aurelia-binding'; import { BehaviorInstruction, BindingLanguage } from 'aurelia-templating'; + + /*eslint dot-notation:0*/ export class SyntaxInterpreter { static inject(): any; constructor(parser: any, observerLocator: any, eventManager: any); @@ -18,7 +20,7 @@ declare module 'aurelia-templating-binding' { static inject(): any; constructor(parser: any, observerLocator: any, syntaxInterpreter: any); inspectAttribute(resources: any, attrName: any, attrValue: any): any; - createAttributeInstruction(resources: any, element: any, info: any, existingInstruction: any): any; + createAttributeInstruction(resources: any, element: any, theInfo: any, existingInstruction: any): any; parseText(resources: any, value: any): any; parseContent(resources: any, attrName: any, attrValue: any): any; } diff --git a/dist/aurelia-templating-binding.js b/dist/aurelia-templating-binding.js deleted file mode 100644 index bd1fb43..0000000 --- a/dist/aurelia-templating-binding.js +++ /dev/null @@ -1,549 +0,0 @@ -import * as LogManager from 'aurelia-logging'; -import {Parser,ObserverLocator,EventManager,ListenerExpression,BindingExpression,NameExpression,CallExpression,bindingMode} from 'aurelia-binding'; -import {BehaviorInstruction,BindingLanguage} from 'aurelia-templating'; - -export class SyntaxInterpreter { - static inject() { return [Parser,ObserverLocator,EventManager]; } - constructor(parser, observerLocator, eventManager){ - this.parser = parser; - this.observerLocator = observerLocator; - this.eventManager = eventManager; - } - - interpret(resources, element, info, existingInstruction){ - if(info.command in this){ - return this[info.command](resources, element, info, existingInstruction); - } - - return this.handleUnknownCommand(resources, element, info, existingInstruction); - } - - handleUnknownCommand(resources, element, info, existingInstruction){ - var attrName = info.attrName, - command = info.command; - - var instruction = this.options(resources, element, info, existingInstruction); - - instruction.alteredAttr = true; - instruction.attrName = 'global-behavior'; - instruction.attributes.aureliaAttrName = attrName; - instruction.attributes.aureliaCommand = command; - - return instruction; - } - - determineDefaultBindingMode(element, attrName){ - var tagName = element.tagName.toLowerCase(); - - if(tagName === 'input'){ - return attrName === 'value' || attrName === 'checked' || attrName === 'files' ? bindingMode.twoWay : bindingMode.oneWay; - }else if(tagName == 'textarea' || tagName == 'select'){ - return attrName == 'value' ? bindingMode.twoWay : bindingMode.oneWay; - }else if(attrName === 'textcontent' || attrName === 'innerhtml'){ - return element.contentEditable === 'true' ? bindingMode.twoWay : bindingMode.oneWay; - } else if(attrName === 'scrolltop' || attrName === 'scrollleft'){ - return bindingMode.twoWay; - } - - return bindingMode.oneWay; - } - - bind(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - instruction.attributes[info.attrName] = new BindingExpression( - this.observerLocator, - this.attributeMap[info.attrName] || info.attrName, - this.parser.parse(info.attrValue), - info.defaultBindingMode || this.determineDefaultBindingMode(element, info.attrName), - resources.valueConverterLookupFunction - ); - - return instruction; - } - - trigger(resources, element, info){ - return new ListenerExpression( - this.eventManager, - info.attrName, - this.parser.parse(info.attrValue), - false, - true - ); - } - - delegate(resources, element, info){ - return new ListenerExpression( - this.eventManager, - info.attrName, - this.parser.parse(info.attrValue), - true, - true - ); - } - - call(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - instruction.attributes[info.attrName] = new CallExpression( - this.observerLocator, - info.attrName, - this.parser.parse(info.attrValue), - resources.valueConverterLookupFunction - ); - - return instruction; - }; - - options(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName), - attrValue = info.attrValue, - language = this.language, - name = null, target = '', current, i , ii; - - for(i = 0, ii = attrValue.length; i < ii; ++i){ - current = attrValue[i]; - - if(current === ';'){ - info = language.inspectAttribute(resources, name, target.trim()); - language.createAttributeInstruction(resources, element, info, instruction); - - if(!instruction.attributes[info.attrName]){ - instruction.attributes[info.attrName] = info.attrValue; - } - - target = ''; - name = null; - } else if(current === ':' && name === null){ - name = target.trim(); - target = ''; - } else { - target += current; - } - } - - if(name !== null){ - info = language.inspectAttribute(resources, name, target.trim()); - language.createAttributeInstruction(resources, element, info, instruction); - - if(!instruction.attributes[info.attrName]){ - instruction.attributes[info.attrName] = info.attrValue; - } - } - - return instruction; - } -} - -SyntaxInterpreter.prototype['for'] = function(resources, element, info, existingInstruction){ - var parts, keyValue, instruction, attrValue, isDestructuring; - attrValue = info.attrValue; - isDestructuring = attrValue.match(/[[].+[\]]/); - parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of '); - - if(parts.length !== 2){ - throw new Error('Incorrect syntax for "for". The form is: "$local of $items" or "[$key, $value] of $items".'); - } - - instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - if(isDestructuring){ - keyValue = parts[0].replace(/[[\]]/g, '').replace(/,/g, ' ').replace(/\s+/g, ' ').trim().split(' '); - instruction.attributes.key = keyValue[0]; - instruction.attributes.value = keyValue[1]; - }else{ - instruction.attributes.local = parts[0]; - } - - instruction.attributes.items = new BindingExpression( - this.observerLocator, - 'items', - this.parser.parse(parts[1]), - bindingMode.oneWay, - resources.valueConverterLookupFunction - ); - - return instruction; -}; - -SyntaxInterpreter.prototype['two-way'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - instruction.attributes[info.attrName] = new BindingExpression( - this.observerLocator, - this.attributeMap[info.attrName] || info.attrName, - this.parser.parse(info.attrValue), - bindingMode.twoWay, - resources.valueConverterLookupFunction - ); - - return instruction; -}; - -SyntaxInterpreter.prototype['one-way'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - instruction.attributes[info.attrName] = new BindingExpression( - this.observerLocator, - this.attributeMap[info.attrName] || info.attrName, - this.parser.parse(info.attrValue), - bindingMode.oneWay, - resources.valueConverterLookupFunction - ); - - return instruction; -}; - -SyntaxInterpreter.prototype['one-time'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - - instruction.attributes[info.attrName] = new BindingExpression( - this.observerLocator, - this.attributeMap[info.attrName] || info.attrName, - this.parser.parse(info.attrValue), - bindingMode.oneTime, - resources.valueConverterLookupFunction - ); - - return instruction; -}; - -var info = {}, - logger = LogManager.getLogger('templating-binding'); - -export class TemplatingBindingLanguage extends BindingLanguage { - static inject() { return [Parser, ObserverLocator, SyntaxInterpreter]; } - constructor(parser, observerLocator, syntaxInterpreter){ - super(); - this.parser = parser; - this.observerLocator = observerLocator; - this.syntaxInterpreter = syntaxInterpreter; - this.emptyStringExpression = this.parser.parse('\'\''); - syntaxInterpreter.language = this; - this.attributeMap = syntaxInterpreter.attributeMap = { - 'contenteditable':'contentEditable', - 'for':'htmlFor', - 'tabindex':'tabIndex', - 'textcontent': 'textContent', - 'innerhtml': 'innerHTML', - // HTMLInputElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement - 'maxlength':'maxLength', - 'minlength':'minLength', - 'formaction':'formAction', - 'formenctype':'formEncType', - 'formmethod':'formMethod', - 'formnovalidate':'formNoValidate', - 'formtarget':'formTarget', - 'rowspan':'rowSpan', - 'colspan':'colSpan', - 'scrolltop':'scrollTop', - 'scrollleft':'scrollLeft', - 'readonly':'readOnly' - }; - } - - inspectAttribute(resources, attrName, attrValue){ - var parts = attrName.split('.'); - - info.defaultBindingMode = null; - - if(parts.length == 2){ - info.attrName = parts[0].trim(); - info.attrValue = attrValue; - info.command = parts[1].trim(); - - if(info.command === 'ref'){ - info.expression = new NameExpression(attrValue, info.attrName); - info.command = null; - info.attrName = 'ref'; - } else{ - info.expression = null; - } - }else if(attrName == 'ref'){ - info.attrName = attrName; - info.attrValue = attrValue; - info.command = null; - info.expression = new NameExpression(attrValue, 'element'); - }else{ - info.attrName = attrName; - info.attrValue = attrValue; - info.command = null; - info.expression = this.parseContent(resources, attrName, attrValue); - } - - return info; - } - - createAttributeInstruction(resources, element, info, existingInstruction){ - var instruction; - - if(info.expression){ - if(info.attrName === 'ref'){ - return info.expression; - } - - instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - instruction.attributes[info.attrName] = info.expression; - } else if(info.command){ - instruction = this.syntaxInterpreter.interpret( - resources, - element, - info, - existingInstruction - ); - } - - return instruction; - } - - parseText(resources, value){ - return this.parseContent(resources, 'textContent', value); - } - - parseContent(resources, attrName, attrValue){ - var i = attrValue.indexOf('${', 0), ii = attrValue.length, - char, pos = 0, open = 0, quote = null, interpolationStart, - parts, partIndex = 0; - while(i >= 0 && i < ii - 2) { - open = 1; - interpolationStart = i; - i += 2; - - do { - char = attrValue[i]; - i++; - switch(char) { - case "'": - case '"': - if (quote === null) { - quote = char; - } else if (quote === char) { - quote = null; - } - continue; - case '\\': - i++; - continue; - } - - if (quote !== null) { - continue; - } - - if (char === '{') { - open++; - } else if (char === '}') { - open--; - } - } while(open > 0 && i < ii) - - if (open === 0) { - // lazy allocate array - parts = parts || []; - if (attrValue[interpolationStart - 1] === '\\' && attrValue[interpolationStart - 2] !== '\\') { - // escaped interpolation - parts[partIndex] = attrValue.substring(pos, interpolationStart - 1) + attrValue.substring(interpolationStart, i); - partIndex++; - parts[partIndex] = this.emptyStringExpression; - partIndex++; - } else { - // standard interpolation - parts[partIndex] = attrValue.substring(pos, interpolationStart); - partIndex++; - parts[partIndex] = this.parser.parse(attrValue.substring(interpolationStart + 2, i - 1)); - partIndex++; - } - pos = i; - i = attrValue.indexOf('${', i); - } else { - break; - } - } - - // no interpolation. - if (partIndex === 0) { - return null; - } - - // literal. - parts[partIndex] = attrValue.substr(pos); - - return new InterpolationBindingExpression( - this.observerLocator, - this.attributeMap[attrName] || attrName, - parts, - bindingMode.oneWay, - resources.valueConverterLookupFunction, - attrName - ); - } -} - -export class InterpolationBindingExpression { - constructor(observerLocator, targetProperty, parts, - mode, valueConverterLookupFunction, attribute){ - this.observerLocator = observerLocator; - this.targetProperty = targetProperty; - this.parts = parts; - this.mode = mode; - this.valueConverterLookupFunction = valueConverterLookupFunction; - this.attribute = this.attrToRemove = attribute; - this.discrete = false; - } - - createBinding(target){ - return new InterpolationBinding( - this.observerLocator, - this.parts, - target, - this.targetProperty, - this.mode, - this.valueConverterLookupFunction - ); - } -} - -class InterpolationBinding { - constructor(observerLocator, parts, target, targetProperty, mode, valueConverterLookupFunction){ - if (targetProperty === 'style') { - logger.info('Internet Explorer does not support interpolation in "style" attributes. Use the style attribute\'s alias, "css" instead.'); - } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && targetProperty === 'textContent') { - throw new Error('Interpolation binding cannot be used in the content of a textarea element. Use instead.'); - } - this.observerLocator = observerLocator; - this.parts = parts; - this.targetProperty = observerLocator.getObserver(target, targetProperty); - this.mode = mode; - this.valueConverterLookupFunction = valueConverterLookupFunction; - this.toDispose = []; - } - - getObserver(obj, propertyName){ - return this.observerLocator.getObserver(obj, propertyName); - } - - bind(source){ - this.source = source; - - if(this.mode == bindingMode.oneWay){ - this.unbind(); - this.connect(); - this.setValue(); - }else{ - this.setValue(); - } - } - - setValue(){ - var value = this.interpolate(); - this.targetProperty.setValue(value); - } - - partChanged(newValue, oldValue, connecting){ - var map, info; - if (!connecting) { - this.setValue(); - } - if (oldValue instanceof Array) { - map = this.arrayPartMap; - info = map ? map.get(oldValue) : null; - if (info) { - info.refs--; - if (info.refs === 0) { - info.dispose(); - map.delete(oldValue); - } - } - } - if (newValue instanceof Array) { - map = this.arrayPartMap || (this.arrayPartMap = new Map()); - info = map.get(newValue); - if (!info) { - info = { - refs: 0, - dispose: this.observerLocator.getArrayObserver(newValue).subscribe(() => this.setValue()) - } - map.set(newValue, info); - } - info.refs++; - } - } - - connect(){ - var info, - parts = this.parts, - source = this.source, - toDispose = this.toDispose = [], - partChanged = this.partChanged.bind(this), - i, ii; - - for(i = 0, ii = parts.length; i < ii; ++i){ - if (i % 2 === 0) { - //do nothing - } else { - info = parts[i].connect(this, source); - if(info.observer){ - toDispose.push(info.observer.subscribe(partChanged)); - } - if (info.value instanceof Array) { - partChanged(info.value, undefined, true); - } - } - } - } - - interpolate(){ - var value = '', - parts = this.parts, - source = this.source, - valueConverterLookupFunction = this.valueConverterLookupFunction, - i, ii, temp; - - for(i = 0, ii = parts.length; i < ii; ++i){ - if (i % 2 === 0) { - value += parts[i]; - } else { - temp = parts[i].evaluate(source, valueConverterLookupFunction); - value += (typeof temp !== 'undefined' && temp !== null ? temp.toString() : ''); - } - } - - return value; - } - - unbind(){ - var i, ii, toDispose = this.toDispose, map = this.arrayPartMap; - - if(toDispose){ - for(i = 0, ii = toDispose.length; i < ii; ++i){ - toDispose[i](); - } - } - - this.toDispose = null; - - if (map) { - for(toDispose of map.values()) { - toDispose.dispose(); - } - map.clear(); - } - - this.arrayPartMap = null; - } -} - -export function configure(config){ - var instance, - getInstance = function (c){ - return instance || (instance = c.invoke(TemplatingBindingLanguage)); - }; - - if(config.container.hasHandler(TemplatingBindingLanguage)){ - instance = config.container.get(TemplatingBindingLanguage); - }else{ - config.container.registerHandler(TemplatingBindingLanguage, getInstance); - } - - config.container.registerHandler(BindingLanguage, getInstance); -} diff --git a/dist/commonjs/aurelia-templating-binding.d.ts b/dist/commonjs/aurelia-templating-binding.d.ts index 1d6b5ce..14b1f16 100644 --- a/dist/commonjs/aurelia-templating-binding.d.ts +++ b/dist/commonjs/aurelia-templating-binding.d.ts @@ -1,7 +1,9 @@ declare module 'aurelia-templating-binding' { import * as LogManager from 'aurelia-logging'; - import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode } from 'aurelia-binding'; + import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression } from 'aurelia-binding'; import { BehaviorInstruction, BindingLanguage } from 'aurelia-templating'; + + /*eslint dot-notation:0*/ export class SyntaxInterpreter { static inject(): any; constructor(parser: any, observerLocator: any, eventManager: any); @@ -18,7 +20,7 @@ declare module 'aurelia-templating-binding' { static inject(): any; constructor(parser: any, observerLocator: any, syntaxInterpreter: any); inspectAttribute(resources: any, attrName: any, attrValue: any): any; - createAttributeInstruction(resources: any, element: any, info: any, existingInstruction: any): any; + createAttributeInstruction(resources: any, element: any, theInfo: any, existingInstruction: any): any; parseText(resources: any, value: any): any; parseContent(resources: any, attrName: any, attrValue: any): any; } diff --git a/dist/commonjs/aurelia-templating-binding.js b/dist/commonjs/aurelia-templating-binding.js index 1229ea3..6df23e2 100644 --- a/dist/commonjs/aurelia-templating-binding.js +++ b/dist/commonjs/aurelia-templating-binding.js @@ -39,9 +39,8 @@ var SyntaxInterpreter = (function () { }; SyntaxInterpreter.prototype.handleUnknownCommand = function handleUnknownCommand(resources, element, info, existingInstruction) { - var attrName = info.attrName, - command = info.command; - + var attrName = info.attrName; + var command = info.command; var instruction = this.options(resources, element, info, existingInstruction); instruction.alteredAttr = true; @@ -57,8 +56,8 @@ var SyntaxInterpreter = (function () { if (tagName === 'input') { return attrName === 'value' || attrName === 'checked' || attrName === 'files' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; - } else if (tagName == 'textarea' || tagName == 'select') { - return attrName == 'value' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; + } else if (tagName === 'textarea' || tagName === 'select') { + return attrName === 'value' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; } else if (attrName === 'textcontent' || attrName === 'innerhtml') { return element.contentEditable === 'true' ? _aureliaBinding.bindingMode.twoWay : _aureliaBinding.bindingMode.oneWay; } else if (attrName === 'scrolltop' || attrName === 'scrollleft') { @@ -93,14 +92,14 @@ var SyntaxInterpreter = (function () { }; SyntaxInterpreter.prototype.options = function options(resources, element, info, existingInstruction) { - var instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName), - attrValue = info.attrValue, - language = this.language, - name = null, - target = '', - current, - i, - ii; + var instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName); + var attrValue = info.attrValue; + var language = this.language; + var name = null; + var target = ''; + var current = undefined; + var i = undefined; + var ii = undefined; for (i = 0, ii = attrValue.length; i < ii; ++i) { current = attrValue[i]; @@ -141,7 +140,12 @@ var SyntaxInterpreter = (function () { exports.SyntaxInterpreter = SyntaxInterpreter; SyntaxInterpreter.prototype['for'] = function (resources, element, info, existingInstruction) { - var parts, keyValue, instruction, attrValue, isDestructuring; + var parts = undefined; + var keyValue = undefined; + var instruction = undefined; + var attrValue = undefined; + var isDestructuring = undefined; + attrValue = info.attrValue; isDestructuring = attrValue.match(/[[].+[\]]/); parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of '); @@ -189,8 +193,8 @@ SyntaxInterpreter.prototype['one-time'] = function (resources, element, info, ex return instruction; }; -var info = {}, - logger = LogManager.getLogger('templating-binding'); +var info = {}; +var logger = LogManager.getLogger('templating-binding'); var TemplatingBindingLanguage = (function (_BindingLanguage) { _inherits(TemplatingBindingLanguage, _BindingLanguage); @@ -235,7 +239,7 @@ var TemplatingBindingLanguage = (function (_BindingLanguage) { info.defaultBindingMode = null; - if (parts.length == 2) { + if (parts.length === 2) { info.attrName = parts[0].trim(); info.attrValue = attrValue; info.command = parts[1].trim(); @@ -247,7 +251,7 @@ var TemplatingBindingLanguage = (function (_BindingLanguage) { } else { info.expression = null; } - } else if (attrName == 'ref') { + } else if (attrName === 'ref') { info.attrName = attrName; info.attrValue = attrValue; info.command = null; @@ -262,18 +266,18 @@ var TemplatingBindingLanguage = (function (_BindingLanguage) { return info; }; - TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, info, existingInstruction) { - var instruction; + TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, theInfo, existingInstruction) { + var instruction = undefined; - if (info.expression) { - if (info.attrName === 'ref') { - return info.expression; + if (theInfo.expression) { + if (theInfo.attrName === 'ref') { + return theInfo.expression; } - instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(info.attrName); - instruction.attributes[info.attrName] = info.expression; - } else if (info.command) { - instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + instruction = existingInstruction || _aureliaTemplating.BehaviorInstruction.attribute(theInfo.attrName); + instruction.attributes[theInfo.attrName] = theInfo.expression; + } else if (theInfo.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, theInfo, existingInstruction); } return instruction; @@ -284,15 +288,16 @@ var TemplatingBindingLanguage = (function (_BindingLanguage) { }; TemplatingBindingLanguage.prototype.parseContent = function parseContent(resources, attrName, attrValue) { - var i = attrValue.indexOf('${', 0), - ii = attrValue.length, - char, - pos = 0, - open = 0, - quote = null, - interpolationStart, - parts, - partIndex = 0; + var i = attrValue.indexOf('${', 0); + var ii = attrValue.length; + var char = undefined; + var pos = 0; + var open = 0; + var quote = null; + var interpolationStart = undefined; + var parts = undefined; + var partIndex = 0; + while (i >= 0 && i < ii - 2) { open = 1; interpolationStart = i; @@ -301,18 +306,19 @@ var TemplatingBindingLanguage = (function (_BindingLanguage) { do { char = attrValue[i]; i++; - switch (char) { - case "'": - case '"': - if (quote === null) { - quote = char; - } else if (quote === char) { - quote = null; - } - continue; - case '\\': - i++; - continue; + + if (char === "'" || char === '"') { + if (quote === null) { + quote = char; + } else if (quote === char) { + quote = null; + } + continue; + } + + if (char === '\\') { + i++; + continue; } if (quote !== null) { @@ -391,6 +397,7 @@ var InterpolationBinding = (function () { } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && targetProperty === 'textContent') { throw new Error('Interpolation binding cannot be used in the content of a textarea element. Use instead.'); } + this.observerLocator = observerLocator; this.parts = parts; this.targetProperty = observerLocator.getObserver(target, targetProperty); @@ -406,7 +413,7 @@ var InterpolationBinding = (function () { InterpolationBinding.prototype.bind = function bind(source) { this.source = source; - if (this.mode == _aureliaBinding.bindingMode.oneWay) { + if (this.mode === _aureliaBinding.bindingMode.oneWay) { this.unbind(); this.connect(); this.setValue(); @@ -423,67 +430,72 @@ var InterpolationBinding = (function () { InterpolationBinding.prototype.partChanged = function partChanged(newValue, oldValue, connecting) { var _this = this; - var map, info; + var map = undefined; + var data = undefined; + if (!connecting) { this.setValue(); } + if (oldValue instanceof Array) { map = this.arrayPartMap; - info = map ? map.get(oldValue) : null; - if (info) { - info.refs--; - if (info.refs === 0) { - info.dispose(); + data = map ? map.get(oldValue) : null; + if (data) { + data.refs--; + if (data.refs === 0) { + data.dispose(); map['delete'](oldValue); } } } + if (newValue instanceof Array) { map = this.arrayPartMap || (this.arrayPartMap = new Map()); - info = map.get(newValue); - if (!info) { - info = { + data = map.get(newValue); + if (!data) { + data = { refs: 0, dispose: this.observerLocator.getArrayObserver(newValue).subscribe(function () { return _this.setValue(); }) }; - map.set(newValue, info); + + map.set(newValue, data); } - info.refs++; + data.refs++; } }; InterpolationBinding.prototype.connect = function connect() { - var info, - parts = this.parts, - source = this.source, - toDispose = this.toDispose = [], - partChanged = this.partChanged.bind(this), - i, - ii; + var result = undefined; + var parts = this.parts; + var source = this.source; + var toDispose = this.toDispose = []; + var partChanged = this.partChanged.bind(this); + var i = undefined; + var ii = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { - if (i % 2 === 0) {} else { - info = parts[i].connect(this, source); - if (info.observer) { - toDispose.push(info.observer.subscribe(partChanged)); - } - if (info.value instanceof Array) { - partChanged(info.value, undefined, true); - } + if (i % 2 !== 0) { + result = parts[i].connect(this, source); + if (result.observer) { + toDispose.push(result.observer.subscribe(partChanged)); + } + if (result.value instanceof Array) { + partChanged(result.value, undefined, true); } + } } }; InterpolationBinding.prototype.interpolate = function interpolate() { - var value = '', - parts = this.parts, - source = this.source, - valueConverterLookupFunction = this.valueConverterLookupFunction, - i, - ii, - temp; + var value = ''; + var parts = this.parts; + var source = this.source; + var valueConverterLookupFunction = this.valueConverterLookupFunction; + var i = undefined; + var ii = undefined; + var temp = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { if (i % 2 === 0) { @@ -498,10 +510,10 @@ var InterpolationBinding = (function () { }; InterpolationBinding.prototype.unbind = function unbind() { - var i, - ii, - toDispose = this.toDispose, - map = this.arrayPartMap; + var i = undefined; + var ii = undefined; + var toDispose = this.toDispose; + var map = this.arrayPartMap; if (toDispose) { for (i = 0, ii = toDispose.length; i < ii; ++i) { @@ -524,6 +536,7 @@ var InterpolationBinding = (function () { toDispose.dispose(); } + map.clear(); } @@ -534,8 +547,8 @@ var InterpolationBinding = (function () { })(); function configure(config) { - var instance, - getInstance = function getInstance(c) { + var instance = undefined; + var getInstance = function getInstance(c) { return instance || (instance = c.invoke(TemplatingBindingLanguage)); }; diff --git a/dist/es6/aurelia-templating-binding.d.ts b/dist/es6/aurelia-templating-binding.d.ts index 1d6b5ce..14b1f16 100644 --- a/dist/es6/aurelia-templating-binding.d.ts +++ b/dist/es6/aurelia-templating-binding.d.ts @@ -1,7 +1,9 @@ declare module 'aurelia-templating-binding' { import * as LogManager from 'aurelia-logging'; - import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode } from 'aurelia-binding'; + import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression } from 'aurelia-binding'; import { BehaviorInstruction, BindingLanguage } from 'aurelia-templating'; + + /*eslint dot-notation:0*/ export class SyntaxInterpreter { static inject(): any; constructor(parser: any, observerLocator: any, eventManager: any); @@ -18,7 +20,7 @@ declare module 'aurelia-templating-binding' { static inject(): any; constructor(parser: any, observerLocator: any, syntaxInterpreter: any); inspectAttribute(resources: any, attrName: any, attrValue: any): any; - createAttributeInstruction(resources: any, element: any, info: any, existingInstruction: any): any; + createAttributeInstruction(resources: any, element: any, theInfo: any, existingInstruction: any): any; parseText(resources: any, value: any): any; parseContent(resources: any, attrName: any, attrValue: any): any; } diff --git a/dist/es6/aurelia-templating-binding.js b/dist/es6/aurelia-templating-binding.js index bd1fb43..98f14b6 100644 --- a/dist/es6/aurelia-templating-binding.js +++ b/dist/es6/aurelia-templating-binding.js @@ -1,28 +1,28 @@ import * as LogManager from 'aurelia-logging'; -import {Parser,ObserverLocator,EventManager,ListenerExpression,BindingExpression,NameExpression,CallExpression,bindingMode} from 'aurelia-binding'; +import {Parser,ObserverLocator,EventManager,ListenerExpression,BindingExpression,CallExpression,bindingMode,NameExpression} from 'aurelia-binding'; import {BehaviorInstruction,BindingLanguage} from 'aurelia-templating'; +/*eslint dot-notation:0*/ export class SyntaxInterpreter { - static inject() { return [Parser,ObserverLocator,EventManager]; } - constructor(parser, observerLocator, eventManager){ + static inject() { return [Parser, ObserverLocator, EventManager]; } + constructor(parser, observerLocator, eventManager) { this.parser = parser; this.observerLocator = observerLocator; this.eventManager = eventManager; } - interpret(resources, element, info, existingInstruction){ - if(info.command in this){ + interpret(resources, element, info, existingInstruction) { + if (info.command in this) { return this[info.command](resources, element, info, existingInstruction); } return this.handleUnknownCommand(resources, element, info, existingInstruction); } - handleUnknownCommand(resources, element, info, existingInstruction){ - var attrName = info.attrName, - command = info.command; - - var instruction = this.options(resources, element, info, existingInstruction); + handleUnknownCommand(resources, element, info, existingInstruction) { + let attrName = info.attrName; + let command = info.command; + let instruction = this.options(resources, element, info, existingInstruction); instruction.alteredAttr = true; instruction.attrName = 'global-behavior'; @@ -32,24 +32,24 @@ export class SyntaxInterpreter { return instruction; } - determineDefaultBindingMode(element, attrName){ - var tagName = element.tagName.toLowerCase(); + determineDefaultBindingMode(element, attrName) { + let tagName = element.tagName.toLowerCase(); - if(tagName === 'input'){ + if (tagName === 'input') { return attrName === 'value' || attrName === 'checked' || attrName === 'files' ? bindingMode.twoWay : bindingMode.oneWay; - }else if(tagName == 'textarea' || tagName == 'select'){ - return attrName == 'value' ? bindingMode.twoWay : bindingMode.oneWay; - }else if(attrName === 'textcontent' || attrName === 'innerhtml'){ + } else if (tagName === 'textarea' || tagName === 'select') { + return attrName === 'value' ? bindingMode.twoWay : bindingMode.oneWay; + } else if (attrName === 'textcontent' || attrName === 'innerhtml') { return element.contentEditable === 'true' ? bindingMode.twoWay : bindingMode.oneWay; - } else if(attrName === 'scrolltop' || attrName === 'scrollleft'){ + } else if (attrName === 'scrolltop' || attrName === 'scrollleft') { return bindingMode.twoWay; } return bindingMode.oneWay; } - bind(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); + bind(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); instruction.attributes[info.attrName] = new BindingExpression( this.observerLocator, @@ -62,7 +62,7 @@ export class SyntaxInterpreter { return instruction; } - trigger(resources, element, info){ + trigger(resources, element, info) { return new ListenerExpression( this.eventManager, info.attrName, @@ -72,7 +72,7 @@ export class SyntaxInterpreter { ); } - delegate(resources, element, info){ + delegate(resources, element, info) { return new ListenerExpression( this.eventManager, info.attrName, @@ -82,8 +82,8 @@ export class SyntaxInterpreter { ); } - call(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); + call(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); instruction.attributes[info.attrName] = new CallExpression( this.observerLocator, @@ -93,28 +93,32 @@ export class SyntaxInterpreter { ); return instruction; - }; - - options(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName), - attrValue = info.attrValue, - language = this.language, - name = null, target = '', current, i , ii; + } - for(i = 0, ii = attrValue.length; i < ii; ++i){ + options(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); + let attrValue = info.attrValue; + let language = this.language; + let name = null; + let target = ''; + let current; + let i; + let ii; + + for (i = 0, ii = attrValue.length; i < ii; ++i) { current = attrValue[i]; - if(current === ';'){ + if (current === ';') { info = language.inspectAttribute(resources, name, target.trim()); language.createAttributeInstruction(resources, element, info, instruction); - if(!instruction.attributes[info.attrName]){ + if (!instruction.attributes[info.attrName]) { instruction.attributes[info.attrName] = info.attrValue; } target = ''; name = null; - } else if(current === ':' && name === null){ + } else if (current === ':' && name === null) { name = target.trim(); target = ''; } else { @@ -122,11 +126,11 @@ export class SyntaxInterpreter { } } - if(name !== null){ + if (name !== null) { info = language.inspectAttribute(resources, name, target.trim()); language.createAttributeInstruction(resources, element, info, instruction); - if(!instruction.attributes[info.attrName]){ + if (!instruction.attributes[info.attrName]) { instruction.attributes[info.attrName] = info.attrValue; } } @@ -135,23 +139,28 @@ export class SyntaxInterpreter { } } -SyntaxInterpreter.prototype['for'] = function(resources, element, info, existingInstruction){ - var parts, keyValue, instruction, attrValue, isDestructuring; +SyntaxInterpreter.prototype['for'] = function(resources, element, info, existingInstruction) { + let parts; + let keyValue; + let instruction; + let attrValue; + let isDestructuring; + attrValue = info.attrValue; isDestructuring = attrValue.match(/[[].+[\]]/); parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of '); - if(parts.length !== 2){ + if (parts.length !== 2) { throw new Error('Incorrect syntax for "for". The form is: "$local of $items" or "[$key, $value] of $items".'); } instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - if(isDestructuring){ + if (isDestructuring) { keyValue = parts[0].replace(/[[\]]/g, '').replace(/,/g, ' ').replace(/\s+/g, ' ').trim().split(' '); instruction.attributes.key = keyValue[0]; instruction.attributes.value = keyValue[1]; - }else{ + } else { instruction.attributes.local = parts[0]; } @@ -166,8 +175,8 @@ SyntaxInterpreter.prototype['for'] = function(resources, element, info, existing return instruction; }; -SyntaxInterpreter.prototype['two-way'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); +SyntaxInterpreter.prototype['two-way'] = function(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); instruction.attributes[info.attrName] = new BindingExpression( this.observerLocator, @@ -180,8 +189,8 @@ SyntaxInterpreter.prototype['two-way'] = function(resources, element, info, exis return instruction; }; -SyntaxInterpreter.prototype['one-way'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); +SyntaxInterpreter.prototype['one-way'] = function(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); instruction.attributes[info.attrName] = new BindingExpression( this.observerLocator, @@ -194,8 +203,8 @@ SyntaxInterpreter.prototype['one-way'] = function(resources, element, info, exis return instruction; }; -SyntaxInterpreter.prototype['one-time'] = function(resources, element, info, existingInstruction){ - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); +SyntaxInterpreter.prototype['one-time'] = function(resources, element, info, existingInstruction) { + let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); instruction.attributes[info.attrName] = new BindingExpression( this.observerLocator, @@ -208,12 +217,12 @@ SyntaxInterpreter.prototype['one-time'] = function(resources, element, info, exi return instruction; }; -var info = {}, - logger = LogManager.getLogger('templating-binding'); +let info = {}; +let logger = LogManager.getLogger('templating-binding'); export class TemplatingBindingLanguage extends BindingLanguage { static inject() { return [Parser, ObserverLocator, SyntaxInterpreter]; } - constructor(parser, observerLocator, syntaxInterpreter){ + constructor(parser, observerLocator, syntaxInterpreter) { super(); this.parser = parser; this.observerLocator = observerLocator; @@ -221,50 +230,50 @@ export class TemplatingBindingLanguage extends BindingLanguage { this.emptyStringExpression = this.parser.parse('\'\''); syntaxInterpreter.language = this; this.attributeMap = syntaxInterpreter.attributeMap = { - 'contenteditable':'contentEditable', - 'for':'htmlFor', - 'tabindex':'tabIndex', + 'contenteditable': 'contentEditable', + 'for': 'htmlFor', + 'tabindex': 'tabIndex', 'textcontent': 'textContent', 'innerhtml': 'innerHTML', // HTMLInputElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement - 'maxlength':'maxLength', - 'minlength':'minLength', - 'formaction':'formAction', - 'formenctype':'formEncType', - 'formmethod':'formMethod', - 'formnovalidate':'formNoValidate', - 'formtarget':'formTarget', - 'rowspan':'rowSpan', - 'colspan':'colSpan', - 'scrolltop':'scrollTop', - 'scrollleft':'scrollLeft', - 'readonly':'readOnly' + 'maxlength': 'maxLength', + 'minlength': 'minLength', + 'formaction': 'formAction', + 'formenctype': 'formEncType', + 'formmethod': 'formMethod', + 'formnovalidate': 'formNoValidate', + 'formtarget': 'formTarget', + 'rowspan': 'rowSpan', + 'colspan': 'colSpan', + 'scrolltop': 'scrollTop', + 'scrollleft': 'scrollLeft', + 'readonly': 'readOnly' }; } - inspectAttribute(resources, attrName, attrValue){ - var parts = attrName.split('.'); + inspectAttribute(resources, attrName, attrValue) { + let parts = attrName.split('.'); info.defaultBindingMode = null; - if(parts.length == 2){ + if (parts.length === 2) { info.attrName = parts[0].trim(); info.attrValue = attrValue; info.command = parts[1].trim(); - if(info.command === 'ref'){ + if (info.command === 'ref') { info.expression = new NameExpression(attrValue, info.attrName); info.command = null; info.attrName = 'ref'; - } else{ + } else { info.expression = null; } - }else if(attrName == 'ref'){ + } else if (attrName === 'ref') { info.attrName = attrName; info.attrValue = attrValue; info.command = null; info.expression = new NameExpression(attrValue, 'element'); - }else{ + } else { info.attrName = attrName; info.attrValue = attrValue; info.command = null; @@ -274,37 +283,44 @@ export class TemplatingBindingLanguage extends BindingLanguage { return info; } - createAttributeInstruction(resources, element, info, existingInstruction){ - var instruction; + createAttributeInstruction(resources, element, theInfo, existingInstruction) { + let instruction; - if(info.expression){ - if(info.attrName === 'ref'){ - return info.expression; + if (theInfo.expression) { + if (theInfo.attrName === 'ref') { + return theInfo.expression; } - instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - instruction.attributes[info.attrName] = info.expression; - } else if(info.command){ + instruction = existingInstruction || BehaviorInstruction.attribute(theInfo.attrName); + instruction.attributes[theInfo.attrName] = theInfo.expression; + } else if (theInfo.command) { instruction = this.syntaxInterpreter.interpret( resources, element, - info, + theInfo, existingInstruction ); } - return instruction; - } + return instruction; + } - parseText(resources, value){ + parseText(resources, value) { return this.parseContent(resources, 'textContent', value); } - parseContent(resources, attrName, attrValue){ - var i = attrValue.indexOf('${', 0), ii = attrValue.length, - char, pos = 0, open = 0, quote = null, interpolationStart, - parts, partIndex = 0; - while(i >= 0 && i < ii - 2) { + parseContent(resources, attrName, attrValue) { + let i = attrValue.indexOf('${', 0); + let ii = attrValue.length; + let char; + let pos = 0; + let open = 0; + let quote = null; + let interpolationStart; + let parts; + let partIndex = 0; + + while (i >= 0 && i < ii - 2) { open = 1; interpolationStart = i; i += 2; @@ -312,18 +328,19 @@ export class TemplatingBindingLanguage extends BindingLanguage { do { char = attrValue[i]; i++; - switch(char) { - case "'": - case '"': - if (quote === null) { - quote = char; - } else if (quote === char) { - quote = null; - } - continue; - case '\\': - i++; - continue; + + if (char === "'" || char === '"') { + if (quote === null) { + quote = char; + } else if (quote === char) { + quote = null; + } + continue; + } + + if (char === '\\') { + i++; + continue; } if (quote !== null) { @@ -335,7 +352,7 @@ export class TemplatingBindingLanguage extends BindingLanguage { } else if (char === '}') { open--; } - } while(open > 0 && i < ii) + } while (open > 0 && i < ii) if (open === 0) { // lazy allocate array @@ -381,7 +398,7 @@ export class TemplatingBindingLanguage extends BindingLanguage { export class InterpolationBindingExpression { constructor(observerLocator, targetProperty, parts, - mode, valueConverterLookupFunction, attribute){ + mode, valueConverterLookupFunction, attribute) { this.observerLocator = observerLocator; this.targetProperty = targetProperty; this.parts = parts; @@ -391,7 +408,7 @@ export class InterpolationBindingExpression { this.discrete = false; } - createBinding(target){ + createBinding(target) { return new InterpolationBinding( this.observerLocator, this.parts, @@ -404,12 +421,13 @@ export class InterpolationBindingExpression { } class InterpolationBinding { - constructor(observerLocator, parts, target, targetProperty, mode, valueConverterLookupFunction){ + constructor(observerLocator, parts, target, targetProperty, mode, valueConverterLookupFunction) { if (targetProperty === 'style') { logger.info('Internet Explorer does not support interpolation in "style" attributes. Use the style attribute\'s alias, "css" instead.'); } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && targetProperty === 'textContent') { throw new Error('Interpolation binding cannot be used in the content of a textarea element. Use instead.'); } + this.observerLocator = observerLocator; this.parts = parts; this.targetProperty = observerLocator.getObserver(target, targetProperty); @@ -418,88 +436,94 @@ class InterpolationBinding { this.toDispose = []; } - getObserver(obj, propertyName){ + getObserver(obj, propertyName) { return this.observerLocator.getObserver(obj, propertyName); } - bind(source){ + bind(source) { this.source = source; - if(this.mode == bindingMode.oneWay){ + if (this.mode === bindingMode.oneWay) { this.unbind(); this.connect(); this.setValue(); - }else{ + } else { this.setValue(); } } - setValue(){ - var value = this.interpolate(); + setValue() { + let value = this.interpolate(); this.targetProperty.setValue(value); } - partChanged(newValue, oldValue, connecting){ - var map, info; + partChanged(newValue, oldValue, connecting) { + let map; + let data; + if (!connecting) { this.setValue(); } + if (oldValue instanceof Array) { map = this.arrayPartMap; - info = map ? map.get(oldValue) : null; - if (info) { - info.refs--; - if (info.refs === 0) { - info.dispose(); + data = map ? map.get(oldValue) : null; + if (data) { + data.refs--; + if (data.refs === 0) { + data.dispose(); map.delete(oldValue); } } } + if (newValue instanceof Array) { map = this.arrayPartMap || (this.arrayPartMap = new Map()); - info = map.get(newValue); - if (!info) { - info = { + data = map.get(newValue); + if (!data) { + data = { refs: 0, dispose: this.observerLocator.getArrayObserver(newValue).subscribe(() => this.setValue()) - } - map.set(newValue, info); + }; + + map.set(newValue, data); } - info.refs++; + data.refs++; } } - connect(){ - var info, - parts = this.parts, - source = this.source, - toDispose = this.toDispose = [], - partChanged = this.partChanged.bind(this), - i, ii; - - for(i = 0, ii = parts.length; i < ii; ++i){ - if (i % 2 === 0) { - //do nothing - } else { - info = parts[i].connect(this, source); - if(info.observer){ - toDispose.push(info.observer.subscribe(partChanged)); + connect() { + let result; + let parts = this.parts; + let source = this.source; + let toDispose = this.toDispose = []; + let partChanged = this.partChanged.bind(this); + let i; + let ii; + + for (i = 0, ii = parts.length; i < ii; ++i) { + if (i % 2 !== 0) { + result = parts[i].connect(this, source); + if (result.observer) { + toDispose.push(result.observer.subscribe(partChanged)); } - if (info.value instanceof Array) { - partChanged(info.value, undefined, true); + if (result.value instanceof Array) { + partChanged(result.value, undefined, true); } } } } - interpolate(){ - var value = '', - parts = this.parts, - source = this.source, - valueConverterLookupFunction = this.valueConverterLookupFunction, - i, ii, temp; + interpolate() { + let value = ''; + let parts = this.parts; + let source = this.source; + let valueConverterLookupFunction = this.valueConverterLookupFunction; + let i; + let ii; + let temp; - for(i = 0, ii = parts.length; i < ii; ++i){ + for (i = 0, ii = parts.length; i < ii; ++i) { if (i % 2 === 0) { value += parts[i]; } else { @@ -511,11 +535,14 @@ class InterpolationBinding { return value; } - unbind(){ - var i, ii, toDispose = this.toDispose, map = this.arrayPartMap; + unbind() { + let i; + let ii; + let toDispose = this.toDispose; + let map = this.arrayPartMap; - if(toDispose){ - for(i = 0, ii = toDispose.length; i < ii; ++i){ + if (toDispose) { + for (i = 0, ii = toDispose.length; i < ii; ++i) { toDispose[i](); } } @@ -523,9 +550,10 @@ class InterpolationBinding { this.toDispose = null; if (map) { - for(toDispose of map.values()) { + for (toDispose of map.values()) { toDispose.dispose(); } + map.clear(); } @@ -533,15 +561,15 @@ class InterpolationBinding { } } -export function configure(config){ - var instance, - getInstance = function (c){ - return instance || (instance = c.invoke(TemplatingBindingLanguage)); - }; +export function configure(config) { + let instance; + let getInstance = function(c) { + return instance || (instance = c.invoke(TemplatingBindingLanguage)); + }; - if(config.container.hasHandler(TemplatingBindingLanguage)){ + if (config.container.hasHandler(TemplatingBindingLanguage)) { instance = config.container.get(TemplatingBindingLanguage); - }else{ + } else { config.container.registerHandler(TemplatingBindingLanguage, getInstance); } diff --git a/dist/system/aurelia-templating-binding.d.ts b/dist/system/aurelia-templating-binding.d.ts index 1d6b5ce..14b1f16 100644 --- a/dist/system/aurelia-templating-binding.d.ts +++ b/dist/system/aurelia-templating-binding.d.ts @@ -1,7 +1,9 @@ declare module 'aurelia-templating-binding' { import * as LogManager from 'aurelia-logging'; - import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode } from 'aurelia-binding'; + import { Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression } from 'aurelia-binding'; import { BehaviorInstruction, BindingLanguage } from 'aurelia-templating'; + + /*eslint dot-notation:0*/ export class SyntaxInterpreter { static inject(): any; constructor(parser: any, observerLocator: any, eventManager: any); @@ -18,7 +20,7 @@ declare module 'aurelia-templating-binding' { static inject(): any; constructor(parser: any, observerLocator: any, syntaxInterpreter: any); inspectAttribute(resources: any, attrName: any, attrValue: any): any; - createAttributeInstruction(resources: any, element: any, info: any, existingInstruction: any): any; + createAttributeInstruction(resources: any, element: any, theInfo: any, existingInstruction: any): any; parseText(resources: any, value: any): any; parseContent(resources: any, attrName: any, attrValue: any): any; } diff --git a/dist/system/aurelia-templating-binding.js b/dist/system/aurelia-templating-binding.js index 2222d42..9148908 100644 --- a/dist/system/aurelia-templating-binding.js +++ b/dist/system/aurelia-templating-binding.js @@ -1,7 +1,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], function (_export) { 'use strict'; - var LogManager, Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, bindingMode, BehaviorInstruction, BindingLanguage, SyntaxInterpreter, info, logger, TemplatingBindingLanguage, InterpolationBindingExpression, InterpolationBinding; + var LogManager, Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, CallExpression, bindingMode, NameExpression, BehaviorInstruction, BindingLanguage, SyntaxInterpreter, info, logger, TemplatingBindingLanguage, InterpolationBindingExpression, InterpolationBinding; _export('configure', configure); @@ -10,8 +10,8 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function configure(config) { - var instance, - getInstance = function getInstance(c) { + var instance = undefined; + var getInstance = function getInstance(c) { return instance || (instance = c.invoke(TemplatingBindingLanguage)); }; @@ -33,9 +33,9 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu EventManager = _aureliaBinding.EventManager; ListenerExpression = _aureliaBinding.ListenerExpression; BindingExpression = _aureliaBinding.BindingExpression; - NameExpression = _aureliaBinding.NameExpression; CallExpression = _aureliaBinding.CallExpression; bindingMode = _aureliaBinding.bindingMode; + NameExpression = _aureliaBinding.NameExpression; }, function (_aureliaTemplating) { BehaviorInstruction = _aureliaTemplating.BehaviorInstruction; BindingLanguage = _aureliaTemplating.BindingLanguage; @@ -63,9 +63,8 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu }; SyntaxInterpreter.prototype.handleUnknownCommand = function handleUnknownCommand(resources, element, info, existingInstruction) { - var attrName = info.attrName, - command = info.command; - + var attrName = info.attrName; + var command = info.command; var instruction = this.options(resources, element, info, existingInstruction); instruction.alteredAttr = true; @@ -81,8 +80,8 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu if (tagName === 'input') { return attrName === 'value' || attrName === 'checked' || attrName === 'files' ? bindingMode.twoWay : bindingMode.oneWay; - } else if (tagName == 'textarea' || tagName == 'select') { - return attrName == 'value' ? bindingMode.twoWay : bindingMode.oneWay; + } else if (tagName === 'textarea' || tagName === 'select') { + return attrName === 'value' ? bindingMode.twoWay : bindingMode.oneWay; } else if (attrName === 'textcontent' || attrName === 'innerhtml') { return element.contentEditable === 'true' ? bindingMode.twoWay : bindingMode.oneWay; } else if (attrName === 'scrolltop' || attrName === 'scrollleft') { @@ -117,14 +116,14 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu }; SyntaxInterpreter.prototype.options = function options(resources, element, info, existingInstruction) { - var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName), - attrValue = info.attrValue, - language = this.language, - name = null, - target = '', - current, - i, - ii; + var instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); + var attrValue = info.attrValue; + var language = this.language; + var name = null; + var target = ''; + var current = undefined; + var i = undefined; + var ii = undefined; for (i = 0, ii = attrValue.length; i < ii; ++i) { current = attrValue[i]; @@ -165,7 +164,12 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu _export('SyntaxInterpreter', SyntaxInterpreter); SyntaxInterpreter.prototype['for'] = function (resources, element, info, existingInstruction) { - var parts, keyValue, instruction, attrValue, isDestructuring; + var parts = undefined; + var keyValue = undefined; + var instruction = undefined; + var attrValue = undefined; + var isDestructuring = undefined; + attrValue = info.attrValue; isDestructuring = attrValue.match(/[[].+[\]]/); parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of '); @@ -259,7 +263,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu info.defaultBindingMode = null; - if (parts.length == 2) { + if (parts.length === 2) { info.attrName = parts[0].trim(); info.attrValue = attrValue; info.command = parts[1].trim(); @@ -271,7 +275,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu } else { info.expression = null; } - } else if (attrName == 'ref') { + } else if (attrName === 'ref') { info.attrName = attrName; info.attrValue = attrValue; info.command = null; @@ -286,18 +290,18 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu return info; }; - TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, info, existingInstruction) { - var instruction; + TemplatingBindingLanguage.prototype.createAttributeInstruction = function createAttributeInstruction(resources, element, theInfo, existingInstruction) { + var instruction = undefined; - if (info.expression) { - if (info.attrName === 'ref') { - return info.expression; + if (theInfo.expression) { + if (theInfo.attrName === 'ref') { + return theInfo.expression; } - instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName); - instruction.attributes[info.attrName] = info.expression; - } else if (info.command) { - instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + instruction = existingInstruction || BehaviorInstruction.attribute(theInfo.attrName); + instruction.attributes[theInfo.attrName] = theInfo.expression; + } else if (theInfo.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, theInfo, existingInstruction); } return instruction; @@ -308,15 +312,16 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu }; TemplatingBindingLanguage.prototype.parseContent = function parseContent(resources, attrName, attrValue) { - var i = attrValue.indexOf('${', 0), - ii = attrValue.length, - char, - pos = 0, - open = 0, - quote = null, - interpolationStart, - parts, - partIndex = 0; + var i = attrValue.indexOf('${', 0); + var ii = attrValue.length; + var char = undefined; + var pos = 0; + var open = 0; + var quote = null; + var interpolationStart = undefined; + var parts = undefined; + var partIndex = 0; + while (i >= 0 && i < ii - 2) { open = 1; interpolationStart = i; @@ -325,18 +330,19 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu do { char = attrValue[i]; i++; - switch (char) { - case "'": - case '"': - if (quote === null) { - quote = char; - } else if (quote === char) { - quote = null; - } - continue; - case '\\': - i++; - continue; + + if (char === "'" || char === '"') { + if (quote === null) { + quote = char; + } else if (quote === char) { + quote = null; + } + continue; + } + + if (char === '\\') { + i++; + continue; } if (quote !== null) { @@ -415,6 +421,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && targetProperty === 'textContent') { throw new Error('Interpolation binding cannot be used in the content of a textarea element. Use instead.'); } + this.observerLocator = observerLocator; this.parts = parts; this.targetProperty = observerLocator.getObserver(target, targetProperty); @@ -430,7 +437,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu InterpolationBinding.prototype.bind = function bind(source) { this.source = source; - if (this.mode == bindingMode.oneWay) { + if (this.mode === bindingMode.oneWay) { this.unbind(); this.connect(); this.setValue(); @@ -447,67 +454,72 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu InterpolationBinding.prototype.partChanged = function partChanged(newValue, oldValue, connecting) { var _this = this; - var map, info; + var map = undefined; + var data = undefined; + if (!connecting) { this.setValue(); } + if (oldValue instanceof Array) { map = this.arrayPartMap; - info = map ? map.get(oldValue) : null; - if (info) { - info.refs--; - if (info.refs === 0) { - info.dispose(); + data = map ? map.get(oldValue) : null; + if (data) { + data.refs--; + if (data.refs === 0) { + data.dispose(); map['delete'](oldValue); } } } + if (newValue instanceof Array) { map = this.arrayPartMap || (this.arrayPartMap = new Map()); - info = map.get(newValue); - if (!info) { - info = { + data = map.get(newValue); + if (!data) { + data = { refs: 0, dispose: this.observerLocator.getArrayObserver(newValue).subscribe(function () { return _this.setValue(); }) }; - map.set(newValue, info); + + map.set(newValue, data); } - info.refs++; + data.refs++; } }; InterpolationBinding.prototype.connect = function connect() { - var info, - parts = this.parts, - source = this.source, - toDispose = this.toDispose = [], - partChanged = this.partChanged.bind(this), - i, - ii; + var result = undefined; + var parts = this.parts; + var source = this.source; + var toDispose = this.toDispose = []; + var partChanged = this.partChanged.bind(this); + var i = undefined; + var ii = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { - if (i % 2 === 0) {} else { - info = parts[i].connect(this, source); - if (info.observer) { - toDispose.push(info.observer.subscribe(partChanged)); - } - if (info.value instanceof Array) { - partChanged(info.value, undefined, true); - } + if (i % 2 !== 0) { + result = parts[i].connect(this, source); + if (result.observer) { + toDispose.push(result.observer.subscribe(partChanged)); + } + if (result.value instanceof Array) { + partChanged(result.value, undefined, true); } + } } }; InterpolationBinding.prototype.interpolate = function interpolate() { - var value = '', - parts = this.parts, - source = this.source, - valueConverterLookupFunction = this.valueConverterLookupFunction, - i, - ii, - temp; + var value = ''; + var parts = this.parts; + var source = this.source; + var valueConverterLookupFunction = this.valueConverterLookupFunction; + var i = undefined; + var ii = undefined; + var temp = undefined; for (i = 0, ii = parts.length; i < ii; ++i) { if (i % 2 === 0) { @@ -522,10 +534,10 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu }; InterpolationBinding.prototype.unbind = function unbind() { - var i, - ii, - toDispose = this.toDispose, - map = this.arrayPartMap; + var i = undefined; + var ii = undefined; + var toDispose = this.toDispose; + var map = this.arrayPartMap; if (toDispose) { for (i = 0, ii = toDispose.length; i < ii; ++i) { @@ -548,6 +560,7 @@ System.register(['aurelia-logging', 'aurelia-binding', 'aurelia-templating'], fu toDispose.dispose(); } + map.clear(); } diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 51cd6a4..69df8e4 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.15.0 (2015-09-05) + + +#### Bug Fixes + +* **build:** update linting, testing and tools ([9c763bac](http://github.com/aurelia/templating-binding/commit/9c763baccbe013cc0e45ec90676cddb843280ecf)) + + +#### Features + +* **docs:** generate api.json from .d.ts file ([ea1742b7](http://github.com/aurelia/templating-binding/commit/ea1742b74bec9711d82e4c0d02ae9d2c90a72d87)) + + ## 0.14.0 (2015-08-14) diff --git a/package.json b/package.json index dc1820e..26480c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aurelia-templating-binding", - "version": "0.14.0", + "version": "0.15.0", "description": "An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.", "keywords": [ "aurelia", @@ -26,9 +26,9 @@ "lib": "dist/amd" }, "dependencies": { - "aurelia-binding": "github:aurelia/binding@^0.8.6", - "aurelia-logging": "github:aurelia/logging@^0.6.4", - "aurelia-templating": "github:aurelia/templating@^0.14.0" + "aurelia-binding": "github:aurelia/binding@^0.9.0", + "aurelia-logging": "github:aurelia/logging@^0.7.0", + "aurelia-templating": "github:aurelia/templating@^0.15.0" }, "devDependencies": { "babel": "npm:babel-core@^5.1.13", diff --git a/test/interpolation-binding.spec.js b/test/interpolation-binding.spec.js index 8b619a2..429f620 100644 --- a/test/interpolation-binding.spec.js +++ b/test/interpolation-binding.spec.js @@ -16,7 +16,7 @@ import { import {ViewResources} from 'aurelia-templating'; -import {TaskQueue} from 'jspm_packages/github/aurelia/task-queue@0.6.2/aurelia-task-queue'; +import {TaskQueue} from 'jspm_packages/github/aurelia/task-queue@0.7.0/aurelia-task-queue'; function createElement(html) { var div = document.createElement('div');