diff --git a/edit.html b/edit.html
index 55808341..d8223424 100644
--- a/edit.html
+++ b/edit.html
@@ -135,6 +135,17 @@
.CodeMirror-vscrollbar {
margin-bottom: 8px; /* make space for resize-grip */
}
+ .CodeMirror-search-field {
+ -webkit-animation: highlight 3s ease-out;
+ }
+ @-webkit-keyframes highlight {
+ from {
+ background-color: #ff9;
+ }
+ to {
+ background-color: transparent;
+ }
+ }
.resize-grip {
position: absolute;
display: block;
diff --git a/edit.js b/edit.js
index 941135a5..8b2f5006 100644
--- a/edit.js
+++ b/edit.js
@@ -178,6 +178,7 @@ function setupCodeMirror(textarea, index) {
// ensure the section doesn't jump when clicking selected text
cm.on("cursorActivity", function(cm) {
+ editors.lastActive = cm;
setTimeout(function() {
lockScroll = {
windowScrollY: window.scrollY,
@@ -204,6 +205,20 @@ function setupCodeMirror(textarea, index) {
document.removeEventListener("mousemove", resize);
});
});
+ // resizeGrip has enough space when scrollbars.horiz is visible
+ if (cm.display.scrollbars.horiz.style.display != "") {
+ cm.display.scrollbars.vert.style.marginBottom = "0";
+ }
+ // resizeGrip space adjustment in case a long line was entered/deleted by a user
+ new MutationObserver(function(mutations) {
+ var hScrollbar = mutations[0].target;
+ var hScrollbarVisible = hScrollbar.style.display != "";
+ var vScrollbar = hScrollbar.parentNode.CodeMirror.display.scrollbars.vert;
+ vScrollbar.style.marginBottom = hScrollbarVisible ? "0" : "";
+ }).observe(cm.display.scrollbars.horiz, {
+ attributes: true,
+ attributeFilter: ["style"]
+ });
editors.splice(index || editors.length, 0, cm);
return cm;
@@ -224,10 +239,21 @@ document.addEventListener("scroll", function(e) {
}
});
-window.addEventListener("keydown", function(e) {
- if (e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey && e.keyCode == 83) {
- e.preventDefault();
- save();
+document.addEventListener("keydown", function(e) {
+ if (!e.altKey && e.keyCode >= 70 && e.keyCode <= 114) {
+ if (e.keyCode == 83 && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // Ctrl-S, Cmd-S
+ e.preventDefault();
+ e.stopPropagation();
+ save();
+ } else if (e.target.localName != "textarea") { // textareas are handled by CodeMirror
+ if (e.keyCode == 70 && (e.ctrlKey || e.metaKey) && !e.shiftKey) { /* Ctrl-F, Cmd-F */
+ document.browserSearchHandler(e, "find");
+ } else if (e.keyCode == 71 && (e.ctrlKey || e.metaKey)) { /*Ctrl-G, Ctrl-Shift-G, Cmd-G, Cmd-Shift-G*/
+ document.browserSearchHandler(e, e.shiftKey ? "findPrev" : "findNext");
+ } else if (e.keyCode == 114 && !e.ctrlKey && !e.metaKey) { /*F3, Shift-F3*/
+ document.browserSearchHandler(e, e.shiftKey ? "findPrev" : "findNext");
+ }
+ }
}
});
@@ -438,9 +464,47 @@ function setupGlobalSearch() {
originalCommand[reverse ? "findPrev" : "findNext"](activeCM);
}
+ function findPrev(cm) {
+ findNext(cm, true);
+ }
+
+ function getVisibleEditor() {
+ var linesVisible = 2; // closest editor should have at least # lines visible
+ function getScrollDistance(cm) {
+ var bounds = cm.display.wrapper.parentNode.getBoundingClientRect();
+ if (bounds.top < 0) {
+ return -bounds.top;
+ } else if (bounds.top < window.innerHeight - cm.defaultTextHeight() * linesVisible) {
+ return 0;
+ } else {
+ return bounds.top - bounds.height;
+ }
+ }
+ if (editors.lastActive && getScrollDistance(editors.lastActive) == 0) {
+ return editors.lastActive;
+ }
+ var sorted = editors
+ .map(function(cm, index) { return {cm: cm, distance: getScrollDistance(cm), index: index} })
+ .sort(function(a, b) { return Math.sign(a.distance - b.distance) || Math.sign(a.index - b.index)});
+ var cm = sorted[0].cm;
+ if (sorted[0].distance > 0) {
+ makeSectionVisible(cm)
+ }
+ cm.focus();
+ return cm;
+ }
+
+ document.browserSearchHandler = function(event, command) {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!event.target.classList.contains("CodeMirror-search-field")) {
+ CodeMirror.commands[command](getVisibleEditor());
+ }
+ }
+
CodeMirror.commands.find = find;
- CodeMirror.commands.findNext = function(cm) { findNext(cm) }
- CodeMirror.commands.findPrev = function(cm) { findNext(cm, true) }
+ CodeMirror.commands.findNext = findNext;
+ CodeMirror.commands.findPrev = findPrev;
}
function jumpToLine(cm) {