|
10 | 10 | // a regex to validate hexadecimal colors |
11 | 11 | var HEX_COLOR = /^#?((?:[\da-f]){3,4}|(?:[\da-f]{2}){3,4})$/i; |
12 | 12 |
|
13 | | - /** |
14 | | - * Parses the given hexadecimal representation and returns the parsed RGBA color. |
15 | | - * |
16 | | - * If the format of the given string is invalid, `undefined` will be returned. |
17 | | - * Valid formats are: `RGB`, `RGBA`, `RRGGBB`, and `RRGGBBAA`. |
18 | | - * |
19 | | - * Hexadecimal colors are parsed because they are not fully supported by older browsers, so converting them to |
20 | | - * `rgba` functions improves browser compatibility. |
21 | | - * |
22 | | - * @param {string} hex |
23 | | - * @returns {string | undefined} |
24 | | - */ |
25 | | - function parseHexColor(hex) { |
26 | | - var match = HEX_COLOR.exec(hex); |
27 | | - if (!match) { |
28 | | - return undefined; |
29 | | - } |
30 | | - hex = match[1]; // removes the leading "#" |
31 | | - |
32 | | - // the width and number of channels |
33 | | - var channelWidth = hex.length >= 6 ? 2 : 1; |
34 | | - var channelCount = hex.length / channelWidth; |
35 | | - |
36 | | - // the scale used to normalize 4bit and 8bit values |
37 | | - var scale = channelWidth == 1 ? 1 / 15 : 1 / 255; |
38 | | - |
39 | | - // normalized RGBA channels |
40 | | - var channels = []; |
41 | | - for (var i = 0; i < channelCount; i++) { |
42 | | - var int = parseInt(hex.substr(i * channelWidth, channelWidth), 16); |
43 | | - channels.push(int * scale); |
44 | | - } |
45 | | - if (channelCount == 3) { |
46 | | - channels.push(1); // add alpha of 100% |
47 | | - } |
48 | | - |
49 | | - // output |
50 | | - var rgb = channels.slice(0, 3).map(function (x) { |
51 | | - return String(Math.round(x * 255)); |
52 | | - }).join(','); |
53 | | - var alpha = String(Number(channels[3].toFixed(3))); // easy way to round 3 decimal places |
54 | | - |
55 | | - return 'rgba(' + rgb + ',' + alpha + ')'; |
56 | | - } |
57 | | - |
58 | 13 | /** |
59 | 14 | * Validates the given Color using the current browser's internal implementation. |
60 | 15 | * |
|
66 | 21 | s.color = color; |
67 | 22 | return s.color ? color : undefined; |
68 | 23 | } |
69 | | - |
| 24 | + |
| 25 | + var isMobile = navigator.userAgent.match('Mobile') ?? false; |
| 26 | + |
70 | 27 | /** |
71 | | - * An array of function which parse a given string representation of a color. |
72 | | - * |
73 | | - * These parser serve as validators and as a layer of compatibility to support color formats which the browser |
74 | | - * might not support natively. |
75 | | - * |
76 | | - * @type {((value: string) => (string|undefined))[]} |
| 28 | + * Global exports |
77 | 29 | */ |
78 | | - var parsers = [ |
79 | | - parseHexColor, |
80 | | - validateColor |
81 | | - ]; |
| 30 | + Prism.plugins.inlineColor = { |
| 31 | + |
| 32 | + /** |
| 33 | + * Opens color picker for given element. |
| 34 | + */ |
| 35 | + openPicker: (el, event) => { |
| 36 | + |
| 37 | + // if on desktop |
| 38 | + if (!isMobile) { |
| 39 | + |
| 40 | + // create eye dropper |
| 41 | + var eyeDropper = new EyeDropper(); |
| 42 | + |
| 43 | + // open eye dropper |
| 44 | + eyeDropper.open() |
| 45 | + .then(colorSelectionResult => { |
| 46 | + |
| 47 | + // hex color value (#RRGGBB) |
| 48 | + var result = colorSelectionResult.sRGBHex; |
| 49 | + |
| 50 | + el.children[0].style.backgroundColor = result; |
| 51 | + el.nextSibling.textContent = result; |
| 52 | + |
| 53 | + document.querySelector('cd-el').dispatchEvent(new Event('type')); |
| 54 | + |
| 55 | + }).catch(error => {}); |
| 56 | + |
| 57 | + } |
| 58 | + |
| 59 | + } |
| 60 | + |
| 61 | + }; |
82 | 62 |
|
83 | 63 |
|
84 | 64 | Prism.hooks.add('wrap', function (env) { |
85 | 65 | if (env.type === 'color' || env.classes.indexOf('color') >= 0) { |
86 | 66 | var content = env.content; |
87 | | - |
88 | | - // remove all HTML tags inside |
89 | | - var rawText = content.split(HTML_TAG).join(''); |
90 | | - |
91 | | - var color; |
92 | | - for (var i = 0, l = parsers.length; i < l && !color; i++) { |
93 | | - color = parsers[i](rawText); |
| 67 | + |
| 68 | + // if token dosen't already have an inline color element |
| 69 | + if (!env.content.includes('inline-color-wrapper')) { |
| 70 | + |
| 71 | + // remove all HTML tags inside |
| 72 | + var rawText = content.split(HTML_TAG).join(''); |
| 73 | + |
| 74 | + var color = validateColor(rawText); |
| 75 | + |
| 76 | + if (!color) { |
| 77 | + return; |
| 78 | + } |
| 79 | + |
| 80 | + var previewElement = '<span class="inline-color-wrapper" onclick="Prism.plugins.inlineColor.openPicker(this, event)" aria-hidden="true" contenteditable="false"><span class="inline-color" style="background-color:' + color + ';"></span></span>'; |
| 81 | + env.content = previewElement + content; |
| 82 | + |
94 | 83 | } |
95 | | - |
96 | | - if (!color) { |
97 | | - return; |
98 | | - } |
99 | | - |
100 | | - var previewElement = '<span class="inline-color-wrapper"><span class="inline-color" style="background-color:' + color + ';"></span></span>'; |
101 | | - env.content = previewElement + content; |
102 | 84 | } |
103 | 85 | }); |
104 | 86 |
|
|
0 commit comments