From 1e71698b795be5f23674f8df70cd6314370c1ffb Mon Sep 17 00:00:00 2001 From: djmaze Date: Fri, 17 Jul 2020 13:46:49 +0200 Subject: [PATCH] Improved initHorizontalLayoutResizer and initVerticalLayoutResizer with custom resizer --- dev/App/User.js | 206 ++++++++++-------- dev/Styles/Layout.less | 51 ++++- .../css/no-theme/jquery-ui-1.12.1.custom.css | 70 ------ .../smoothness/jquery-ui-1.12.1.custom.css | 72 +----- 4 files changed, 164 insertions(+), 235 deletions(-) diff --git a/dev/App/User.js b/dev/App/User.js index d706df677..735827869 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -95,6 +95,36 @@ import { hideLoading, routeOff, routeOn, setHash, startScreens, showScreenPopup import { AbstractApp } from 'App/Abstract'; +if (!window.ResizeObserver) { + window.ResizeObserver = class { + constructor(callback) { + this.observer = new window.MutationObserver(mutations => { + let entries = []; + mutations.forEach(mutation => { + if ('style' == mutation.attributeName) { + entries.push({ + contentRect: { + width: mutation.target.offsetWidth, + height: mutation.target.offsetHeight + }, + target: mutation.target + }); + } + }); + callback(entries); + }); + } + + disconnect() { + this.observer.disconnect(); + } + + observe(target) { + this.observer.observe(target, { attributes: true }); + } + }; +} + class AppUser extends AbstractApp { constructor() { super(Remote); @@ -881,112 +911,102 @@ class AppUser extends AbstractApp { Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList); } - initHorizontalLayoutResizer() { - let top = null, - bottom = null, - observer = null; - - const - fDisable = (bDisable) => { - if (bDisable) { - if (observer) { - observer.disconnect(); - top.removeAttribute('style'); - top.classList.remove('resizable'); - bottom.removeAttribute('style'); - } - } else if ($htmlCL.contains('rl-bottom-preview-pane')) { - top = window.document.querySelector('.b-message-list-wrapper'); - bottom = window.document.querySelector('.b-message-view-wrapper'); - if (top && bottom) { - top.classList.add('resizable'); - if (window.ResizeObserver) { - if (!observer) { - observer = new window.ResizeObserver(entries => { - entries.forEach(entry => { - if (entry.target === top) { - bottom.style.top = (56 + entry.borderBoxSize.blockSize) + 'px'; - } - }); - }); + setLayoutResizer(source, target, bDisable) { + if (bDisable) { + source.observer && source.observer.disconnect(); + source.classList.remove('resizable'); + } else { + source.classList.add('resizable'); + if (!source.querySelector('.resizer')) { + const resizer = window.document.createElement('div'), + css = window.getComputedStyle(source, null), + cssint = s => parseFloat(css.getPropertyValue(s).replace('px', '')); + resizer.className = 'resizer'; + source.appendChild(resizer); + resizer.addEventListener('mousedown', { + source: source, + handleEvent: function(e) { + if ('mousedown' == e.type) { + e.preventDefault(); + if ('horizontal' == css.getPropertyValue('resize')) { + this.mode = 'width'; + this.pos = e.pageX; + } else { + this.mode = 'height'; + this.pos = e.pageY; } - observer.observe(top); - } else { - if (!observer) { - observer = new window.MutationObserver(mutations => { - mutations.forEach(mutation => { - if (mutation.target === top && 'style' == mutation.attributeName) { - bottom.style.top = (56 + top.offsetHeight) + 'px'; - } - }); - }); + this.min = cssint('min-'+this.mode); + this.max = cssint('max-'+this.mode); + this.org = cssint(this.mode); + window.addEventListener('mousemove', this); + window.addEventListener('mouseup', this); + } else if ('mousemove' == e.type) { + const length = this.org + (('width' == this.mode ? e.pageX : e.pageY) - this.pos); + if (length >= this.min && length <= this.max ) { + this.source.style[this.mode] = length + 'px'; } - observer.observe(top, { attributes: true }); + } else if ('mouseup' == e.type) { + window.removeEventListener('mousemove', this); + window.removeEventListener('mouseup', this); } } + }); + if ('horizontal' == css.getPropertyValue('resize')) { + source.observer = new window.ResizeObserver(entries => { + entries.forEach(entry => { +// target.style.left = entry.borderBoxSize.blockSize + 'px'; +// target.style.left = source.offsetWidth + 'px'; + target.style.left = entry.contentRect.width + 'px'; + }); + }); + } else { + source.observer = new window.ResizeObserver(entries => { + entries.forEach(entry => { +// target.style.top = entry.borderBoxSize.inlineSize + 'px'; +// target.style.top = (4 + source.offsetTop + source.offsetHeight) + 'px'; + target.style.top = (4 + source.offsetTop + entry.contentRect.height) + 'px'; + }); + }); } - }; + } + source.observer.observe(source, { box: 'border-box' }); + } + source.removeAttribute('style'); + target.removeAttribute('style'); + } - fDisable(false); + initHorizontalLayoutResizer() { + let top = window.document.querySelector('.b-message-list-wrapper'), + bottom = window.document.querySelector('.b-message-view-wrapper'); - Events.sub('layout', (layout) => { - fDisable(Layout.BottomPreview !== layout); - }); + if (top && bottom) { + const + fDisable = (bDisable) => { + this.setLayoutResizer(top, bottom, bDisable || !$htmlCL.contains('rl-bottom-preview-pane')); + }; + + fDisable(false); + + Events.sub('layout', layout => fDisable(Layout.BottomPreview !== layout)); + } } initVerticalLayoutResizer() { - let rlLeft = null, - rlRight = null, - observer = null; + let left = window.document.getElementById('rl-left'), + right = window.document.getElementById('rl-right'); - const - fDisable = (bDisable) => { - if (bDisable) { - if (observer) { - observer.disconnect(); - } - rlLeft.classList.remove('resizable'); - rlLeft.removeAttribute('style'); - rlRight.removeAttribute('style'); - } else { - rlLeft = window.document.getElementById('rl-left'); - rlRight = window.document.getElementById('rl-right'); - if (rlLeft && rlRight) { - rlLeft.classList.add('resizable'); - rlLeft.removeAttribute('style'); - rlRight.removeAttribute('style'); - if (window.ResizeObserver) { - let observer = new window.ResizeObserver(entries => { - entries.forEach(entry => { - if (entry.target === rlLeft) { - rlRight.style.left = entry.borderBoxSize.inlineSize + 'px'; - } - }); - }); - observer.observe(rlLeft); - } else { - let observer = new window.MutationObserver(mutations => { - mutations.forEach(mutation => { - if (mutation.target === rlLeft && 'style' == mutation.attributeName) { - rlRight.style.left = rlLeft.offsetWidth + 'px'; - } - }); - }); - observer.observe(rlLeft, { attributes: true }); - } - } - } - }; + if (left && right) { + const + fDisable = bDisable => { + this.setLayoutResizer(left, right, bDisable); + }; - fDisable(false); - - Events.sub('left-panel.off', () => { - fDisable(true); - }); - - Events.sub('left-panel.on', () => { fDisable(false); - }); + + Events.sub('left-panel.off', () => fDisable(true)); + + Events.sub('left-panel.on', () => fDisable(false)); + } } logout() { diff --git a/dev/Styles/Layout.less b/dev/Styles/Layout.less index c99270b97..10df16ca9 100644 --- a/dev/Styles/Layout.less +++ b/dev/Styles/Layout.less @@ -53,18 +53,67 @@ html.rl-mobile { min-width: 60px; } +/* +.resizable::after { + pointer-events: none; + position: absolute; + height: 22px; + width: 20px; + text-align: center; + bottom: 0; + right: 0; + background-color: #aaa; +} +.resizable::-webkit-resizer { + background: #aaa; + background: rgba(255,255,255,0.5); +} +*/ + +.resizable > .resizer { + background: #aaa; + background: rgba(255,255,255,0.5); + display: none; + opacity: 0; + position: absolute; + z-index: 102; +} +.resizable > .resizer:hover { + opacity: 1; +} + html:not(.rl-left-panel-disabled) #rl-left.resizable { resize: horizontal; overflow: hidden; min-width: 155px; max-width: 350px; } +#rl-left > .resizer { + cursor: ew-resize; + height: 100%; + right: 0; + top: 0; + width: 5px; +} + .b-message-list-wrapper.resizable { resize: vertical; overflow: hidden; min-height: 200px; max-height: 500px; } +.b-message-list-wrapper > .resizer { + cursor: ns-resize; + height: 5px; + left: 0; + bottom: 0; + width: 100%; +} + +html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer, +.b-message-list-wrapper > .resizer { + display: block; +} #rl-right { .g-ui-absolute-reset; @@ -300,7 +349,7 @@ html.rl-no-preview-pane { } } -html.rl-side-preview-pane #rl-right .ui-resizable-handle { +html.rl-side-preview-pane #rl-right .resizer { display: none !important; } diff --git a/vendors/jquery-ui/css/no-theme/jquery-ui-1.12.1.custom.css b/vendors/jquery-ui/css/no-theme/jquery-ui-1.12.1.custom.css index 54e52d0ca..a46cff213 100644 --- a/vendors/jquery-ui/css/no-theme/jquery-ui-1.12.1.custom.css +++ b/vendors/jquery-ui/css/no-theme/jquery-ui-1.12.1.custom.css @@ -88,73 +88,3 @@ width: 100%; height: 100%; } -.ui-resizable { - position: relative; -} -.ui-resizable-handle { - position: absolute; - font-size: 0.1px; - display: block; - -ms-touch-action: none; - touch-action: none; -} -.ui-resizable-disabled .ui-resizable-handle, -.ui-resizable-autohide .ui-resizable-handle { - display: none; -} -.ui-resizable-n { - cursor: n-resize; - height: 7px; - width: 100%; - top: -5px; - left: 0; -} -.ui-resizable-s { - cursor: s-resize; - height: 7px; - width: 100%; - bottom: -5px; - left: 0; -} -.ui-resizable-e { - cursor: e-resize; - width: 7px; - right: -5px; - top: 0; - height: 100%; -} -.ui-resizable-w { - cursor: w-resize; - width: 7px; - left: -5px; - top: 0; - height: 100%; -} -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 1px; - bottom: 1px; -} -.ui-resizable-sw { - cursor: sw-resize; - width: 9px; - height: 9px; - left: -5px; - bottom: -5px; -} -.ui-resizable-nw { - cursor: nw-resize; - width: 9px; - height: 9px; - left: -5px; - top: -5px; -} -.ui-resizable-ne { - cursor: ne-resize; - width: 9px; - height: 9px; - right: -5px; - top: -5px; -} diff --git a/vendors/jquery-ui/css/smoothness/jquery-ui-1.12.1.custom.css b/vendors/jquery-ui/css/smoothness/jquery-ui-1.12.1.custom.css index eff0a6420..20a911606 100644 --- a/vendors/jquery-ui/css/smoothness/jquery-ui-1.12.1.custom.css +++ b/vendors/jquery-ui/css/smoothness/jquery-ui-1.12.1.custom.css @@ -1,6 +1,6 @@ /*! jQuery UI - v1.10.3 - 2013-11-25 * http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.menu.css, jquery.ui.theme.css +* Includes: jquery.ui.core.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.menu.css, jquery.ui.theme.css * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ /* Layout helpers @@ -90,76 +90,6 @@ width: 100%; height: 100%; } -.ui-resizable { - position: relative; -} -.ui-resizable-handle { - position: absolute; - font-size: 0.1px; - display: block; - -ms-touch-action: none; - touch-action: none; -} -.ui-resizable-disabled .ui-resizable-handle, -.ui-resizable-autohide .ui-resizable-handle { - display: none; -} -.ui-resizable-n { - cursor: n-resize; - height: 7px; - width: 100%; - top: -5px; - left: 0; -} -.ui-resizable-s { - cursor: s-resize; - height: 7px; - width: 100%; - bottom: -5px; - left: 0; -} -.ui-resizable-e { - cursor: e-resize; - width: 7px; - right: -5px; - top: 0; - height: 100%; -} -.ui-resizable-w { - cursor: w-resize; - width: 7px; - left: -5px; - top: 0; - height: 100%; -} -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 1px; - bottom: 1px; -} -.ui-resizable-sw { - cursor: sw-resize; - width: 9px; - height: 9px; - left: -5px; - bottom: -5px; -} -.ui-resizable-nw { - cursor: nw-resize; - width: 9px; - height: 9px; - left: -5px; - top: -5px; -} -.ui-resizable-ne { - cursor: ne-resize; - width: 9px; - height: 9px; - right: -5px; - top: -5px; -} .ui-selectable-helper { position: absolute; z-index: 100;