Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions packages/ember-glimmer/lib/syntax/curly-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ function aliasIdToElementId(args, props) {
}
}

// We must traverse the attributeBindings in reverse keeping track of
// what has already been applied. This is essentially refining the concated
// properties applying right to left.
function applyAttributeBindings(attributeBindings, component, operations) {
let seen = [];
let i = attributeBindings.length - 1;

while (i !== -1) {
let binding = attributeBindings[i];
let parsedMicroSyntax = AttributeBindingReference.parseMicroSyntax(binding);
let [ prop ] = parsedMicroSyntax;

if (seen.indexOf(prop) === -1) {
seen.push(prop);
AttributeBindingReference.apply(component, parsedMicroSyntax, operations);
}

i--;
}
}

export class CurlyComponentSyntax extends StatementSyntax {
constructor({ args, definition, templates }) {
super();
Expand Down Expand Up @@ -138,9 +159,7 @@ class CurlyComponentManager {
let { attributeBindings, classNames, classNameBindings } = component;

if (attributeBindings) {
attributeBindings.forEach(binding => {
AttributeBindingReference.apply(component, binding, operations);
});
applyAttributeBindings(attributeBindings, component, operations);
}

if (classRef) {
Expand Down
20 changes: 15 additions & 5 deletions packages/ember-glimmer/lib/utils/references.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,24 +237,34 @@ export class InternalHelperReference extends CachedReference {
import { assert } from 'ember-metal/debug';

export class AttributeBindingReference extends CachedReference {
static apply(component, microsyntax, operations) {
let reference = this.parse(component, microsyntax);
static apply(component, parsedMicroSyntax, operations) {
let reference;
let prop = parsedMicroSyntax[0];
let attr;

if (parsedMicroSyntax.length === 1) {
reference = new this(component, prop);
} else {
attr = parsedMicroSyntax[1];
reference = new this(component, prop, attr);
}

operations.addAttribute(reference.attributeName, reference);
}

static parse(component, microsyntax) {
static parseMicroSyntax(microsyntax) {
let colonIndex = microsyntax.indexOf(':');

if (colonIndex === -1) {
assert('You cannot use class as an attributeBinding, use classNameBindings instead.', microsyntax !== 'class');
return new this(component, microsyntax);
return [microsyntax];
} else {
let prop = microsyntax.substring(0, colonIndex);
let attr = microsyntax.substring(colonIndex + 1);

assert('You cannot use class as an attributeBinding, use classNameBindings instead.', attr !== 'class');

return new this(component, prop, attr);
return [prop, attr];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ moduleFor('Attribute bindings integration', class extends RenderingTest {
this.assertComponentElement(this.nthChild(0), { tagName: 'div', attrs: { 'id': 'special-sauce' } });
}

['@htmlbars attributeBindings are overwritten']() {
['@test attributeBindings are overwritten']() {
let FooBarComponent = Component.extend({
attributeBindings: ['href'],
href: 'a href'
Expand Down