// # js/quick-reply-singleton.js // // 以下2つは外すこと // - js/fix-google-recaptcha-v2.js // - js/quick-reply.js // // 浮動する投稿フォームを実装する. // quick-reply.js とは違いフォームを複製しない. // 元々あるメインフォームを見掛け上移動できるようにする. // これは特殊キャプチャを動作するようにして、各種イベント設定を簡単にする. function makeFormDraggable(el) { let isDragging = false; // クリック位置と要素左上の差分を保存する let offsetX = 0; let offsetY = 0; // 最低でも画面内にあるpixel数 const minVisibility = 50; function ensureElementInViewport() { const rect = el.getBoundingClientRect(); const vpwidth = window.innerWidth || document.documentElement.clientWidth; const vpheight = window.innerHeight || document.documentElement.clientHeight; const m = minVisibility; if (rect.bottom < m) { // 上すぎるのをなおす el.style.top = -(rect.height - m) + 'px'; } else if (rect.top > vpheight - m) { // 下すぎるのをなおす el.style.top = (vpheight - m) + 'px'; }; if (rect.right < m) { // 右すぎるのをなおす el.style.left = -(rect.width - m) + 'px'; } else if (rect.left > vpwidth - m) { // 左すぎるのをなおす el.style.left = (vpwidth - m) + 'px'; }; }; function setWidthHeight(element) { const width = el.getBoundingClientRect().width; const height = el.getBoundingClientRect().height; element.style.minWidth = width + 'px'; element.style.minHeight = height + 'px'; }; function setPlaceHolder() { const div = document.createElement('DIV'); setWidthHeight(div); el.parentElement.insertBefore(div, el); }; function startDragging(e) { isDragging = true; offsetX = e.clientX - el.getBoundingClientRect().left; offsetY = e.clientY - el.getBoundingClientRect().top; }; if (el.style.position === 'fixed') { return; }; setPlaceHolder(); el.style.position = 'fixed'; el.style.zIndex = 9999; el.style.backgroundColor = '#8883'; { const r = el.getBoundingClientRect(); const vpw = window.innerWidth || document.documentElement.clientWidth; const vph = window.innerHeight || document.documentElement.clientHeight; el.style.left = ((vpw - r.width) / 2) + 'px'; el.style.top = ((vph - r.height) / 2) + 'px'; }; el.addEventListener('mousedown', (e) => { if (e.shiftKey || e.ctrlKey || e.altKey) { return; }; if (e.button !== 0) { return; }; const toDrag = [ 'FORM', 'TABLE', 'CAPTION', 'THEAD', 'TR', 'TH', 'TD', 'TBODY', 'TFOOT']; const toNoDrag = ['TEXTAREA', 'INPUT']; if (toNoDrag.includes(e.target.tagName)) { return; }; if (toDrag.includes(e.target.tagName)) { startDragging(e); e.preventDefault(); return; }; startDragging(e); }); document.addEventListener('mousemove', (e) => { if (isDragging) { el.style.left = (e.clientX - offsetX) + 'px'; el.style.top = (e.clientY - offsetY) + 'px'; } }); document.addEventListener('mouseup', () => { isDragging = false; ensureElementInViewport(); }); let resizeTimer; window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(ensureElementInViewport, 100); }); }; $(window).on('cite', function(e, id, with_link) { const target = document.querySelector('form[name="post"]'); if (target) { makeFormDraggable(target); }; });