X Tutup
Skip to content
Closed
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
42 changes: 37 additions & 5 deletions modules/angular2/src/core/compiler/command_compiler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {isPresent, isBlank, Type, isString} from 'angular2/src/core/facade/lang';
import {isPresent, isBlank, Type, isString, StringWrapper} from 'angular2/src/core/facade/lang';
import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
import {
TemplateCmd,
Expand Down Expand Up @@ -44,6 +44,8 @@ export var TEMPLATE_COMMANDS_MODULE_REF =
moduleRef(`package:angular2/src/core/linker/template_commands${MODULE_SUFFIX}`);

const IMPLICIT_TEMPLATE_VAR = '\$implicit';
const CLASS_ATTR = 'class';
const STYLE_ATTR = 'style';

@Injectable()
export class CommandCompiler {
Expand Down Expand Up @@ -211,14 +213,14 @@ class CommandBuilderVisitor<R> implements TemplateAstVisitor {

private _readAttrNameAndValues(directives: CompileDirectiveMetadata[],
attrAsts: TemplateAst[]): string[] {
var attrNameAndValues: string[] = visitAndReturnContext(this, attrAsts, []);
var attrs = keyValueArrayToMap(visitAndReturnContext(this, attrAsts, []));
directives.forEach(directiveMeta => {
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value, name) => {
attrNameAndValues.push(name);
attrNameAndValues.push(value);
var prevValue = attrs[name];
attrs[name] = isPresent(prevValue) ? mergeAttributeValue(name, prevValue, value) : value;
});
});
return removeKeyValueArrayDuplicates(attrNameAndValues);
return mapToKeyValueArray(attrs);
}

visitNgContent(ast: NgContentAst, context: any): any {
Expand Down Expand Up @@ -328,6 +330,36 @@ function removeKeyValueArrayDuplicates(keyValueArray: string[]): string[] {
return resultKeyValueArray;
}

function keyValueArrayToMap(keyValueArr: string[]): {[key: string]: string} {
var data: {[key: string]: string} = {};
for (var i = 0; i < keyValueArr.length; i += 2) {
data[keyValueArr[i]] = keyValueArr[i + 1];
}
return data;
}

function mapToKeyValueArray(data: {[key: string]: string}): string[] {
var entryArray = [];
StringMapWrapper.forEach(data, (value, name) => { entryArray.push([name, value]); });
// We need to sort to get a defined output order
// for tests and for caching generated artifacts...
ListWrapper.sort(entryArray, (entry1, entry2) => StringWrapper.compare(entry1[0], entry2[0]));
var keyValueArray = [];
entryArray.forEach((entry) => {
keyValueArray.push(entry[0]);
keyValueArray.push(entry[1]);
});
return keyValueArray;
}

function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: string): string {
if (attrName == CLASS_ATTR || attrName == STYLE_ATTR) {
return `${attrValue1} ${attrValue2}`;
} else {
return attrValue2;
}
}

class DirectiveContext {
constructor(public index: number, public eventTargetAndNames: string[],
public targetVariableNameAndValues: any[],
Expand Down
42 changes: 42 additions & 0 deletions modules/angular2/test/core/compiler/command_compiler_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,48 @@ export function main() {
});
}));

it('should merge element attributes with host attributes',
inject([AsyncTestCompleter], (async) => {
var rootComp = createComp({
type: RootCompTypeMeta,
template: '<div class="origclass" style="origstyle" role="origrole" attr1>'
});
var dir = CompileDirectiveMetadata.create({
selector: 'div',
isComponent: false,
type: SomeDirTypeMeta,
host: {'class': 'newclass', 'style': 'newstyle', 'role': 'newrole', 'attr2': ''}
});
run(rootComp, [dir])
.then((data) => {
expect(data).toEqual([
[
BEGIN_ELEMENT,
'div',
[
'attr1',
'',
'attr2',
'',
'class',
'origclass newclass',
'role',
'newrole',
'style',
'origstyle newstyle'
],
[],
[],
['SomeDirType'],
true,
null
],
[END_ELEMENT]
]);
async.done();
});
}));

it('should emulate style encapsulation', inject([AsyncTestCompleter], (async) => {
var rootComp = createComp({
type: RootCompTypeMeta,
Expand Down
X Tutup