diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index c2ad450416..705e341601 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -470,10 +470,52 @@ function get_element_parent(node: Element): Element | null { return parent as Element | null; } +/** + * Finds the given node's previous sibling in the DOM + * + * Unless the component is a custom element (web component), which in this + * case, the element is actually real, the Svelte is just a + * placeholder and is not actually real. Any children nodes in + * are 'flattened' and considered as the same level as the 's siblings + * + * e.g. + *

Heading 1

+ * + *

Heading 2

+ *
+ * + * is considered to look like: + *

Heading 1

+ *

Heading 2

+ */ +function find_previous_sibling(node: INode): INode { + if (node.component.compile_options.customElement) { + return node.prev; + } + + let current_node: INode = node; + do { + if (current_node.type === 'Slot') { + const slot_children = current_node.children; + if (slot_children.length > 0) { + current_node = slot_children.slice(-1)[0]; // go to its last child first + continue; + } + } + + while (!current_node.prev && current_node.parent && current_node.parent.type === 'Slot') { + current_node = current_node.parent; + } + current_node = current_node.prev; + } while (current_node && current_node.type === 'Slot'); + + return current_node; +} + function get_possible_element_siblings(node: INode, adjacent_only: boolean): Map { const result: Map = new Map(); let prev: INode = node; - while (prev = prev.prev) { + while (prev = find_previous_sibling(prev)) { if (prev.type === 'Element') { if (!prev.attributes.find(attr => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot')) { result.set(prev, NodeExist.Definitely); diff --git a/src/compiler/compile/nodes/Slot.ts b/src/compiler/compile/nodes/Slot.ts index 9a0b1ea815..8dfcc09c03 100644 --- a/src/compiler/compile/nodes/Slot.ts +++ b/src/compiler/compile/nodes/Slot.ts @@ -7,7 +7,8 @@ import { TemplateNode } from '../../interfaces'; import compiler_errors from '../compiler_errors'; export default class Slot extends Element { - type: 'Element'; + // @ts-ignore Slot elements have the 'Slot' type, but TypeScript doesn't allow us to have 'Slot' when it extends Element + type: 'Slot'; name: string; children: INode[]; slot_name: string; diff --git a/test/css/samples/general-siblings-combinator-former-element-in-slot/expected.css b/test/css/samples/general-siblings-combinator-former-element-in-slot/expected.css new file mode 100644 index 0000000000..f365e3dc24 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-former-element-in-slot/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz~p.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-former-element-in-slot/input.svelte b/test/css/samples/general-siblings-combinator-former-element-in-slot/input.svelte new file mode 100644 index 0000000000..66a8a09796 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-former-element-in-slot/input.svelte @@ -0,0 +1,12 @@ + +

Heading 1

+
+Span 1 +Span 2 +

Paragraph 2

+ + diff --git a/test/css/samples/general-siblings-combinator-nested-slots-flattened/expected.css b/test/css/samples/general-siblings-combinator-nested-slots-flattened/expected.css new file mode 100644 index 0000000000..f365e3dc24 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-nested-slots-flattened/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz~p.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-nested-slots-flattened/input.svelte b/test/css/samples/general-siblings-combinator-nested-slots-flattened/input.svelte new file mode 100644 index 0000000000..0d521b8385 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-nested-slots-flattened/input.svelte @@ -0,0 +1,7 @@ +

Heading 1

Span 1Span 2

Paragraph 2

+ + diff --git a/test/css/samples/general-siblings-combinator-nested-slots/expected.css b/test/css/samples/general-siblings-combinator-nested-slots/expected.css new file mode 100644 index 0000000000..f365e3dc24 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-nested-slots/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz~p.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-nested-slots/input.svelte b/test/css/samples/general-siblings-combinator-nested-slots/input.svelte new file mode 100644 index 0000000000..d820705782 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-nested-slots/input.svelte @@ -0,0 +1,18 @@ + + +

Heading 1

+
+
+Span 1 +Span 2 + + +

Paragraph 2

+
+
+ + diff --git a/test/css/samples/general-siblings-combinator-selects-slot-fallback/expected.css b/test/css/samples/general-siblings-combinator-selects-slot-fallback/expected.css new file mode 100644 index 0000000000..f365e3dc24 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-selects-slot-fallback/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz~p.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-selects-slot-fallback/input.svelte b/test/css/samples/general-siblings-combinator-selects-slot-fallback/input.svelte new file mode 100644 index 0000000000..61d829d257 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-selects-slot-fallback/input.svelte @@ -0,0 +1,12 @@ +

Heading 1

+Span 1 +Span 2 + +

Paragraph 2

+
+ + diff --git a/test/css/samples/general-siblings-combinator-slots-between/expected.css b/test/css/samples/general-siblings-combinator-slots-between/expected.css new file mode 100644 index 0000000000..b6edba4ef7 --- /dev/null +++ b/test/css/samples/general-siblings-combinator-slots-between/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz~span.svelte-xyz{color:green}h1.svelte-xyz~p.svelte-xyz{color:red}span.svelte-xyz~p.svelte-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/general-siblings-combinator-slots-between/input.svelte b/test/css/samples/general-siblings-combinator-slots-between/input.svelte new file mode 100644 index 0000000000..8b80b4de3e --- /dev/null +++ b/test/css/samples/general-siblings-combinator-slots-between/input.svelte @@ -0,0 +1,22 @@ +

Heading 1

+ + Span 1 + + + Span 2 + +

Paragraph 2

+ + diff --git a/test/css/samples/siblings-combinator-former-element-in-slot/expected.css b/test/css/samples/siblings-combinator-former-element-in-slot/expected.css new file mode 100644 index 0000000000..d523f1d533 --- /dev/null +++ b/test/css/samples/siblings-combinator-former-element-in-slot/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz+span.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-former-element-in-slot/input.svelte b/test/css/samples/siblings-combinator-former-element-in-slot/input.svelte new file mode 100644 index 0000000000..8cbf9bd709 --- /dev/null +++ b/test/css/samples/siblings-combinator-former-element-in-slot/input.svelte @@ -0,0 +1,10 @@ + +

test

+
+Hello + + diff --git a/test/css/samples/siblings-combinator-nested-slots-flattened/expected.css b/test/css/samples/siblings-combinator-nested-slots-flattened/expected.css new file mode 100644 index 0000000000..d523f1d533 --- /dev/null +++ b/test/css/samples/siblings-combinator-nested-slots-flattened/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz+span.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-nested-slots-flattened/input.svelte b/test/css/samples/siblings-combinator-nested-slots-flattened/input.svelte new file mode 100644 index 0000000000..475aa85426 --- /dev/null +++ b/test/css/samples/siblings-combinator-nested-slots-flattened/input.svelte @@ -0,0 +1,7 @@ +

test

Hello + + diff --git a/test/css/samples/siblings-combinator-nested-slots/expected.css b/test/css/samples/siblings-combinator-nested-slots/expected.css new file mode 100644 index 0000000000..d523f1d533 --- /dev/null +++ b/test/css/samples/siblings-combinator-nested-slots/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz+span.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-nested-slots/input.svelte b/test/css/samples/siblings-combinator-nested-slots/input.svelte new file mode 100644 index 0000000000..cb8cbbbe08 --- /dev/null +++ b/test/css/samples/siblings-combinator-nested-slots/input.svelte @@ -0,0 +1,18 @@ + + + +

test

+
+
+
+ + + Hello + + + + diff --git a/test/css/samples/siblings-combinator-selects-slot-fallback/expected.css b/test/css/samples/siblings-combinator-selects-slot-fallback/expected.css new file mode 100644 index 0000000000..d523f1d533 --- /dev/null +++ b/test/css/samples/siblings-combinator-selects-slot-fallback/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz+span.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-selects-slot-fallback/input.svelte b/test/css/samples/siblings-combinator-selects-slot-fallback/input.svelte new file mode 100644 index 0000000000..7fa02c8305 --- /dev/null +++ b/test/css/samples/siblings-combinator-selects-slot-fallback/input.svelte @@ -0,0 +1,10 @@ +

test

+ + Hello + + + diff --git a/test/css/samples/siblings-combinator-slots-between/expected.css b/test/css/samples/siblings-combinator-slots-between/expected.css new file mode 100644 index 0000000000..d523f1d533 --- /dev/null +++ b/test/css/samples/siblings-combinator-slots-between/expected.css @@ -0,0 +1 @@ +h1.svelte-xyz+span.svelte-xyz{color:red} \ No newline at end of file diff --git a/test/css/samples/siblings-combinator-slots-between/input.svelte b/test/css/samples/siblings-combinator-slots-between/input.svelte new file mode 100644 index 0000000000..36219534fe --- /dev/null +++ b/test/css/samples/siblings-combinator-slots-between/input.svelte @@ -0,0 +1,11 @@ +

test

+ + + +Hello + + diff --git a/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/_config.js b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/_config.js new file mode 100644 index 0000000000..6fc797bfd8 --- /dev/null +++ b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/_config.js @@ -0,0 +1,3 @@ +export default { + customElement: true +}; diff --git a/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte new file mode 100644 index 0000000000..ffaeb2c097 --- /dev/null +++ b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte @@ -0,0 +1,20 @@ + + +

Heading 1

+Span 1 +Span 2 + +

Paragraph 2

+
+ + diff --git a/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json new file mode 100644 index 0000000000..0336660caf --- /dev/null +++ b/test/validator/samples/general-siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json @@ -0,0 +1,14 @@ +[ + { + "code": "css-unused-selector", + "message": "Unused CSS selector \"h1 ~ p\"", + "start": { + "column": 1, + "line": 12 + }, + "end": { + "column": 7, + "line": 12 + } + } +] \ No newline at end of file diff --git a/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/_config.js b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/_config.js new file mode 100644 index 0000000000..6fc797bfd8 --- /dev/null +++ b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/_config.js @@ -0,0 +1,3 @@ +export default { + customElement: true +}; diff --git a/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte new file mode 100644 index 0000000000..1d98415321 --- /dev/null +++ b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/input.svelte @@ -0,0 +1,18 @@ + + +

test

+ + Hello + + + diff --git a/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json new file mode 100644 index 0000000000..3ef66ebf60 --- /dev/null +++ b/test/validator/samples/siblings-combinator-in-custom-element-selects-slot-fallback/warnings.json @@ -0,0 +1,14 @@ +[ + { + "code": "css-unused-selector", + "end": { + "column": 11, + "line": 10 + }, + "message": "Unused CSS selector \"h1 + span\"", + "start": { + "column": 2, + "line": 10 + } + } +] \ No newline at end of file