| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- /* global CodeMirror loadScript editors showHelp */
- 'use strict';
- // eslint-disable-next-line no-var
- var initColorpicker = () => {
- initOverlayHooks();
- onDOMready().then(() => {
- $('#colorpicker-settings').onclick = configureColorpicker;
- });
- const scripts = [
- '/vendor-overwrites/colorpicker/colorpicker.css',
- '/vendor-overwrites/colorpicker/colorpicker.js',
- '/vendor-overwrites/colorpicker/colorview.js',
- ];
- prefs.subscribe(['editor.colorpicker.hotkey'], registerHotkey);
- prefs.subscribe(['editor.colorpicker'], colorpickerOnDemand);
- return prefs.get('editor.colorpicker') && colorpickerOnDemand(null, true);
- function colorpickerOnDemand(id, enabled) {
- return loadScript(enabled && scripts)
- .then(() => setColorpickerOption(id, enabled));
- }
- function setColorpickerOption(id, enabled) {
- const defaults = CodeMirror.defaults;
- const keyName = prefs.get('editor.colorpicker.hotkey');
- delete defaults.extraKeys[keyName];
- defaults.colorpicker = enabled;
- if (enabled) {
- if (keyName) {
- CodeMirror.commands.colorpicker = invokeColorpicker;
- defaults.extraKeys[keyName] = 'colorpicker';
- }
- defaults.colorpicker = {
- forceUpdate: editors.length > 0,
- tooltip: t('colorpickerTooltip'),
- popupOptions: {
- tooltipForSwitcher: t('colorpickerSwitchFormatTooltip'),
- hexUppercase: prefs.get('editor.colorpicker.hexUppercase'),
- hideDelay: 5000,
- embedderCallback: state => {
- ['hexUppercase', 'color']
- .filter(name => state[name] !== prefs.get('editor.colorpicker.' + name))
- .forEach(name => prefs.set('editor.colorpicker.' + name, state[name]));
- },
- },
- };
- }
- // on page load runs before CodeMirror.setOption is defined
- editors.forEach(cm => cm.setOption('colorpicker', defaults.colorpicker));
- }
- function registerHotkey(id, hotkey) {
- CodeMirror.commands.colorpicker = invokeColorpicker;
- const extraKeys = CodeMirror.defaults.extraKeys;
- for (const key in extraKeys) {
- if (extraKeys[key] === 'colorpicker') {
- delete extraKeys[key];
- break;
- }
- }
- if (hotkey) {
- extraKeys[hotkey] = 'colorpicker';
- }
- }
- function invokeColorpicker(cm) {
- cm.state.colorpicker.openPopup(prefs.get('editor.colorpicker.color'));
- }
- function configureColorpicker() {
- const input = $element({
- tag: 'input',
- type: 'search',
- spellcheck: false,
- value: prefs.get('editor.colorpicker.hotkey'),
- onkeydown(event) {
- const key = CodeMirror.keyName(event);
- // ignore: [Shift?] characters, modifiers-only, [Shift?] Esc, Enter, [Shift?] Tab
- if (key === 'Enter' || key === 'Esc') {
- $('#help-popup .dismiss').onclick();
- return;
- } else if (/^(Space|(Shift-)?(Esc|Tab|[!-~])|(Shift-?|Ctrl-?|Alt-?|Cmd-?)*)$/.test(key)) {
- this.setCustomValidity('Not allowed');
- } else {
- this.setCustomValidity('');
- prefs.set('editor.colorpicker.hotkey', key);
- }
- event.preventDefault();
- event.stopPropagation();
- this.value = key;
- },
- oninput() {
- // fired on pressing "x" to clear the field
- prefs.set('editor.colorpicker.hotkey', '');
- },
- onpaste(event) {
- event.preventDefault();
- }
- });
- const popup = showHelp(t('helpKeyMapHotkey'), input);
- if (this instanceof Element) {
- const bounds = this.getBoundingClientRect();
- popup.style.left = bounds.right + 10 + 'px';
- popup.style.top = bounds.top - popup.clientHeight / 2 + 'px';
- popup.style.right = 'auto';
- }
- input.focus();
- }
- function initOverlayHooks() {
- const COLORVIEW_DISABLED_SUFFIX = ' colorview-disabled';
- const COLORVIEW_NEXT_DISABLED_SUFFIX = ' colorview-next-disabled';
- const originalAddOverlay = CodeMirror.prototype.addOverlay;
- CodeMirror.prototype.addOverlay = addOverlayHook;
- function addOverlayHook(overlay) {
- if (overlay.token !== tokenHook && (
- overlay === (this.state.matchHighlighter || {}).overlay ||
- overlay === (this.state.search || {}).overlay)) {
- overlay.colopickerHelper = {token: overlay.token};
- overlay.token = tokenHook;
- }
- originalAddOverlay.apply(this, arguments);
- }
- function tokenHook(stream) {
- const style = this.colopickerHelper.token.apply(this, arguments);
- if (!style) {
- return style;
- }
- const {start, pos, lineOracle: {baseTokens}} = stream;
- if (!baseTokens) {
- return style;
- }
- for (let prev = 0, i = 1; i < baseTokens.length; i += 2) {
- const end = baseTokens[i];
- if (prev <= start && start <= end) {
- const base = baseTokens[i + 1];
- if (base && base.includes('colorview')) {
- return style +
- (start > prev ? COLORVIEW_DISABLED_SUFFIX : '') +
- (pos < end ? COLORVIEW_NEXT_DISABLED_SUFFIX : '');
- }
- } else if (end > pos) {
- break;
- }
- prev = end;
- }
- return style;
- }
- }
- };
|