diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini
index 02657af53e1d0..8843e2cd6e946 100644
--- a/administrator/language/en-GB/en-GB.ini
+++ b/administrator/language/en-GB/en-GB.ini
@@ -194,6 +194,9 @@ JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL="Logout Description Text"
JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC="Show or hide logout description."
JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL="Logout Description"
JFIELD_CATEGORY_DESC="The category that this item is assigned to. You may select an existing category or enter a new category by typing the name in the field and pressing enter."
+JFIELD_COLOR_SELECT="Select a colour"
+JFIELD_COLOR_TRANSPARENT="No colour, transparent"
+JFIELD_COLOR_VALUE="Colour with hexadecimal value of"
JFIELD_ENABLED_DESC="The enabled status of this item."
JFIELD_FIELDS_CATEGORY_DESC="Select the category that this field is assigned to."
JFIELD_KEY_REFERENCE_DESC="Used to store information referring to an external resource."
diff --git a/build/webcomponents/js/field-simple-color/field-simple-color.js b/build/webcomponents/js/field-simple-color/field-simple-color.js
new file mode 100644
index 0000000000000..cd7e40861f263
--- /dev/null
+++ b/build/webcomponents/js/field-simple-color/field-simple-color.js
@@ -0,0 +1,397 @@
+/**
+ * Based on:
+ * Very simple jQuery Color Picker
+ * Copyright (C) 2012 Tanguy Krotoff
+ * Licensed under the MIT license
+ *
+ * ADAPTED BY: Dimitris Grammatikogiannis
+ *
+ */
+((customElements) => {
+ const KEYCODE = {
+ TAB: 9,
+ ESC: 27,
+ };
+
+ const colorNames = {
+ aliceblue: '#f0f8ff',
+ antiquewhite: '#faebd7',
+ aqua: '#00ffff',
+ aquamarine: '#7fffd4',
+ azure: '#f0ffff',
+ beige: '#f5f5dc',
+ bisque: '#ffe4c4',
+ black: '#000000',
+ blanchedalmond: '#ffebcd',
+ blue: '#0000ff',
+ blueviolet: '#8a2be2',
+ brown: '#a52a2a',
+ burlywood: '#deb887',
+ cadetblue: '#5f9ea0',
+ chartreuse: '#7fff00',
+ chocolate: '#d2691e',
+ coral: '#ff7f50',
+ cornflowerblue: '#6495ed',
+ cornsilk: '#fff8dc',
+ crimson: '#dc143c',
+ cyan: '#00ffff',
+ darkblue: '#00008b',
+ darkcyan: '#008b8b',
+ darkgoldenrod: '#b8860b',
+ darkgray: '#a9a9a9',
+ darkgreen: '#006400',
+ darkgrey: '#a9a9a9',
+ darkkhaki: '#bdb76b',
+ darkmagenta: '#8b008b',
+ darkolivegreen: '#556b2f',
+ darkorange: '#ff8c00',
+ darkorchid: '#9932cc',
+ darkred: '#8b0000',
+ darksalmon: '#e9967a',
+ darkseagreen: '#8fbc8f',
+ darkslateblue: '#483d8b',
+ darkslategray: '#2f4f4f',
+ darkslategrey: '#2f4f4f',
+ darkturquoise: '#00ced1',
+ darkviolet: '#9400d3',
+ deeppink: '#ff1493',
+ deepskyblue: '#00bfff',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1e90ff',
+ firebrick: '#b22222',
+ floralwhite: '#fffaf0',
+ forestgreen: '#228b22',
+ fuchsia: '#ff00ff',
+ gainsboro: '#dcdcdc',
+ ghostwhite: '#f8f8ff',
+ gold: '#ffd700',
+ goldenrod: '#daa520',
+ gray: '#808080',
+ green: '#008000',
+ greenyellow: '#adff2f',
+ grey: '#808080',
+ honeydew: '#f0fff0',
+ hotpink: '#ff69b4',
+ indianred: '#cd5c5c',
+ indigo: '#4b0082',
+ ivory: '#fffff0',
+ khaki: '#f0e68c',
+ lavender: '#e6e6fa',
+ lavenderblush: '#fff0f5',
+ lawngreen: '#7cfc00',
+ lemonchiffon: '#fffacd',
+ lightblue: '#add8e6',
+ lightcoral: '#f08080',
+ lightcyan: '#e0ffff',
+ lightgoldenrodyellow: '#fafad2',
+ lightgray: '#d3d3d3',
+ lightgreen: '#90ee90',
+ lightgrey: '#d3d3d3',
+ lightpink: '#ffb6c1',
+ lightsalmon: '#ffa07a',
+ lightseagreen: '#20b2aa',
+ lightskyblue: '#87cefa',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#b0c4de',
+ lightyellow: '#ffffe0',
+ lime: '#00ff00',
+ limegreen: '#32cd32',
+ linen: '#faf0e6',
+ magenta: '#ff00ff',
+ maroon: '#800000',
+ mediumaquamarine: '#66cdaa',
+ mediumblue: '#0000cd',
+ mediumorchid: '#ba55d3',
+ mediumpurple: '#9370db',
+ mediumseagreen: '#3cb371',
+ mediumslateblue: '#7b68ee',
+ mediumspringgreen: '#00fa9a',
+ mediumturquoise: '#48d1cc',
+ mediumvioletred: '#c71585',
+ midnightblue: '#191970',
+ mintcream: '#f5fffa',
+ mistyrose: '#ffe4e1',
+ moccasin: '#ffe4b5',
+ navajowhite: '#ffdead',
+ navy: '#000080',
+ oldlace: '#fdf5e6',
+ olive: '#808000',
+ olivedrab: '#6b8e23',
+ orange: '#ffa500',
+ orangered: '#ff4500',
+ orchid: '#da70d6',
+ palegoldenrod: '#eee8aa',
+ palegreen: '#98fb98',
+ paleturquoise: '#afeeee',
+ palevioletred: '#db7093',
+ papayawhip: '#ffefd5',
+ peachpuff: '#ffdab9',
+ peru: '#cd853f',
+ pink: '#ffc0cb',
+ plum: '#dda0dd',
+ powderblue: '#b0e0e6',
+ purple: '#800080',
+ red: '#ff0000',
+ rosybrown: '#bc8f8f',
+ royalblue: '#4169e1',
+ saddlebrown: '#8b4513',
+ salmon: '#fa8072',
+ sandybrown: '#f4a460',
+ seagreen: '#2e8b57',
+ seashell: '#fff5ee',
+ sienna: '#a0522d',
+ silver: '#c0c0c0',
+ skyblue: '#87ceeb',
+ slateblue: '#6a5acd',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#fffafa',
+ springgreen: '#00ff7f',
+ steelblue: '#4682b4',
+ tan: '#d2b48c',
+ teal: '#008080',
+ thistle: '#d8bfd8',
+ tomato: '#ff6347',
+ turquoise: '#40e0d0',
+ violet: '#ee82ee',
+ wheat: '#f5deb3',
+ white: '#ffffff',
+ whitesmoke: '#f5f5f5',
+ yellow: '#ffff00',
+ yellowgreen: '#9acd32',
+ };
+
+ class JoomlaFieldSimpleColor extends HTMLElement {
+ constructor() {
+ super();
+
+ // Define some variables
+ this.select = '';
+ this.options = [];
+ this.icon = '';
+ this.panel = '';
+ this.buttons = [];
+ this.focusableElements = null;
+ 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^="-"])'];
+ }
+
+ connectedCallback() {
+ this.select = this.querySelector('select');
+
+ if (!this.select) {
+ throw new Error('Simple color field requires a select element')
+ }
+
+ this.options = [].slice.call(this.select.querySelectorAll('option'));
+
+ this.select.classList.add('hidden');
+
+ // Build the pop up
+ this.options.forEach((option) => {
+ let color = option.value;
+ let clss = 'swatch';
+
+ if (color === 'none') {
+ clss += ' nocolor';
+ color = 'transparent';
+ }
+ if (option.selected) {
+ clss += ' active';
+ }
+
+ const el = document.createElement('button');
+ el.setAttribute('class', clss);
+ el.style.backgroundColor = color;
+ el.setAttribute('type', 'button');
+ const a11yColor = color === 'transparent' ? this.textTransp : this.getColorName(color);
+ el.innerHTML = `${a11yColor}`;
+
+ this.buttons.push(el)
+ });
+
+ // Add a close button
+ const close = document.createElement('button');
+ close.setAttribute('class', 'btn-close');
+ close.setAttribute('type', 'button');
+ close.innerHTML = this.textClose;
+
+ this.buttons.push(close);
+
+ let color = this.select.value;
+ let clss = '';
+
+ if (color === 'none') {
+ clss += ' nocolor';
+ color = 'transparent';
+ }
+
+ this.icon = document.createElement('button');
+
+ if (clss) {
+ this.icon.setAttribute('class', clss);
+ }
+
+ const uniqueId = `simple-color-${Math.random().toString(36).substr(2, 10)}`;
+ this.icon.setAttribute('type', 'button');
+ this.icon.setAttribute('tabindex', '0');
+ this.icon.style.backgroundColor = color
+ this.icon.innerHTML = '' + this.textSelect + '';
+ this.icon.id = uniqueId;
+ this.select.insertAdjacentElement('beforebegin', this.icon);
+ this.icon.addEventListener('click', this.show.bind(this));
+
+ this.panel = document.createElement('div');
+ this.panel.classList.add('simplecolors-panel');
+ this.panel.setAttribute('aria-labelledby', uniqueId);
+
+ this.buttons.forEach((el) => {
+ if (el.classList.contains('btn-close')) {
+ el.addEventListener('click', this.hide.bind(this));
+ } else {
+ el.addEventListener('click', this.colorSelect.bind(this));
+ }
+
+ this.panel.insertAdjacentElement('beforeend', el);
+ });
+
+ this.appendChild(this.panel);
+
+ this.focusableElements = [].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join()));
+
+ this.keys = this.keys .bind(this);
+ this.hide = this.hide.bind(this);
+ this.mousedown = this.mousedown.bind(this);
+ }
+
+ disconnectedCallback() {
+
+ }
+
+ static get observedAttributes() {
+ return ['text-select', 'text-color', 'text-close', 'text-transparent'];
+ }
+
+ get textSelect() { return this.getAttribute('text-select'); }
+ get textColor() { return this.getAttribute('text-color'); }
+ get textClose() { return this.getAttribute('text-close'); }
+ get textTransp() { return this.getAttribute('text-transparent'); }
+
+ // Show the panel
+ show() {
+ document.addEventListener('mousedown', this.hide);
+ this.addEventListener('keydown', this.keys);
+ this.panel.addEventListener('mousedown', this.mousedown);
+ this.panel.setAttribute('data-open', '');
+
+ const focused = this.panel.querySelector('button');
+
+ if (focused) {
+ focused.focus();
+ }
+ }
+
+ // Hide panel
+ hide() {
+ document.removeEventListener('mousedown', this.hide, false);
+ this.removeEventListener('keydown', this.keys);
+
+ if (this.panel.hasAttribute('data-open')) {
+ this.panel.removeAttribute('data-open');
+ }
+
+ this.icon.focus();
+ }
+
+ colorSelect(e) {
+ let color = '';
+ let bgcolor = '';
+ let clss = '';
+
+ if (e.target.classList.contains('nocolor')) {
+ color = 'none';
+ bgcolor = 'transparent';
+ clss = 'nocolor';
+ } else {
+ color = e.target.style.backgroundColor;
+ bgcolor = color;
+ }
+
+ // Reset the active class
+ this.buttons.forEach((el) => {
+ if (el.classList.contains('active')) {
+ el.classList.remove('active')
+ }
+ });
+
+ // Add the active class to the selected button
+ e.target.classList.add('active');
+
+ this.icon.classList.remove('nocolor');
+ this.icon.setAttribute('class', clss);
+ this.icon.style.backgroundColor = bgcolor;
+
+ // Hide the panel
+ this.hide();
+
+ // Change select value
+ this.options.forEach((el) => {
+ if (el.selected) {
+ el.removeAttribute('selected');
+ }
+
+ if (el.value === bgcolor) {
+ el.setAttribute('selected', '');
+ }
+ });
+ }
+
+ keys(e) {
+ if (e.keyCode === KEYCODE.ESC) {
+ this.hide();
+ }
+
+ if (e.keyCode === KEYCODE.TAB) {
+ // Get the index of the current active element
+ const focusedIndex = this.focusableElements.indexOf(document.activeElement);
+
+ // If first element is focused and shiftkey is in use, focus last item within modal
+ if (e.shiftKey && (focusedIndex === 0 || focusedIndex === -1)) {
+ this.focusableElements[this.focusableElements.length - 1].focus();
+ e.preventDefault();
+ }
+ // If last element is focused and shiftkey is not in use, focus first item within modal
+ if (!e.shiftKey && focusedIndex === this.focusableElements.length - 1) {
+ this.focusableElements[0].focus();
+ e.preventDefault();
+ }
+ }
+ }
+
+ // Prevents the mousedown event from "eating" the click event.
+ mousedown(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+
+ getColorName(value) {
+ // Expand any short code
+ let newValue = value;
+ if (value.length === 4) {
+ const tmpValue = value.split('');
+ newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] + tmpValue[2] + tmpValue[3] + tmpValue[3];
+ }
+
+ for (const color in colorNames) {
+ if (colorNames.hasOwnProperty(color) && newValue.toLowerCase() === colorNames[color]) {
+ return color;
+ }
+ }
+
+ return this.textColor + ' ' + value.replace('#', '').split('').join(', ')
+ }
+ }
+
+ customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor);
+})(customElements);
diff --git a/build/webcomponents/scss/field-simple-color/field-simple-color.scss b/build/webcomponents/scss/field-simple-color/field-simple-color.scss
new file mode 100644
index 0000000000000..106312a738b14
--- /dev/null
+++ b/build/webcomponents/scss/field-simple-color/field-simple-color.scss
@@ -0,0 +1,70 @@
+joomla-field-simple-color {
+ display: block;
+
+ .hidden {
+ display: none;
+ }
+
+ .sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0,0,0,0);
+ border: 0;
+ }
+
+ button {
+ width: 20px;
+ height: 20px;
+ border: solid 1px #ccc;
+ vertical-align: middle;
+ border-radius: 3px;
+ overflow: hidden;
+ background: none;
+ -webkit-appearence: none;
+ }
+
+ .btn-close {
+ width: auto;
+ padding: 0 6px;
+ margin-top: -4px;
+ font-size: 1rem;
+ line-height: 1.5;
+ text-align: center;
+ vertical-align: middle;
+ }
+
+ .nocolor {
+ background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggRDQENU0dyawAAACZJREFUGNNjPHXqDAMSMDY2ROYyMeAFNJVm/Pv3LzL/7Nnzg8VpAKebCGpIIxHBAAAAAElFTkSuQmCC') !important;
+ }
+ .simplecolors-panel .swatch {
+ margin: 0 4px 4px 0;
+ }
+
+ .swatch:hover,
+ .swatch.active {
+ border-color: rgba(82, 168, 236, .8);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82, 168, 236, .6);
+ }
+
+ .simplecolors-panel[data-open=""] {
+ display: block;
+ }
+ .simplecolors-panel {
+ position: absolute;
+ z-index: 12;
+ display: none;
+ float: left;
+ padding: 6px 2px 2px 6px;
+ margin: 1px 0 0;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ddd;
+ border-radius: 5px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ }
+}
+
diff --git a/language/en-GB/en-GB.ini b/language/en-GB/en-GB.ini
index 42b7db9a2d477..dbadd1f29361d 100644
--- a/language/en-GB/en-GB.ini
+++ b/language/en-GB/en-GB.ini
@@ -150,6 +150,9 @@ JFIELD_ALIAS_LABEL="Alias"
JFIELD_ALIAS_PLACEHOLDER="Auto-generate from title"
JFIELD_ALT_PAGE_TITLE_LABEL="Alternative Page Title"
JFIELD_CATEGORY_DESC="Category"
+JFIELD_COLOR_SELECT="Select a colour"
+JFIELD_COLOR_TRANSPARENT="No colour, transparent"
+JFIELD_COLOR_VALUE="Colour with hexadecimal value of"
JFIELD_FIELDS_CATEGORY_DESC="Select the category that this field is assigned to."
JFIELD_LANGUAGE_DESC="Assign a language to this article."
JFIELD_LANGUAGE_LABEL="Language"
diff --git a/layouts/joomla/form/field/color/simple.php b/layouts/joomla/form/field/color/simple.php
index fa7e5ed9da106..89f687d3dc760 100644
--- a/layouts/joomla/form/field/color/simple.php
+++ b/layouts/joomla/form/field/color/simple.php
@@ -10,8 +10,9 @@
defined('JPATH_BASE') or die;
use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
-extract($displayData);
+extract($displayData, null);
/**
* Layout variables
@@ -45,25 +46,21 @@
* @var array $checked Is this field checked?
* @var array $position Is this field checked?
* @var array $control Is this field checked?
+ * @var array $colors The specified colors
*/
-$class = ' class="custom-select ' . trim('simplecolors chzn-done ' . $class) . '"';
+$class = ' class="custom-select ' . trim($class) . '"';
$disabled = $disabled ? ' disabled' : '';
$readonly = $readonly ? ' readonly' : '';
-// Include jQuery
-HTMLHelper::_('jquery.framework');
-HTMLHelper::_('script', 'system/fields/simplecolors.min.js', array('version' => 'auto', 'relative' => true));
-HTMLHelper::_('stylesheet', 'system/simplecolors.css', array('version' => 'auto', 'relative' => true));
-HTMLHelper::_('script', 'system/fields/color-field-init.min.js', array('version' => 'auto', 'relative' => true));
+HTMLHelper::_('webcomponent', 'system/webcomponents/joomla-field-simple-color.min.js', ['version' => 'auto', 'relative' => true]);
?>
-
+
+
+
diff --git a/media/system/css/simplecolors.css b/media/system/css/simplecolors.css
deleted file mode 100644
index 2d69d2042236e..0000000000000
--- a/media/system/css/simplecolors.css
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * LOOSELY BASED ON:
- * Very simple jQuery Color Picker
- * Copyright (C) 2012 Tanguy Krotoff
- * Licensed under the MIT license
- *
- * ADAPTED BY:
- * Copyright (C) 2013 Peter van Westen
- */
-
-.simplecolors-swatch {
- cursor: pointer;
- position: relative;
- width: 20px;
- height: 20px;
- background: url(../images/jquery.minicolors.png) -80px 0;
- border: solid 1px #CCC;
- vertical-align: middle;
- display: inline-block;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- overflow: hidden;
-}
-
-.simplecolors-swatch span {
- position: absolute;
- width: 100%;
- height: 100%;
- background: none;
- -webkit-box-shadow: inset 0 9px 0 rgba(255, 255, 255, .1);
- -moz-box-shadow: inset 0 9px 0 rgba(255, 255, 255, .1);
- box-shadow: inset 0 9px 0 rgba(255, 255, 255, .1);
- display: inline-block;
-}
-
-.simplecolors-panel .simplecolors-swatch {
- margin: 0 4px 4px 0;
-}
-
-.simplecolors-swatch.active,
-.simplecolors-swatch:hover,
-.simplecolors-swatch:focus,
-.simplecolors-swatch span:focus {
- outline: 0;
- outline: thin dotted \9; /* IE6-9 */
-}
-
-.simplecolors-swatch:hover,
-.simplecolors-swatch.active {
- border-color: rgba(82, 168, 236, 0.8);
- -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
- -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
- box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
-}
-
-.simplecolors-panel {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: 12;
- display: none;
- float: left;
- padding: 6px 2px 2px 6px;
- margin: 1px 0 0;
- list-style: none;
- background-color: #ffffff;
- border: 1px solid #dddddd;
- *border-right-width: 2px;
- *border-bottom-width: 2px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- -webkit-background-clip: padding-box;
- -moz-background-clip: padding-box;
- background-clip: padding-box;
-}
diff --git a/media/system/js/fields/color-field-init.js b/media/system/js/fields/color-field-init.js
deleted file mode 100644
index f50be0da98051..0000000000000
--- a/media/system/js/fields/color-field-init.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE.txt
- */
-
-!(function(document, $) {
- "use strict";
-
- function initSimpleColorField (event) {
- $(event.target).find('select.simplecolors').simplecolors();
- }
-
- /**
- * Initialize at an initial page load
- */
- document.addEventListener("DOMContentLoaded", initSimpleColorField);
-
- /**
- * Initialize when a part of the page was updated
- */
- document.addEventListener("joomla:updated", initSimpleColorField);
-
-})(document, jQuery);
diff --git a/media/system/js/fields/color-field-init.min.js b/media/system/js/fields/color-field-init.min.js
deleted file mode 100644
index 32af48b72ab36..0000000000000
--- a/media/system/js/fields/color-field-init.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,t){"use strict";function n(e){t(e.target).find("select.simplecolors").simplecolors()}e.addEventListener("DOMContentLoaded",n),e.addEventListener("joomla:updated",n)}(document,jQuery);
\ No newline at end of file
diff --git a/media/system/js/fields/simplecolors.js b/media/system/js/fields/simplecolors.js
deleted file mode 100644
index 8b0ff37387742..0000000000000
--- a/media/system/js/fields/simplecolors.js
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * LOOSELY BASED ON:
- * Very simple jQuery Color Picker
- * Copyright (C) 2012 Tanguy Krotoff
- * Licensed under the MIT license
- *
- * ADAPTED BY:
- * Copyright (C) 2013 Peter van Westen
- */
-
-(function($) {
- var SimpleColorPicker = function(element, options) {
- this.select = $(element);
- this.options = $.extend({}, $.fn.simplecolors.defaults, options);
-
- this.select.hide();
-
- // Build the list of colors
- var list = '';
- $('option', this.select).each(function() {
- var option = $(this);
- var color = option.val();
- if (option.text() == '-') {
- list += '
';
- } else {
- var clss = 'simplecolors-swatch';
- if (color == 'none') {
- clss += ' nocolor';
- color = 'transparent';
- }
- if (option.attr('selected')) {
- clss += ' active';
- }
- list += '';
- }
- });
-
- var color = this.select.val();
- var clss = 'simplecolors-swatch';
- if (color == 'none') {
- clss += ' nocolor';
- color = 'transparent';
- }
- this.icon = $('').insertAfter(this.select);
- this.icon.on('click', $.proxy(this.show, this));
-
- this.panel = $('').appendTo(document.body);
- this.panel.html(list);
- this.panel.on('click', $.proxy(this.click, this));
-
- // Hide panel when clicking outside
- $(document).on('mousedown', $.proxy(this.hide, this));
- this.panel.on('mousedown', $.proxy(this.mousedown, this));
-
- };
-
- /**
- * SimpleColorPicker class
- */
- SimpleColorPicker.prototype = {
- constructor: SimpleColorPicker,
-
- show: function() {
- var panelpadding = 7; // Empirical value
- var pos = this.icon.offset();
- switch (this.select.attr('data-position')) {
- case 'top':
- this.panel.css({
- left: pos.left - panelpadding,
- top: pos.top - this.panel.outerHeight() - 1
- });
- break;
- case 'bottom':
- this.panel.css({
- left: pos.left - panelpadding,
- top: pos.top + this.icon.outerHeight()
- });
- break;
- case 'left':
- this.panel.css({
- left: pos.left - this.panel.outerWidth(),
- top: pos.top - ( (this.panel.outerHeight() - this.icon.outerHeight() ) / 2 ) - 1
- });
- break;
- case 'right':
- default:
- this.panel.css({
- left: pos.left + this.icon.outerWidth(),
- top: pos.top - ( (this.panel.outerHeight() - this.icon.outerHeight() ) / 2 ) - 1
- });
- break;
- }
-
- this.panel.show(this.options.delay);
- },
-
- hide: function() {
- if (this.panel.css('display') != 'none') {
- this.panel.hide(this.options.delay);
- }
- },
-
- click: function(e) {
- var target = $(e.target);
- if (target.length === 1) {
- if (target[0].nodeName.toLowerCase() === 'span') {
- // When you click on a color
-
- var color = '';
- var bgcolor = '';
- var clss = '';
- if (target.parent().hasClass('nocolor')) {
- color = 'none';
- bgcolor = 'transparent';
- clss = 'nocolor';
- } else {
- color = this.rgb2hex(target.css('background-color'));
- bgcolor = color;
- }
-
- // Mark this div as the selected one
- target.parent().siblings().removeClass('active');
- target.parent().addClass('active');
-
- this.icon.removeClass('nocolor').addClass(clss);
- this.icon.find('span').css('background-color', bgcolor);
-
- // Hide the panel
- this.hide();
-
- // Change select value
- this.select.val(color).change();
- }
- }
- },
-
- /**
- * Prevents the mousedown event from "eating" the click event.
- */
- mousedown: function(e) {
- e.stopPropagation();
- e.preventDefault();
- },
-
- /**
- * Converts a RGB color to its hexadecimal value.
- *
- * See http://stackoverflow.com/questions/1740700/get-hex-value-rather-than-rgb-value-using-$
- */
- rgb2hex: function(rgb) {
- function hex(x) {
- return ("0" + parseInt(x, 10).toString(16)).slice(-2);
- }
-
- var matches = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
- if (matches === null) {
- // Fix for Internet Explorer < 9
- // Variable rgb is already a hexadecimal value
- return rgb;
- } else {
- return '#' + hex(matches[1]) + hex(matches[2]) + hex(matches[3]);
- }
- }
- };
-
- /**
- * Plugin definition.
- */
- $.fn.simplecolors = function(option) {
- // For HTML element passed to the plugin
- return this.each(function() {
- var $this = $(this),
- data = $this.data('simplecolors'),
- options = typeof option === 'object' && option;
- if (!data) {
- $this.data('simplecolors', (data = new SimpleColorPicker(this, options)));
- }
- if (typeof option === 'string') {
- data[option]();
- }
- });
- };
-
- $.fn.simplecolors.Constructor = SimpleColorPicker;
-
- /**
- * Default options.
- */
- $.fn.simplecolors.defaults = {
- // Animation delay
- delay: 0
- };
-})(jQuery);
diff --git a/media/system/js/fields/simplecolors.min.js b/media/system/js/fields/simplecolors.min.js
deleted file mode 100644
index 8126476cfd0d8..0000000000000
--- a/media/system/js/fields/simplecolors.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(t){var s=function(s,e){this.select=t(s),this.options=t.extend({},t.fn.simplecolors.defaults,e),this.select.hide();var o="";t("option",this.select).each(function(){var s=t(this),e=s.val();if("-"==s.text())o+="
";else{var n="simplecolors-swatch";"none"==e&&(n+=" nocolor",e="transparent"),s.attr("selected")&&(n+=" active"),o+=''}});var n=this.select.val(),i="simplecolors-swatch";"none"==n&&(i+=" nocolor",n="transparent"),this.icon=t('').insertAfter(this.select),this.icon.on("click",t.proxy(this.show,this)),this.panel=t('').appendTo(document.body),this.panel.html(o),this.panel.on("click",t.proxy(this.click,this)),t(document).on("mousedown",t.proxy(this.hide,this)),this.panel.on("mousedown",t.proxy(this.mousedown,this))};s.prototype={constructor:s,show:function(){var t=this.icon.offset();switch(this.select.attr("data-position")){case"top":this.panel.css({left:t.left-7,top:t.top-this.panel.outerHeight()-1});break;case"bottom":this.panel.css({left:t.left-7,top:t.top+this.icon.outerHeight()});break;case"left":this.panel.css({left:t.left-this.panel.outerWidth(),top:t.top-(this.panel.outerHeight()-this.icon.outerHeight())/2-1});break;case"right":default:this.panel.css({left:t.left+this.icon.outerWidth(),top:t.top-(this.panel.outerHeight()-this.icon.outerHeight())/2-1})}this.panel.show(this.options.delay)},hide:function(){"none"!=this.panel.css("display")&&this.panel.hide(this.options.delay)},click:function(s){var e=t(s.target);if(1===e.length&&"span"===e[0].nodeName.toLowerCase()){var o="",n="",i="";e.parent().hasClass("nocolor")?(o="none",n="transparent",i="nocolor"):n=o=this.rgb2hex(e.css("background-color")),e.parent().siblings().removeClass("active"),e.parent().addClass("active"),this.icon.removeClass("nocolor").addClass(i),this.icon.find("span").css("background-color",n),this.hide(),this.select.val(o).change()}},mousedown:function(t){t.stopPropagation(),t.preventDefault()},rgb2hex:function(t){function s(t){return("0"+parseInt(t,10).toString(16)).slice(-2)}var e=t.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);return null===e?t:"#"+s(e[1])+s(e[2])+s(e[3])}},t.fn.simplecolors=function(e){return this.each(function(){var o=t(this),n=o.data("simplecolors"),i="object"==typeof e&&e;n||o.data("simplecolors",n=new s(this,i)),"string"==typeof e&&n[e]()})},t.fn.simplecolors.Constructor=s,t.fn.simplecolors.defaults={delay:0}}(jQuery);
\ No newline at end of file
diff --git a/media/system/webcomponents/css/joomla-field-simple-color.css b/media/system/webcomponents/css/joomla-field-simple-color.css
new file mode 100644
index 0000000000000..3ed029baaa58e
--- /dev/null
+++ b/media/system/webcomponents/css/joomla-field-simple-color.css
@@ -0,0 +1,54 @@
+joomla-field-simple-color {
+ display: block; }
+ joomla-field-simple-color .hidden {
+ display: none; }
+ joomla-field-simple-color .sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0; }
+ joomla-field-simple-color button {
+ width: 20px;
+ height: 20px;
+ border: solid 1px #ccc;
+ vertical-align: middle;
+ border-radius: 3px;
+ overflow: hidden;
+ background: none;
+ -webkit-appearence: none; }
+ joomla-field-simple-color .btn-close {
+ width: auto;
+ padding: 0 6px;
+ margin-top: -4px;
+ font-size: 1rem;
+ line-height: 1.5;
+ text-align: center;
+ vertical-align: middle; }
+ joomla-field-simple-color .nocolor {
+ background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggRDQENU0dyawAAACZJREFUGNNjPHXqDAMSMDY2ROYyMeAFNJVm/Pv3LzL/7Nnzg8VpAKebCGpIIxHBAAAAAElFTkSuQmCC") !important; }
+ joomla-field-simple-color .simplecolors-panel .swatch {
+ margin: 0 4px 4px 0; }
+ joomla-field-simple-color .swatch:hover,
+ joomla-field-simple-color .swatch.active {
+ border-color: rgba(82, 168, 236, 0.8);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
+ joomla-field-simple-color .simplecolors-panel[data-open=""] {
+ display: block; }
+ joomla-field-simple-color .simplecolors-panel {
+ position: absolute;
+ z-index: 12;
+ display: none;
+ float: left;
+ padding: 6px 2px 2px 6px;
+ margin: 1px 0 0;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ddd;
+ border-radius: 5px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); }
diff --git a/media/system/webcomponents/css/joomla-field-simple-color.min.css b/media/system/webcomponents/css/joomla-field-simple-color.min.css
new file mode 100644
index 0000000000000..8acbc0fd23b9a
--- /dev/null
+++ b/media/system/webcomponents/css/joomla-field-simple-color.min.css
@@ -0,0 +1 @@
+joomla-field-simple-color{display:block}joomla-field-simple-color .hidden{display:none}joomla-field-simple-color .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}joomla-field-simple-color button{width:20px;height:20px;border:solid 1px #ccc;vertical-align:middle;border-radius:3px;overflow:hidden;background:0;-webkit-appearence:none}joomla-field-simple-color .btn-close{width:auto;padding:0 6px;margin-top:-4px;font-size:1rem;line-height:1.5;text-align:center;vertical-align:middle}joomla-field-simple-color .nocolor{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggRDQENU0dyawAAACZJREFUGNNjPHXqDAMSMDY2ROYyMeAFNJVm/Pv3LzL/7Nnzg8VpAKebCGpIIxHBAAAAAElFTkSuQmCC") !important}joomla-field-simple-color .simplecolors-panel .swatch{margin:0 4px 4px 0}joomla-field-simple-color .swatch:hover,joomla-field-simple-color .swatch.active{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}joomla-field-simple-color .simplecolors-panel[data-open=""]{display:block}joomla-field-simple-color .simplecolors-panel{position:absolute;z-index:12;display:none;float:left;padding:6px 2px 2px 6px;margin:1px 0 0;background-color:#fff;background-clip:padding-box;border:1px solid #ddd;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}
\ No newline at end of file
diff --git a/media/system/webcomponents/js/joomla-field-simple-color-es5.js b/media/system/webcomponents/js/joomla-field-simple-color-es5.js
new file mode 100644
index 0000000000000..7becec7c2963e
--- /dev/null
+++ b/media/system/webcomponents/js/joomla-field-simple-color-es5.js
@@ -0,0 +1,449 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o';
+
+ _this2.buttons.push(el);
+ });
+
+ // Add a close button
+ var close = document.createElement('button');
+ close.setAttribute('class', 'btn-close');
+ close.setAttribute('type', 'button');
+ close.innerHTML = this.textClose;
+
+ this.buttons.push(close);
+
+ var color = this.select.value;
+ var clss = '';
+
+ if (color === 'none') {
+ clss += ' nocolor';
+ color = 'transparent';
+ }
+
+ this.icon = document.createElement('button');
+
+ if (clss) {
+ this.icon.setAttribute('class', clss);
+ }
+
+ var uniqueId = 'simple-color-' + Math.random().toString(36).substr(2, 10);
+ this.icon.setAttribute('type', 'button');
+ this.icon.setAttribute('tabindex', '0');
+ this.icon.style.backgroundColor = color;
+ this.icon.innerHTML = '' + this.textSelect + '';
+ this.icon.id = uniqueId;
+ this.select.insertAdjacentElement('beforebegin', this.icon);
+ this.icon.addEventListener('click', this.show.bind(this));
+
+ this.panel = document.createElement('div');
+ this.panel.classList.add('simplecolors-panel');
+ this.panel.setAttribute('aria-labelledby', uniqueId);
+
+ this.buttons.forEach(function (el) {
+ if (el.classList.contains('btn-close')) {
+ el.addEventListener('click', _this2.hide.bind(_this2));
+ } else {
+ el.addEventListener('click', _this2.colorSelect.bind(_this2));
+ }
+
+ _this2.panel.insertAdjacentElement('beforeend', el);
+ });
+
+ this.appendChild(this.panel);
+
+ this.focusableElements = [].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join()));
+
+ this.keys = this.keys.bind(this);
+ this.hide = this.hide.bind(this);
+ this.mousedown = this.mousedown.bind(this);
+ }
+ }, {
+ key: 'disconnectedCallback',
+ value: function disconnectedCallback() {}
+ }, {
+ key: 'show',
+
+
+ // Show the panel
+ value: function show() {
+ document.addEventListener('mousedown', this.hide);
+ this.addEventListener('keydown', this.keys);
+ this.panel.addEventListener('mousedown', this.mousedown);
+ this.panel.setAttribute('data-open', '');
+
+ var focused = this.panel.querySelector('button');
+
+ if (focused) {
+ focused.focus();
+ }
+ }
+
+ // Hide panel
+
+ }, {
+ key: 'hide',
+ value: function hide() {
+ document.removeEventListener('mousedown', this.hide, false);
+ this.removeEventListener('keydown', this.keys);
+
+ if (this.panel.hasAttribute('data-open')) {
+ this.panel.removeAttribute('data-open');
+ }
+
+ this.icon.focus();
+ }
+ }, {
+ key: 'colorSelect',
+ value: function colorSelect(e) {
+ var color = '';
+ var bgcolor = '';
+ var clss = '';
+
+ if (e.target.classList.contains('nocolor')) {
+ color = 'none';
+ bgcolor = 'transparent';
+ clss = 'nocolor';
+ } else {
+ color = e.target.style.backgroundColor;
+ bgcolor = color;
+ }
+
+ // Reset the active class
+ this.buttons.forEach(function (el) {
+ if (el.classList.contains('active')) {
+ el.classList.remove('active');
+ }
+ });
+
+ // Add the active class to the selected button
+ e.target.classList.add('active');
+
+ this.icon.classList.remove('nocolor');
+ this.icon.setAttribute('class', clss);
+ this.icon.style.backgroundColor = bgcolor;
+
+ // Hide the panel
+ this.hide();
+
+ // Change select value
+ this.options.forEach(function (el) {
+ if (el.selected) {
+ el.removeAttribute('selected');
+ }
+
+ if (el.value === bgcolor) {
+ el.setAttribute('selected', '');
+ }
+ });
+ }
+ }, {
+ key: 'keys',
+ value: function keys(e) {
+ if (e.keyCode === KEYCODE.ESC) {
+ this.hide();
+ }
+
+ if (e.keyCode === KEYCODE.TAB) {
+ // Get the index of the current active element
+ var focusedIndex = this.focusableElements.indexOf(document.activeElement);
+
+ // If first element is focused and shiftkey is in use, focus last item within modal
+ if (e.shiftKey && (focusedIndex === 0 || focusedIndex === -1)) {
+ this.focusableElements[this.focusableElements.length - 1].focus();
+ e.preventDefault();
+ }
+ // If last element is focused and shiftkey is not in use, focus first item within modal
+ if (!e.shiftKey && focusedIndex === this.focusableElements.length - 1) {
+ this.focusableElements[0].focus();
+ e.preventDefault();
+ }
+ }
+ }
+
+ // Prevents the mousedown event from "eating" the click event.
+
+ }, {
+ key: 'mousedown',
+ value: function mousedown(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }, {
+ key: 'getColorName',
+ value: function getColorName(value) {
+ // Expand any short code
+ var newValue = value;
+ if (value.length === 4) {
+ var tmpValue = value.split('');
+ newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] + tmpValue[2] + tmpValue[3] + tmpValue[3];
+ }
+
+ for (var color in colorNames) {
+ if (colorNames.hasOwnProperty(color) && newValue.toLowerCase() === colorNames[color]) {
+ return color;
+ }
+ }
+
+ return this.textColor + ' ' + value.replace('#', '').split('').join(', ');
+ }
+ }, {
+ key: 'textSelect',
+ get: function get() {
+ return this.getAttribute('text-select');
+ }
+ }, {
+ key: 'textColor',
+ get: function get() {
+ return this.getAttribute('text-color');
+ }
+ }, {
+ key: 'textClose',
+ get: function get() {
+ return this.getAttribute('text-close');
+ }
+ }, {
+ key: 'textTransp',
+ get: function get() {
+ return this.getAttribute('text-transparent');
+ }
+ }], [{
+ key: 'observedAttributes',
+ get: function get() {
+ return ['text-select', 'text-color', 'text-close', 'text-transparent'];
+ }
+ }]);
+
+ return JoomlaFieldSimpleColor;
+ }(HTMLElement);
+
+ customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor);
+})(customElements);
+
+},{}]},{},[1]);
diff --git a/media/system/webcomponents/js/joomla-field-simple-color-es5.min.js b/media/system/webcomponents/js/joomla-field-simple-color-es5.min.js
new file mode 100644
index 0000000000000..9ab1da8c5eefd
--- /dev/null
+++ b/media/system/webcomponents/js/joomla-field-simple-color-es5.min.js
@@ -0,0 +1,4 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o'+f+'',a.buttons.push(e)});var b=document.createElement('button');b.setAttribute('class','btn-close'),b.setAttribute('type','button'),b.innerHTML=this.textClose,this.buttons.push(b);var c=this.select.value,d='';'none'===c&&(d+=' nocolor',c='transparent'),this.icon=document.createElement('button'),d&&this.icon.setAttribute('class',d);var e='simple-color-'+Math.random().toString(36).substr(2,10);this.icon.setAttribute('type','button'),this.icon.setAttribute('tabindex','0'),this.icon.style.backgroundColor=c,this.icon.innerHTML=''+this.textSelect+'',this.icon.id=e,this.select.insertAdjacentElement('beforebegin',this.icon),this.icon.addEventListener('click',this.show.bind(this)),this.panel=document.createElement('div'),this.panel.classList.add('simplecolors-panel'),this.panel.setAttribute('aria-labelledby',e),this.buttons.forEach(function(b){b.classList.contains('btn-close')?b.addEventListener('click',a.hide.bind(a)):b.addEventListener('click',a.colorSelect.bind(a)),a.panel.insertAdjacentElement('beforeend',b)}),this.appendChild(this.panel),this.focusableElements=[].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join())),this.keys=this.keys.bind(this),this.hide=this.hide.bind(this),this.mousedown=this.mousedown.bind(this)}},{key:'disconnectedCallback',value:function disconnectedCallback(){}},{key:'show',value:function show(){document.addEventListener('mousedown',this.hide),this.addEventListener('keydown',this.keys),this.panel.addEventListener('mousedown',this.mousedown),this.panel.setAttribute('data-open','');var a=this.panel.querySelector('button');a&&a.focus()}},{key:'hide',value:function hide(){document.removeEventListener('mousedown',this.hide,!1),this.removeEventListener('keydown',this.keys),this.panel.hasAttribute('data-open')&&this.panel.removeAttribute('data-open'),this.icon.focus()}},{key:'colorSelect',value:function colorSelect(a){var b='',c='',d='';a.target.classList.contains('nocolor')?(b='none',c='transparent',d='nocolor'):(b=a.target.style.backgroundColor,c=b),this.buttons.forEach(function(a){a.classList.contains('active')&&a.classList.remove('active')}),a.target.classList.add('active'),this.icon.classList.remove('nocolor'),this.icon.setAttribute('class',d),this.icon.style.backgroundColor=c,this.hide(),this.options.forEach(function(a){a.selected&&a.removeAttribute('selected'),a.value===c&&a.setAttribute('selected','')})}},{key:'keys',value:function keys(a){if(a.keyCode===b.ESC&&this.hide(),a.keyCode===b.TAB){var c=this.focusableElements.indexOf(document.activeElement);a.shiftKey&&(0===c||-1===c)&&(this.focusableElements[this.focusableElements.length-1].focus(),a.preventDefault()),a.shiftKey||c!==this.focusableElements.length-1||(this.focusableElements[0].focus(),a.preventDefault())}}},{key:'mousedown',value:function mousedown(a){a.stopPropagation(),a.preventDefault()}},{key:'getColorName',value:function getColorName(a){var b=a;if(4===a.length){var d=a.split('');b=d[0]+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]}for(var e in c)if(c.hasOwnProperty(e)&&b.toLowerCase()===c[e])return e;return this.textColor+' '+a.replace('#','').split('').join(', ')}},{key:'textSelect',get:function get(){return this.getAttribute('text-select')}},{key:'textColor',get:function get(){return this.getAttribute('text-color')}},{key:'textClose',get:function get(){return this.getAttribute('text-close')}},{key:'textTransp',get:function get(){return this.getAttribute('text-transparent')}}],[{key:'observedAttributes',get:function get(){return['text-select','text-color','text-close','text-transparent']}}]),d}(HTMLElement);a.define('joomla-field-simple-color',d)})(customElements);
+
+},{}]},{},[1]);
diff --git a/media/system/webcomponents/js/joomla-field-simple-color.js b/media/system/webcomponents/js/joomla-field-simple-color.js
new file mode 100644
index 0000000000000..cd7e40861f263
--- /dev/null
+++ b/media/system/webcomponents/js/joomla-field-simple-color.js
@@ -0,0 +1,397 @@
+/**
+ * Based on:
+ * Very simple jQuery Color Picker
+ * Copyright (C) 2012 Tanguy Krotoff
+ * Licensed under the MIT license
+ *
+ * ADAPTED BY: Dimitris Grammatikogiannis
+ *
+ */
+((customElements) => {
+ const KEYCODE = {
+ TAB: 9,
+ ESC: 27,
+ };
+
+ const colorNames = {
+ aliceblue: '#f0f8ff',
+ antiquewhite: '#faebd7',
+ aqua: '#00ffff',
+ aquamarine: '#7fffd4',
+ azure: '#f0ffff',
+ beige: '#f5f5dc',
+ bisque: '#ffe4c4',
+ black: '#000000',
+ blanchedalmond: '#ffebcd',
+ blue: '#0000ff',
+ blueviolet: '#8a2be2',
+ brown: '#a52a2a',
+ burlywood: '#deb887',
+ cadetblue: '#5f9ea0',
+ chartreuse: '#7fff00',
+ chocolate: '#d2691e',
+ coral: '#ff7f50',
+ cornflowerblue: '#6495ed',
+ cornsilk: '#fff8dc',
+ crimson: '#dc143c',
+ cyan: '#00ffff',
+ darkblue: '#00008b',
+ darkcyan: '#008b8b',
+ darkgoldenrod: '#b8860b',
+ darkgray: '#a9a9a9',
+ darkgreen: '#006400',
+ darkgrey: '#a9a9a9',
+ darkkhaki: '#bdb76b',
+ darkmagenta: '#8b008b',
+ darkolivegreen: '#556b2f',
+ darkorange: '#ff8c00',
+ darkorchid: '#9932cc',
+ darkred: '#8b0000',
+ darksalmon: '#e9967a',
+ darkseagreen: '#8fbc8f',
+ darkslateblue: '#483d8b',
+ darkslategray: '#2f4f4f',
+ darkslategrey: '#2f4f4f',
+ darkturquoise: '#00ced1',
+ darkviolet: '#9400d3',
+ deeppink: '#ff1493',
+ deepskyblue: '#00bfff',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1e90ff',
+ firebrick: '#b22222',
+ floralwhite: '#fffaf0',
+ forestgreen: '#228b22',
+ fuchsia: '#ff00ff',
+ gainsboro: '#dcdcdc',
+ ghostwhite: '#f8f8ff',
+ gold: '#ffd700',
+ goldenrod: '#daa520',
+ gray: '#808080',
+ green: '#008000',
+ greenyellow: '#adff2f',
+ grey: '#808080',
+ honeydew: '#f0fff0',
+ hotpink: '#ff69b4',
+ indianred: '#cd5c5c',
+ indigo: '#4b0082',
+ ivory: '#fffff0',
+ khaki: '#f0e68c',
+ lavender: '#e6e6fa',
+ lavenderblush: '#fff0f5',
+ lawngreen: '#7cfc00',
+ lemonchiffon: '#fffacd',
+ lightblue: '#add8e6',
+ lightcoral: '#f08080',
+ lightcyan: '#e0ffff',
+ lightgoldenrodyellow: '#fafad2',
+ lightgray: '#d3d3d3',
+ lightgreen: '#90ee90',
+ lightgrey: '#d3d3d3',
+ lightpink: '#ffb6c1',
+ lightsalmon: '#ffa07a',
+ lightseagreen: '#20b2aa',
+ lightskyblue: '#87cefa',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#b0c4de',
+ lightyellow: '#ffffe0',
+ lime: '#00ff00',
+ limegreen: '#32cd32',
+ linen: '#faf0e6',
+ magenta: '#ff00ff',
+ maroon: '#800000',
+ mediumaquamarine: '#66cdaa',
+ mediumblue: '#0000cd',
+ mediumorchid: '#ba55d3',
+ mediumpurple: '#9370db',
+ mediumseagreen: '#3cb371',
+ mediumslateblue: '#7b68ee',
+ mediumspringgreen: '#00fa9a',
+ mediumturquoise: '#48d1cc',
+ mediumvioletred: '#c71585',
+ midnightblue: '#191970',
+ mintcream: '#f5fffa',
+ mistyrose: '#ffe4e1',
+ moccasin: '#ffe4b5',
+ navajowhite: '#ffdead',
+ navy: '#000080',
+ oldlace: '#fdf5e6',
+ olive: '#808000',
+ olivedrab: '#6b8e23',
+ orange: '#ffa500',
+ orangered: '#ff4500',
+ orchid: '#da70d6',
+ palegoldenrod: '#eee8aa',
+ palegreen: '#98fb98',
+ paleturquoise: '#afeeee',
+ palevioletred: '#db7093',
+ papayawhip: '#ffefd5',
+ peachpuff: '#ffdab9',
+ peru: '#cd853f',
+ pink: '#ffc0cb',
+ plum: '#dda0dd',
+ powderblue: '#b0e0e6',
+ purple: '#800080',
+ red: '#ff0000',
+ rosybrown: '#bc8f8f',
+ royalblue: '#4169e1',
+ saddlebrown: '#8b4513',
+ salmon: '#fa8072',
+ sandybrown: '#f4a460',
+ seagreen: '#2e8b57',
+ seashell: '#fff5ee',
+ sienna: '#a0522d',
+ silver: '#c0c0c0',
+ skyblue: '#87ceeb',
+ slateblue: '#6a5acd',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#fffafa',
+ springgreen: '#00ff7f',
+ steelblue: '#4682b4',
+ tan: '#d2b48c',
+ teal: '#008080',
+ thistle: '#d8bfd8',
+ tomato: '#ff6347',
+ turquoise: '#40e0d0',
+ violet: '#ee82ee',
+ wheat: '#f5deb3',
+ white: '#ffffff',
+ whitesmoke: '#f5f5f5',
+ yellow: '#ffff00',
+ yellowgreen: '#9acd32',
+ };
+
+ class JoomlaFieldSimpleColor extends HTMLElement {
+ constructor() {
+ super();
+
+ // Define some variables
+ this.select = '';
+ this.options = [];
+ this.icon = '';
+ this.panel = '';
+ this.buttons = [];
+ this.focusableElements = null;
+ 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^="-"])'];
+ }
+
+ connectedCallback() {
+ this.select = this.querySelector('select');
+
+ if (!this.select) {
+ throw new Error('Simple color field requires a select element')
+ }
+
+ this.options = [].slice.call(this.select.querySelectorAll('option'));
+
+ this.select.classList.add('hidden');
+
+ // Build the pop up
+ this.options.forEach((option) => {
+ let color = option.value;
+ let clss = 'swatch';
+
+ if (color === 'none') {
+ clss += ' nocolor';
+ color = 'transparent';
+ }
+ if (option.selected) {
+ clss += ' active';
+ }
+
+ const el = document.createElement('button');
+ el.setAttribute('class', clss);
+ el.style.backgroundColor = color;
+ el.setAttribute('type', 'button');
+ const a11yColor = color === 'transparent' ? this.textTransp : this.getColorName(color);
+ el.innerHTML = `${a11yColor}`;
+
+ this.buttons.push(el)
+ });
+
+ // Add a close button
+ const close = document.createElement('button');
+ close.setAttribute('class', 'btn-close');
+ close.setAttribute('type', 'button');
+ close.innerHTML = this.textClose;
+
+ this.buttons.push(close);
+
+ let color = this.select.value;
+ let clss = '';
+
+ if (color === 'none') {
+ clss += ' nocolor';
+ color = 'transparent';
+ }
+
+ this.icon = document.createElement('button');
+
+ if (clss) {
+ this.icon.setAttribute('class', clss);
+ }
+
+ const uniqueId = `simple-color-${Math.random().toString(36).substr(2, 10)}`;
+ this.icon.setAttribute('type', 'button');
+ this.icon.setAttribute('tabindex', '0');
+ this.icon.style.backgroundColor = color
+ this.icon.innerHTML = '' + this.textSelect + '';
+ this.icon.id = uniqueId;
+ this.select.insertAdjacentElement('beforebegin', this.icon);
+ this.icon.addEventListener('click', this.show.bind(this));
+
+ this.panel = document.createElement('div');
+ this.panel.classList.add('simplecolors-panel');
+ this.panel.setAttribute('aria-labelledby', uniqueId);
+
+ this.buttons.forEach((el) => {
+ if (el.classList.contains('btn-close')) {
+ el.addEventListener('click', this.hide.bind(this));
+ } else {
+ el.addEventListener('click', this.colorSelect.bind(this));
+ }
+
+ this.panel.insertAdjacentElement('beforeend', el);
+ });
+
+ this.appendChild(this.panel);
+
+ this.focusableElements = [].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join()));
+
+ this.keys = this.keys .bind(this);
+ this.hide = this.hide.bind(this);
+ this.mousedown = this.mousedown.bind(this);
+ }
+
+ disconnectedCallback() {
+
+ }
+
+ static get observedAttributes() {
+ return ['text-select', 'text-color', 'text-close', 'text-transparent'];
+ }
+
+ get textSelect() { return this.getAttribute('text-select'); }
+ get textColor() { return this.getAttribute('text-color'); }
+ get textClose() { return this.getAttribute('text-close'); }
+ get textTransp() { return this.getAttribute('text-transparent'); }
+
+ // Show the panel
+ show() {
+ document.addEventListener('mousedown', this.hide);
+ this.addEventListener('keydown', this.keys);
+ this.panel.addEventListener('mousedown', this.mousedown);
+ this.panel.setAttribute('data-open', '');
+
+ const focused = this.panel.querySelector('button');
+
+ if (focused) {
+ focused.focus();
+ }
+ }
+
+ // Hide panel
+ hide() {
+ document.removeEventListener('mousedown', this.hide, false);
+ this.removeEventListener('keydown', this.keys);
+
+ if (this.panel.hasAttribute('data-open')) {
+ this.panel.removeAttribute('data-open');
+ }
+
+ this.icon.focus();
+ }
+
+ colorSelect(e) {
+ let color = '';
+ let bgcolor = '';
+ let clss = '';
+
+ if (e.target.classList.contains('nocolor')) {
+ color = 'none';
+ bgcolor = 'transparent';
+ clss = 'nocolor';
+ } else {
+ color = e.target.style.backgroundColor;
+ bgcolor = color;
+ }
+
+ // Reset the active class
+ this.buttons.forEach((el) => {
+ if (el.classList.contains('active')) {
+ el.classList.remove('active')
+ }
+ });
+
+ // Add the active class to the selected button
+ e.target.classList.add('active');
+
+ this.icon.classList.remove('nocolor');
+ this.icon.setAttribute('class', clss);
+ this.icon.style.backgroundColor = bgcolor;
+
+ // Hide the panel
+ this.hide();
+
+ // Change select value
+ this.options.forEach((el) => {
+ if (el.selected) {
+ el.removeAttribute('selected');
+ }
+
+ if (el.value === bgcolor) {
+ el.setAttribute('selected', '');
+ }
+ });
+ }
+
+ keys(e) {
+ if (e.keyCode === KEYCODE.ESC) {
+ this.hide();
+ }
+
+ if (e.keyCode === KEYCODE.TAB) {
+ // Get the index of the current active element
+ const focusedIndex = this.focusableElements.indexOf(document.activeElement);
+
+ // If first element is focused and shiftkey is in use, focus last item within modal
+ if (e.shiftKey && (focusedIndex === 0 || focusedIndex === -1)) {
+ this.focusableElements[this.focusableElements.length - 1].focus();
+ e.preventDefault();
+ }
+ // If last element is focused and shiftkey is not in use, focus first item within modal
+ if (!e.shiftKey && focusedIndex === this.focusableElements.length - 1) {
+ this.focusableElements[0].focus();
+ e.preventDefault();
+ }
+ }
+ }
+
+ // Prevents the mousedown event from "eating" the click event.
+ mousedown(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+
+ getColorName(value) {
+ // Expand any short code
+ let newValue = value;
+ if (value.length === 4) {
+ const tmpValue = value.split('');
+ newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] + tmpValue[2] + tmpValue[3] + tmpValue[3];
+ }
+
+ for (const color in colorNames) {
+ if (colorNames.hasOwnProperty(color) && newValue.toLowerCase() === colorNames[color]) {
+ return color;
+ }
+ }
+
+ return this.textColor + ' ' + value.replace('#', '').split('').join(', ')
+ }
+ }
+
+ customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor);
+})(customElements);
diff --git a/media/system/webcomponents/js/joomla-field-simple-color.min.js b/media/system/webcomponents/js/joomla-field-simple-color.min.js
new file mode 100644
index 0000000000000..7939b43edbb3c
--- /dev/null
+++ b/media/system/webcomponents/js/joomla-field-simple-color.min.js
@@ -0,0 +1 @@
+(e=>{const t={TAB:9,ESC:27},s={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};e.define("joomla-field-simple-color",class extends HTMLElement{constructor(){super(),this.select="",this.options=[],this.icon="",this.panel="",this.buttons=[],this.focusableElements=null,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^="-"])']}connectedCallback(){if(this.select=this.querySelector("select"),!this.select)throw new Error("Simple color field requires a select element");this.options=[].slice.call(this.select.querySelectorAll("option")),this.select.classList.add("hidden"),this.options.forEach(e=>{let t=e.value,s="swatch";"none"===t&&(s+=" nocolor",t="transparent"),e.selected&&(s+=" active");const i=document.createElement("button");i.setAttribute("class",s),i.style.backgroundColor=t,i.setAttribute("type","button");const a="transparent"===t?this.textTransp:this.getColorName(t);i.innerHTML=`${a}`,this.buttons.push(i)});const e=document.createElement("button");e.setAttribute("class","btn-close"),e.setAttribute("type","button"),e.innerHTML=this.textClose,this.buttons.push(e);let t=this.select.value,s="";"none"===t&&(s+=" nocolor",t="transparent"),this.icon=document.createElement("button"),s&&this.icon.setAttribute("class",s);const i=`simple-color-${Math.random().toString(36).substr(2,10)}`;this.icon.setAttribute("type","button"),this.icon.setAttribute("tabindex","0"),this.icon.style.backgroundColor=t,this.icon.innerHTML=''+this.textSelect+"",this.icon.id=i,this.select.insertAdjacentElement("beforebegin",this.icon),this.icon.addEventListener("click",this.show.bind(this)),this.panel=document.createElement("div"),this.panel.classList.add("simplecolors-panel"),this.panel.setAttribute("aria-labelledby",i),this.buttons.forEach(e=>{e.classList.contains("btn-close")?e.addEventListener("click",this.hide.bind(this)):e.addEventListener("click",this.colorSelect.bind(this)),this.panel.insertAdjacentElement("beforeend",e)}),this.appendChild(this.panel),this.focusableElements=[].slice.call(this.panel.querySelectorAll(this.focusableSelectors.join())),this.keys=this.keys.bind(this),this.hide=this.hide.bind(this),this.mousedown=this.mousedown.bind(this)}disconnectedCallback(){}static get observedAttributes(){return["text-select","text-color","text-close","text-transparent"]}get textSelect(){return this.getAttribute("text-select")}get textColor(){return this.getAttribute("text-color")}get textClose(){return this.getAttribute("text-close")}get textTransp(){return this.getAttribute("text-transparent")}show(){document.addEventListener("mousedown",this.hide),this.addEventListener("keydown",this.keys),this.panel.addEventListener("mousedown",this.mousedown),this.panel.setAttribute("data-open","");const e=this.panel.querySelector("button");e&&e.focus()}hide(){document.removeEventListener("mousedown",this.hide,!1),this.removeEventListener("keydown",this.keys),this.panel.hasAttribute("data-open")&&this.panel.removeAttribute("data-open"),this.icon.focus()}colorSelect(e){let t="",s="",i="";e.target.classList.contains("nocolor")?(t="none",s="transparent",i="nocolor"):(t=e.target.style.backgroundColor,s=t),this.buttons.forEach(e=>{e.classList.contains("active")&&e.classList.remove("active")}),e.target.classList.add("active"),this.icon.classList.remove("nocolor"),this.icon.setAttribute("class",i),this.icon.style.backgroundColor=s,this.hide(),this.options.forEach(e=>{e.selected&&e.removeAttribute("selected"),e.value===s&&e.setAttribute("selected","")})}keys(e){if(e.keyCode===t.ESC&&this.hide(),e.keyCode===t.TAB){const t=this.focusableElements.indexOf(document.activeElement);!e.shiftKey||0!==t&&-1!==t||(this.focusableElements[this.focusableElements.length-1].focus(),e.preventDefault()),e.shiftKey||t!==this.focusableElements.length-1||(this.focusableElements[0].focus(),e.preventDefault())}}mousedown(e){e.stopPropagation(),e.preventDefault()}getColorName(e){let t=e;if(4===e.length){const s=e.split("");t=s[0]+s[1]+s[1]+s[2]+s[2]+s[3]+s[3]}for(const e in s)if(s.hasOwnProperty(e)&&t.toLowerCase()===s[e])return e;return this.textColor+" "+e.replace("#","").split("").join(", ")}})})(customElements);
\ No newline at end of file
diff --git a/package.json b/package.json
index 028432f1d9f27..d71abdbef3b66 100644
--- a/package.json
+++ b/package.json
@@ -82,7 +82,8 @@
"field-media",
"field-user",
"field-switcher",
- "field-send-test-mail",
+ "field-simple-color",
+ "field-send-test-mail"
"hidden-mail"
],
"webcomponents": {
@@ -94,6 +95,7 @@
"css": "media/system/webcomponents/css",
"js": "media/system/webcomponents/js"
},
+ "field-simple-color": {
"field-send-test-mail": {
"css": "media/system/webcomponents/css",
"js": "media/system/webcomponents/js"
diff --git a/templates/cassiopeia/templateDetails.xml b/templates/cassiopeia/templateDetails.xml
index 99769751eb452..b293d4b0ed951 100644
--- a/templates/cassiopeia/templateDetails.xml
+++ b/templates/cassiopeia/templateDetails.xml
@@ -79,6 +79,13 @@
+