Path: blob/master/javascript/resizeHandle.js
3055 views
(function() {1const GRADIO_MIN_WIDTH = 320;2const PAD = 16;3const DEBOUNCE_TIME = 100;4const DOUBLE_TAP_DELAY = 200; //ms56const R = {7tracking: false,8parent: null,9parentWidth: null,10leftCol: null,11leftColStartWidth: null,12screenX: null,13lastTapTime: null,14};1516let resizeTimer;17let parents = [];1819function setLeftColGridTemplate(el, width) {20el.style.gridTemplateColumns = `${width}px 16px 1fr`;21}2223function displayResizeHandle(parent) {24if (!parent.needHideOnMoblie) {25return true;26}27if (window.innerWidth < GRADIO_MIN_WIDTH * 2 + PAD * 4) {28parent.style.display = 'flex';29parent.resizeHandle.style.display = "none";30return false;31} else {32parent.style.display = 'grid';33parent.resizeHandle.style.display = "block";34return true;35}36}3738function afterResize(parent) {39if (displayResizeHandle(parent) && parent.style.gridTemplateColumns != parent.style.originalGridTemplateColumns) {40const oldParentWidth = R.parentWidth;41const newParentWidth = parent.offsetWidth;42const widthL = parseInt(parent.style.gridTemplateColumns.split(' ')[0]);4344const ratio = newParentWidth / oldParentWidth;4546const newWidthL = Math.max(Math.floor(ratio * widthL), parent.minLeftColWidth);47setLeftColGridTemplate(parent, newWidthL);4849R.parentWidth = newParentWidth;50}51}5253function setup(parent) {5455function onDoubleClick(evt) {56evt.preventDefault();57evt.stopPropagation();5859parent.style.gridTemplateColumns = parent.style.originalGridTemplateColumns;60}6162const leftCol = parent.firstElementChild;63const rightCol = parent.lastElementChild;6465parents.push(parent);6667parent.style.display = 'grid';68parent.style.gap = '0';69let leftColTemplate = "";70if (parent.children[0].style.flexGrow) {71leftColTemplate = `${parent.children[0].style.flexGrow}fr`;72parent.minLeftColWidth = GRADIO_MIN_WIDTH;73parent.minRightColWidth = GRADIO_MIN_WIDTH;74parent.needHideOnMoblie = true;75} else {76leftColTemplate = parent.children[0].style.flexBasis;77parent.minLeftColWidth = parent.children[0].style.flexBasis.slice(0, -2) / 2;78parent.minRightColWidth = 0;79parent.needHideOnMoblie = false;80}8182if (!leftColTemplate) {83leftColTemplate = '1fr';84}8586const gridTemplateColumns = `${leftColTemplate} ${PAD}px ${parent.children[1].style.flexGrow}fr`;87parent.style.gridTemplateColumns = gridTemplateColumns;88parent.style.originalGridTemplateColumns = gridTemplateColumns;8990const resizeHandle = document.createElement('div');91resizeHandle.classList.add('resize-handle');92parent.insertBefore(resizeHandle, rightCol);93parent.resizeHandle = resizeHandle;9495['mousedown', 'touchstart'].forEach((eventType) => {96resizeHandle.addEventListener(eventType, (evt) => {97if (eventType.startsWith('mouse')) {98if (evt.button !== 0) return;99} else {100if (evt.changedTouches.length !== 1) return;101102const currentTime = new Date().getTime();103if (R.lastTapTime && currentTime - R.lastTapTime <= DOUBLE_TAP_DELAY) {104onDoubleClick(evt);105return;106}107108R.lastTapTime = currentTime;109}110111evt.preventDefault();112evt.stopPropagation();113114document.body.classList.add('resizing');115116R.tracking = true;117R.parent = parent;118R.parentWidth = parent.offsetWidth;119R.leftCol = leftCol;120R.leftColStartWidth = leftCol.offsetWidth;121if (eventType.startsWith('mouse')) {122R.screenX = evt.screenX;123} else {124R.screenX = evt.changedTouches[0].screenX;125}126});127});128129resizeHandle.addEventListener('dblclick', onDoubleClick);130131afterResize(parent);132}133134['mousemove', 'touchmove'].forEach((eventType) => {135window.addEventListener(eventType, (evt) => {136if (eventType.startsWith('mouse')) {137if (evt.button !== 0) return;138} else {139if (evt.changedTouches.length !== 1) return;140}141142if (R.tracking) {143if (eventType.startsWith('mouse')) {144evt.preventDefault();145}146evt.stopPropagation();147148let delta = 0;149if (eventType.startsWith('mouse')) {150delta = R.screenX - evt.screenX;151} else {152delta = R.screenX - evt.changedTouches[0].screenX;153}154const leftColWidth = Math.max(Math.min(R.leftColStartWidth - delta, R.parent.offsetWidth - R.parent.minRightColWidth - PAD), R.parent.minLeftColWidth);155setLeftColGridTemplate(R.parent, leftColWidth);156}157});158});159160['mouseup', 'touchend'].forEach((eventType) => {161window.addEventListener(eventType, (evt) => {162if (eventType.startsWith('mouse')) {163if (evt.button !== 0) return;164} else {165if (evt.changedTouches.length !== 1) return;166}167168if (R.tracking) {169evt.preventDefault();170evt.stopPropagation();171172R.tracking = false;173174document.body.classList.remove('resizing');175}176});177});178179180window.addEventListener('resize', () => {181clearTimeout(resizeTimer);182183resizeTimer = setTimeout(function() {184for (const parent of parents) {185afterResize(parent);186}187}, DEBOUNCE_TIME);188});189190setupResizeHandle = setup;191})();192193194function setupAllResizeHandles() {195for (var elem of gradioApp().querySelectorAll('.resize-handle-row')) {196if (!elem.querySelector('.resize-handle') && !elem.children[0].classList.contains("hidden")) {197setupResizeHandle(elem);198}199}200}201202203onUiLoaded(setupAllResizeHandles);204205206207