From fc9032cd080bb935c9a69f37e6dc7ca489a8033f Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Wed, 20 Apr 2022 01:00:03 +0800 Subject: [PATCH] support !important in style directive --- src/compiler/compile/nodes/StyleDirective.ts | 9 ++++- .../render_dom/wrappers/Element/index.ts | 4 +-- .../compile/render_ssr/handlers/Element.ts | 5 ++- .../_config.js | 34 +++++++++++++++++++ .../main.svelte | 21 ++++++++++++ .../_config.js | 27 +++++++++++++++ .../main.svelte | 15 ++++++++ 7 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 test/runtime-puppeteer/samples/inline-style-directive-important/_config.js create mode 100644 test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte create mode 100644 test/runtime/samples/inline-style-directive-important/_config.js create mode 100644 test/runtime/samples/inline-style-directive-important/main.svelte diff --git a/src/compiler/compile/nodes/StyleDirective.ts b/src/compiler/compile/nodes/StyleDirective.ts index ea340cf2dc..9e3b4981e6 100644 --- a/src/compiler/compile/nodes/StyleDirective.ts +++ b/src/compiler/compile/nodes/StyleDirective.ts @@ -10,6 +10,7 @@ export default class StyleDirective extends Node { name: string; expression: Expression; should_cache: boolean; + important: boolean = false; constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) { super(component, parent, scope, info); @@ -30,10 +31,16 @@ export default class StyleDirective extends Node { this.expression = new Expression(component, this, scope, identifier); this.should_cache = false; } else { + const last_chunk = info.value[info.value.length - 1]; + if (last_chunk && last_chunk.type === 'Text' && /\s*!important\s*;?\s*$/.test(last_chunk.data)) { + this.important = true; + last_chunk.data = last_chunk.data.replace(/\s*!important\s*;?\s*$/, ''); + if (!last_chunk.data) info.value.pop(); + } + const raw_expression = nodes_to_template_literal(info.value); this.expression = new Expression(component, this, scope, raw_expression); this.should_cache = raw_expression.expressions.length > 0; } - } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 5145db9fef..5f730dab6a 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -1072,7 +1072,7 @@ export default class ElementWrapper extends Wrapper { add_styles(block: Block) { const has_spread = this.node.attributes.some(attr => attr.is_spread); this.node.styles.forEach((style_directive) => { - const { name, expression, should_cache } = style_directive; + const { name, expression, should_cache, important } = style_directive; const snippet = expression.manipulate(block); let cached_snippet; @@ -1081,7 +1081,7 @@ export default class ElementWrapper extends Wrapper { block.add_variable(cached_snippet, snippet); } - const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, false)`; + const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, ${important ? 'true' : 'false'})`; block.chunks.hydrate.push(updater); diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 5957e1db0d..31a7845403 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -40,7 +40,10 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`); const style_expression_list = node.styles.map(style_directive => { - const { name, expression: { node: expression } } = style_directive; + let { name, important, expression: { node: expression } } = style_directive; + if (important) { + expression = x`${expression} + ' !important'`; + } return p`"${name}": ${expression}`; }); diff --git a/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js b/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js new file mode 100644 index 0000000000..e06a640767 --- /dev/null +++ b/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js @@ -0,0 +1,34 @@ +export default { + html: ` +

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+ `, + + ssrHtml: ` +

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+ `, + + test({ assert, target, window }) { + const h1s = target.querySelectorAll('h1'); + const h2s = target.querySelectorAll('h2'); + + assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'rgb(0, 0, 255)'); + assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'rgb(0, 0, 255)'); + assert.equal(window.getComputedStyle(h1s[2])['backgroundColor'], 'rgb(255, 0, 0)'); + assert.equal(window.getComputedStyle(h1s[3])['backgroundColor'], 'rgb(255, 0, 0)'); + assert.equal(window.getComputedStyle(h1s[4])['backgroundColor'], 'rgb(255, 0, 0)'); + assert.equal(window.getComputedStyle(h2s[0])['backgroundColor'], 'rgb(0, 0, 255)'); + assert.equal(window.getComputedStyle(h2s[1])['backgroundColor'], 'rgb(255, 0, 0)'); + } +}; diff --git a/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte b/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte new file mode 100644 index 0000000000..29725d1f9d --- /dev/null +++ b/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte @@ -0,0 +1,21 @@ + + +

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+

hello

+ + \ No newline at end of file diff --git a/test/runtime/samples/inline-style-directive-important/_config.js b/test/runtime/samples/inline-style-directive-important/_config.js new file mode 100644 index 0000000000..bf1664d39c --- /dev/null +++ b/test/runtime/samples/inline-style-directive-important/_config.js @@ -0,0 +1,27 @@ +export default { + html: ` +

hello

+

hello

+

hello

+

hello

+

hello

+ `, + + ssrHtml: ` +

hello

+

hello

+

hello

+

hello

+

hello

+ `, + + test({ assert, target, window }) { + const h1s = target.querySelectorAll('h1'); + + assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'red'); + assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'blue'); + assert.equal(window.getComputedStyle(h1s[2])['backgroundColor'], 'red'); + assert.equal(window.getComputedStyle(h1s[3])['backgroundColor'], 'red'); + assert.equal(window.getComputedStyle(h1s[4])['backgroundColor'], 'red'); + } +}; diff --git a/test/runtime/samples/inline-style-directive-important/main.svelte b/test/runtime/samples/inline-style-directive-important/main.svelte new file mode 100644 index 0000000000..5830905dc6 --- /dev/null +++ b/test/runtime/samples/inline-style-directive-important/main.svelte @@ -0,0 +1,15 @@ + + +

hello

+

hello

+

hello

+

hello

+

hello

+ + \ No newline at end of file