Skip to content

Commit

Permalink
Merge 967b8f2 into 02913ab
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Sep 20, 2019
2 parents 02913ab + 967b8f2 commit 961f721
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 24 deletions.
20 changes: 10 additions & 10 deletions index.js
Expand Up @@ -6,15 +6,16 @@ const testParameter = (name, filters) => {
return filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
};

const normalizeDataURL = urlString => {
const parts = urlString.trim().match(/^data:(.*?),(.*)$/);
const normalizeDataURL = (urlString, {stripHash}) => {
const parts = urlString.match(/^data:(.*?),(.*?)(?:#(.*))?$/);

if (!parts) {
throw new Error(`Invalid URL: ${urlString}`);
}

const mediaType = parts[1].split(';');
const body = parts[2];
const hash = stripHash ? '' : parts[3];

let base64 = false;

Expand Down Expand Up @@ -50,7 +51,7 @@ const normalizeDataURL = urlString => {
normalizedMediaType.unshift(mimeType);
}

return `data:${normalizedMediaType.join(';')},${base64 ? body.trim() : body}`;
return `data:${normalizedMediaType.join(';')},${base64 ? body.trim() : body}${hash ? `#${hash}` : ''}`;
};

const normalizeUrl = (urlString, options) => {
Expand Down Expand Up @@ -84,11 +85,16 @@ const normalizeUrl = (urlString, options) => {

urlString = urlString.trim();

// Data URL
if (/^data:/i.test(urlString)) {
return normalizeDataURL(urlString, options);
}

const hasRelativeProtocol = urlString.startsWith('//');
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);

// Prepend protocol
if (!isRelativeUrl && !/^data:/i.test(urlString)) {
if (!isRelativeUrl) {
urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
}

Expand Down Expand Up @@ -177,12 +183,6 @@ const normalizeUrl = (urlString, options) => {
urlObj.searchParams.sort();
}

// Data URL
if (urlObj.protocol === 'data:') {
const url = normalizeDataURL(`${urlObj.protocol}${urlObj.pathname}`);
return `${url}${urlObj.search}${urlObj.hash}`;
}

if (options.removeTrailingSlash) {
urlObj.pathname = urlObj.pathname.replace(/\/$/, '');
}
Expand Down
48 changes: 34 additions & 14 deletions test.js
Expand Up @@ -221,29 +221,49 @@ test('data URL', t => {
// Lowercase the MIME type.
t.is(normalizeUrl('data:TEXT/plain,foo'), 'data:text/plain,foo');

// Strip empty hash.
t.is(normalizeUrl('data:,foo# '), 'data:,foo');

// Lowercase the charset.
t.is(normalizeUrl('data:text/plain;charset=UTF-8,foo'), 'data:text/plain;charset=utf-8,foo');

// Remove spaces after the comma when it's base64.
t.is(normalizeUrl('data:image/gif;base64, R0lGODlhAQABAAAAACw= ?foo=bar'), 'data:image/gif;base64,R0lGODlhAQABAAAAACw=?foo=bar');
t.is(normalizeUrl('data:image/gif;base64, R0lGODlhAQABAAAAACw= #foo #bar'), 'data:image/gif;base64,R0lGODlhAQABAAAAACw=#foo #bar');

// Keep spaces when it's not base64.
t.is(normalizeUrl('data:text/plain;charset=utf-8, foo ?foo=bar'), 'data:text/plain;charset=utf-8, foo?foo=bar');

// Data URL with query and hash.
t.is(normalizeUrl('data:image/gif;base64,R0lGODlhAQABAAAAACw=?foo=bar#baz'), 'data:image/gif;base64,R0lGODlhAQABAAAAACw=?foo=bar#baz');
t.is(normalizeUrl('data:text/plain;charset=utf-8, foo #bar'), 'data:text/plain;charset=utf-8, foo #bar');

// Options.
t.is(normalizeUrl('data:text/plain;charset=utf-8,www.foo/index.html?foo=bar&a=a&utm_medium=test#baz', {
// Protocol should not be changed.
t.is(normalizeUrl('data:,', {
defaultProtocol: 'http:',
normalizeProtocol: true,
forceHttp: true,
stripHash: true,
stripWWW: true,
stripProtocol: true,
stripProtocol: true
}), 'data:,');

// Option: removeTrailingSlash.
t.is(normalizeUrl('data:,foo/', {
removeTrailingSlash: true
}), 'data:,foo/');

// Option: removeDirectoryIndex.
t.is(normalizeUrl('data:,foo/index.html', {
removeTrailingSlash: true
}), 'data:,foo/index.html');

// Option: removeQueryParameters & sortQueryParameters.
t.is(normalizeUrl('data:,foo?foo=bar&a=a&utm_medium=test', {
removeQueryParameters: [/^utm_\w+/i, 'ref'],
sortQueryParameters: true,
removeTrailingSlash: true,
removeDirectoryIndex: true
}), 'data:text/plain;charset=utf-8,www.foo/index.html?a=a&foo=bar');
sortQueryParameters: true
}), 'data:,foo?foo=bar&a=a&utm_medium=test');

// Option: stripHash.
t.is(normalizeUrl('data:,foo#bar', {
stripHash: true
}), 'data:,foo');

// Option: stripWWW.
t.is(normalizeUrl('data:,www.foo.com', {
stripWWW: true
}), 'data:,www.foo.com');
});

0 comments on commit 961f721

Please sign in to comment.