Fix: switch to editor

This commit is contained in:
eight 2018-10-10 00:41:07 +08:00
parent 06e22d0d18
commit fd9ab5d6e5
11 changed files with 45 additions and 40 deletions

View File

@ -72,7 +72,7 @@ API_METHODS.styleViaAPI = !CHROME && (() => {
}); });
} }
function styleDeleted({id}, {tab, frameId}) { function styleDeleted({style: {id}}, {tab, frameId}) {
const {tabFrames, frameStyles, styleSections} = getCachedData(tab.id, frameId, id); const {tabFrames, frameStyles, styleSections} = getCachedData(tab.id, frameId, id);
const code = styleSections.join('\n'); const code = styleSections.join('\n');
if (code && !duplicateCodeExists({frameStyles, id, code})) { if (code && !duplicateCodeExists({frameStyles, id, code})) {
@ -86,7 +86,7 @@ API_METHODS.styleViaAPI = !CHROME && (() => {
function styleUpdated({style}, sender) { function styleUpdated({style}, sender) {
if (!style.enabled) { if (!style.enabled) {
return styleDeleted(style, sender); return styleDeleted({style}, sender);
} }
const {tab, frameId} = sender; const {tab, frameId} = sender;
const {frameStyles, styleSections} = getCachedData(tab.id, frameId, style.id); const {frameStyles, styleSections} = getCachedData(tab.id, frameId, style.id);

View File

@ -102,7 +102,7 @@
switch (request.method) { switch (request.method) {
case 'styleDeleted': case 'styleDeleted':
removeStyle(request); removeStyle(request.style);
break; break;
case 'styleUpdated': case 'styleUpdated':

View File

@ -35,7 +35,7 @@
<script src="edit/source-editor.js"></script> <script src="edit/source-editor.js"></script>
<script src="edit/colorpicker-helper.js"></script> <script src="edit/colorpicker-helper.js"></script>
<script src="edit/beautify.js"></script> <script src="edit/beautify.js"></script>
<script src="edit/sections.js"></script> <script src="edit/sections-editor.js"></script>
<script src="edit/show-keymap-help.js"></script> <script src="edit/show-keymap-help.js"></script>
<script src="edit/codemirror-editing-hooks.js"></script> <script src="edit/codemirror-editing-hooks.js"></script>
<script src="edit/edit.js"></script> <script src="edit/edit.js"></script>

View File

@ -47,7 +47,6 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
const wrapper = cm.display.wrapper; const wrapper = cm.display.wrapper;
cm.on('blur', () => { cm.on('blur', () => {
editors.lastActive = cm;
cm.rerouteHotkeys(true); cm.rerouteHotkeys(true);
setTimeout(() => { setTimeout(() => {
wrapper.classList.toggle('CodeMirror-active', wrapper.contains(document.activeElement)); wrapper.classList.toggle('CodeMirror-active', wrapper.contains(document.activeElement));
@ -89,6 +88,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
function setOption(o, v) { function setOption(o, v) {
CodeMirror.defaults[o] = v; CodeMirror.defaults[o] = v;
const editors = editor.getEditors();
if (editors.length > 4 && (o === 'theme' || o === 'lineWrapping')) { if (editors.length > 4 && (o === 'theme' || o === 'lineWrapping')) {
throttleSetOption({key: o, value: v, index: 0}); throttleSetOption({key: o, value: v, index: 0});
return; return;
@ -103,8 +103,8 @@ onDOMscriptReady('/codemirror.js').then(() => {
value, value,
index, index,
timeStart = performance.now(), timeStart = performance.now(),
cmStart = editors.lastActive || editors[0], cmStart = editor.getLastActivatedEditor(),
editorsCopy = editors.slice(), editorsCopy = editor.getEditors().slice(),
progress, progress,
}) { }) {
if (index === 0) { if (index === 0) {
@ -119,6 +119,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
const t0 = performance.now(); const t0 = performance.now();
const total = editorsCopy.length; const total = editorsCopy.length;
const editors = editor.getEditors();
while (index < total) { while (index < total) {
const cm = editorsCopy[index++]; const cm = editorsCopy[index++];
if (cm === cmStart || if (cm === cmStart ||
@ -185,7 +186,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
function nextPrevEditor(cm, direction) { function nextPrevEditor(cm, direction) {
const editors = style.getEditors(); const editors = editor.getEditors();
cm = editors[(editors.indexOf(cm) + direction + editors.length) % editors.length]; cm = editors[(editors.indexOf(cm) + direction + editors.length) % editors.length];
editor.scrollToEditor(cm); editor.scrollToEditor(cm);
cm.focus(); cm.focus();
@ -277,7 +278,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
case 'autocompleteOnTyping': case 'autocompleteOnTyping':
editors.forEach(cm => setupAutocomplete(cm, el.checked)); editor.getEditors().forEach(cm => setupAutocomplete(cm, el.checked));
return; return;
case 'autoCloseBrackets': case 'autoCloseBrackets':
@ -412,7 +413,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
} }
// closest editor should have at least 2 lines visible // closest editor should have at least 2 lines visible
const lineHeight = editors[0].defaultTextHeight(); const lineHeight = editor.getEditors()[0].defaultTextHeight();
const scrollY = window.scrollY; const scrollY = window.scrollY;
const windowBottom = scrollY + window.innerHeight - 2 * lineHeight; const windowBottom = scrollY + window.innerHeight - 2 * lineHeight;
const allSectionsContainerTop = scrollY + $('#sections').getBoundingClientRect().top; const allSectionsContainerTop = scrollY + $('#sections').getBoundingClientRect().top;
@ -424,7 +425,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
if (index >= 0 && distances[index] !== undefined) { if (index >= 0 && distances[index] !== undefined) {
return distances[index]; return distances[index];
} }
const section = (cm || editors[index]).getSection(); const section = cm.display.wrapper.closest('.section');
if (!section) { if (!section) {
return 1e9; return 1e9;
} }
@ -443,6 +444,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
} }
function findClosest() { function findClosest() {
const editors = editor.getEditors();
const last = editors.length - 1; const last = editors.length - 1;
let a = 0; let a = 0;
let b = last; let b = last;

View File

@ -7,7 +7,7 @@ global beautify
global initWithSectionStyle addSections removeSection getSectionsHashes global initWithSectionStyle addSections removeSection getSectionsHashes
global sectionsToMozFormat global sectionsToMozFormat
global exclusions global exclusions
global moveFocus editorWorker msg global moveFocus editorWorker msg createSectionEditor
*/ */
'use strict'; 'use strict';
@ -35,17 +35,16 @@ Promise.all([
]) ])
.then(([style]) => { .then(([style]) => {
const usercss = isUsercss(style); const usercss = isUsercss(style);
$('#heading').textContent = t(styleId ? 'editStyleHeading' : 'addStyleTitle'); $('#heading').textContent = t(style.id ? 'editStyleHeading' : 'addStyleTitle');
$('#name').placeholder = t(usercss ? 'usercssEditorNamePlaceholder' : 'styleMissingName'); $('#name').placeholder = t(usercss ? 'usercssEditorNamePlaceholder' : 'styleMissingName');
$('#name').title = usercss ? t('usercssReplaceTemplateName') : ''; $('#name').title = usercss ? t('usercssReplaceTemplateName') : '';
$('#preview-label').classList.toggle('hidden', !styleId); $('#preview-label').classList.toggle('hidden', !style.id);
$('#beautify').onclick = () => beautify(editor.getEditors()); $('#beautify').onclick = () => beautify(editor.getEditors());
$('#lint').addEventListener('scroll', hideLintHeaderOnScroll, {passive: true}); $('#lint').addEventListener('scroll', hideLintHeaderOnScroll, {passive: true});
window.addEventListener('resize', () => debounce(rememberWindowSize, 100)); window.addEventListener('resize', () => debounce(rememberWindowSize, 100));
exclusions.init(style);
editor = usercss ? createSourceEditor(style) : createSectionEditor(style); editor = usercss ? createSourceEditor(style) : createSectionEditor(style);
}); });
@ -152,7 +151,7 @@ function preinit() {
function onRuntimeMessage(request) { function onRuntimeMessage(request) {
switch (request.method) { switch (request.method) {
case 'styleUpdated': case 'styleUpdated':
if (styleId && styleId === request.style.id && if (editor.getStyleId() === request.style.id &&
request.reason !== 'editPreview' && request.reason !== 'editPreview' &&
request.reason !== 'editSave' && request.reason !== 'editSave' &&
request.reason !== 'config') { request.reason !== 'config') {
@ -167,7 +166,7 @@ function onRuntimeMessage(request) {
} }
break; break;
case 'styleDeleted': case 'styleDeleted':
if (styleId === request.id || editor && editor.getStyle().id === request.id) { if (editor.getStyleId() === request.style.id) {
document.removeEventListener('visibilitychange', beforeUnload); document.removeEventListener('visibilitychange', beforeUnload);
window.onbeforeunload = null; window.onbeforeunload = null;
closeCurrentTab(); closeCurrentTab();
@ -235,15 +234,14 @@ function initStyleData() {
}); });
return fetchStyle() return fetchStyle()
.then(style => { .then(style => {
styleId = style.id; if (style.id) sessionStorage.justEditedStyleId = style.id;
if (styleId) sessionStorage.justEditedStyleId = styleId;
// we set "usercss" class on <html> when <body> is empty // we set "usercss" class on <html> when <body> is empty
// so there'll be no flickering of the elements that depend on it // so there'll be no flickering of the elements that depend on it
if (isUsercss(style)) { if (isUsercss(style)) {
document.documentElement.classList.add('usercss'); document.documentElement.classList.add('usercss');
} }
// strip URL parameters when invoked for a non-existent id // strip URL parameters when invoked for a non-existent id
if (!styleId) { if (!style.id) {
history.replaceState({}, document.title, location.pathname); history.replaceState({}, document.title, location.pathname);
} }
return style; return style;

View File

@ -1,6 +1,6 @@
/* global CodeMirror editors makeSectionVisible */ /* global CodeMirror editors makeSectionVisible */
/* global focusAccessibility */ /* global focusAccessibility */
/* global colorMimicry */ /* global colorMimicry editor */
'use strict'; 'use strict';
onDOMready().then(() => { onDOMready().then(() => {

View File

@ -1,4 +1,4 @@
/* global linter editors clipString createLinterHelpDialog makeSectionVisible */ /* global linter editor clipString createLinterHelpDialog makeSectionVisible */
'use strict'; 'use strict';
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
@ -16,12 +16,8 @@ Object.assign(linter, (() => {
table = createTable(cm); table = createTable(cm);
tables.set(cm, table); tables.set(cm, table);
const container = $('.lint-report-container'); const container = $('.lint-report-container');
if (typeof editor === 'object') { const nextSibling = findNextSibling(tables, cm);
container.append(table.element); container.insertBefore(table.element, nextSibling && tables.get(nextSibling).element);
} else {
const nextSibling = findNextSibling(tables, cm);
container.insertBefore(table.element, nextSibling && tables.get(nextSibling).element);
}
} }
table.updateCaption(); table.updateCaption();
table.updateAnnotations(annotations); table.updateAnnotations(annotations);
@ -57,6 +53,7 @@ Object.assign(linter, (() => {
} }
function findNextSibling(tables, cm) { function findNextSibling(tables, cm) {
const editors = editor.getEditors();
let i = editors.indexOf(cm) + 1; let i = editors.indexOf(cm) + 1;
while (i < editors.length) { while (i < editors.length) {
if (tables.has(editors[i])) { if (tables.has(editors[i])) {
@ -85,8 +82,7 @@ Object.assign(linter, (() => {
}; };
function updateCaption() { function updateCaption() {
caption.textContent = typeof editor === 'object' ? caption.textContent = editor.getEditorTitle(cm);
'' : `${t('sectionCode')} ${editors.indexOf(cm) + 1}`;
} }
function updateAnnotations(lines) { function updateAnnotations(lines) {

View File

@ -1,7 +1,8 @@
/* global dirtyReporter showToMozillaHelp /* global dirtyReporter showToMozillaHelp
showSectionHelp toggleContextMenuDelete setGlobalProgress maximizeCodeHeight showSectionHelp toggleContextMenuDelete setGlobalProgress maximizeCodeHeight
CodeMirror nextPrevEditorOnKeydown showAppliesToHelp propertyToCss CodeMirror nextPrevEditorOnKeydown showAppliesToHelp propertyToCss
regExpTester linter cssToProperty regExpTester linter cssToProperty createLivePreview showCodeMirrorPopup
sectionsToMozFormat editorWorker messageBox clipString beautify
*/ */
'use strict'; 'use strict';
@ -131,7 +132,12 @@ function createSectionsEditor(style) {
getEditors: () => getEditors: () =>
sections.filter(s => !s.isRemoved()).map(s => s.cm), sections.filter(s => !s.isRemoved()).map(s => s.cm),
getLastActivatedEditor, getLastActivatedEditor,
scrollToEditor scrollToEditor,
getStyleId: () => style.id,
getEditorTitle: cm => {
const index = sections.filter(s => !s.isRemoved()).findIndex(s => s.cm === cm) + 1;
return `${t('sectionCode')} ${index + 1}`;
}
}; };
function scrollToEditor(cm) { function scrollToEditor(cm) {
@ -177,7 +183,7 @@ function createSectionsEditor(style) {
// fallthrough to arrow Up // fallthrough to arrow Up
case 38: case 38:
// arrow Up // arrow Up
if (line > 0 || cm === editors[0]) { if (line > 0 || cm === sections[0].cm) {
return; return;
} }
event.preventDefault(); event.preventDefault();
@ -193,7 +199,7 @@ function createSectionsEditor(style) {
// fallthrough to arrow Down // fallthrough to arrow Down
case 40: case 40:
// arrow Down // arrow Down
if (line < cm.doc.size - 1 || cm === editors.last) { if (line < cm.doc.size - 1 || cm === sections[sections.length - 1].cm) {
return; return;
} }
event.preventDefault(); event.preventDefault();
@ -331,7 +337,7 @@ function createSectionsEditor(style) {
return true; return true;
} }
function save() { function saveStyle() {
const newStyle = getModel(); const newStyle = getModel();
if (!validate(newStyle)) { if (!validate(newStyle)) {
return; return;
@ -507,7 +513,6 @@ function createSectionsEditor(style) {
el, el,
cm, cm,
render, render,
destroy,
getCode, getCode,
getModel, getModel,
remove, remove,
@ -580,7 +585,9 @@ function createSectionsEditor(style) {
if (!FIREFOX) { if (!FIREFOX) {
cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event)); cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event));
} }
cm.on('focus', () => lastActive = Date.now()); cm.on('focus', () => {
lastActive = Date.now();
});
cm.display.wrapper.addEventListener('keydown', event => cm.display.wrapper.addEventListener('keydown', event =>
nextPrevEditorOnKeydown(cm, event), true); nextPrevEditorOnKeydown(cm, event), true);

View File

@ -407,6 +407,8 @@ function createSourceEditor(style) {
getStyle: () => style, getStyle: () => style,
getEditors: () => [cm], getEditors: () => [cm],
getLastActivatedEditor: () => cm, getLastActivatedEditor: () => cm,
scrollToEditor: () => {} scrollToEditor: () => {},
getStyleId: () => style.id,
getEditorTitle: () => ''
}; };
} }

View File

@ -48,7 +48,7 @@ function onRuntimeMessage(msg) {
handleUpdate(msg.style, msg); handleUpdate(msg.style, msg);
break; break;
case 'styleDeleted': case 'styleDeleted':
handleDelete(msg.id); handleDelete(msg.style.id);
break; break;
case 'styleApply': case 'styleApply':
case 'styleReplaceAll': case 'styleReplaceAll':

View File

@ -37,7 +37,7 @@ function onRuntimeMessage(msg) {
handleUpdate(msg.style); handleUpdate(msg.style);
break; break;
case 'styleDeleted': case 'styleDeleted':
handleDelete(msg.id); handleDelete(msg.style.id);
break; break;
case 'prefChanged': case 'prefChanged':
if ('popup.stylesFirst' in msg.prefs) { if ('popup.stylesFirst' in msg.prefs) {