1(function () { 2 var STORAGE_KEY = 'vlibrasPosition'; 3 var MOVED_EPSILON = 2; 4 var DRAGGING_CLASS = 'vlibras-dragging'; 5 6 function getWidget() { 7 return document.querySelector('div[vw].enabled'); 8 } 9 10 function clamp(value, min, max) { 11 return Math.min(Math.max(value, min), max); 12 } 13 14 function applyPosition(el, right, bottom) { 15 var rect = el.getBoundingClientRect(); 16 var maxRight = Math.max(window.innerWidth - rect.width, 0); 17 var maxBottom = Math.max(window.innerHeight - rect.height, 0); 18 right = clamp(right, 0, maxRight); 19 bottom = clamp(bottom, 0, maxBottom); 20 el.style.setProperty('left', 'auto', 'important'); 21 el.style.setProperty('top', 'auto', 'important'); 22 el.style.setProperty('right', right + 'px', 'important'); 23 el.style.setProperty('bottom', bottom + 'px', 'important'); 24 el.style.setProperty('transform', 'none', 'important'); 25 return { right: right, bottom: bottom }; 26 } 27 28 function loadSavedPosition(el) { 29 var saved; 30 try { 31 saved = JSON.parse(localStorage.getItem(STORAGE_KEY)); 32 } catch (e) { 33 return; 34 } 35 if (saved && typeof saved.right === 'number' && typeof saved.bottom === 'number') { 36 applyPosition(el, saved.right, saved.bottom); 37 } 38 } 39 40 function savePosition(right, bottom) { 41 try { 42 localStorage.setItem(STORAGE_KEY, JSON.stringify({ right: right, bottom: bottom })); 43 } catch (e) { 44 // localStorage indisponivel (modo privado, quota etc): ignora. 45 } 46 } 47 48 function setupDrag(widget, handle) { 49 var dragging = false; 50 var moved = false; 51 var startX, startY, startRight, startBottom; 52 53 handle.style.touchAction = 'none'; 54 55 handle.addEventListener('pointerdown', function (ev) { 56 if (ev.button !== undefined && ev.button !== 0) return; 57 dragging = true; 58 moved = false; 59 startX = ev.clientX; 60 startY = ev.clientY; 61 var style = window.getComputedStyle(widget); 62 startRight = parseFloat(style.right) || 0; 63 startBottom = parseFloat(style.bottom) || 0; 64 // Evita o drag nativo de imagem do navegador e a selecao de texto, 65 // que atrapalham o arraste customizado logo no primeiro movimento. 66 ev.preventDefault(); 67 // Feedback visual imediato: ao segurar o botao, ele ja mostra que 68 // esta liberado para ser arrastado, antes mesmo de mover o mouse. 69 handle.classList.add(DRAGGING_CLASS); 70 if (handle.setPointerCapture) { 71 handle.setPointerCapture(ev.pointerId); 72 } 73 }); 74 75 handle.addEventListener('pointermove', function (ev) { 76 if (!dragging) return; 77 var dx = ev.clientX - startX; 78 var dy = ev.clientY - startY; 79 if (!moved && (Math.abs(dx) > MOVED_EPSILON || Math.abs(dy) > MOVED_EPSILON)) { 80 moved = true; 81 } 82 // Acompanha o cursor desde o primeiro pixel de movimento, sem 83 // esperar um limite minimo, para o arraste parecer imediato. 84 applyPosition(widget, startRight - dx, startBottom - dy); 85 }); 86 87 function endDrag() { 88 if (!dragging) return; 89 dragging = false; 90 handle.classList.remove(DRAGGING_CLASS); 91 if (moved) { 92 var style = window.getComputedStyle(widget); 93 savePosition(parseFloat(style.right) || 0, parseFloat(style.bottom) || 0); 94 // O clique gerado pelo navegador logo apos o "pointerup" chega 95 // de forma sincrona e ainda vera moved=true para ser 96 // suprimido; este timeout so limpa a flag caso, por algum 97 // motivo, esse clique nao chegue a ocorrer. 98 setTimeout(function () { moved = false; }, 0); 99 } 100 } 101 102 handle.addEventListener('pointerup', endDrag); 103 handle.addEventListener('pointercancel', endDrag); 104 105 // Se o gesto foi um arraste, bloqueia o clique que o VLibras usa 106 // para abrir/fechar o painel de traducao. 107 handle.addEventListener('click', function (ev) { 108 if (moved) { 109 ev.stopImmediatePropagation(); 110 ev.preventDefault(); 111 moved = false;
112 } 113 }, true); 114 } 115 116 function init() { 117 var widget = getWidget(); 118 if (!widget) return; 119 var handle = widget.querySelector('[vw-access-button]'); 120 if (!handle) return; 121 122 loadSavedPosition(widget); 123 setupDrag(widget, handle); 124 } 125 126 if (document.readyState === 'loading') { 127 document.addEventListener('DOMContentLoaded', init); 128 } else { 129 init(); 130 } 131 132 // O proprio script do VLibras reaplica sua posicao padrao (centralizada) 133 // via estilo inline quando a pagina termina de carregar. Reaplicamos a 134 // posicao salva do usuario logo em seguida para que ela prevaleca. 135 window.addEventListener('load', function () { 136 setTimeout(function () { 137 var widget = getWidget(); 138 if (widget) loadSavedPosition(widget); 139 }, 50); 140 }); 141})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.