@@ -11,7 +11,7 @@ import StyleDirective from './StyleDirective';
1111import Text from './Text' ;
1212import { namespaces } from '../../utils/namespaces' ;
1313import map_children from './shared/map_children' ;
14- import { dimensions , start_newline } from '../../utils/patterns' ;
14+ import { regex_dimensions , regex_starts_with_newline , regex_non_whitespace_character } from '../../utils/patterns' ;
1515import fuzzymatch from '../../utils/fuzzymatch' ;
1616import list from '../../utils/list' ;
1717import Let from './Let' ;
@@ -203,6 +203,10 @@ function is_valid_aria_attribute_value(schema: ARIAPropertyDefinition, value: st
203203 }
204204}
205205
206+ const regex_any_repeated_whitespaces = / [ \s ] + / g;
207+ const regex_heading_tags = / ^ h [ 1 - 6 ] $ / ;
208+ const regex_illegal_attribute_character = / ( ^ [ 0 - 9 - .] ) | [ \^ $ @ % & # ? ! | ( ) [ \] { } ^ * + ~ ; ] / ;
209+
206210export default class Element extends Node {
207211 type : 'Element' ;
208212 name : string ;
@@ -253,7 +257,7 @@ export default class Element extends Node {
253257 // places if there's another newline afterwards.
254258 // see https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
255259 // see https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
256- first . data = first . data . replace ( start_newline , '' ) ;
260+ first . data = first . data . replace ( regex_starts_with_newline , '' ) ;
257261 }
258262 }
259263
@@ -398,7 +402,7 @@ export default class Element extends Node {
398402
399403 // Errors
400404
401- if ( / ( ^ [ 0 - 9 - . ] ) | [ \^ $ @ % & # ? ! | ( ) [ \] { } ^ * + ~ ; ] / . test ( name ) ) {
405+ if ( regex_illegal_attribute_character . test ( name ) ) {
402406 return component . error ( attribute , compiler_errors . illegal_attribute ( name ) ) ;
403407 }
404408
@@ -464,7 +468,7 @@ export default class Element extends Node {
464468 component . warn ( attribute , compiler_warnings . a11y_unknown_aria_attribute ( type , match ) ) ;
465469 }
466470
467- if ( name === 'aria-hidden' && / ^ h [ 1 - 6 ] $ / . test ( this . name ) ) {
471+ if ( name === 'aria-hidden' && regex_heading_tags . test ( this . name ) ) {
468472 component . warn ( attribute , compiler_warnings . a11y_hidden ( this . name ) ) ;
469473 }
470474
@@ -729,7 +733,7 @@ export default class Element extends Node {
729733 if ( this . name === 'figure' ) {
730734 const children = this . children . filter ( node => {
731735 if ( node . type === 'Comment' ) return false ;
732- if ( node . type === 'Text' ) return / \S / . test ( node . data ) ;
736+ if ( node . type === 'Text' ) return regex_non_whitespace_character . test ( node . data ) ;
733737 return true ;
734738 } ) ;
735739
@@ -861,7 +865,7 @@ export default class Element extends Node {
861865 if ( this . name !== 'video' ) {
862866 return component . error ( binding , compiler_errors . invalid_binding_element_with ( '<video>' , name ) ) ;
863867 }
864- } else if ( dimensions . test ( name ) ) {
868+ } else if ( regex_dimensions . test ( name ) ) {
865869 if ( this . name === 'svg' && ( name === 'offsetWidth' || name === 'offsetHeight' ) ) {
866870 return component . error ( binding , compiler_errors . invalid_binding_on ( binding . name , `<svg>. Use '${ name . replace ( 'offset' , 'client' ) } ' instead` ) ) ;
867871 } else if ( is_svg ( this . name ) ) {
@@ -988,7 +992,7 @@ export default class Element extends Node {
988992 if ( attribute && ! attribute . is_true ) {
989993 attribute . chunks . forEach ( ( chunk , index ) => {
990994 if ( chunk . type === 'Text' ) {
991- let data = chunk . data . replace ( / [ \s \n \t ] + / g , ' ' ) ;
995+ let data = chunk . data . replace ( regex_any_repeated_whitespaces , ' ' ) ;
992996 if ( index === 0 ) {
993997 data = data . trimLeft ( ) ;
994998 } else if ( index === attribute . chunks . length - 1 ) {
@@ -1002,23 +1006,27 @@ export default class Element extends Node {
10021006 }
10031007}
10041008
1009+ const regex_starts_with_vovel = / ^ [ a e i o u ] / ;
1010+
10051011function should_have_attribute (
10061012 node ,
10071013 attributes : string [ ] ,
10081014 name = node . name
10091015) {
1010- const article = / ^ [ a e i o u ] / . test ( attributes [ 0 ] ) ? 'an' : 'a' ;
1016+ const article = regex_starts_with_vovel . test ( attributes [ 0 ] ) ? 'an' : 'a' ;
10111017 const sequence = attributes . length > 1 ?
10121018 attributes . slice ( 0 , - 1 ) . join ( ', ' ) + ` or ${ attributes [ attributes . length - 1 ] } ` :
10131019 attributes [ 0 ] ;
10141020
10151021 node . component . warn ( node , compiler_warnings . a11y_missing_attribute ( name , article , sequence ) ) ;
10161022}
10171023
1024+ const regex_minus_sign = / - / ;
1025+
10181026function within_custom_element ( parent : INode ) {
10191027 while ( parent ) {
10201028 if ( parent . type === 'InlineComponent' ) return false ;
1021- if ( parent . type === 'Element' && / - / . test ( parent . name ) ) return true ;
1029+ if ( parent . type === 'Element' && regex_minus_sign . test ( parent . name ) ) return true ;
10221030 parent = parent . parent ;
10231031 }
10241032 return false ;
0 commit comments