|
|
@@ -1218,6 +1218,190 @@ describe('defineCustomElement', () => {
|
|
|
assertStyles(el, [`div { color: blue; }`, `div { color: red; }`])
|
|
|
})
|
|
|
|
|
|
+ test('root custom element HMR should preserve child-first style order', async () => {
|
|
|
+ const Child = defineComponent({
|
|
|
+ styles: [`div { color: green; }`],
|
|
|
+ render() {
|
|
|
+ return 'child'
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const def = defineComponent({
|
|
|
+ __hmrId: 'root-child-style-order',
|
|
|
+ styles: [`div { color: red; }`],
|
|
|
+ render() {
|
|
|
+ return h(Child)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const Foo = defineCustomElement(def)
|
|
|
+ customElements.define('my-el-root-hmr-style-order', Foo)
|
|
|
+ container.innerHTML = `<my-el-root-hmr-style-order></my-el-root-hmr-style-order>`
|
|
|
+ const el = container.childNodes[0] as VueElement
|
|
|
+
|
|
|
+ assertStyles(el, [`div { color: green; }`, `div { color: red; }`])
|
|
|
+
|
|
|
+ __VUE_HMR_RUNTIME__.reload(def.__hmrId!, {
|
|
|
+ ...def,
|
|
|
+ styles: [`div { color: blue; }`, `div { color: yellow; }`],
|
|
|
+ } as any)
|
|
|
+
|
|
|
+ await nextTick()
|
|
|
+ assertStyles(el, [
|
|
|
+ `div { color: green; }`,
|
|
|
+ `div { color: blue; }`,
|
|
|
+ `div { color: yellow; }`,
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ test('inject child component styles before parent styles', async () => {
|
|
|
+ const Baz = () => h(Bar)
|
|
|
+ const Bar = defineComponent({
|
|
|
+ styles: [`div { color: green; }`],
|
|
|
+ render() {
|
|
|
+ return 'bar'
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WrapperBar = defineComponent({
|
|
|
+ styles: [`div { color: blue; }`],
|
|
|
+ render() {
|
|
|
+ return h(Baz)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WBaz = () => h(WrapperBar)
|
|
|
+ const Foo = defineCustomElement({
|
|
|
+ styles: [`div { color: red; }`],
|
|
|
+ render() {
|
|
|
+ return [h(Baz), h(WBaz)]
|
|
|
+ },
|
|
|
+ })
|
|
|
+ customElements.define('my-el-with-wrapper-child-styles', Foo)
|
|
|
+ container.innerHTML = `<my-el-with-wrapper-child-styles></my-el-with-wrapper-child-styles>`
|
|
|
+ const el = container.childNodes[0] as VueElement
|
|
|
+
|
|
|
+ // inject order should be child -> parent
|
|
|
+ assertStyles(el, [
|
|
|
+ `div { color: green; }`,
|
|
|
+ `div { color: blue; }`,
|
|
|
+ `div { color: red; }`,
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
+ test('inject nested child component styles after HMR removes parent styles', async () => {
|
|
|
+ const Bar = defineComponent({
|
|
|
+ __hmrId: 'nested-child-style-hmr-bar',
|
|
|
+ styles: [`div { color: green; }`],
|
|
|
+ render() {
|
|
|
+ return 'bar'
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WrapperBar = defineComponent({
|
|
|
+ __hmrId: 'nested-child-style-hmr-wrapper',
|
|
|
+ styles: [`div { color: blue; }`],
|
|
|
+ render() {
|
|
|
+ return h(Bar)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const Foo = defineCustomElement({
|
|
|
+ styles: [`div { color: red; }`],
|
|
|
+ render() {
|
|
|
+ return h(WrapperBar)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ customElements.define('my-el-with-hmr-nested-child-styles', Foo)
|
|
|
+ container.innerHTML = `<my-el-with-hmr-nested-child-styles></my-el-with-hmr-nested-child-styles>`
|
|
|
+ const el = container.childNodes[0] as VueElement
|
|
|
+
|
|
|
+ assertStyles(el, [
|
|
|
+ `div { color: green; }`,
|
|
|
+ `div { color: blue; }`,
|
|
|
+ `div { color: red; }`,
|
|
|
+ ])
|
|
|
+
|
|
|
+ __VUE_HMR_RUNTIME__.reload(WrapperBar.__hmrId!, {
|
|
|
+ ...WrapperBar,
|
|
|
+ styles: undefined,
|
|
|
+ } as any)
|
|
|
+ await nextTick()
|
|
|
+ assertStyles(el, [`div { color: green; }`, `div { color: red; }`])
|
|
|
+
|
|
|
+ __VUE_HMR_RUNTIME__.reload(Bar.__hmrId!, {
|
|
|
+ ...Bar,
|
|
|
+ styles: [`div { color: yellow; }`],
|
|
|
+ } as any)
|
|
|
+ await nextTick()
|
|
|
+ assertStyles(el, [`div { color: yellow; }`, `div { color: red; }`])
|
|
|
+ })
|
|
|
+
|
|
|
+ test('inject child component styles when parent has no styles', async () => {
|
|
|
+ const Baz = () => h(Bar)
|
|
|
+ const Bar = defineComponent({
|
|
|
+ styles: [`div { color: green; }`],
|
|
|
+ render() {
|
|
|
+ return 'bar'
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WrapperBar = defineComponent({
|
|
|
+ styles: [`div { color: blue; }`],
|
|
|
+ render() {
|
|
|
+ return h(Baz)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WBaz = () => h(WrapperBar)
|
|
|
+ // without styles
|
|
|
+ const Foo = defineCustomElement({
|
|
|
+ render() {
|
|
|
+ return [h(Baz), h(WBaz)]
|
|
|
+ },
|
|
|
+ })
|
|
|
+ customElements.define('my-el-with-inject-child-styles', Foo)
|
|
|
+ container.innerHTML = `<my-el-with-inject-child-styles></my-el-with-inject-child-styles>`
|
|
|
+ const el = container.childNodes[0] as VueElement
|
|
|
+
|
|
|
+ assertStyles(el, [`div { color: green; }`, `div { color: blue; }`])
|
|
|
+ })
|
|
|
+
|
|
|
+ test('inject nested child component styles', async () => {
|
|
|
+ const Baz = defineComponent({
|
|
|
+ styles: [`div { color: yellow; }`],
|
|
|
+ render() {
|
|
|
+ return h(Bar)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const Bar = defineComponent({
|
|
|
+ styles: [`div { color: green; }`],
|
|
|
+ render() {
|
|
|
+ return 'bar'
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WrapperBar = defineComponent({
|
|
|
+ styles: [`div { color: blue; }`],
|
|
|
+ render() {
|
|
|
+ return h(Baz)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const WBaz = defineComponent({
|
|
|
+ styles: [`div { color: black; }`],
|
|
|
+ render() {
|
|
|
+ return h(WrapperBar)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const Foo = defineCustomElement({
|
|
|
+ styles: [`div { color: red; }`],
|
|
|
+ render() {
|
|
|
+ return [h(Baz), h(WBaz)]
|
|
|
+ },
|
|
|
+ })
|
|
|
+ customElements.define('my-el-with-inject-nested-child-styles', Foo)
|
|
|
+ container.innerHTML = `<my-el-with-inject-nested-child-styles></my-el-with-inject-nested-child-styles>`
|
|
|
+ const el = container.childNodes[0] as VueElement
|
|
|
+ assertStyles(el, [
|
|
|
+ `div { color: green; }`,
|
|
|
+ `div { color: yellow; }`,
|
|
|
+ `div { color: blue; }`,
|
|
|
+ `div { color: black; }`,
|
|
|
+ `div { color: red; }`,
|
|
|
+ ])
|
|
|
+ })
|
|
|
+
|
|
|
test("child components should not inject styles to root element's shadow root w/ shadowRoot false", async () => {
|
|
|
const Bar = defineComponent({
|
|
|
styles: [`div { color: green; }`],
|