-
-
Notifications
You must be signed in to change notification settings - Fork 469
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
added option to fix relative urls #186
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
/node_modules | ||
/node_modules | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
|
||
/** | ||
* When source maps are enabled, `style-loader` uses a link element with a data-uri to | ||
* embed the css on the page. This breaks all relative urls because now they are relative to a | ||
* bundle instead of the current page. | ||
* | ||
* One solution is to only use full urls, but that may be impossible. | ||
* | ||
* Instead, this function "fixes" the relative urls to be absolute according to the current page location. | ||
* | ||
* A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command. | ||
* | ||
*/ | ||
module.exports = function (css) { | ||
// get current location | ||
var location = typeof window !== "undefined" && window.location; | ||
|
||
if (!location) { | ||
throw new Error("fixUrls requires window.location"); | ||
} | ||
|
||
// blank or null? | ||
if (!css || typeof css !== "string") { | ||
return css; | ||
} | ||
|
||
var baseUrl = location.protocol + "//" + location.host; | ||
var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/"); | ||
|
||
// convert each url(...) | ||
var fixedCss = css.replace(/url *\( *(.+?) *\)/g, function(fullMatch, origUrl) { | ||
// strip quotes (if they exist) | ||
var unquotedOrigUrl = origUrl | ||
.replace(/^"(.*)"$/, function(o, $1){ return $1; }) | ||
.replace(/^'(.*)'$/, function(o, $1){ return $1; }); | ||
|
||
// already a full url? no change | ||
if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) { | ||
return fullMatch; | ||
} | ||
|
||
// convert the url to a full url | ||
var newUrl; | ||
|
||
if (unquotedOrigUrl.indexOf("//") === 0) { | ||
//TODO: should we add protocol? | ||
newUrl = unquotedOrigUrl; | ||
} else if (unquotedOrigUrl.indexOf("/") === 0) { | ||
// path should be relative to the base url | ||
newUrl = baseUrl + unquotedOrigUrl; // already starts with '/' | ||
} else { | ||
// path should be relative to current directory | ||
newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './' | ||
} | ||
|
||
// send back the fixed url(...) | ||
return "url(" + JSON.stringify(newUrl) + ")"; | ||
}); | ||
|
||
// send back the fixed css | ||
return fixedCss; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
// Node v4 requires "use strict" to allow block scoped let & const | ||
"use strict"; | ||
var assert = require("assert"); | ||
var url = require('url'); | ||
|
||
describe("fix urls tests", function() { | ||
var fixUrls = require("../fixUrls"); | ||
var defaultUrl = "https://x.y.z/a/b.html"; | ||
|
||
beforeEach(function() { | ||
global.window = { | ||
location: url.parse(defaultUrl) | ||
}; | ||
}); | ||
|
||
var assertUrl = function (origCss, expectedCss, specialUrl) { | ||
if (specialUrl) { | ||
global.window = { | ||
location: url.parse(specialUrl) | ||
}; | ||
} | ||
var resultCss = fixUrls(origCss, specialUrl || defaultUrl); | ||
expectedCss = expectedCss || origCss; | ||
|
||
assert.equal(resultCss, expectedCss); | ||
}; | ||
|
||
// no change | ||
it("Null css is not modified", function() { | ||
assertUrl(null) | ||
}); | ||
|
||
it("Blank css is not modified", function() { assertUrl("") }); | ||
|
||
it("No url is not modified", function () { assertUrl("body { }") }); | ||
|
||
it("Full url isn't changed (no quotes)", function() { | ||
assertUrl("body { background-image:url(http://example.com/bg.jpg); }") | ||
}); | ||
|
||
it("Full url isn't changed (no quotes, spaces)", function() { | ||
assertUrl("body { background-image:url ( http://example.com/bg.jpg ); }"); | ||
}); | ||
|
||
it("Full url isn't changed (double quotes)", function() { | ||
assertUrl("body { background-image:url(\"http://example.com/bg.jpg\"); }") | ||
}); | ||
|
||
it("Full url isn't changed (double quotes, spaces)", function() { | ||
assertUrl("body { background-image:url ( \"http://example.com/bg.jpg\" ); }") | ||
}); | ||
|
||
it("Full url isn't changed (single quotes)", function() { | ||
assertUrl("body { background-image:url('http://example.com/bg.jpg'); }") | ||
}); | ||
|
||
it("Full url isn't changed (single quotes, spaces)", function() { | ||
assertUrl("body { background-image:url ( 'http://example.com/bg.jpg' ); }") | ||
}); | ||
|
||
it("Multiple full urls are not changed", function() { | ||
assertUrl( | ||
"body { background-image:url(http://example.com/bg.jpg); }\ndiv.main { background-image:url ( 'https://www.anothersite.com/another.png' ); }" | ||
); | ||
}); | ||
|
||
it("Http url isn't changed", function() { | ||
assertUrl("body { background-image:url(http://example.com/bg.jpg); }"); | ||
}); | ||
|
||
it("Https url isn't changed", function() { | ||
assertUrl("body { background-image:url(https://example.com/bg.jpg); }"); | ||
}); | ||
|
||
it("HTTPS url isn't changed", function() { | ||
assertUrl("body { background-image:url(HTTPS://example.com/bg.jpg); }") | ||
}); | ||
|
||
it("File url isn't changed", function() { | ||
assertUrl("body { background-image:url(file:///example.com/bg.jpg); }") | ||
}); | ||
|
||
it("Double slash url isn't changed", function() { | ||
assertUrl( | ||
"body { background-image:url(//example.com/bg.jpg); }", | ||
"body { background-image:url(\"//example.com/bg.jpg\"); }" | ||
) | ||
}); | ||
|
||
it("Image data uri url isn't changed", function() { | ||
assertUrl("body { background-image:url(data:image/png;base64,qsrwABYuwNkimqm3gAAAABJRU5ErkJggg==); }") | ||
}); | ||
|
||
it("Font data uri url isn't changed", function() { | ||
assertUrl( | ||
"body { background-image:url(data:application/x-font-woff;charset=utf-8;base64,qsrwABYuwNkimqm3gAAAABJRU5ErkJggg); }" | ||
); | ||
}); | ||
|
||
// relative urls | ||
it("Relative url", function() { | ||
assertUrl( | ||
"body { background-image:url(bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }" | ||
); | ||
}); | ||
|
||
it("Relative url with path", function() { | ||
assertUrl( | ||
"body { background-image:url(c/d/bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/a/c/d/bg.jpg\"); }" | ||
); | ||
}); | ||
it("Relative url with dot slash", function() { | ||
assertUrl( | ||
"body { background-image:url(./c/d/bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/a/c/d/bg.jpg\"); }" | ||
); | ||
}); | ||
|
||
it("Multiple relative urls", function() { | ||
assertUrl( | ||
"body { background-image:url(bg.jpg); }\ndiv.main { background-image:url(./c/d/bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }\ndiv.main { background-image:url(\"https://x.y.z/a/c/d/bg.jpg\"); }" | ||
); | ||
}); | ||
it("Relative url that looks like data-uri", function() { | ||
assertUrl( | ||
"body { background-image:url(data/image/png.base64); }", | ||
"body { background-image:url(\"https://x.y.z/a/data/image/png.base64\"); }" | ||
); | ||
}); | ||
|
||
// urls with hashes | ||
it("Relative url with hash are not changed", function() { | ||
assertUrl("body { background-image:url(#bg.jpg); }"); | ||
}); | ||
|
||
// rooted urls | ||
it("Rooted url", function() { | ||
assertUrl( | ||
"body { background-image:url(/bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/bg.jpg\"); }" | ||
); | ||
}); | ||
it("Rooted url with path", function() { | ||
assertUrl( | ||
"body { background-image:url(/a/b/bg.jpg); }", | ||
"body { background-image:url(\"https://x.y.z/a/b/bg.jpg\"); }" | ||
); | ||
}); | ||
|
||
//special locations | ||
it("Location with no path, filename only", function() { | ||
assertUrl( | ||
"body { background-image:url(bg.jpg); }", | ||
"body { background-image:url(\"http://x.y.z/bg.jpg\"); }", | ||
"http://x.y.z" | ||
); | ||
}); | ||
|
||
it("Location with no path, path with filename", function() { | ||
assertUrl( | ||
"body { background-image:url(a/bg.jpg); }", | ||
"body { background-image:url(\"http://x.y.z/a/bg.jpg\"); }", | ||
"http://x.y.z" | ||
); | ||
}); | ||
it("Location with no path, rel path with filename", function() { | ||
assertUrl( | ||
"body { background-image:url(./a/bg.jpg); }", | ||
"body { background-image:url(\"http://x.y.z/a/bg.jpg\"); }", | ||
"http://x.y.z" | ||
); | ||
}); | ||
it("Location with no path, root filename", function() { | ||
assertUrl( | ||
"body { background-image:url(/a/bg.jpg); }", | ||
"body { background-image:url(\"http://x.y.z/a/bg.jpg\"); }", | ||
"http://x.y.z" | ||
); | ||
}); | ||
}); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the description it feels like there could be a better name for the parameter. How about
convertToAbsoluteUrls
?fixUrls
feels too vague and you have to look it up to understand what it fixes exactly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is general consensus that
convertToAbsoluteUrls
is the way we are going? I have no strong opinions about this as long as I get the feature so I can stop using a fork :)