Skip to content

Commit

Permalink
Merge pull request #202 from bholloway/initial-v5-changes
Browse files Browse the repository at this point in the history
Initial v5 changes
  • Loading branch information
bholloway committed May 20, 2021
2 parents e094fa6 + b168dd3 commit 1cd5be8
Show file tree
Hide file tree
Showing 43 changed files with 588 additions and 4,070 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.9
12
19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,27 @@
"devDependencies": {
"blue-tape": "^1.0.0",
"compose-function": "^3.0.3",
"cross-env": "^6.0.3",
"cross-env": "^7.0.3",
"enforce-node-version": "^0.1.0",
"es6-promisify": "^6.0.2",
"escape-string-regexp": "^2.0.0",
"escape-string-regexp": "^4.0.0",
"get-value": "^3.0.1",
"has-prop": "^0.1.2",
"joi": "^14.3.1",
"jshint": "^2.10.3",
"micromatch": "^4.0.2",
"ms": "^2.1.2",
"outdent": "^0.7.0",
"micromatch": "^4.0.4",
"ms": "^2.1.3",
"outdent": "^0.8.0",
"promise-compose": "^1.1.2",
"recursive-readdir": "^2.2.2",
"rework": "1.0.1",
"rework-visit": "1.0.0",
"sinon": "^8.0.2",
"sinon": "^10.0.0",
"tap-diff": "^0.1.1",
"vlq": "^1.0.1"
},
"engines": {
"node": ">=8.9"
"node": ">=12"
},
"resolutions": {
"diff": "^3.5.0",
"lodash": "^4.17.21"
"diff": "^4.0.2"
}
}
2 changes: 1 addition & 1 deletion packages/resolve-url-loader-filesearch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"homepage": "https://github.com/bholloway/resolve-url-loader",
"engines": {
"node": ">=8.9"
"node": ">=12"
},
"files": [
"index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/resolve-url-loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var valueProcessor = require('./lib/value-processor'),
const DEPRECATED_OPTIONS = {
engine: [
'DEP_RESOLVE_URL_LOADER_OPTION_ENGINE',
'the "engine" option is deprecated, "postcss" engine is the default, using "rework" engine is not advised'
'the "engine" option is deprecated, "postcss" engine is the default, there are no other available engines'
],
keepQuery: [
'DEP_RESOLVE_URL_LOADER_OPTION_KEEP_QUERY',
Expand Down
171 changes: 90 additions & 81 deletions packages/resolve-url-loader/lib/engine/postcss.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
*/
'use strict';

var os = require('os'),
path = require('path'),
postcss = require('postcss');
const os = require('os');
const path = require('path');
const postcss = require('postcss');

var fileProtocol = require('../file-protocol');
var algerbra = require('../position-algerbra');
const fileProtocol = require('../file-protocol');
const algerbra = require('../position-algerbra');

var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
const ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;

/**
* Process the given CSS content into reworked CSS content.
Expand All @@ -24,66 +24,96 @@ var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
*/
function process(sourceFile, sourceContent, params) {
// #107 libsass emits orphan CR not considered newline, postcss does consider newline (content vs source-map mismatch)
var correctedContent = params.removeCR && (os.EOL !== '\r') ?
const correctedContent = params.removeCR && (os.EOL !== '\r') ?
sourceContent.replace(ORPHAN_CR_REGEX, ' $1') :
sourceContent;

/**
* Plugin for postcss that follows SASS transpilation.
*/
const postcssPlugin = {
postcssPlugin: 'postcss-resolve-url',
Declaration: (declaration) => {
var prefix,
isValid = declaration.value && (declaration.value.indexOf('url') >= 0);
if (isValid) {
prefix = declaration.prop + declaration.raws.between;
declaration.value = params.transformDeclaration(declaration.value, getPathsAtChar);
}
// IMPORTANT - prepend file protocol to all sources to avoid problems with source map
const plugin = Object.assign(
() => ({
postcssPlugin: 'postcss-resolve-url',
prepare: () => {
const visited = new Set();

/**
* Given an apparent position find the directory of the original file.
*
* @param startPosApparent {{line: number, column: number}}
* @returns {false|string} Directory of original file or false on invalid
*/
const positionToOriginalDirectory = (startPosApparent) => {
// reverse the original source-map to find the original source file before transpilation
const startPosOriginal =
!!params.sourceMapConsumer &&
params.sourceMapConsumer.originalPositionFor(startPosApparent);

/**
* Create a hash of base path strings.
*
* Position in the declaration is supported by postcss at the position of the url() statement.
*
* @param {number} index Index in the declaration value at which to evaluate
* @throws Error on invalid source map
* @returns {{subString:string, value:string, property:string, selector:string}} Hash of base path strings
*/
function getPathsAtChar(index) {
var subString = declaration.value.slice(0, index),
posSelector = algerbra.sanitise(declaration.parent.source.start),
posProperty = algerbra.sanitise(declaration.source.start),
posValue = algerbra.add([posProperty, algerbra.strToOffset(prefix)]),
posSubString = algerbra.add([posValue, algerbra.strToOffset(subString)]);
// we require a valid directory for the specified file
const directory =
!!startPosOriginal &&
!!startPosOriginal.source &&
fileProtocol.remove(path.dirname(startPosOriginal.source));

var result = {
subString: positionToOriginalDirectory(posSubString),
value : positionToOriginalDirectory(posValue),
property : positionToOriginalDirectory(posProperty),
selector : positionToOriginalDirectory(posSelector)
return directory;
};

var isValid = [result.subString, result.value, result.property, result.selector].every(Boolean);
if (isValid) {
return result;
}
else if (params.sourceMapConsumer) {
throw new Error(
'source-map information is not available at url() declaration ' +
(ORPHAN_CR_REGEX.test(sourceContent) ? '(found orphan CR, try removeCR option)' : '(no orphan CR found)')
);
} else {
throw new Error('a valid source-map is not present (ensure preceding loaders output a source-map)');
}
return {
Declaration: (declaration) => {
var prefix,
isValid = declaration.value && (declaration.value.indexOf('url') >= 0) && !visited.has(declaration);
if (isValid) {
prefix = declaration.prop + declaration.raws.between;
declaration.value = params.transformDeclaration(declaration.value, getPathsAtChar);
visited.add(declaration);
}

/**
* Create a hash of base path strings.
*
* Position in the declaration is supported by postcss at the position of the url() statement.
*
* @param {number} index Index in the declaration value at which to evaluate
* @throws Error on invalid source map
* @returns {{subString:string, value:string, property:string, selector:string}} Hash of base path strings
*/
function getPathsAtChar(index) {
var subString = declaration.value.slice(0, index),
posSelector = algerbra.sanitise(declaration.parent.source.start),
posProperty = algerbra.sanitise(declaration.source.start),
posValue = algerbra.add([posProperty, algerbra.strToOffset(prefix)]),
posSubString = algerbra.add([posValue, algerbra.strToOffset(subString)]);

var result = {
subString: positionToOriginalDirectory(posSubString),
value : positionToOriginalDirectory(posValue),
property : positionToOriginalDirectory(posProperty),
selector : positionToOriginalDirectory(posSelector)
};

var isValid = [result.subString, result.value, result.property, result.selector].every(Boolean);
if (isValid) {
return result;
}
else if (params.sourceMapConsumer) {
throw new Error(
'source-map information is not available at url() declaration ' + (
ORPHAN_CR_REGEX.test(sourceContent) ?
'(found orphan CR, try removeCR option)' :
'(no orphan CR found)'
)
);
} else {
throw new Error('a valid source-map is not present (ensure preceding loaders output a source-map)');
}
}
}
};
}
}
}
}),
{ postcss: true }
);

// prepend file protocol to all sources to avoid problems with source map
return postcss([
postcssPlugin
])
// IMPORTANT - prepend file protocol to all sources to avoid problems with source map
return postcss([plugin])
.process(correctedContent, {
from: fileProtocol.prepend(sourceFile),
map : params.outputSourceMap && {
Expand All @@ -93,31 +123,10 @@ function process(sourceFile, sourceContent, params) {
sourcesContent: true // #98 sourcesContent missing from output map
}
})
.then(result => ({
content: result.css,
map : params.outputSourceMap ? fileProtocol.remove(result.map.toJSON()) : null
.then(({css, map}) => ({
content: css,
map : params.outputSourceMap ? fileProtocol.remove(map.toJSON()) : null
}));

/**
* Given an apparent position find the directory of the original file.
*
* @param startPosApparent {{line: number, column: number}}
* @returns {false|string} Directory of original file or false on invalid
*/
function positionToOriginalDirectory(startPosApparent) {
// reverse the original source-map to find the original source file before transpilation
var startPosOriginal =
!!params.sourceMapConsumer &&
params.sourceMapConsumer.originalPositionFor(startPosApparent);

// we require a valid directory for the specified file
var directory =
!!startPosOriginal &&
!!startPosOriginal.source &&
fileProtocol.remove(path.dirname(startPosOriginal.source));

return directory;
}
}

module.exports = process;
Loading

0 comments on commit 1cd5be8

Please sign in to comment.