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';
|
'use strict';
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,8 @@ onDOMscriptReady('/codemirror.js').then(() => {
|
||||||
'find', 'findNext', 'findPrev', 'replace', 'replaceAll',
|
'find', 'findNext', 'findPrev', 'replace', 'replaceAll',
|
||||||
'colorpicker',
|
'colorpicker',
|
||||||
]);
|
]);
|
||||||
Object.assign(CodeMirror, {
|
|
||||||
getOption,
|
|
||||||
setOption,
|
|
||||||
closestVisible,
|
|
||||||
});
|
|
||||||
Object.assign(CodeMirror.prototype, {
|
Object.assign(CodeMirror.prototype, {
|
||||||
getSection,
|
// getSection,
|
||||||
rerouteHotkeys,
|
rerouteHotkeys,
|
||||||
});
|
});
|
||||||
Object.assign(CodeMirror.commands, COMMANDS);
|
Object.assign(CodeMirror.commands, COMMANDS);
|
||||||
|
@ -256,6 +251,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
|
||||||
|
|
||||||
case 'autocompleteOnTyping':
|
case 'autocompleteOnTyping':
|
||||||
if (editor) {
|
if (editor) {
|
||||||
|
// FIXME: this won't work with removed sections
|
||||||
editor.getEditors().forEach(cm => setupAutocomplete(cm, value));
|
editor.getEditors().forEach(cm => setupAutocomplete(cm, value));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -304,7 +300,7 @@ onDOMscriptReady('/codemirror.js').then(() => {
|
||||||
}
|
}
|
||||||
const rerouteCommand = name => {
|
const rerouteCommand = name => {
|
||||||
if (REROUTED.has(name)) {
|
if (REROUTED.has(name)) {
|
||||||
CodeMirror.commands[name](closestVisible(event.target));
|
CodeMirror.commands[name](editor.closestVisible(event.target));
|
||||||
return true;
|
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) {
|
function setupAutocomplete(cm, enable = true) {
|
||||||
|
|
|
@ -4,9 +4,7 @@ global createSourceEditor
|
||||||
global closeCurrentTab regExpTester messageBox
|
global closeCurrentTab regExpTester messageBox
|
||||||
global setupCodeMirror
|
global setupCodeMirror
|
||||||
global beautify
|
global beautify
|
||||||
global initWithSectionStyle addSections removeSection getSectionsHashes
|
|
||||||
global sectionsToMozFormat
|
global sectionsToMozFormat
|
||||||
global exclusions
|
|
||||||
global moveFocus editorWorker msg createSectionEditor
|
global moveFocus editorWorker msg createSectionEditor
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global CodeMirror editors makeSectionVisible */
|
/* global CodeMirror */
|
||||||
/* global focusAccessibility */
|
/* global focusAccessibility */
|
||||||
/* global colorMimicry editor */
|
/* global colorMimicry editor */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -207,7 +207,7 @@ onDOMready().then(() => {
|
||||||
}
|
}
|
||||||
const cmFocused = document.activeElement && document.activeElement.closest('.CodeMirror');
|
const cmFocused = document.activeElement && document.activeElement.closest('.CodeMirror');
|
||||||
state.activeAppliesTo = $(`.${APPLIES_VALUE_CLASS}:focus, .${APPLIES_VALUE_CLASS}.${TARGET_CLASS}`);
|
state.activeAppliesTo = $(`.${APPLIES_VALUE_CLASS}:focus, .${APPLIES_VALUE_CLASS}.${TARGET_CLASS}`);
|
||||||
state.cmStart = CodeMirror.closestVisible(
|
state.cmStart = editor.closestVisible(
|
||||||
cmFocused && document.activeElement ||
|
cmFocused && document.activeElement ||
|
||||||
state.activeAppliesTo ||
|
state.activeAppliesTo ||
|
||||||
state.cm);
|
state.cm);
|
||||||
|
@ -291,7 +291,7 @@ onDOMready().then(() => {
|
||||||
|
|
||||||
function doSearchInApplies(cm, canAdvance) {
|
function doSearchInApplies(cm, canAdvance) {
|
||||||
if (!state.searchInApplies) return;
|
if (!state.searchInApplies) return;
|
||||||
const inputs = [...cm.getSection().getElementsByClassName(APPLIES_VALUE_CLASS)];
|
const inputs = editor.getSearchableInputs(cm);
|
||||||
if (state.reverse) inputs.reverse();
|
if (state.reverse) inputs.reverse();
|
||||||
inputs.splice(0, inputs.indexOf(state.activeAppliesTo));
|
inputs.splice(0, inputs.indexOf(state.activeAppliesTo));
|
||||||
for (const input of inputs) {
|
for (const input of inputs) {
|
||||||
|
|
|
@ -61,10 +61,11 @@ function createResizeGrip(cm) {
|
||||||
const allBounds = $('#sections').getBoundingClientRect();
|
const allBounds = $('#sections').getBoundingClientRect();
|
||||||
const pageExtrasHeight = allBounds.top + window.scrollY +
|
const pageExtrasHeight = allBounds.top + window.scrollY +
|
||||||
parseFloat(getComputedStyle($('#sections')).paddingBottom);
|
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.state.toggleHeightSaved = wrapper.clientHeight;
|
||||||
cm.setSize(null, window.innerHeight - sectionExtrasHeight - pageExtrasHeight);
|
cm.setSize(null, window.innerHeight - sectionExtrasHeight - pageExtrasHeight);
|
||||||
const bounds = cm.getSection().getBoundingClientRect();
|
const bounds = sectionEl.getBoundingClientRect();
|
||||||
if (bounds.top < 0 || bounds.bottom > window.innerHeight) {
|
if (bounds.top < 0 || bounds.bottom > window.innerHeight) {
|
||||||
window.scrollBy(0, bounds.top);
|
window.scrollBy(0, bounds.top);
|
||||||
}
|
}
|
||||||
|
@ -143,9 +144,96 @@ function createSectionsEditor(style) {
|
||||||
save: saveStyle,
|
save: saveStyle,
|
||||||
toggleStyle,
|
toggleStyle,
|
||||||
nextEditor,
|
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() {
|
function getEditors() {
|
||||||
return sections.filter(s => !s.isRemoved()).map(s => s.cm);
|
return sections.filter(s => !s.isRemoved()).map(s => s.cm);
|
||||||
}
|
}
|
||||||
|
@ -241,12 +329,13 @@ function createSectionsEditor(style) {
|
||||||
cm.setCursor(0, 0);
|
cm.setCursor(0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const animation = (cm.getSection().firstElementChild.getAnimations() || [])[0];
|
// FIXME: what is this?
|
||||||
if (animation) {
|
// const animation = (cm.getSection().firstElementChild.getAnimations() || [])[0];
|
||||||
animation.playbackRate = -1;
|
// if (animation) {
|
||||||
animation.currentTime = 2000;
|
// animation.playbackRate = -1;
|
||||||
animation.play();
|
// animation.currentTime = 2000;
|
||||||
}
|
// animation.play();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollEntirePageOnCtrlShift(event) {
|
function scrollEntirePageOnCtrlShift(event) {
|
||||||
|
|
|
@ -52,8 +52,6 @@ function createSourceEditor(style) {
|
||||||
updateLivePreview();
|
updateLivePreview();
|
||||||
});
|
});
|
||||||
|
|
||||||
CodeMirror.closestVisible = () => cm;
|
|
||||||
|
|
||||||
cm.operation(initAppliesToLineWidget);
|
cm.operation(initAppliesToLineWidget);
|
||||||
|
|
||||||
const metaCompiler = createMetaCompiler(cm);
|
const metaCompiler = createMetaCompiler(cm);
|
||||||
|
@ -409,6 +407,7 @@ function createSourceEditor(style) {
|
||||||
save,
|
save,
|
||||||
toggleStyle,
|
toggleStyle,
|
||||||
prevEditor: cm => nextPrevMozDocument(cm, -1),
|
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