diff --git a/Build/Gruntfile.js b/Build/Gruntfile.js index 65b99fc1a5c0ba58e2622c2e7bd2b5c088781a27..6e6fae1329bd60745e26ded8cd301c68e2296806 100644 --- a/Build/Gruntfile.js +++ b/Build/Gruntfile.js @@ -112,6 +112,9 @@ module.exports = function(grunt) { } }, watch: { + options: { + livereload: true + }, less: { files: '<%= paths.less %>**/*.less', tasks: 'css' @@ -169,6 +172,17 @@ module.exports = function(grunt) { runBower: false, srcPrefix: "bower_components/" }, + glob: { + files: { + // When using glob patterns, destinations are *always* folder names + // into which matching files will be copied + // Also note that subdirectories are **not** maintained + // if a destination is specified + // For example, one of the files copied here is + // 'lodash/dist/lodash.js' -> 'public/js/libs/lodash/lodash.js' + '<%= paths.sysext %>core/Resources/Public/Images/colorpicker': 'jquery-minicolors/*.png' + } + }, all: { options: { destPrefix: "<%= paths.core %>Public/JavaScript/Contrib" @@ -186,6 +200,7 @@ module.exports = function(grunt) { 'autosize.js': 'autosize/dist/autosize.min.js', 'taboverride.min.js': 'taboverride/build/output/taboverride.min.js', 'bootstrap-slider.min.js': 'seiyria-bootstrap-slider/dist/bootstrap-slider.min.js', + 'jquery.minicolors.js': 'jquery-minicolors/jquery.minicolors.min.js', /* disabled until autocomplete groupBy is fixed by the author see https://github.com/devbridge/jQuery-Autocomplete/pull/387 'jquery.autocomplete.js': 'devbridge-autocomplete/src/jquery.autocomplete.js', diff --git a/Build/Resources/Public/Less/Component/colorpicker.less b/Build/Resources/Public/Less/Component/colorpicker.less new file mode 100644 index 0000000000000000000000000000000000000000..75c5b026a6b4e49e54a1757464a1c9f9c30f49ab --- /dev/null +++ b/Build/Resources/Public/Less/Component/colorpicker.less @@ -0,0 +1,247 @@ +// +// Minicolors +// ============ +// Optimized version of http://labs.abeautifulsite.net/jquery-minicolors/ +// for TYPO3 CMS colorpicker used in the backend. +// + + +// +// Variables +// +@minicolors-swatch-height: 20px; +@minicolors-swatch-width: 20px; +@minicolors-swatch-border-radius: 1px; +@minicolors-swatch-border: @input-border; +@minicolors-panel-bg: #fff; +@minicolors-panel-border: @input-border; +@minicolors-panel-border-radius: @border-radius-base; + +// +// Component +// +.minicolors { + position: relative; +} + +.userTS .minicolors { + // fix for constantmanager + position: absolute; +} + +.minicolors-sprite { + background-image: url("@{path-sysext}/core/Resources/Public/Images/colorpicker/jquery.minicolors.png"); +} + +// +// Swatch +// +.minicolors-swatch { + position: absolute; + vertical-align: middle; + background-position: -80px 0; + cursor: text; + padding: 0; + margin: 0; + display: inline-block; + top: 50%; + left: @padding-base-horizontal; + z-index: 2; + transform: translate(0,-50%); + width: @minicolors-swatch-width; + height: @minicolors-swatch-height; + border-radius: @minicolors-swatch-border-radius; +} +.minicolors-swatch-color { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; +} + +// +// Input +// +.minicolors-input { + float: none; + padding-left: (@padding-base-horizontal * 2) + @minicolors-swatch-width; +} + +// +// Panel +// +.minicolors-panel { + margin-top: 1px; + overflow: hidden; + border-radius: @minicolors-panel-border-radius; + position: absolute; + width: 173px; + height: 152px; + background: @minicolors-panel-bg; + border: solid 1px @minicolors-panel-border; + box-shadow: 0 0 20px rgba(0, 0, 0, .2); + z-index: 99999; + box-sizing: content-box; + display: none; +} +.minicolors-panel.minicolors-with-swatches { + height: 182px; +} +.minicolors-panel.minicolors-visible { + display: block; +} + +// +// Position +// +.minicolors-position-top .minicolors-panel { + top: -154px; +} +.minicolors-position-right .minicolors-panel { + right: 0; +} +.minicolors-position-bottom .minicolors-panel { + top: auto; +} +.minicolors-position-left .minicolors-panel { + left: 0; +} +.minicolors-with-opacity .minicolors-panel { + width: 194px; +} + +// +// Grid +// +.minicolors .minicolors-grid { + position: absolute; + top: 1px; + left: 1px; + width: 150px; + height: 150px; + background-position: -120px 0; + cursor: crosshair; +} +.minicolors .minicolors-grid-inner { + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; +} + +// +// Slider +// +.minicolors-slider-saturation .minicolors-grid { + background-position: -420px 0; +} +.minicolors-slider-saturation .minicolors-grid-inner { + background-position: -270px 0; + background-image: inherit; +} +.minicolors-slider-brightness .minicolors-grid { + background-position: -570px 0; +} +.minicolors-slider-brightness .minicolors-grid-inner { + background-color: black; +} +.minicolors-slider-wheel .minicolors-grid { + background-position: -720px 0; +} +.minicolors-slider, +.minicolors-opacity-slider { + position: absolute; + top: 1px; + left: 152px; + width: 20px; + height: 150px; + background-color: white; + background-position: 0 0; + cursor: row-resize; +} +.minicolors-slider-saturation .minicolors-slider { + background-position: -60px 0; +} +.minicolors-slider-brightness .minicolors-slider { + background-position: -20px 0; +} +.minicolors-slider-wheel .minicolors-slider { + background-position: -20px 0; +} +.minicolors-opacity-slider { + left: 173px; + background-position: -40px 0; + display: none; +} +.minicolors-with-opacity .minicolors-opacity-slider { + display: block; +} + +// +// Picker +// +.minicolors-grid .minicolors-picker { + position: absolute; + top: 70px; + left: 70px; + width: 12px; + height: 12px; + border: solid 1px black; + border-radius: 10px; + margin-top: -6px; + margin-left: -6px; + background: none; +} +.minicolors-grid .minicolors-picker > div { + position: absolute; + top: 0; + left: 0; + width: 8px; + height: 8px; + border-radius: 8px; + border: solid 2px white; + box-sizing: content-box; +} +.minicolors-picker { + position: absolute; + top: 0; + left: 0; + width: 18px; + height: 2px; + background: white; + border: solid 1px black; + margin-top: -2px; + box-sizing: content-box; +} + +// +// Swatches +// +.minicolors-swatches,.minicolors-swatches li { + margin: 0; + padding: 0; + list-style: none; + overflow: hidden; + position: absolute; + top: 157px; + left: 5px; +} +.minicolors-swatches .minicolors-swatch { + position: relative; + float: left; + cursor: pointer; + margin:0 4px 0 0; + top: 0; + left: 0; + width: 20px; + height: 20px; +} +.minicolors-with-opacity .minicolors-swatches .minicolors-swatch { + margin-right:7px; +} +.minicolors-swatch.selected { + border-color:#000; +} diff --git a/Build/Resources/Public/Less/backend.less b/Build/Resources/Public/Less/backend.less index 72c6cd804a6bcf1e94c64419d51b338157dcb8b8..bb6533b1e0a5bdc55eb99742784dab2895d2f670 100644 --- a/Build/Resources/Public/Less/backend.less +++ b/Build/Resources/Public/Less/backend.less @@ -10,6 +10,11 @@ // @import "_minimal.less"; +// +// Components +// +@import "Component/colorpicker.less"; + // // Components from bootstrap plugins // diff --git a/Build/bower.json b/Build/bower.json index 2cb60e8cc5beb7996261eab7c2cfb6cae576ec70..8f4d2e646ddc563a268e375c1b56698f7a581a59 100644 --- a/Build/bower.json +++ b/Build/bower.json @@ -43,6 +43,7 @@ "devbridge-autocomplete": "1.2.24", "region-flags": "*", "wmdbsystems-typo3-icons": "0.0.10", - "matchHeight": "matchheight#^0.7.0" + "matchHeight": "matchheight#^0.7.0", + "jquery-minicolors": "^2.2.4" } } diff --git a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php index 01177f7615a676dc35aac825043552170a82cf38..940c3f453c2a82202b1a95b2dd062ade0490857d 100644 --- a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php @@ -65,6 +65,11 @@ abstract class AbstractFormElement extends AbstractNode */ protected $clipboard = null; + /** + * @var NodeFactory + */ + protected $nodeFactory; + /** * Container objects give $nodeFactory down to other containers. * @@ -306,46 +311,6 @@ abstract class AbstractFormElement extends AbstractNode '</a>'; break; - case 'colorbox': - $params = array(); - $params['params'] = $wizardConfiguration['params']; - $params['exampleImg'] = $wizardConfiguration['exampleImg']; - $params['table'] = $table; - $params['uid'] = $row['uid']; - $params['pid'] = $row['pid']; - $params['field'] = $field; - $params['flexFormPath'] = $flexFormPath; - $params['md5ID'] = $md5ID; - $params['returnUrl'] = $this->data['returnUrl']; - - $params['formName'] = 'editform'; - $params['itemName'] = $itemName; - $params['hmac'] = GeneralUtility::hmac($params['formName'] . $params['itemName'], 'wizard_js'); - $params['fieldChangeFunc'] = $fieldChangeFunc; - $params['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($fieldChangeFunc)); - - // Resolving script filename and setting URL. - $urlParameters = array(); - if (isset($wizardConfiguration['module']['urlParameters']) && is_array($wizardConfiguration['module']['urlParameters'])) { - $urlParameters = $wizardConfiguration['module']['urlParameters']; - } - $wScript = BackendUtility::getModuleUrl($wizardConfiguration['module']['name'], $urlParameters, ''); - $url = $wScript . (strstr($wScript, '?') ? '' : '?') . GeneralUtility::implodeArrayForUrl('', array('P' => $params)); - - $aOnClick = - 'this.blur();' . - 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url) . '+\'&P[currentValue]=\'+TBE_EDITOR.rawurlencode(' . - 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value,300' . - ')' . - '+\'&P[currentSelectedValues]=\'+TBE_EDITOR.curSelected(' . GeneralUtility::quoteJSvalue($itemName) . '),' . - GeneralUtility::quoteJSvalue('popUp' . $md5ID) . ',' . - GeneralUtility::quoteJSvalue($wizardConfiguration['JSopenParams']) . - ');' . - 'vHWin.focus();' . - 'return false;'; - - $otherWizards[] = '<a id="' . $md5ID . '" class="btn btn-default" href="#" onclick="' . htmlspecialchars($aOnClick) . '"><span class="t3-icon fa fa-eyedropper"></span></a>'; - break; case 'slider': $params = array(); $params['fieldConfig'] = $PA['fieldConf']['config']; diff --git a/typo3/sysext/backend/Classes/Form/Element/InputColorPickerElement.php b/typo3/sysext/backend/Classes/Form/Element/InputColorPickerElement.php new file mode 100644 index 0000000000000000000000000000000000000000..9b525b268f04a3590e396133e2a071e73b9e6241 --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Element/InputColorPickerElement.php @@ -0,0 +1,162 @@ +<?php +namespace TYPO3\CMS\Backend\Form\Element; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Form\Element\AbstractFormElement; +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Imaging\Icon; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Utility\StringUtility; + +/** + * Class InputColorPickerElement + */ +class InputColorPickerElement extends AbstractFormElement +{ + + /** + * This will render a single-line input form field, possibly with various control/validation features + * + * @return array As defined in initializeResultArray() of AbstractNode + */ + public function render() + { + $table = $this->data['tableName']; + $fieldName = $this->data['fieldName']; + $row = $this->data['databaseRow']; + $parameterArray = $this->data['parameterArray']; + $resultArray = $this->initializeResultArray(); + + $config = $parameterArray['fieldConf']['config']; + $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']); + $size = MathUtility::forceIntegerInRange($config['size'] ?: $this->defaultInputWidth, $this->minimumInputWidth, $this->maxInputWidth); + $evalList = GeneralUtility::trimExplode(',', $config['eval'], true); + $classes = array(); + $attributes = array(); + + // readonly + if ($config['readOnly']) { + $itemFormElValue = $parameterArray['itemFormElValue']; + $options = $this->data; + $options['parameterArray'] = array( + 'fieldConf' => array( + 'config' => $config, + ), + 'itemFormElValue' => $itemFormElValue, + ); + $options['renderType'] = 'none'; + return $this->nodeFactory->create($options)->render(); + } + + // @todo: The whole eval handling is a mess and needs refactoring + foreach ($evalList as $func) { + switch ($func) { + case 'required': + $attributes['data-formengine-validation-rules'] = $this->getValidationDataAsJsonString(array('required' => true)); + break; + default: + // @todo: This is ugly: The code should find out on it's own whether a eval definition is a + // @todo: keyword like "date", or a class reference. The global registration could be dropped then + // Pair hook to the one in \TYPO3\CMS\Core\DataHandling\DataHandler::checkValue_input_Eval() + if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func])) { + if (class_exists($func)) { + $evalObj = GeneralUtility::makeInstance($func); + if (method_exists($evalObj, 'deevaluateFieldValue')) { + $_params = array( + 'value' => $parameterArray['itemFormElValue'] + ); + $parameterArray['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params); + } + } + } + } + } + + $paramsList = array( + 'field' => $parameterArray['itemFormElName'], + 'evalList' => implode(',', $evalList), + 'is_in' => trim($config['is_in']), + ); + + // set classes + $classes[] = 'form-control'; + $classes[] = 'hasDefaultValue'; + $classes[] = 't3js-clearable'; + $classes[] = 'formengine-colorpickerelement'; + $attributes['class'] = implode(' ', $classes); + + // calculate attributes + $attributes['data-formengine-validation-rules'] = $this->getValidationDataAsJsonString($config); + $attributes['data-formengine-input-params'] = json_encode($paramsList); + $attributes['data-formengine-input-name'] = $parameterArray['itemFormElName']; + $attributes['id'] = StringUtility::getUniqueId('formengine-input-'); + $attributes['value'] = ''; + if (isset($config['max']) && (int)$config['max'] > 0) { + $attributes['maxlength'] = (int)$config['max']; + } + + // This is the EDITABLE form field. + if (!empty($config['placeholder'])) { + $attributes['placeholder'] = trim($config['placeholder']); + } + + if (isset($config['autocomplete'])) { + $attributes['autocomplete'] = empty($config['autocomplete']) ? 'off' : 'on'; + } + + // Build the attribute string + $attributeString = ''; + foreach ($attributes as $attributeName => $attributeValue) { + $attributeString .= ' ' . $attributeName . '="' . htmlspecialchars($attributeValue) . '"'; + } + + $html = '<input type="text" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" ' . $attributeString . ' />'; + + // This is the ACTUAL form field - values from the EDITABLE field must be transferred to this field which is the one that is written to the database. + $html .= '<input type="hidden" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />'; + + // Going through all custom evaluations configured for this field + // @todo: Similar to above code! + foreach ($evalList as $evalData) { + if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$evalData])) { + if (class_exists($evalData)) { + $evalObj = GeneralUtility::makeInstance($evalData); + if (method_exists($evalObj, 'returnFieldJS')) { + $resultArray['extJSCODE'] .= LF . 'TBE_EDITOR.customEvalFunctions[' . GeneralUtility::quoteJSvalue($evalData) . '] = function(value) {' . $evalObj->returnFieldJS() . '}'; + } + } + } + } + + // Wrap a wizard around the item? + $html = $this->renderWizards( + array($html), + $config['wizards'], + $table, + $row, + $fieldName, + $parameterArray, + $parameterArray['itemFormElName'], + $specConf + ); + + // Add a wrapper to remain maximum width + $width = (int)$this->formMaxWidth($size); + $html = '<div class="form-control-wrap"' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>' . $html . '</div>'; + $resultArray['html'] = $html; + return $resultArray; + } +} diff --git a/typo3/sysext/backend/Classes/Form/NodeFactory.php b/typo3/sysext/backend/Classes/Form/NodeFactory.php index d6b42737aadb8bdb5898031580c47976d7538d3b..04ea9b4bc05612cf778d4c1b6f07008bedb2fa1c 100644 --- a/typo3/sysext/backend/Classes/Form/NodeFactory.php +++ b/typo3/sysext/backend/Classes/Form/NodeFactory.php @@ -58,6 +58,7 @@ class NodeFactory 'selectTree' => Element\SelectTreeElement::class, 'selectSingle' => Element\SelectSingleElement::class, 'selectSingleBox' => Element\SelectSingleBoxElement::class, + 'colorpicker' => Element\InputColorPickerElement::class, // t3editor is defined with a fallback so extensions can use it even if ext:t3editor is not loaded 't3editor' => Element\TextElement::class, 'text' => Element\TextElement::class, diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js index 219c19e318b7f30c90f7d21dcb753a55a3ac735b..3c09f7d53edab824916b35dfde232f95191bff86 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js @@ -893,6 +893,17 @@ define(['jquery', require(['TYPO3/CMS/Backend/DateTimePicker'], function(DateTimePicker) { DateTimePicker.initialize(); }); + + if ($('.formengine-colorpickerelement').length) { + require(['TYPO3/CMS/Core/Contrib/jquery.minicolors'], function(minicolor) { + $('.formengine-colorpickerelement').minicolors({ + theme: 'bootstrap', + format: 'hex', + position: 'bottom left' + }); + }); + } + FormEngine.convertTextareasResizable(); FormEngine.convertTextareasEnableTab(); }; diff --git a/typo3/sysext/core/Classes/Migrations/TcaMigration.php b/typo3/sysext/core/Classes/Migrations/TcaMigration.php index d418590e7067f6449b10b039a4c29702aef73f01..87528e1ef93f64d501d39d09ce6255cdb044821b 100644 --- a/typo3/sysext/core/Classes/Migrations/TcaMigration.php +++ b/typo3/sysext/core/Classes/Migrations/TcaMigration.php @@ -53,6 +53,7 @@ class TcaMigration $tca = $this->migrateSelectFieldIconTable($tca); $tca = $this->migrateElementBrowserWizardToLinkHandler($tca); $tca = $this->migrateDefaultExtrasRteTransFormOptions($tca); + $tca = $this->migrateColorPickerWizardToRenderType($tca); // @todo: if showitem/defaultExtras wizards[xy] is migrated to columnsOverrides here, enableByTypeConfig could be dropped return $tca; } @@ -631,7 +632,7 @@ class TcaMigration foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { if ( isset($fieldConfig['config']['wizards']['link']['module']['name']) && $fieldConfig['config']['wizards']['link']['module']['name'] === 'wizard_element_browser' - && isset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']) && $fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode'] === 'wizard' + && isset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']) && $fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode'] === 'wizard' ) { $fieldConfig['config']['wizards']['link']['module']['name'] = 'wizard_link'; unset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']); @@ -710,4 +711,38 @@ class TcaMigration return $tca; } + + /** + * Migrates fields having a colorpicker wizard to a color field + * + * @param array $tca Incoming TCA + * @return array Migrated TCA + */ + protected function migrateColorPickerWizardToRenderType(array $tca) + { + foreach ($tca as $table => &$tableDefinition) { + if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) { + continue; + } + foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { + if (isset($fieldConfig['config'])) { + if (isset($fieldConfig['config']['wizards'])) { + foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizard) { + if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) { + unset($fieldConfig['config']['wizards'][$wizardName]); + $fieldConfig['config']['renderType'] = 'colorpicker'; + + $this->messages[] = 'The color-picker wizard using \'colorbox\' is deprecated' + . ' in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']' + . '[\'wizards\'][\'' . $wizardName . '\'] and is changed to ' . $table + . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] = \'colorpicker\''; + } + } + } + } + } + } + + return $tca; + } } diff --git a/typo3/sysext/core/Classes/TypoScript/ExtendedTemplateService.php b/typo3/sysext/core/Classes/TypoScript/ExtendedTemplateService.php index f1c904e4be26e8c536c59539b77bb2f15dfa0e12..6a06b38109641bb9238a435d2684770ea88d067c 100644 --- a/typo3/sysext/core/Classes/TypoScript/ExtendedTemplateService.php +++ b/typo3/sysext/core/Classes/TypoScript/ExtendedTemplateService.php @@ -40,11 +40,6 @@ class ExtendedTemplateService extends TemplateService */ public $edit_divider = '###MOD_TS:EDITABLE_CONSTANTS###'; - /** - * @var string - */ - public $HTMLcolorList = 'aqua,beige,black,blue,brown,fuchsia,gold,gray,green,lime,maroon,navy,olive,orange,purple,red,silver,tan,teal,turquoise,yellow,white'; - /** * @var array */ @@ -266,6 +261,21 @@ class ExtendedTemplateService extends TemplateService */ public $lastComment = ''; + /** + * @var array + */ + protected $inlineJavaScript = []; + + /** + * Gets the inline JavaScript. + * + * @return array + */ + public function getInlineJavaScript() + { + return $this->inlineJavaScript; + } + /** * Substitute constant * @@ -1199,17 +1209,20 @@ class ExtendedTemplateService extends TemplateService . ' name="' . $fN . '" value="' . $fV . '"' . ' onChange="uFormUrl(' . $aname . ')" />'; break; case 'color': - $colorNames = explode(',', ',' . $this->HTMLcolorList); - $p_field = ''; - foreach ($colorNames as $val) { - $sel = ''; - if ($val == strtolower($params['value'])) { - $sel = ' selected'; - } - $p_field .= '<option value="' . htmlspecialchars($val) . '"' . $sel . '>' . $val . '</option>'; + $p_field = ' + <input class="form-control formengine-colorpickerelement" type="text" id="input-' . $idName . '" rel="' . $idName . + '" name="' . $fN . '" value="' . $fV . '"' . $this->getDocumentTemplate()->formWidth(7) . ' onChange="uFormUrl(' . $aname . ')" />'; + + if (empty($this->inlineJavaScript[$typeDat['type']])) { + $this->inlineJavaScript[$typeDat['type']] = ' + require([\'TYPO3/CMS/Core/Contrib/jquery.minicolors\'], function() { + TYPO3.jQuery(\'.formengine-colorpickerelement\').minicolors({ + theme: \'bootstrap\', + format: \'hex\', + align: \'bottom left\' + }); + });'; } - $p_field = '<select class="form-control t3js-color-select" id="select-' . $idName . '" rel="' . $idName . '" name="C' . $fN . '" onChange="uFormUrl(' . $aname . ');"' . $this->getDocumentTemplate()->formWidth(7) . '>' . $p_field . '</select>'; - $p_field .= '<input class="form-control t3js-color-input" type="text" id="input-' . $idName . '" rel="' . $idName . '" name="' . $fN . '" value="' . $fV . '"' . $this->getDocumentTemplate()->formWidth(7) . ' onChange="uFormUrl(' . $aname . ')" />'; break; case 'wrap': $wArr = explode('|', $fV); @@ -1297,12 +1310,6 @@ class ExtendedTemplateService extends TemplateService $defaultTyposcriptID = 'defaultTS-' . $idName; $checkboxName = 'check[' . $params['name'] . ']'; $checkboxID = 'check-' . $idName; - // Handle type=color specially - if ($typeDat['type'] === 'color' && substr($params['value'], 0, 2) != '{$') { - $appendedGroupAddon = '<span class="input-group-addon colorbox" id="colorbox-' . $idName . '" style="background-color:' . $params['value'] . ';"></span>'; - } else { - $appendedGroupAddon = ''; - } $userTyposcriptStyle = ''; $deleteIconHTML = ''; $constantCheckbox = ''; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-73728-WizardTypeColorboxIsDeprecated.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-73728-WizardTypeColorboxIsDeprecated.rst new file mode 100644 index 0000000000000000000000000000000000000000..18da33768f9713da344cdce54872ad3be96743fe --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-73728-WizardTypeColorboxIsDeprecated.rst @@ -0,0 +1,44 @@ +======================================================== +Deprecation: #73728 - Wizard type colorbox is deprecated +======================================================== + +Description +=========== + +The color-picker is now available as dedicated render-type which will integrate +an inline color-picker widget based on bootstrap. Thus, the old wizard type +``colorbox`` is deprecated. + + +Impact +====== + +Using the TCA wizard type ``colorbox`` will trigger an internal deprecation +message. The possibility to pick the color from a custom image has been removed +without any substitution as well as the possibility to use color names like +"red" or "white". + + +Affected Installations +====================== + +All TCA fields that are using the wizard type ``colorbox``, like e.g. + + +.. code-block:: php + + $GLOBALS['TCA']['tableName']['fieldName']['config']['wizards']['colorbox'] = [ + 'type' => 'colorbox', + 'script' => 'wizard_colorpicker.php', + ... + ]; + + +Migration +========= + +Use the new render-type ``colorpicker`` in the TCA field configuration, like e.g. + +.. code-block:: php + + $GLOBALS['TCA']['tableName']['fieldName']['config']['renderType'] = 'colorpicker'; diff --git a/typo3/sysext/core/Resources/Public/Images/colorpicker/jquery.minicolors.png b/typo3/sysext/core/Resources/Public/Images/colorpicker/jquery.minicolors.png new file mode 100644 index 0000000000000000000000000000000000000000..bccc2012af78a0358e893f004e0207cac8f9e642 Binary files /dev/null and b/typo3/sysext/core/Resources/Public/Images/colorpicker/jquery.minicolors.png differ diff --git a/typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery.minicolors.js b/typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery.minicolors.js new file mode 100644 index 0000000000000000000000000000000000000000..346f7f977329ffe025d85cda41ff854477301b8e --- /dev/null +++ b/typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery.minicolors.js @@ -0,0 +1,11 @@ +/* + * jQuery MiniColors: A tiny color picker built on jQuery + * + * Copyright: Cory LaViska for A Beautiful Site, LLC: http://www.abeautifulsite.net/ + * + * Contribute: https://github.com/claviska/jquery-minicolors + * + * @license: http://opensource.org/licenses/MIT + * + */ +!function(i){"function"==typeof define&&define.amd?define(["jquery"],i):"object"==typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function($){"use strict";function i(i,t){var o=$('<div class="minicolors" />'),s=$.minicolors.defaults,a,n,r,c,l;if(!i.data("minicolors-initialized")){if(t=$.extend(!0,{},s,t),o.addClass("minicolors-theme-"+t.theme).toggleClass("minicolors-with-opacity",t.opacity).toggleClass("minicolors-no-data-uris",t.dataUris!==!0),void 0!==t.position&&$.each(t.position.split(" "),function(){o.addClass("minicolors-position-"+this)}),a="rgb"===t.format?t.opacity?"25":"20":t.keywords?"11":"7",i.addClass("minicolors-input").data("minicolors-initialized",!1).data("minicolors-settings",t).prop("size",a).wrap(o).after('<div class="minicolors-panel minicolors-slider-'+t.control+'"><div class="minicolors-slider minicolors-sprite"><div class="minicolors-picker"></div></div><div class="minicolors-opacity-slider minicolors-sprite"><div class="minicolors-picker"></div></div><div class="minicolors-grid minicolors-sprite"><div class="minicolors-grid-inner"></div><div class="minicolors-picker"><div></div></div></div></div>'),t.inline||(i.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>'),i.next(".minicolors-input-swatch").on("click",function(t){t.preventDefault(),i.focus()})),c=i.parent().find(".minicolors-panel"),c.on("selectstart",function(){return!1}).end(),t.swatches&&0!==t.swatches.length)for(t.swatches.length>7&&(t.swatches.length=7),c.addClass("minicolors-with-swatches"),n=$('<ul class="minicolors-swatches"></ul>').appendTo(c),l=0;l<t.swatches.length;++l)r=t.swatches[l],r=f(r)?u(r,!0):x(p(r,!0)),$('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>').appendTo(n).data("swatch-color",t.swatches[l]).find(".minicolors-swatch-color").css({backgroundColor:y(r),opacity:r.a}),t.swatches[l]=r;t.inline&&i.parent().addClass("minicolors-inline"),e(i,!1),i.data("minicolors-initialized",!0)}}function t(i){var t=i.parent();i.removeData("minicolors-initialized").removeData("minicolors-settings").removeProp("size").removeClass("minicolors-input"),t.before(i).remove()}function o(i){var t=i.parent(),o=t.find(".minicolors-panel"),a=i.data("minicolors-settings");!i.data("minicolors-initialized")||i.prop("disabled")||t.hasClass("minicolors-inline")||t.hasClass("minicolors-focus")||(s(),t.addClass("minicolors-focus"),o.stop(!0,!0).fadeIn(a.showSpeed,function(){a.show&&a.show.call(i.get(0))}))}function s(){$(".minicolors-focus").each(function(){var i=$(this),t=i.find(".minicolors-input"),o=i.find(".minicolors-panel"),s=t.data("minicolors-settings");o.fadeOut(s.hideSpeed,function(){s.hide&&s.hide.call(t.get(0)),i.removeClass("minicolors-focus")})})}function a(i,t,o){var s=i.parents(".minicolors").find(".minicolors-input"),a=s.data("minicolors-settings"),r=i.find("[class$=-picker]"),e=i.offset().left,c=i.offset().top,l=Math.round(t.pageX-e),h=Math.round(t.pageY-c),d=o?a.animationSpeed:0,p,u,g,m;t.originalEvent.changedTouches&&(l=t.originalEvent.changedTouches[0].pageX-e,h=t.originalEvent.changedTouches[0].pageY-c),0>l&&(l=0),0>h&&(h=0),l>i.width()&&(l=i.width()),h>i.height()&&(h=i.height()),i.parent().is(".minicolors-slider-wheel")&&r.parent().is(".minicolors-grid")&&(p=75-l,u=75-h,g=Math.sqrt(p*p+u*u),m=Math.atan2(u,p),0>m&&(m+=2*Math.PI),g>75&&(g=75,l=75-75*Math.cos(m),h=75-75*Math.sin(m)),l=Math.round(l),h=Math.round(h)),i.is(".minicolors-grid")?r.stop(!0).animate({top:h+"px",left:l+"px"},d,a.animationEasing,function(){n(s,i)}):r.stop(!0).animate({top:h+"px"},d,a.animationEasing,function(){n(s,i)})}function n(i,t){function o(i,t){var o,s;return i.length&&t?(o=i.offset().left,s=i.offset().top,{x:o-t.offset().left+i.outerWidth()/2,y:s-t.offset().top+i.outerHeight()/2}):null}var s,a,n,e,l,h,d,p=i.val(),u=i.attr("data-opacity"),g=i.parent(),f=i.data("minicolors-settings"),v=g.find(".minicolors-input-swatch"),b=g.find(".minicolors-grid"),w=g.find(".minicolors-slider"),y=g.find(".minicolors-opacity-slider"),k=b.find("[class$=-picker]"),M=w.find("[class$=-picker]"),x=y.find("[class$=-picker]"),I=o(k,b),S=o(M,w),z=o(x,y);if(t.is(".minicolors-grid, .minicolors-slider, .minicolors-opacity-slider")){switch(f.control){case"wheel":e=b.width()/2-I.x,l=b.height()/2-I.y,h=Math.sqrt(e*e+l*l),d=Math.atan2(l,e),0>d&&(d+=2*Math.PI),h>75&&(h=75,I.x=69-75*Math.cos(d),I.y=69-75*Math.sin(d)),a=m(h/.75,0,100),s=m(180*d/Math.PI,0,360),n=m(100-Math.floor(S.y*(100/w.height())),0,100),p=C({h:s,s:a,b:n}),w.css("backgroundColor",C({h:s,s:a,b:100}));break;case"saturation":s=m(parseInt(I.x*(360/b.width()),10),0,360),a=m(100-Math.floor(S.y*(100/w.height())),0,100),n=m(100-Math.floor(I.y*(100/b.height())),0,100),p=C({h:s,s:a,b:n}),w.css("backgroundColor",C({h:s,s:100,b:n})),g.find(".minicolors-grid-inner").css("opacity",a/100);break;case"brightness":s=m(parseInt(I.x*(360/b.width()),10),0,360),a=m(100-Math.floor(I.y*(100/b.height())),0,100),n=m(100-Math.floor(S.y*(100/w.height())),0,100),p=C({h:s,s:a,b:n}),w.css("backgroundColor",C({h:s,s:a,b:100})),g.find(".minicolors-grid-inner").css("opacity",1-n/100);break;default:s=m(360-parseInt(S.y*(360/w.height()),10),0,360),a=m(Math.floor(I.x*(100/b.width())),0,100),n=m(100-Math.floor(I.y*(100/b.height())),0,100),p=C({h:s,s:a,b:n}),b.css("backgroundColor",C({h:s,s:100,b:100}))}u=f.opacity?parseFloat(1-z.y/y.height()).toFixed(2):1,r(i,p,u)}else v.find("span").css({backgroundColor:p,opacity:u}),c(i,p,u)}function r(i,t,o){var s,a=i.parent(),n=i.data("minicolors-settings"),r=a.find(".minicolors-input-swatch");n.opacity&&i.attr("data-opacity",o),"rgb"===n.format?(s=f(t)?u(t,!0):x(p(t,!0)),o=""===i.attr("data-opacity")?1:m(parseFloat(i.attr("data-opacity")).toFixed(2),0,1),(isNaN(o)||!n.opacity)&&(o=1),t=i.minicolors("rgbObject").a<=1&&s&&n.opacity?"rgba("+s.r+", "+s.g+", "+s.b+", "+parseFloat(o)+")":"rgb("+s.r+", "+s.g+", "+s.b+")"):(f(t)&&(t=w(t)),t=d(t,n.letterCase)),i.val(t),r.find("span").css({backgroundColor:t,opacity:o}),c(i,t,o)}function e(i,t){var o,s,a,n,r,e,l,h,b,y,M=i.parent(),x=i.data("minicolors-settings"),I=M.find(".minicolors-input-swatch"),S=M.find(".minicolors-grid"),z=M.find(".minicolors-slider"),F=M.find(".minicolors-opacity-slider"),D=S.find("[class$=-picker]"),T=z.find("[class$=-picker]"),j=F.find("[class$=-picker]");switch(f(i.val())?(o=w(i.val()),r=m(parseFloat(v(i.val())).toFixed(2),0,1),r&&i.attr("data-opacity",r)):o=d(p(i.val(),!0),x.letterCase),o||(o=d(g(x.defaultValue,!0),x.letterCase)),s=k(o),n=x.keywords?$.map(x.keywords.split(","),function(i){return $.trim(i.toLowerCase())}):[],e=""!==i.val()&&$.inArray(i.val().toLowerCase(),n)>-1?d(i.val()):f(i.val())?u(i.val()):o,t||i.val(e),x.opacity&&(a=""===i.attr("data-opacity")?1:m(parseFloat(i.attr("data-opacity")).toFixed(2),0,1),isNaN(a)&&(a=1),i.attr("data-opacity",a),I.find("span").css("opacity",a),h=m(F.height()-F.height()*a,0,F.height()),j.css("top",h+"px")),"transparent"===i.val().toLowerCase()&&I.find("span").css("opacity",0),I.find("span").css("backgroundColor",o),x.control){case"wheel":b=m(Math.ceil(.75*s.s),0,S.height()/2),y=s.h*Math.PI/180,l=m(75-Math.cos(y)*b,0,S.width()),h=m(75-Math.sin(y)*b,0,S.height()),D.css({top:h+"px",left:l+"px"}),h=150-s.b/(100/S.height()),""===o&&(h=0),T.css("top",h+"px"),z.css("backgroundColor",C({h:s.h,s:s.s,b:100}));break;case"saturation":l=m(5*s.h/12,0,150),h=m(S.height()-Math.ceil(s.b/(100/S.height())),0,S.height()),D.css({top:h+"px",left:l+"px"}),h=m(z.height()-s.s*(z.height()/100),0,z.height()),T.css("top",h+"px"),z.css("backgroundColor",C({h:s.h,s:100,b:s.b})),M.find(".minicolors-grid-inner").css("opacity",s.s/100);break;case"brightness":l=m(5*s.h/12,0,150),h=m(S.height()-Math.ceil(s.s/(100/S.height())),0,S.height()),D.css({top:h+"px",left:l+"px"}),h=m(z.height()-s.b*(z.height()/100),0,z.height()),T.css("top",h+"px"),z.css("backgroundColor",C({h:s.h,s:s.s,b:100})),M.find(".minicolors-grid-inner").css("opacity",1-s.b/100);break;default:l=m(Math.ceil(s.s/(100/S.width())),0,S.width()),h=m(S.height()-Math.ceil(s.b/(100/S.height())),0,S.height()),D.css({top:h+"px",left:l+"px"}),h=m(z.height()-s.h/(360/z.height()),0,z.height()),T.css("top",h+"px"),S.css("backgroundColor",C({h:s.h,s:100,b:100}))}i.data("minicolors-initialized")&&c(i,e,a)}function c(i,t,o){var s=i.data("minicolors-settings"),a=i.data("minicolors-lastChange"),n,r,e;if(!a||a.value!==t||a.opacity!==o){if(i.data("minicolors-lastChange",{value:t,opacity:o}),s.swatches&&0!==s.swatches.length){for(n=f(t)?u(t,!0):x(t),r=-1,e=0;e<s.swatches.length;++e)if(n.r===s.swatches[e].r&&n.g===s.swatches[e].g&&n.b===s.swatches[e].b&&n.a===s.swatches[e].a){r=e;break}i.parent().find(".minicolors-swatches .minicolors-swatch").removeClass("selected"),-1!==e&&i.parent().find(".minicolors-swatches .minicolors-swatch").eq(e).addClass("selected")}s.change&&(s.changeDelay?(clearTimeout(i.data("minicolors-changeTimeout")),i.data("minicolors-changeTimeout",setTimeout(function(){s.change.call(i.get(0),t,o)},s.changeDelay))):s.change.call(i.get(0),t,o)),i.trigger("change").trigger("input")}}function l(i){var t=p($(i).val(),!0),o=x(t),s=$(i).attr("data-opacity");return o?(void 0!==s&&$.extend(o,{a:parseFloat(s)}),o):null}function h(i,t){var o=p($(i).val(),!0),s=x(o),a=$(i).attr("data-opacity");return s?(void 0===a&&(a=1),t?"rgba("+s.r+", "+s.g+", "+s.b+", "+parseFloat(a)+")":"rgb("+s.r+", "+s.g+", "+s.b+")"):null}function d(i,t){return"uppercase"===t?i.toUpperCase():i.toLowerCase()}function p(i,t){return i=i.replace(/^#/g,""),i.match(/^[A-F0-9]{3,6}/gi)?3!==i.length&&6!==i.length?"":(3===i.length&&t&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),"#"+i):""}function u(i,t){var o=i.replace(/[^\d,.]/g,""),s=o.split(",");return s[0]=m(parseInt(s[0],10),0,255),s[1]=m(parseInt(s[1],10),0,255),s[2]=m(parseInt(s[2],10),0,255),s[3]&&(s[3]=m(parseFloat(s[3],10),0,1)),t?{r:s[0],g:s[1],b:s[2],a:s[3]?s[3]:null}:"undefined"!=typeof s[3]&&s[3]<=1?"rgba("+s[0]+", "+s[1]+", "+s[2]+", "+s[3]+")":"rgb("+s[0]+", "+s[1]+", "+s[2]+")"}function g(i,t){return f(i)?u(i):p(i,t)}function m(i,t,o){return t>i&&(i=t),i>o&&(i=o),i}function f(i){var t=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);return t&&4===t.length?!0:!1}function v(i){return i=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i),i&&6===i.length?i[4]:"1"}function b(i){var t={},o=Math.round(i.h),s=Math.round(255*i.s/100),a=Math.round(255*i.b/100);if(0===s)t.r=t.g=t.b=a;else{var n=a,r=(255-s)*a/255,e=(n-r)*(o%60)/60;360===o&&(o=0),60>o?(t.r=n,t.b=r,t.g=r+e):120>o?(t.g=n,t.b=r,t.r=n-e):180>o?(t.g=n,t.r=r,t.b=r+e):240>o?(t.b=n,t.r=r,t.g=n-e):300>o?(t.b=n,t.g=r,t.r=r+e):360>o?(t.r=n,t.g=r,t.b=n-e):(t.r=0,t.g=0,t.b=0)}return{r:Math.round(t.r),g:Math.round(t.g),b:Math.round(t.b)}}function w(i){return i=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i),i&&4===i.length?"#"+("0"+parseInt(i[1],10).toString(16)).slice(-2)+("0"+parseInt(i[2],10).toString(16)).slice(-2)+("0"+parseInt(i[3],10).toString(16)).slice(-2):""}function y(i){var t=[i.r.toString(16),i.g.toString(16),i.b.toString(16)];return $.each(t,function(i,o){1===o.length&&(t[i]="0"+o)}),"#"+t.join("")}function C(i){return y(b(i))}function k(i){var t=M(x(i));return 0===t.s&&(t.h=360),t}function M(i){var t={h:0,s:0,b:0},o=Math.min(i.r,i.g,i.b),s=Math.max(i.r,i.g,i.b),a=s-o;return t.b=s,t.s=0!==s?255*a/s:0,0!==t.s?i.r===s?t.h=(i.g-i.b)/a:i.g===s?t.h=2+(i.b-i.r)/a:t.h=4+(i.r-i.g)/a:t.h=-1,t.h*=60,t.h<0&&(t.h+=360),t.s*=100/255,t.b*=100/255,t}function x(i){return i=parseInt(i.indexOf("#")>-1?i.substring(1):i,16),{r:i>>16,g:(65280&i)>>8,b:255&i}}$.minicolors={defaults:{animationSpeed:50,animationEasing:"swing",change:null,changeDelay:0,control:"hue",dataUris:!0,defaultValue:"",format:"hex",hide:null,hideSpeed:100,inline:!1,keywords:"",letterCase:"lowercase",opacity:!1,position:"bottom left",show:null,showSpeed:100,theme:"default",swatches:[]}},$.extend($.fn,{minicolors:function(a,n){switch(a){case"destroy":return $(this).each(function(){t($(this))}),$(this);case"hide":return s(),$(this);case"opacity":return void 0===n?$(this).attr("data-opacity"):($(this).each(function(){e($(this).attr("data-opacity",n))}),$(this));case"rgbObject":return l($(this),"rgbaObject"===a);case"rgbString":case"rgbaString":return h($(this),"rgbaString"===a);case"settings":return void 0===n?$(this).data("minicolors-settings"):($(this).each(function(){var i=$(this).data("minicolors-settings")||{};t($(this)),$(this).minicolors($.extend(!0,i,n))}),$(this));case"show":return o($(this).eq(0)),$(this);case"value":return void 0===n?$(this).val():($(this).each(function(){"object"==typeof n?(n.opacity&&$(this).attr("data-opacity",m(n.opacity,0,1)),n.color&&$(this).val(n.color)):$(this).val(n),e($(this))}),$(this));default:return"create"!==a&&(n=a),$(this).each(function(){i($(this),n)}),$(this)}}}),$(document).on("mousedown.minicolors touchstart.minicolors",function(i){$(i.target).parents().add(i.target).hasClass("minicolors")||s()}).on("mousedown.minicolors touchstart.minicolors",".minicolors-grid, .minicolors-slider, .minicolors-opacity-slider",function(i){var t=$(this);i.preventDefault(),$(document).data("minicolors-target",t),a(t,i,!0)}).on("mousemove.minicolors touchmove.minicolors",function(i){var t=$(document).data("minicolors-target");t&&a(t,i)}).on("mouseup.minicolors touchend.minicolors",function(){$(this).removeData("minicolors-target")}).on("click.minicolors",".minicolors-swatches li",function(i){i.preventDefault();var t=$(this),o=t.parents(".minicolors").find(".minicolors-input"),s=t.data("swatch-color");r(o,s,v(s)),e(o)}).on("mousedown.minicolors touchstart.minicolors",".minicolors-input-swatch",function(i){var t=$(this).parent().find(".minicolors-input");i.preventDefault(),o(t)}).on("focus.minicolors",".minicolors-input",function(){var i=$(this);i.data("minicolors-initialized")&&o(i)}).on("blur.minicolors",".minicolors-input",function(){var i=$(this),t=i.data("minicolors-settings"),o,s,a,n,r;i.data("minicolors-initialized")&&(o=t.keywords?$.map(t.keywords.split(","),function(i){return $.trim(i.toLowerCase())}):[],""!==i.val()&&$.inArray(i.val().toLowerCase(),o)>-1?r=i.val():(f(i.val())?a=u(i.val(),!0):(s=p(i.val(),!0),a=s?x(s):null),r=null===a?t.defaultValue:"rgb"===t.format?u(t.opacity?"rgba("+a.r+","+a.g+","+a.b+","+i.attr("data-opacity")+")":"rgb("+a.r+","+a.g+","+a.b+")"):y(a)),n=t.opacity?i.attr("data-opacity"):1,"transparent"===r.toLowerCase()&&(n=0),i.closest(".minicolors").find(".minicolors-input-swatch > span").css("opacity",n),i.val(r),""===i.val()&&i.val(g(t.defaultValue,!0)),i.val(d(i.val(),t.letterCase)))}).on("keydown.minicolors",".minicolors-input",function(i){var t=$(this);if(t.data("minicolors-initialized"))switch(i.keyCode){case 9:s();break;case 13:case 27:s(),t.blur()}}).on("keyup.minicolors",".minicolors-input",function(){var i=$(this);i.data("minicolors-initialized")&&e(i,!0)}).on("paste.minicolors",".minicolors-input",function(){var i=$(this);i.data("minicolors-initialized")&&setTimeout(function(){e(i,!0)},1)})}); \ No newline at end of file diff --git a/typo3/sysext/css_styled_content/Configuration/TypoScript/v7/constants.txt b/typo3/sysext/css_styled_content/Configuration/TypoScript/v7/constants.txt index 2de506d0a1dfa2a1926d531e56c59d428af8c967..ff5c5afad8bf4702a15bffda5ce2e9c7a19bb975 100644 --- a/typo3/sysext/css_styled_content/Configuration/TypoScript/v7/constants.txt +++ b/typo3/sysext/css_styled_content/Configuration/TypoScript/v7/constants.txt @@ -65,7 +65,7 @@ styles.content.imgtext { textMargin = 10 # cat=content/cImage/i1; type=color; label= Image border, color: Bordercolor of images in content elements when "Border"-option for element is set. - borderColor = black + borderColor = #000000 # cat=content/cImage/i2; type=int[0-100]; label= Image border, thickness: Thickness of border around images in content elements when "Border"-option for element is set. borderThick = 2 # cat=content/cImage/i3; type=int+; label= Image border, padding: Padding left and right to the image, around the border. @@ -101,15 +101,15 @@ styles.content.table { # cat=content/cTable/k3; type=color; label= Table background color, Color 2: Background color for table when "Backgr. Color" has been set to "Color 2" backgroundColor.2 = #F5FFAA # cat=content/cTable/k5; type=color; label= Table background color, Black: Background color for table when "Backgr. Color" has been set to "Black" - backgroundColor.240 = black + backgroundColor.240 = #000000 # cat=content/cTable/k6; type=color; label= Table background color, White: Background color for table when "Backgr. Color" has been set to "White" - backgroundColor.241 = white + backgroundColor.241 = #FFFFFF # cat=content/cTable/k7; type=color; label= Table background color, Dark Gray: Background color for table when "Backgr. Color" has been set to "Dark Gray" backgroundColor.242 = #333333 # cat=content/cTable/k8; type=color; label= Table background color, Gray: Background color for table when "Backgr. Color" has been set to "Gray" - backgroundColor.243 = gray + backgroundColor.243 = #808080 # cat=content/cTable/k9; type=color; label= Table background color, Silver: Background color for table when "Backgr. Color" has been set to "Silver" - backgroundColor.244 = silver + backgroundColor.244 = #C0C0C0 } # cat=advanced/links; type=small; label= Target for internal links: Should match the name of the content PAGE-object in TypoScript when used with frames. Most cases: set to "" (empty). If you have frames in the template set to "page" diff --git a/typo3/sysext/css_styled_content/static/constants.txt b/typo3/sysext/css_styled_content/static/constants.txt index 70b7f1d49c71c731de16d398567f7fbb873ed2d9..ab0e1d148245581959720d5fe2e46e507d027fdc 100644 --- a/typo3/sysext/css_styled_content/static/constants.txt +++ b/typo3/sysext/css_styled_content/static/constants.txt @@ -63,7 +63,9 @@ styles.content.imgtext { textMargin = 10 # cat=content/cImage/i1; type=color; label= Image border, color: Bordercolor of images in content elements when "Border"-option for element is set. - borderColor = black + borderColor = #000000 + # cat=content/cImage/i1; type=color; label= Image border, color: Bordercolor of images in content elements when "Border"-option for element is set. + borderColor2 = #000000 # cat=content/cImage/i2; type=int[0-100]; label= Image border, thickness: Thickness of border around images in content elements when "Border"-option for element is set. borderThick = 2 # cat=content/cImage/i3; type=int+; label= Image border, padding: Padding left and right to the image, around the border. @@ -91,15 +93,15 @@ styles.content.table { # cat=content/cTable/k3; type=color; label= Table background color, Color 2: Background color for table when "Backgr. Color" has been set to "Color 2" backgroundColor.2 = #F5FFAA # cat=content/cTable/k5; type=color; label= Table background color, Black: Background color for table when "Backgr. Color" has been set to "Black" - backgroundColor.240 = black + backgroundColor.240 = #000000 # cat=content/cTable/k6; type=color; label= Table background color, White: Background color for table when "Backgr. Color" has been set to "White" - backgroundColor.241 = white + backgroundColor.241 = #FFFFFF # cat=content/cTable/k7; type=color; label= Table background color, Dark Gray: Background color for table when "Backgr. Color" has been set to "Dark Gray" backgroundColor.242 = #333333 # cat=content/cTable/k8; type=color; label= Table background color, Gray: Background color for table when "Backgr. Color" has been set to "Gray" - backgroundColor.243 = gray + backgroundColor.243 = #808080 # cat=content/cTable/k9; type=color; label= Table background color, Silver: Background color for table when "Backgr. Color" has been set to "Silver" - backgroundColor.244 = silver + backgroundColor.244 = #C0C0C0 } # cat=advanced/links; type=small; label= Target for internal links: Should match the name of the content PAGE-object in TypoScript when used with frames. Most cases: set to "" (empty). If you have frames in the template set to "page" diff --git a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Form/TypoScriptConstantsViewHelper.php b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Form/TypoScriptConstantsViewHelper.php index a63cbc3bf956f880bef66f1d88e3646316be12e9..78d24362a54819457f5601f015e05bf9f48c209e 100644 --- a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Form/TypoScriptConstantsViewHelper.php +++ b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Form/TypoScriptConstantsViewHelper.php @@ -101,26 +101,20 @@ class TypoScriptConstantsViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\Abs $this->tag->addAttribute('value', $configuration->getValue()); } - // configure colorpicker wizard - $params = array( - 'formName' => 'configurationform', - 'itemName' => $elementName, - ); - $onClick = - 'this.blur();' . - 'vHWin=window.open(' . - GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('wizard_colorpicker', array('P' => $params))) . ' + \'&P[currentValue]=\' + encodeURIComponent(document.getElementById(' . GeneralUtility::quoteJSvalue($elementId) . ').value),' . - '\'popUpem-' . GeneralUtility::shortMD5($elementName) . '\',' . - '\'height=400,width=400,status=0,menubar=0,scrollbars=1\'' . - ');' . - 'vHWin.focus();' . - 'return false;'; - - // wrap the field - $output = '<div class="form-wizards-wrap form-wizards-aside">' - . '<div class="form-wizards-element">' . $this->tag->render() . '</div>' - . '<div class="form-wizards-items"><a href="#" onClick="' . htmlspecialchars($onClick) . '" class="btn btn-default"><span class="t3-icon fa fa-eyedropper"></span></a></div>' - . '</div>'; + $output = ' + <div class="form-wizards-element"> + <input class="form-control t3js-color-input formengine-colorpickerelement" type="text" + name="' . htmlspecialchars($elementName) . '" value="' . $this->tag->getAttribute('value') . '"/> + <script type="text/javascript"> + require([\'TYPO3/CMS/Core/Contrib/jquery.minicolors\'], function () { + $(\'.formengine-colorpickerelement\').minicolors({ + theme: \'bootstrap\', + format: \'hex\', + position: \'bottom left\' + }); + }); + </script> + </div>'; return $output; } diff --git a/typo3/sysext/fluid_styled_content/Configuration/TypoScript/Static/constants.txt b/typo3/sysext/fluid_styled_content/Configuration/TypoScript/Static/constants.txt index 483471bf703d32c2a60a036ddae5baf2775c3d53..c6a315ecb9342119e732df52bedc882075127b45 100644 --- a/typo3/sysext/fluid_styled_content/Configuration/TypoScript/Static/constants.txt +++ b/typo3/sysext/fluid_styled_content/Configuration/TypoScript/Static/constants.txt @@ -31,7 +31,7 @@ styles.content { textMargin = 10 # cat=content/cTextmedia/i1; type=color; label= Media element border, color: Bordercolor of media elements in content elements when "Border"-option for an element is set - borderColor = black + borderColor = #000000 # cat=content/cTextmedia/i2; type=int[0-100]; label= Media element border, thickness: Thickness of border around media elements in content elements when "Border"-option for element is set borderWidth = 2 # cat=content/cTextmedia/i3; type=int+; label= Media element border, padding: Padding left and right to the media element, around the border diff --git a/typo3/sysext/t3skin/Resources/Public/Css/backend.css b/typo3/sysext/t3skin/Resources/Public/Css/backend.css index d095ed629cd549f5c492fd95ab28c6bcab9eb01a..539d833f6e271eb500c5de4546c65efd8a2f1785 100644 --- a/typo3/sysext/t3skin/Resources/Public/Css/backend.css +++ b/typo3/sysext/t3skin/Resources/Public/Css/backend.css @@ -7875,6 +7875,198 @@ button.close { display: none !important; } } +.minicolors { + position: relative; +} +.userTS .minicolors { + position: absolute; +} +.minicolors-sprite { + background-image: url("../../../../../../typo3/sysext/core/Resources/Public/Images/colorpicker/jquery.minicolors.png"); +} +.minicolors-swatch { + position: absolute; + vertical-align: middle; + background-position: -80px 0; + cursor: text; + padding: 0; + margin: 0; + display: inline-block; + top: 50%; + left: 6px; + z-index: 2; + -webkit-transform: translate(0, -50%); + transform: translate(0, -50%); + width: 20px; + height: 20px; + border-radius: 1px; +} +.minicolors-swatch-color { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; +} +.minicolors-input { + float: none; + padding-left: 32px; +} +.minicolors-panel { + margin-top: 1px; + overflow: hidden; + border-radius: 2px; + position: absolute; + width: 173px; + height: 152px; + background: #ffffff; + border: solid 1px #bbbbbb; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); + z-index: 99999; + box-sizing: content-box; + display: none; +} +.minicolors-panel.minicolors-with-swatches { + height: 182px; +} +.minicolors-panel.minicolors-visible { + display: block; +} +.minicolors-position-top .minicolors-panel { + top: -154px; +} +.minicolors-position-right .minicolors-panel { + right: 0; +} +.minicolors-position-bottom .minicolors-panel { + top: auto; +} +.minicolors-position-left .minicolors-panel { + left: 0; +} +.minicolors-with-opacity .minicolors-panel { + width: 194px; +} +.minicolors .minicolors-grid { + position: absolute; + top: 1px; + left: 1px; + width: 150px; + height: 150px; + background-position: -120px 0; + cursor: crosshair; +} +.minicolors .minicolors-grid-inner { + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; +} +.minicolors-slider-saturation .minicolors-grid { + background-position: -420px 0; +} +.minicolors-slider-saturation .minicolors-grid-inner { + background-position: -270px 0; + background-image: inherit; +} +.minicolors-slider-brightness .minicolors-grid { + background-position: -570px 0; +} +.minicolors-slider-brightness .minicolors-grid-inner { + background-color: black; +} +.minicolors-slider-wheel .minicolors-grid { + background-position: -720px 0; +} +.minicolors-slider, +.minicolors-opacity-slider { + position: absolute; + top: 1px; + left: 152px; + width: 20px; + height: 150px; + background-color: white; + background-position: 0 0; + cursor: row-resize; +} +.minicolors-slider-saturation .minicolors-slider { + background-position: -60px 0; +} +.minicolors-slider-brightness .minicolors-slider { + background-position: -20px 0; +} +.minicolors-slider-wheel .minicolors-slider { + background-position: -20px 0; +} +.minicolors-opacity-slider { + left: 173px; + background-position: -40px 0; + display: none; +} +.minicolors-with-opacity .minicolors-opacity-slider { + display: block; +} +.minicolors-grid .minicolors-picker { + position: absolute; + top: 70px; + left: 70px; + width: 12px; + height: 12px; + border: solid 1px black; + border-radius: 10px; + margin-top: -6px; + margin-left: -6px; + background: none; +} +.minicolors-grid .minicolors-picker > div { + position: absolute; + top: 0; + left: 0; + width: 8px; + height: 8px; + border-radius: 8px; + border: solid 2px white; + box-sizing: content-box; +} +.minicolors-picker { + position: absolute; + top: 0; + left: 0; + width: 18px; + height: 2px; + background: white; + border: solid 1px black; + margin-top: -2px; + box-sizing: content-box; +} +.minicolors-swatches, +.minicolors-swatches li { + margin: 0; + padding: 0; + list-style: none; + overflow: hidden; + position: absolute; + top: 157px; + left: 5px; +} +.minicolors-swatches .minicolors-swatch { + position: relative; + float: left; + cursor: pointer; + margin: 0 4px 0 0; + top: 0; + left: 0; + width: 20px; + height: 20px; +} +.minicolors-with-opacity .minicolors-swatches .minicolors-swatch { + margin-right: 7px; +} +.minicolors-swatch.selected { + border-color: #000; +} /*! * Datetimepicker for Bootstrap 3 * version : 4.17.37 diff --git a/typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateConstantEditorModuleFunctionController.php b/typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateConstantEditorModuleFunctionController.php index 7877c38afa35c8b64cea3626c1247609c57c9489..2ccf67d895784595a04fde3c8fa1fe155a376f88 100644 --- a/typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateConstantEditorModuleFunctionController.php +++ b/typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateConstantEditorModuleFunctionController.php @@ -172,6 +172,10 @@ class TypoScriptTemplateConstantEditorModuleFunctionController extends AbstractF $templateService->ext_getTSCE_config($category); $printFields = trim($templateService->ext_printFields($theConstants, $category)); + foreach ($templateService->getInlineJavaScript() as $name => $inlineJavaScript) { + $this->pageRenderer->addJsInlineCode($name, $inlineJavaScript); + } + if ($printFields) { $theOutput .= '<div>' . $printFields . '</div>'; }