|
1 |
| -import CSS_COLOR_NAMES from "./html-colors"; |
2 |
| -import toPx from "./css-length-converter"; |
| 1 | +import CSS_COLOR_NAMES from "./external/bobspace:html-colors"; |
| 2 | +import toPx from "./external/heygrady:units:length"; |
3 | 3 |
|
4 |
| -function _getAttributeFromString(string, method, ...data) { |
5 |
| - if (!string) return false |
6 |
| - string = string.split(' ') |
7 |
| - for (let i in string) { |
8 |
| - const res = method(string, Number(i), ...data) |
9 |
| - if (res) return res |
10 |
| - } |
11 |
| -} |
12 |
| - |
13 |
| -function _getColor(border, i) { |
14 |
| - const val = border[i] |
| 4 | +/** @returns {string} */ |
| 5 | +function convertPlainColor(val) { |
| 6 | + if (!val) return '#000' |
| 7 | + val = val?.toLowerCase() |
15 | 8 | // color is a hex code
|
16 |
| - if (val.toLowerCase().match(/#([0-9a-f]{3}){1,2}/)) return val |
| 9 | + if (val?.match(/#([0-9a-f]{3}){1,2}/)) return val |
17 | 10 | // color is a function (rgb, rgba, hsl, hsla)
|
18 |
| - if (val.startsWith('rgb') || val.startsWith('hsl')) { |
19 |
| - let color = val; |
20 |
| - if (!val.endsWith(')')) |
21 |
| - for (let j = 1; !border[i + j - 1].endsWith(')'); j++) { |
22 |
| - color += border[i + j] |
23 |
| - } |
24 |
| - if (color[3] === 'a') |
25 |
| - color = color.replace('a', '').replace(/,[^),]+\)/, ')') |
26 |
| - return color |
27 |
| - } |
| 11 | + else if (val?.match(/^(rgb|hsl)a?\(([^,]{1,3},? *){3}(\d*\.?\d+)?\)/)) |
| 12 | + return val |
| 13 | + .replace('a', '') |
| 14 | + .replace(/\((([\d%]{1,3}, *){2}([\d%]{1,3}))(, *\d*\.?\d+)?\)/, '($1)') |
28 | 15 | // color is a html color name
|
29 |
| - if ( |
30 |
| - CSS_COLOR_NAMES.map(color => color.toLowerCase()) |
31 |
| - .includes(val.toLowerCase()) |
32 |
| - ) return val |
33 |
| - return false |
| 16 | + else if (CSS_COLOR_NAMES.map(color => color.toLowerCase()) |
| 17 | + .includes(val.toLowerCase())) |
| 18 | + return val |
| 19 | + else if (val === 'currentcolor') { |
| 20 | + return 'currentcolor' |
| 21 | + } else return '#000' |
34 | 22 | }
|
35 | 23 |
|
36 |
| -function _getOpacity(border, i) { |
37 |
| - let val = border[i] |
38 |
| - if (val.startsWith('rgba') || val.startsWith('hsla')) { |
39 |
| - if (!val.endsWith(')')) |
40 |
| - for (let j = 1; !border[i + j - 1].endsWith(')'); j++) { |
41 |
| - val += border[i + j] |
42 |
| - } |
43 |
| - return val.replace(/(rgb|hsl)a?\(([^,)]+,){3}/, '').replace(/\)$/, '') |
44 |
| - } |
45 |
| - if (border.length - 1 === i) |
46 |
| - return 1 |
| 24 | +/** @returns {number} */ |
| 25 | +function convertColorOpacity(val) { |
| 26 | + if (val?.startsWith('rgba') || val?.startsWith('hsla')) { |
| 27 | + return Number(val.match(/(\d*\.?\d+)?\)$/)[1]) |
| 28 | + } else return 1 |
47 | 29 | }
|
48 | 30 |
|
49 |
| -const htmlLengthNotSvgError = new Error('<RoundDiv> Border lengths must be either "thin", "medium", "thick", or in one of the following units: ch, cm, em, ex, in, mm, pc, pt, px, rem, vh, vmax, vmin, vw.') |
50 |
| - |
51 |
| -function unitCheck(length) { |
52 |
| - if (length?.match(/(cap|ic|lh|rlh|vi|vm|vb|Q|mozmm)/g)) throw htmlLengthNotSvgError |
53 |
| - return length |
| 31 | +const htmlLengthNotSvgErrorTemplate = (a, b) => `<RoundDiv> ${a} must be ${b ? `either ${b}, or` : ''} in one of the following units: ch, cm, em, ex, in, mm, pc, pt, px, rem, vh, vmax, vmin, vw.` |
| 32 | +const htmlBorderLengthNotSvgError = |
| 33 | + new Error(htmlLengthNotSvgErrorTemplate('border lengths', '"thin", "medium", "thick"')) |
| 34 | +const htmlBorderRadiusNotSvgError = |
| 35 | + new Error(htmlLengthNotSvgErrorTemplate('border radii')) |
| 36 | + |
| 37 | +function toNumber(length, element, err) { |
| 38 | + if (!length) return false |
| 39 | + if (typeof length === 'number' || !length.match(/\D+/)) |
| 40 | + return Number(length); |
| 41 | + else if (length?.match(/(cap|ic|lh|rlh|vi|vm|vb|Q|mozmm)/g)) |
| 42 | + if (err) throw err |
| 43 | + else return false |
| 44 | + else if (length?.match(/(\d+(\.\d+)?(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)|0)/)) |
| 45 | + return toPx(element, length) |
54 | 46 | }
|
55 | 47 |
|
56 |
| -function _getWidth(border, i, element) { |
57 |
| - const val = border[i] |
58 |
| - // width is 0 |
59 |
| - if (val === '0') return 0 |
| 48 | +/** @returns {number} */ |
| 49 | +function convertBorderWidth(val, element) { |
| 50 | + if (!val) return 0 |
60 | 51 | // width is a word
|
61 |
| - if (val.toLowerCase() === 'thin') return 1 |
62 |
| - if (val.toLowerCase() === 'medium') return 3 |
63 |
| - if (val.toLowerCase() === 'thick') return 5 |
64 |
| - unitCheck(val) |
| 52 | + if (val?.toLowerCase() === 'thin') |
| 53 | + return 1 |
| 54 | + else if (val?.toLowerCase() === 'medium') |
| 55 | + return 3 |
| 56 | + else if (val?.toLowerCase() === 'thick') |
| 57 | + return 5 |
65 | 58 | // width is <length>
|
66 |
| - if (val.match(/(\d+(\.\d+)?(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)|0)/)) |
67 |
| - return toPx(element, val) |
68 |
| - return false |
| 59 | + else |
| 60 | + return toNumber(val, element, htmlBorderLengthNotSvgError) || 0 |
69 | 61 | }
|
70 | 62 |
|
71 |
| -const getWidth = s => _getAttributeFromString(s, _getWidth), |
72 |
| - getColor = s => _getAttributeFromString(s, _getColor), |
73 |
| - getOpacity = s => _getAttributeFromString(s, _getOpacity) |
74 |
| - |
75 |
| -export {getWidth, getColor, unitCheck, getOpacity} |
| 63 | +export {convertPlainColor, convertColorOpacity, convertBorderWidth, toNumber, htmlBorderRadiusNotSvgError} |
0 commit comments