WIP: kill getSection
This commit is contained in:
parent
ba6159e067
commit
15a1f552f6
|
@ -1,4 +1,4 @@
|
|||
/* global CodeMirror prefs loadScript editor editors */
|
||||
/* global CodeMirror prefs loadScript editor */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user