From c23f315c52f658b7bf33f7a748f6287a710bd64b Mon Sep 17 00:00:00 2001 From: eight Date: Wed, 10 Oct 2018 17:40:07 +0800 Subject: [PATCH] Refactor: use CodeMirror.defineOption --- background/usercss-helper.js | 1 - edit/codemirror-default.js | 1 + edit/codemirror-factory.js | 155 ++++++++++++++++------------------- edit/source-editor.js | 5 +- js/script-loader.js | 2 +- 5 files changed, 73 insertions(+), 91 deletions(-) diff --git a/background/usercss-helper.js b/background/usercss-helper.js index e3d3d91f..e4c66d84 100644 --- a/background/usercss-helper.js +++ b/background/usercss-helper.js @@ -9,7 +9,6 @@ API_METHODS.buildUsercss = build; API_METHODS.openUsercssInstallPage = install; - API_METHODS.parseUsercss = parse; API_METHODS.findUsercss = find; const TEMP_CODE_PREFIX = 'tempUsercssCode'; diff --git a/edit/codemirror-default.js b/edit/codemirror-default.js index 274042fe..732e9a80 100644 --- a/edit/codemirror-default.js +++ b/edit/codemirror-default.js @@ -9,6 +9,7 @@ } const defaults = { + autocompleteOnTyping: prefs.get('editor.autocompleteOnTyping'), mode: 'css', lineNumbers: true, lineWrapping: prefs.get('editor.lineWrapping'), diff --git a/edit/codemirror-factory.js b/edit/codemirror-factory.js index 0150be5b..8c2346e8 100644 --- a/edit/codemirror-factory.js +++ b/edit/codemirror-factory.js @@ -10,90 +10,82 @@ const cmFactory = (() => { // used by `indentWithTabs` option const INSERT_TAB_COMMAND = CodeMirror.commands.insertTab; const INSERT_SOFT_TAB_COMMAND = CodeMirror.commands.insertSoftTab; - prefs.subscribe(null, onPrefChanged); - return {create, destroy, setOption}; - function onPrefChanged(key, value) { - let option = key.replace(/^editor\./, ''); + CodeMirror.defineOption('tabSize', (cm, value) => { + cm.setOption('indentUnit', Number(value)); + }); + + CodeMirror.defineOption('indentWithTabs', (cm, value) => { + CodeMirror.commands.insertTab = value ? + INSERT_TAB_COMMAND : + INSERT_SOFT_TAB_COMMAND; + }); + + CodeMirror.defineOption('autocompleteOnTyping', (cm, value) => { + const onOff = value ? 'on' : 'off'; + cm[onOff]('changes', autocompleteOnTyping); + cm[onOff]('pick', autocompletePicked); + }); + + CodeMirror.defineOption('matchHighlight', (cm, value) => { + if (value === 'token') { + cm.setOption('highlightSelectionMatches', { + showToken: /[#.\-\w]/, + annotateScrollbar: true + }); + } else if (value === 'selection') { + cm.setOption('highlightSelectionMatches', { + showToken: false, + annotateScrollbar: true + }); + } else { + cm.setOption('highlightSelectionMatches', null); + } + }); + + CodeMirror.defineOption('selectByTokens', (cm, value) => { + cm.setOption('configureMouse', value ? configureMouseFn : null); + }); + + prefs.subscribe(null, (key, value) => { + const option = key.replace(/^editor\./, ''); if (!option) { console.error('no "cm_option"', key); return; } - switch (option) { - case 'tabSize': - value = Number(value); - setOption('indentUnit', value); - break; - - case 'indentWithTabs': - CodeMirror.commands.insertTab = value ? - INSERT_TAB_COMMAND : - INSERT_SOFT_TAB_COMMAND; - break; - - case 'theme': { - const themeLink = $('#cm-theme'); - // use non-localized 'default' internally - if (!value || value === 'default' || value === t('defaultTheme')) { - value = 'default'; - if (prefs.get(key) !== value) { - prefs.set(key, value); - } - themeLink.href = ''; - $('#editor.theme').value = value; - break; - } - const url = chrome.runtime.getURL('vendor/codemirror/theme/' + value + '.css'); - if (themeLink.href === url) { - // preloaded in initCodeMirror() - break; - } - // avoid flicker: wait for the second stylesheet to load, then apply the theme - document.head.appendChild($create('link#cm-theme2', {rel: 'stylesheet', href: url})); - setTimeout(() => { - setOption(option, value); - themeLink.remove(); - $('#cm-theme2').id = 'cm-theme'; - }, 100); - return; - } - - case 'autocompleteOnTyping': - for (const cm of editors) { - setupAutocomplete(cm, value); - } - return; - - case 'autoCloseBrackets': - Promise.resolve(value && loadScript('/vendor/codemirror/addon/edit/closebrackets.js')).then(() => { - setOption(option, value); - }); - return; - - case 'matchHighlight': - switch (value) { - case 'token': - case 'selection': - document.body.dataset[option] = value; - value = {showToken: value === 'token' && /[#.\-\w]/, annotateScrollbar: true}; - break; - default: - value = null; - } - option = 'highlightSelectionMatches'; - break; - - case 'colorpicker': - // FIXME: this is implemented in `colorpicker-helper.js`. - return; - - case 'selectByTokens': - option = 'configureMouse'; - value = value ? configureMouseFn : null; - break; + // FIXME: this is implemented in `colorpicker-helper.js`. + if (option === 'colorpicker') { + return; } + // FIXME: is this an overhead? + if (option === 'autoCloseBrackets' && value) { + loadScript('/vendor/codemirror/addon/edit/closebrackets.js'); + } + if (option === 'theme') { + const themeLink = $('#cm-theme'); + // use non-localized 'default' internally + if (value === 'default') { + themeLink.href = ''; + } else { + const url = chrome.runtime.getURL('vendor/codemirror/theme/' + value + '.css'); + if (themeLink.href !== url) { + // avoid flicker: wait for the second stylesheet to load, then apply the theme + return loadScript(url).then(([newThemeLink]) => { + setOption(option, value); + themeLink.remove(); + newThemeLink.id = 'cm-theme'; + // already loaded but is removed. + if (!newThemeLink.parentNode) { + document.head.appendChild(newThemeLink); + } + }); + } + } + } + // broadcast option setOption(option, value); - } + }); + return {create, destroy, setOption}; function configureMouseFn(cm, repeat) { return repeat === 'double' ? @@ -152,12 +144,6 @@ const cmFactory = (() => { }; } - function setupAutocomplete(cm, enable = true) { - const onOff = enable ? 'on' : 'off'; - cm[onOff]('changes', autocompleteOnTyping); - cm[onOff]('pick', autocompletePicked); - } - function autocompleteOnTyping(cm, [info], debounced) { if ( cm.state.completionActive || @@ -194,9 +180,6 @@ const cmFactory = (() => { function create(init, options) { const cm = CodeMirror(init, options); - if (prefs.get('editor.autocompleteOnTyping')) { - setupAutocomplete(cm); - } cm.lastActive = 0; const wrapper = cm.display.wrapper; cm.on('blur', () => { diff --git a/edit/source-editor.js b/edit/source-editor.js index baaa22b1..b6abbec2 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -2,8 +2,6 @@ global CodeMirror dirtyReporter global createAppliesToLineWidget messageBox global sectionsToMozFormat -global exclusions -global beforeUnload global createMetaCompiler linter createLivePreview cmFactory */ 'use strict'; @@ -402,6 +400,7 @@ function createSourceEditor(style) { toggleStyle, prevEditor: cm => nextPrevMozDocument(cm, -1), nextEditor: cm => nextPrevMozDocument(cm, 1), - closestVisible: () => cm + closestVisible: () => cm, + getSearchableInputs: () => [] }; } diff --git a/js/script-loader.js b/js/script-loader.js index c2f0ca04..a017ea02 100644 --- a/js/script-loader.js +++ b/js/script-loader.js @@ -26,7 +26,7 @@ var loadScript = (() => { el.onload = () => { el.onload = null; el.onerror = null; - resolve(); + resolve(el); }; el.onerror = () => { el.onload = null;