@@ -33,8 +33,10 @@ export type StyleList = { [name: string]: string };
3333/* prettier-ignore */
3434export type connection = {
3535 children : string [ ] , // suffix names to add to the base name
36+ parts ?: string [ ] , // suffix names for sub-parts
3637 split : ( name : string ) => void , // function to split the value for the children
3738 combine : ( name : string ) => void // function to combine the child values when one changes
39+ subPart ?: boolean // true means children combine to a different parent
3840} ;
3941
4042/**
@@ -53,7 +55,7 @@ export const WSC = ['width', 'style', 'color'];
5355 * Split a style at spaces (taking quotation marks and commas into account)
5456 *
5557 * @param {string } text The combined styles to be split at spaces
56- * @returns {string[] } Array of parts of the style (separated by spaces)
58+ * @returns {string[] } Array of parts of the style (separated by spaces)
5759 */
5860function splitSpaces ( text : string ) : string [ ] {
5961 const parts = text . split ( / ( (?: ' [ ^ ' \n ] * ' | " [ ^ " \n ] * " | , [ \s \n ] | [ ^ \s \n ] ) * ) / g) ;
@@ -105,7 +107,7 @@ function combineTRBL(name: string) {
105107 const children = Styles . connect [ name ] . children ;
106108 const parts = [ ] as string [ ] ;
107109 for ( const child of children ) {
108- const part = this . styles [ name + '-' + child ] ;
110+ const part = this . styles [ this . childName ( name , child ) ] ;
109111 if ( ! part ) {
110112 delete this . styles [ name ] ;
111113 return ;
@@ -124,6 +126,18 @@ function combineTRBL(name: string) {
124126 this . styles [ name ] = parts . join ( ' ' ) ;
125127}
126128
129+ /**
130+ * Combine styles for a given border part (e.g., border-color)
131+ *
132+ * @param {string } name The name of the part to process
133+ */
134+ function combinePart ( name : string ) {
135+ combineTRBL . call ( this , name ) ;
136+ this . combineChildren ( name ) ;
137+ combineSame . call ( this , name ) ;
138+ this . combineParent ( name ) ;
139+ }
140+
127141/*********************************************************/
128142/**
129143 * Use the same value for all children
@@ -151,7 +165,9 @@ function combineSame(name: string) {
151165 return ;
152166 }
153167 }
154- this . styles [ name ] = value ;
168+ if ( value ) {
169+ this . styles [ name ] = value ;
170+ }
155171}
156172
157173/*********************************************************/
@@ -198,7 +214,7 @@ function combineWSC(name: string) {
198214 parts . push ( value ) ;
199215 }
200216 }
201- if ( parts . length ) {
217+ if ( parts . length > 1 ) {
202218 this . styles [ name ] = parts . join ( ' ' ) ;
203219 } else {
204220 delete this . styles [ name ] ;
@@ -373,6 +389,7 @@ export class Styles {
373389
374390 border : {
375391 children : TRBL ,
392+ parts : WSC ,
376393 split : splitSame ,
377394 combine : combineSame ,
378395 } ,
@@ -399,17 +416,20 @@ export class Styles {
399416 'border-width' : {
400417 children : TRBL ,
401418 split : splitTRBL ,
402- combine : null , // means its children combine to a different parent
419+ combine : combinePart ,
420+ subPart : true ,
403421 } ,
404422 'border-style' : {
405423 children : TRBL ,
406424 split : splitTRBL ,
407- combine : null , // means its children combine to a different parent
425+ combine : combinePart ,
426+ subPart : true ,
408427 } ,
409428 'border-color' : {
410429 children : TRBL ,
411430 split : splitTRBL ,
412- combine : null , // means its children combine to a different parent
431+ combine : combinePart ,
432+ subPart : true ,
413433 } ,
414434
415435 font : {
@@ -469,9 +489,12 @@ export class Styles {
469489 for ( const name of Object . keys ( this . styles ) ) {
470490 const parent = this . parentName ( name ) ;
471491 const cname = name . replace ( / .* - / , '' ) ;
492+ const pname = this . childName ( this . parentName ( parent ) , cname ) ;
472493 if (
473- ! this . styles [ parent ] ||
474- ! Styles . connect [ parent ] ?. children ?. includes ( cname )
494+ this . styles [ name ] &&
495+ ! this . styles [ pname ] &&
496+ ( ! this . styles [ parent ] ||
497+ ! Styles . connect [ parent ] ?. children ?. includes ( cname ) )
475498 ) {
476499 styles . push ( `${ name } : ${ this . styles [ name ] } ;` ) ;
477500 }
@@ -493,37 +516,49 @@ export class Styles {
493516 public set ( name : string , value : string | number | boolean ) {
494517 name = this . normalizeName ( name ) ;
495518 this . setStyle ( name , String ( value ) ) ;
496- //
497- // If there is no combine function, the children combine to
498- // a separate parent (e.g., border-width sets border-top-width, etc.
499- // and combines to border-top)
500- //
501- if ( Styles . connect [ name ] && ! Styles . connect [ name ] . combine ) {
502- this . combineChildren ( name ) ;
503- delete this . styles [ name ] ;
519+ const connect = Styles . connect [ name ] ;
520+ if ( connect ?. subPart ) {
521+ connect . combine . call ( this , name ) ;
522+ return ;
504523 }
505- //
506- // If we just changed a child, we need to try to combine
507- // it with its parent's other children
508- //
524+ this . combineParent ( name ) ;
525+ if ( name . match ( / - .* - / ) ) {
526+ const pname = name . replace ( / - .* - / , '-' ) ;
527+ combineSame . call ( this , pname ) ;
528+ }
529+ }
530+
531+ /**
532+ * When we change a child, we need to try to combine
533+ * it with its parent's other children.
534+ *
535+ * @param {string } name The child that was changed
536+ */
537+ public combineParent ( name : string ) {
509538 while ( name . match ( / - / ) ) {
510539 const cname = name ;
511540 name = this . parentName ( name ) ;
541+ const connect = Styles . connect [ name ] ;
512542 if (
513543 ! Styles . connect [ cname ] &&
514- ! Styles . connect [ name ] ?. children ?. includes (
515- cname . substring ( name . length + 1 )
516- )
544+ ! connect ?. children ?. includes ( cname . substring ( name . length + 1 ) )
517545 ) {
518546 break ;
519547 }
520- Styles . connect [ name ] . combine . call ( this , name ) ;
548+ connect . combine . call ( this , name ) ;
549+ }
550+ if ( ! this . styles [ name ] ) {
551+ return ;
552+ }
553+ const connect = Styles . connect [ name ] ;
554+ for ( const cname of connect ?. parts || [ ] ) {
555+ delete this . styles [ this . childName ( name , cname ) ] ;
521556 }
522557 }
523558
524559 /**
525560 * @param {string } name The name of the style to get
526- * @returns {string } The value of the style (or empty string if not defined)
561+ * @returns {string } The value of the style (or empty string if not defined)
527562 */
528563 public get ( name : string ) : string {
529564 name = this . normalizeName ( name ) ;
@@ -536,7 +571,7 @@ export class Styles {
536571 */
537572 protected setStyle ( name : string , value : string ) {
538573 this . styles [ name ] = this . sanitizeValue ( value ) ;
539- if ( Styles . connect [ name ] && Styles . connect [ name ] . children ) {
574+ if ( Styles . connect [ name ] ? .children ) {
540575 Styles . connect [ name ] . split . call ( this , name ) ;
541576 }
542577 if ( value === '' ) {
@@ -577,10 +612,10 @@ export class Styles {
577612 return child ;
578613 }
579614 //
580- // For non-combining styles, like border-width, insert
581- // the child name before the find word, e.g., border-top-width
615+ // For sub-part styles, like border-width, insert
616+ // the child name before the final word, e.g., border-top-width
582617 //
583- if ( Styles . connect [ name ] && ! Styles . connect [ name ] . combine ) {
618+ if ( Styles . connect [ name ] ?. subPart ) {
584619 child += name . replace ( / .* - / , '-' ) ;
585620 name = this . parentName ( name ) ;
586621 }
@@ -589,7 +624,7 @@ export class Styles {
589624
590625 /**
591626 * @param {string } name The name of a style to normalize
592- * @returns {string } The name converted from CamelCase to lowercase with dashes
627+ * @returns {string } The name converted from CamelCase to lowercase with dashes
593628 */
594629 protected normalizeName ( name : string ) : string {
595630 return name . replace ( / [ A - Z ] / g, ( c ) => '-' + c . toLowerCase ( ) ) ;
0 commit comments