@@ -144,11 +144,18 @@ export default class Parser {
144144 attr . push ( this . currToken ) ;
145145 this . position ++ ;
146146 }
147- if ( this . currToken [ TOKEN . TYPE ] !== tokens . closeSquare ) {
148- return this . expected ( 'closing square bracket' , this . currToken [ TOKEN . START_POS ] ) ;
147+
148+ if ( ! this . currToken ) {
149+ this . position -- ;
150+ return this . missingClosingSquareBracket ( ) ;
149151 }
150152
151153 const len = attr . length ;
154+
155+ if ( len === 0 ) {
156+ return this . expected ( 'attribute' , this . currToken [ TOKEN . START_POS ] ) ;
157+ }
158+
152159 const node = {
153160 source : getSource (
154161 startingToken [ 1 ] ,
@@ -465,8 +472,7 @@ export default class Parser {
465472 if ( rawSpace === space ) {
466473 rawSpace = undefined ;
467474 }
468- let result = { space, rawSpace} ;
469- return result ;
475+ return { space, rawSpace} ;
470476 }
471477
472478 isNamedCombinator ( position = this . position ) {
@@ -475,30 +481,27 @@ export default class Parser {
475481 this . tokens [ position + 2 ] && this . tokens [ position + 2 ] [ TOKEN . TYPE ] === tokens . slash ;
476482
477483 }
484+
478485 namedCombinator ( ) {
479- if ( this . isNamedCombinator ( ) ) {
480- let nameRaw = this . content ( this . tokens [ this . position + 1 ] ) ;
481- let name = unesc ( nameRaw ) . toLowerCase ( ) ;
482- let raws = { } ;
483- if ( name !== nameRaw ) {
484- raws . value = `/${ nameRaw } /` ;
485- }
486- let node = new Combinator ( {
487- value : `/${ name } /` ,
488- source : getSource (
489- this . currToken [ TOKEN . START_LINE ] ,
490- this . currToken [ TOKEN . START_COL ] ,
491- this . tokens [ this . position + 2 ] [ TOKEN . END_LINE ] ,
492- this . tokens [ this . position + 2 ] [ TOKEN . END_COL ] ,
493- ) ,
494- sourceIndex : this . currToken [ TOKEN . START_POS ] ,
495- raws,
496- } ) ;
497- this . position = this . position + 3 ;
498- return node ;
499- } else {
500- this . unexpected ( ) ;
486+ let nameRaw = this . content ( this . tokens [ this . position + 1 ] ) ;
487+ let name = unesc ( nameRaw ) . toLowerCase ( ) ;
488+ let raws = { } ;
489+ if ( name !== nameRaw ) {
490+ raws . value = `/${ nameRaw } /` ;
501491 }
492+ let node = new Combinator ( {
493+ value : `/${ name } /` ,
494+ source : getSource (
495+ this . currToken [ TOKEN . START_LINE ] ,
496+ this . currToken [ TOKEN . START_COL ] ,
497+ this . tokens [ this . position + 2 ] [ TOKEN . END_LINE ] ,
498+ this . tokens [ this . position + 2 ] [ TOKEN . END_COL ] ,
499+ ) ,
500+ sourceIndex : this . currToken [ TOKEN . START_POS ] ,
501+ raws,
502+ } ) ;
503+ this . position = this . position + 3 ;
504+ return node ;
502505 }
503506
504507 combinator ( ) {
@@ -620,14 +623,22 @@ export default class Parser {
620623 } ) ;
621624 }
622625
623- missingParenthesis ( ) {
626+ missingOpeningParenthesis ( ) {
624627 return this . expected ( 'opening parenthesis' , this . currToken [ TOKEN . START_POS ] ) ;
625628 }
626629
627- missingSquareBracket ( ) {
630+ missingClosingParenthesis ( ) {
631+ return this . expected ( 'closing parenthesis' , this . currToken [ TOKEN . START_POS ] ) ;
632+ }
633+
634+ missingOpeningSquareBracket ( ) {
628635 return this . expected ( 'opening square bracket' , this . currToken [ TOKEN . START_POS ] ) ;
629636 }
630637
638+ missingClosingSquareBracket ( ) {
639+ return this . expected ( 'closing square bracket' , this . currToken [ TOKEN . START_POS ] ) ;
640+ }
641+
631642 unexpected ( ) {
632643 return this . error ( `Unexpected '${ this . content ( ) } '. Escaping special characters with \\ may help.` , this . currToken [ TOKEN . START_POS ] ) ;
633644 }
@@ -702,6 +713,10 @@ export default class Parser {
702713 parenValue += this . parseParenthesisToken ( this . currToken ) ;
703714 this . position ++ ;
704715 }
716+ if ( unbalanced ) {
717+ this . position -- ;
718+ return this . missingClosingParenthesis ( ) ;
719+ }
705720 if ( last ) {
706721 last . appendToPropertyAndEscape ( "value" , parenValue , parenValue ) ;
707722 } else {
@@ -718,7 +733,8 @@ export default class Parser {
718733 }
719734 }
720735 if ( unbalanced ) {
721- return this . expected ( 'closing parenthesis' , this . currToken [ TOKEN . START_POS ] ) ;
736+ this . position -- ;
737+ return this . missingClosingParenthesis ( ) ;
722738 }
723739 }
724740
@@ -733,22 +749,13 @@ export default class Parser {
733749 return this . expected ( [ 'pseudo-class' , 'pseudo-element' ] , this . position - 1 ) ;
734750 }
735751 if ( this . currToken [ TOKEN . TYPE ] === tokens . word ) {
736- this . splitWord ( false , ( first , length ) => {
752+ this . splitWord ( false , ( first ) => {
737753 pseudoStr += first ;
738754 this . newNode ( new Pseudo ( {
739755 value : pseudoStr ,
740756 source : getTokenSourceSpan ( startingToken , this . currToken ) ,
741757 sourceIndex : startingToken [ TOKEN . START_POS ] ,
742758 } ) ) ;
743- if (
744- length > 1 &&
745- this . nextToken &&
746- this . nextToken [ TOKEN . TYPE ] === tokens . openParenthesis
747- ) {
748- this . error ( 'Misplaced parenthesis.' , {
749- index : this . nextToken [ TOKEN . START_POS ] ,
750- } ) ;
751- }
752759 } ) ;
753760 } else {
754761 return this . expected ( [ 'pseudo-class' , 'pseudo-element' ] , this . currToken [ TOKEN . START_POS ] ) ;
@@ -813,13 +820,6 @@ export default class Parser {
813820 this . position ++ ;
814821 let current = this . content ( ) ;
815822 word += current ;
816- if ( current . lastIndexOf ( '\\' ) === current . length - 1 ) {
817- let next = this . nextToken ;
818- if ( next && next [ TOKEN . TYPE ] === tokens . space ) {
819- word += this . requiredSpace ( this . content ( next ) ) ;
820- this . position ++ ;
821- }
822- }
823823 nextToken = this . nextToken ;
824824 }
825825 const hasClass = indexesOf ( word , '.' ) . filter ( i => word [ i - 1 ] !== '\\' ) ;
@@ -905,7 +905,7 @@ export default class Parser {
905905 break ;
906906 case tokens . closeParenthesis :
907907 if ( throwOnParenthesis ) {
908- this . missingParenthesis ( ) ;
908+ this . missingOpeningParenthesis ( ) ;
909909 }
910910 break ;
911911 case tokens . openSquare :
@@ -938,7 +938,7 @@ export default class Parser {
938938 break ;
939939 // These cases throw; no break needed.
940940 case tokens . closeSquare :
941- this . missingSquareBracket ( ) ;
941+ this . missingOpeningSquareBracket ( ) ;
942942 case tokens . semicolon :
943943 this . missingBackslash ( ) ;
944944 default :
0 commit comments