source: trip-planner-front/node_modules/resolve-url-loader/lib/engine/postcss.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[6a3a178]1/*
2 * MIT License http://opensource.org/licenses/MIT
3 * Author: Ben Holloway @bholloway
4 */
5'use strict';
6
7var os = require('os'),
8 path = require('path'),
9 postcss = require('postcss');
10
11var fileProtocol = require('../file-protocol');
12var algerbra = require('../position-algerbra');
13
14var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
15
16/**
17 * Process the given CSS content into reworked CSS content.
18 *
19 * @param {string} sourceFile The absolute path of the file being processed
20 * @param {string} sourceContent CSS content without source-map
21 * @param {{outputSourceMap: boolean, transformDeclaration:function, absSourceMap:object,
22 * sourceMapConsumer:object, removeCR:boolean}} params Named parameters
23 * @return {{content: string, map: object}} Reworked CSS and optional source-map
24 */
25function process(sourceFile, sourceContent, params) {
26 // #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') ?
28 sourceContent.replace(ORPHAN_CR_REGEX, ' $1') :
29 sourceContent;
30
31 // prepend file protocol to all sources to avoid problems with source map
32 return postcss([
33 postcss.plugin('postcss-resolve-url', postcssPlugin)
34 ])
35 .process(correctedContent, {
36 from: fileProtocol.prepend(sourceFile),
37 map : params.outputSourceMap && {
38 prev : !!params.absSourceMap && fileProtocol.prepend(params.absSourceMap),
39 inline : false,
40 annotation : false,
41 sourcesContent: true // #98 sourcesContent missing from output map
42 }
43 })
44 .then(result => ({
45 content: result.css,
46 map : params.outputSourceMap ? fileProtocol.remove(result.map.toJSON()) : null
47 }));
48
49 /**
50 * Plugin for postcss that follows SASS transpilation.
51 */
52 function postcssPlugin() {
53 return function applyPlugin(styles) {
54 styles.walkDecls(eachDeclaration);
55 };
56
57 /**
58 * Process a declaration from the syntax tree.
59 * @param declaration
60 */
61 function eachDeclaration(declaration) {
62 var prefix,
63 isValid = declaration.value && (declaration.value.indexOf('url') >= 0);
64 if (isValid) {
65 prefix = declaration.prop + declaration.raws.between;
66 declaration.value = params.transformDeclaration(declaration.value, getPathsAtChar);
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) ? '(found orphan CR, try removeCR option)' : '(no orphan CR found)')
100 );
101 } else {
102 throw new Error('a valid source-map is not present (ensure preceding loaders output a source-map)');
103 }
104 }
105 }
106 }
107
108 /**
109 * Given an apparent position find the directory of the original file.
110 *
111 * @param startPosApparent {{line: number, column: number}}
112 * @returns {false|string} Directory of original file or false on invalid
113 */
114 function positionToOriginalDirectory(startPosApparent) {
115 // reverse the original source-map to find the original source file before transpilation
116 var startPosOriginal =
117 !!params.sourceMapConsumer &&
118 params.sourceMapConsumer.originalPositionFor(startPosApparent);
119
120 // we require a valid directory for the specified file
121 var directory =
122 !!startPosOriginal &&
123 !!startPosOriginal.source &&
124 fileProtocol.remove(path.dirname(startPosOriginal.source));
125
126 return directory;
127 }
128}
129
130module.exports = process;
Note: See TracBrowser for help on using the repository browser.