@@ -1274,24 +1274,73 @@ export class PugPrinter {
12741274 private class ( token : ClassToken ) : void {
12751275 if ( this . options . pugClassNotation === 'attribute' ) {
12761276 this . classLiteralToAttribute . push ( token . val ) ;
1277+
1278+ // An extra div should be printed if...
12771279 if (
1278- this . previousToken ?. type !== 'tag' &&
1279- this . previousToken ?. type !== 'class'
1280+ this . previousToken === undefined ||
1281+ // ...the previous token indicates that this was the first class literal and thus a div did not previously exist...
1282+ this . checkTokenType (
1283+ this . previousToken ,
1284+ [ 'tag' , 'class' , 'end-attributes' ] ,
1285+ true ,
1286+ ) ||
1287+ // ...OR the previous token is a div that will be removed because of the no explicit divs rule.
1288+ ( this . previousToken . type === 'tag' &&
1289+ this . previousToken . val === 'div' &&
1290+ this . nextToken ?. type !== 'attribute' &&
1291+ ! this . options . pugExplicitDiv )
12801292 ) {
12811293 this . result += `${ this . computedIndent } div` ;
12821294 }
1295+
12831296 if (
1284- this . nextToken &&
1285- [ 'text' , 'newline' , 'indent' , 'outdent' , 'eos' ] . includes (
1286- this . nextToken . type ,
1287- )
1297+ this . checkTokenType ( this . nextToken , [
1298+ 'text' ,
1299+ 'newline' ,
1300+ 'indent' ,
1301+ 'outdent' ,
1302+ 'eos' ,
1303+ ':' ,
1304+ ] )
12881305 ) {
1306+ // Copy and clear the class literals list.
12891307 const classes : string [ ] = this . classLiteralToAttribute . splice (
12901308 0 ,
12911309 this . classLiteralToAttribute . length ,
12921310 ) ;
1293- this . result += `(class=${ this . quoteString ( classes . join ( ' ' ) ) } )` ;
1294- if ( this . nextToken . type === 'text' ) {
1311+
1312+ // If the last result character was a )...
1313+ if ( this . result . at ( - 1 ) === ')' ) {
1314+ // Look for 'class=' that is before the last '('...
1315+ const attributesStartIndex : number = this . result . lastIndexOf ( '(' ) ;
1316+ const lastClassIndex : number = this . result . indexOf (
1317+ 'class=' ,
1318+ attributesStartIndex ,
1319+ ) ;
1320+
1321+ // If a 'class=' is found...
1322+ // eslint-disable-next-line unicorn/prefer-ternary -- This is more readable without ternaries.
1323+ if ( lastClassIndex > - 1 ) {
1324+ // ...then insert the new class into it.
1325+ this . result = [
1326+ this . result . slice ( 0 , lastClassIndex + 7 ) ,
1327+ classes . join ( ' ' ) ,
1328+ ' ' ,
1329+ this . result . slice ( lastClassIndex + 7 ) ,
1330+ ] . join ( '' ) ;
1331+ } else {
1332+ // ...otherwise add a new class attribute into the existing attributes.
1333+ this . result =
1334+ this . result . slice ( 0 , - 1 ) +
1335+ `${ this . neverUseAttributeSeparator ? ' ' : ', ' } class=${ this . quoteString ( classes . join ( ' ' ) ) } )` ;
1336+ }
1337+ // ...or if the element has no attributes...
1338+ } else {
1339+ // Start a new attribute list with the class attribute in it.
1340+ this . result += `(class=${ this . quoteString ( classes . join ( ' ' ) ) } )` ;
1341+ }
1342+
1343+ if ( this . nextToken ?. type === 'text' ) {
12951344 this . result += ' ' ;
12961345 }
12971346 }
0 commit comments