UNPKG

@uiw/codemirror-extensions-color

Version:
322 lines (321 loc) 14.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); exports.colorView = exports.colorTheme = exports.color = exports.ColorType = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _callSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/callSuper")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper")); var _view = require("@codemirror/view"); var _language = require("@codemirror/language"); var _colorsNamed = _interopRequireDefault(require("colors-named")); var _colorsNamedHex = _interopRequireDefault(require("colors-named-hex")); var _hslMatcher = _interopRequireWildcard(require("hsl-matcher")); var _utils = require("./utils"); var _excluded = ["color", "colorRaw"]; var ColorType = exports.ColorType = /*#__PURE__*/function (ColorType) { ColorType["rgb"] = "RGB"; ColorType["hex"] = "HEX"; ColorType["named"] = "NAMED"; ColorType["hsl"] = "HSL"; return ColorType; }({}); var colorState = new WeakMap(); function colorDecorations(view) { var widgets = []; var _iterator = (0, _createForOfIteratorHelper2["default"])(view.visibleRanges), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var range = _step.value; (0, _language.syntaxTree)(view.state).iterate({ from: range.from, to: range.to, enter: function enter(_ref) { var type = _ref.type, from = _ref.from, to = _ref.to; var callExp = view.state.doc.sliceString(from, to); /** * ``` * rgb(0 107 128, .5); ❌ ❌ ❌ * rgb( 0 107 128 ); ✅ ✅ ✅ * RGB( 0 107 128 ); ✅ ✅ ✅ * Rgb( 0 107 128 ); ✅ ✅ ✅ * rgb( 0 107 128 / ); ❌ ❌ ❌ * rgb( 0 107 128 / 60%); ✅ ✅ ✅ * rgb(0,107,128 / 60%); ❌ ❌ ❌ * rgb( 255, 255, 255 ) ✅ ✅ ✅ * rgba( 255, 255, 255 ) ✅ ✅ ✅ * rgba( 255, 255 , 255, ) ❌ ❌ ❌ * rgba( 255, 255 , 255, .5 ) ✅ ✅ ✅ * rgba( 255 255 255 / 0.5 ); ✅ ✅ ✅ * rgba( 255 255 255 0.5 ); ❌ ❌ ❌ * rgba( 255 255 255 / ); ❌ ❌ ❌ * ``` */ if (type.name === 'CallExpression' && callExp.startsWith('rgb')) { var match = /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,?\s*(\d{1,3})\s*(,\s*\d*\.\d*\s*)?\)/i.exec(callExp) || /rgba?\(\s*(\d{1,3})\s*(\d{1,3})\s*(\d{1,3})\s*(\/?\s*\d+%)?(\/\s*\d+\.\d\s*)?\)/i.exec(callExp); if (!match) return; var _match = (0, _slicedToArray2["default"])(match, 5), _ = _match[0], r = _match[1], g = _match[2], b = _match[3], a = _match[4]; var hex = (0, _utils.rgbToHex)(Number(r), Number(g), Number(b)); var widget = _view.Decoration.widget({ widget: new ColorWidget({ colorType: ColorType.rgb, color: hex, colorRaw: callExp, from: from, to: to, alpha: a ? a.replace(/(\/|,)/g, '') : '' }), side: 0 }); widgets.push(widget.range(from)); } else if (type.name === 'CallExpression' && (0, _hslMatcher["default"])(callExp)) { /** * # valid * hsl(240, 100%, 50%) // ✅ comma separated * hsl(240, 100%, 50%, 0.1) // ✅ comma separated with opacity * hsl(240, 100%, 50%, 10%) // ✅ comma separated with % opacity * hsl(240,100%,50%,0.1) // ✅ comma separated without spaces * hsl(180deg, 100%, 50%, 0.1) // ✅ hue with 'deg' * hsl(3.14rad, 100%, 50%, 0.1) // ✅ hue with 'rad' * hsl(200grad, 100%, 50%, 0.1) // ✅ hue with 'grad' * hsl(0.5turn, 100%, 50%, 0.1) // ✅ hue with 'turn' * hsl(-240, -100%, -50%, -0.1) // ✅ negative values * hsl(+240, +100%, +50%, +0.1) // ✅ explicit positive sign * hsl(240.5, 99.99%, 49.999%, 0.9999) // ✅ non-integer values * hsl(.9, .99%, .999%, .9999) // ✅ fraction w/o leading zero * hsl(0240, 0100%, 0050%, 01) // ✅ leading zeros * hsl(240.0, 100.00%, 50.000%, 1.0000) // ✅ trailing decimal zeros * hsl(2400, 1000%, 1000%, 10) // ✅ out of range values * hsl(-2400.01deg, -1000.5%, -1000.05%, -100) // ✅ combination of above * hsl(2.40e+2, 1.00e+2%, 5.00e+1%, 1E-3) // ✅ scientific notation * hsl(240 100% 50%) // ✅ space separated (CSS Color Level 4) * hsl(240 100% 50% / 0.1) // ✅ space separated with opacity * hsla(240, 100%, 50%) // ✅ hsla() alias * hsla(240, 100%, 50%, 0.1) // ✅ hsla() with opacity * HSL(240Deg, 100%, 50%) // ✅ case insensitive */ var _match2 = (0, _hslMatcher.hlsStringToRGB)(callExp); if (!_match2) return; var _r = _match2.r, _g = _match2.g, _b = _match2.b; var _hex = (0, _utils.rgbToHex)(Number(_r), Number(_g), Number(_b)); var _widget = _view.Decoration.widget({ widget: new ColorWidget({ colorType: ColorType.hsl, color: _hex, colorRaw: callExp, from: from, to: to, alpha: _match2.a ? _match2.a.toString() : '' }), side: 0 }); widgets.push(_widget.range(from)); } else if (type.name === 'ColorLiteral') { var _toFullHex = (0, _utils.toFullHex)(callExp), _toFullHex2 = (0, _slicedToArray2["default"])(_toFullHex, 2), _color = _toFullHex2[0], alpha = _toFullHex2[1]; var _widget2 = _view.Decoration.widget({ widget: new ColorWidget({ colorType: ColorType.hex, color: _color, colorRaw: callExp, from: from, to: to, alpha: alpha }), side: 0 }); widgets.push(_widget2.range(from)); } else if (type.name === 'ValueName') { var name = callExp; if (_colorsNamed["default"].includes(name)) { var _widget3 = _view.Decoration.widget({ widget: new ColorWidget({ colorType: ColorType.named, color: _colorsNamedHex["default"][_colorsNamed["default"].indexOf(name)], colorRaw: callExp, from: from, to: to, alpha: '' }), side: 0 }); widgets.push(_widget3.range(from)); } } } }); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return _view.Decoration.set(widgets); } var ColorWidget = /*#__PURE__*/function (_WidgetType) { function ColorWidget(_ref2) { var _this; var color = _ref2.color, colorRaw = _ref2.colorRaw, state = (0, _objectWithoutProperties2["default"])(_ref2, _excluded); (0, _classCallCheck2["default"])(this, ColorWidget); _this = (0, _callSuper2["default"])(this, ColorWidget); (0, _defineProperty2["default"])(_this, "state", void 0); (0, _defineProperty2["default"])(_this, "color", void 0); (0, _defineProperty2["default"])(_this, "colorRaw", void 0); _this.state = state; _this.color = color; _this.colorRaw = colorRaw; return _this; } (0, _inherits2["default"])(ColorWidget, _WidgetType); return (0, _createClass2["default"])(ColorWidget, [{ key: "eq", value: function eq(other) { return other.state.colorType === this.state.colorType && other.color === this.color && other.state.from === this.state.from && other.state.to === this.state.to && other.state.alpha === this.state.alpha; } }, { key: "toDOM", value: function toDOM() { var picker = document.createElement('input'); colorState.set(picker, this.state); picker.type = 'color'; picker.value = this.color; picker.dataset['color'] = this.color; picker.dataset['colorraw'] = this.colorRaw; var wrapper = document.createElement('span'); wrapper.appendChild(picker); wrapper.dataset['color'] = this.color; wrapper.style.backgroundColor = this.colorRaw; return wrapper; } }, { key: "ignoreEvent", value: function ignoreEvent() { return false; } }]); }(_view.WidgetType); var colorView = exports.colorView = function colorView() { var showPicker = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; return _view.ViewPlugin.fromClass(/*#__PURE__*/function () { function ColorView(view) { (0, _classCallCheck2["default"])(this, ColorView); (0, _defineProperty2["default"])(this, "decorations", void 0); this.decorations = colorDecorations(view); } return (0, _createClass2["default"])(ColorView, [{ key: "update", value: function update(_update) { if (_update.docChanged || _update.viewportChanged) { this.decorations = colorDecorations(_update.view); } var readOnly = _update.view.contentDOM.ariaReadOnly === 'true'; var editable = _update.view.contentDOM.contentEditable === 'true'; var canBeEdited = readOnly === false && editable; this.changePicker(_update.view, canBeEdited); } }, { key: "changePicker", value: function changePicker(view, canBeEdited) { var doms = view.contentDOM.querySelectorAll('input[type=color]'); doms.forEach(function (inp) { if (!showPicker) { inp.setAttribute('disabled', ''); } else { canBeEdited ? inp.removeAttribute('disabled') : inp.setAttribute('disabled', ''); } }); } }]); }(), { decorations: function decorations(v) { return v.decorations; }, eventHandlers: { change: function change(e, view) { var target = e.target; if (target.nodeName !== 'INPUT' || !target.parentElement || !target.dataset.color && !target.dataset.colorraw) return false; var data = colorState.get(target); var value = target.value; var rgb = (0, _utils.hexToRgb)(value); var colorraw = target.dataset.colorraw; var slash = (target.dataset.colorraw || '').indexOf('/') > 4; var comma = (target.dataset.colorraw || '').indexOf(',') > 4; var converted = target.value; if (data.colorType === ColorType.rgb) { var funName = colorraw !== null && colorraw !== void 0 && colorraw.match(/^(rgba?)/) ? colorraw === null || colorraw === void 0 ? void 0 : colorraw.match(/^(rgba?)/)[0] : undefined; if (comma) { converted = rgb ? "".concat(funName, "(").concat(rgb.r, ", ").concat(rgb.g, ", ").concat(rgb.b).concat(data.alpha ? ', ' + data.alpha.trim() : '', ")") : value; } else if (slash) { converted = rgb ? "".concat(funName, "(").concat(rgb.r, " ").concat(rgb.g, " ").concat(rgb.b).concat(data.alpha ? ' / ' + data.alpha.trim() : '', ")") : value; } else { converted = rgb ? "".concat(funName, "(").concat(rgb.r, " ").concat(rgb.g, " ").concat(rgb.b, ")") : value; } } else if (data.colorType === ColorType.hsl) { var _rgb = (0, _utils.hexToRgb)(value); if (_rgb) { var _RGBToHSL = (0, _utils.RGBToHSL)(_rgb === null || _rgb === void 0 ? void 0 : _rgb.r, _rgb === null || _rgb === void 0 ? void 0 : _rgb.g, _rgb === null || _rgb === void 0 ? void 0 : _rgb.b), h = _RGBToHSL.h, s = _RGBToHSL.s, l = _RGBToHSL.l; converted = "hsl(".concat(h, "deg ").concat(s, "% ").concat(l, "%").concat(data.alpha ? ' / ' + data.alpha : '', ")"); } } view.dispatch({ changes: { from: data.from, to: data.to, insert: converted } }); return true; } } }); }; var colorTheme = exports.colorTheme = _view.EditorView.baseTheme({ 'span[data-color]': { width: '12px', height: '12px', display: 'inline-block', borderRadius: '2px', marginRight: '0.5ch', outline: '1px solid #00000040', overflow: 'hidden', verticalAlign: 'middle', marginTop: '-2px' }, 'span[data-color] input[type="color"]': { background: 'transparent', display: 'block', border: 'none', outline: '0', paddingLeft: '24px', height: '12px' }, 'span[data-color] input[type="color"]::-webkit-color-swatch': { border: 'none', paddingLeft: '24px' } }); var color = exports.color = [colorView(), colorTheme];