source: imaps-frontend/node_modules/rtl-css-js/dist/rtl-css-js.umd.js

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

Update repo after prototype presentation

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