|
|
|
@ -175,7 +175,13 @@ function apply_selector(relative_selectors, rule, element, stylesheet) {
|
|
|
|
|
let sibling_matched = false;
|
|
|
|
|
|
|
|
|
|
for (const possible_sibling of siblings.keys()) {
|
|
|
|
|
if (apply_selector(parent_selectors, rule, possible_sibling, stylesheet)) {
|
|
|
|
|
if (possible_sibling.type === 'RenderTag' || possible_sibling.type === 'SlotElement') {
|
|
|
|
|
// `{@render foo()}<p>foo</p>` with `:global(.x) + p` is a match
|
|
|
|
|
if (parent_selectors.length === 1 && parent_selectors[0].metadata.is_global) {
|
|
|
|
|
mark(relative_selector, element);
|
|
|
|
|
sibling_matched = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (apply_selector(parent_selectors, rule, possible_sibling, stylesheet)) {
|
|
|
|
|
mark(relative_selector, element);
|
|
|
|
|
sibling_matched = true;
|
|
|
|
|
}
|
|
|
|
@ -564,38 +570,39 @@ function get_element_parent(node) {
|
|
|
|
|
function find_previous_sibling(node) {
|
|
|
|
|
/** @type {import('#compiler').SvelteNode} */
|
|
|
|
|
let current_node = node;
|
|
|
|
|
do {
|
|
|
|
|
if (current_node.type === 'SlotElement') {
|
|
|
|
|
const slot_children = current_node.fragment.nodes;
|
|
|
|
|
if (slot_children.length > 0) {
|
|
|
|
|
current_node = slot_children.slice(-1)[0]; // go to its last child first
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
!current_node.prev &&
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
current_node.parent &&
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
current_node.parent.type === 'SlotElement'
|
|
|
|
|
) {
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
current_node = current_node.parent;
|
|
|
|
|
|
|
|
|
|
while (
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
!current_node.prev &&
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
current_node.parent?.type === 'SlotElement'
|
|
|
|
|
) {
|
|
|
|
|
// @ts-expect-error TODO
|
|
|
|
|
current_node = current_node.parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
current_node = current_node.prev;
|
|
|
|
|
|
|
|
|
|
while (current_node?.type === 'SlotElement') {
|
|
|
|
|
const slot_children = current_node.fragment.nodes;
|
|
|
|
|
if (slot_children.length > 0) {
|
|
|
|
|
current_node = slot_children.slice(-1)[0];
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
current_node = current_node.prev;
|
|
|
|
|
} while (current_node && current_node.type === 'SlotElement');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return current_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {import('#compiler').SvelteNode} node
|
|
|
|
|
* @param {boolean} adjacent_only
|
|
|
|
|
* @returns {Map<import('#compiler').RegularElement, NodeExistsValue>}
|
|
|
|
|
* @returns {Map<import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').SlotElement | import('#compiler').RenderTag, NodeExistsValue>}
|
|
|
|
|
*/
|
|
|
|
|
function get_possible_element_siblings(node, adjacent_only) {
|
|
|
|
|
/** @type {Map<import('#compiler').RegularElement, NodeExistsValue>} */
|
|
|
|
|
/** @type {Map<import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').SlotElement | import('#compiler').RenderTag, NodeExistsValue>} */
|
|
|
|
|
const result = new Map();
|
|
|
|
|
|
|
|
|
|
/** @type {import('#compiler').SvelteNode} */
|
|
|
|
@ -618,6 +625,14 @@ function get_possible_element_siblings(node, adjacent_only) {
|
|
|
|
|
if (adjacent_only && has_definite_elements(possible_last_child)) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
} else if (
|
|
|
|
|
prev.type === 'SlotElement' ||
|
|
|
|
|
prev.type === 'RenderTag' ||
|
|
|
|
|
prev.type === 'SvelteElement'
|
|
|
|
|
) {
|
|
|
|
|
result.set(prev, NODE_PROBABLY_EXISTS);
|
|
|
|
|
// Special case: slots, render tags and svelte:element tags could resolve to no siblings,
|
|
|
|
|
// so we want to continue until we find a definite sibling even with the adjacent-only combinator
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -720,7 +735,7 @@ function get_possible_last_child(relative_selector, adjacent_only) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {Map<import('#compiler').RegularElement, NodeExistsValue>} result
|
|
|
|
|
* @param {Map<unknown, NodeExistsValue>} result
|
|
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
|
|
|
|
function has_definite_elements(result) {
|
|
|
|
@ -734,8 +749,9 @@ function has_definite_elements(result) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {Map<import('#compiler').RegularElement, NodeExistsValue>} from
|
|
|
|
|
* @param {Map<import('#compiler').RegularElement, NodeExistsValue>} to
|
|
|
|
|
* @template T
|
|
|
|
|
* @param {Map<T, NodeExistsValue>} from
|
|
|
|
|
* @param {Map<T, NodeExistsValue>} to
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
function add_to_map(from, to) {
|
|
|
|
|