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",
"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"

View File

@ -681,6 +681,9 @@
<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>
</template>
<template data-id="resizeGrip">
<div class="resize-grip" i18n-title="cm_resizeGripHint"></div>
</template>
</head>
<body id="stylus-edit">

80
edit.js
View File

@ -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;
@ -874,6 +881,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')