$.Redactor.prototype.WoltLabColor = function() {
"use strict";
+ // these are hex values, but the '#' was left out for convenience
+ var _defaultColors = [
+ '000000', '800000', '8B4513', '2F4F4F', '008080', '000080', '4B0082', '696969',
+ 'B22222', 'A52A2A', 'DAA520', '006400', '40E0D0', '0000CD', '800080', '808080',
+ 'FF0000', 'FF8C00', 'FFD700', '008000', '00FFFF', '0000FF', 'EE82EE', 'A9A9A9',
+ 'FFA07A', 'FFA500', 'FFFF00', '00FF00', 'AFEEEE', 'ADD8E6', 'DDA0DD', 'D3D3D3',
+ 'FFF0F5', 'FAEBD7', 'FFFFE0', 'F0FFF0', 'F0FFFF', 'F0F8FF', 'E6E6FA', 'FFFFFF'
+ ];
+
return {
init: function() {
- // these are hex values, but the '#' was left out for convenience
- var colors = [
- '000000', '800000', '8B4513', '2F4F4F', '008080', '000080', '4B0082', '696969',
- 'B22222', 'A52A2A', 'DAA520', '006400', '40E0D0', '0000CD', '800080', '808080',
- 'FF0000', 'FF8C00', 'FFD700', '008000', '00FFFF', '0000FF', 'EE82EE', 'A9A9A9',
- 'FFA07A', 'FFA500', 'FFFF00', '00FF00', 'AFEEEE', 'ADD8E6', 'DDA0DD', 'D3D3D3',
- 'FFF0F5', 'FAEBD7', 'FFFFE0', 'F0FFF0', 'F0FFFF', 'F0F8FF', 'E6E6FA', 'FFFFFF'
- ];
-
var callback = this.WoltLabColor.setColor.bind(this), color;
var dropdown = {
'removeColor': {
func: this.WoltLabColor.removeColor.bind(this)
}
};
- for (var i = 0, length = colors.length; i < length; i++) {
- color = colors[i];
+ for (var i = 0, length = _defaultColors.length; i < length; i++) {
+ color = _defaultColors[i];
dropdown['color_' + color] = {
title: '#' + color,
WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'convertTags_' + this.$element[0].id, function (data) {
elBySelAll('woltlab-color', data.div, function (element) {
- if (element.className.match(/^woltlab-color-([0-9A-F]{6})$/)) {
- if (colors.indexOf(RegExp.$1) !== -1) {
- data.addToStorage(element, ['class']);
- }
- }
+ data.addToStorage(element, ['class']);
});
});
+
+ this.WoltLabColor.registerColors();
+
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'codeStart_' + this.$element[0].id, this.WoltLabColor.registerColors.bind(this));
},
setColor: function(key) {
this.buffer.set();
}).bind(this));
+ },
+
+ registerColors: function () {
+ require(['WoltLabSuite/Core/Ui/Redactor/RuntimeStyle'], (function (UiRedactorRuntimeStyle) {
+ elBySelAll('woltlab-color', this.$editor[0], (function (color) {
+ if (color.className.match(/woltlab-color-([a-z0-9]{3}(?:[a-z0-9]{3})?)/i)) {
+ var code = RegExp.$1;
+ if (code.length === 3) code = code.substr(0, 1) + code.substr(0, 1) + code.substr(1, 1) + code.substr(1, 1) + code.substr(2, 1) + code.substr(2, 1);
+ code = code.toUpperCase();
+
+ if (_defaultColors.indexOf(code) === -1) {
+ UiRedactorRuntimeStyle.add('woltlab-color-' + code, 'color: #' + code + ';');
+ }
+ }
+ }).bind(this));
+ }).bind(this));
}
};
};
],
'p' => ['text-center', 'text-justify', 'text-right'],
'td' => ['text-center', 'text-justify', 'text-right'],
- 'woltlab-color' => [
- 'woltlab-color-000000', 'woltlab-color-000080', 'woltlab-color-0000CD', 'woltlab-color-0000FF', 'woltlab-color-006400', 'woltlab-color-008000',
- 'woltlab-color-008080', 'woltlab-color-00FF00', 'woltlab-color-00FFFF', 'woltlab-color-2F4F4F', 'woltlab-color-40E0D0', 'woltlab-color-4B0082',
- 'woltlab-color-696969', 'woltlab-color-800000', 'woltlab-color-800080', 'woltlab-color-808080', 'woltlab-color-8B4513', 'woltlab-color-A52A2A',
- 'woltlab-color-A9A9A9', 'woltlab-color-ADD8E6', 'woltlab-color-AFEEEE', 'woltlab-color-B22222', 'woltlab-color-D3D3D3', 'woltlab-color-DAA520',
- 'woltlab-color-DDA0DD', 'woltlab-color-E6E6FA', 'woltlab-color-EE82EE', 'woltlab-color-F0F8FF', 'woltlab-color-F0FFF0', 'woltlab-color-F0FFFF',
- 'woltlab-color-FAEBD7', 'woltlab-color-FF0000', 'woltlab-color-FF8C00', 'woltlab-color-FFA07A', 'woltlab-color-FFA500', 'woltlab-color-FFD700',
- 'woltlab-color-FFF0F5', 'woltlab-color-FFFF00', 'woltlab-color-FFFFE0', 'woltlab-color-FFFFFF'
- ],
+ 'woltlab-color' => '*',
'woltlab-font' => [
'woltlab-font-arial', 'woltlab-font-comicSansMs', 'woltlab-font-courierNew', 'woltlab-font-georgia', 'woltlab-font-lucidaSansUnicode',
'woltlab-font-tahoma', 'woltlab-font-timesNewRoman', 'woltlab-font-trebuchetMs', 'woltlab-font-verdana'
foreach ($this->getXPath()->query('//*[@class]') as $element) {
$nodeName = $element->nodeName;
if (isset(self::$allowedClassNames[$nodeName])) {
+ if (self::$allowedClassNames[$nodeName] === '*') {
+ continue;
+ }
+
$classNames = explode(' ', $element->getAttribute('class'));
$classNames = array_filter($classNames, function ($className) use ($nodeName) {
return ($className && in_array($className, self::$allowedClassNames[$nodeName]));
*/
protected $tagName = 'woltlab-color';
- public static $validColors = [
- '000000', '000080', '0000CD', '0000FF', '006400', '008000', '008080', '00FF00',
- '00FFFF', '2F4F4F', '40E0D0', '4B0082', '696969', '800000', '800080', '808080',
- '8B4513', 'A52A2A', 'A9A9A9', 'ADD8E6', 'AFEEEE', 'B22222', 'D3D3D3', 'DAA520',
- 'DDA0DD', 'E6E6FA', 'EE82EE', 'F0F8FF', 'F0FFF0', 'F0FFFF', 'FAEBD7', 'FF0000',
- 'FF8C00', 'FFA07A', 'FFA500', 'FFD700', 'FFF0F5', 'FFFF00', 'FFFFE0', 'FFFFFF'
+ /**
+ * list of color names in CSS
+ * @var string[]
+ */
+ protected $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',
+ 'darkgrey' => 'A9A9A9', 'darkgreen' => '006400', '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',
+ 'grey' => '808080', 'green' => '008000', 'greenyellow' => 'ADFF2F', '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',
+ 'lightgrey' => 'D3D3D3', 'lightgreen' => '90EE90', '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' => '9370D8', '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' => 'D87093',
+ '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'
];
- protected static $colorsToLab = [];
-
/**
* @inheritDoc
*/
public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) {
/** @var \DOMElement $element */
foreach ($elements as $element) {
- if (preg_match('~\bwoltlab-color-([a-z0-9]{6})\b~i', $element->getAttribute('class'), $matches)) {
- $color = strtoupper($matches[1]);
- if (!in_array($color, self::$validColors)) {
- $color = $this->getClosestColor($color);
+ $className = $element->getAttribute('class');
+ $colorCode = '';
+ if (preg_match('~^woltlab-color-([a-z0-9]{3}(?:[a-z0-9]{3})?)$~i', $className, $matches)) {
+ if (strlen($matches[1]) === 3) {
+ $colorCode = $matches[1]{0}.$matches[1]{0} . $matches[1]{1}.$matches[1]{1} . $matches[1]{2}.$matches[1]{2};
+ }
+ else {
+ $colorCode = $matches[1];
}
-
- $element->setAttribute('class', 'woltlab-color-'.$color);
- }
- else {
- DOMUtil::removeNode($element, true);
}
- }
- }
-
- protected function getClosestColor($hex) {
- if (empty(self::$colorsToLab)) {
- // build static lookup table
- foreach (self::$validColors as $color) {
- self::$colorsToLab[$color] = $this->hexToLab($color);
+ else if (preg_match('~^woltlab-color-([a-z]+)$~i', $className, $matches)) {
+ $colorName = strtolower($matches[1]);
+ if (isset($this->colorNames[$colorName])) {
+ $colorCode = $this->colorNames[$colorName];
+ }
}
- }
-
- $lab1 = $this->hexToLab($hex);
-
- $diff = 0;
- $newColor = '';
-
- foreach (self::$colorsToLab as $color => $lab2) {
- $newDiff = $this->deltaE_cie1994($lab1, $lab2);
- if ($newColor === '' || $diff > $newDiff) {
- $diff = $newDiff;
- $newColor = $color;
+ if (empty($colorCode)) {
+ DOMUtil::removeNode($element, true);
+ }
+ else {
+ $element->setAttribute('class', 'woltlab-color-' . strtoupper($colorCode));
}
}
-
- return $newColor;
- }
-
- protected function hexToLab($hex) {
- return $this->xyzToLab(
- $this->rgbToXyz(
- $this->hexToRgb($hex)
- )
- );
- }
-
- protected function hexToRgb($hex) {
- // [r, g, b]
- return [
- hexdec($hex{0}.$hex{1}),
- hexdec($hex{2}.$hex{3}),
- hexdec($hex{4}.$hex{5})
- ];
- }
-
- protected function rgbToXyz($rgb) {
- // convert into values between 0 and 1
- $red = $rgb[0] / 255;
- $green = $rgb[1] / 255;
- $blue = $rgb[2] / 255;
-
- if ($red > 0.04045) {
- $red = ($red + 0.055) / 1.055;
- $red = pow($red, 2.4);
- }
- else {
- $red = $red / 12.92;
- }
-
- if ($green > 0.04045) {
- $green = ($green + 0.055) / 1.055;
- $green = pow($green, 2.4);
- }
- else {
- $green = $green / 12.92;
- }
-
- if ($blue > 0.04045) {
- $blue = ($blue + 0.055) / 1.055;
- $blue = pow($blue, 2.4);
- }
- else {
- $blue = $blue / 12.92;
- }
-
- $red *= 100;
- $green *= 100;
- $blue *= 100;
-
- // [x, y, z]
- return [
- $red * 0.4124 + $green * 0.3576 + $blue * 0.1805,
- $red * 0.2126 + $green * 0.7152 + $blue * 0.0722,
- $red * 0.0193 + $green * 0.1192 + $blue * 0.9505
- ];
- }
-
- protected function xyzToLab($xyz) {
- $x = $xyz[0] / 95.047;
- $y = $xyz[1] / 100;
- $z = $xyz[2] / 108.883;
-
- if ($x > 0.008856) {
- $x = pow($x, 1 / 3);
- }
- else {
- $x = 7.787 * $x + 16 / 116;
- }
-
- if ($y > 0.008856) {
- $y = pow($y, 1 / 3);
- }
- else {
- $y = (7.787 * $y) + (16 / 116);
- }
-
- if ($z > 0.008856) {
- $z = pow($z, 1 / 3);
- }
- else {
- $z = 7.787 * $z + 16 / 116;
- }
-
- // [l, a, b]
- return [
- 116 * $y - 16,
- 500 * ($x - $y),
- 200 * ($y - $z)
- ];
- }
-
- protected function deltaE_cie1994($lab1, $lab2) {
- // Delta E (CIE 1994) difference of two colors
- // http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE94.html
- $c1 = sqrt($lab1[1] * $lab1[1] + $lab1[2] * $lab1[2]);
- $c2 = sqrt($lab2[1] * $lab2[1] + $lab2[2] * $lab2[2]);
-
- $dc = $c1 - $c2;
- $dl = $lab1[0] - $lab2[0];
- $da = $lab1[1] - $lab2[1];
- $db = $lab1[2] - $lab2[2];
- $dh = ($da * $da) + ($db * $db) - ($dc * $dc);
- $dh = ($dh < 0) ? 0 : sqrt($dh);
-
- $first = $dl;
- $second = $dc / (1 + 0.045 * $c1);
- $third = $dh / (1 + 0.015 * $c1);
-
- return sqrt($first * $first + $second * $second + $third * $third);
}
}