diff --git a/glass-easel/src/class_list.ts b/glass-easel/src/class_list.ts index b544f0c..a83f742 100644 --- a/glass-easel/src/class_list.ts +++ b/glass-easel/src/class_list.ts @@ -76,22 +76,16 @@ export class ClassList { constructor( elem: Element, externalNameAlias: { [externalName: string]: string[] | null } | null, + owner: ClassList | null, + styleScope: number, + extraStyleScope: number | undefined, ) { this._$elem = elem - const ownerComp = elem.ownerShadowRoot?.getHostNode() - if (ownerComp) { - const compOptions = ownerComp.getComponentOptions() - this._$owner = ownerComp.classList - this._$defaultScope = compOptions.styleScope - this._$extraScope = - compOptions.extraStyleScope === null ? undefined : compOptions.extraStyleScope - this._$rootScope = ownerComp.classList!._$rootScope ?? this._$defaultScope - } else { - this._$owner = null - this._$defaultScope = StyleScopeManager.globalScope() - this._$extraScope = undefined - this._$rootScope = undefined - } + this._$owner = owner + this._$defaultScope = styleScope + this._$extraScope = extraStyleScope + // root owner got globalScope as it's styleScope, avoid the root owner + this._$rootScope = owner?._$owner ? owner._$rootScope : styleScope this._$alias = externalNameAlias if (externalNameAlias) { const resolved = Object.create(null) as { [externalName: string]: null } @@ -128,12 +122,13 @@ export class ClassList { cb(this._$rootScope, name.slice(1)) } else if (name[0] === '^') { let n = name.slice(1) - let owner = this._$owner - while (owner && n[0] === '^') { + let owner: ClassList | null | undefined = this._$owner + while (n[0] === '^') { n = n.slice(1) - owner = owner._$owner + owner = owner?._$owner } - const scopeId = owner ? owner._$defaultScope : this._$rootScope + // root owner got globalScope as it's styleScope, avoid the root owner + const scopeId = owner?._$owner ? owner._$defaultScope : this._$rootScope cb(scopeId, n) } else { if (this._$extraScope !== undefined) { diff --git a/glass-easel/src/component.ts b/glass-easel/src/component.ts index bde3a18..03b0333 100644 --- a/glass-easel/src/component.ts +++ b/glass-easel/src/component.ts @@ -49,7 +49,7 @@ import { } from './data_proxy' import { Relation, generateRelationDefinitionGroup, RelationDefinitionGroup } from './relation' import { Template, TemplateEngine, TemplateInstance } from './template_engine' -import { ClassList } from './class_list' +import { ClassList, StyleScopeManager } from './class_list' import { GeneralBackendContext, GeneralBackendElement } from './node' import { DataPath, parseSinglePath, parseMultiPaths } from './data_path' import { ExternalShadowRoot } from './external_shadow_tree' @@ -543,7 +543,19 @@ export class Component< externalClassAlias[externalClasses[i]!] = null } } - comp.classList = new ClassList(comp, externalClassAlias) + const styleScope = owner + ? owner.getHostNode().getComponentOptions().styleScope + : StyleScopeManager.globalScope() + const extraStyleScope = owner + ? owner.getHostNode().getComponentOptions().extraStyleScope ?? undefined + : undefined + comp.classList = new ClassList( + comp, + externalClassAlias, + owner ? owner.getHostNode().classList : null, + styleScope, + extraStyleScope, + ) if (backendElement) { const styleScope = owner ? owner.getHostNode()._$definition._$options.styleScope diff --git a/glass-easel/src/native_node.ts b/glass-easel/src/native_node.ts index bd3fd6f..9209058 100644 --- a/glass-easel/src/native_node.ts +++ b/glass-easel/src/native_node.ts @@ -2,7 +2,7 @@ import * as backend from './backend/backend_protocol' import * as composedBackend from './backend/composed_backend_protocol' import * as domlikeBackend from './backend/domlike_backend_protocol' import { globalOptions } from './global_options' -import { ClassList } from './class_list' +import { ClassList, StyleScopeManager } from './class_list' import { Element } from './element' import { ShadowRoot } from './shadow_root' import { GeneralBackendElement } from '.' @@ -40,7 +40,16 @@ export class NativeNode extends Element { backendElement = backend.createElement(tagName, stylingName ?? tagName) } node._$initialize(false, backendElement, owner, nodeTreeContext) - node.classList = new ClassList(node, null) + const ownerOptions = owner.getHostNode().getComponentOptions() + const styleScope = owner ? ownerOptions.styleScope : StyleScopeManager.globalScope() + const extraStyleScope = owner ? ownerOptions.extraStyleScope ?? undefined : undefined + node.classList = new ClassList( + node, + null, + owner ? owner.getHostNode().classList : null, + styleScope, + extraStyleScope, + ) if (owner && backendElement) { const styleScope = owner.getHostNode()._$definition._$options.styleScope if (styleScope) { diff --git a/glass-easel/tests/legacy/component.test.js b/glass-easel/tests/legacy/component.test.js index caaab74..6f0f0ac 100644 --- a/glass-easel/tests/legacy/component.test.js +++ b/glass-easel/tests/legacy/component.test.js @@ -1017,7 +1017,7 @@ describe('Component', function () { options: { styleScope: componentSpace.styleScopeManager.register('a'), }, - template: '', + template: '', }) regElem({ is: 'component-class-special-prefix-b', @@ -1025,25 +1025,25 @@ describe('Component', function () { styleScope: componentSpace.styleScopeManager.register('b'), extraStyleScope: glassEasel.StyleScopeManager.globalScope(), }, - template: '', + template: '', }) regElem({ is: 'component-class-special-prefix-c', options: { styleScope: componentSpace.styleScopeManager.register('c'), }, - template: '', + template: '', }) var elem = createElem('component-class-special-prefix-c') - expect(elem.$.c.class).toBe('c ^c ~c') - expect(elem.$.c.$$.getAttribute('class')).toBe('c--c c') - expect(elem.$.c.shadowRoot.querySelector('.bb').$$.getAttribute('class')).toBe( - 'b b--b c--b c--bbb c--bb', + expect(elem.$.c.class).toBe('c ^c1 ^^c2 ~c3') + expect(elem.$.c.$$.getAttribute('class')).toBe('c--c c--c1 c--c2 c--c3') + expect(elem.$.c.shadowRoot.querySelector('.b2').$$.getAttribute('class')).toBe( + 'b b--b c--b1 c--b2 c--b3 c--b4', ) - expect(elem.$.c.$.b.shadowRoot.querySelector('.aa').$$.getAttribute('class')).toBe( - 'a--a b--a c--aa c--a', + expect(elem.$.c.$.b.shadowRoot.querySelector('.a2').$$.getAttribute('class')).toBe( + 'a--a b--a1 c--a2 c--a3 c--a4 c--a5', ) - expect(elem.$.c.$.b.$.a.$$.getAttribute('class')).toBe('a--a b--a c--aa c--a') + expect(elem.$.c.$.b.$.a.$$.getAttribute('class')).toBe('a--a b--a1 c--a2 c--a3 c--a4 c--a5') }) it('should adding write ID and class prefix info to DOM when required', function () {