[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/fields/ -> joomla-field-color-slider-es5.js (source)

   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  })();


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer