mirror of https://github.com/sveltejs/svelte
Merge 205bcfac7e
into 71daf4fc2f
commit
3dd59049ef
@ -0,0 +1,150 @@
|
||||
import { groupSelectors, isGlobalSelector, walkRules } from '../utils/css';
|
||||
import { Node } from '../interfaces';
|
||||
|
||||
export default class Selector {
|
||||
node: Node;
|
||||
blocks: Node[][];
|
||||
parts: Node[];
|
||||
used: boolean;
|
||||
|
||||
constructor(node: Node) {
|
||||
this.node = node;
|
||||
|
||||
this.blocks = groupSelectors(this.node);
|
||||
|
||||
// take trailing :global(...) selectors out of consideration
|
||||
let i = node.children.length;
|
||||
while (i > 2) {
|
||||
const last = node.children[i-1];
|
||||
const penultimate = node.children[i-2];
|
||||
|
||||
if (last.type === 'PseudoClassSelector' && last.name === 'global') {
|
||||
i -= 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.parts = node.children.slice(0, i);
|
||||
|
||||
this.used = isGlobalSelector(this.blocks[0]);
|
||||
}
|
||||
|
||||
apply(node: Node, stack: Node[]) {
|
||||
const applies = selectorAppliesTo(this.parts, node, stack.slice());
|
||||
|
||||
if (applies) {
|
||||
this.used = true;
|
||||
|
||||
// add svelte-123xyz attribute to outermost and innermost
|
||||
// elements — no need to add it to intermediate elements
|
||||
node._needsCssAttribute = true;
|
||||
if (stack[0] && this.node.children.find(isDescendantSelector)) stack[0]._needsCssAttribute = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isDescendantSelector(selector: Node) {
|
||||
return selector.type === 'WhiteSpace' || selector.type === 'Combinator';
|
||||
}
|
||||
|
||||
function selectorAppliesTo(parts: Node[], node: Node, stack: Node[]): boolean {
|
||||
let i = parts.length;
|
||||
let j = stack.length;
|
||||
|
||||
while (i--) {
|
||||
if (!node) {
|
||||
return parts.every((part: Node) => {
|
||||
return part.type === 'Combinator' || (part.type === 'PseudoClassSelector' && part.name === 'global');
|
||||
});
|
||||
}
|
||||
|
||||
const part = parts[i];
|
||||
|
||||
if (part.type === 'PseudoClassSelector' && part.name === 'global') {
|
||||
// TODO shouldn't see this here... maybe we should enforce that :global(...)
|
||||
// cannot be sandwiched between non-global selectors?
|
||||
return false;
|
||||
}
|
||||
|
||||
if (part.type === 'PseudoClassSelector' || part.type === 'PseudoElementSelector') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part.type === 'ClassSelector') {
|
||||
if (!attributeMatches(node, 'class', part.name, '~=', false)) return false;
|
||||
}
|
||||
|
||||
else if (part.type === 'IdSelector') {
|
||||
if (!attributeMatches(node, 'id', part.name, '=', false)) return false;
|
||||
}
|
||||
|
||||
else if (part.type === 'AttributeSelector') {
|
||||
if (!attributeMatches(node, part.name.name, part.value && unquote(part.value.value), part.operator, part.flags)) return false;
|
||||
}
|
||||
|
||||
else if (part.type === 'TypeSelector') {
|
||||
if (part.name === '*') return true;
|
||||
if (node.name !== part.name) return false;
|
||||
}
|
||||
|
||||
else if (part.type === 'WhiteSpace') {
|
||||
parts = parts.slice(0, i);
|
||||
|
||||
while (stack.length) {
|
||||
if (selectorAppliesTo(parts, stack.pop(), stack)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (part.type === 'Combinator') {
|
||||
if (part.name === '>') {
|
||||
return selectorAppliesTo(parts.slice(0, i), stack.pop(), stack);
|
||||
}
|
||||
|
||||
// TODO other combinators
|
||||
return true;
|
||||
}
|
||||
|
||||
else {
|
||||
// bail. TODO figure out what these could be
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const operators = {
|
||||
'=' : (value: string, flags: string) => new RegExp(`^${value}$`, flags),
|
||||
'~=': (value: string, flags: string) => new RegExp(`\\b${value}\\b`, flags),
|
||||
'|=': (value: string, flags: string) => new RegExp(`^${value}(-.+)?$`, flags),
|
||||
'^=': (value: string, flags: string) => new RegExp(`^${value}`, flags),
|
||||
'$=': (value: string, flags: string) => new RegExp(`${value}$`, flags),
|
||||
'*=': (value: string, flags: string) => new RegExp(value, flags)
|
||||
};
|
||||
|
||||
function attributeMatches(node: Node, name: string, expectedValue: string, operator: string, caseInsensitive: boolean) {
|
||||
const attr = node.attributes.find((attr: Node) => attr.name === name);
|
||||
if (!attr) return false;
|
||||
if (attr.value === true) return operator === null;
|
||||
if (isDynamic(attr.value)) return true;
|
||||
|
||||
const actualValue = attr.value[0].data;
|
||||
|
||||
const pattern = operators[operator](expectedValue, caseInsensitive ? 'i' : '');
|
||||
return pattern.test(actualValue);
|
||||
}
|
||||
|
||||
function isDynamic(value: Node) {
|
||||
return value.length > 1 || value[0].type !== 'Text';
|
||||
}
|
||||
|
||||
function unquote(str: string) {
|
||||
if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
|
||||
return str.slice(1, str.length - 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
import { SsrGenerator } from './index';
|
||||
import { Node } from '../../interfaces';
|
||||
|
||||
function noop () {}
|
||||
|
||||
function isElseIf(node: Node) {
|
||||
return (
|
||||
node && node.children.length === 1 && node.children[0].type === 'IfBlock'
|
||||
);
|
||||
}
|
||||
|
||||
const preprocessors = {
|
||||
MustacheTag: noop,
|
||||
RawMustacheTag: noop,
|
||||
Text: noop,
|
||||
|
||||
IfBlock: (
|
||||
generator: SsrGenerator,
|
||||
node: Node,
|
||||
elementStack: Node[]
|
||||
) => {
|
||||
function attachBlocks(node: Node) {
|
||||
preprocessChildren(generator, node, elementStack);
|
||||
|
||||
if (isElseIf(node.else)) {
|
||||
attachBlocks(node.else.children[0]);
|
||||
} else if (node.else) {
|
||||
preprocessChildren(
|
||||
generator,
|
||||
node.else,
|
||||
elementStack
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
attachBlocks(node);
|
||||
},
|
||||
|
||||
EachBlock: (
|
||||
generator: SsrGenerator,
|
||||
node: Node,
|
||||
elementStack: Node[]
|
||||
) => {
|
||||
preprocessChildren(generator, node, elementStack);
|
||||
|
||||
if (node.else) {
|
||||
preprocessChildren(
|
||||
generator,
|
||||
node.else,
|
||||
elementStack
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Element: (
|
||||
generator: SsrGenerator,
|
||||
node: Node,
|
||||
elementStack: Node[]
|
||||
) => {
|
||||
const isComponent =
|
||||
generator.components.has(node.name) || node.name === ':Self';
|
||||
|
||||
if (!isComponent) {
|
||||
generator.applyCss(node, elementStack);
|
||||
}
|
||||
|
||||
if (node.children.length) {
|
||||
if (isComponent) {
|
||||
preprocessChildren(generator, node, elementStack);
|
||||
} else {
|
||||
preprocessChildren(generator, node, elementStack.concat(node));
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function preprocessChildren(
|
||||
generator: SsrGenerator,
|
||||
node: Node,
|
||||
elementStack: Node[]
|
||||
) {
|
||||
node.children.forEach((child: Node, i: number) => {
|
||||
const preprocessor = preprocessors[child.type];
|
||||
if (preprocessor) preprocessor(generator, child, elementStack);
|
||||
});
|
||||
}
|
||||
|
||||
export default function preprocess(generator: SsrGenerator, html: Node) {
|
||||
preprocessChildren(generator, html, []);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
import { Node } from '../interfaces';
|
||||
|
||||
export function isGlobalSelector(block: Node[]) {
|
||||
return block.length === 1 && block[0].type === 'PseudoClassSelector' && block[0].name === 'global';
|
||||
}
|
||||
|
||||
export function groupSelectors(selector: Node) {
|
||||
let block: Node[] = [];
|
||||
const blocks: Node[][] = [block];
|
||||
|
||||
selector.children.forEach((child: Node) => {
|
||||
if (child.type === 'WhiteSpace' || child.type === 'Combinator') {
|
||||
block = [];
|
||||
blocks.push(block);
|
||||
} else {
|
||||
block.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
export function walkRules(nodes: Node[], callback: (node: Node) => void) {
|
||||
nodes.forEach((node: Node) => {
|
||||
if (node.type === 'Rule') {
|
||||
callback(node);
|
||||
} else if (node.type === 'Atrule') {
|
||||
if (node.name === 'media' || node.name === 'supports' || node.name === 'document') {
|
||||
walkRules(node.block.children, callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import { groupSelectors, isGlobalSelector, walkRules } from '../../utils/css';
|
||||
import { Validator } from '../index';
|
||||
import { Node } from '../../interfaces';
|
||||
|
||||
export default function validateCss(validator: Validator, css: Node) {
|
||||
walkRules(css.children, rule => {
|
||||
rule.selector.children.forEach(validateSelector);
|
||||
});
|
||||
|
||||
function validateSelector(selector: Node) {
|
||||
const blocks: Node[][] = groupSelectors(selector);
|
||||
|
||||
blocks.forEach((block, i) => {
|
||||
if (block.find((part: Node) => part.type === 'PseudoClassSelector' && part.name === 'global')) {
|
||||
// check that :global(...) is by itself
|
||||
if (block.length !== 1) {
|
||||
validator.error(`:global(...) cannot be mixed with non-global selectors`, block[0].start);
|
||||
}
|
||||
|
||||
// check that :global(...) isn't sandwiched by other selectors
|
||||
// if (i > 0 && i < blocks.length - 1) {
|
||||
// validator.error(`:global(...) can be at the start or end of a selector sequence, but not in the middle`, block[0].start);
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
let start = 0;
|
||||
let end = blocks.length;
|
||||
|
||||
for (; start < end; start += 1) {
|
||||
if (!isGlobalSelector(blocks[start])) break;
|
||||
}
|
||||
|
||||
for (; end > start; end -= 1) {
|
||||
if (!isGlobalSelector(blocks[end - 1])) break;
|
||||
}
|
||||
|
||||
for (let i = start; i < end; i += 1) {
|
||||
if (isGlobalSelector(blocks[i])) {
|
||||
validator.error(`:global(...) can be at the start or end of a selector sequence, but not in the middle`, blocks[i][0].start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[svelte-2950902288] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div svelte-2950902288=""></div>
|
@ -0,0 +1,7 @@
|
||||
<div></div>
|
||||
|
||||
<style>
|
||||
* {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo*='bar'][svelte-4224841812] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-4224841812="" data-foo="foobarbaz">this is styled</p>
|
||||
<p data-foo="fooBARbaz">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='foobarbaz'>this is styled</p>
|
||||
<p data-foo='fooBARbaz'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo*='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo='bar' i][svelte-4191913977] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-4191913977="" data-foo="BAR">this is styled</p>
|
||||
<p data-foo="BAZ">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='BAR'>this is styled</p>
|
||||
<p data-foo='BAZ'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo='bar' i] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
data: {
|
||||
dynamic: 'whatever'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo='bar'][svelte-1339732946] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-1339732946="" data-foo="whatever">this is styled</p>
|
||||
<p data-foo="baz">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='{{dynamic}}'>this is styled</p>
|
||||
<p data-foo='baz'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo='bar'][svelte-2543760126] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-2543760126="" data-foo="bar">this is styled</p>
|
||||
<p data-foo="baz">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='bar'>this is styled</p>
|
||||
<p data-foo='baz'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo|='bar'][svelte-1225676040] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<div><p svelte-1225676040="" data-foo="bar">this is styled</p>
|
||||
<p svelte-1225676040="" data-foo="bar-baz">this is styled</p>
|
||||
<p data-foo="baz-bar">this is unstyled</p></div>
|
@ -0,0 +1,11 @@
|
||||
<div>
|
||||
<p data-foo='bar'>this is styled</p>
|
||||
<p data-foo='bar-baz'>this is styled</p>
|
||||
<p data-foo='baz-bar'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo|='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo^='bar'][svelte-3106767242] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-3106767242="" data-foo="barbaz">this is styled</p>
|
||||
<p data-foo="bazbar">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='barbaz'>this is styled</p>
|
||||
<p data-foo='bazbar'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo^='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo$='bar'][svelte-207782622] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p data-foo="barbaz">this is unstyled</p>
|
||||
<p svelte-207782622="" data-foo="bazbar">this is styled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='barbaz'>this is unstyled</p>
|
||||
<p data-foo='bazbar'>this is styled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo$='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[data-foo~='bar'][svelte-1786044856] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><p svelte-1786044856="" data-foo="qux bar">this is styled</p>
|
||||
<p data-foo="qux baz">this is unstyled</p></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<p data-foo='qux bar'>this is styled</p>
|
||||
<p data-foo='qux baz'>this is unstyled</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[data-foo~='bar'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
[autoplay][svelte-240005720] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div><video svelte-240005720 autoplay></video>
|
||||
<video></video></div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
<video autoplay></video>
|
||||
<video></video>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[autoplay] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
.foo[svelte-2643270928] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<p svelte-2643270928="" class="whatever">this is styled</p>
|
||||
<p class="bar">this is unstyled</p>
|
@ -0,0 +1,18 @@
|
||||
<p class='{{unknown}}'>this is styled</p>
|
||||
<p class='bar'>this is unstyled</p>
|
||||
|
||||
<style>
|
||||
.foo {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
unknown: 'whatever'
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
.foo[svelte-633959357] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<p svelte-633959357="" class="foo">this is styled</p>
|
||||
<p class="bar">this is unstyled</p>
|
@ -0,0 +1,8 @@
|
||||
<p class='foo'>this is styled</p>
|
||||
<p class='bar'>this is unstyled</p>
|
||||
|
||||
<style>
|
||||
.foo {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
.foo[svelte-2122726581] .bar {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div svelte-2122726581="" class="foo"></div>
|
@ -0,0 +1,9 @@
|
||||
<div class='foo'>
|
||||
<!-- html injected somehow -->
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.foo :global(.bar) {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div[svelte-3386191472] > p > em {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div svelte-3386191472=""></div>
|
@ -0,0 +1,9 @@
|
||||
<div>
|
||||
<!-- html injected somehow -->
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div > :global(p) > :global(em) {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div[svelte-3744486606] > p {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div svelte-3744486606=""></div>
|
@ -0,0 +1,9 @@
|
||||
<div>
|
||||
<!-- html injected somehow -->
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div > :global(p) {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div > section > p[svelte-3390623146] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<p svelte-3390623146="">this may or may not be styled</p>
|
@ -0,0 +1,7 @@
|
||||
<p>this may or may not be styled</p>
|
||||
|
||||
<style>
|
||||
:global(div) > :global(section) > p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div > p[svelte-794545435] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<p svelte-794545435="">this may or may not be styled</p>
|
@ -0,0 +1,7 @@
|
||||
<p>this may or may not be styled</p>
|
||||
|
||||
<style>
|
||||
:global(div) > p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,19 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
warnings: [{
|
||||
message: 'Unused CSS selector',
|
||||
loc: {
|
||||
line: 8,
|
||||
column: 1
|
||||
},
|
||||
pos: 74,
|
||||
frame: `
|
||||
6:
|
||||
7: <style>
|
||||
8: div > p {
|
||||
^
|
||||
9: color: red;
|
||||
10: }`
|
||||
}]
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div[svelte-2557028325] > p[svelte-2557028325] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div><section><p>this is not styled</p></section></div>
|
@ -0,0 +1,11 @@
|
||||
<div>
|
||||
<section>
|
||||
<p>this is not styled</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div > p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cascade: false,
|
||||
|
||||
data: {
|
||||
raw: '<p>raw</p>'
|
||||
}
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div></div>
|
@ -0,0 +1,7 @@
|
||||
<div></div>
|
||||
|
||||
<style>
|
||||
:global(div) {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
#foo[svelte-2727164615] {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<div svelte-2727164615="" id="foo"></div>
|
||||
<div id="bar"></div>
|
@ -0,0 +1,8 @@
|
||||
<div id='foo'></div>
|
||||
<div id='bar'></div>
|
||||
|
||||
<style>
|
||||
#foo {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
cascade: false
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
|
||||
div[svelte-4032668709] section p[svelte-4032668709] {
|
||||
color: red;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue