editor: add double-click to resize grip

This commit is contained in:
tophf 2017-06-28 09:09:29 +03:00
parent 9ffc525391
commit 565f23fa6e
3 changed files with 61 additions and 26 deletions

View File

@ -131,6 +131,10 @@
"message": "Selection only", "message": "Selection only",
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text" "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": { "genericDisabledLabel": {
"message": "Disabled", "message": "Disabled",
"description": "Used in various lists/options to indicate that something is disabled" "description": "Used in various lists/options to indicate that something is disabled"

View File

@ -681,6 +681,9 @@
<template data-id="regexpTestPartial"> <template data-id="regexpTestPartial">
<a target="_blank" href="https://github.com/stylish-userstyles/stylish/wiki/Applying-styles-to-specific-sites#advanced-matching-with-regular-expressions"><svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></a> <a target="_blank" href="https://github.com/stylish-userstyles/stylish/wiki/Applying-styles-to-specific-sites#advanced-matching-with-regular-expressions"><svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></a>
</template> </template>
<template data-id="resizeGrip">
<div class="resize-grip" i18n-title="cm_resizeGripHint"></div>
</template>
</head> </head>
<body id="stylus-edit"> <body id="stylus-edit">

80
edit.js
View File

@ -343,53 +343,60 @@ function acmeEventListener(event) {
// replace given textarea with the CodeMirror editor // replace given textarea with the CodeMirror editor
function setupCodeMirror(textarea, index) { 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')) { if (prefs.get('editor.autocompleteOnTyping')) {
cm.on('change', autocompleteOnTyping); cm.on('change', autocompleteOnTyping);
cm.on('pick', autocompletePicked); cm.on('pick', autocompletePicked);
} }
cm.on("blur", function(cm) { cm.on('blur', () => {
editors.lastActive = cm; editors.lastActive = cm;
hotkeyRerouter.setState(true); hotkeyRerouter.setState(true);
setTimeout(function() { setTimeout(() => {
var cm = editors.lastActive; wrapper.classList.toggle('CodeMirror-active', wrapper.contains(document.activeElement));
var childFocused = cm.display.wrapper.contains(document.activeElement);
cm.display.wrapper.classList.toggle("CodeMirror-active", childFocused);
}, 0);
}); });
cm.on("focus", function() { });
cm.on('focus', () => {
hotkeyRerouter.setState(false); hotkeyRerouter.setState(false);
cm.display.wrapper.classList.add("CodeMirror-active"); wrapper.classList.add('CodeMirror-active');
}); });
cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event)); cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event));
var resizeGrip = cm.display.wrapper.appendChild(document.createElement("div")); let lastClickTime = 0;
resizeGrip.className = "resize-grip"; const resizeGrip = wrapper.appendChild(template.resizeGrip.cloneNode(true));
resizeGrip.addEventListener("mousedown", function(e) { resizeGrip.onmousedown = event => {
e.preventDefault(); if (event.button != 0) {
var cm = e.target.parentNode.CodeMirror; return;
var minHeight = cm.defaultTextHeight() }
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.lineDiv.offsetParent.offsetTop /* .CodeMirror-lines padding */
+ cm.display.wrapper.offsetHeight - cm.display.wrapper.clientHeight /* borders */; + wrapper.offsetHeight - wrapper.clientHeight /* borders */;
cm.display.wrapper.style.pointerEvents = 'none'; wrapper.style.pointerEvents = 'none';
document.body.style.cursor = 's-resize'; document.body.style.cursor = 's-resize';
function resize(e) { 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); const height = Math.max(minHeight, e.pageY - cmPageY);
if (height != cm.display.wrapper.clientHeight) { if (height != wrapper.clientHeight) {
cm.setSize(null, height); cm.setSize(null, height);
} }
} }
document.addEventListener("mousemove", resize); document.addEventListener('mousemove', resize);
document.addEventListener("mouseup", function resizeStop() { document.addEventListener('mouseup', function resizeStop() {
document.removeEventListener("mouseup", resizeStop); document.removeEventListener('mouseup', resizeStop);
document.removeEventListener("mousemove", resize); document.removeEventListener('mousemove', resize);
cm.display.wrapper.style.pointerEvents = ''; wrapper.style.pointerEvents = '';
document.body.style.cursor = ''; document.body.style.cursor = '';
}); });
}); };
editors.splice(index || editors.length, 0, cm); editors.splice(index || editors.length, 0, cm);
return cm; return cm;
@ -874,6 +881,27 @@ function toggleStyle() {
save(); 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) { function autocompleteOnTyping(cm, info, debounced) {
if (cm.state.completionActive if (cm.state.completionActive
|| info.origin && !info.origin.includes('input') || info.origin && !info.origin.includes('input')