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); 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 c = this.node.start;
let started = false; let started = false;
this.selectors.forEach((selector, i) => { this.selectors.forEach((selector, i) => {
if (cascade || selector.used) { if (selector.used) {
const separator = started ? ',' : ''; const separator = started ? ',' : '';
if ((selector.node.start - c) > separator.length) { if ((selector.node.start - c) > separator.length) {
code.overwrite(c, selector.node.start, separator); code.overwrite(c, selector.node.start, separator);
} }
if (!cascade) selector.minify(code); selector.minify(code);
c = selector.node.end; c = selector.node.end;
started = true; started = true;
@ -66,39 +66,12 @@ class Rule {
code.remove(c, this.node.block.end - 1); 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; if (this.parent && this.parent.node.type === 'Atrule' && this.parent.node.name === 'keyframes') return true;
const attr = `.${id}`; const attr = `.${id}`;
if (cascade) { this.selectors.forEach(selector => selector.transform(code, attr));
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.declarations.forEach(declaration => declaration.transform(code, keyframes)); this.declarations.forEach(declaration => declaration.transform(code, keyframes));
} }
@ -182,7 +155,7 @@ class Atrule {
return true; // TODO return true; // TODO
} }
minify(code: MagicString, cascade: boolean, dev: boolean) { minify(code: MagicString, dev: boolean) {
if (this.node.name === 'media') { if (this.node.name === 'media') {
const expressionChar = code.original[this.node.expression.start]; const expressionChar = code.original[this.node.expression.start];
let c = this.node.start + (expressionChar === '(' ? 6 : 7); let c = this.node.start + (expressionChar === '(' ? 6 : 7);
@ -215,9 +188,9 @@ class Atrule {
let c = this.node.block.start + 1; let c = this.node.block.start + 1;
this.children.forEach(child => { this.children.forEach(child => {
if (cascade || child.isUsed(dev)) { if (child.isUsed(dev)) {
code.remove(c, child.node.start); code.remove(c, child.node.start);
child.minify(code, cascade, dev); child.minify(code, dev);
c = child.node.end; 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') { if (this.node.name === 'keyframes') {
this.node.expression.children.forEach(({ type, name, start, end }: Node) => { this.node.expression.children.forEach(({ type, name, start, end }: Node) => {
if (type === 'Identifier') { if (type === 'Identifier') {
@ -240,7 +213,7 @@ class Atrule {
} }
this.children.forEach(child => { 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 { export default class Stylesheet {
source: string; source: string;
parsed: Parsed; parsed: Parsed;
cascade: boolean;
filename: string; filename: string;
dev: boolean; dev: boolean;
@ -276,10 +248,9 @@ export default class Stylesheet {
nodesWithCssClass: Set<Node>; 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.source = source;
this.parsed = parsed; this.parsed = parsed;
this.cascade = cascade;
this.filename = filename; this.filename = filename;
this.dev = dev; this.dev = dev;
@ -356,11 +327,6 @@ export default class Stylesheet {
if (parent.type === 'Element') stack.unshift(<Element>parent); 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) { for (let i = 0; i < this.children.length; i += 1) {
const child = this.children[i]; const child = this.children[i];
child.apply(node, stack); child.apply(node, stack);
@ -389,15 +355,15 @@ export default class Stylesheet {
if (shouldTransformSelectors) { if (shouldTransformSelectors) {
this.children.forEach((child: (Atrule|Rule)) => { 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; let c = 0;
this.children.forEach(child => { this.children.forEach(child => {
if (this.cascade || child.isUsed(this.dev)) { if (child.isUsed(this.dev)) {
code.remove(c, child.node.start); code.remove(c, child.node.start);
child.minify(code, this.cascade, this.dev); child.minify(code, this.dev);
c = child.node.end; c = child.node.end;
} }
}); });
@ -421,8 +387,6 @@ export default class Stylesheet {
} }
warnOnUnusedSelectors(onwarn: (warning: Warning) => void) { warnOnUnusedSelectors(onwarn: (warning: Warning) => void) {
if (this.cascade) return;
let locator; let locator;
const handler = (selector: Selector) => { const handler = (selector: Selector) => {

@ -124,7 +124,7 @@ function compile(source: string, _options: CompileOptions) {
} }
stats.start('stylesheet'); 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.stop('stylesheet');
stats.start('validate'); 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 { export default {
cascade: false,
warnings: [{ warnings: [{
filename: "SvelteComponent.html", filename: "SvelteComponent.html",
code: `css-unused-selector`, code: `css-unused-selector`,

@ -1,4 +1,3 @@
export default { export default {
cascade: false,
dev: true dev: true
}; };

@ -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='animated'>animated</div>
<div class='also-animated'>also animated</div>
<style> <style>
@keyframes why { @keyframes why {
@ -9,4 +10,8 @@
.animated { .animated {
animation: why 2s; animation: why 2s;
} }
.also-animated {
animation: not-defined-here 2s;
}
</style> </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 { export default {
cascade: false,
data: { data: {
dynamic: 'x' dynamic: 'x'
} }

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

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

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

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

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

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

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

@ -1,6 +1,4 @@
export default { export default {
cascade: false,
data: { data: {
raw: '<p>raw</p>' 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 { export default {
cascade: false,
data: { data: {
active: true active: true
}, },

@ -1,6 +1,4 @@
export default { export default {
cascade: false,
warnings: [{ warnings: [{
code: `css-unused-selector`, code: `css-unused-selector`,
message: 'Unused CSS 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 { export default {
cascade: false,
warnings: [ warnings: [
{ {
filename: "SvelteComponent.html", filename: "SvelteComponent.html",

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

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

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

@ -1,2 +1,2 @@
div.svelte-bzh57p,.svelte-bzh57p div{color:red} div.svelte-bzh57p{color:red}
div.svelte-4yw8vx,.svelte-4yw8vx div{color:green} 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, { const { js, css } = svelte.compile(input, {
filename, filename,
outputFilename: `${outputFilename}.js`, outputFilename: `${outputFilename}.js`,
cssOutputFilename: `${outputFilename}.css`, cssOutputFilename: `${outputFilename}.css`
cascade: config.cascade
}); });
const _code = js.code.replace(/Svelte v\d+\.\d+\.\d+/, match => match.replace(/\d/g, 'x')); 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 */ /*# 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>" "<p class='foo'>red</p>\n\n<style>\n\t.foo {\n\t\tcolor: red;\n\t}\n</style>"
], ],
"names": [], "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