From e2950a53f6392c4ab0b8da69477ec8925fadf7a8 Mon Sep 17 00:00:00 2001 From: tophf Date: Tue, 27 Jun 2017 18:55:17 +0300 Subject: [PATCH 1/3] editor: horizontal resize grip --- edit.html | 31 ++++++++++++++++++++++++++----- edit.js | 14 -------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/edit.html b/edit.html index c8ae2927..4f869e73 100644 --- a/edit.html +++ b/edit.html @@ -192,7 +192,13 @@ background: none; } .CodeMirror-vscrollbar { - margin-bottom: 8px; /* make space for resize-grip */ + margin-bottom: 7px; /* make space for resize-grip */ + } + .CodeMirror-hscrollbar { + bottom: 7px; /* make space for resize-grip */ + } + .CodeMirror-scrollbar-filler { + bottom: 7px; /* make space for resize-grip */ } .CodeMirror-dialog { -webkit-animation: highlight 3s ease-out; @@ -242,14 +248,29 @@ .resize-grip { position: absolute; display: block; - width: 8px; - height: 8px; - content: " "; + height: 6px; + content: ""; + left: 0; right: 0; bottom: 0; z-index: 99; cursor: n-resize; - background: linear-gradient(-45deg, transparent 2px, rgba(0,0,0,0.5) 2px, transparent 3px, transparent 4.5px, rgba(0,0,0,0.5) 5px, transparent 5.5px); + background-color: inherit; + border-top-width: 1px; + border-top-style: solid; + border-top-color: inherit; + } + .resize-grip:after { + content: ""; + bottom: 2px; + left: 0; + right: 0; + margin: 0 8px; + display: block; + position: absolute; + border-top-width: 2px; + border-top-style: dotted; + border-top-color: inherit; } /* applies-to */ .applies-to { diff --git a/edit.js b/edit.js index f8e2cd01..fb3b7eeb 100644 --- a/edit.js +++ b/edit.js @@ -390,20 +390,6 @@ function setupCodeMirror(textarea, index) { document.body.style.cursor = ''; }); }); - // 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; From f7bfec97bb1b91e0b6df2e7ec6b168a7b026ab04 Mon Sep 17 00:00:00 2001 From: tophf Date: Wed, 28 Jun 2017 07:51:12 +0300 Subject: [PATCH 2/3] fix z-index issue --- edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit.html b/edit.html index 4f869e73..d770fd14 100644 --- a/edit.html +++ b/edit.html @@ -253,7 +253,7 @@ left: 0; right: 0; bottom: 0; - z-index: 99; + z-index: 9; cursor: n-resize; background-color: inherit; border-top-width: 1px; From 7a89c999552c3e4060e819d785888aee6a7b03eb Mon Sep 17 00:00:00 2001 From: tophf Date: Wed, 28 Jun 2017 09:09:29 +0300 Subject: [PATCH 3/3] add double-click --- _locales/en/messages.json | 4 ++ edit.html | 3 ++ edit.js | 80 ++++++++++++++++++++++++++------------- 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 584bb716..c6a336cf 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -131,6 +131,10 @@ "message": "Selection only", "description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text" }, + "cm_resizeGripHint": { + "message": "Double-click to maximize/restore the height", + "description": "Tooltip for the resize grip in style editor" + }, "genericDisabledLabel": { "message": "Disabled", "description": "Used in various lists/options to indicate that something is disabled" diff --git a/edit.html b/edit.html index d770fd14..2bfbd888 100644 --- a/edit.html +++ b/edit.html @@ -681,6 +681,9 @@ + diff --git a/edit.js b/edit.js index fb3b7eeb..70f077f8 100644 --- a/edit.js +++ b/edit.js @@ -343,53 +343,60 @@ function acmeEventListener(event) { // replace given textarea with the CodeMirror editor function setupCodeMirror(textarea, index) { - var cm = CodeMirror.fromTextArea(textarea, {lint: null}); + const cm = CodeMirror.fromTextArea(textarea, {lint: null}); + const wrapper = cm.display.wrapper; - cm.on("change", indicateCodeChange); + cm.on('change', indicateCodeChange); if (prefs.get('editor.autocompleteOnTyping')) { cm.on('change', autocompleteOnTyping); cm.on('pick', autocompletePicked); } - cm.on("blur", function(cm) { + cm.on('blur', () => { editors.lastActive = cm; hotkeyRerouter.setState(true); - setTimeout(function() { - var cm = editors.lastActive; - var childFocused = cm.display.wrapper.contains(document.activeElement); - cm.display.wrapper.classList.toggle("CodeMirror-active", childFocused); - }, 0); + setTimeout(() => { + wrapper.classList.toggle('CodeMirror-active', wrapper.contains(document.activeElement)); + }); }); - cm.on("focus", function() { + cm.on('focus', () => { hotkeyRerouter.setState(false); - cm.display.wrapper.classList.add("CodeMirror-active"); + wrapper.classList.add('CodeMirror-active'); }); cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event)); - var resizeGrip = cm.display.wrapper.appendChild(document.createElement("div")); - resizeGrip.className = "resize-grip"; - resizeGrip.addEventListener("mousedown", function(e) { - e.preventDefault(); - var cm = e.target.parentNode.CodeMirror; - var minHeight = cm.defaultTextHeight() + let lastClickTime = 0; + const resizeGrip = wrapper.appendChild(template.resizeGrip.cloneNode(true)); + resizeGrip.onmousedown = event => { + if (event.button != 0) { + return; + } + event.preventDefault(); + if (Date.now() - lastClickTime < 500) { + lastClickTime = 0; + toggleSectionHeight(cm); + return; + } + lastClickTime = Date.now(); + const minHeight = cm.defaultTextHeight() + cm.display.lineDiv.offsetParent.offsetTop /* .CodeMirror-lines padding */ - + cm.display.wrapper.offsetHeight - cm.display.wrapper.clientHeight /* borders */; - cm.display.wrapper.style.pointerEvents = 'none'; + + wrapper.offsetHeight - wrapper.clientHeight /* borders */; + wrapper.style.pointerEvents = 'none'; document.body.style.cursor = 's-resize'; function resize(e) { - const cmPageY = cm.display.wrapper.getBoundingClientRect().top + window.scrollY; + const cmPageY = wrapper.getBoundingClientRect().top + window.scrollY; const height = Math.max(minHeight, e.pageY - cmPageY); - if (height != cm.display.wrapper.clientHeight) { + if (height != wrapper.clientHeight) { cm.setSize(null, height); } } - document.addEventListener("mousemove", resize); - document.addEventListener("mouseup", function resizeStop() { - document.removeEventListener("mouseup", resizeStop); - document.removeEventListener("mousemove", resize); - cm.display.wrapper.style.pointerEvents = ''; + document.addEventListener('mousemove', resize); + document.addEventListener('mouseup', function resizeStop() { + document.removeEventListener('mouseup', resizeStop); + document.removeEventListener('mousemove', resize); + wrapper.style.pointerEvents = ''; document.body.style.cursor = ''; }); - }); + }; editors.splice(index || editors.length, 0, cm); return cm; @@ -872,6 +879,27 @@ function toggleStyle() { save(); } +function toggleSectionHeight(cm) { + if (cm.state.toggleHeightSaved) { + // restore previous size + cm.setSize(null, cm.state.toggleHeightSaved); + cm.state.toggleHeightSaved = 0; + } else { + // maximize + const wrapper = cm.display.wrapper; + const allBounds = $('#sections').getBoundingClientRect(); + const pageExtrasHeight = allBounds.top + window.scrollY + + parseFloat(getComputedStyle($('#sections')).paddingBottom); + const sectionExtrasHeight = cm.getSection().clientHeight - wrapper.offsetHeight; + cm.state.toggleHeightSaved = wrapper.clientHeight; + cm.setSize(null, window.innerHeight - sectionExtrasHeight - pageExtrasHeight); + const bounds = cm.getSection().getBoundingClientRect(); + if (bounds.top < 0 || bounds.bottom > window.innerHeight) { + window.scrollBy(0, bounds.top); + } + } +} + function autocompleteOnTyping(cm, info, debounced) { if (cm.state.completionActive || info.origin && !info.origin.includes('input')