···11+MIT License
22+33+Copyright (c) 2018 Phil Plรผckthun
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+19
README.md
···11+# `tiny-css-prefixer`
22+33+**Bare essentials CSS prefixing helpers in less than 1KB ๐**
44+55+[](https://www.npmjs.com/package/tiny-css-prefixer)
66+[](https://unpkg.com/tiny-css-prefixer)
77+88+Currently supports prefixing properties for most browsers as it makes sense.
99+[See `SUPPORT.md` for more information on which prefixes and transformations have been omitted.](./SUPPORT.md)
1010+1111+The API is fairly straightforward and only consists of two functions, `prefixProperty` and `prefixValue`.
1212+1313+```js
1414+prefixProperty('margin'); // ['margin']
1515+prefixProperty('appearance'); // ['appearance', '-moz-appearance', '-webkit-appearance']
1616+1717+prefixValue('color', 'palevioletred'); // 'palevioletred'
1818+prefixValue('position', 'sticky'); // '-webkit-sticky, sticky'
1919+```
+41
SUPPORT.md
···11+# Support
22+33+This prefixer aims to be small in terms of bundle size but
44+also aims to support all common transformations and prefixes
55+for all evergreen browsers and IE11.
66+77+Most transformation can be expressed as simple prefixes, which
88+add `-ms-`, `-moz-`, or `-webkit-` to a CSS property.
99+These are compiled into three regular expressions, which is
1010+generated by `scripts/generate-prefix-map.js`.
1111+This code generation is based on the data available in
1212+`inline-style-prefixer` and `mdn-data/css`.
1313+1414+Some transformations are more complex and require full functions
1515+to be executed. However, not all transformations (i.e. "plugins")
1616+from `inline-style-prefixer` have been ported, since they're not
1717+all supported in IE11 anyway. If the output
1818+of a transformation is not supported in IE11, then it won't be
1919+included in this library, and additionally, if a transformation
2020+is not needed by any browser within a reasonable usage range,
2121+then it's also omitted:
2222+2323+- `calc`: Won't be prefixed with `-moz` for Firefox <16, as its
2424+ usage has dropped below 0.1%.
2525+- `cross-fade()`: Not supported by Firefox, Edge, or IE11.
2626+- `cursor`: Does not need to be prefixed for any supported browser.
2727+- `filter`: Not supported by Firefox, Edge, Chrome, or IE11.
2828+- `image-set()`: Not supported by Firefox, Edge, or IE11.
2929+- `animation`: All browsers that require prefixing have usage
3030+ numbers at or below 0.66%.
3131+- `transition`: All browsers that require prefixing have usage
3232+ numbers at or below 0.66%.
3333+- Intrinsic & Extrinsic Sizing: This is not widely supported yet,
3434+ with IE11 and Edge not supporting it, and most other browsers requiring
3535+ prefixes.
3636+- CSS Gradient functions: All browsers that require prefixing
3737+ have usage numbers at or below 0.66%.
3838+- `background-clip`: The `text` value does not transform to
3939+ `-webkit-text, text` as that's not supported in IE11.
4040+- Flexbox and Grid: No prefix is worth being performed due to the amount
4141+ of inconsistencies which would only apply to IE11.
···11+#!/usr/bin/env node
22+33+const fs = require('fs');
44+const path = require('path');
55+const prefixMap = require('inline-style-prefixer/lib/data').default.prefixMap;
66+const mdnProperties = require('mdn-data/css/properties.json');
77+88+const PREFIX_MS = 'ms';
99+const PREFIX_MOZ = 'Moz';
1010+const PREFIX_WEBKIT = 'Webkit';
1111+const prefixPropRe = /^-(ms|moz|webkit)-/;
1212+1313+/** A list of all properties that have to be prefixed */
1414+const properties = Object.keys(prefixMap)
1515+ .map(prop => ({
1616+ // Convert inline-style-based name to CSS property name
1717+ name: prop.replace(/[A-Z]/g, '-$&').toLowerCase(),
1818+ // This describes what kind of prefixes are necessary:
1919+ ms: !!prefixMap[prop].includes(PREFIX_MS),
2020+ moz: !!prefixMap[prop].includes(PREFIX_MOZ),
2121+ webkit: !!prefixMap[prop].includes(PREFIX_WEBKIT),
2222+ }))
2323+ // Omit CSS properties that are not listed by MDN or are obsolete
2424+ .filter(({ name }) => (
2525+ mdnProperties[name] &&
2626+ mdnProperties[name].status !== 'obsolete' &&
2727+ // Skip some properties that aren't widely supported or don't need prefixing:
2828+ name !== 'backdrop-filter' &&
2929+ name !== 'filter' &&
3030+ // Skip some properties that are obsolete:
3131+ name !== 'scroll-snap-points-x' &&
3232+ name !== 'scroll-snap-points-y' &&
3333+ name !== 'scroll-snap-points-destination' &&
3434+ name !== 'scroll-snap-points-coordinate' &&
3535+ name !== 'flow-into' &&
3636+ name !== 'flow-from' &&
3737+ name !== 'wrap-flow' &&
3838+ name !== 'wrap-through' &&
3939+ name !== 'wrap-margin'
4040+ ));
4141+4242+// See SUPPORT.md on background-clip
4343+properties.push({
4444+ name: 'background-clip',
4545+ ms: false,
4646+ moz: false,
4747+ webkit: true
4848+});
4949+5050+// These are supported in Firefox, Chrome, and Safari
5151+// NOTE: Their variants with before/after are not supported
5252+// by Firefox and should be avoided
5353+properties.push(...[
5454+ 'margin-start',
5555+ 'margin-end',
5656+ 'padding-start',
5757+ 'padding-end',
5858+ 'border-start',
5959+ 'border-start-color',
6060+ 'border-start-style',
6161+ 'border-start-width',
6262+ 'border-end',
6363+ 'border-end-color',
6464+ 'border-end-style',
6565+ 'border-end-width',
6666+].map(name => ({ name, ms: false, moz: true, webkit: true })));
6767+6868+/** A list of stable, non-prefixable property names */
6969+const stablePropertyNames = Object.keys(mdnProperties)
7070+ .filter(x => (
7171+ // Only include non-obsolete CSS properties
7272+ mdnProperties[x].status !== 'obsolete' &&
7373+ x !== 'all' &&
7474+ x !== '--*' &&
7575+ // Skip some properties that aren't widely supported:
7676+ x !== 'text-decoration-skip-ink' &&
7777+ x !== 'text-decoration-thickness' &&
7878+ // Exclude prefixed properties
7979+ !prefixPropRe.test(x) &&
8080+ // Exclude properties that are to be prefixed (i.e. non-standard)
8181+ !properties.some(({ name }) => name === x)
8282+ ));
8383+8484+/** Lists each prefixed property with the minimum substring that is needed to uniquely identity it */
8585+const prefixPatterns = properties
8686+ .map(prop => {
8787+ let name = prop.name;
8888+ for (let i = 2, l = name.length; i < l; i++) {
8989+ const substr = name.slice(0, i);
9090+ // Check for any name that conflicts with the substring in all known CSS properties
9191+ if (stablePropertyNames.every(x => x === name || !x.startsWith(substr))) {
9292+ name = substr;
9393+ break;
9494+ }
9595+ }
9696+9797+ return { ...prop, name };
9898+ });
9999+100100+/** Accepts a filter and builds a list of names in `prefixPatterns` */
101101+const reducePrefixes = (filter = x => !!x) => {
102102+ const set = prefixPatterns.reduce((acc, prop) => {
103103+ if (filter(prop)) acc.add(prop.name);
104104+ return acc;
105105+ }, new Set());
106106+107107+ return [...set].sort();
108108+};
109109+110110+const buildRegex = groups => `^(${groups.join('|')})`;
111111+112112+// Create all prefix sets for each prefix
113113+const msPrefixes = buildRegex(reducePrefixes(x => x.ms));
114114+const mozPrefixes = buildRegex(reducePrefixes(x => x.moz));
115115+const webkitPrefixes = buildRegex(reducePrefixes(x => x.webkit));
116116+117117+module.exports = `
118118+var msPrefixRe = /${msPrefixes}/;
119119+var mozPrefixRe = /${mozPrefixes}/;
120120+var webkitPrefixRe = /${webkitPrefixes}/;
121121+`.trim();
+7
src/index.d.ts
···11+export = CSSPrefixer;
22+export as namespace CSSPrefixer;
33+44+declare namespace CSSPrefixer {
55+ function prefixProperty(prop: string): string[];
66+ function prefixValue(prop: string, value: string): string;
77+}