From 445fe983ac183a7a2eb9f3465000e9dfe35f79c6 Mon Sep 17 00:00:00 2001 From: Ivan Hofer Date: Wed, 10 Aug 2022 19:35:07 +0200 Subject: [PATCH] optimize `.test() calls --- src/compiler/compile/Component.ts | 14 +++++++++----- src/compiler/compile/css/Selector.ts | 13 +++++++++---- src/compiler/compile/css/Stylesheet.ts | 7 +++++-- src/compiler/compile/index.ts | 7 +++++-- src/compiler/compile/nodes/Element.ts | 17 +++++++++++------ src/compiler/compile/nodes/EventHandler.ts | 6 ++++-- src/compiler/compile/nodes/Head.ts | 4 +++- src/compiler/compile/nodes/InlineComponent.ts | 8 +++++--- src/compiler/compile/nodes/Text.ts | 7 +++++-- .../compile/nodes/shared/AbstractBlock.ts | 4 +++- src/compiler/compile/nodes/shared/Expression.ts | 4 +++- .../render_dom/wrappers/Element/Attribute.ts | 7 ++++--- .../wrappers/Element/StyleAttribute.ts | 3 ++- .../render_dom/wrappers/Element/index.ts | 9 +++++++-- .../compile/render_dom/wrappers/Fragment.ts | 4 +++- .../compile/render_dom/wrappers/Text.ts | 4 +++- .../utils/remove_whitespace_children.ts | 4 +++- src/compiler/parse/state/tag.ts | 3 ++- src/compiler/utils/extract_svelte_ignore.ts | 4 ++-- 19 files changed, 88 insertions(+), 41 deletions(-) diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 779e51f47c..0ce27d2e0c 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -48,6 +48,8 @@ interface ComponentOptions { } const regex_leading_directory_separator = /^[/\\]/; +const regex_starts_with_Export = /^Export/; +const regex_contains_Function = /Function/; export default class Component { stats: Stats; @@ -640,7 +642,7 @@ export default class Component { body.splice(i, 1); } - if (/^Export/.test(node.type)) { + if (regex_starts_with_Export.test(node.type)) { const replacement = this.extract_exports(node, true); if (replacement) { body[i] = replacement; @@ -797,7 +799,7 @@ export default class Component { return this.skip(); } - if (/^Export/.test(node.type)) { + if (regex_starts_with_Export.test(node.type)) { const replacement = component.extract_exports(node); if (replacement) { this.replace(replacement); @@ -920,7 +922,7 @@ export default class Component { } if (name[1] !== '$' && scope.has(name.slice(1)) && scope.find_owner(name.slice(1)) !== this.instance_scope) { - if (!((/Function/.test(parent.type) && prop === 'params') || (parent.type === 'VariableDeclarator' && prop === 'id'))) { + if (!((regex_contains_Function.test(parent.type) && prop === 'params') || (parent.type === 'VariableDeclarator' && prop === 'id'))) { return this.error(node as any, compiler_errors.contextual_store); } } @@ -967,7 +969,7 @@ export default class Component { walk(this.ast.instance.content, { enter(node: Node) { - if (/Function/.test(node.type)) { + if (regex_contains_Function.test(node.type)) { return this.skip(); } @@ -1462,6 +1464,8 @@ export default class Component { } } +const regex_valid_tag_name = /^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/; + function process_component_options(component: Component, nodes) { const component_options: ComponentOptions = { immutable: component.compile_options.immutable || false, @@ -1507,7 +1511,7 @@ function process_component_options(component: Component, nodes) { return component.error(attribute, compiler_errors.invalid_tag_attribute); } - if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) { + if (tag && !regex_valid_tag_name.test(tag)) { return component.error(attribute, compiler_errors.invalid_tag_property); } diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index 1ebacbdd86..ce6b04f7f5 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -25,6 +25,8 @@ const whitelist_attribute_selector = new Map([ ['dialog', new Set(['open'])] ]); +const regex_is_single_css_selector = /[^\\],(?!([^([]+[^\\]|[^([\\])[)\]])/; + export default class Selector { node: CssNode; stylesheet: Stylesheet; @@ -157,7 +159,7 @@ export default class Selector { for (const block of this.blocks) { for (const selector of block.selectors) { if (selector.type === 'PseudoClassSelector' && selector.name === 'global') { - if (/[^\\],(?!([^([]+[^\\]|[^([\\])[)\]])/.test(selector.children[0].value)) { + if (regex_is_single_css_selector.test(selector.children[0].value)) { component.error(selector, compiler_errors.css_invalid_global_selector); } } @@ -338,6 +340,9 @@ function test_attribute(operator, expected_value, case_insensitive, value) { } } +const regex_starts_with_whitespace = /^\s/; +const regex_ends_with_whitespace = /\s$/; + function attribute_matches(node: CssNode, name: string, expected_value: string, operator: string, case_insensitive: boolean) { const spread = node.attributes.find(attr => attr.type === 'Spread'); if (spread) return true; @@ -373,7 +378,7 @@ function attribute_matches(node: CssNode, name: string, expected_value: string, const start_with_space = []; const remaining = []; current_possible_values.forEach((current_possible_value: string) => { - if (/^\s/.test(current_possible_value)) { + if (regex_starts_with_whitespace.test(current_possible_value)) { start_with_space.push(current_possible_value); } else { remaining.push(current_possible_value); @@ -394,7 +399,7 @@ function attribute_matches(node: CssNode, name: string, expected_value: string, prev_values = combined; start_with_space.forEach((value: string) => { - if (/\s$/.test(value)) { + if (regex_ends_with_whitespace.test(value)) { possible_values.add(value); } else { prev_values.push(value); @@ -408,7 +413,7 @@ function attribute_matches(node: CssNode, name: string, expected_value: string, } current_possible_values.forEach((current_possible_value: string) => { - if (/\s$/.test(current_possible_value)) { + if (regex_ends_with_whitespace.test(current_possible_value)) { possible_values.add(current_possible_value); } else { prev_values.push(current_possible_value); diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index f983204b13..cc03115749 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -118,6 +118,9 @@ class Rule { } } +const regex_only_whitespace = /^\s+$/; +const regex_whitespace = /\s/; + class Declaration { node: CssNode; @@ -149,10 +152,10 @@ class Declaration { // Don't minify whitespace in custom properties, since some browsers (Chromium < 99) // treat --foo: ; and --foo:; differently - if (first.type === 'Raw' && /^\s+$/.test(first.value)) return; + if (first.type === 'Raw' && regex_only_whitespace.test(first.value)) return; let start = first.start; - while (/\s/.test(code.original[start])) start += 1; + while (regex_whitespace.test(code.original[start])) start += 1; if (start - c > 1) { code.overwrite(c, start, ':'); diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index afe9c56cf4..a5edc3a6f7 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -35,6 +35,9 @@ const valid_options = [ 'cssHash' ]; +const regex_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; +const regex_starts_with_lowercase_character = /^[a-z]/; + function validate_options(options: CompileOptions, warnings: Warning[]) { const { name, filename, loopGuardTimeout, dev, namespace } = options; @@ -48,11 +51,11 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { } }); - if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { + if (name && !regex_valid_identifier.test(name)) { throw new Error(`options.name must be a valid identifier (got '${name}')`); } - if (name && /^[a-z]/.test(name)) { + if (name && regex_starts_with_lowercase_character.test(name)) { const message = 'options.name should be capitalised'; warnings.push({ code: 'options-lowercase-name', diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 0315a67b98..a4bbe707fa 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -203,7 +203,10 @@ function is_valid_aria_attribute_value(schema: ARIAPropertyDefinition, value: st } } -const regex_any_repeated_whitespace = /[\s]+/g; +const regex_any_repeated_whitespaces = /[\s]+/g; +const regex_heading_tags = /^h[1-6]$/; +const regex_illegal_attribute_character = /(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/; +const regex_non_whitespace_characters = /\S/; export default class Element extends Node { type: 'Element'; @@ -400,7 +403,7 @@ export default class Element extends Node { // Errors - if (/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/.test(name)) { + if (regex_illegal_attribute_character.test(name)) { return component.error(attribute, compiler_errors.illegal_attribute(name)); } @@ -466,7 +469,7 @@ export default class Element extends Node { component.warn(attribute, compiler_warnings.a11y_unknown_aria_attribute(type, match)); } - if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) { + if (name === 'aria-hidden' && regex_heading_tags.test(this.name)) { component.warn(attribute, compiler_warnings.a11y_hidden(this.name)); } @@ -731,7 +734,7 @@ export default class Element extends Node { if (this.name === 'figure') { const children = this.children.filter(node => { if (node.type === 'Comment') return false; - if (node.type === 'Text') return /\S/.test(node.data); + if (node.type === 'Text') return regex_non_whitespace_characters.test(node.data); return true; }); @@ -990,7 +993,7 @@ export default class Element extends Node { if (attribute && !attribute.is_true) { attribute.chunks.forEach((chunk, index) => { if (chunk.type === 'Text') { - let data = chunk.data.replace(regex_any_repeated_whitespace, ' '); + let data = chunk.data.replace(regex_any_repeated_whitespaces, ' '); if (index === 0) { data = data.trimLeft(); } else if (index === attribute.chunks.length - 1) { @@ -1019,10 +1022,12 @@ function should_have_attribute( node.component.warn(node, compiler_warnings.a11y_missing_attribute(name, article, sequence)); } +const regex_minus_sign = /-/; + function within_custom_element(parent: INode) { while (parent) { if (parent.type === 'InlineComponent') return false; - if (parent.type === 'Element' && /-/.test(parent.name)) return true; + if (parent.type === 'Element' && regex_minus_sign.test(parent.name)) return true; parent = parent.parent; } return false; diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 1bac53b6af..5d29c0c5e4 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -6,6 +6,8 @@ import { Identifier } from 'estree'; import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; +const regex_FunctionExpression = /FunctionExpression/; + export default class EventHandler extends Node { type: 'EventHandler'; name: string; @@ -25,7 +27,7 @@ export default class EventHandler extends Node { this.expression = new Expression(component, this, template_scope, info.expression); this.uses_context = this.expression.uses_context; - if (/FunctionExpression/.test(info.expression.type) && info.expression.params.length === 0) { + if (regex_FunctionExpression.test(info.expression.type) && info.expression.params.length === 0) { // TODO make this detection more accurate — if `event.preventDefault` isn't called, and // `event` is passed to another function, we can make it passive this.can_make_passive = true; @@ -55,7 +57,7 @@ export default class EventHandler extends Node { } const node = this.expression.node; - if (/FunctionExpression/.test(node.type)) { + if (regex_FunctionExpression.test(node.type)) { return false; } diff --git a/src/compiler/compile/nodes/Head.ts b/src/compiler/compile/nodes/Head.ts index fb000e0d5b..a78f32e3d8 100644 --- a/src/compiler/compile/nodes/Head.ts +++ b/src/compiler/compile/nodes/Head.ts @@ -6,6 +6,8 @@ import TemplateScope from './shared/TemplateScope'; import { TemplateNode } from '../../interfaces'; import compiler_errors from '../compiler_errors'; +const regex_non_whitespace_characters = /\S/; + export default class Head extends Node { type: 'Head'; children: any[]; // TODO @@ -20,7 +22,7 @@ export default class Head extends Node { } this.children = map_children(component, parent, scope, info.children.filter(child => { - return (child.type !== 'Text' || /\S/.test(child.data)); + return (child.type !== 'Text' || regex_non_whitespace_characters.test(child.data)); })); if (this.children.length > 0) { diff --git a/src/compiler/compile/nodes/InlineComponent.ts b/src/compiler/compile/nodes/InlineComponent.ts index 8871c5f306..f25cc8d1ac 100644 --- a/src/compiler/compile/nodes/InlineComponent.ts +++ b/src/compiler/compile/nodes/InlineComponent.ts @@ -73,10 +73,10 @@ export default class InlineComponent extends Node { case 'Transition': return component.error(node, compiler_errors.invalid_transition); - + case 'StyleDirective': return component.error(node, compiler_errors.invalid_component_style_directive); - + default: throw new Error(`Not implemented: ${node.type}`); } @@ -164,8 +164,10 @@ export default class InlineComponent extends Node { } } +const regex_only_whitespace = /^\s+$/; + function not_whitespace_text(node) { - return !(node.type === 'Text' && /^\s+$/.test(node.data)); + return !(node.type === 'Text' && regex_only_whitespace.test(node.data)); } function get_namespace(parent: Node, explicit_namespace: string) { diff --git a/src/compiler/compile/nodes/Text.ts b/src/compiler/compile/nodes/Text.ts index 347beb9c23..a8db5115cd 100644 --- a/src/compiler/compile/nodes/Text.ts +++ b/src/compiler/compile/nodes/Text.ts @@ -16,6 +16,9 @@ const elements_without_text = new Set([ 'video' ]); +const regex_ends_with_svg = /svg$/; +const regex_non_whitespace_characters = /\S/; + export default class Text extends Node { type: 'Text'; data: string; @@ -28,7 +31,7 @@ export default class Text extends Node { } should_skip() { - if (/\S/.test(this.data)) return false; + if (regex_non_whitespace_characters.test(this.data)) return false; const parent_element = this.find_nearest(/(?:Element|InlineComponent|SlotTemplate|Head)/); if (!parent_element) return false; @@ -37,7 +40,7 @@ export default class Text extends Node { if (parent_element.type === 'InlineComponent') return parent_element.children.length === 1 && this === parent_element.children[0]; // svg namespace exclusions - if (/svg$/.test(parent_element.namespace)) { + if (regex_ends_with_svg.test(parent_element.namespace)) { if (this.prev && this.prev.type === 'Element' && this.prev.name === 'tspan') return false; } diff --git a/src/compiler/compile/nodes/shared/AbstractBlock.ts b/src/compiler/compile/nodes/shared/AbstractBlock.ts index 1f03bac05c..7df61574e5 100644 --- a/src/compiler/compile/nodes/shared/AbstractBlock.ts +++ b/src/compiler/compile/nodes/shared/AbstractBlock.ts @@ -4,6 +4,8 @@ import Node from './Node'; import { INode } from '../interfaces'; import compiler_warnings from '../../compiler_warnings'; +const regex_non_whitespace_characters = /\S/; + export default class AbstractBlock extends Node { block: Block; children: INode[]; @@ -17,7 +19,7 @@ export default class AbstractBlock extends Node { const child = this.children[0]; - if (!child || (child.type === 'Text' && !/[^\s]/.test(child.data))) { + if (!child || (child.type === 'Text' && !regex_non_whitespace_characters.test(child.data))) { this.component.warn(this, compiler_warnings.empty_block); } } diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 0603c15589..c5a5b89a5e 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -21,6 +21,8 @@ import compiler_errors from '../../compiler_errors'; type Owner = INode; +const regex_FunctionExpression = /FunctionExpression/; + export default class Expression { type: 'Expression' = 'Expression'; component: Component; @@ -72,7 +74,7 @@ export default class Expression { scope = map.get(node); } - if (!function_expression && /FunctionExpression/.test(node.type)) { + if (!function_expression && regex_FunctionExpression.test(node.type)) { function_expression = node; } diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts index 48cda4cb93..4f67812f01 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts @@ -42,7 +42,7 @@ export class BaseAttributeWrapper { } } - render(_block: Block) {} + render(_block: Block) { } } const regex_minus_sign = /-/; @@ -385,13 +385,14 @@ function should_cache(attribute: AttributeWrapper) { return attribute.is_src || attribute.node.should_cache(); } +const regex_checked_or_group = /checked|group/; + function is_indirectly_bound_value(attribute: AttributeWrapper) { const element = attribute.parent; return attribute.name === 'value' && (element.node.name === 'option' || // TODO check it's actually bound (element.node.name === 'input' && element.node.bindings.some( - (binding) => - /checked|group/.test(binding.name) + (binding) => regex_checked_or_group.test(binding.name) ))); } diff --git a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts index 4cc895848c..da7aed2add 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts @@ -109,6 +109,7 @@ function optimize_style(value: Array) { } const regex_important_flag = /\s*!important\s*$/; +const regex_semicolon_or_Whitespace = /[;\s]/; function get_style_value(chunks: Array) { const value: Array = []; @@ -155,7 +156,7 @@ function get_style_value(chunks: Array) { } as Text); } - while (/[;\s]/.test(chunk.data[c])) c += 1; + while (regex_semicolon_or_Whitespace.test(chunk.data[c])) c += 1; const remaining_data = chunk.data.slice(c); if (remaining_data) { diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 4e90131521..9d83f1bbbb 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -34,12 +34,16 @@ interface BindingGroup { bindings: Binding[]; } +const regex_radio_or_checkbox_or_file = /radio|checkbox|file/; +const regex_radio_or_checkbox_or_range_or_file = /radio|checkbox|range|file/; + const events = [ { event_names: ['input'], filter: (node: Element, _name: string) => node.name === 'textarea' || - node.name === 'input' && !/radio|checkbox|range|file/.test(node.get_static_attribute_value('type') as string) + node.name === 'input' && + !regex_radio_or_checkbox_or_range_or_file.test(node.get_static_attribute_value('type') as string) }, { event_names: ['input'], @@ -51,7 +55,8 @@ const events = [ event_names: ['change'], filter: (node: Element, _name: string) => node.name === 'select' || - node.name === 'input' && /radio|checkbox|file/.test(node.get_static_attribute_value('type') as string) + node.name === 'input' && + regex_radio_or_checkbox_or_file.test(node.get_static_attribute_value('type') as string) }, { event_names: ['change', 'input'], diff --git a/src/compiler/compile/render_dom/wrappers/Fragment.ts b/src/compiler/compile/render_dom/wrappers/Fragment.ts index 87ce775ca9..100e707908 100644 --- a/src/compiler/compile/render_dom/wrappers/Fragment.ts +++ b/src/compiler/compile/render_dom/wrappers/Fragment.ts @@ -50,6 +50,8 @@ function trimmable_at(child: INode, next_sibling: Wrapper): boolean { return (next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/)) || next_sibling.node.prev.type === 'EachBlock'; } +const regex_starts_with_whitespace = /^\s/; + export default class FragmentWrapper { nodes: Wrapper[]; @@ -92,7 +94,7 @@ export default class FragmentWrapper { // *unless* there is no whitespace between this node and its next sibling if (this.nodes.length === 0) { const should_trim = ( - next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.node.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock') + next_sibling ? (next_sibling.node.type === 'Text' && regex_starts_with_whitespace.test(next_sibling.node.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock') ); if (should_trim && !child.keep_space()) { diff --git a/src/compiler/compile/render_dom/wrappers/Text.ts b/src/compiler/compile/render_dom/wrappers/Text.ts index 2a342b5678..7d02735d9a 100644 --- a/src/compiler/compile/render_dom/wrappers/Text.ts +++ b/src/compiler/compile/render_dom/wrappers/Text.ts @@ -5,6 +5,8 @@ import Wrapper from './shared/Wrapper'; import { x } from 'code-red'; import { Identifier } from 'estree'; +const regex_non_whitespace_characters = /[\S\u00A0]/; + export default class TextWrapper extends Wrapper { node: Text; data: string; @@ -27,7 +29,7 @@ export default class TextWrapper extends Wrapper { use_space() { if (this.renderer.component.component_options.preserveWhitespace) return false; - if (/[\S\u00A0]/.test(this.data)) return false; + if (regex_non_whitespace_characters.test(this.data)) return false; return !this.node.within_pre(); } diff --git a/src/compiler/compile/render_ssr/handlers/utils/remove_whitespace_children.ts b/src/compiler/compile/render_ssr/handlers/utils/remove_whitespace_children.ts index 7733c89cb8..33584942a9 100644 --- a/src/compiler/compile/render_ssr/handlers/utils/remove_whitespace_children.ts +++ b/src/compiler/compile/render_ssr/handlers/utils/remove_whitespace_children.ts @@ -2,6 +2,8 @@ import { INode } from '../../../nodes/interfaces'; import { trim_end, trim_start } from '../../../../utils/trim'; import { link } from '../../../../utils/link'; +const regex_starts_with_whitespace = /^\s/; + // similar logic from `compile/render_dom/wrappers/Fragment` // We want to remove trailing whitespace inside an element/component/block, // *unless* there is no whitespace between this node and its next sibling @@ -22,7 +24,7 @@ export default function remove_whitespace_children(children: INode[], next?: INo if (nodes.length === 0) { const should_trim = next ? next.type === 'Text' && - /^\s/.test(next.data) && + regex_starts_with_whitespace.test(next.data) && trimmable_at(child, next) : !child.has_ancestor('EachBlock'); diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts index 19d0e79da6..bf50c6c774 100644 --- a/src/compiler/parse/state/tag.ts +++ b/src/compiler/parse/state/tag.ts @@ -55,6 +55,7 @@ function parent_is_head(stack) { const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i; const regex_closing_comment = /-->/; +const regex_capital_letter = /[A-Z]/; export default function tag(parser: Parser) { const start = parser.index++; @@ -107,7 +108,7 @@ export default function tag(parser: Parser) { const type = meta_tags.has(name) ? meta_tags.get(name) - : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent' + : (regex_capital_letter.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent' : name === 'svelte:fragment' ? 'SlotTemplate' : name === 'title' && parent_is_head(parser.stack) ? 'Title' : name === 'slot' && !parser.customElement ? 'Slot' : 'Element'; diff --git a/src/compiler/utils/extract_svelte_ignore.ts b/src/compiler/utils/extract_svelte_ignore.ts index 4931929639..4217bb0f83 100644 --- a/src/compiler/utils/extract_svelte_ignore.ts +++ b/src/compiler/utils/extract_svelte_ignore.ts @@ -3,11 +3,11 @@ import { flatten } from './flatten'; const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m; -const regex_no_whitespace_character = /[^\S]/; +const regex_whitespace_characters = /\s/; export function extract_svelte_ignore(text: string): string[] { const match = pattern.exec(text); - return match ? match[1].split(regex_no_whitespace_character).map(x => x.trim()).filter(Boolean) : []; + return match ? match[1].split(regex_whitespace_characters).map(x => x.trim()).filter(Boolean) : []; } export function extract_svelte_ignore_from_comments }>(node: Node): string[] {