···3838 return css;
3939};
4040```
4141+4242+Additionally `prefixValue` can accept full declarations to avoid
4343+having to apply it before concatenation, which can be useful in case
4444+you're trying to minimise string operations:
4545+4646+```js
4747+const declaration = 'position: sticky';
4848+prefixValue(declaration, declaration); // 'position: -webkit-sticky, sticky'
4949+```
···4949// NOTE: Their variants with before/after are not supported
5050// by Firefox and should be avoided
5151properties.push(...[
5252- 'margin-start',
5353- 'margin-end',
5454- 'padding-start',
5555- 'padding-end',
5652 'border-start',
5753 'border-start-color',
5854 'border-start-style',
···8379 !properties.some(({ name }) => name === x)
8480 ));
85818686-/** Lists each prefixed property with the minimum substring that is needed to uniquely identity it */
8787-const prefixPatterns = properties
8888- .map(prop => {
8989- let name = prop.name;
9090- for (let i = 2, l = name.length; i < l; i++) {
9191- const substr = name.slice(0, i);
9292- // Check for any name that conflicts with the substring in all known CSS properties
9393- if (stablePropertyNames.every(x => x === name || !x.startsWith(substr))) {
9494- name = substr;
9595- break;
9696- }
8282+/** Finds the minimum starting substring that uniquely identifier a property out of all known CSS properties */
8383+const findMinimumSubstr = name => {
8484+ for (let i = 2, l = name.length; i < l; i++) {
8585+ const substr = name.slice(0, i);
8686+ // Check for any name that conflicts with the substring in all known CSS properties
8787+ if (stablePropertyNames.every(x => x === name || !x.startsWith(substr))) {
8888+ return substr;
9789 }
9090+ }
98919999- return { ...prop, name };
100100- });
9292+ return name;
9393+};
9494+9595+/** Lists each prefixed property with the minimum substring that is needed to uniquely identity it */
9696+const prefixPatterns = properties.map(prop => ({
9797+ ...prop,
9898+ name: findMinimumSubstr(prop.name)
9999+}));
100100+101101+/** For Webkit prefixes, these properties will need some values to be prefixed */
102102+const prefixValuePatterns = ['position', 'background-clip'].map(findMinimumSubstr);
101103102104/** Accepts a filter and builds a list of names in `prefixPatterns` */
103105const reducePrefixes = (filter = x => !!x) => {
···106108 return acc;
107109 }, new Set());
108110109109- return [...set].sort();
111111+ return [...set].sort((a, b) => {
112112+ if (a.length === b.length) return a.localeCompare(b);
113113+ return a.length - b.length;
114114+ });
110115};
111116117117+/** Creates a regex matching property names */
112118const buildRegex = groups => `^(${groups.join('|')})`;
113119114120// Create all prefix sets for each prefix
···116122const mozPrefixes = buildRegex(reducePrefixes(x => x.moz));
117123const webkitPrefixes = buildRegex(reducePrefixes(x => x.webkit));
118124125125+// Create a regex for webkit value transforms
126126+const webkitValuePrefix = buildRegex(prefixValuePatterns);
127127+119128module.exports = `
120129var msPrefixRe = /${msPrefixes}/;
121130var mozPrefixRe = /${mozPrefixes}/;
122131var webkitPrefixRe = /${webkitPrefixes}/;
132132+var webkitValuePrefixRe = /${webkitValuePrefix}/;
123133`.trim();