WIP: kill getSection

This commit is contained in:
eight 2018-10-10 12:08:35 +08:00
parent ba6159e067
commit 15a1f552f6
6 changed files with 107 additions and 106 deletions

View File

@ -1,4 +1,4 @@
/* global CodeMirror prefs loadScript editor editors */
/* global CodeMirror prefs loadScript editor */
'use strict';

View File

@ -27,13 +27,8 @@ onDOMscriptReady('/codemirror.js').then(() => {
'find', 'findNext', 'findPrev', 'replace', 'replaceAll',
'colorpicker',
]);
Object.assign(CodeMirror, {
getOption,
setOption,
closestVisible,
});
Object.assign(CodeMirror.prototype, {
getSection,
// getSection,
rerouteHotkeys,
});
Object.assign(CodeMirror.commands, COMMANDS);
@ -256,6 +251,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
case 'autocompleteOnTyping':
if (editor) {
// FIXME: this won't work with removed sections
editor.getEditors().forEach(cm => setupAutocomplete(cm, value));
}
return;
@ -304,7 +300,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
}
const rerouteCommand = name => {
if (REROUTED.has(name)) {
CodeMirror.commands[name](closestVisible(event.target));
CodeMirror.commands[name](editor.closestVisible(event.target));
return true;
}
};
@ -317,87 +313,6 @@ onDOMscriptReady('/codemirror.js').then(() => {
////////////////////////////////////////////////
// priority:
// 1. associated CM for applies-to element
// 2. last active if visible
// 3. first visible
function closestVisible(nearbyElement) {
const cm =
nearbyElement instanceof CodeMirror ? nearbyElement :
nearbyElement instanceof Node &&
(nearbyElement.closest('#sections > .section') || {}).CodeMirror ||
editor.getLastActivatedEditor();
if (nearbyElement instanceof Node && cm) {
const {left, top} = nearbyElement.getBoundingClientRect();
const bounds = cm.display.wrapper.getBoundingClientRect();
if (top >= 0 && top >= bounds.top &&
left >= 0 && left >= bounds.left) {
return cm;
}
}
// closest editor should have at least 2 lines visible
const lineHeight = editor.getEditors()[0].defaultTextHeight();
const scrollY = window.scrollY;
const windowBottom = scrollY + window.innerHeight - 2 * lineHeight;
const allSectionsContainerTop = scrollY + $('#sections').getBoundingClientRect().top;
const distances = [];
const alreadyInView = cm && offscreenDistance(null, cm) === 0;
return alreadyInView ? cm : findClosest();
function offscreenDistance(index, cm) {
if (index >= 0 && distances[index] !== undefined) {
return distances[index];
}
const section = cm.display.wrapper.closest('.section');
if (!section) {
return 1e9;
}
const top = allSectionsContainerTop + section.offsetTop;
if (top < scrollY + lineHeight) {
return Math.max(0, scrollY - top - lineHeight);
}
if (top < windowBottom) {
return 0;
}
const distance = top - windowBottom + section.offsetHeight;
if (index >= 0) {
distances[index] = distance;
}
return distance;
}
function findClosest() {
const editors = editor.getEditors();
const last = editors.length - 1;
let a = 0;
let b = last;
let c;
let distance;
while (a < b - 1) {
c = (a + b) / 2 | 0;
distance = offscreenDistance(c);
if (!distance || !c) {
break;
}
const distancePrev = offscreenDistance(c - 1);
const distanceNext = c < last ? offscreenDistance(c + 1) : 1e20;
if (distancePrev <= distance && distance <= distanceNext) {
b = c;
} else {
a = c;
}
}
while (b && offscreenDistance(b - 1) <= offscreenDistance(b)) {
b--;
}
const cm = editors[b];
if (distances[b] > 0) {
editor.scrollToEditor(cm);
}
return cm;
}
}
////////////////////////////////////////////////
function setupAutocomplete(cm, enable = true) {

View File

@ -4,9 +4,7 @@ global createSourceEditor
global closeCurrentTab regExpTester messageBox
global setupCodeMirror
global beautify
global initWithSectionStyle addSections removeSection getSectionsHashes
global sectionsToMozFormat
global exclusions
global moveFocus editorWorker msg createSectionEditor
*/
'use strict';

View File

@ -1,4 +1,4 @@
/* global CodeMirror editors makeSectionVisible */
/* global CodeMirror */
/* global focusAccessibility */
/* global colorMimicry editor */
'use strict';
@ -207,7 +207,7 @@ onDOMready().then(() => {
}
const cmFocused = document.activeElement && document.activeElement.closest('.CodeMirror');
state.activeAppliesTo = $(`.${APPLIES_VALUE_CLASS}:focus, .${APPLIES_VALUE_CLASS}.${TARGET_CLASS}`);
state.cmStart = CodeMirror.closestVisible(
state.cmStart = editor.closestVisible(
cmFocused && document.activeElement ||
state.activeAppliesTo ||
state.cm);
@ -291,7 +291,7 @@ onDOMready().then(() => {
function doSearchInApplies(cm, canAdvance) {
if (!state.searchInApplies) return;
const inputs = [...cm.getSection().getElementsByClassName(APPLIES_VALUE_CLASS)];
const inputs = editor.getSearchableInputs(cm);
if (state.reverse) inputs.reverse();
inputs.splice(0, inputs.indexOf(state.activeAppliesTo));
for (const input of inputs) {

View File

@ -61,10 +61,11 @@ function createResizeGrip(cm) {
const allBounds = $('#sections').getBoundingClientRect();
const pageExtrasHeight = allBounds.top + window.scrollY +
parseFloat(getComputedStyle($('#sections')).paddingBottom);
const sectionExtrasHeight = cm.getSection().clientHeight - wrapper.offsetHeight;
const sectionEl = wrapper.parentNode;
const sectionExtrasHeight = sectionEl.clientHeight - wrapper.offsetHeight;
cm.state.toggleHeightSaved = wrapper.clientHeight;
cm.setSize(null, window.innerHeight - sectionExtrasHeight - pageExtrasHeight);
const bounds = cm.getSection().getBoundingClientRect();
const bounds = sectionEl.getBoundingClientRect();
if (bounds.top < 0 || bounds.bottom > window.innerHeight) {
window.scrollBy(0, bounds.top);
}
@ -143,9 +144,96 @@ function createSectionsEditor(style) {
save: saveStyle,
toggleStyle,
nextEditor,
prevEditor
prevEditor,
closestVisible,
getSearchableInputs,
};
function getSearchableInputs(cm) {
return sections.find(s => s.cm === cm).appliesTo.map(a => a.valueEl).filter(Boolean);
}
// priority:
// 1. associated CM for applies-to element
// 2. last active if visible
// 3. first visible
function closestVisible(nearbyElement) {
const cm =
nearbyElement instanceof CodeMirror ? nearbyElement :
nearbyElement instanceof Node &&
(nearbyElement.closest('#sections > .section') || {}).CodeMirror ||
editor.getLastActivatedEditor();
if (nearbyElement instanceof Node && cm) {
const {left, top} = nearbyElement.getBoundingClientRect();
const bounds = cm.display.wrapper.getBoundingClientRect();
if (top >= 0 && top >= bounds.top &&
left >= 0 && left >= bounds.left) {
return cm;
}
}
// closest editor should have at least 2 lines visible
const lineHeight = editor.getEditors()[0].defaultTextHeight();
const scrollY = window.scrollY;
const windowBottom = scrollY + window.innerHeight - 2 * lineHeight;
const allSectionsContainerTop = scrollY + $('#sections').getBoundingClientRect().top;
const distances = [];
const alreadyInView = cm && offscreenDistance(null, cm) === 0;
return alreadyInView ? cm : findClosest();
function offscreenDistance(index, cm) {
if (index >= 0 && distances[index] !== undefined) {
return distances[index];
}
const section = cm.display.wrapper.closest('.section');
if (!section) {
return 1e9;
}
const top = allSectionsContainerTop + section.offsetTop;
if (top < scrollY + lineHeight) {
return Math.max(0, scrollY - top - lineHeight);
}
if (top < windowBottom) {
return 0;
}
const distance = top - windowBottom + section.offsetHeight;
if (index >= 0) {
distances[index] = distance;
}
return distance;
}
function findClosest() {
const editors = editor.getEditors();
const last = editors.length - 1;
let a = 0;
let b = last;
let c;
let distance;
while (a < b - 1) {
c = (a + b) / 2 | 0;
distance = offscreenDistance(c);
if (!distance || !c) {
break;
}
const distancePrev = offscreenDistance(c - 1);
const distanceNext = c < last ? offscreenDistance(c + 1) : 1e20;
if (distancePrev <= distance && distance <= distanceNext) {
b = c;
} else {
a = c;
}
}
while (b && offscreenDistance(b - 1) <= offscreenDistance(b)) {
b--;
}
const cm = editors[b];
if (distances[b] > 0) {
editor.scrollToEditor(cm);
}
return cm;
}
}
function getEditors() {
return sections.filter(s => !s.isRemoved()).map(s => s.cm);
}
@ -241,12 +329,13 @@ function createSectionsEditor(style) {
cm.setCursor(0, 0);
break;
}
const animation = (cm.getSection().firstElementChild.getAnimations() || [])[0];
if (animation) {
animation.playbackRate = -1;
animation.currentTime = 2000;
animation.play();
}
// FIXME: what is this?
// const animation = (cm.getSection().firstElementChild.getAnimations() || [])[0];
// if (animation) {
// animation.playbackRate = -1;
// animation.currentTime = 2000;
// animation.play();
// }
}
function scrollEntirePageOnCtrlShift(event) {

View File

@ -52,8 +52,6 @@ function createSourceEditor(style) {
updateLivePreview();
});
CodeMirror.closestVisible = () => cm;
cm.operation(initAppliesToLineWidget);
const metaCompiler = createMetaCompiler(cm);
@ -409,6 +407,7 @@ function createSourceEditor(style) {
save,
toggleStyle,
prevEditor: cm => nextPrevMozDocument(cm, -1),
nextEditor: cm => nextPrevMozDocument(cm, 1)
nextEditor: cm => nextPrevMozDocument(cm, 1),
closestVisible: () => cm
};
}