fix(ShadowCss): fix `:host(tag)` and `:host-context(tag)`

fixes #11972
This commit is contained in:
Victor Berchet 2016-09-30 11:42:46 -07:00 committed by Chuck Jazdzewski
parent 3898dc488e
commit a6bb84e02b
2 changed files with 27 additions and 13 deletions

View File

@ -253,7 +253,7 @@ export class ShadowCss {
*
* to
*
* scopeName.foo > .bar
* .foo<scopeName> > .bar
*/
private _convertColonHost(cssText: string): string {
return this._convertColonRule(cssText, _cssColonHostRe, this._colonHostPartReplacer);
@ -264,7 +264,7 @@ export class ShadowCss {
*
* to
*
* scopeName.foo > .bar, .foo scopeName > .bar { }
* .foo<scopeName> > .bar, .foo scopeName > .bar { }
*
* and
*
@ -272,7 +272,7 @@ export class ShadowCss {
*
* to
*
* scopeName.foo .bar { ... }
* .foo<scopeName> .bar { ... }
*/
private _convertColonHostContext(cssText: string): string {
return this._convertColonRule(
@ -280,7 +280,7 @@ export class ShadowCss {
}
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
// p1 = :host, p2 = contents of (), p3 rest of rule
// m[1] = :host, m[2] = contents of (), m[3] rest of rule
return cssText.replace(regExp, function(...m: string[]) {
if (m[2]) {
const parts = m[2].split(',');
@ -376,13 +376,14 @@ export class ShadowCss {
string {
// In Android browser, the lastIndex is not reset when the regex is used in String.replace()
_polyfillHostRe.lastIndex = 0;
if (_polyfillHostRe.test(selector)) {
const replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
return selector.replace(_polyfillHostNoCombinator, replaceBy)
return selector.replace(_polyfillHostNoCombinatorRe, (hnc, selector) => selector + replaceBy)
.replace(_polyfillHostRe, replaceBy + ' ');
} else {
return scopeSelector + ' ' + selector;
}
return scopeSelector + ' ' + selector;
}
// return a selector with [name] suffix on each simple selector
@ -447,6 +448,7 @@ export class ShadowCss {
inAttributeSelector = false;
}
}
return scoped + _scopeSelectorPart(selector.substring(startIndex));
}
@ -469,6 +471,7 @@ const _parenSuffix = ')(?:\\((' +
const _cssColonHostRe = new RegExp('(' + _polyfillHost + _parenSuffix, 'gim');
const _cssColonHostContextRe = new RegExp('(' + _polyfillHostContext + _parenSuffix, 'gim');
const _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
const _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/;
const _shadowDOMSelectorsRe = [
/::shadow/g,
/::content/g,

View File

@ -99,16 +99,27 @@ export function main() {
it('should handle :host', () => {
expect(s(':host {}', 'a', 'a-host')).toEqual('[a-host] {}');
expect(s(':host(.x,.y) {}', 'a', 'a-host')).toEqual('[a-host].x, [a-host].y {}');
expect(s(':host(.x) {}', 'a', 'a-host')).toEqual('.x[a-host] {}');
expect(s(':host(ul) {}', 'a', 'a-host')).toEqual('ul[a-host] {}');
expect(s(':host(.x,.y) {}', 'a', 'a-host')).toEqual('.x[a-host], .y[a-host] {}');
expect(s(':host(ul,li) {}', 'a', 'a-host')).toEqual('ul[a-host], li[a-host] {}');
expect(s(':host(.x,.y) > .z {}', 'a', 'a-host'))
.toEqual('[a-host].x > .z[a], [a-host].y > .z[a] {}');
.toEqual('.x[a-host] > .z[a], .y[a-host] > .z[a] {}');
expect(s(':host(ul,li) > .z {}', 'a', 'a-host'))
.toEqual('ul[a-host] > .z[a], li[a-host] > .z[a] {}');
});
it('should handle :host-context', () => {
expect(s(':host-context(.x) {}', 'a', 'a-host')).toEqual('[a-host].x, .x [a-host] {}');
expect(s(':host-context(.x) {}', 'a', 'a-host')).toEqual('.x[a-host], .x [a-host] {}');
expect(s(':host-context(div) {}', 'a', 'a-host')).toEqual('div[a-host], div [a-host] {}');
expect(s(':host-context(.x) > .y {}', 'a', 'a-host'))
.toEqual('[a-host].x > .y[a], .x [a-host] > .y[a] {}');
.toEqual('.x[a-host] > .y[a], .x [a-host] > .y[a] {}');
expect(s(':host-context(ul) > .y {}', 'a', 'a-host'))
.toEqual('ul[a-host] > .y[a], ul [a-host] > .y[a] {}');
});
it('should support polyfill-next-selector', () => {
@ -138,10 +149,10 @@ export function main() {
it('should support polyfill-rule', () => {
let css = s('polyfill-rule {content: \':host.foo .bar\';color: blue;}', 'a', 'a-host');
expect(css).toEqual('[a-host].foo .bar[a] {;color:blue;}');
expect(css).toEqual('.foo[a-host] .bar[a] {;color:blue;}');
css = s('polyfill-rule {content: ":host.foo .bar";color:blue;}', 'a', 'a-host');
expect(css).toEqual('[a-host].foo .bar[a] {;color:blue;}');
expect(css).toEqual('.foo[a-host] .bar[a] {;color:blue;}');
});
it('should handle ::shadow', () => {