[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 /** 2 * Based on: 3 * Very simple jQuery Color Picker 4 * Copyright (C) 2012 Tanguy Krotoff 5 * Licensed under the MIT license 6 * 7 * ADAPTED BY: Dimitris Grammatikogiannis 8 * 9 * MIT License 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining 12 * a copy of this software and associated documentation files (the 13 * "Software"), to deal in the Software without restriction, including 14 * without limitation the rights to use, copy, modify, merge, publish, 15 * distribute, sublicense, and/or sell copies of the Software, and to 16 * permit persons to whom the Software is furnished to do so, subject to 17 * the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be 20 * included in all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 */ 30 (customElements => { 31 const KEYCODE = { 32 TAB: 9, 33 ESC: 27 34 }; 35 const colorNames = { 36 aliceblue: '#f0f8ff', 37 antiquewhite: '#faebd7', 38 aqua: '#00ffff', 39 aquamarine: '#7fffd4', 40 azure: '#f0ffff', 41 beige: '#f5f5dc', 42 bisque: '#ffe4c4', 43 black: '#000000', 44 blanchedalmond: '#ffebcd', 45 blue: '#0000ff', 46 blueviolet: '#8a2be2', 47 brown: '#a52a2a', 48 burlywood: '#deb887', 49 cadetblue: '#5f9ea0', 50 chartreuse: '#7fff00', 51 chocolate: '#d2691e', 52 coral: '#ff7f50', 53 cornflowerblue: '#6495ed', 54 cornsilk: '#fff8dc', 55 crimson: '#dc143c', 56 cyan: '#00ffff', 57 darkblue: '#00008b', 58 darkcyan: '#008b8b', 59 darkgoldenrod: '#b8860b', 60 darkgray: '#a9a9a9', 61 darkgreen: '#006400', 62 darkgrey: '#a9a9a9', 63 darkkhaki: '#bdb76b', 64 darkmagenta: '#8b008b', 65 darkolivegreen: '#556b2f', 66 darkorange: '#ff8c00', 67 darkorchid: '#9932cc', 68 darkred: '#8b0000', 69 darksalmon: '#e9967a', 70 darkseagreen: '#8fbc8f', 71 darkslateblue: '#483d8b', 72 darkslategray: '#2f4f4f', 73 darkslategrey: '#2f4f4f', 74 darkturquoise: '#00ced1', 75 darkviolet: '#9400d3', 76 deeppink: '#ff1493', 77 deepskyblue: '#00bfff', 78 dimgray: '#696969', 79 dimgrey: '#696969', 80 dodgerblue: '#1e90ff', 81 firebrick: '#b22222', 82 floralwhite: '#fffaf0', 83 forestgreen: '#228b22', 84 fuchsia: '#ff00ff', 85 gainsboro: '#dcdcdc', 86 ghostwhite: '#f8f8ff', 87 gold: '#ffd700', 88 goldenrod: '#daa520', 89 gray: '#808080', 90 green: '#008000', 91 greenyellow: '#adff2f', 92 grey: '#808080', 93 honeydew: '#f0fff0', 94 hotpink: '#ff69b4', 95 indianred: '#cd5c5c', 96 indigo: '#4b0082', 97 ivory: '#fffff0', 98 khaki: '#f0e68c', 99 lavender: '#e6e6fa', 100 lavenderblush: '#fff0f5', 101 lawngreen: '#7cfc00', 102 lemonchiffon: '#fffacd', 103 lightblue: '#add8e6', 104 lightcoral: '#f08080', 105 lightcyan: '#e0ffff', 106 lightgoldenrodyellow: '#fafad2', 107 lightgray: '#d3d3d3', 108 lightgreen: '#90ee90', 109 lightgrey: '#d3d3d3', 110 lightpink: '#ffb6c1', 111 lightsalmon: '#ffa07a', 112 lightseagreen: '#20b2aa', 113 lightskyblue: '#87cefa', 114 lightslategray: '#778899', 115 lightslategrey: '#778899', 116 lightsteelblue: '#b0c4de', 117 lightyellow: '#ffffe0', 118 lime: '#00ff00', 119 limegreen: '#32cd32', 120 linen: '#faf0e6', 121 magenta: '#ff00ff', 122 maroon: '#800000', 123 mediumaquamarine: '#66cdaa', 124 mediumblue: '#0000cd', 125 mediumorchid: '#ba55d3', 126 mediumpurple: '#9370db', 127 mediumseagreen: '#3cb371', 128 mediumslateblue: '#7b68ee', 129 mediumspringgreen: '#00fa9a', 130 mediumturquoise: '#48d1cc', 131 mediumvioletred: '#c71585', 132 midnightblue: '#191970', 133 mintcream: '#f5fffa', 134 mistyrose: '#ffe4e1', 135 moccasin: '#ffe4b5', 136 navajowhite: '#ffdead', 137 navy: '#000080', 138 oldlace: '#fdf5e6', 139 olive: '#808000', 140 olivedrab: '#6b8e23', 141 orange: '#ffa500', 142 orangered: '#ff4500', 143 orchid: '#da70d6', 144 palegoldenrod: '#eee8aa', 145 palegreen: '#98fb98', 146 paleturquoise: '#afeeee', 147 palevioletred: '#db7093', 148 papayawhip: '#ffefd5', 149 peachpuff: '#ffdab9', 150 peru: '#cd853f', 151 pink: '#ffc0cb', 152 plum: '#dda0dd', 153 powderblue: '#b0e0e6', 154 purple: '#800080', 155 red: '#ff0000', 156 rosybrown: '#bc8f8f', 157 royalblue: '#4169e1', 158 saddlebrown: '#8b4513', 159 salmon: '#fa8072', 160 sandybrown: '#f4a460', 161 seagreen: '#2e8b57', 162 seashell: '#fff5ee', 163 sienna: '#a0522d', 164 silver: '#c0c0c0', 165 skyblue: '#87ceeb', 166 slateblue: '#6a5acd', 167 slategray: '#708090', 168 slategrey: '#708090', 169 snow: '#fffafa', 170 springgreen: '#00ff7f', 171 steelblue: '#4682b4', 172 tan: '#d2b48c', 173 teal: '#008080', 174 thistle: '#d8bfd8', 175 tomato: '#ff6347', 176 turquoise: '#40e0d0', 177 violet: '#ee82ee', 178 wheat: '#f5deb3', 179 white: '#ffffff', 180 whitesmoke: '#f5f5f5', 181 yellow: '#ffff00', 182 yellowgreen: '#9acd32' 183 }; 184 185 class JoomlaFieldSimpleColor extends HTMLElement { 186 constructor() { 187 super(); // Define some variables 188 189 this.select = ''; 190 this.options = []; 191 this.icon = ''; 192 this.panel = ''; 193 this.buttons = []; 194 this.focusableElements = null; 195 this.focusableSelectors = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'iframe', 'object', 'embed', '[contenteditable]', '[tabindex]:not([tabindex^="-"])']; 196 } 197 198 connectedCallback() { 199 this.select = this.querySelector('select'); 200 201 if (!this.select) { 202 throw new Error('Simple color field requires a select element'); 203 } 204 205 this.options = [].slice.call(this.select.querySelectorAll('option')); 206 this.select.classList.add('hidden'); // Build the pop up 207 208 this.options.forEach(option => { 209 let color = option.value; 210 let clss = 'swatch'; 211 212 if (color === 'none') { 213 clss += ' nocolor'; 214 color = 'transparent'; 215 } 216 217 if (option.selected) { 218 clss += ' active'; 219 } 220 221 const el = document.createElement('button'); 222 el.setAttribute('class', clss); 223 el.style.backgroundColor = color; 224 el.setAttribute('type', 'button'); 225 const a11yColor = color === 'transparent' ? this.textTransp : this.getColorName(color); 226 el.innerHTML = Joomla.sanitizeHtml(`<span class="visually-hidden">$a11yColor}</span>`); 227 this.buttons.push(el); 228 }); // Add a close button 229 230 const close = document.createElement('button'); 231 close.setAttribute('class', 'btn-close'); 232 close.setAttribute('type', 'button'); 233 close.innerHTML = Joomla.sanitizeHtml(this.textClose); 234 this.buttons.push(close); 235 let color = this.select.value; 236 let clss = ''; 237 238 if (color === 'none') { 239 clss += ' nocolor'; 240 color = 'transparent'; 241 } 242 243 this.icon = document.createElement('button'); 244 245 if (clss) { 246 this.icon.setAttribute('class', clss); 247 } 248 249 const uniqueId = `simple-color-$Math.random().toString(36).substr(2, 10)}`; 250 this.icon.setAttribute('type', 'button'); 251 this.icon.setAttribute('tabindex', '0'); 252 this.icon.style.backgroundColor = color; 253 this.icon.innerHTML = Joomla.sanitizeHtml(`<span class="visually-hidden">$this.textSelect}</span>`); 254 this.icon.id = uniqueId; 255 this.select.insertAdjacentElement('beforebegin', this.icon); 256 this.icon.addEventListener('click', this.show.bind(this)); 257 this.panel = document.createElement('div'); 258 this.panel.classList.add('simplecolors-panel'); 259 this.panel.setAttribute('aria-labelledby', uniqueId); 260 this.hide = this.hide.bind(this); 261 this.colorSelect = this.colorSelect.bind(this); 262 this.buttons.forEach(el => { 263 if (el.classList.contains('btn-close')) { 264 el.addEventListener('click', this.hide); 265 } else { 266 el.addEventListener('click', this.colorSelect); 267 } 268 269 this.panel.insertAdjacentElement('beforeend', el); 270 }); 271 this.appendChild(this.panel); 272 this.focusableElements = [].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join())); 273 this.keys = this.keys.bind(this); 274 this.hide = this.hide.bind(this); 275 this.mousedown = this.mousedown.bind(this); 276 } 277 278 static get observedAttributes() { 279 return ['text-select', 'text-color', 'text-close', 'text-transparent']; 280 } 281 282 get textSelect() { 283 return this.getAttribute('text-select'); 284 } 285 286 get textColor() { 287 return this.getAttribute('text-color'); 288 } 289 290 get textClose() { 291 return this.getAttribute('text-close'); 292 } 293 294 get textTransp() { 295 return this.getAttribute('text-transparent'); 296 } // Show the panel 297 298 299 show() { 300 document.addEventListener('mousedown', this.hide); 301 this.addEventListener('keydown', this.keys); 302 this.panel.addEventListener('mousedown', this.mousedown); 303 this.panel.setAttribute('data-open', ''); 304 const focused = this.panel.querySelector('button'); 305 306 if (focused) { 307 focused.focus(); 308 } 309 } // Hide panel 310 311 312 hide() { 313 document.removeEventListener('mousedown', this.hide, false); 314 this.removeEventListener('keydown', this.keys); 315 316 if (this.panel.hasAttribute('data-open')) { 317 this.panel.removeAttribute('data-open'); 318 } 319 320 this.icon.focus(); 321 } 322 323 colorSelect(e) { 324 let color = ''; 325 let bgcolor = ''; 326 let clss = ''; 327 328 if (e.target.classList.contains('nocolor')) { 329 color = 'none'; 330 bgcolor = 'transparent'; 331 clss = 'nocolor'; 332 } else { 333 color = this.rgb2hex(e.target.style.backgroundColor); 334 bgcolor = color; 335 } // Reset the active class 336 337 338 this.buttons.forEach(el => { 339 if (el.classList.contains('active')) { 340 el.classList.remove('active'); 341 } 342 }); // Add the active class to the selected button 343 344 e.target.classList.add('active'); 345 this.icon.classList.remove('nocolor'); 346 this.icon.setAttribute('class', clss); 347 this.icon.style.backgroundColor = bgcolor; // trigger change event both on the select and on the custom element 348 349 this.select.dispatchEvent(new Event('change')); 350 this.dispatchEvent(new CustomEvent('change', { 351 detail: { 352 value: color 353 }, 354 bubbles: true 355 })); // Hide the panel 356 357 this.hide(); // Change select value 358 359 this.options.forEach(el => { 360 if (el.selected) { 361 el.removeAttribute('selected'); 362 } 363 364 if (el.value === bgcolor) { 365 el.setAttribute('selected', ''); 366 } 367 }); 368 } 369 370 keys(e) { 371 if (e.keyCode === KEYCODE.ESC) { 372 this.hide(); 373 } 374 375 if (e.keyCode === KEYCODE.TAB) { 376 // Get the index of the current active element 377 const focusedIndex = this.focusableElements.indexOf(document.activeElement); // If first element is focused and shiftkey is in use, focus last item within modal 378 379 if (e.shiftKey && (focusedIndex === 0 || focusedIndex === -1)) { 380 this.focusableElements[this.focusableElements.length - 1].focus(); 381 e.preventDefault(); 382 } // If last element is focused and shiftkey is not in use, focus first item within modal 383 384 385 if (!e.shiftKey && focusedIndex === this.focusableElements.length - 1) { 386 this.focusableElements[0].focus(); 387 e.preventDefault(); 388 } 389 } 390 } // Prevents the mousedown event from "eating" the click event. 391 // eslint-disable-next-line class-methods-use-this 392 393 394 mousedown(e) { 395 e.stopPropagation(); 396 e.preventDefault(); 397 } 398 399 getColorName(value) { 400 // Expand any short code 401 let newValue = value; 402 403 if (value.length === 4) { 404 const tmpValue = value.split(''); 405 newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] + tmpValue[2] + tmpValue[3] + tmpValue[3]; 406 } // eslint-disable-next-line no-restricted-syntax 407 408 409 for (const color in colorNames) { 410 // eslint-disable-next-line no-prototype-builtins 411 if (colorNames.hasOwnProperty(color) && newValue.toLowerCase() === colorNames[color]) { 412 return color; 413 } 414 } 415 416 return `$this.textColor} $value.replace('#', '').split('').join(', ')}`; 417 } 418 /** 419 * Converts a RGB color to its hexadecimal value. 420 * See http://stackoverflow.com/questions/1740700/get-hex-value-rather-than-rgb-value-using-$ 421 */ 422 // eslint-disable-next-line class-methods-use-this 423 424 425 rgb2hex(rgb) { 426 const hex = x => `0$parseInt(x, 10).toString(16)}`.slice(-2); 427 428 const matches = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 429 return `#$hex(matches[1])}$hex(matches[2])}$hex(matches[3])}`; 430 } 431 432 } 433 434 customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor); 435 })(customElements);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |