feat: camelCase Angular (kebab-case removal)

BREAKING CHANGE:

Angular is now fully camel case.

Before:

    <p *ng-if="cond">
    <my-cmp [my-prop]="exp">
    <my-cmp (my-event)="action()">
    <my-cmp [(my-prop)]="prop">
    <input #my-input>
    <template ng-for #my-item [ng-for-of]=items #my-index="index">

After

    <p *ngIf="cond">
    <my-cmp [myProp]="exp">
    <my-cmp (myEvent)="action()">
    <my-cmp [(myProp)]="prop">
    <input #myInput>`,
    <template ngFor="#my-item" [ngForOf]=items #myIndex="index">

The full details are found in [angular2/docs/migration/kebab-case.md](https://github.com/angular/angular/blob/master/modules/angular2/docs/migration/kebab-case.md)
This commit is contained in:
Victor Berchet
2015-11-23 16:02:19 -08:00
committed by Igor Minar
parent b386d1134a
commit da9b46a071
120 changed files with 759 additions and 802 deletions

View File

@ -200,7 +200,7 @@ class TreeBuilder {
private _popElement(fullName: string): boolean {
for (let stackIndex = this.elementStack.length - 1; stackIndex >= 0; stackIndex--) {
let el = this.elementStack[stackIndex];
if (el.name.toLowerCase() == fullName.toLowerCase()) {
if (el.name == fullName) {
ListWrapper.splice(this.elementStack, stackIndex, this.elementStack.length - stackIndex);
return true;
}

View File

@ -84,12 +84,7 @@ export class CssSelector {
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
}
setElement(element: string = null) {
if (isPresent(element)) {
element = element.toLowerCase();
}
this.element = element;
}
setElement(element: string = null) { this.element = element; }
/** Gets a template string for an element that matches the selector. */
getMatchingElementTemplate(): string {
@ -107,7 +102,7 @@ export class CssSelector {
}
addAttribute(name: string, value: string = _EMPTY_ATTR_VALUE) {
this.attrs.push(name.toLowerCase());
this.attrs.push(name);
if (isPresent(value)) {
value = value.toLowerCase();
} else {

View File

@ -44,7 +44,7 @@ import {
htmlVisitAll
} from './html_ast';
import {dashCaseToCamelCase, camelCaseToDashCase, splitAtColon} from './util';
import {splitAtColon} from './util';
// Group 1 = "bind-"
// Group 2 = "var-" or "#"
@ -55,7 +55,7 @@ import {dashCaseToCamelCase, camelCaseToDashCase, splitAtColon} from './util';
// Group 7 = idenitifer inside []
// Group 8 = identifier inside ()
var BIND_NAME_REGEXP =
/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/ig;
/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g;
const TEMPLATE_ELEMENT = 'template';
const TEMPLATE_ATTR = 'template';
@ -270,7 +270,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
targetProps: BoundElementOrDirectiveProperty[],
targetVars: VariableAst[]): boolean {
var templateBindingsSource = null;
if (attr.name.toLowerCase() == TEMPLATE_ATTR) {
if (attr.name == TEMPLATE_ATTR) {
templateBindingsSource = attr.value;
} else if (attr.name.startsWith(TEMPLATE_ATTR_PREFIX)) {
var key = attr.name.substring(TEMPLATE_ATTR_PREFIX.length); // remove the star
@ -280,17 +280,15 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var bindings = this._parseTemplateBindings(templateBindingsSource, attr.sourceSpan);
for (var i = 0; i < bindings.length; i++) {
var binding = bindings[i];
var dashCaseKey = camelCaseToDashCase(binding.key);
if (binding.keyIsVar) {
targetVars.push(
new VariableAst(dashCaseToCamelCase(binding.key), binding.name, attr.sourceSpan));
targetMatchableAttrs.push([dashCaseKey, binding.name]);
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
targetMatchableAttrs.push([binding.key, binding.name]);
} else if (isPresent(binding.expression)) {
this._parsePropertyAst(dashCaseKey, binding.expression, attr.sourceSpan,
this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan,
targetMatchableAttrs, targetProps);
} else {
targetMatchableAttrs.push([dashCaseKey, '']);
this._parseLiteralAttr(dashCaseKey, null, attr.sourceSpan, targetProps);
targetMatchableAttrs.push([binding.key, '']);
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
}
}
return true;
@ -356,7 +354,10 @@ class TemplateParseVisitor implements HtmlAstVisitor {
private _parseVariable(identifier: string, value: string, sourceSpan: ParseSourceSpan,
targetVars: VariableAst[]) {
targetVars.push(new VariableAst(dashCaseToCamelCase(identifier), value, sourceSpan));
if (identifier.indexOf('-') > -1) {
this._reportError(`"-" is not allowed in variable names`, sourceSpan);
}
targetVars.push(new VariableAst(identifier, value, sourceSpan));
}
private _parseProperty(name: string, expression: string, sourceSpan: ParseSourceSpan,
@ -386,7 +387,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
private _parseAssignmentEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
this._parseEvent(`${name}-change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs,
this._parseEvent(`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs,
targetEvents);
}
@ -396,7 +397,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var parts = splitAtColon(name, [null, name]);
var target = parts[0];
var eventName = parts[1];
targetEvents.push(new BoundEventAst(dashCaseToCamelCase(eventName), target,
targetEvents.push(new BoundEventAst(eventName, target,
this._parseAction(expression, sourceSpan), sourceSpan));
// Don't detect directives for event names for now,
// so don't add the event name to the matchableAttrs
@ -405,8 +406,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
private _parseLiteralAttr(name: string, value: string, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) {
targetProps.push(new BoundElementOrDirectiveProperty(
dashCaseToCamelCase(name), this._exprParser.wrapLiteralPrimitive(value, ''), true,
sourceSpan));
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
}
private _parseDirectives(selectorMatcher: SelectorMatcher,
@ -493,16 +493,14 @@ class TemplateParseVisitor implements HtmlAstVisitor {
if (isPresent(directiveProperties)) {
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
boundProps.forEach(boundProp => {
var key = dashCaseToCamelCase(boundProp.name);
var prevValue = boundPropsByName.get(boundProp.name);
if (isBlank(prevValue) || prevValue.isLiteral) {
// give [a]="b" a higher precedence thatn a="b" on the same element
boundPropsByName.set(key, boundProp);
// give [a]="b" a higher precedence than a="b" on the same element
boundPropsByName.set(boundProp.name, boundProp);
}
});
StringMapWrapper.forEach(directiveProperties, (elProp: string, dirProp: string) => {
elProp = dashCaseToCamelCase(elProp);
var boundProp = boundPropsByName.get(elProp);
// Bindings are optional, so this binding only needs to be set up if an expression is given.
@ -539,7 +537,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var boundPropertyName;
var parts = name.split(PROPERTY_PARTS_SEPARATOR);
if (parts.length === 1) {
boundPropertyName = this._schemaRegistry.getMappedPropName(dashCaseToCamelCase(parts[0]));
boundPropertyName = this._schemaRegistry.getMappedPropName(parts[0]);
bindingType = PropertyBindingType.Property;
if (!this._schemaRegistry.hasProperty(elementName, boundPropertyName)) {
this._reportError(
@ -547,20 +545,18 @@ class TemplateParseVisitor implements HtmlAstVisitor {
sourceSpan);
}
} else {
let lcPrefix = parts[0].toLowerCase();
if (lcPrefix == ATTRIBUTE_PREFIX) {
boundPropertyName = dashCaseToCamelCase(parts[1]);
if (parts[0] == ATTRIBUTE_PREFIX) {
boundPropertyName = parts[1];
bindingType = PropertyBindingType.Attribute;
} else if (lcPrefix == CLASS_PREFIX) {
// keep original case!
} else if (parts[0] == CLASS_PREFIX) {
boundPropertyName = parts[1];
bindingType = PropertyBindingType.Class;
} else if (lcPrefix == STYLE_PREFIX) {
} else if (parts[0] == STYLE_PREFIX) {
unit = parts.length > 2 ? parts[2] : null;
boundPropertyName = dashCaseToCamelCase(parts[1]);
boundPropertyName = parts[1];
bindingType = PropertyBindingType.Style;
} else {
this._reportError(`Invalid property name ${name}`, sourceSpan);
this._reportError(`Invalid property name '${name}'`, sourceSpan);
bindingType = null;
}
}
@ -694,7 +690,7 @@ function createElementCssSelector(elementName: string, matchableAttrs: string[][
cssSelector.setElement(elementName);
for (var i = 0; i < matchableAttrs.length; i++) {
var attrName = matchableAttrs[i][0].toLowerCase();
var attrName = matchableAttrs[i][0];
var attrValue = matchableAttrs[i][1];
cssSelector.addAttribute(attrName, attrValue);
if (attrName == CLASS_ATTR) {

View File

@ -9,7 +9,7 @@ const LINK_STYLE_HREF_ATTR = 'href';
const LINK_STYLE_REL_VALUE = 'stylesheet';
const STYLE_ELEMENT = 'style';
const SCRIPT_ELEMENT = 'script';
const NG_NON_BINDABLE_ATTR = 'ng-non-bindable';
const NG_NON_BINDABLE_ATTR = 'ngNonBindable';
export function preparseElement(ast: HtmlElementAst): PreparsedElement {
var selectAttr = null;
@ -17,14 +17,14 @@ export function preparseElement(ast: HtmlElementAst): PreparsedElement {
var relAttr = null;
var nonBindable = false;
ast.attrs.forEach(attr => {
let attrName = attr.name.toLowerCase();
if (attrName == NG_CONTENT_SELECT_ATTR) {
let lcAttrName = attr.name.toLowerCase();
if (lcAttrName == NG_CONTENT_SELECT_ATTR) {
selectAttr = attr.value;
} else if (attrName == LINK_STYLE_HREF_ATTR) {
} else if (lcAttrName == LINK_STYLE_HREF_ATTR) {
hrefAttr = attr.value;
} else if (attrName == LINK_STYLE_REL_ATTR) {
} else if (lcAttrName == LINK_STYLE_REL_ATTR) {
relAttr = attr.value;
} else if (attrName == NG_NON_BINDABLE_ATTR) {
} else if (attr.name == NG_NON_BINDABLE_ATTR) {
nonBindable = true;
}
});