source: imaps-frontend/node_modules/rtl-css-js/dist/esm/convert-9768a965.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 20.9 KB
RevLine 
[d565449]1/**
2 * Takes an array of [keyValue1, keyValue2] pairs and creates an object of {keyValue1: keyValue2, keyValue2: keyValue1}
3 * @param {Array} array the array of pairs
4 * @return {Object} the {key, value} pair object
5 */
6function arrayToObject(array) {
7 return array.reduce(function (obj, _ref) {
8 var prop1 = _ref[0],
9 prop2 = _ref[1];
10 obj[prop1] = prop2;
11 obj[prop2] = prop1;
12 return obj;
13 }, {});
14}
15function isBoolean(val) {
16 return typeof val === 'boolean';
17}
18function isFunction(val) {
19 return typeof val === 'function';
20}
21function isNumber(val) {
22 return typeof val === 'number';
23}
24function isNullOrUndefined(val) {
25 return val === null || typeof val === 'undefined';
26}
27function isObject(val) {
28 return val && typeof val === 'object';
29}
30function isString(val) {
31 return typeof val === 'string';
32}
33function includes(inclusive, inclusee) {
34 return inclusive.indexOf(inclusee) !== -1;
35}
36
37/**
38 * Flip the sign of a CSS value, possibly with a unit.
39 *
40 * We can't just negate the value with unary minus due to the units.
41 *
42 * @private
43 * @param {String} value - the original value (for example 77%)
44 * @return {String} the result (for example -77%)
45 */
46function flipSign(value) {
47 if (parseFloat(value) === 0) {
48 // Don't mangle zeroes
49 return value;
50 }
51 if (value[0] === '-') {
52 return value.slice(1);
53 }
54 return "-" + value;
55}
56function flipTransformSign(match, prefix, offset, suffix) {
57 return prefix + flipSign(offset) + suffix;
58}
59
60/**
61 * Takes a percentage for background position and inverts it.
62 * This was copied and modified from CSSJanus:
63 * https://github.com/cssjanus/cssjanus/blob/4245f834365f6cfb0239191a151432fb85abab23/src/cssjanus.js#L152-L175
64 * @param {String} value - the original value (for example 77%)
65 * @return {String} the result (for example 23%)
66 */
67function calculateNewBackgroundPosition(value) {
68 var idx = value.indexOf('.');
69 if (idx === -1) {
70 value = 100 - parseFloat(value) + "%";
71 } else {
72 // Two off, one for the "%" at the end, one for the dot itself
73 var len = value.length - idx - 2;
74 value = 100 - parseFloat(value);
75 value = value.toFixed(len) + "%";
76 }
77 return value;
78}
79
80/**
81 * This takes a list of CSS values and converts it to an array
82 * @param {String} value - something like `1px`, `1px 2em`, or `3pt rgb(150, 230, 550) 40px calc(100% - 5px)`
83 * @return {Array} the split values (for example: `['3pt', 'rgb(150, 230, 550)', '40px', 'calc(100% - 5px)']`)
84 */
85function getValuesAsList(value) {
86 return value.replace(/ +/g, ' ') // remove all extraneous spaces
87 .split(' ').map(function (i) {
88 return i.trim();
89 }) // get rid of extra space before/after each item
90 .filter(Boolean) // get rid of empty strings
91 // join items which are within parenthese
92 // luckily `calc (100% - 5px)` is invalid syntax and it must be `calc(100% - 5px)`, otherwise this would be even more complex
93 .reduce(function (_ref2, item) {
94 var list = _ref2.list,
95 state = _ref2.state;
96 var openParansCount = (item.match(/\(/g) || []).length;
97 var closedParansCount = (item.match(/\)/g) || []).length;
98 if (state.parensDepth > 0) {
99 list[list.length - 1] = list[list.length - 1] + " " + item;
100 } else {
101 list.push(item);
102 }
103 state.parensDepth += openParansCount - closedParansCount;
104 return {
105 list: list,
106 state: state
107 };
108 }, {
109 list: [],
110 state: {
111 parensDepth: 0
112 }
113 }).list;
114}
115
116/**
117 * This is intended for properties that are `top right bottom left` and will switch them to `top left bottom right`
118 * @param {String} value - `1px 2px 3px 4px` for example, but also handles cases where there are too few/too many and
119 * simply returns the value in those cases (which is the correct behavior)
120 * @return {String} the result - `1px 4px 3px 2px` for example.
121 */
122function handleQuartetValues(value) {
123 var splitValues = getValuesAsList(value);
124 if (splitValues.length <= 3 || splitValues.length > 4) {
125 return value;
126 }
127 var top = splitValues[0],
128 right = splitValues[1],
129 bottom = splitValues[2],
130 left = splitValues[3];
131 return [top, left, bottom, right].join(' ');
132}
133
134/**
135 *
136 * @param {String|Number|Object} value css property value to test
137 * @returns If the css property value can(should?) have an RTL equivalent
138 */
139function canConvertValue(value) {
140 return !isBoolean(value) && !isNullOrUndefined(value);
141}
142
143/**
144 * Splits a shadow style into its separate shadows using the comma delimiter, but creating an exception
145 * for comma separated values in parentheses often used for rgba colours.
146 * @param {String} value
147 * @returns {Array} array of all box shadow values in the string
148 */
149function splitShadow(value) {
150 var shadows = [];
151 var start = 0;
152 var end = 0;
153 var rgba = false;
154 while (end < value.length) {
155 if (!rgba && value[end] === ',') {
156 shadows.push(value.substring(start, end).trim());
157 end++;
158 start = end;
159 } else if (value[end] === "(") {
160 rgba = true;
161 end++;
162 } else if (value[end] === ')') {
163 rgba = false;
164 end++;
165 } else {
166 end++;
167 }
168 }
169
170 // push the last shadow value if there is one
171 // istanbul ignore next
172 if (start != end) {
173 shadows.push(value.substring(start, end + 1));
174 }
175 return shadows;
176}
177
178// some values require a little fudging, that fudging goes here.
179var propertyValueConverters = {
180 padding: function padding(_ref) {
181 var value = _ref.value;
182 if (isNumber(value)) {
183 return value;
184 }
185 return handleQuartetValues(value);
186 },
187 textShadow: function textShadow(_ref2) {
188 var value = _ref2.value;
189 var flippedShadows = splitShadow(value).map(function (shadow) {
190 // intentionally leaving off the `g` flag here because we only want to change the first number (which is the offset-x)
191 return shadow.replace(/(^|\s)(-*)([.|\d]+)/, function (match, whiteSpace, negative, number) {
192 if (number === '0') {
193 return match;
194 }
195 var doubleNegative = negative === '' ? '-' : '';
196 return "" + whiteSpace + doubleNegative + number;
197 });
198 });
199 return flippedShadows.join(',');
200 },
201 borderColor: function borderColor(_ref3) {
202 var value = _ref3.value;
203 return handleQuartetValues(value);
204 },
205 borderRadius: function borderRadius(_ref4) {
206 var value = _ref4.value;
207 if (isNumber(value)) {
208 return value;
209 }
210 if (includes(value, '/')) {
211 var _value$split = value.split('/'),
212 radius1 = _value$split[0],
213 radius2 = _value$split[1];
214 var convertedRadius1 = propertyValueConverters.borderRadius({
215 value: radius1.trim()
216 });
217 var convertedRadius2 = propertyValueConverters.borderRadius({
218 value: radius2.trim()
219 });
220 return convertedRadius1 + " / " + convertedRadius2;
221 }
222 var splitValues = getValuesAsList(value);
223 switch (splitValues.length) {
224 case 2:
225 {
226 return splitValues.reverse().join(' ');
227 }
228 case 4:
229 {
230 var topLeft = splitValues[0],
231 topRight = splitValues[1],
232 bottomRight = splitValues[2],
233 bottomLeft = splitValues[3];
234 return [topRight, topLeft, bottomLeft, bottomRight].join(' ');
235 }
236 default:
237 {
238 return value;
239 }
240 }
241 },
242 background: function background(_ref5) {
243 var value = _ref5.value,
244 valuesToConvert = _ref5.valuesToConvert,
245 isRtl = _ref5.isRtl,
246 bgImgDirectionRegex = _ref5.bgImgDirectionRegex,
247 bgPosDirectionRegex = _ref5.bgPosDirectionRegex;
248 if (isNumber(value)) {
249 return value;
250 }
251
252 // Yeah, this is in need of a refactor 🙃...
253 // but this property is a tough cookie 🍪
254 // get the backgroundPosition out of the string by removing everything that couldn't be the backgroundPosition value
255 var backgroundPositionValue = value.replace(/(url\(.*?\))|(rgba?\(.*?\))|(hsl\(.*?\))|(#[a-fA-F0-9]+)|((^| )(\D)+( |$))/g, '').trim();
256 // replace that backgroundPosition value with the converted version
257 value = value.replace(backgroundPositionValue, propertyValueConverters.backgroundPosition({
258 value: backgroundPositionValue,
259 valuesToConvert: valuesToConvert,
260 isRtl: isRtl,
261 bgPosDirectionRegex: bgPosDirectionRegex
262 }));
263 // do the backgroundImage value replacing on the whole value (because why not?)
264 return propertyValueConverters.backgroundImage({
265 value: value,
266 valuesToConvert: valuesToConvert,
267 bgImgDirectionRegex: bgImgDirectionRegex
268 });
269 },
270 backgroundImage: function backgroundImage(_ref6) {
271 var value = _ref6.value,
272 valuesToConvert = _ref6.valuesToConvert,
273 bgImgDirectionRegex = _ref6.bgImgDirectionRegex;
274 if (!includes(value, 'url(') && !includes(value, 'linear-gradient(')) {
275 return value;
276 }
277 return value.replace(bgImgDirectionRegex, function (match, g1, group2) {
278 return match.replace(group2, valuesToConvert[group2]);
279 });
280 },
281 backgroundPosition: function backgroundPosition(_ref7) {
282 var value = _ref7.value,
283 valuesToConvert = _ref7.valuesToConvert,
284 isRtl = _ref7.isRtl,
285 bgPosDirectionRegex = _ref7.bgPosDirectionRegex;
286 return value
287 // intentionally only grabbing the first instance of this because that represents `left`
288 .replace(isRtl ? /^((-|\d|\.)+%)/ : null, function (match, group) {
289 return calculateNewBackgroundPosition(group);
290 }).replace(bgPosDirectionRegex, function (match) {
291 return valuesToConvert[match];
292 });
293 },
294 backgroundPositionX: function backgroundPositionX(_ref8) {
295 var value = _ref8.value,
296 valuesToConvert = _ref8.valuesToConvert,
297 isRtl = _ref8.isRtl,
298 bgPosDirectionRegex = _ref8.bgPosDirectionRegex;
299 if (isNumber(value)) {
300 return value;
301 }
302 return propertyValueConverters.backgroundPosition({
303 value: value,
304 valuesToConvert: valuesToConvert,
305 isRtl: isRtl,
306 bgPosDirectionRegex: bgPosDirectionRegex
307 });
308 },
309 transition: function transition(_ref9) {
310 var value = _ref9.value,
311 propertiesToConvert = _ref9.propertiesToConvert;
312 return value.split(/,\s*/g).map(function (transition) {
313 var values = transition.split(' ');
314
315 // Property is always defined first
316 values[0] = propertiesToConvert[values[0]] || values[0];
317 return values.join(' ');
318 }).join(', ');
319 },
320 transitionProperty: function transitionProperty(_ref10) {
321 var value = _ref10.value,
322 propertiesToConvert = _ref10.propertiesToConvert;
323 return value.split(/,\s*/g).map(function (prop) {
324 return propertiesToConvert[prop] || prop;
325 }).join(', ');
326 },
327 transform: function transform(_ref11) {
328 var value = _ref11.value;
329 // This was copied and modified from CSSJanus:
330 // https://github.com/cssjanus/cssjanus/blob/4a40f001b1ba35567112d8b8e1d9d95eda4234c3/src/cssjanus.js#L152-L153
331 var nonAsciiPattern = "[^\\u0020-\\u007e]";
332 var escapePattern = "(?:" + '(?:(?:\\[0-9a-f]{1,6})(?:\\r\\n|\\s)?)' + "|\\\\[^\\r\\n\\f0-9a-f])";
333 var signedQuantPattern = "((?:-?" + ('(?:[0-9]*\\.[0-9]+|[0-9]+)' + "(?:\\s*" + '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)' + "|" + ("-?" + ("(?:[_a-z]|" + nonAsciiPattern + "|" + escapePattern + ")") + ("(?:[_a-z0-9-]|" + nonAsciiPattern + "|" + escapePattern + ")") + "*") + ")?") + ")|(?:inherit|auto))";
334 var translateXRegExp = new RegExp("(translateX\\s*\\(\\s*)" + signedQuantPattern + "(\\s*\\))", 'gi');
335 var translateRegExp = new RegExp("(translate\\s*\\(\\s*)" + signedQuantPattern + "((?:\\s*,\\s*" + signedQuantPattern + "){0,1}\\s*\\))", 'gi');
336 var translate3dRegExp = new RegExp("(translate3d\\s*\\(\\s*)" + signedQuantPattern + "((?:\\s*,\\s*" + signedQuantPattern + "){0,2}\\s*\\))", 'gi');
337 var rotateRegExp = new RegExp("(rotate[ZY]?\\s*\\(\\s*)" + signedQuantPattern + "(\\s*\\))", 'gi');
338 return value.replace(translateXRegExp, flipTransformSign).replace(translateRegExp, flipTransformSign).replace(translate3dRegExp, flipTransformSign).replace(rotateRegExp, flipTransformSign);
339 }
340};
341propertyValueConverters.objectPosition = propertyValueConverters.backgroundPosition;
342propertyValueConverters.margin = propertyValueConverters.padding;
343propertyValueConverters.borderWidth = propertyValueConverters.padding;
344propertyValueConverters.boxShadow = propertyValueConverters.textShadow;
345propertyValueConverters.webkitBoxShadow = propertyValueConverters.boxShadow;
346propertyValueConverters.mozBoxShadow = propertyValueConverters.boxShadow;
347propertyValueConverters.WebkitBoxShadow = propertyValueConverters.boxShadow;
348propertyValueConverters.MozBoxShadow = propertyValueConverters.boxShadow;
349propertyValueConverters.borderStyle = propertyValueConverters.borderColor;
350propertyValueConverters.webkitTransform = propertyValueConverters.transform;
351propertyValueConverters.mozTransform = propertyValueConverters.transform;
352propertyValueConverters.WebkitTransform = propertyValueConverters.transform;
353propertyValueConverters.MozTransform = propertyValueConverters.transform;
354propertyValueConverters.transformOrigin = propertyValueConverters.backgroundPosition;
355propertyValueConverters.webkitTransformOrigin = propertyValueConverters.transformOrigin;
356propertyValueConverters.mozTransformOrigin = propertyValueConverters.transformOrigin;
357propertyValueConverters.WebkitTransformOrigin = propertyValueConverters.transformOrigin;
358propertyValueConverters.MozTransformOrigin = propertyValueConverters.transformOrigin;
359propertyValueConverters.webkitTransition = propertyValueConverters.transition;
360propertyValueConverters.mozTransition = propertyValueConverters.transition;
361propertyValueConverters.WebkitTransition = propertyValueConverters.transition;
362propertyValueConverters.MozTransition = propertyValueConverters.transition;
363propertyValueConverters.webkitTransitionProperty = propertyValueConverters.transitionProperty;
364propertyValueConverters.mozTransitionProperty = propertyValueConverters.transitionProperty;
365propertyValueConverters.WebkitTransitionProperty = propertyValueConverters.transitionProperty;
366propertyValueConverters.MozTransitionProperty = propertyValueConverters.transitionProperty;
367
368// kebab-case versions
369
370propertyValueConverters['text-shadow'] = propertyValueConverters.textShadow;
371propertyValueConverters['border-color'] = propertyValueConverters.borderColor;
372propertyValueConverters['border-radius'] = propertyValueConverters.borderRadius;
373propertyValueConverters['background-image'] = propertyValueConverters.backgroundImage;
374propertyValueConverters['background-position'] = propertyValueConverters.backgroundPosition;
375propertyValueConverters['background-position-x'] = propertyValueConverters.backgroundPositionX;
376propertyValueConverters['object-position'] = propertyValueConverters.objectPosition;
377propertyValueConverters['border-width'] = propertyValueConverters.padding;
378propertyValueConverters['box-shadow'] = propertyValueConverters.textShadow;
379propertyValueConverters['-webkit-box-shadow'] = propertyValueConverters.textShadow;
380propertyValueConverters['-moz-box-shadow'] = propertyValueConverters.textShadow;
381propertyValueConverters['border-style'] = propertyValueConverters.borderColor;
382propertyValueConverters['-webkit-transform'] = propertyValueConverters.transform;
383propertyValueConverters['-moz-transform'] = propertyValueConverters.transform;
384propertyValueConverters['transform-origin'] = propertyValueConverters.transformOrigin;
385propertyValueConverters['-webkit-transform-origin'] = propertyValueConverters.transformOrigin;
386propertyValueConverters['-moz-transform-origin'] = propertyValueConverters.transformOrigin;
387propertyValueConverters['-webkit-transition'] = propertyValueConverters.transition;
388propertyValueConverters['-moz-transition'] = propertyValueConverters.transition;
389propertyValueConverters['transition-property'] = propertyValueConverters.transitionProperty;
390propertyValueConverters['-webkit-transition-property'] = propertyValueConverters.transitionProperty;
391propertyValueConverters['-moz-transition-property'] = propertyValueConverters.transitionProperty;
392
393// this will be an object of properties that map to their corresponding rtl property (their doppelganger)
394var propertiesToConvert = arrayToObject([['paddingLeft', 'paddingRight'], ['marginLeft', 'marginRight'], ['left', 'right'], ['borderLeft', 'borderRight'], ['borderLeftColor', 'borderRightColor'], ['borderLeftStyle', 'borderRightStyle'], ['borderLeftWidth', 'borderRightWidth'], ['borderTopLeftRadius', 'borderTopRightRadius'], ['borderBottomLeftRadius', 'borderBottomRightRadius'],
395// kebab-case versions
396['padding-left', 'padding-right'], ['margin-left', 'margin-right'], ['border-left', 'border-right'], ['border-left-color', 'border-right-color'], ['border-left-style', 'border-right-style'], ['border-left-width', 'border-right-width'], ['border-top-left-radius', 'border-top-right-radius'], ['border-bottom-left-radius', 'border-bottom-right-radius']]);
397var propsToIgnore = ['content'];
398
399// this is the same as the propertiesToConvert except for values
400var valuesToConvert = arrayToObject([['ltr', 'rtl'], ['left', 'right'], ['w-resize', 'e-resize'], ['sw-resize', 'se-resize'], ['nw-resize', 'ne-resize']]);
401
402// Sorry for the regex 😞, but basically thisis used to replace _every_ instance of
403// `ltr`, `rtl`, `right`, and `left` in `backgroundimage` with the corresponding opposite.
404// A situation we're accepting here:
405// url('/left/right/rtl/ltr.png') will be changed to url('/right/left/ltr/rtl.png')
406// Definite trade-offs here, but I think it's a good call.
407var bgImgDirectionRegex = new RegExp('(^|\\W|_)((ltr)|(rtl)|(left)|(right))(\\W|_|$)', 'g');
408var bgPosDirectionRegex = new RegExp('(left)|(right)');
409
410/**
411 * converts properties and values in the CSS in JS object to their corresponding RTL values
412 * @param {Object} object the CSS in JS object
413 * @return {Object} the RTL converted object
414 */
415function convert(object) {
416 return Object.keys(object).reduce(function (newObj, originalKey) {
417 var originalValue = object[originalKey];
418 if (isString(originalValue)) {
419 // you're welcome to later code 😺
420 originalValue = originalValue.trim();
421 }
422
423 // Some properties should never be transformed
424 if (includes(propsToIgnore, originalKey)) {
425 newObj[originalKey] = originalValue;
426 return newObj;
427 }
428 var _convertProperty = convertProperty(originalKey, originalValue),
429 key = _convertProperty.key,
430 value = _convertProperty.value;
431 newObj[key] = value;
432 return newObj;
433 }, Array.isArray(object) ? [] : {});
434}
435
436/**
437 * Converts a property and its value to the corresponding RTL key and value
438 * @param {String} originalKey the original property key
439 * @param {Number|String|Object} originalValue the original css property value
440 * @return {Object} the new {key, value} pair
441 */
442function convertProperty(originalKey, originalValue) {
443 var isNoFlip = /\/\*\s?@noflip\s?\*\//.test(originalValue);
444 var key = isNoFlip ? originalKey : getPropertyDoppelganger(originalKey);
445 var value = isNoFlip ? originalValue : getValueDoppelganger(key, originalValue);
446 return {
447 key: key,
448 value: value
449 };
450}
451
452/**
453 * This gets the RTL version of the given property if it has a corresponding RTL property
454 * @param {String} property the name of the property
455 * @return {String} the name of the RTL property
456 */
457function getPropertyDoppelganger(property) {
458 return propertiesToConvert[property] || property;
459}
460
461/**
462 * This converts the given value to the RTL version of that value based on the key
463 * @param {String} key this is the key (note: this should be the RTL version of the originalKey)
464 * @param {String|Number|Object} originalValue the original css property value. If it's an object, then we'll convert that as well
465 * @return {String|Number|Object} the converted value
466 */
467function getValueDoppelganger(key, originalValue) {
468 if (!canConvertValue(originalValue)) {
469 return originalValue;
470 }
471 if (isObject(originalValue)) {
472 return convert(originalValue); // recursion 🌀
473 }
474
475 var isNum = isNumber(originalValue);
476 var isFunc = isFunction(originalValue);
477 var importantlessValue = isNum || isFunc ? originalValue : originalValue.replace(/ !important.*?$/, '');
478 var isImportant = !isNum && importantlessValue.length !== originalValue.length;
479 var valueConverter = propertyValueConverters[key];
480 var newValue;
481 if (valueConverter) {
482 newValue = valueConverter({
483 value: importantlessValue,
484 valuesToConvert: valuesToConvert,
485 propertiesToConvert: propertiesToConvert,
486 isRtl: true,
487 bgImgDirectionRegex: bgImgDirectionRegex,
488 bgPosDirectionRegex: bgPosDirectionRegex
489 });
490 } else {
491 newValue = valuesToConvert[importantlessValue] || importantlessValue;
492 }
493 if (isImportant) {
494 return newValue + " !important";
495 }
496 return newValue;
497}
498
499export { propertiesToConvert as a, propsToIgnore as b, convert as c, convertProperty as d, getValueDoppelganger as e, arrayToObject as f, getPropertyDoppelganger as g, calculateNewBackgroundPosition as h, canConvertValue as i, flipTransformSign as j, flipSign as k, handleQuartetValues as l, includes as m, isBoolean as n, isFunction as o, propertyValueConverters as p, isNumber as q, isNullOrUndefined as r, isObject as s, isString as t, getValuesAsList as u, valuesToConvert as v, splitShadow as w };
Note: See TracBrowser for help on using the repository browser.