Refactor: use CodeMirror.defineOption

This commit is contained in:
eight 2018-10-10 17:40:07 +08:00
parent 4419c5dc1e
commit c23f315c52
5 changed files with 73 additions and 91 deletions

View File

@ -9,7 +9,6 @@
API_METHODS.buildUsercss = build; API_METHODS.buildUsercss = build;
API_METHODS.openUsercssInstallPage = install; API_METHODS.openUsercssInstallPage = install;
API_METHODS.parseUsercss = parse;
API_METHODS.findUsercss = find; API_METHODS.findUsercss = find;
const TEMP_CODE_PREFIX = 'tempUsercssCode'; const TEMP_CODE_PREFIX = 'tempUsercssCode';

View File

@ -9,6 +9,7 @@
} }
const defaults = { const defaults = {
autocompleteOnTyping: prefs.get('editor.autocompleteOnTyping'),
mode: 'css', mode: 'css',
lineNumbers: true, lineNumbers: true,
lineWrapping: prefs.get('editor.lineWrapping'), lineWrapping: prefs.get('editor.lineWrapping'),

View File

@ -10,90 +10,82 @@ const cmFactory = (() => {
// used by `indentWithTabs` option // used by `indentWithTabs` option
const INSERT_TAB_COMMAND = CodeMirror.commands.insertTab; const INSERT_TAB_COMMAND = CodeMirror.commands.insertTab;
const INSERT_SOFT_TAB_COMMAND = CodeMirror.commands.insertSoftTab; const INSERT_SOFT_TAB_COMMAND = CodeMirror.commands.insertSoftTab;
prefs.subscribe(null, onPrefChanged);
return {create, destroy, setOption};
function onPrefChanged(key, value) { CodeMirror.defineOption('tabSize', (cm, value) => {
let option = key.replace(/^editor\./, ''); 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) { if (!option) {
console.error('no "cm_option"', key); console.error('no "cm_option"', key);
return; return;
} }
switch (option) { // FIXME: this is implemented in `colorpicker-helper.js`.
case 'tabSize': if (option === 'colorpicker') {
value = Number(value); return;
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: 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); setOption(option, value);
} });
return {create, destroy, setOption};
function configureMouseFn(cm, repeat) { function configureMouseFn(cm, repeat) {
return repeat === 'double' ? 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) { function autocompleteOnTyping(cm, [info], debounced) {
if ( if (
cm.state.completionActive || cm.state.completionActive ||
@ -194,9 +180,6 @@ const cmFactory = (() => {
function create(init, options) { function create(init, options) {
const cm = CodeMirror(init, options); const cm = CodeMirror(init, options);
if (prefs.get('editor.autocompleteOnTyping')) {
setupAutocomplete(cm);
}
cm.lastActive = 0; cm.lastActive = 0;
const wrapper = cm.display.wrapper; const wrapper = cm.display.wrapper;
cm.on('blur', () => { cm.on('blur', () => {

View File

@ -2,8 +2,6 @@
global CodeMirror dirtyReporter global CodeMirror dirtyReporter
global createAppliesToLineWidget messageBox global createAppliesToLineWidget messageBox
global sectionsToMozFormat global sectionsToMozFormat
global exclusions
global beforeUnload
global createMetaCompiler linter createLivePreview cmFactory global createMetaCompiler linter createLivePreview cmFactory
*/ */
'use strict'; 'use strict';
@ -402,6 +400,7 @@ function createSourceEditor(style) {
toggleStyle, toggleStyle,
prevEditor: cm => nextPrevMozDocument(cm, -1), prevEditor: cm => nextPrevMozDocument(cm, -1),
nextEditor: cm => nextPrevMozDocument(cm, 1), nextEditor: cm => nextPrevMozDocument(cm, 1),
closestVisible: () => cm closestVisible: () => cm,
getSearchableInputs: () => []
}; };
} }

View File

@ -26,7 +26,7 @@ var loadScript = (() => {
el.onload = () => { el.onload = () => {
el.onload = null; el.onload = null;
el.onerror = null; el.onerror = null;
resolve(); resolve(el);
}; };
el.onerror = () => { el.onerror = () => {
el.onload = null; el.onload = null;