summaryrefslogtreecommitdiff
path: root/node_modules/postcss-minify-font-values
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-minify-font-values
parent3fd9400d4dccc25aa29b5702216732e0b7542073 (diff)
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/postcss-minify-font-values')
-rw-r--r--node_modules/postcss-minify-font-values/LICENSE22
-rw-r--r--node_modules/postcss-minify-font-values/README.md81
-rw-r--r--node_modules/postcss-minify-font-values/package.json39
-rw-r--r--node_modules/postcss-minify-font-values/src/index.js98
-rw-r--r--node_modules/postcss-minify-font-values/src/lib/keywords.js40
-rw-r--r--node_modules/postcss-minify-font-values/src/lib/minify-family.js248
-rw-r--r--node_modules/postcss-minify-font-values/src/lib/minify-font.js64
-rw-r--r--node_modules/postcss-minify-font-values/src/lib/minify-weight.js14
-rw-r--r--node_modules/postcss-minify-font-values/types/index.d.ts17
-rw-r--r--node_modules/postcss-minify-font-values/types/lib/keywords.d.ts5
-rw-r--r--node_modules/postcss-minify-font-values/types/lib/minify-family.d.ts2
-rw-r--r--node_modules/postcss-minify-font-values/types/lib/minify-font.d.ts2
-rw-r--r--node_modules/postcss-minify-font-values/types/lib/minify-weight.d.ts2
13 files changed, 634 insertions, 0 deletions
diff --git a/node_modules/postcss-minify-font-values/LICENSE b/node_modules/postcss-minify-font-values/LICENSE
new file mode 100644
index 00000000..6dcaefcb
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) Bogdan Chadkin <trysound@yandex.ru>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/postcss-minify-font-values/README.md b/node_modules/postcss-minify-font-values/README.md
new file mode 100644
index 00000000..23e90b8e
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/README.md
@@ -0,0 +1,81 @@
+# postcss-minify-font-values [![Build Status][ci-img]][ci]
+
+> Minify font declarations with PostCSS.
+
+This module will try to minimise the `font-family`, `font-weight` and `font` shorthand
+properties; it can unquote font families where necessary, detect & remove
+duplicates, and cut short a declaration after it finds a keyword. For more
+examples, see the [tests](test).
+
+```css
+h1 {
+ font:bold 2.2rem/.9 "Open Sans Condensed", sans-serif;
+}
+
+p {
+ font-family: "Helvetica Neue", Arial, sans-serif, Helvetica;
+ font-weight: normal;
+}
+```
+
+```css
+h1 {
+ font:700 2.2rem/.9 Open Sans Condensed,sans-serif
+}
+
+p {
+ font-family: Helvetica Neue,Arial,sans-serif;
+ font-weight: 400;
+}
+```
+
+## API
+
+### minifyFontValues([options])
+
+#### options
+
+##### removeAfterKeyword
+
+Type: `boolean`
+Default: `false`
+
+Pass `true` to remove font families after the module encounters a font keyword,
+for example `sans-serif`.
+
+##### removeDuplicates
+
+Type: `boolean`
+Default: `true`
+
+Pass `false` to disable the module from removing duplicated font families.
+
+##### removeQuotes
+
+Type: `boolean`
+Default: `true`
+
+Pass `false` to disable the module from removing quotes from font families.
+Note that oftentimes, this is a *safe optimisation* & is done safely. For more
+details, see [Mathias Bynens' article][mathias].
+
+## Usage
+
+```js
+postcss([ require('postcss-minify-font-values') ])
+```
+
+See [PostCSS] docs for examples for your environment.
+
+## Contributors
+
+See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).
+
+# License
+
+MIT © [Bogdan Chadkin](mailto:trysound@yandex.ru)
+
+[mathias]: https://mathiasbynens.be/notes/unquoted-font-family
+[PostCSS]: https://github.com/postcss/postcss
+[ci-img]: https://travis-ci.org/cssnano/postcss-minify-font-values.svg
+[ci]: https://travis-ci.org/cssnano/postcss-minify-font-values
diff --git a/node_modules/postcss-minify-font-values/package.json b/node_modules/postcss-minify-font-values/package.json
new file mode 100644
index 00000000..cf2d2d21
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "postcss-minify-font-values",
+ "version": "6.0.0",
+ "description": "Minify font declarations with PostCSS",
+ "main": "src/index.js",
+ "types": "types/index.d.ts",
+ "files": [
+ "src",
+ "LICENSE",
+ "types"
+ ],
+ "author": "Bogdan Chadkin <trysound@yandex.ru>",
+ "license": "MIT",
+ "keywords": [
+ "css",
+ "font",
+ "font-family",
+ "font-weight",
+ "optimise",
+ "postcss-plugin"
+ ],
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "repository": "cssnano/cssnano",
+ "bugs": {
+ "url": "https://github.com/cssnano/cssnano/issues"
+ },
+ "homepage": "https://github.com/cssnano/cssnano",
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "devDependencies": {
+ "postcss": "^8.2.15"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+} \ No newline at end of file
diff --git a/node_modules/postcss-minify-font-values/src/index.js b/node_modules/postcss-minify-font-values/src/index.js
new file mode 100644
index 00000000..2de13504
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/src/index.js
@@ -0,0 +1,98 @@
+'use strict';
+const valueParser = require('postcss-value-parser');
+const minifyWeight = require('./lib/minify-weight');
+const minifyFamily = require('./lib/minify-family');
+const minifyFont = require('./lib/minify-font');
+
+/**
+ * @param {string} value
+ * @return {boolean}
+ */
+function hasVariableFunction(value) {
+ const lowerCasedValue = value.toLowerCase();
+
+ return lowerCasedValue.includes('var(') || lowerCasedValue.includes('env(');
+}
+
+/**
+ * @param {string} prop
+ * @param {string} value
+ * @param {Options} opts
+ * @return {string}
+ */
+function transform(prop, value, opts) {
+ let lowerCasedProp = prop.toLowerCase();
+
+ if (lowerCasedProp === 'font-weight' && !hasVariableFunction(value)) {
+ return minifyWeight(value);
+ } else if (lowerCasedProp === 'font-family' && !hasVariableFunction(value)) {
+ const tree = valueParser(value);
+
+ tree.nodes = minifyFamily(tree.nodes, opts);
+
+ return tree.toString();
+ } else if (lowerCasedProp === 'font') {
+ const tree = valueParser(value);
+
+ tree.nodes = minifyFont(tree.nodes, opts);
+
+ return tree.toString();
+ }
+
+ return value;
+}
+
+/** @typedef {{removeAfterKeyword?: boolean, removeDuplicates?: boolean, removeQuotes?: boolean}} Options */
+
+/**
+ * @type {import('postcss').PluginCreator<Options>}
+ * @param {Options} opts
+ * @return {import('postcss').Plugin}
+ */
+function pluginCreator(opts) {
+ opts = Object.assign(
+ {},
+ {
+ removeAfterKeyword: false,
+ removeDuplicates: true,
+ removeQuotes: true,
+ },
+ opts
+ );
+
+ return {
+ postcssPlugin: 'postcss-minify-font-values',
+ prepare() {
+ const cache = new Map();
+ return {
+ OnceExit(css) {
+ css.walkDecls(/font/i, (decl) => {
+ const value = decl.value;
+
+ if (!value) {
+ return;
+ }
+
+ const prop = decl.prop;
+
+ const cacheKey = `${prop}|${value}`;
+
+ if (cache.has(cacheKey)) {
+ decl.value = cache.get(cacheKey);
+
+ return;
+ }
+
+ const newValue = transform(prop, value, opts);
+
+ decl.value = newValue;
+ cache.set(cacheKey, newValue);
+ });
+ },
+ };
+ },
+ };
+}
+
+pluginCreator.postcss = true;
+module.exports = pluginCreator;
diff --git a/node_modules/postcss-minify-font-values/src/lib/keywords.js b/node_modules/postcss-minify-font-values/src/lib/keywords.js
new file mode 100644
index 00000000..73950155
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/src/lib/keywords.js
@@ -0,0 +1,40 @@
+'use strict';
+module.exports = {
+ style: new Set(['italic', 'oblique']),
+ variant: new Set(['small-caps']),
+ weight: new Set([
+ '100',
+ '200',
+ '300',
+ '400',
+ '500',
+ '600',
+ '700',
+ '800',
+ '900',
+ 'bold',
+ 'lighter',
+ 'bolder',
+ ]),
+ stretch: new Set([
+ 'ultra-condensed',
+ 'extra-condensed',
+ 'condensed',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'expanded',
+ 'extra-expanded',
+ 'ultra-expanded',
+ ]),
+ size: new Set([
+ 'xx-small',
+ 'x-small',
+ 'small',
+ 'medium',
+ 'large',
+ 'x-large',
+ 'xx-large',
+ 'larger',
+ 'smaller',
+ ]),
+};
diff --git a/node_modules/postcss-minify-font-values/src/lib/minify-family.js b/node_modules/postcss-minify-font-values/src/lib/minify-family.js
new file mode 100644
index 00000000..5d6c4851
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/src/lib/minify-family.js
@@ -0,0 +1,248 @@
+'use strict';
+const { stringify } = require('postcss-value-parser');
+
+/**
+ * @param {string[]} list
+ * @return {string[]}
+ */
+function uniqueFontFamilies(list) {
+ return list.filter((item, i) => {
+ if (item.toLowerCase() === 'monospace') {
+ return true;
+ }
+ return i === list.indexOf(item);
+ });
+}
+
+const globalKeywords = ['inherit', 'initial', 'unset'];
+const genericFontFamilykeywords = new Set([
+ 'sans-serif',
+ 'serif',
+ 'fantasy',
+ 'cursive',
+ 'monospace',
+ 'system-ui',
+]);
+
+/**
+ * @param {string} value
+ * @param {number} length
+ * @return {string[]}
+ */
+function makeArray(value, length) {
+ let array = [];
+ while (length--) {
+ array[length] = value;
+ }
+ return array;
+}
+
+// eslint-disable-next-line no-useless-escape
+const regexSimpleEscapeCharacters = /[ !"#$%&'()*+,.\/;<=>?@\[\\\]^`{|}~]/;
+
+/**
+ * @param {string} string
+ * @param {boolean} escapeForString
+ * @return {string}
+ */
+function escape(string, escapeForString) {
+ let counter = 0;
+ let character;
+ let charCode;
+ let value;
+ let output = '';
+
+ while (counter < string.length) {
+ character = string.charAt(counter++);
+ charCode = character.charCodeAt(0);
+
+ // \r is already tokenized away at this point
+ // `:` can be escaped as `\:`, but that fails in IE < 8
+ if (!escapeForString && /[\t\n\v\f:]/.test(character)) {
+ value = '\\' + charCode.toString(16) + ' ';
+ } else if (
+ !escapeForString &&
+ regexSimpleEscapeCharacters.test(character)
+ ) {
+ value = '\\' + character;
+ } else {
+ value = character;
+ }
+
+ output += value;
+ }
+
+ if (!escapeForString) {
+ if (/^-[-\d]/.test(output)) {
+ output = '\\-' + output.slice(1);
+ }
+
+ const firstChar = string.charAt(0);
+
+ if (/\d/.test(firstChar)) {
+ output = '\\3' + firstChar + ' ' + output.slice(1);
+ }
+ }
+
+ return output;
+}
+
+const regexKeyword = new RegExp(
+ [...genericFontFamilykeywords].concat(globalKeywords).join('|'),
+ 'i'
+);
+const regexInvalidIdentifier = /^(-?\d|--)/;
+const regexSpaceAtStart = /^\x20/;
+const regexWhitespace = /[\t\n\f\r\x20]/g;
+const regexIdentifierCharacter = /^[a-zA-Z\d\xa0-\uffff_-]+$/;
+const regexConsecutiveSpaces = /(\\(?:[a-fA-F0-9]{1,6}\x20|\x20))?(\x20{2,})/g;
+const regexTrailingEscape = /\\[a-fA-F0-9]{0,6}\x20$/;
+const regexTrailingSpace = /\x20$/;
+
+/**
+ * @param {string} string
+ * @return {string}
+ */
+function escapeIdentifierSequence(string) {
+ let identifiers = string.split(regexWhitespace);
+ let index = 0;
+ /** @type {string[] | string} */
+ let result = [];
+ let escapeResult;
+
+ while (index < identifiers.length) {
+ let subString = identifiers[index++];
+
+ if (subString === '') {
+ result.push(subString);
+ continue;
+ }
+
+ escapeResult = escape(subString, false);
+
+ if (regexIdentifierCharacter.test(subString)) {
+ // the font family name part consists of allowed characters exclusively
+ if (regexInvalidIdentifier.test(subString)) {
+ // the font family name part starts with two hyphens, a digit, or a
+ // hyphen followed by a digit
+ if (index === 1) {
+ // if this is the first item
+ result.push(escapeResult);
+ } else {
+ // if it’s not the first item, we can simply escape the space
+ // between the two identifiers to merge them into a single
+ // identifier rather than escaping the start characters of the
+ // second identifier
+ result[index - 2] += '\\';
+ result.push(escape(subString, true));
+ }
+ } else {
+ // the font family name part doesn’t start with two hyphens, a digit,
+ // or a hyphen followed by a digit
+ result.push(escapeResult);
+ }
+ } else {
+ // the font family name part contains invalid identifier characters
+ result.push(escapeResult);
+ }
+ }
+
+ result = result.join(' ').replace(regexConsecutiveSpaces, ($0, $1, $2) => {
+ const spaceCount = $2.length;
+ const escapesNeeded = Math.floor(spaceCount / 2);
+ const array = makeArray('\\ ', escapesNeeded);
+
+ if (spaceCount % 2) {
+ array[escapesNeeded - 1] += '\\ ';
+ }
+
+ return ($1 || '') + ' ' + array.join(' ');
+ });
+
+ // Escape trailing spaces unless they’re already part of an escape
+ if (regexTrailingSpace.test(result) && !regexTrailingEscape.test(result)) {
+ result = result.replace(regexTrailingSpace, '\\ ');
+ }
+
+ if (regexSpaceAtStart.test(result)) {
+ result = '\\ ' + result.slice(1);
+ }
+
+ return result;
+}
+/**
+ * @param {import('postcss-value-parser').Node[]} nodes
+ * @param {import('../index').Options} opts
+ * @return {import('postcss-value-parser').WordNode[]}
+ */
+module.exports = function (nodes, opts) {
+ /** @type {import('postcss-value-parser').Node[]} */
+ const family = [];
+ /** @type {import('postcss-value-parser').WordNode | null} */
+ let last = null;
+ let i, max;
+
+ nodes.forEach((node, index, arr) => {
+ if (node.type === 'string' || node.type === 'function') {
+ family.push(node);
+ } else if (node.type === 'word') {
+ if (!last) {
+ last = /** @type {import('postcss-value-parser').WordNode} */ ({
+ type: 'word',
+ value: '',
+ });
+ family.push(last);
+ }
+
+ last.value += node.value;
+ } else if (node.type === 'space') {
+ if (last && index !== arr.length - 1) {
+ last.value += ' ';
+ }
+ } else {
+ last = null;
+ }
+ });
+
+ let normalizedFamilies = family.map((node) => {
+ if (node.type === 'string') {
+ const isKeyword = regexKeyword.test(node.value);
+
+ if (
+ !opts.removeQuotes ||
+ isKeyword ||
+ /[0-9]/.test(node.value.slice(0, 1))
+ ) {
+ return stringify(node);
+ }
+
+ let escaped = escapeIdentifierSequence(node.value);
+
+ if (escaped.length < node.value.length + 2) {
+ return escaped;
+ }
+ }
+
+ return stringify(node);
+ });
+
+ if (opts.removeAfterKeyword) {
+ for (i = 0, max = normalizedFamilies.length; i < max; i += 1) {
+ if (genericFontFamilykeywords.has(normalizedFamilies[i].toLowerCase())) {
+ normalizedFamilies = normalizedFamilies.slice(0, i + 1);
+ break;
+ }
+ }
+ }
+
+ if (opts.removeDuplicates) {
+ normalizedFamilies = uniqueFontFamilies(normalizedFamilies);
+ }
+
+ return [
+ /** @type {import('postcss-value-parser').WordNode} */ ({
+ type: 'word',
+ value: normalizedFamilies.join(),
+ }),
+ ];
+};
diff --git a/node_modules/postcss-minify-font-values/src/lib/minify-font.js b/node_modules/postcss-minify-font-values/src/lib/minify-font.js
new file mode 100644
index 00000000..82cd0e49
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/src/lib/minify-font.js
@@ -0,0 +1,64 @@
+'use strict';
+const { unit } = require('postcss-value-parser');
+const keywords = require('./keywords');
+const minifyFamily = require('./minify-family');
+const minifyWeight = require('./minify-weight');
+
+/**
+ * @param {import('postcss-value-parser').Node[]} nodes
+ * @param {import('../index').Options} opts
+ * @return {import('postcss-value-parser').Node[]}
+ */
+module.exports = function (nodes, opts) {
+ let i, max, node, family;
+ let familyStart = NaN;
+ let hasSize = false;
+
+ for (i = 0, max = nodes.length; i < max; i += 1) {
+ node = nodes[i];
+
+ if (node.type === 'word') {
+ if (hasSize) {
+ continue;
+ }
+
+ const value = node.value.toLowerCase();
+
+ if (
+ value === 'normal' ||
+ value === 'inherit' ||
+ value === 'initial' ||
+ value === 'unset'
+ ) {
+ familyStart = i;
+ } else if (keywords.style.has(value) || unit(value)) {
+ familyStart = i;
+ } else if (keywords.variant.has(value)) {
+ familyStart = i;
+ } else if (keywords.weight.has(value)) {
+ node.value = minifyWeight(value);
+ familyStart = i;
+ } else if (keywords.stretch.has(value)) {
+ familyStart = i;
+ } else if (keywords.size.has(value) || unit(value)) {
+ familyStart = i;
+ hasSize = true;
+ }
+ } else if (
+ node.type === 'function' &&
+ nodes[i + 1] &&
+ nodes[i + 1].type === 'space'
+ ) {
+ familyStart = i;
+ } else if (node.type === 'div' && node.value === '/') {
+ familyStart = i + 1;
+ break;
+ }
+ }
+
+ familyStart += 2;
+
+ family = minifyFamily(nodes.slice(familyStart), opts);
+
+ return nodes.slice(0, familyStart).concat(family);
+};
diff --git a/node_modules/postcss-minify-font-values/src/lib/minify-weight.js b/node_modules/postcss-minify-font-values/src/lib/minify-weight.js
new file mode 100644
index 00000000..3371f422
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/src/lib/minify-weight.js
@@ -0,0 +1,14 @@
+'use strict';
+/**
+ * @param {string} value
+ * @return {string}
+ */
+module.exports = function (value) {
+ const lowerCasedValue = value.toLowerCase();
+
+ return lowerCasedValue === 'normal'
+ ? '400'
+ : lowerCasedValue === 'bold'
+ ? '700'
+ : value;
+};
diff --git a/node_modules/postcss-minify-font-values/types/index.d.ts b/node_modules/postcss-minify-font-values/types/index.d.ts
new file mode 100644
index 00000000..d474f043
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/types/index.d.ts
@@ -0,0 +1,17 @@
+export = pluginCreator;
+/** @typedef {{removeAfterKeyword?: boolean, removeDuplicates?: boolean, removeQuotes?: boolean}} Options */
+/**
+ * @type {import('postcss').PluginCreator<Options>}
+ * @param {Options} opts
+ * @return {import('postcss').Plugin}
+ */
+declare function pluginCreator(opts: Options): import('postcss').Plugin;
+declare namespace pluginCreator {
+ export { postcss, Options };
+}
+type Options = {
+ removeAfterKeyword?: boolean;
+ removeDuplicates?: boolean;
+ removeQuotes?: boolean;
+};
+declare var postcss: true;
diff --git a/node_modules/postcss-minify-font-values/types/lib/keywords.d.ts b/node_modules/postcss-minify-font-values/types/lib/keywords.d.ts
new file mode 100644
index 00000000..5921cbb6
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/types/lib/keywords.d.ts
@@ -0,0 +1,5 @@
+export const style: Set<string>;
+export const variant: Set<string>;
+export const weight: Set<string>;
+export const stretch: Set<string>;
+export const size: Set<string>;
diff --git a/node_modules/postcss-minify-font-values/types/lib/minify-family.d.ts b/node_modules/postcss-minify-font-values/types/lib/minify-family.d.ts
new file mode 100644
index 00000000..51d8fd32
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/types/lib/minify-family.d.ts
@@ -0,0 +1,2 @@
+declare function _exports(nodes: import('postcss-value-parser').Node[], opts: import('../index').Options): import('postcss-value-parser').WordNode[];
+export = _exports;
diff --git a/node_modules/postcss-minify-font-values/types/lib/minify-font.d.ts b/node_modules/postcss-minify-font-values/types/lib/minify-font.d.ts
new file mode 100644
index 00000000..1de41fd3
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/types/lib/minify-font.d.ts
@@ -0,0 +1,2 @@
+declare function _exports(nodes: import('postcss-value-parser').Node[], opts: import('../index').Options): import('postcss-value-parser').Node[];
+export = _exports;
diff --git a/node_modules/postcss-minify-font-values/types/lib/minify-weight.d.ts b/node_modules/postcss-minify-font-values/types/lib/minify-weight.d.ts
new file mode 100644
index 00000000..01eb13be
--- /dev/null
+++ b/node_modules/postcss-minify-font-values/types/lib/minify-weight.d.ts
@@ -0,0 +1,2 @@
+declare function _exports(value: string): string;
+export = _exports;