Skip to content

feat: Resolve relative URLs in property values #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ See [PostCSS](https://github.com/postcss/postcss#usage) docs for examples for yo

## Options
* `recursive` (boolean) To import URLs recursively (default: `true`)
* `modernBrowser` (boolean) set user-agent string to 'Mozilla/5.0 AppleWebKit/537.36 Chrome/65.0.0.0 Safari/537.36', this option maybe useful for importing fonts from Google. Google check `user-agent` header string and respond can be different (default: `false`)
* `resolveUrls` (boolean) To transform relative URLs found in remote stylesheets into fully qualified URLs ([see #18](https://github.com/unlight/postcss-import-url/pull/18)) (default: `false`)
* `modernBrowser` (boolean) Set user-agent string to 'Mozilla/5.0 AppleWebKit/537.36 Chrome/65.0.0.0 Safari/537.36', this option maybe useful for importing fonts from Google. Google check `user-agent` header string and respond can be different (default: `false`)
* `userAgent` (string) Custom user-agent header (default: `null`)

## Known Issues
Expand Down
14 changes: 14 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ var resolveRelative = require("resolve-relative-url");
var assign = require("lodash.assign");
var defaults = {
recursive: true,
resolveURLs: false,
modernBrowser: false,
userAgent: null
};
var space = postcss.list.space;
var url = require('url');
var urlRegexp = /url\(["'].+?['"]\)/;

function postcssImportUrl(options) {
options = assign({}, defaults, options || {});
Expand All @@ -35,6 +37,14 @@ function postcssImportUrl(options) {
mediaNode.append(newNode);
newNode = mediaNode;
}

if (options.resolveUrls) {
// Convert relative paths to absolute paths
newNode = newNode.replaceValues(urlRegexp, { fast: 'url(' }, function(url) {
return resolveUrls(url, remoteFile);
});
}

var p = (options.recursive) ? importUrl(newNode, null, r.parent) : Promise.resolve(newNode);
return p.then(function(tree) {
atRule.replaceWith(tree);
Expand All @@ -57,6 +67,10 @@ function cleanupRemoteFile(value) {
return value;
}

function resolveUrls(to, from) {
return 'url("' + resolveRelative(cleanupRemoteFile(to), from) + '")';
}

function createPromise(remoteFile, options) {
var reqOptions = url.parse(remoteFile);
reqOptions.headers = {};
Expand Down
24 changes: 24 additions & 0 deletions test/fixture-3/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@import './recursive/b.css';

@font-face {
src: url("./font.woff");
}
.implicit-sibling {
background-image: url("implicit-sibling.png");
}
.absolute {
background-image: url("http://example.com/absolute.png");
}
.root-relative {
background-image: url("/root-relative.png");
}
.sibling {
background-image: url("./sibling.png");
}
.parent {
background-image: url("../parent.png");
}
.grandparent {
background-image: url("../../grandparent.png");
}

1 change: 1 addition & 0 deletions test/fixture-3/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<link rel="stylesheet" type="text/css" href="style.css">
19 changes: 19 additions & 0 deletions test/fixture-3/recursive/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@font-face {
src: url("../font-recursive.woff");
}

.sibling-recursive {
background-image: url("./sibling-recursive.png");
}

.parent-recursive {
background-image: url("../parent-recursive.png");
}

.grandparent-recursive {
background-image: url("../../grandparent-recursive.png");
}

.absolute-recursive {
background-image: url("http://example.com/absolute-recursive.png");
}
4 changes: 4 additions & 0 deletions test/fixture-3/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import url(http://localhost:1234/fixture-3/a.css);
.style {
content: ".style";
}
69 changes: 69 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,75 @@ describe("recursive import", function() {
});
});

describe("fixture-3 convert relative paths in property values", function() {

it("does not resolve relative URLs by default", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'src: url("./font.woff");', {}, {}, done);
});

it("does not resolve relative URLs when option.resolveURLs is false", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'src: url("./font.woff");', { resolveUrls: false }, {}, done);
});

var _opts = { resolveUrls: true };

it("resolves relative URLs when option.resolveURLs is true", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'src: url("http://localhost:1234/fixture-3/font.woff");', _opts, {}, done);
});

it("does not modify absolute paths", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://example.com/absolute.png");', _opts, {}, done);
});

it("makes root relative paths absolute", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/root-relative.png")', _opts, {}, done);
});

it("makes implicit sibling paths absolute", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/fixture-3/implicit-sibling.png")', _opts, {}, done);
});

it("makes relative sibling paths absolute", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/fixture-3/sibling.png")', _opts, {}, done);
});

it("makes parent relative paths absolute", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/parent.png")', _opts, {}, done);
});

it("makes grandparent relative paths absolute", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/grandparent.png")', _opts, {}, done);
});

var _optsRecursive = { resolveUrls: true, recursive: true };

// Test paths are resolved for recursively imported stylesheets
it("makes relative sibling paths absolute - recursive", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/fixture-3/recursive/sibling-recursive.png")', _optsRecursive, {}, done);
});

it("makes parent relative paths absolute - recursive", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/fixture-3/parent-recursive.png")', _optsRecursive, {}, done);
});

it("makes grandparent relative paths absolute - recursive", function(done) {
var input = '@import url(http://localhost:1234/fixture-3/style.css)';
testContains(input, 'background-image: url("http://localhost:1234/grandparent-recursive.png")', _optsRecursive, {}, done);
});

});

});

describe("google font woff", function() {
Expand Down