summaryrefslogtreecommitdiff
path: root/node_modules/postcss-normalize-url/src/normalize.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
commitc06f7ee0a40255214c477e13d9b956a7e07c2900 (patch)
treef5982a568ef8fab865d0142e71c7494fea3e4c1b /node_modules/postcss-normalize-url/src/normalize.js
parent3fd9400d4dccc25aa29b5702216732e0b7542073 (diff)
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/postcss-normalize-url/src/normalize.js')
-rw-r--r--node_modules/postcss-normalize-url/src/normalize.js153
1 files changed, 153 insertions, 0 deletions
diff --git a/node_modules/postcss-normalize-url/src/normalize.js b/node_modules/postcss-normalize-url/src/normalize.js
new file mode 100644
index 00000000..e6597e0d
--- /dev/null
+++ b/node_modules/postcss-normalize-url/src/normalize.js
@@ -0,0 +1,153 @@
+'use strict';
+/* Derived from normalize-url https://github.com/sindresorhus/normalize-url/main/index.js by Sindre Sorhus */
+
+// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
+const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
+const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
+
+const supportedProtocols = new Set(['https:', 'http:', 'file:']);
+
+/**
+ * @param {string} urlString
+ * @return {boolean} */
+function hasCustomProtocol(urlString) {
+ try {
+ const { protocol } = new URL(urlString);
+ return protocol.endsWith(':') && !supportedProtocols.has(protocol);
+ } catch {
+ return false;
+ }
+}
+
+/**
+ * @param {string} urlString
+ * @return {string} */
+function normalizeDataURL(urlString) {
+ const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(
+ urlString
+ );
+
+ if (!match) {
+ throw new Error(`Invalid URL: ${urlString}`);
+ }
+
+ let { type, data, hash } =
+ /** @type {{type: string, data: string, hash: string}} */ (match.groups);
+ const mediaType = type.split(';');
+
+ let isBase64 = false;
+ if (mediaType[mediaType.length - 1] === 'base64') {
+ mediaType.pop();
+ isBase64 = true;
+ }
+
+ // Lowercase MIME type
+ const mimeType = mediaType.shift()?.toLowerCase() ?? '';
+ const attributes = mediaType
+ .map(
+ /** @type {(string: string) => string} */ (attribute) => {
+ let [key, value = ''] = attribute
+ .split('=')
+ .map(
+ /** @type {(string: string) => string} */ (string) => string.trim()
+ );
+
+ // Lowercase `charset`
+ if (key === 'charset') {
+ value = value.toLowerCase();
+
+ if (value === DATA_URL_DEFAULT_CHARSET) {
+ return '';
+ }
+ }
+
+ return `${key}${value ? `=${value}` : ''}`;
+ }
+ )
+ .filter(Boolean);
+
+ const normalizedMediaType = [...attributes];
+
+ if (isBase64) {
+ normalizedMediaType.push('base64');
+ }
+
+ if (
+ normalizedMediaType.length > 0 ||
+ (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)
+ ) {
+ normalizedMediaType.unshift(mimeType);
+ }
+
+ return `data:${normalizedMediaType.join(';')},${
+ isBase64 ? data.trim() : data
+ }${hash ? `#${hash}` : ''}`;
+}
+
+/**
+ * @param {string} urlString
+ * @return {string}
+ */
+function normalizeUrl(urlString) {
+ urlString = urlString.trim();
+
+ // Data URL
+ if (/^data:/i.test(urlString)) {
+ return normalizeDataURL(urlString);
+ }
+
+ if (hasCustomProtocol(urlString)) {
+ return urlString;
+ }
+
+ const hasRelativeProtocol = urlString.startsWith('//');
+ const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
+
+ // Prepend protocol
+ if (!isRelativeUrl) {
+ urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, 'http:');
+ }
+
+ const urlObject = new URL(urlString);
+
+ // Remove duplicate slashes if not preceded by a protocol
+ if (urlObject.pathname) {
+ urlObject.pathname = urlObject.pathname.replace(
+ /(?<!\b[a-z][a-z\d+\-.]{1,50}:)\/{2,}/g,
+ '/'
+ );
+ }
+
+ // Decode URI octets
+ if (urlObject.pathname) {
+ try {
+ urlObject.pathname = decodeURI(urlObject.pathname);
+ } catch {
+ /* Do nothing */
+ }
+ }
+
+ if (urlObject.hostname) {
+ // Remove trailing dot
+ urlObject.hostname = urlObject.hostname.replace(/\.$/, '');
+ }
+
+ urlObject.pathname = urlObject.pathname.replace(/\/$/, '');
+
+ // Take advantage of many of the Node `url` normalizations
+ urlString = urlObject.toString();
+
+ // Remove ending `/`
+ if (urlObject.pathname === '/' && urlObject.hash === '') {
+ urlString = urlString.replace(/\/$/, '');
+ }
+
+ // Restore relative protocol
+ if (hasRelativeProtocol) {
+ urlString = urlString.replace(/^http:\/\//, '//');
+ }
+
+ return urlString;
+}
+
+module.exports = normalizeUrl;