fix: hover ADD nonce captureId and cleanup old badge DOM to prevent duplicate old overlay handlers
Browse files
src-tauri/resources/scripts/hover_overlay.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
| 1 |
/* Refstudio hover overlay: + ADD button on web images.
|
| 2 |
-
*
|
| 3 |
-
* Previous versions fired 3 channels causing duplicate images.
|
| 4 |
*/
|
| 5 |
(function () {
|
| 6 |
-
if (window.
|
| 7 |
-
window.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
var MIN = 90;
|
| 10 |
var activeImg = null;
|
| 11 |
var badge = null;
|
| 12 |
var showTimer = 0;
|
| 13 |
var hideTimer = 0;
|
| 14 |
-
var capturing = false;
|
| 15 |
|
| 16 |
function injectCSS() {
|
| 17 |
-
if (document.getElementById('
|
| 18 |
-
var s = document.createElement('style'); s.id = '
|
| 19 |
s.textContent = '#__muse_add_badge{all:initial;position:fixed;z-index:2147483647;display:flex;align-items:center;gap:5px;padding:8px 16px;background:rgba(10,132,255,0.95);color:#fff;border-radius:999px;box-shadow:0 4px 20px rgba(0,0,0,0.4),0 0 0 1px rgba(255,255,255,0.1);font:700 12px/1 -apple-system,BlinkMacSystemFont,"Inter",sans-serif;cursor:pointer;opacity:0;transform:translateY(4px) scale(0.92);transition:opacity .2s,transform .2s,background .1s;pointer-events:auto;letter-spacing:0.01em;user-select:none}#__muse_add_badge.v{opacity:1;transform:none}#__muse_add_badge:hover{background:rgba(10,132,255,1);box-shadow:0 6px 28px rgba(10,132,255,0.4),0 0 0 1px rgba(255,255,255,0.2);transform:scale(1.06)}#__muse_add_badge:active{transform:scale(0.92);background:rgba(10,100,220,1)}#__muse_add_badge svg{width:14px;height:14px;stroke-width:2.5;pointer-events:none}#__mt7{all:initial;position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(8px);z-index:2147483647;padding:9px 16px;border-radius:999px;background:rgba(20,20,20,.97);border:1px solid rgba(255,255,255,.1);box-shadow:0 10px 36px rgba(0,0,0,.5);font:600 12px/1 -apple-system,sans-serif;color:#fff;opacity:0;transition:opacity .16s,transform .16s;pointer-events:none}#__mt7.s{opacity:1;transform:translateX(-50%) translateY(0)}';
|
| 20 |
(document.head || document.documentElement).appendChild(s);
|
| 21 |
}
|
| 22 |
|
| 23 |
function enc(v) { return encodeURIComponent(v == null ? '' : String(v)); }
|
| 24 |
function absUrl(s) { try { return new URL(s || '', location.href).href; } catch (_) { return s || ''; } }
|
|
|
|
| 25 |
|
| 26 |
function bestImageUrl(img) {
|
| 27 |
var srcset = img.getAttribute('srcset') || '';
|
|
@@ -37,19 +42,15 @@
|
|
| 37 |
function fireAction(url, title, w, h) {
|
| 38 |
if (capturing) return;
|
| 39 |
capturing = true;
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
var u = 'muse-action://board?url='+enc(url)+'&source='+enc(location.href)+'&title='+enc(title)+'&w='+enc(w)+'&h='+enc(h);
|
| 43 |
window.location.href = u;
|
| 44 |
-
// Reset after short delay (the page won't actually navigate since Rust returns false)
|
| 45 |
setTimeout(function(){ capturing = false; }, 1000);
|
| 46 |
}
|
| 47 |
|
| 48 |
function clearHide(){clearTimeout(hideTimer);}
|
| 49 |
function scheduleHide(){clearHide();hideTimer=setTimeout(hide,600);}
|
| 50 |
-
|
| 51 |
function hide(){if(!badge)return;badge.classList.remove('v');activeImg=null;}
|
| 52 |
-
|
| 53 |
function pos(el,img){var r=img.getBoundingClientRect();var x=r.right-80,y=r.top+10;if(x<r.left+4)x=r.left+4;if(x>innerWidth-90)x=innerWidth-90;if(y<4)y=4;if(y>innerHeight-40)y=innerHeight-40;el.style.left=x+'px';el.style.top=y+'px';}
|
| 54 |
|
| 55 |
function show(img){
|
|
@@ -68,7 +69,6 @@
|
|
| 68 |
}
|
| 69 |
|
| 70 |
function isValid(el){if(!el||el.tagName!=='IMG')return false;if(el===badge)return false;var r=el.getBoundingClientRect();return r.width>=MIN&&r.height>=MIN;}
|
| 71 |
-
|
| 72 |
document.addEventListener('mouseover',function(e){var t=e.target;if(badge&&(t===badge||badge.contains(t))){clearHide();return;}if(!isValid(t))return;if(t===activeImg){clearHide();return;}clearHide();clearTimeout(showTimer);showTimer=setTimeout(function(){show(t);},150);},true);
|
| 73 |
document.addEventListener('mouseout',function(e){var t=e.target;if(!t||t.tagName!=='IMG'||t!==activeImg)return;var rel=e.relatedTarget;if(badge&&rel&&(badge===rel||badge.contains(rel))){clearHide();return;}clearTimeout(showTimer);scheduleHide();},true);
|
| 74 |
window.addEventListener('scroll',function(){if(!badge||!activeImg)return;var r=activeImg.getBoundingClientRect();if(r.bottom<-20||r.top>innerHeight+20)hide();else pos(badge,activeImg);},{passive:true,capture:true});
|
|
|
|
| 1 |
/* Refstudio hover overlay: + ADD button on web images.
|
| 2 |
+
* v12 — stable one-click capture with captureId nonce.
|
|
|
|
| 3 |
*/
|
| 4 |
(function () {
|
| 5 |
+
if (window.__muse_hover_v12) return;
|
| 6 |
+
window.__muse_hover_v12 = true;
|
| 7 |
+
|
| 8 |
+
// Remove old badge DOM left by previous injected versions. Anonymous old listeners
|
| 9 |
+
// may still exist, but they cannot duplicate backend actions because v12 adds captureId
|
| 10 |
+
// and Rust dedupes captureIds.
|
| 11 |
+
try { var old = document.getElementById('__muse_add_badge'); if (old) old.remove(); } catch (_) {}
|
| 12 |
|
| 13 |
var MIN = 90;
|
| 14 |
var activeImg = null;
|
| 15 |
var badge = null;
|
| 16 |
var showTimer = 0;
|
| 17 |
var hideTimer = 0;
|
| 18 |
+
var capturing = false;
|
| 19 |
|
| 20 |
function injectCSS() {
|
| 21 |
+
if (document.getElementById('__muse_badge_css_v12')) return;
|
| 22 |
+
var s = document.createElement('style'); s.id = '__muse_badge_css_v12';
|
| 23 |
s.textContent = '#__muse_add_badge{all:initial;position:fixed;z-index:2147483647;display:flex;align-items:center;gap:5px;padding:8px 16px;background:rgba(10,132,255,0.95);color:#fff;border-radius:999px;box-shadow:0 4px 20px rgba(0,0,0,0.4),0 0 0 1px rgba(255,255,255,0.1);font:700 12px/1 -apple-system,BlinkMacSystemFont,"Inter",sans-serif;cursor:pointer;opacity:0;transform:translateY(4px) scale(0.92);transition:opacity .2s,transform .2s,background .1s;pointer-events:auto;letter-spacing:0.01em;user-select:none}#__muse_add_badge.v{opacity:1;transform:none}#__muse_add_badge:hover{background:rgba(10,132,255,1);box-shadow:0 6px 28px rgba(10,132,255,0.4),0 0 0 1px rgba(255,255,255,0.2);transform:scale(1.06)}#__muse_add_badge:active{transform:scale(0.92);background:rgba(10,100,220,1)}#__muse_add_badge svg{width:14px;height:14px;stroke-width:2.5;pointer-events:none}#__mt7{all:initial;position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(8px);z-index:2147483647;padding:9px 16px;border-radius:999px;background:rgba(20,20,20,.97);border:1px solid rgba(255,255,255,.1);box-shadow:0 10px 36px rgba(0,0,0,.5);font:600 12px/1 -apple-system,sans-serif;color:#fff;opacity:0;transition:opacity .16s,transform .16s;pointer-events:none}#__mt7.s{opacity:1;transform:translateX(-50%) translateY(0)}';
|
| 24 |
(document.head || document.documentElement).appendChild(s);
|
| 25 |
}
|
| 26 |
|
| 27 |
function enc(v) { return encodeURIComponent(v == null ? '' : String(v)); }
|
| 28 |
function absUrl(s) { try { return new URL(s || '', location.href).href; } catch (_) { return s || ''; } }
|
| 29 |
+
function captureId() { return Date.now().toString(36) + '-' + Math.random().toString(36).slice(2); }
|
| 30 |
|
| 31 |
function bestImageUrl(img) {
|
| 32 |
var srcset = img.getAttribute('srcset') || '';
|
|
|
|
| 42 |
function fireAction(url, title, w, h) {
|
| 43 |
if (capturing) return;
|
| 44 |
capturing = true;
|
| 45 |
+
var id = captureId();
|
| 46 |
+
var u = 'muse-action://board?captureId='+enc(id)+'&url='+enc(url)+'&source='+enc(location.href)+'&title='+enc(title)+'&w='+enc(w)+'&h='+enc(h);
|
|
|
|
| 47 |
window.location.href = u;
|
|
|
|
| 48 |
setTimeout(function(){ capturing = false; }, 1000);
|
| 49 |
}
|
| 50 |
|
| 51 |
function clearHide(){clearTimeout(hideTimer);}
|
| 52 |
function scheduleHide(){clearHide();hideTimer=setTimeout(hide,600);}
|
|
|
|
| 53 |
function hide(){if(!badge)return;badge.classList.remove('v');activeImg=null;}
|
|
|
|
| 54 |
function pos(el,img){var r=img.getBoundingClientRect();var x=r.right-80,y=r.top+10;if(x<r.left+4)x=r.left+4;if(x>innerWidth-90)x=innerWidth-90;if(y<4)y=4;if(y>innerHeight-40)y=innerHeight-40;el.style.left=x+'px';el.style.top=y+'px';}
|
| 55 |
|
| 56 |
function show(img){
|
|
|
|
| 69 |
}
|
| 70 |
|
| 71 |
function isValid(el){if(!el||el.tagName!=='IMG')return false;if(el===badge)return false;var r=el.getBoundingClientRect();return r.width>=MIN&&r.height>=MIN;}
|
|
|
|
| 72 |
document.addEventListener('mouseover',function(e){var t=e.target;if(badge&&(t===badge||badge.contains(t))){clearHide();return;}if(!isValid(t))return;if(t===activeImg){clearHide();return;}clearHide();clearTimeout(showTimer);showTimer=setTimeout(function(){show(t);},150);},true);
|
| 73 |
document.addEventListener('mouseout',function(e){var t=e.target;if(!t||t.tagName!=='IMG'||t!==activeImg)return;var rel=e.relatedTarget;if(badge&&rel&&(badge===rel||badge.contains(rel))){clearHide();return;}clearTimeout(showTimer);scheduleHide();},true);
|
| 74 |
window.addEventListener('scroll',function(){if(!badge||!activeImg)return;var r=activeImg.getBoundingClientRect();if(r.bottom<-20||r.top>innerHeight+20)hide();else pos(badge,activeImg);},{passive:true,capture:true});
|