[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 (function () { 2 'use strict'; 3 4 /** 5 * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> 6 * @license GNU General Public License version 2 or later; see LICENSE.txt 7 */ 8 9 /* eslint class-methods-use-this: ["error", { "exceptMethods": ["rgbToHex", "hslToRgb"] }] */ 10 (function (document) { 11 /** 12 * Regex for hex values e.g. #FF3929 13 * @type {RegExp} 14 */ 15 var hexRegex = /^#([a-z0-9]{1,2})([a-z0-9]{1,2})([a-z0-9]{1,2})$/i; 16 /** 17 * Regex for rgb values e.g. rgba(255, 0, 24, 0.5); 18 * @type {RegExp} 19 */ 20 21 var rgbRegex = /^rgba?\(([0-9]+)[\D]+([0-9]+)[\D]+([0-9]+)(?:[\D]+([0-9](?:.\d+)?))?\)$/i; 22 /** 23 * Regex for hsl values e.g. hsl(255,0,24); 24 * @type {RegExp} 25 */ 26 27 var hslRegex = /^hsla?\(([0-9]+)[\D]+([0-9]+)[\D]+([0-9]+)[\D]+([0-9](?:.\d+)?)?\)$/i; 28 /** 29 * Regex for saturation and lightness of hsl - only accepts 1 or 0 or 0.4 or 40 30 * @type {RegExp} 31 */ 32 33 var hslNumberRegex = /^(([0-1])|(0\\.[0-9]+)|([0-9]{1,2})|(100))$/; 34 /** 35 * Regex for hue values - one to three numbers 36 * @type {RegExp} 37 */ 38 39 var hueRegex = /^[0-9]{1,3}$/; 40 /** 41 * Creates a slider for the color values hue, saturation and light. 42 * 43 * @since 4.0.0 44 */ 45 46 var JoomlaFieldColorSlider = /*#__PURE__*/function () { 47 /** 48 * @param {HTMLElement} element 49 */ 50 function JoomlaFieldColorSlider(element) { 51 var _this = this; 52 53 // Elements 54 this.messageSpan = element.querySelector('.form-control-feedback'); 55 this.mainInput = element.querySelector('.color-input'); 56 this.input = element.querySelector('#slider-input'); 57 this.sliders = element.querySelectorAll('.color-slider'); 58 this.hueSlider = element.querySelector('#hue-slider'); 59 this.saturationSlider = element.querySelector('#saturation-slider'); 60 this.lightSlider = element.querySelector('#light-slider'); 61 this.alphaSlider = element.querySelector('#alpha-slider'); // Attributes 62 63 this.color = element.dataset.color || ''; 64 this.default = element.dataset.default || ''; 65 this.format = this.input.dataset.format || 'hex'; 66 this.saveFormat = this.mainInput.dataset.format || 'hex'; 67 this.preview = element.dataset.preview === 'true'; 68 this.setAlpha = this.format === 'hsla' || this.format === 'rgba'; 69 this.hue = 360; 70 this.saturation = 1; 71 this.light = 1; 72 this.alpha = 1; 73 this.defaultHsl = [this.hue, this.saturation, this.light, this.alpha]; 74 this.setInitValue(); 75 this.setBackground(); // Hide preview field, when selected value should not be visible 76 77 if (!this.preview) { 78 this.input.classList.add('hidden'); 79 } else { 80 this.setInputPattern(); 81 } // Always hide main input field (value saved in database) 82 83 84 this.mainInput.classList.add('hidden'); 85 Array.prototype.forEach.call(this.sliders, function (slider) { 86 slider.addEventListener('change', function () { 87 return _this.updateValue(slider); 88 }); 89 }); 90 this.input.addEventListener('change', function () { 91 return _this.changeInput(_this.input); 92 }); 93 } 94 /** 95 * Set selected value into input field and set it as its background-color. 96 */ 97 98 99 var _proto = JoomlaFieldColorSlider.prototype; 100 101 _proto.updateValue = function updateValue(slider) { 102 this.showError(''); 103 var hsl = this.getSliderValueAsHsl(slider.value, slider.dataset.type); 104 var rgb = this.hslToRgb(hsl); 105 this.hue = hsl[0]; 106 this.saturation = hsl[1]; 107 this.light = hsl[2]; 108 this.alpha = hsl[3]; 109 this.input.style.border = "2px solid " + this.getRgbString(rgb); 110 this.setSliderValues(hsl, slider.dataset.type); 111 this.setInputValue(hsl); 112 this.setBackground(slider); 113 } 114 /** 115 * React on user changing input value 116 * 117 * @param {HTMLElement} inputField 118 */ 119 ; 120 121 _proto.changeInput = function changeInput(inputField) { 122 var hsl = [this.hue, this.saturation, this.light, this.alpha]; 123 124 if (!inputField.value) { 125 this.mainInput.value = ''; 126 this.showError(''); 127 return; 128 } 129 130 if (!this.checkValue(inputField.value)) { 131 this.showError('JFIELD_COLOR_ERROR_WRONG_FORMAT'); 132 this.setInputValue(this.defaultHsl); 133 } else { 134 this.showError(''); 135 136 switch (this.format) { 137 case 'hue': 138 hsl[0] = inputField.value; 139 this.hue = inputField.value; 140 break; 141 142 case 'saturation': 143 hsl[1] = inputField.value; 144 this.saturation = inputField.value; 145 break; 146 147 case 'light': 148 hsl[2] = inputField.value; 149 this.light = inputField.value; 150 break; 151 152 case 'alpha': 153 hsl[3] = inputField.value; 154 this.alpha = inputField.value; 155 break; 156 157 default: 158 hsl = this.getHsl(inputField.value); 159 } 160 161 this.setSliderValues(hsl); 162 this.setInputValue(hsl, true); 163 } 164 } 165 /** 166 * Check validity of value 167 * 168 * @param {number|string} value to check 169 * @param {string=false} format for which the value gets tested 170 * @returns {boolean} 171 */ 172 ; 173 174 _proto.checkValue = function checkValue(value, format) { 175 var test = format || this.format; 176 177 switch (test) { 178 case 'hue': 179 return value <= 360 && hueRegex.test(value); 180 181 case 'saturation': 182 case 'light': 183 case 'alpha': 184 return hslNumberRegex.test(value); 185 186 case 'hsl': 187 case 'hsla': 188 return hslRegex.test(value); 189 190 case 'hex': 191 return hexRegex.test(value); 192 193 case 'rgb': 194 case 'rgba': 195 return rgbRegex.test(value); 196 197 default: 198 return false; 199 } 200 } 201 /** 202 * Set validation pattern on input field 203 */ 204 ; 205 206 _proto.setInputPattern = function setInputPattern() { 207 var pattern; // RegExp has '/' at start and end 208 209 switch (this.format) { 210 case 'hue': 211 pattern = hueRegex.source.slice(1, -1); 212 break; 213 214 case 'saturation': 215 case 'light': 216 case 'alpha': 217 pattern = hslNumberRegex.source.slice(1, -1); 218 break; 219 220 case 'hsl': 221 case 'hsla': 222 pattern = hslRegex.source.slice(1, -1); 223 break; 224 225 case 'rgb': 226 pattern = rgbRegex.source.slice(1, -1); 227 break; 228 229 case 'hex': 230 default: 231 pattern = hexRegex.source.slice(1, -1); 232 } 233 234 this.input.setAttribute('pattern', pattern); 235 } 236 /** 237 * Set linear gradient for slider background 238 * @param {HTMLInputElement} [exceptSlider] 239 */ 240 ; 241 242 _proto.setBackground = function setBackground(exceptSlider) { 243 var _this2 = this; 244 245 Array.prototype.forEach.call(this.sliders, function (slider) { 246 // Jump over changed slider 247 if (exceptSlider === slider) { 248 return; 249 } 250 251 var colors = []; 252 var endValue = 100; // Longer start color so slider selection matches displayed colors 253 254 colors.push(_this2.getSliderValueAsRgb(0, slider.dataset.type)); 255 256 if (slider.dataset.type === 'hue') { 257 var steps = Math.floor(360 / 20); 258 endValue = 360; 259 260 for (var i = 0; i <= 360; i += steps) { 261 colors.push(_this2.getSliderValueAsRgb(i, slider.dataset.type)); 262 } 263 } else { 264 for (var _i = 0; _i <= 100; _i += 10) { 265 colors.push(_this2.getSliderValueAsRgb(_i, slider.dataset.type)); 266 } 267 } // Longer end color so slider selection matches displayed colors 268 269 270 colors.push(_this2.getSliderValueAsRgb(endValue, slider.dataset.type)); 271 colors = colors.map(function (value) { 272 return _this2.getRgbString(value); 273 }); 274 slider.style.background = "linear-gradient(90deg, " + colors.join(',') + ")"; 275 slider.style.webkitAppearance = 'none'; 276 }); 277 } 278 /** 279 * Convert given color into hue, saturation and light 280 */ 281 ; 282 283 _proto.setInitValue = function setInitValue() { 284 // The initial value can be also a color defined in css 285 var cssValue = window.getComputedStyle(this.input).getPropertyValue(this.default); 286 this.default = cssValue || this.default; 287 288 if (this.color === '' || typeof this.color === 'undefined') { 289 // Unable to get hsl with empty value 290 this.input.value = ''; 291 this.mainInput.value = ''; 292 return; 293 } 294 295 var value = this.checkValue(this.color, this.saveFormat) ? this.color : this.default; 296 297 if (!value) { 298 this.showError('JFIELD_COLOR_ERROR_NO_COLOUR'); 299 return; 300 } 301 302 var hsl = []; // When given value is a number, use it as defined format and get rest from default value 303 304 if (/^[0-9]+$/.test(value)) { 305 hsl = this.default && this.getHsl(this.default); 306 307 if (this.format === 'hue') { 308 hsl[0] = value; 309 } 310 311 if (this.format === 'saturation') { 312 hsl[1] = value > 1 ? value / 100 : value; 313 } 314 315 if (this.format === 'light') { 316 hsl[2] = value > 1 ? value / 100 : value; 317 } 318 319 if (this.format === 'alpha') { 320 hsl[3] = value > 1 ? value / 100 : value; 321 } 322 } else { 323 hsl = this.getHsl(value); 324 } 325 326 var _hsl = hsl; 327 this.hue = _hsl[0]; 328 this.saturation = _hsl[1]; 329 this.light = _hsl[2]; 330 this.alpha = hsl[4] || this.alpha; 331 this.defaultHsl = this.default ? this.getHsl(this.default) : hsl; 332 this.setSliderValues(hsl); 333 this.setInputValue(hsl); 334 this.input.style.border = "2px solid " + this.getRgbString(this.hslToRgb(hsl)); 335 } 336 /** 337 * Insert message into error message span 338 * Message gets handled with Joomla.Text or as empty string 339 * 340 * @param {string} msg 341 */ 342 ; 343 344 _proto.showError = function showError(msg) { 345 this.messageSpan.innerText = msg ? Joomla.Text._(msg) : ''; 346 } 347 /** 348 * Convert value into HSLa e.g. #003E7C => [210, 100, 24] 349 * @param {array|number|string} value 350 * @returns {array} 351 */ 352 ; 353 354 _proto.getHsl = function getHsl(value) { 355 var hsl = []; 356 357 if (Array.isArray(value)) { 358 hsl = value; 359 } else if (hexRegex.test(value)) { 360 hsl = this.hexToHsl(value); 361 } else if (rgbRegex.test(value)) { 362 hsl = this.rgbToHsl(value); 363 } else if (hslRegex.test(value)) { 364 var matches = value.match(hslRegex); 365 hsl = [matches[1], matches[2], matches[3], matches[4]]; 366 } else { 367 this.showError('JFIELD_COLOR_ERROR_CONVERT_HSL'); 368 return this.defaultHsl; 369 } // Convert saturation etc. values from e.g. 40 to 0.4 370 371 372 var i; 373 374 for (i = 1; i < hsl.length; i += 1) { 375 hsl[i] = hsl[i] > 1 ? hsl[i] / 100 : hsl[i]; 376 } 377 378 return hsl; 379 } 380 /** 381 * Returns HSL value from color slider value 382 * @params {int} value convert this value 383 * @params {string} type type of value: hue, saturation, light or alpha 384 * @returns array 385 */ 386 ; 387 388 _proto.getSliderValueAsHsl = function getSliderValueAsHsl(value, type) { 389 var h = this.hue; 390 var s = this.saturation; 391 var l = this.light; 392 var a = this.alpha; 393 394 switch (type) { 395 case 'alpha': 396 a = value; 397 break; 398 399 case 'saturation': 400 s = value; 401 break; 402 403 case 'light': 404 l = value; 405 break; 406 407 case 'hue': 408 default: 409 h = value; 410 } // Percentage light and saturation 411 412 413 if (l > 1) { 414 l /= 100; 415 } 416 417 if (s > 1) { 418 s /= 100; 419 } 420 421 if (a > 1) { 422 a /= 100; 423 } 424 425 return [h, s, l, a]; 426 } 427 /** 428 * Calculates RGB value from color slider value 429 * @params {int} value convert this value 430 * @params {string} type type of value: hue, saturation, light or alpha 431 * @returns array 432 */ 433 ; 434 435 _proto.getSliderValueAsRgb = function getSliderValueAsRgb(value, type) { 436 return this.hslToRgb(this.getSliderValueAsHsl(value, type)); 437 } 438 /** 439 * Set value in all sliders 440 * @param {array} [hsla] 441 * @param {string} [except] 442 */ 443 ; 444 445 _proto.setSliderValues = function setSliderValues(_ref, except) { 446 var h = _ref[0], 447 s = _ref[1], 448 l = _ref[2], 449 a = _ref[3]; 450 451 if (this.hueSlider && except !== 'hue') { 452 this.hueSlider.value = Math.round(h); 453 } 454 455 if (this.saturationSlider && except !== 'saturation') { 456 this.saturationSlider.value = Math.round(s * 100); 457 } 458 459 if (this.lightSlider && except !== 'light') { 460 this.lightSlider.value = Math.round(l * 100); 461 } 462 463 if (a && this.alphaSlider && except !== 'alpha') { 464 this.alphaSlider.value = Math.round(a * 100); 465 } 466 } 467 /** 468 * Set value in text input fields depending on their format 469 * @param {array} hsl 470 * @param {boolean=false} onlyMain indicates to change mainInput only 471 */ 472 ; 473 474 _proto.setInputValue = function setInputValue(hsl, onlyMain) { 475 var _this3 = this; 476 477 var inputs = [this.mainInput]; 478 479 if (!onlyMain) { 480 inputs.push(this.input); 481 } 482 483 inputs.forEach(function (input) { 484 var value; 485 486 switch (input.dataset.format) { 487 case 'hsl': 488 value = _this3.getHslString(hsl); 489 break; 490 491 case 'hsla': 492 value = _this3.getHslString(hsl, true); 493 break; 494 495 case 'rgb': 496 value = _this3.getRgbString(_this3.hslToRgb(hsl)); 497 break; 498 499 case 'rgba': 500 value = _this3.getRgbString(_this3.hslToRgb(hsl), true); 501 break; 502 503 case 'hex': 504 value = _this3.rgbToHex(_this3.hslToRgb(hsl)); 505 break; 506 507 case 'alpha': 508 value = Math.round(hsl[3] * 100); 509 break; 510 511 case 'saturation': 512 value = Math.round(hsl[1] * 100); 513 break; 514 515 case 'light': 516 value = Math.round(hsl[2] * 100); 517 break; 518 519 case 'hue': 520 default: 521 value = Math.round(hsl[0]); 522 break; 523 } 524 525 input.value = value; 526 }); 527 } 528 /** 529 * Put RGB values into a string like 'rgb(<R>, <G>, <B>)' 530 * @params {array} rgba 531 * @params {boolean=false} withAlpha 532 * @return {string} 533 */ 534 ; 535 536 _proto.getRgbString = function getRgbString(_ref2, withAlpha) { 537 var r = _ref2[0], 538 g = _ref2[1], 539 b = _ref2[2], 540 a = _ref2[3]; 541 542 if (withAlpha || this.setAlpha) { 543 var alpha = typeof a === 'undefined' ? this.alpha : a; 544 return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")"; 545 } 546 547 return "rgb(" + r + ", " + g + ", " + b + ")"; 548 } 549 /** 550 * Put HSL values into a string like 'hsl(<H>, <S>%, <L>%, <a>)' 551 * @params {array} values 552 * @params {boolean=false} withAlpha 553 * @return {string} 554 */ 555 ; 556 557 _proto.getHslString = function getHslString(values, withAlpha) { 558 var h = values[0], 559 s = values[1], 560 l = values[2], 561 a = values[3]; 562 s *= 100; 563 l *= 100; 564 565 var _map = [h, s, l].map(function (value) { 566 return Math.round(value); 567 }); 568 569 h = _map[0]; 570 s = _map[1]; 571 l = _map[2]; 572 573 if (withAlpha || this.setAlpha) { 574 a = a || this.alpha; 575 return "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")"; 576 } 577 578 return "hsl(" + h + ", " + s + "%, " + l + "%)"; 579 } 580 /** 581 * Returns hsl values out of hex 582 * @param {array} rgb 583 * @return {string} 584 */ 585 ; 586 587 _proto.rgbToHex = function rgbToHex(rgb) { 588 var r = rgb[0].toString(16).toUpperCase(); 589 var g = rgb[1].toString(16).toUpperCase(); 590 var b = rgb[2].toString(16).toUpperCase(); // Double value for hex with '#' and 6 chars 591 592 r = r.length === 1 ? "" + r + r : r; 593 g = g.length === 1 ? "" + g + g : g; 594 b = b.length === 1 ? "" + b + b : b; 595 return "#" + r + g + b; 596 } 597 /** 598 * Returns hsl values out of rgb 599 * @param {string|array} values 600 * @return {array} 601 */ 602 ; 603 604 _proto.rgbToHsl = function rgbToHsl(values) { 605 var rgb = values; 606 607 if (typeof values === 'string') { 608 var parts = values.match(rgbRegex); 609 rgb = [parts[1], parts[2], parts[3], parts[4]]; 610 } 611 612 var _rgb$map = rgb.map(function (value) { 613 return value > 1 ? value / 255 : value; 614 }), 615 r = _rgb$map[0], 616 g = _rgb$map[1], 617 b = _rgb$map[2]; 618 619 var max = Math.max(r, g, b); 620 var min = Math.min(r, g, b); 621 var l = (max + min) / 2; 622 var d = max - min; 623 var h = 0; 624 var s = 0; 625 var a = rgb[3] || values[3] || this.alpha; 626 627 if (max !== min) { 628 if (max === 0) { 629 s = max; 630 } else if (min === 1) { 631 s = min; 632 } else { 633 s = (max - l) / Math.min(l, 1 - l); 634 } 635 636 switch (max) { 637 case r: 638 h = 60 * (g - b) / d; 639 break; 640 641 case g: 642 h = 60 * (2 + (b - r) / d); 643 break; 644 645 case b: 646 default: 647 h = 60 * (4 + (r - g) / d); 648 break; 649 } 650 } 651 652 h = h < 0 ? h + 360 : h; 653 a = a > 1 ? a / 100 : a; 654 return [h, s, l, a]; 655 } 656 /** 657 * Returns hsl values out of hex 658 * @param {string} hex 659 * @return {array} 660 */ 661 ; 662 663 _proto.hexToHsl = function hexToHsl(hex) { 664 var parts = hex.match(hexRegex); 665 var r = parts[1]; 666 var g = parts[2]; 667 var b = parts[3]; 668 var rgb = [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)]; 669 return this.rgbToHsl(rgb); 670 } 671 /** 672 * Convert HSLa values into RGBa 673 * @param {array} hsla 674 * @returns {number[]} 675 */ 676 ; 677 678 _proto.hslToRgb = function hslToRgb(_ref3) { 679 var h = _ref3[0], 680 sat = _ref3[1], 681 light = _ref3[2], 682 alpha = _ref3[3]; 683 var r = 1; 684 var g = 1; 685 var b = 1; // Saturation and light were calculated as 0.24 instead of 24% 686 687 var s = sat > 1 ? sat / 100 : sat; 688 var l = light > 1 ? light / 100 : light; 689 var a = alpha > 1 ? alpha / 100 : alpha; 690 691 if (h < 0 || h > 360 || s < 0 || s > 1 || l < 0 || l > 1) { 692 this.showError('JFIELD_COLOR_ERROR_CONVERT_HSL'); 693 return this.hslToRgb(this.defaultHsl); 694 } 695 696 var c = (1 - Math.abs(2 * l - 1)) * s; 697 var hi = h / 60; 698 var x = c * (1 - Math.abs(hi % 2 - 1)); 699 var m = l - c / 2; 700 701 if (h >= 0 && h < 60) { 702 r = c; 703 g = x; 704 b = 0; 705 } else if (h >= 60 && h < 120) { 706 r = x; 707 g = c; 708 b = 0; 709 } else if (h >= 120 && h < 180) { 710 r = 0; 711 g = c; 712 b = x; 713 } else if (h >= 180 && h < 240) { 714 r = 0; 715 g = x; 716 b = c; 717 } else if (h >= 240 && h < 300) { 718 r = x; 719 g = 0; 720 b = c; 721 } else if (h >= 300 && h <= 360) { 722 r = c; 723 g = 0; 724 b = x; 725 } else { 726 this.showError('JFIELD_COLOR_ERROR_CONVERT_HUE'); 727 return this.hslToRgb(this.defaultHsl); 728 } 729 730 var rgb = [r, g, b].map(function (value) { 731 return Math.round((value + m) * 255); 732 }); 733 rgb.push(a); 734 return rgb; 735 }; 736 737 return JoomlaFieldColorSlider; 738 }(); 739 740 document.addEventListener('DOMContentLoaded', function () { 741 var fields = document.querySelectorAll('.color-slider-wrapper'); 742 743 if (fields) { 744 Array.prototype.forEach.call(fields, function (slider) { 745 // eslint-disable-next-line no-new 746 new JoomlaFieldColorSlider(slider); 747 }); 748 } 749 }); 750 })(document); 751 752 })();
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 |