support !important in style directive

pull/7470/head
tanhauhau 4 years ago
parent 9e8592ef2c
commit fc9032cd08

@ -10,6 +10,7 @@ export default class StyleDirective extends Node {
name: string; name: string;
expression: Expression; expression: Expression;
should_cache: boolean; should_cache: boolean;
important: boolean = false;
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) { constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
super(component, parent, scope, info); super(component, parent, scope, info);
@ -30,10 +31,16 @@ export default class StyleDirective extends Node {
this.expression = new Expression(component, this, scope, identifier); this.expression = new Expression(component, this, scope, identifier);
this.should_cache = false; this.should_cache = false;
} else { } 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); const raw_expression = nodes_to_template_literal(info.value);
this.expression = new Expression(component, this, scope, raw_expression); this.expression = new Expression(component, this, scope, raw_expression);
this.should_cache = raw_expression.expressions.length > 0; this.should_cache = raw_expression.expressions.length > 0;
} }
} }
} }

@ -1072,7 +1072,7 @@ export default class ElementWrapper extends Wrapper {
add_styles(block: Block) { add_styles(block: Block) {
const has_spread = this.node.attributes.some(attr => attr.is_spread); const has_spread = this.node.attributes.some(attr => attr.is_spread);
this.node.styles.forEach((style_directive) => { 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); const snippet = expression.manipulate(block);
let cached_snippet; let cached_snippet;
@ -1081,7 +1081,7 @@ export default class ElementWrapper extends Wrapper {
block.add_variable(cached_snippet, snippet); 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); block.chunks.hydrate.push(updater);

@ -40,7 +40,10 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`); class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`);
const style_expression_list = node.styles.map(style_directive => { 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}`; return p`"${name}": ${expression}`;
}); });

@ -0,0 +1,34 @@
export default {
html: `
<h1 class="svelte-udf14z" style="background-color: red;">hello</h1>
<h1 class="svelte-udf14z">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important;">hello</h1>
<h2 class="svelte-udf14z" style="--background-color:red;">hello</h2>
<h2 class="svelte-udf14z" style="--background-color:red !important;">hello</h2>
`,
ssrHtml: `
<h1 class="svelte-udf14z" style="background-color: red;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red important;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important;">hello</h1>
<h1 class="svelte-udf14z" style="background-color: red !important">hello</h1>
<h2 class="svelte-udf14z" style="--background-color: red;">hello</h2>
<h2 class="svelte-udf14z" style="--background-color: red !important;">hello</h2>
`,
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)');
}
};

@ -0,0 +1,21 @@
<script>
export let color = 'red'
</script>
<h1 style:background-color={color} >hello</h1>
<h1 style:background-color="{color} important">hello</h1>
<h1 style:background-color="{color} !important">hello</h1>
<h1 style:background-color="{color} !important;">hello</h1>
<h1 style="background-color: {color} !important">hello</h1>
<h2 style:--background-color={color}>hello</h2>
<h2 style:--background-color="{color} !important;">hello</h2>
<style>
h1 {
background-color: blue !important;
}
h2 {
--background-color: blue !important;
background-color: var(--background-color);
}
</style>

@ -0,0 +1,27 @@
export default {
html: `
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
<h1 class="svelte-szzkfu">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
`,
ssrHtml: `
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red important;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red !important;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red !important;">hello</h1>
<h1 class="svelte-szzkfu" style="background-color: red !important">hello</h1>
`,
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');
}
};

@ -0,0 +1,15 @@
<script>
export let color = 'red'
</script>
<h1 style:background-color={color} >hello</h1>
<h1 style:background-color="{color} important">hello</h1>
<h1 style:background-color="{color} !important">hello</h1>
<h1 style:background-color="{color} !important;">hello</h1>
<h1 style="background-color: {color} !important">hello</h1>
<style>
h1 {
background-color: blue !important;
}
</style>
Loading…
Cancel
Save