在我的aurelia应用程序中,我的一个自定义元素panel
(shadow DOM)包含另一个自定义元素widget
(shadow DOM),它具有自定义属性own-attribute
(模板控制器)它。 panel
有一个范围样式表(<require from="./panel.css" as="scoped"></require>
)。在编译时,aurelia正确地将./panel.css
注入panel
的阴影根。但是,在单独的步骤中,在own-context
内widget
上编译panel
时,aurelia会将./panel.css
注入<head>
,从而打破了自定义元素样式表的抽象,通常会对我的应用程序造成严重破坏。
我该如何解决这个问题?
我尝试制作一个羽毛here,但它不起作用。我正在使用ES2017,这会让生活更加复杂。
panel
由ViewCompiler.compile()
编译
ViewCompiler._compileNode()
widget
上的calls itself widget
上的calls ViewCompiler._compileElement()
own-context
视为“提升指令”和calls HtmlBehaviorResource.compile()
widget
上的calls ViewCompiler.compile()
beforeCompile
invokeHook
CSSViewEngineHooks.beforeCompile()
时,会将一堆样式注入<head>
这是一个问题。 HtmlBehaviorResource.compile()
对ViewResource.compile()
的调用未传递编译指令,因此后者使用默认值。因此,CSS钩子不会得到它们应该注入阴影根的消息。更不用说这是没有充分理由双重注射这些样式。
at eval (eval at injectStyles (http://example.com/jspm/npm/aurelia-pal-browser@1.1.0/aurelia-pal-browser.js), <anonymous>:1:11)
at Object.injectStyles (http://example.com/jspm/npm/aurelia-pal-browser@1.1.0/aurelia-pal-browser.js:434:27)
at ViewCSS.beforeCompile (http://example.com/jspm/npm/aurelia-templating-resources@1.2.0/css-resource.js:105:25)
at ViewResources._invokeHook (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:1281:25)
at ViewCompiler.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2509:17)
at HtmlBehaviorResource.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:3972:46)
at ViewCompiler._compileElement (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2813:40)
at ViewCompiler._compileNode (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2543:23)
at ViewCompiler._compileNode (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2565:33)
at ViewCompiler.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2512:12)
import { useShadowDOM, customElement } from 'aurelia-templating';
export { PanelModule };
@useShadowDOM
@customElement('panel-elem')
class PanelModule {}
<template>
<require from="./panel.css" as="scoped"></require>
<require from="lib:widget"></require>
<require from="lib:own-context"></require>
<widget-elem own-context>
<content>
some content
</content>
</widget-elem>
</template>
import { useShadowDOM, customElement } from 'aurelia-templating';
export { WidgetModule };
@useShadowDOM
@customElement('widget-elem')
class WidgetModule {}
<template>
<require from="./widget.css" as="scoped"></require>
<div id="thing">
<slot></slot>
</div
</template>
import { inject, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import { createOverrideContext } from 'aurelia-binding';
// from https://github.com/aurelia/templating/issues/411
@templateController
@inject(BoundViewFactory, ViewSlot)
class OwnContextCustomAttribute {
constructor(factory, slot) {
this.factory = factory;
this.slot = slot;
}
bind(bindingContext, overrideContext) {
let newContext = { };
overrideContext = createOverrideContext(newContext, overrideContext);
if (!this.view) {
this.view = this.factory.create();
this.view.bind(newContext, overrideContext);
this.slot.add(this.view);
} else {
this.view.bind(newContext, overrideContext);
}
}
unbind() {
if (this.view)
this.view.unbind();
}
}
我似乎有所作为。我打了补丁aurelia/templating-resources/css-resource.js
:
beforeCompile(content: DocumentFragment, resources: ViewResources, instruction: ViewCompileInstruction): void {
+ if (this.done) {
+ return
+ } else {
+ this.done = true
+ }
if (instruction.targetShadowDOM) {
DOM.injectStyles(this.css, content, true);
} else if (FEATURE.scopedCSS) {
let styleNode = DOM.injectStyles(this.css, content, true);
styleNode.setAttribute('scoped', 'scoped');
} else if (!this.owner._alreadyGloballyInjected) {
DOM.injectStyles(this.css);
this.owner._alreadyGloballyInjected = true;
}
}