remove cascade option

pull/1348/head
Rich Harris 6 years ago
parent 40e6b4fc11
commit 87a8e37150

@ -31,18 +31,18 @@ class Rule {
return this.selectors.some(s => s.used);
}
minify(code: MagicString, cascade: boolean, dev: boolean) {
minify(code: MagicString, dev: boolean) {
let c = this.node.start;
let started = false;
this.selectors.forEach((selector, i) => {
if (cascade || selector.used) {
if (selector.used) {
const separator = started ? ',' : '';
if ((selector.node.start - c) > separator.length) {
code.overwrite(c, selector.node.start, separator);
}
if (!cascade) selector.minify(code);
selector.minify(code);
c = selector.node.end;
started = true;
@ -66,39 +66,12 @@ class Rule {
code.remove(c, this.node.block.end - 1);
}
transform(code: MagicString, id: string, keyframes: Map<string, string>, cascade: boolean) {
transform(code: MagicString, id: string, keyframes: Map<string, string>) {
if (this.parent && this.parent.node.type === 'Atrule' && this.parent.node.name === 'keyframes') return true;
const attr = `.${id}`;
if (cascade) {
this.selectors.forEach(selector => {
// TODO disable cascading (without :global(...)) in v2
const { start, end, children } = selector.node;
const css = code.original;
const selectorString = css.slice(start, end);
const firstToken = children[0];
let transformed;
if (firstToken.type === 'TypeSelector') {
const insert = firstToken.end;
const head = firstToken.name === '*' ? '' : css.slice(start, insert);
const tail = css.slice(insert, end);
transformed = `${head}${attr}${tail},${attr} ${selectorString}`;
} else {
transformed = `${attr}${selectorString},${attr} ${selectorString}`;
}
code.overwrite(start, end, transformed);
});
} else {
this.selectors.forEach(selector => selector.transform(code, attr));
}
this.selectors.forEach(selector => selector.transform(code, attr));
this.declarations.forEach(declaration => declaration.transform(code, keyframes));
}
@ -182,7 +155,7 @@ class Atrule {
return true; // TODO
}
minify(code: MagicString, cascade: boolean, dev: boolean) {
minify(code: MagicString, dev: boolean) {
if (this.node.name === 'media') {
const expressionChar = code.original[this.node.expression.start];
let c = this.node.start + (expressionChar === '(' ? 6 : 7);
@ -215,9 +188,9 @@ class Atrule {
let c = this.node.block.start + 1;
this.children.forEach(child => {
if (cascade || child.isUsed(dev)) {
if (child.isUsed(dev)) {
code.remove(c, child.node.start);
child.minify(code, cascade, dev);
child.minify(code, dev);
c = child.node.end;
}
});
@ -226,7 +199,7 @@ class Atrule {
}
}
transform(code: MagicString, id: string, keyframes: Map<string, string>, cascade: boolean) {
transform(code: MagicString, id: string, keyframes: Map<string, string>) {
if (this.node.name === 'keyframes') {
this.node.expression.children.forEach(({ type, name, start, end }: Node) => {
if (type === 'Identifier') {
@ -240,7 +213,7 @@ class Atrule {
}
this.children.forEach(child => {
child.transform(code, id, keyframes, cascade);
child.transform(code, id, keyframes);
})
}
@ -264,7 +237,6 @@ const keys = {};
export default class Stylesheet {
source: string;
parsed: Parsed;
cascade: boolean;
filename: string;
dev: boolean;
@ -276,10 +248,9 @@ export default class Stylesheet {
nodesWithCssClass: Set<Node>;
constructor(source: string, parsed: Parsed, filename: string, cascade: boolean, dev: boolean) {
constructor(source: string, parsed: Parsed, filename: string, dev: boolean) {
this.source = source;
this.parsed = parsed;
this.cascade = cascade;
this.filename = filename;
this.dev = dev;
@ -356,11 +327,6 @@ export default class Stylesheet {
if (parent.type === 'Element') stack.unshift(<Element>parent);
}
if (this.cascade) {
if (stack.length === 0) this.nodesWithCssClass.add(node);
return;
}
for (let i = 0; i < this.children.length; i += 1) {
const child = this.children[i];
child.apply(node, stack);
@ -389,15 +355,15 @@ export default class Stylesheet {
if (shouldTransformSelectors) {
this.children.forEach((child: (Atrule|Rule)) => {
child.transform(code, this.id, this.keyframes, this.cascade);
child.transform(code, this.id, this.keyframes);
});
}
let c = 0;
this.children.forEach(child => {
if (this.cascade || child.isUsed(this.dev)) {
if (child.isUsed(this.dev)) {
code.remove(c, child.node.start);
child.minify(code, this.cascade, this.dev);
child.minify(code, this.dev);
c = child.node.end;
}
});
@ -421,8 +387,6 @@ export default class Stylesheet {
}
warnOnUnusedSelectors(onwarn: (warning: Warning) => void) {
if (this.cascade) return;
let locator;
const handler = (selector: Selector) => {

@ -124,7 +124,7 @@ function compile(source: string, _options: CompileOptions) {
}
stats.start('stylesheet');
const stylesheet = new Stylesheet(source, parsed, options.filename, options.cascade !== false, options.dev);
const stylesheet = new Stylesheet(source, parsed, options.filename, options.dev);
stats.stop('stylesheet');
stats.start('validate');

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1 +1 @@
div.svelte-xyz,.svelte-xyz div{color:red}
div.svelte-xyz{color:red}

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1 +0,0 @@
@keyframes svelte-xyz-why{0%{color:red}100%{color:blue}}.animated.svelte-xyz{animation:svelte-xyz-why 2s}.also-animated.svelte-xyz{animation:not-defined-here 2s}

@ -1,17 +0,0 @@
<div class='animated'>animated</div>
<div class='also-animated'>also animated</div>
<style>
@keyframes why {
0% { color: red; }
100% { color: blue; }
}
.animated {
animation: why 2s;
}
.also-animated {
animation: not-defined-here 2s;
}
</style>

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,7 +0,0 @@
<div></div>
<style>
* {
color: red;
}
</style>

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1 +0,0 @@
div.svelte-xyz{color:red}div.foo.svelte-xyz{color:blue}.foo.svelte-xyz{font-weight:bold}

@ -1,16 +0,0 @@
<div>red</div>
<div class='foo'>bold/blue</div>
<style>
div {
color: red;
}
div.foo {
color: blue;
}
.foo {
font-weight: bold;
}
</style>

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1 +1 @@
div.svelte-xyz,.svelte-xyz div{--test:10}
div.svelte-xyz{--test:10}

@ -1,6 +1,4 @@
export default {
cascade: false,
warnings: [{
filename: "SvelteComponent.html",
code: `css-unused-selector`,

@ -1 +1 @@
@keyframes svelte-xyz-why{0%{color:red}100%{color:blue}}.svelte-xyz.animated,.svelte-xyz .animated{animation:svelte-xyz-why 2s}
@keyframes svelte-xyz-why{0%{color:red}100%{color:blue}}.animated.svelte-xyz{animation:svelte-xyz-why 2s}.also-animated.svelte-xyz{animation:not-defined-here 2s}

@ -1,4 +1,5 @@
<div class='animated'>animated</div>
<div class='also-animated'>also animated</div>
<style>
@keyframes why {
@ -9,4 +10,8 @@
.animated {
animation: why 2s;
}
.also-animated {
animation: not-defined-here 2s;
}
</style>

@ -1 +1 @@
@media only screen and (min-width: 400px){div.svelte-xyz,.svelte-xyz div{color:red}}
@media only screen and (min-width: 400px){div.svelte-xyz{color:red}}

@ -1 +1 @@
@media(min-width: 400px){.svelte-xyz.large-screen,.svelte-xyz .large-screen{display:block}}
@media(min-width: 400px){.large-screen.svelte-xyz{display:block}}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
dynamic: 'x'
}

@ -1,5 +1,4 @@
export default {
cascade: false,
data: {
dynamic: 'whatever'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,6 +1,4 @@
export default {
cascade: false,
warnings: [{
code: `css-unused-selector`,
message: 'Unused CSS selector',

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
raw: '<p>raw</p>'
}

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
active: true
},

@ -1,6 +1,4 @@
export default {
cascade: false,
warnings: [{
code: `css-unused-selector`,
message: 'Unused CSS selector',

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1 +1 @@
.svelte-xyz,.svelte-xyz *{color:red}
.svelte-xyz{color:red}

@ -1 +1 @@
div.svelte-xyz,.svelte-xyz div{@apply --funky-div;}
div.svelte-xyz{@apply --funky-div;}

@ -1,6 +1,4 @@
export default {
cascade: false,
warnings: [
{
filename: "SvelteComponent.html",

@ -1,6 +1,4 @@
export default {
cascade: false,
data: {
active: true
},

@ -1,6 +1,4 @@
export default {
cascade: false,
warnings: [{
filename: "SvelteComponent.html",
code: `css-unused-selector`,

@ -1,8 +1,4 @@
export default {
compileOptions: {
cascade: false
},
data: {
x: 'bar'
},

@ -1,2 +1,2 @@
div.svelte-bzh57p,.svelte-bzh57p div{color:red}
div.svelte-4yw8vx,.svelte-4yw8vx div{color:green}
div.svelte-bzh57p{color:red}
div.svelte-4yw8vx{color:green}

@ -1 +1 @@
div.svelte-bzh57p,.svelte-bzh57p div{color:red}
div.svelte-bzh57p{color:red}

@ -30,8 +30,7 @@ describe("sourcemaps", () => {
const { js, css } = svelte.compile(input, {
filename,
outputFilename: `${outputFilename}.js`,
cssOutputFilename: `${outputFilename}.css`,
cascade: config.cascade
cssOutputFilename: `${outputFilename}.css`
});
const _code = js.code.replace(/Svelte v\d+\.\d+\.\d+/, match => match.replace(/\d/g, 'x'));

@ -1,3 +0,0 @@
export default {
cascade: false
};

@ -1,7 +0,0 @@
<p class='foo'>red</p>
<style>
.foo {
color: red;
}
</style>

@ -1,2 +0,0 @@
.foo.svelte-sg04hs{color:red}
/*# sourceMappingURL=output.css.map */

@ -1,12 +0,0 @@
{
"version": 3,
"file": "output.css",
"sources": [
"input.html"
],
"sourcesContent": [
"<p class='foo'>red</p>\n\n<style>\n\t.foo {\n\t\tcolor: red;\n\t}\n</style>"
],
"names": [],
"mappings": "AAGC,IAAI,cAAC,CAAC,AACL,KAAK,CAAE,GAAG,AACX,CAAC"
}

@ -1,17 +0,0 @@
export function test ({ assert, smcCss, locateInSource, locateInGeneratedCss }) {
const expected = locateInSource( '.foo' );
const loc = locateInGeneratedCss( '.foo' );
const actual = smcCss.originalPositionFor({
line: loc.line + 1,
column: loc.column
});
assert.deepEqual( actual, {
source: 'input.html',
name: null,
line: expected.line + 1,
column: expected.column
});
}

@ -1,2 +1,2 @@
.svelte-sg04hs.foo,.svelte-sg04hs .foo{color:red}
.foo.svelte-sg04hs{color:red}
/*# sourceMappingURL=output.css.map */

@ -8,5 +8,5 @@
"<p class='foo'>red</p>\n\n<style>\n\t.foo {\n\t\tcolor: red;\n\t}\n</style>"
],
"names": [],
"mappings": "AAGC,sCAAK,CAAC,AACL,KAAK,CAAE,GAAG,AACX,CAAC"
"mappings": "AAGC,IAAI,cAAC,CAAC,AACL,KAAK,CAAE,GAAG,AACX,CAAC"
}
Loading…
Cancel
Save