44 */
55'use strict' ;
66
7- var os = require ( 'os' ) ,
8- path = require ( 'path' ) ,
9- postcss = require ( 'postcss' ) ;
7+ const os = require ( 'os' ) ;
8+ const path = require ( 'path' ) ;
9+ const postcss = require ( 'postcss' ) ;
1010
11- var fileProtocol = require ( '../file-protocol' ) ;
12- var algerbra = require ( '../position-algerbra' ) ;
11+ const fileProtocol = require ( '../file-protocol' ) ;
12+ const algerbra = require ( '../position-algerbra' ) ;
1313
14- var ORPHAN_CR_REGEX = / \r (? ! \n ) ( .| \n ) ? / g;
14+ const ORPHAN_CR_REGEX = / \r (? ! \n ) ( .| \n ) ? / g;
1515
1616/**
1717 * Process the given CSS content into reworked CSS content.
@@ -24,66 +24,96 @@ var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
2424 */
2525function process ( sourceFile , sourceContent , params ) {
2626 // #107 libsass emits orphan CR not considered newline, postcss does consider newline (content vs source-map mismatch)
27- var correctedContent = params . removeCR && ( os . EOL !== '\r' ) ?
27+ const correctedContent = params . removeCR && ( os . EOL !== '\r' ) ?
2828 sourceContent . replace ( ORPHAN_CR_REGEX , ' $1' ) :
2929 sourceContent ;
3030
31- /**
32- * Plugin for postcss that follows SASS transpilation.
33- */
34- const postcssPlugin = {
35- postcssPlugin : 'postcss-resolve-url' ,
36- Declaration : ( declaration ) => {
37- var prefix ,
38- isValid = declaration . value && ( declaration . value . indexOf ( 'url' ) >= 0 ) ;
39- if ( isValid ) {
40- prefix = declaration . prop + declaration . raws . between ;
41- declaration . value = params . transformDeclaration ( declaration . value , getPathsAtChar ) ;
42- }
31+ // IMPORTANT - prepend file protocol to all sources to avoid problems with source map
32+ const plugin = Object . assign (
33+ ( ) => ( {
34+ postcssPlugin : 'postcss-resolve-url' ,
35+ prepare : ( ) => {
36+ const visited = new Set ( ) ;
37+
38+ /**
39+ * Given an apparent position find the directory of the original file.
40+ *
41+ * @param startPosApparent {{line: number, column: number}}
42+ * @returns {false|string } Directory of original file or false on invalid
43+ */
44+ const positionToOriginalDirectory = ( startPosApparent ) => {
45+ // reverse the original source-map to find the original source file before transpilation
46+ const startPosOriginal =
47+ ! ! params . sourceMapConsumer &&
48+ params . sourceMapConsumer . originalPositionFor ( startPosApparent ) ;
4349
44- /**
45- * Create a hash of base path strings.
46- *
47- * Position in the declaration is supported by postcss at the position of the url() statement.
48- *
49- * @param {number } index Index in the declaration value at which to evaluate
50- * @throws Error on invalid source map
51- * @returns {{subString:string, value:string, property:string, selector:string} } Hash of base path strings
52- */
53- function getPathsAtChar ( index ) {
54- var subString = declaration . value . slice ( 0 , index ) ,
55- posSelector = algerbra . sanitise ( declaration . parent . source . start ) ,
56- posProperty = algerbra . sanitise ( declaration . source . start ) ,
57- posValue = algerbra . add ( [ posProperty , algerbra . strToOffset ( prefix ) ] ) ,
58- posSubString = algerbra . add ( [ posValue , algerbra . strToOffset ( subString ) ] ) ;
50+ // we require a valid directory for the specified file
51+ const directory =
52+ ! ! startPosOriginal &&
53+ ! ! startPosOriginal . source &&
54+ fileProtocol . remove ( path . dirname ( startPosOriginal . source ) ) ;
5955
60- var result = {
61- subString : positionToOriginalDirectory ( posSubString ) ,
62- value : positionToOriginalDirectory ( posValue ) ,
63- property : positionToOriginalDirectory ( posProperty ) ,
64- selector : positionToOriginalDirectory ( posSelector )
56+ return directory ;
6557 } ;
6658
67- var isValid = [ result . subString , result . value , result . property , result . selector ] . every ( Boolean ) ;
68- if ( isValid ) {
69- return result ;
70- }
71- else if ( params . sourceMapConsumer ) {
72- throw new Error (
73- 'source-map information is not available at url() declaration ' +
74- ( ORPHAN_CR_REGEX . test ( sourceContent ) ? '(found orphan CR, try removeCR option)' : '(no orphan CR found)' )
75- ) ;
76- } else {
77- throw new Error ( 'a valid source-map is not present (ensure preceding loaders output a source-map)' ) ;
78- }
59+ return {
60+ Declaration : ( declaration ) => {
61+ var prefix ,
62+ isValid = declaration . value && ( declaration . value . indexOf ( 'url' ) >= 0 ) && ! visited . has ( declaration ) ;
63+ if ( isValid ) {
64+ prefix = declaration . prop + declaration . raws . between ;
65+ declaration . value = params . transformDeclaration ( declaration . value , getPathsAtChar ) ;
66+ visited . add ( declaration ) ;
67+ }
68+
69+ /**
70+ * Create a hash of base path strings.
71+ *
72+ * Position in the declaration is supported by postcss at the position of the url() statement.
73+ *
74+ * @param {number } index Index in the declaration value at which to evaluate
75+ * @throws Error on invalid source map
76+ * @returns {{subString:string, value:string, property:string, selector:string} } Hash of base path strings
77+ */
78+ function getPathsAtChar ( index ) {
79+ var subString = declaration . value . slice ( 0 , index ) ,
80+ posSelector = algerbra . sanitise ( declaration . parent . source . start ) ,
81+ posProperty = algerbra . sanitise ( declaration . source . start ) ,
82+ posValue = algerbra . add ( [ posProperty , algerbra . strToOffset ( prefix ) ] ) ,
83+ posSubString = algerbra . add ( [ posValue , algerbra . strToOffset ( subString ) ] ) ;
84+
85+ var result = {
86+ subString : positionToOriginalDirectory ( posSubString ) ,
87+ value : positionToOriginalDirectory ( posValue ) ,
88+ property : positionToOriginalDirectory ( posProperty ) ,
89+ selector : positionToOriginalDirectory ( posSelector )
90+ } ;
91+
92+ var isValid = [ result . subString , result . value , result . property , result . selector ] . every ( Boolean ) ;
93+ if ( isValid ) {
94+ return result ;
95+ }
96+ else if ( params . sourceMapConsumer ) {
97+ throw new Error (
98+ 'source-map information is not available at url() declaration ' + (
99+ ORPHAN_CR_REGEX . test ( sourceContent ) ?
100+ '(found orphan CR, try removeCR option)' :
101+ '(no orphan CR found)'
102+ )
103+ ) ;
104+ } else {
105+ throw new Error ( 'a valid source-map is not present (ensure preceding loaders output a source-map)' ) ;
106+ }
107+ }
108+ }
109+ } ;
79110 }
80- }
81- }
111+ } ) ,
112+ { postcss : true }
113+ ) ;
82114
83- // prepend file protocol to all sources to avoid problems with source map
84- return postcss ( [
85- postcssPlugin
86- ] )
115+ // IMPORTANT - prepend file protocol to all sources to avoid problems with source map
116+ return postcss ( [ plugin ] )
87117 . process ( correctedContent , {
88118 from : fileProtocol . prepend ( sourceFile ) ,
89119 map : params . outputSourceMap && {
@@ -93,31 +123,10 @@ function process(sourceFile, sourceContent, params) {
93123 sourcesContent : true // #98 sourcesContent missing from output map
94124 }
95125 } )
96- . then ( result => ( {
97- content : result . css ,
98- map : params . outputSourceMap ? fileProtocol . remove ( result . map . toJSON ( ) ) : null
126+ . then ( ( { css , map } ) => ( {
127+ content : css ,
128+ map : params . outputSourceMap ? fileProtocol . remove ( map . toJSON ( ) ) : null
99129 } ) ) ;
100-
101- /**
102- * Given an apparent position find the directory of the original file.
103- *
104- * @param startPosApparent {{line: number, column: number}}
105- * @returns {false|string } Directory of original file or false on invalid
106- */
107- function positionToOriginalDirectory ( startPosApparent ) {
108- // reverse the original source-map to find the original source file before transpilation
109- var startPosOriginal =
110- ! ! params . sourceMapConsumer &&
111- params . sourceMapConsumer . originalPositionFor ( startPosApparent ) ;
112-
113- // we require a valid directory for the specified file
114- var directory =
115- ! ! startPosOriginal &&
116- ! ! startPosOriginal . source &&
117- fileProtocol . remove ( path . dirname ( startPosOriginal . source ) ) ;
118-
119- return directory ;
120- }
121130}
122131
123132module . exports = process ;
0 commit comments