From 65914646577b0d502e2d26fed09eb911978ced19 Mon Sep 17 00:00:00 2001 From: Rob Eisenberg Date: Mon, 12 Jan 2015 09:49:40 -0500 Subject: [PATCH] chore(all): prepare release 0.7.0 --- bower.json | 2 +- dist/amd/binding-language.js | 151 ++++++++----- dist/amd/syntax-interpreter.js | 262 ++++++++++++++--------- dist/commonjs/binding-language.js | 151 ++++++++----- dist/commonjs/syntax-interpreter.js | 262 ++++++++++++++--------- dist/es6/binding-language.js | 65 ++++-- dist/es6/syntax-interpreter.js | 316 +++++++++++++++------------- dist/system/binding-language.js | 150 ++++++++----- dist/system/syntax-interpreter.js | 264 ++++++++++++++--------- doc/CHANGELOG.md | 17 ++ package.json | 2 +- 11 files changed, 1036 insertions(+), 606 deletions(-) diff --git a/bower.json b/bower.json index 24b821c..eb4e71d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "aurelia-templating-binding", - "version": "0.6.0", + "version": "0.7.0", "description": "An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.", "keywords": [ "aurelia", diff --git a/dist/amd/binding-language.js b/dist/amd/binding-language.js index 96f7f0f..de60d5e 100644 --- a/dist/amd/binding-language.js +++ b/dist/amd/binding-language.js @@ -1,6 +1,11 @@ define(["exports", "aurelia-templating", "aurelia-binding", "./syntax-interpreter"], function (exports, _aureliaTemplating, _aureliaBinding, _syntaxInterpreter) { "use strict"; + var _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); + }; + var _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -20,10 +25,14 @@ define(["exports", "aurelia-templating", "aurelia-binding", "./syntax-interprete var Parser = _aureliaBinding.Parser; var ObserverLocator = _aureliaBinding.ObserverLocator; var BindingExpression = _aureliaBinding.BindingExpression; + var NameExpression = _aureliaBinding.NameExpression; var ONE_WAY = _aureliaBinding.ONE_WAY; var SyntaxInterpreter = _syntaxInterpreter.SyntaxInterpreter; - var TemplatingBindingLanguage = (function () { - var _BindingLanguage = BindingLanguage; + + + var info = {}; + + var TemplatingBindingLanguage = (function (BindingLanguage) { var TemplatingBindingLanguage = function TemplatingBindingLanguage(parser, observerLocator, syntaxInterpreter) { this.parser = parser; this.observerLocator = observerLocator; @@ -32,63 +41,107 @@ define(["exports", "aurelia-templating", "aurelia-binding", "./syntax-interprete syntaxInterpreter.language = this; }; - _inherits(TemplatingBindingLanguage, _BindingLanguage); - - TemplatingBindingLanguage.inject = function () { - return [Parser, ObserverLocator, SyntaxInterpreter]; - }; + _inherits(TemplatingBindingLanguage, BindingLanguage); - TemplatingBindingLanguage.prototype.parseAttribute = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrName.split("."), instruction; - - if (parts.length == 2) { - instruction = this.syntaxInterpreter.interpret(parts[1].trim(), resources, element, parts[0].trim(), attrValue, existingInstruction); - - if (!existingInstruction) { - instruction.originalAttrName = attrName; - } - } else { - var expression = this.parseContent(resources, attrName, attrValue); - if (expression) { - instruction = existingInstruction || { attrName: attrName, attributes: {} }; - instruction.attributes[attrName] = expression; - } + _prototypeProperties(TemplatingBindingLanguage, { + inject: { + value: function () { + return [Parser, ObserverLocator, SyntaxInterpreter]; + }, + writable: true, + enumerable: true, + configurable: true } + }, { + inspectAttribute: { + value: function (resources, attrName, attrValue) { + var parts = attrName.split("."); + + if (parts.length == 2) { + info.attrName = parts[0].trim(); + info.attrValue = attrValue; + info.command = parts[1].trim(); + 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; + }, + writable: true, + enumerable: true, + configurable: true + }, + createAttributeInstruction: { + value: function (resources, element, info, existingInstruction) { + var instruction; + + if (info.expression) { + if (info.attrName === "ref") { + return info.expression; + } + + instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + instruction.attributes[info.attrName] = info.expression; + } else if (info.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + parseText: { + value: function (resources, value) { + return this.parseContent(resources, "textContent", value); + }, + writable: true, + enumerable: true, + configurable: true + }, + parseContent: { + value: function (resources, attrName, attrValue) { + var expressionText, expression; - return instruction; - }; - - TemplatingBindingLanguage.prototype.parseText = function (resources, value) { - return this.parseContent(resources, "textContent", value); - }; - - TemplatingBindingLanguage.prototype.parseContent = function (resources, attrName, attrValue) { - var expressionText, expression; + var parts = attrValue.split(this.interpolationRegex); + if (parts.length <= 1) { + return null; + } - var parts = attrValue.split(this.interpolationRegex); - if (parts.length <= 1) { - return null; - } + parts.forEach(function (part, index) { + if (index % 2 === 0) { + parts[index] = "'" + part + "'"; + } else { + parts[index] = "(" + part + ")"; + } + }); - parts.forEach(function (part, index) { - if (index % 2 === 0) { - parts[index] = "'" + part + "'"; - } else { - parts[index] = "(" + part + ")"; - } - }); + expressionText = parts.join("+"); - expressionText = parts.join("+"); + expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); - expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); + expression.attribute = attrName; - expression.attribute = attrName; - - return expression; - }; + return expression; + }, + writable: true, + enumerable: true, + configurable: true + } + }); return TemplatingBindingLanguage; - })(); + })(BindingLanguage); exports.TemplatingBindingLanguage = TemplatingBindingLanguage; }); \ No newline at end of file diff --git a/dist/amd/syntax-interpreter.js b/dist/amd/syntax-interpreter.js index 55e3c90..c2df8ac 100644 --- a/dist/amd/syntax-interpreter.js +++ b/dist/amd/syntax-interpreter.js @@ -1,6 +1,11 @@ define(["exports", "aurelia-binding"], function (exports, _aureliaBinding) { "use strict"; + var _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); + }; + var Parser = _aureliaBinding.Parser; var ObserverLocator = _aureliaBinding.ObserverLocator; var EventManager = _aureliaBinding.EventManager; @@ -11,125 +16,194 @@ define(["exports", "aurelia-binding"], function (exports, _aureliaBinding) { var ONE_WAY = _aureliaBinding.ONE_WAY; var TWO_WAY = _aureliaBinding.TWO_WAY; var ONE_TIME = _aureliaBinding.ONE_TIME; - var SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { - this.parser = parser; - this.observerLocator = observerLocator; - this.eventManager = eventManager; - - this["for"] = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrValue.split(" of "); - - if (parts.length !== 2) { - throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); - } - - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes.local = parts[0]; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["two-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), TWO_WAY, resources.valueConverterLookupFunction); - - return instruction; + var SyntaxInterpreter = (function () { + var SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { + this.parser = parser; + this.observerLocator = observerLocator; + this.eventManager = eventManager; }; - this["one-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["one-time"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_TIME, resources.valueConverterLookupFunction); - - return instruction; - }; + _prototypeProperties(SyntaxInterpreter, { + inject: { + value: function () { + return [Parser, ObserverLocator, EventManager]; + }, + writable: true, + enumerable: true, + configurable: true + } + }, { + interpret: { + value: function (resources, element, info, existingInstruction) { + if (info.command in this) { + return this[info.command](resources, element, info, existingInstruction); + } + + return this.handleUnknownCommand(resources, element, info, existingInstruction); + }, + writable: true, + enumerable: true, + configurable: true + }, + handleUnknownCommand: { + value: function (resources, element, info, existingInstruction) { + throw new Error("Unknown binding command ${info.command} used."); + }, + writable: true, + enumerable: true, + configurable: true + }, + determineDefaultBindingMode: { + value: function (element, attrName) { + var tagName = element.tagName.toLowerCase(); + + if (tagName === "input") { + return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; + } else if (tagName == "textarea" || tagName == "select") { + return attrName == "value" ? TWO_WAY : ONE_WAY; + } + + return ONE_WAY; + }, + writable: true, + enumerable: true, + configurable: true + }, + bind: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), this.determineDefaultBindingMode(element, info.attrName), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + trigger: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), false, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + delegate: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), true, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + call: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new CallExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + options: { + value: function (resources, element, info) { + var instruction = { attrName: info.attrName, attributes: {} }, + 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] = target; + } + + 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] = target; + } + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + } + }); - this.call = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; + return SyntaxInterpreter; + })(); - instruction.attributes[attrName] = new CallExpression(this.observerLocator, attrName, this.parser.parse(attrValue), resources.valueConverterLookupFunction); + exports.SyntaxInterpreter = SyntaxInterpreter; - return instruction; - }; - }; - SyntaxInterpreter.inject = function () { - return [Parser, ObserverLocator, EventManager]; - }; + SyntaxInterpreter.prototype["for"] = function (resources, element, info, existingInstruction) { + var parts = info.attrValue.split(" of "); - SyntaxInterpreter.prototype.interpret = function (type, resources, element, attrName, attrValue, existingInstruction) { - if (type in this) { - return this[type](resources, element, attrName, attrValue, existingInstruction); + if (parts.length !== 2) { + throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); } - }; - SyntaxInterpreter.prototype.determineDefaultBindingMode = function (element, attrName) { - var tagName = element.tagName.toLowerCase(); + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (tagName === "input") { - return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; - } else if (tagName == "textarea" || tagName == "select") { - return attrName == "value" ? TWO_WAY : ONE_WAY; - } + instruction.attributes.local = parts[0]; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - return ONE_WAY; + return instruction; }; - SyntaxInterpreter.prototype.bind = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; + SyntaxInterpreter.prototype["two-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), this.determineDefaultBindingMode(element, attrName), resources.valueConverterLookupFunction); + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), TWO_WAY, resources.valueConverterLookupFunction); return instruction; }; - SyntaxInterpreter.prototype.trigger = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), false, true); - }; + SyntaxInterpreter.prototype["one-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - SyntaxInterpreter.prototype.delegate = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), true, true); - }; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_WAY, resources.valueConverterLookupFunction); - SyntaxInterpreter.prototype.ref = function (resources, element, attrName, attrValue) { - return new NameExpression(attrName, attrValue); + return instruction; }; - SyntaxInterpreter.prototype.options = function (resources, element, attrName, attrValue) { - var instruction = { attrName: attrName, attributes: {} }, language = this.language, name = null, target = "", current, i, ii; - - for (i = 0, ii = attrValue.length; i < ii; ++i) { - current = attrValue[i]; - - if (current === ";") { - language.parseAttribute(resources, element, name, target, instruction); - target = ""; - name = null; - } else if (current === ":" && name === null) { - name = target.trim(); - target = ""; - } else { - target += current; - } - } + SyntaxInterpreter.prototype["one-time"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (name !== null) { - language.parseAttribute(resources, element, name, target, instruction); - } + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_TIME, resources.valueConverterLookupFunction); return instruction; }; - exports.SyntaxInterpreter = SyntaxInterpreter; + SyntaxInterpreter.prototype["view-model"] = function (resources, element, info) { + return new NameExpression(info.attrValue, "view-model"); + }; }); \ No newline at end of file diff --git a/dist/commonjs/binding-language.js b/dist/commonjs/binding-language.js index 4892546..903a76f 100644 --- a/dist/commonjs/binding-language.js +++ b/dist/commonjs/binding-language.js @@ -1,5 +1,10 @@ "use strict"; +var _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -19,10 +24,14 @@ var BindingLanguage = require("aurelia-templating").BindingLanguage; var Parser = require("aurelia-binding").Parser; var ObserverLocator = require("aurelia-binding").ObserverLocator; var BindingExpression = require("aurelia-binding").BindingExpression; +var NameExpression = require("aurelia-binding").NameExpression; var ONE_WAY = require("aurelia-binding").ONE_WAY; var SyntaxInterpreter = require("./syntax-interpreter").SyntaxInterpreter; -var TemplatingBindingLanguage = (function () { - var _BindingLanguage = BindingLanguage; + + +var info = {}; + +var TemplatingBindingLanguage = (function (BindingLanguage) { var TemplatingBindingLanguage = function TemplatingBindingLanguage(parser, observerLocator, syntaxInterpreter) { this.parser = parser; this.observerLocator = observerLocator; @@ -31,62 +40,106 @@ var TemplatingBindingLanguage = (function () { syntaxInterpreter.language = this; }; - _inherits(TemplatingBindingLanguage, _BindingLanguage); - - TemplatingBindingLanguage.inject = function () { - return [Parser, ObserverLocator, SyntaxInterpreter]; - }; + _inherits(TemplatingBindingLanguage, BindingLanguage); - TemplatingBindingLanguage.prototype.parseAttribute = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrName.split("."), instruction; - - if (parts.length == 2) { - instruction = this.syntaxInterpreter.interpret(parts[1].trim(), resources, element, parts[0].trim(), attrValue, existingInstruction); - - if (!existingInstruction) { - instruction.originalAttrName = attrName; - } - } else { - var expression = this.parseContent(resources, attrName, attrValue); - if (expression) { - instruction = existingInstruction || { attrName: attrName, attributes: {} }; - instruction.attributes[attrName] = expression; - } + _prototypeProperties(TemplatingBindingLanguage, { + inject: { + value: function () { + return [Parser, ObserverLocator, SyntaxInterpreter]; + }, + writable: true, + enumerable: true, + configurable: true } + }, { + inspectAttribute: { + value: function (resources, attrName, attrValue) { + var parts = attrName.split("."); + + if (parts.length == 2) { + info.attrName = parts[0].trim(); + info.attrValue = attrValue; + info.command = parts[1].trim(); + 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; + }, + writable: true, + enumerable: true, + configurable: true + }, + createAttributeInstruction: { + value: function (resources, element, info, existingInstruction) { + var instruction; + + if (info.expression) { + if (info.attrName === "ref") { + return info.expression; + } + + instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + instruction.attributes[info.attrName] = info.expression; + } else if (info.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + parseText: { + value: function (resources, value) { + return this.parseContent(resources, "textContent", value); + }, + writable: true, + enumerable: true, + configurable: true + }, + parseContent: { + value: function (resources, attrName, attrValue) { + var expressionText, expression; - return instruction; - }; - - TemplatingBindingLanguage.prototype.parseText = function (resources, value) { - return this.parseContent(resources, "textContent", value); - }; - - TemplatingBindingLanguage.prototype.parseContent = function (resources, attrName, attrValue) { - var expressionText, expression; + var parts = attrValue.split(this.interpolationRegex); + if (parts.length <= 1) { + return null; + } - var parts = attrValue.split(this.interpolationRegex); - if (parts.length <= 1) { - return null; - } + parts.forEach(function (part, index) { + if (index % 2 === 0) { + parts[index] = "'" + part + "'"; + } else { + parts[index] = "(" + part + ")"; + } + }); - parts.forEach(function (part, index) { - if (index % 2 === 0) { - parts[index] = "'" + part + "'"; - } else { - parts[index] = "(" + part + ")"; - } - }); + expressionText = parts.join("+"); - expressionText = parts.join("+"); + expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); - expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); + expression.attribute = attrName; - expression.attribute = attrName; - - return expression; - }; + return expression; + }, + writable: true, + enumerable: true, + configurable: true + } + }); return TemplatingBindingLanguage; -})(); +})(BindingLanguage); exports.TemplatingBindingLanguage = TemplatingBindingLanguage; \ No newline at end of file diff --git a/dist/commonjs/syntax-interpreter.js b/dist/commonjs/syntax-interpreter.js index 185f6a4..02e34fb 100644 --- a/dist/commonjs/syntax-interpreter.js +++ b/dist/commonjs/syntax-interpreter.js @@ -1,5 +1,10 @@ "use strict"; +var _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); +}; + var Parser = require("aurelia-binding").Parser; var ObserverLocator = require("aurelia-binding").ObserverLocator; var EventManager = require("aurelia-binding").EventManager; @@ -10,124 +15,193 @@ var CallExpression = require("aurelia-binding").CallExpression; var ONE_WAY = require("aurelia-binding").ONE_WAY; var TWO_WAY = require("aurelia-binding").TWO_WAY; var ONE_TIME = require("aurelia-binding").ONE_TIME; -var SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { - this.parser = parser; - this.observerLocator = observerLocator; - this.eventManager = eventManager; - - this["for"] = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrValue.split(" of "); - - if (parts.length !== 2) { - throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); - } - - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes.local = parts[0]; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; +var SyntaxInterpreter = (function () { + var SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { + this.parser = parser; + this.observerLocator = observerLocator; + this.eventManager = eventManager; }; - this["two-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), TWO_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["one-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["one-time"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_TIME, resources.valueConverterLookupFunction); - - return instruction; - }; + _prototypeProperties(SyntaxInterpreter, { + inject: { + value: function () { + return [Parser, ObserverLocator, EventManager]; + }, + writable: true, + enumerable: true, + configurable: true + } + }, { + interpret: { + value: function (resources, element, info, existingInstruction) { + if (info.command in this) { + return this[info.command](resources, element, info, existingInstruction); + } + + return this.handleUnknownCommand(resources, element, info, existingInstruction); + }, + writable: true, + enumerable: true, + configurable: true + }, + handleUnknownCommand: { + value: function (resources, element, info, existingInstruction) { + throw new Error("Unknown binding command ${info.command} used."); + }, + writable: true, + enumerable: true, + configurable: true + }, + determineDefaultBindingMode: { + value: function (element, attrName) { + var tagName = element.tagName.toLowerCase(); + + if (tagName === "input") { + return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; + } else if (tagName == "textarea" || tagName == "select") { + return attrName == "value" ? TWO_WAY : ONE_WAY; + } + + return ONE_WAY; + }, + writable: true, + enumerable: true, + configurable: true + }, + bind: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), this.determineDefaultBindingMode(element, info.attrName), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + trigger: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), false, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + delegate: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), true, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + call: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new CallExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + options: { + value: function (resources, element, info) { + var instruction = { attrName: info.attrName, attributes: {} }, + 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] = target; + } + + 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] = target; + } + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + } + }); - this.call = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; + return SyntaxInterpreter; +})(); - instruction.attributes[attrName] = new CallExpression(this.observerLocator, attrName, this.parser.parse(attrValue), resources.valueConverterLookupFunction); +exports.SyntaxInterpreter = SyntaxInterpreter; - return instruction; - }; -}; -SyntaxInterpreter.inject = function () { - return [Parser, ObserverLocator, EventManager]; -}; +SyntaxInterpreter.prototype["for"] = function (resources, element, info, existingInstruction) { + var parts = info.attrValue.split(" of "); -SyntaxInterpreter.prototype.interpret = function (type, resources, element, attrName, attrValue, existingInstruction) { - if (type in this) { - return this[type](resources, element, attrName, attrValue, existingInstruction); + if (parts.length !== 2) { + throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); } -}; -SyntaxInterpreter.prototype.determineDefaultBindingMode = function (element, attrName) { - var tagName = element.tagName.toLowerCase(); + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (tagName === "input") { - return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; - } else if (tagName == "textarea" || tagName == "select") { - return attrName == "value" ? TWO_WAY : ONE_WAY; - } + instruction.attributes.local = parts[0]; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - return ONE_WAY; + return instruction; }; -SyntaxInterpreter.prototype.bind = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; +SyntaxInterpreter.prototype["two-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), this.determineDefaultBindingMode(element, attrName), resources.valueConverterLookupFunction); + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), TWO_WAY, resources.valueConverterLookupFunction); return instruction; }; -SyntaxInterpreter.prototype.trigger = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), false, true); -}; +SyntaxInterpreter.prototype["one-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; -SyntaxInterpreter.prototype.delegate = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), true, true); -}; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_WAY, resources.valueConverterLookupFunction); -SyntaxInterpreter.prototype.ref = function (resources, element, attrName, attrValue) { - return new NameExpression(attrName, attrValue); + return instruction; }; -SyntaxInterpreter.prototype.options = function (resources, element, attrName, attrValue) { - var instruction = { attrName: attrName, attributes: {} }, language = this.language, name = null, target = "", current, i, ii; - - for (i = 0, ii = attrValue.length; i < ii; ++i) { - current = attrValue[i]; - - if (current === ";") { - language.parseAttribute(resources, element, name, target, instruction); - target = ""; - name = null; - } else if (current === ":" && name === null) { - name = target.trim(); - target = ""; - } else { - target += current; - } - } +SyntaxInterpreter.prototype["one-time"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (name !== null) { - language.parseAttribute(resources, element, name, target, instruction); - } + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_TIME, resources.valueConverterLookupFunction); return instruction; }; -exports.SyntaxInterpreter = SyntaxInterpreter; \ No newline at end of file +SyntaxInterpreter.prototype["view-model"] = function (resources, element, info) { + return new NameExpression(info.attrValue, "view-model"); +}; \ No newline at end of file diff --git a/dist/es6/binding-language.js b/dist/es6/binding-language.js index d03a5e5..7419846 100644 --- a/dist/es6/binding-language.js +++ b/dist/es6/binding-language.js @@ -1,7 +1,9 @@ import {BindingLanguage} from 'aurelia-templating'; -import {Parser, ObserverLocator, BindingExpression, ONE_WAY} from 'aurelia-binding'; +import {Parser, ObserverLocator, BindingExpression, NameExpression, ONE_WAY} from 'aurelia-binding'; import {SyntaxInterpreter} from './syntax-interpreter'; +var info = {}; + export class TemplatingBindingLanguage extends BindingLanguage { static inject() { return [Parser, ObserverLocator,SyntaxInterpreter]; } constructor(parser, observerLocator, syntaxInterpreter){ @@ -12,30 +14,47 @@ export class TemplatingBindingLanguage extends BindingLanguage { syntaxInterpreter.language = this; } - parseAttribute(resources, element, attrName, attrValue, existingInstruction){ - var parts = attrName.split('.'), - instruction; - - if(parts.length == 2){ - instruction = this.syntaxInterpreter.interpret( - parts[1].trim(), - resources, - element, - parts[0].trim(), - attrValue, - existingInstruction - ); + inspectAttribute(resources, attrName, attrValue){ + var parts = attrName.split('.'); + + if(parts.length == 2){ + info.attrName = parts[0].trim(); + info.attrValue = attrValue; + info.command = parts[1].trim(); + 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(!existingInstruction){ - instruction.originalAttrName = attrName; + if(info.expression){ + if(info.attrName === 'ref'){ + return info.expression; } - } else { - var expression = this.parseContent(resources, attrName, attrValue); - if(expression){ - instruction = existingInstruction || {attrName:attrName, attributes:{}}; - instruction.attributes[attrName] = expression; - } - } + + instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + instruction.attributes[info.attrName] = info.expression; + } else if(info.command){ + instruction = this.syntaxInterpreter.interpret( + resources, + element, + info, + existingInstruction + ); + } return instruction; } diff --git a/dist/es6/syntax-interpreter.js b/dist/es6/syntax-interpreter.js index 4229090..9e35ce8 100644 --- a/dist/es6/syntax-interpreter.js +++ b/dist/es6/syntax-interpreter.js @@ -1,180 +1,198 @@ import { - Parser, - ObserverLocator, - EventManager, - ListenerExpression, - BindingExpression, - NameExpression, + Parser, + ObserverLocator, + EventManager, + ListenerExpression, + BindingExpression, + NameExpression, CallExpression, - ONE_WAY, - TWO_WAY, - ONE_TIME + ONE_WAY, + TWO_WAY, + ONE_TIME } from 'aurelia-binding'; export class SyntaxInterpreter { static inject() { return [Parser,ObserverLocator,EventManager]; } - constructor(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); + } - this['for'] = function(resources, element, attrName, attrValue, existingInstruction){ - var parts = attrValue.split(' of '); - - if(parts.length !== 2){ - throw new Error('Incorrect syntax for "for". The form is: "$local of $items".'); - } - - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; - - instruction.attributes.local = parts[0]; - instruction.attributes[attrName] = new BindingExpression( - this.observerLocator, - attrName, - this.parser.parse(parts[1]), - ONE_WAY, - resources.valueConverterLookupFunction - ); - - return instruction; - }; - - this['two-way'] = function(resources, element, attrName, attrValue, existingInstruction){ - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; - - instruction.attributes[attrName] = new BindingExpression( - this.observerLocator, - attrName, - this.parser.parse(attrValue), - TWO_WAY, - resources.valueConverterLookupFunction - ); - - return instruction; - }; - - this['one-way'] = function(resources, element, attrName, attrValue, existingInstruction){ - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; - - instruction.attributes[attrName] = new BindingExpression( - this.observerLocator, - attrName === 'class' ? 'className' : attrName, - this.parser.parse(attrValue), - ONE_WAY, - resources.valueConverterLookupFunction - ); - - return instruction; - }; - - this['one-time'] = function(resources, element, attrName, attrValue, existingInstruction){ - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; - - instruction.attributes[attrName] = new BindingExpression( - this.observerLocator, - attrName === 'class' ? 'className' : attrName, - this.parser.parse(attrValue), - ONE_TIME, - resources.valueConverterLookupFunction - ); - - return instruction; - }; - - this['call'] = function(resources, element, attrName, attrValue, existingInstruction){ - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; - - instruction.attributes[attrName] = new CallExpression( - this.observerLocator, - attrName, - this.parser.parse(attrValue), - resources.valueConverterLookupFunction - ); - - return instruction; - }; + return this.handleUnknownCommand(resources, element, info, existingInstruction); } - interpret(type, resources, element, attrName, attrValue, existingInstruction){ - if(type in this){ - return this[type](resources, element, attrName, attrValue, existingInstruction); - } + handleUnknownCommand(resources, element, info, existingInstruction){ + throw new Error("Unknown binding command ${info.command} used."); } determineDefaultBindingMode(element, attrName){ - var tagName = element.tagName.toLowerCase(); + var tagName = element.tagName.toLowerCase(); - if(tagName === 'input'){ - return attrName === 'value' || attrName === 'checked' ? TWO_WAY : ONE_WAY; - }else if(tagName == 'textarea' || tagName == 'select'){ - return attrName == 'value' ? TWO_WAY : ONE_WAY; - } + if(tagName === 'input'){ + return attrName === 'value' || attrName === 'checked' ? TWO_WAY : ONE_WAY; + }else if(tagName == 'textarea' || tagName == 'select'){ + return attrName == 'value' ? TWO_WAY : ONE_WAY; + } - return ONE_WAY; + return ONE_WAY; } - bind(resources, element, attrName, attrValue, existingInstruction){ - var instruction = existingInstruction || {attrName:attrName, attributes:{}}; + bind(resources, element, info, existingInstruction){ + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; - instruction.attributes[attrName] = new BindingExpression( - this.observerLocator, - attrName, - this.parser.parse(attrValue), - this.determineDefaultBindingMode(element, attrName), - resources.valueConverterLookupFunction - ); + instruction.attributes[info.attrName] = new BindingExpression( + this.observerLocator, + info.attrName, + this.parser.parse(info.attrValue), + this.determineDefaultBindingMode(element, info.attrName), + resources.valueConverterLookupFunction + ); - return instruction; - } + return instruction; + } - trigger(resources, element, attrName, attrValue){ - return new ListenerExpression( + trigger(resources, element, info){ + return new ListenerExpression( this.eventManager, - attrName, - this.parser.parse(attrValue), + info.attrName, + this.parser.parse(info.attrValue), false, true ); - } + } - delegate(resources, element, attrName, attrValue){ - return new ListenerExpression( + delegate(resources, element, info){ + return new ListenerExpression( this.eventManager, - attrName, - this.parser.parse(attrValue), + info.attrName, + this.parser.parse(info.attrValue), true, true ); - } - - ref(resources, element, attrName, attrValue){ - return new NameExpression(attrName, attrValue); - } - - options(resources, element, attrName, attrValue){ - var instruction = {attrName:attrName, attributes:{}}, - language = this.language, - name = null, target = '', current, i , ii; - - for(i = 0, ii = attrValue.length; i < ii; ++i){ - current = attrValue[i]; - - if(current === ';'){ - language.parseAttribute(resources, element, name, target, instruction); - target = ''; - name = null; - } else if(current === ':' && name === null){ - name = target.trim(); - target = ''; - } else { - target += current; - } - } - - if(name !== null){ - language.parseAttribute(resources, element, name, target, instruction); - } - - return instruction; - } -} \ No newline at end of file + } + + call(resources, element, info, existingInstruction){ + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + + instruction.attributes[info.attrName] = new CallExpression( + this.observerLocator, + info.attrName, + this.parser.parse(info.attrValue), + resources.valueConverterLookupFunction + ); + + return instruction; + }; + + options(resources, element, info){ + var instruction = {attrName:info.attrName, attributes:{}}, + 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] = target; + } + + 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] = target; + } + } + + return instruction; + } +} + +SyntaxInterpreter.prototype['for'] = function(resources, element, info, existingInstruction){ + var parts = info.attrValue.split(' of '); + + if(parts.length !== 2){ + throw new Error('Incorrect syntax for "for". The form is: "$local of $items".'); + } + + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + + instruction.attributes.local = parts[0]; + instruction.attributes[info.attrName] = new BindingExpression( + this.observerLocator, + info.attrName, + this.parser.parse(parts[1]), + ONE_WAY, + resources.valueConverterLookupFunction + ); + + return instruction; +}; + +SyntaxInterpreter.prototype['two-way'] = function(resources, element, info, existingInstruction){ + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + + instruction.attributes[info.attrName] = new BindingExpression( + this.observerLocator, + info.attrName, + this.parser.parse(info.attrValue), + TWO_WAY, + resources.valueConverterLookupFunction + ); + + return instruction; +}; + +SyntaxInterpreter.prototype['one-way'] = function(resources, element, info, existingInstruction){ + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + + instruction.attributes[info.attrName] = new BindingExpression( + this.observerLocator, + info.attrName === 'class' ? 'className' : info.attrName, + this.parser.parse(info.attrValue), + ONE_WAY, + resources.valueConverterLookupFunction + ); + + return instruction; +}; + +SyntaxInterpreter.prototype['one-time'] = function(resources, element, info, existingInstruction){ + var instruction = existingInstruction || {attrName:info.attrName, attributes:{}}; + + instruction.attributes[info.attrName] = new BindingExpression( + this.observerLocator, + info.attrName === 'class' ? 'className' : info.attrName, + this.parser.parse(info.attrValue), + ONE_TIME, + resources.valueConverterLookupFunction + ); + + return instruction; +}; + +SyntaxInterpreter.prototype["view-model"] = function (resources, element, info) { + return new NameExpression(info.attrValue, 'view-model'); +}; \ No newline at end of file diff --git a/dist/system/binding-language.js b/dist/system/binding-language.js index ef8a6fc..1f38778 100644 --- a/dist/system/binding-language.js +++ b/dist/system/binding-language.js @@ -1,7 +1,7 @@ System.register(["aurelia-templating", "aurelia-binding", "./syntax-interpreter"], function (_export) { "use strict"; - var BindingLanguage, Parser, ObserverLocator, BindingExpression, ONE_WAY, SyntaxInterpreter, _inherits, TemplatingBindingLanguage; + var BindingLanguage, Parser, ObserverLocator, BindingExpression, NameExpression, ONE_WAY, SyntaxInterpreter, _prototypeProperties, _inherits, info, TemplatingBindingLanguage; return { setters: [function (_aureliaTemplating) { BindingLanguage = _aureliaTemplating.BindingLanguage; @@ -9,11 +9,17 @@ System.register(["aurelia-templating", "aurelia-binding", "./syntax-interpreter" Parser = _aureliaBinding.Parser; ObserverLocator = _aureliaBinding.ObserverLocator; BindingExpression = _aureliaBinding.BindingExpression; + NameExpression = _aureliaBinding.NameExpression; ONE_WAY = _aureliaBinding.ONE_WAY; }, function (_syntaxInterpreter) { SyntaxInterpreter = _syntaxInterpreter.SyntaxInterpreter; }], execute: function () { + _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); + }; + _inherits = function (child, parent) { if (typeof parent !== "function" && parent !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof parent); @@ -29,8 +35,8 @@ System.register(["aurelia-templating", "aurelia-binding", "./syntax-interpreter" if (parent) child.__proto__ = parent; }; - TemplatingBindingLanguage = (function () { - var _BindingLanguage = BindingLanguage; + info = {}; + TemplatingBindingLanguage = (function (BindingLanguage) { var TemplatingBindingLanguage = function TemplatingBindingLanguage(parser, observerLocator, syntaxInterpreter) { this.parser = parser; this.observerLocator = observerLocator; @@ -39,63 +45,107 @@ System.register(["aurelia-templating", "aurelia-binding", "./syntax-interpreter" syntaxInterpreter.language = this; }; - _inherits(TemplatingBindingLanguage, _BindingLanguage); - - TemplatingBindingLanguage.inject = function () { - return [Parser, ObserverLocator, SyntaxInterpreter]; - }; + _inherits(TemplatingBindingLanguage, BindingLanguage); - TemplatingBindingLanguage.prototype.parseAttribute = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrName.split("."), instruction; - - if (parts.length == 2) { - instruction = this.syntaxInterpreter.interpret(parts[1].trim(), resources, element, parts[0].trim(), attrValue, existingInstruction); - - if (!existingInstruction) { - instruction.originalAttrName = attrName; - } - } else { - var expression = this.parseContent(resources, attrName, attrValue); - if (expression) { - instruction = existingInstruction || { attrName: attrName, attributes: {} }; - instruction.attributes[attrName] = expression; - } + _prototypeProperties(TemplatingBindingLanguage, { + inject: { + value: function () { + return [Parser, ObserverLocator, SyntaxInterpreter]; + }, + writable: true, + enumerable: true, + configurable: true } + }, { + inspectAttribute: { + value: function (resources, attrName, attrValue) { + var parts = attrName.split("."); + + if (parts.length == 2) { + info.attrName = parts[0].trim(); + info.attrValue = attrValue; + info.command = parts[1].trim(); + 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; + }, + writable: true, + enumerable: true, + configurable: true + }, + createAttributeInstruction: { + value: function (resources, element, info, existingInstruction) { + var instruction; + + if (info.expression) { + if (info.attrName === "ref") { + return info.expression; + } + + instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + instruction.attributes[info.attrName] = info.expression; + } else if (info.command) { + instruction = this.syntaxInterpreter.interpret(resources, element, info, existingInstruction); + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + parseText: { + value: function (resources, value) { + return this.parseContent(resources, "textContent", value); + }, + writable: true, + enumerable: true, + configurable: true + }, + parseContent: { + value: function (resources, attrName, attrValue) { + var expressionText, expression; - return instruction; - }; - - TemplatingBindingLanguage.prototype.parseText = function (resources, value) { - return this.parseContent(resources, "textContent", value); - }; - - TemplatingBindingLanguage.prototype.parseContent = function (resources, attrName, attrValue) { - var expressionText, expression; - - var parts = attrValue.split(this.interpolationRegex); - if (parts.length <= 1) { - return null; - } + var parts = attrValue.split(this.interpolationRegex); + if (parts.length <= 1) { + return null; + } - parts.forEach(function (part, index) { - if (index % 2 === 0) { - parts[index] = "'" + part + "'"; - } else { - parts[index] = "(" + part + ")"; - } - }); + parts.forEach(function (part, index) { + if (index % 2 === 0) { + parts[index] = "'" + part + "'"; + } else { + parts[index] = "(" + part + ")"; + } + }); - expressionText = parts.join("+"); + expressionText = parts.join("+"); - expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); + expression = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(expressionText), ONE_WAY, resources.valueConverterLookupFunction); - expression.attribute = attrName; + expression.attribute = attrName; - return expression; - }; + return expression; + }, + writable: true, + enumerable: true, + configurable: true + } + }); return TemplatingBindingLanguage; - })(); + })(BindingLanguage); _export("TemplatingBindingLanguage", TemplatingBindingLanguage); } }; diff --git a/dist/system/syntax-interpreter.js b/dist/system/syntax-interpreter.js index ebe3bc1..6b581d2 100644 --- a/dist/system/syntax-interpreter.js +++ b/dist/system/syntax-interpreter.js @@ -1,7 +1,7 @@ System.register(["aurelia-binding"], function (_export) { "use strict"; - var Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, ONE_WAY, TWO_WAY, ONE_TIME, SyntaxInterpreter; + var Parser, ObserverLocator, EventManager, ListenerExpression, BindingExpression, NameExpression, CallExpression, ONE_WAY, TWO_WAY, ONE_TIME, _prototypeProperties, SyntaxInterpreter; return { setters: [function (_aureliaBinding) { Parser = _aureliaBinding.Parser; @@ -16,127 +16,199 @@ System.register(["aurelia-binding"], function (_export) { ONE_TIME = _aureliaBinding.ONE_TIME; }], execute: function () { - SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { - this.parser = parser; - this.observerLocator = observerLocator; - this.eventManager = eventManager; - - this["for"] = function (resources, element, attrName, attrValue, existingInstruction) { - var parts = attrValue.split(" of "); - - if (parts.length !== 2) { - throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); - } - - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes.local = parts[0]; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["two-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), TWO_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["one-way"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_WAY, resources.valueConverterLookupFunction); - - return instruction; - }; - - this["one-time"] = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName === "class" ? "className" : attrName, this.parser.parse(attrValue), ONE_TIME, resources.valueConverterLookupFunction); + _prototypeProperties = function (child, staticProps, instanceProps) { + if (staticProps) Object.defineProperties(child, staticProps); + if (instanceProps) Object.defineProperties(child.prototype, instanceProps); + }; - return instruction; + SyntaxInterpreter = (function () { + var SyntaxInterpreter = function SyntaxInterpreter(parser, observerLocator, eventManager) { + this.parser = parser; + this.observerLocator = observerLocator; + this.eventManager = eventManager; }; - this.call = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; - - instruction.attributes[attrName] = new CallExpression(this.observerLocator, attrName, this.parser.parse(attrValue), resources.valueConverterLookupFunction); + _prototypeProperties(SyntaxInterpreter, { + inject: { + value: function () { + return [Parser, ObserverLocator, EventManager]; + }, + writable: true, + enumerable: true, + configurable: true + } + }, { + interpret: { + value: function (resources, element, info, existingInstruction) { + if (info.command in this) { + return this[info.command](resources, element, info, existingInstruction); + } + + return this.handleUnknownCommand(resources, element, info, existingInstruction); + }, + writable: true, + enumerable: true, + configurable: true + }, + handleUnknownCommand: { + value: function (resources, element, info, existingInstruction) { + throw new Error("Unknown binding command ${info.command} used."); + }, + writable: true, + enumerable: true, + configurable: true + }, + determineDefaultBindingMode: { + value: function (element, attrName) { + var tagName = element.tagName.toLowerCase(); + + if (tagName === "input") { + return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; + } else if (tagName == "textarea" || tagName == "select") { + return attrName == "value" ? TWO_WAY : ONE_WAY; + } + + return ONE_WAY; + }, + writable: true, + enumerable: true, + configurable: true + }, + bind: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), this.determineDefaultBindingMode(element, info.attrName), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + trigger: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), false, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + delegate: { + value: function (resources, element, info) { + return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), true, true); + }, + writable: true, + enumerable: true, + configurable: true + }, + call: { + value: function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; + + instruction.attributes[info.attrName] = new CallExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), resources.valueConverterLookupFunction); + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + }, + options: { + value: function (resources, element, info) { + var instruction = { attrName: info.attrName, attributes: {} }, + 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] = target; + } + + 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] = target; + } + } + + return instruction; + }, + writable: true, + enumerable: true, + configurable: true + } + }); - return instruction; - }; - }; + return SyntaxInterpreter; + })(); + _export("SyntaxInterpreter", SyntaxInterpreter); - SyntaxInterpreter.inject = function () { - return [Parser, ObserverLocator, EventManager]; - }; + SyntaxInterpreter.prototype["for"] = function (resources, element, info, existingInstruction) { + var parts = info.attrValue.split(" of "); - SyntaxInterpreter.prototype.interpret = function (type, resources, element, attrName, attrValue, existingInstruction) { - if (type in this) { - return this[type](resources, element, attrName, attrValue, existingInstruction); + if (parts.length !== 2) { + throw new Error("Incorrect syntax for \"for\". The form is: \"$local of $items\"."); } - }; - SyntaxInterpreter.prototype.determineDefaultBindingMode = function (element, attrName) { - var tagName = element.tagName.toLowerCase(); + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (tagName === "input") { - return attrName === "value" || attrName === "checked" ? TWO_WAY : ONE_WAY; - } else if (tagName == "textarea" || tagName == "select") { - return attrName == "value" ? TWO_WAY : ONE_WAY; - } + instruction.attributes.local = parts[0]; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(parts[1]), ONE_WAY, resources.valueConverterLookupFunction); - return ONE_WAY; + return instruction; }; - SyntaxInterpreter.prototype.bind = function (resources, element, attrName, attrValue, existingInstruction) { - var instruction = existingInstruction || { attrName: attrName, attributes: {} }; + SyntaxInterpreter.prototype["two-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - instruction.attributes[attrName] = new BindingExpression(this.observerLocator, attrName, this.parser.parse(attrValue), this.determineDefaultBindingMode(element, attrName), resources.valueConverterLookupFunction); + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), TWO_WAY, resources.valueConverterLookupFunction); return instruction; }; - SyntaxInterpreter.prototype.trigger = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), false, true); - }; + SyntaxInterpreter.prototype["one-way"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - SyntaxInterpreter.prototype.delegate = function (resources, element, attrName, attrValue) { - return new ListenerExpression(this.eventManager, attrName, this.parser.parse(attrValue), true, true); - }; + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_WAY, resources.valueConverterLookupFunction); - SyntaxInterpreter.prototype.ref = function (resources, element, attrName, attrValue) { - return new NameExpression(attrName, attrValue); + return instruction; }; - SyntaxInterpreter.prototype.options = function (resources, element, attrName, attrValue) { - var instruction = { attrName: attrName, attributes: {} }, language = this.language, name = null, target = "", current, i, ii; - - for (i = 0, ii = attrValue.length; i < ii; ++i) { - current = attrValue[i]; - - if (current === ";") { - language.parseAttribute(resources, element, name, target, instruction); - target = ""; - name = null; - } else if (current === ":" && name === null) { - name = target.trim(); - target = ""; - } else { - target += current; - } - } + SyntaxInterpreter.prototype["one-time"] = function (resources, element, info, existingInstruction) { + var instruction = existingInstruction || { attrName: info.attrName, attributes: {} }; - if (name !== null) { - language.parseAttribute(resources, element, name, target, instruction); - } + instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, info.attrName === "class" ? "className" : info.attrName, this.parser.parse(info.attrValue), ONE_TIME, resources.valueConverterLookupFunction); return instruction; }; - _export("SyntaxInterpreter", SyntaxInterpreter); + SyntaxInterpreter.prototype["view-model"] = function (resources, element, info) { + return new NameExpression(info.attrValue, "view-model"); + }; } }; }); \ No newline at end of file diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 853557c..f29e4bc 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.7.0 (2015-01-12) + + +#### Bug Fixes + +* **all:** typos in binding language and options syntax ([17f91fe0](http://github.com/aurelia/templating-binding/commit/17f91fe0860c5bbf6aeb4a9a970139cf6be3b4b0)) +* **package:** update Aurelia dependencies ([b07b1f85](http://github.com/aurelia/templating-binding/commit/b07b1f850309dfbc6ca556a2c57449cf46ee6c0f)) +* **syntax-interpreter:** handle non bound options values ([c13d9dd9](http://github.com/aurelia/templating-binding/commit/c13d9dd92f594510e1585a0afd98178a8fa0e739)) + + +#### Features + +* **binding-language:** + * new binding language interface ([4fae8ad8](http://github.com/aurelia/templating-binding/commit/4fae8ad893d1e3e3a6ea43e9aa9b2d2ea2e944f4)) + * new syntax for element refs ([a24d5967](http://github.com/aurelia/templating-binding/commit/a24d5967c95e6a322980817dee6a7eae4defc3a3)) + + ## 0.6.0 (2015-01-07) diff --git a/package.json b/package.json index 89f8f77..73e5c4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aurelia-templating-binding", - "version": "0.6.0", + "version": "0.7.0", "description": "An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.", "keywords": [ "aurelia",