@@ -138,12 +138,30 @@ export class ShadowCss {
138138 * The hostSelector is the attribute added to the host itself.
139139 */
140140 shimCssText ( cssText : string , selector : string , hostSelector : string = '' ) : string {
141- const commentsWithHash = extractCommentsWithHash ( cssText ) ;
142- cssText = stripComments ( cssText ) ;
143- cssText = this . _insertDirectives ( cssText ) ;
141+ // **NOTE**: Do not strip comments as this will cause component sourcemaps to break
142+ // due to shift in lines.
143+
144+ // Collect comments and replace them with a placeholder, this is done to avoid complicating
145+ // the rule parsing RegExp and keep it safer.
146+ const comments : string [ ] = [ ] ;
147+ cssText = cssText . replace ( _commentRe , ( m ) => {
148+ if ( m . match ( _commentWithHashRe ) ) {
149+ comments . push ( m ) ;
150+ } else {
151+ // Replace non hash comments with empty lines.
152+ // This is done so that we do not leak any senstive data in comments.
153+ const newLinesMatches = m . match ( _newLinesRe ) ;
154+ comments . push ( ( newLinesMatches ?. join ( '' ) ?? '' ) + '\n' ) ;
155+ }
144156
157+ return COMMENT_PLACEHOLDER ;
158+ } ) ;
159+
160+ cssText = this . _insertDirectives ( cssText ) ;
145161 const scopedCssText = this . _scopeCssText ( cssText , selector , hostSelector ) ;
146- return [ scopedCssText , ...commentsWithHash ] . join ( '\n' ) ;
162+ // Add back comments at the original position.
163+ let commentIdx = 0 ;
164+ return scopedCssText . replace ( _commentWithHashPlaceHolderRe , ( ) => comments [ commentIdx ++ ] ) ;
147165 }
148166
149167 private _insertDirectives ( cssText : string ) : string {
@@ -434,7 +452,7 @@ export class ShadowCss {
434452 return cssText . replace ( _cssColonHostRe , ( _ , hostSelectors : string , otherSelectors : string ) => {
435453 if ( hostSelectors ) {
436454 const convertedSelectors : string [ ] = [ ] ;
437- const hostSelectorArray = hostSelectors . split ( ',' ) . map ( p => p . trim ( ) ) ;
455+ const hostSelectorArray = hostSelectors . split ( ',' ) . map ( ( p ) => p . trim ( ) ) ;
438456 for ( const hostSelector of hostSelectorArray ) {
439457 if ( ! hostSelector ) break ;
440458 const convertedSelector =
@@ -464,7 +482,7 @@ export class ShadowCss {
464482 * .foo<scopeName> .bar { ... }
465483 */
466484 private _convertColonHostContext ( cssText : string ) : string {
467- return cssText . replace ( _cssColonHostContextReGlobal , selectorText => {
485+ return cssText . replace ( _cssColonHostContextReGlobal , ( selectorText ) => {
468486 // We have captured a selector that contains a `:host-context` rule.
469487
470488 // For backward compatibility `:host-context` may contain a comma separated list of selectors.
@@ -478,12 +496,12 @@ export class ShadowCss {
478496 // Execute `_cssColonHostContextRe` over and over until we have extracted all the
479497 // `:host-context` selectors from this selector.
480498 let match : RegExpExecArray | null ;
481- while ( match = _cssColonHostContextRe . exec ( selectorText ) ) {
499+ while ( ( match = _cssColonHostContextRe . exec ( selectorText ) ) ) {
482500 // `match` = [':host-context(<selectors>)<rest>', <selectors>, <rest>]
483501
484502 // The `<selectors>` could actually be a comma separated list: `:host-context(.one, .two)`.
485503 const newContextSelectors =
486- ( match [ 1 ] ?? '' ) . trim ( ) . split ( ',' ) . map ( m => m . trim ( ) ) . filter ( m => m !== '' ) ;
504+ ( match [ 1 ] ?? '' ) . trim ( ) . split ( ',' ) . map ( ( m ) => m . trim ( ) ) . filter ( ( m ) => m !== '' ) ;
487505
488506 // We must duplicate the current selector group for each of these new selectors.
489507 // For example if the current groups are:
@@ -507,8 +525,7 @@ export class ShadowCss {
507525 repeatGroups ( contextSelectorGroups , newContextSelectors . length ) ;
508526 for ( let i = 0 ; i < newContextSelectors . length ; i ++ ) {
509527 for ( let j = 0 ; j < contextSelectorGroupsLength ; j ++ ) {
510- contextSelectorGroups [ j + ( i * contextSelectorGroupsLength ) ] . push (
511- newContextSelectors [ i ] ) ;
528+ contextSelectorGroups [ j + i * contextSelectorGroupsLength ] . push ( newContextSelectors [ i ] ) ;
512529 }
513530 }
514531
@@ -520,7 +537,7 @@ export class ShadowCss {
520537 // selectors that `:host-context` can match. See `combineHostContextSelectors()` for more
521538 // info about how this is done.
522539 return contextSelectorGroups
523- . map ( contextSelectors => combineHostContextSelectors ( contextSelectors , selectorText ) )
540+ . map ( ( contextSelectors ) => combineHostContextSelectors ( contextSelectors , selectorText ) )
524541 . join ( ', ' ) ;
525542 } ) ;
526543 }
@@ -574,7 +591,7 @@ export class ShadowCss {
574591 * ```
575592 */
576593 private _stripScopingSelectors ( cssText : string ) : string {
577- return processRules ( cssText , rule => {
594+ return processRules ( cssText , ( rule ) => {
578595 const selector = rule . selector . replace ( _shadowDeepSelectors , ' ' )
579596 . replace ( _polyfillHostNoCombinatorRe , ' ' ) ;
580597 return new CssRule ( selector , rule . content ) ;
@@ -583,7 +600,7 @@ export class ShadowCss {
583600
584601 private _scopeSelector ( selector : string , scopeSelector : string , hostSelector : string ) : string {
585602 return selector . split ( ',' )
586- . map ( part => part . trim ( ) . split ( _shadowDeepSelectors ) )
603+ . map ( ( part ) => part . trim ( ) . split ( _shadowDeepSelectors ) )
587604 . map ( ( deepParts ) => {
588605 const [ shallowPart , ...otherParts ] = deepParts ;
589606 const applyScope = ( shallowPart : string ) => {
@@ -802,22 +819,18 @@ const _polyfillHostRe = /-shadowcsshost/gim;
802819const _colonHostRe = / : h o s t / gim;
803820const _colonHostContextRe = / : h o s t - c o n t e x t / gim;
804821
822+ const _newLinesRe = / \r ? \n / g;
805823const _commentRe = / \/ \* [ \s \S ] * ?\* \/ / g;
824+ const _commentWithHashRe = / \/ \* \s * # \s * s o u r c e ( M a p p i n g ) ? U R L = / g;
825+ const COMMENT_PLACEHOLDER = '%COMMENT%' ;
826+ const _commentWithHashPlaceHolderRe = new RegExp ( COMMENT_PLACEHOLDER , 'g' ) ;
806827
807828const _placeholderRe = / _ _ p h - ( \d + ) _ _ / g;
808829
809- function stripComments ( input : string ) : string {
810- return input . replace ( _commentRe , '' ) ;
811- }
812-
813- const _commentWithHashRe = / \/ \* \s * # \s * s o u r c e ( M a p p i n g ) ? U R L = [ \s \S ] + ?\* \/ / g;
814-
815- function extractCommentsWithHash ( input : string ) : string [ ] {
816- return input . match ( _commentWithHashRe ) || [ ] ;
817- }
818-
819830const BLOCK_PLACEHOLDER = '%BLOCK%' ;
820- const _ruleRe = / ( \s * ) ( [ ^ ; \{ \} ] + ?) ( \s * ) ( (?: { % B L O C K % } ? \s * ; ? ) | (?: \s * ; ) ) / g;
831+ const _ruleRe = new RegExp (
832+ `(\\s*(?:${ COMMENT_PLACEHOLDER } \\s*)*)([^;\\{\\}]+?)(\\s*)((?:{%BLOCK%}?\\s*;?)|(?:\\s*;))` ,
833+ 'g' ) ;
821834const CONTENT_PAIRS = new Map ( [ [ '{' , '}' ] ] ) ;
822835
823836const COMMA_IN_PLACEHOLDER = '%COMMA_IN_PLACEHOLDER%' ;
@@ -865,6 +878,7 @@ function escapeBlocks(
865878 let blockStartIndex = - 1 ;
866879 let openChar : string | undefined ;
867880 let closeChar : string | undefined ;
881+
868882 for ( let i = 0 ; i < input . length ; i ++ ) {
869883 const char = input [ i ] ;
870884 if ( char === '\\' ) {
@@ -888,12 +902,14 @@ function escapeBlocks(
888902 resultParts . push ( input . substring ( nonBlockStartIndex , blockStartIndex ) ) ;
889903 }
890904 }
905+
891906 if ( blockStartIndex !== - 1 ) {
892907 escapedBlocks . push ( input . substring ( blockStartIndex ) ) ;
893908 resultParts . push ( placeholder ) ;
894909 } else {
895910 resultParts . push ( input . substring ( nonBlockStartIndex ) ) ;
896911 }
912+
897913 return new StringWithEscapedBlocks ( resultParts . join ( '' ) , escapedBlocks ) ;
898914}
899915
@@ -1025,7 +1041,6 @@ function unescapeQuotes(str: string, isQuoted: boolean): string {
10251041 *
10261042 * And so on...
10271043 *
1028- * @param hostMarker the string that selects the host element.
10291044 * @param contextSelectors an array of context selectors that will be combined.
10301045 * @param otherSelectors the rest of the selectors that are not context selectors.
10311046 */
0 commit comments