Skip to content

Commit

Permalink
Fixed attributes keys cannot be accessed in Twig templates. (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianmarz authored and sun committed Aug 2, 2019
1 parent 1993ef5 commit 3bf0804
Showing 1 changed file with 55 additions and 24 deletions.
79 changes: 55 additions & 24 deletions src/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,38 +140,69 @@ class Attributes {
static convert(context) {
_.forEach(context, (value, name) => {
if (typeof name === 'string' && name.indexOf('attributes') > -1) {
context[name] = new Attributes(value);
context[name] = this.proxy(new Attributes(value));
}
else if (_.isObject(value)) {
this.convert(value);
}
});
};

}
/**
* Serializes all attributes into an HTML element attributes string.
*
* The resulting string MUST start with a space, unless there are no attributes
* to serialize.
*
* @return string
*/
toString() {
let string = '';
if (this.classes.length) {
string += ' class="' + _.join(_.uniq(this.classes), ' ') + '"';
}
_.forEach(this.storage, function (value, name) {
if (value !== null) {
string += ` ${name}="${value}"`;
}
else {
string += ` ${name}`;
}
});
return string;
};

/**
* Serializes all attributes into an HTML element attributes string.
*
* The resulting string MUST start with a space, unless there are no attributes
* to serialize.
*
* @return string
*/
Attributes.prototype.toString = function () {
let string = '';
if (this.classes.length) {
string += ' class="' + _.join(_.uniq(this.classes), ' ') + '"';
/**
* Proxies direct accesses to attribute properties.
*
* @param attributes
* @returns {any|undefined}
*/
static proxy(attributes) {
return new Proxy(attributes, {
get (target, name, receiver) {
if (typeof name === 'string' && !Reflect.has(target, name)) {
if (name.indexOf('get') !== -1) {
// Undo Twig's property name to method name conversion.
name = name.replace('get', '').toLowerCase();
// Re-route into storage unless class property is requested.
if (name === 'class') {
name = 'classes';
}
else {
target = target.storage;
}
}
// Do not forward other property accesses and tests (like isset()).
else {
return undefined;
}
}
return Reflect.get(target, name, receiver);
}
});
}
_.forEach(this.storage, function (value, name) {
if (value !== null) {
string += ` ${name}="${value}"`;
}
else {
string += ` ${name}`;
}
});
return string;
};

}

module.exports = Attributes;

0 comments on commit 3bf0804

Please sign in to comment.