Home / Function/ css_visitors.ComplexSelector() — svelte Function Reference

css_visitors.ComplexSelector() — svelte Function Reference

Architecture documentation for the css_visitors.ComplexSelector() function in css-analyze.js from the svelte codebase.

Entity Profile

Dependency Diagram

graph TD
  55b36178_0781_8a80_d86c_236d22b0d74f["css_visitors.ComplexSelector()"]
  ca006f7f_f554_f529_8a19_abaaa45dda8d["css-analyze.js"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|defined in| ca006f7f_f554_f529_8a19_abaaa45dda8d
  e2db59a2_0726_438f_986c_0aa15cc9e5be["css_global_block_invalid_placement()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| e2db59a2_0726_438f_986c_0aa15cc9e5be
  e9b067fe_6d2b_e8a5_4273_6c0120e67111["is_global()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| e9b067fe_6d2b_e8a5_4273_6c0120e67111
  e99d98d7_9bb9_4a9c_ddd1_924ec53748de["css_global_invalid_placement()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| e99d98d7_9bb9_4a9c_ddd1_924ec53748de
  d3b5e1a6_5b28_efc4_4b56_ee6b66cb3730["css_global_invalid_selector_list()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| d3b5e1a6_5b28_efc4_4b56_ee6b66cb3730
  e559babf_3dcf_f719_0c8f_bcb1d1c78246["css_type_selector_invalid_placement()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| e559babf_3dcf_f719_0c8f_bcb1d1c78246
  4706864f_0d58_8beb_2e1c_9e1c41c5fb6f["css_global_invalid_selector()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| 4706864f_0d58_8beb_2e1c_9e1c41c5fb6f
  de2c7a90_dcc5_7509_ecb3_b33884f394c9["is_unscoped_pseudo_class()"]
  55b36178_0781_8a80_d86c_236d22b0d74f -->|calls| de2c7a90_dcc5_7509_ecb3_b33884f394c9
  style 55b36178_0781_8a80_d86c_236d22b0d74f fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js lines 64–141

	ComplexSelector(node, context) {
		context.next(); // analyse relevant selectors first

		{
			const global = node.children.find(is_global);

			if (global) {
				const is_nested = context.path.at(-2)?.type === 'PseudoClassSelector';
				if (is_nested && !global.selectors[0].args) {
					e.css_global_block_invalid_placement(global.selectors[0]);
				}

				const idx = node.children.indexOf(global);
				if (global.selectors[0].args !== null && idx !== 0 && idx !== node.children.length - 1) {
					// ensure `:global(...)` is not used in the middle of a selector (but multiple `global(...)` in sequence are ok)
					for (let i = idx + 1; i < node.children.length; i++) {
						if (!is_global(node.children[i])) {
							e.css_global_invalid_placement(global.selectors[0]);
						}
					}
				}
			}
		}

		// ensure `:global(...)` do not lead to invalid css after `:global()` is removed
		for (const relative_selector of node.children) {
			for (let i = 0; i < relative_selector.selectors.length; i++) {
				const selector = relative_selector.selectors[i];

				if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
					const child = selector.args?.children[0].children[0];
					// ensure `:global(element)` to be at the first position in a compound selector
					if (child?.selectors[0].type === 'TypeSelector' && i !== 0) {
						e.css_global_invalid_selector_list(selector);
					}

					// ensure `:global(.class)` is not followed by a type selector, eg: `:global(.class)element`
					if (relative_selector.selectors[i + 1]?.type === 'TypeSelector') {
						e.css_type_selector_invalid_placement(relative_selector.selectors[i + 1]);
					}

					// ensure `:global(...)`contains a single selector
					// (standalone :global() with multiple selectors is OK)
					if (
						selector.args !== null &&
						selector.args.children.length > 1 &&
						(node.children.length > 1 || relative_selector.selectors.length > 1)
					) {
						e.css_global_invalid_selector(selector);
					}
				}
			}
		}

		node.metadata.rule = context.state.rule;

		node.metadata.is_global = node.children.every(
			({ metadata }) => metadata.is_global || metadata.is_global_like
		);

		node.metadata.used ||= node.metadata.is_global;

		if (
			node.metadata.rule?.metadata.parent_rule &&
			node.children[0]?.selectors[0]?.type === 'NestingSelector'
		) {
			const first = node.children[0]?.selectors[1];
			const no_nesting_scope =
				first?.type !== 'PseudoClassSelector' || is_unscoped_pseudo_class(first);
			const parent_is_global = node.metadata.rule.metadata.parent_rule.prelude.children.some(
				(child) => child.children.length === 1 && child.children[0].metadata.is_global
			);
			// mark `&:hover` in `:global(.foo) { &:hover { color: green }}` as used
			if (no_nesting_scope && parent_is_global) {
				node.metadata.used = true;
			}
		}
	},

Domain

Subdomains

Frequently Asked Questions

What does css_visitors.ComplexSelector() do?
css_visitors.ComplexSelector() is a function in the svelte codebase, defined in packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js.
Where is css_visitors.ComplexSelector() defined?
css_visitors.ComplexSelector() is defined in packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js at line 64.
What does css_visitors.ComplexSelector() call?
css_visitors.ComplexSelector() calls 7 function(s): css_global_block_invalid_placement, css_global_invalid_placement, css_global_invalid_selector, css_global_invalid_selector_list, css_type_selector_invalid_placement, is_global, is_unscoped_pseudo_class.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free