Skip to content

Commit

Permalink
fix(compiler): fix host-contex issue
Browse files Browse the repository at this point in the history
Fix an error when use two or more :host-context selector.
Now all host-context generate all posible combinations in the css result.

Close issue angular#19199
  • Loading branch information
vladimir.arreba@innofis.com committed Jan 2, 2018
1 parent d34f0bf commit 36b2f14
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
40 changes: 40 additions & 0 deletions packages/compiler/src/shadow_css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,33 @@ export class ShadowCss {

private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
// m[1] = :host(-context), m[2] = contents of (), m[3] rest of rule
let _this = this;
return cssText.replace(regExp, function(...m: string[]) {
// Regular expresion for check the next :host-context
const regExprCheckHostContext = /-shadowcsscontext\((.+?)\)/mi;
// Get first repeated :host-context
let match = m[3].match(regExprCheckHostContext);
let arrSelector = [m[2]];
while (match !== null) {
// Clean the founded selector and save it.
const selectorHostContext = match[0].replace('-shadowcsscontext(', '').replace(')','');
arrSelector.push(selectorHostContext);
// Remove the current :host-context
m[3] = m[3].replace(regExprCheckHostContext, '');
// Get the next repeated :host-context
match = m[3].match(regExprCheckHostContext);
}
// If have more than 1 class, generate all combinations.
if(arrSelector.length > 1) {
const listOfCombinations = _this._combineArraySelectors(arrSelector);
m[2] = '';
// Add all combination separated by spaces.
for(let i = 0; i < listOfCombinations.length; i++) {
m[2] += listOfCombinations[i].join(' ') + ',';
}
// Add one case of all clases without space separator.
m[2] += listOfCombinations[0].join('');
}
if (m[2]) {
const parts = m[2].split(',');
const r: string[] = [];
Expand All @@ -298,6 +324,20 @@ export class ShadowCss {
});
}

private _combineArraySelectors(arrSelector: string[]): string[][] {
let results: string[][] = [];
if (arrSelector.length === 1) return [[arrSelector[0]]];
for(let i = 0; i < arrSelector.length; i++) {
let copyArr: string[] = arrSelector.slice();
let firstItem: string[] = copyArr.splice(i, 1);
let childResult: string[][] = this._combineArraySelectors(copyArr);
for(let j = 0; j < childResult.length; j++) {
results.push([...firstItem, ...childResult[j]]);
}
}
return results;
}

private _colonHostContextPartReplacer(host: string, part: string, suffix: string): string {
if (part.indexOf(_polyfillHost) > -1) {
return this._colonHostPartReplacer(host, part, suffix);
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler/test/shadow_css_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ export function main() {
expect(s(':host-context([a=b]) {}', 'contenta', 'a-host'))
.toEqual('[a=b][a-host], [a="b"] [a-host] {}');
});

it('should handle multiple host-context', () => {
expect(s(':host-context(.one) :host-context(.two) {}', 'contenta', 'a-host'))
.toEqual('.one[a-host] .two[contenta], .one .two [a-host], .two[a-host] .one[contenta], .two .one [a-host], .one.two[a-host], .one.two [a-host] {}');
});
});

it('should support polyfill-next-selector', () => {
Expand Down

0 comments on commit 36b2f14

Please sign in to comment.