@emmaexcel/shakecursor 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/overlay.global.js +24 -23
- package/dist/overlay.js +24 -19
- package/package.json +1 -1
package/dist/overlay.global.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e,t,n){return Math.min(Math.max(e,t),n)}function n(e){return e.replace(/\s+/g,` `).trim()}function r(e,t=[]){return t.some(t=>{try{return e.matches(t)||!!e.closest(t)}catch{return!1}})}function i(){return/Mac|iPhone|iPad|iPod/i.test(window.navigator.platform)}function a(e){if(e.rangeCount===0)return null;let t=e.getRangeAt(0),n=t.getBoundingClientRect();return n.width>0||n.height>0?n:t.getClientRects()[0]??null}function o(e){return{rect:e,url:window.location.href,title:document.title}}function s(e){let t=n(e.innerText??``),r=e.tagName.toLowerCase(),i=e.getAttribute(`aria-label`),a=e.getAttribute(`title`),o=[i,a,t].find(Boolean);return{label:o?`${r}: ${o.slice(0,64)}`:r,data:void 0,mimeType:void 0,content:[`Selected element: <${r}>`,i?`ARIA label: ${i}`:``,a?`Title: ${a}`:``,t?`Visible text: ${t.slice(0,5e3)}`:``].filter(Boolean).join(`
|
|
2
2
|
`)}}function c(e){let t=e.currentSrc||e.src,n=e.alt||`No alt text`,r,i;try{let t=document.createElement(`canvas`);t.width=e.naturalWidth,t.height=e.naturalHeight;let n=t.getContext(`2d`);if(n){n.drawImage(e,0,0);let[a,o]=t.toDataURL(`image/jpeg`,.8).split(`,`);r=o,i=a.split(`:`)[1].split(`;`)[0]}}catch(e){console.warn(`Failed to capture image data (likely CORS):`,e)}return{label:`image: ${n.slice(0,64)}`,data:r,mimeType:i,content:[`Selected image`,`Alt text: ${n}`,`Source: ${t}`,`Rendered size: ${Math.round(e.width)}x${Math.round(e.height)}`,`Natural size: ${e.naturalWidth}x${e.naturalHeight}`].join(`
|
|
3
|
-
`)}}function l(e,t){
|
|
3
|
+
`)}}function l(e,t){if(r(e,t.blockedSelectors))return!1;let n=e.getBoundingClientRect(),i=window.innerWidth*window.innerHeight;return!(n.width*n.height>i*.5||t.allowedSelectors.length>0&&!r(e,t.allowedSelectors))}function u(e){let t=t=>{if(!e.isActive())return;let n=t.target;if(!(n instanceof HTMLElement)||e.isOverlayElement(n)){e.onHover(null);return}if(!l(n,e.config)){e.onHover(null);return}e.onHover(n.getBoundingClientRect())},r=()=>{!e.isActive()||!e.config.text||window.setTimeout(()=>{let t=window.getSelection(),r=n(t?.toString()??``);if(!t||!r)return;let i=a(t),s=t.anchorNode?.parentElement;!i||!s||!l(s,e.config)||e.onSelection({kind:`text`,label:`highlighted text`,content:r,...o(i)})},0)},i=t=>{if(!e.isActive())return;let r=t.target;if(!(r instanceof HTMLElement)||e.isOverlayElement(r)||!l(r,e.config)||n(window.getSelection()?.toString()??``))return;let i=r instanceof HTMLImageElement?r:r.querySelector(`img`),a=!!i;if(a&&!e.config.images||!a&&!e.config.elements)return;t.preventDefault(),t.stopPropagation();let u=i?c(i):s(r),d=i?i.getBoundingClientRect():r.getBoundingClientRect();e.onSelection({kind:i?`image`:`element`,label:u.label,content:u.content,data:u.data,mimeType:u.mimeType,...o(d)})};return document.addEventListener(`pointerover`,t),document.addEventListener(`mouseup`,r),document.addEventListener(`click`,i,!0),()=>{document.removeEventListener(`pointerover`,t),document.removeEventListener(`mouseup`,r),document.removeEventListener(`click`,i,!0)}}function d(e){let t=e.windowMs??650,n=e.cooldownMs??1e3,r=e.minSamples??7,i=e.minReversals??5,a=e.minDistance??340,o=e.minDeltaX??16,s=[],c=0,l=l=>{let u=performance.now();if(s.push({x:l.clientX,y:l.clientY,time:u}),s=s.filter(e=>u-e.time<t),s.length<r||u-c<n)return;let d=0,f=0,p=0;for(let e=1;e<s.length;e+=1){let t=s[e].x-s[e-1].x,n=s[e].y-s[e-1].y;if(f+=Math.hypot(t,n),Math.abs(t)<o)continue;let r=Math.sign(t);p!==0&&r!==p&&(d+=1),p=r}d>=i&&f>a&&(c=u,s=[],e.onShake())};return document.addEventListener(`pointermove`,l),()=>{document.removeEventListener(`pointermove`,l)}}var f=`http://localhost:11434/api/chat`,p=`qwen3-coder:480b-cloud`,m=`https://shakeai.onrender.com`;async function h(e,t){let n=e.provider??`ollama`,r=e.endpoint??f,i=e.model??p;if(n===`custom`){let n=await fetch(r,{method:`POST`,headers:{"Content-Type":`application/json`,...e.headers},body:JSON.stringify(t)});if(!n.ok)throw Error(`Custom endpoint returned ${n.status}`);let i=await n.json();return typeof i==`string`?i:i&&typeof i==`object`&&`answer`in i&&typeof i.answer==`string`?i.answer:i&&typeof i==`object`&&`content`in i&&typeof i.content==`string`?i.content:JSON.stringify(i,null,2)}let a=await fetch(r,{method:`POST`,headers:{"Content-Type":`application/json`,...e.headers},body:JSON.stringify({model:i,stream:!1,messages:[{role:`system`,content:`You are an in-page AI assistant. Use the selected website context to answer or transform content. Be direct and practical.`},{role:`user`,content:[`Page title: ${t.selection.title}`,`Page URL: ${t.selection.url}`,`Selection type: ${t.selection.kind}`,`Selection label: ${t.selection.label}`,`Selected context:`,t.selection.content,``,`User request: ${t.question}`].join(`
|
|
4
4
|
`)}]})});if(!a.ok)throw Error(`Ollama returned ${a.status}`);let o=await a.json();if(o.error)throw Error(o.error);return o.message?.content?.trim()||`No response returned.`}async function g(e){let t=await fetch(`${e.apiBaseUrl??m}/v1/ask`,{method:`POST`,headers:{"Content-Type":`application/json`,"x-site-key":e.siteKey},body:JSON.stringify(e.payload)}),n=await t.json();if(!t.ok||n.error)throw Error(n.error??`Hosted API returned ${t.status}`);return n.answer??`No response returned.`}function _(e){let n=document.createElement(`div`);n.dataset.aiOverlayRoot=`true`;let r=document.createElement(`style`);r.dataset.aiOverlayStyle=`true`,r.textContent=`
|
|
5
|
-
body.ai-overlay-active
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
body.ai-overlay-active * {
|
|
9
|
-
cursor: none !important;
|
|
5
|
+
body.ai-overlay-active,
|
|
6
|
+
body.ai-overlay-active * {
|
|
7
|
+
cursor: none !important;
|
|
10
8
|
}
|
|
11
9
|
`;let i=n.attachShadow({mode:`open`});document.head.append(r),document.body.append(n),i.innerHTML=`
|
|
12
10
|
<style>
|
|
@@ -27,27 +25,29 @@
|
|
|
27
25
|
position: fixed;
|
|
28
26
|
left: 0;
|
|
29
27
|
top: 0;
|
|
30
|
-
width:
|
|
31
|
-
height:
|
|
28
|
+
width: 24px;
|
|
29
|
+
height: 24px;
|
|
32
30
|
pointer-events: none;
|
|
33
31
|
z-index: 2147483647;
|
|
34
32
|
display: none;
|
|
35
|
-
|
|
36
|
-
margin-
|
|
37
|
-
|
|
38
|
-
filter: drop-shadow(0 0 8px rgba(66, 133, 244, 0.6));
|
|
33
|
+
margin-left: -2px;
|
|
34
|
+
margin-top: -2px;
|
|
35
|
+
filter: drop-shadow(0 4px 10px rgba(66, 133, 244, 0.3));
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
.custom-cursor.active {
|
|
42
39
|
display: block;
|
|
43
40
|
}
|
|
44
41
|
|
|
42
|
+
/* Rounded pointer shape */
|
|
45
43
|
.cursor-shape {
|
|
46
44
|
width: 100%;
|
|
47
45
|
height: 100%;
|
|
48
46
|
fill: white;
|
|
49
47
|
stroke: var(--ai-blue);
|
|
50
|
-
stroke-width:
|
|
48
|
+
stroke-width: 2.5px;
|
|
49
|
+
/* Using a circle with high radius as base for a rounded pointer */
|
|
50
|
+
stroke-linejoin: round;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.toast {
|
|
@@ -91,15 +91,15 @@
|
|
|
91
91
|
z-index: 2147483644;
|
|
92
92
|
pointer-events: none;
|
|
93
93
|
display: none;
|
|
94
|
-
/*
|
|
95
|
-
border:
|
|
94
|
+
/* Thinner, professional 2px border */
|
|
95
|
+
border: 2px solid transparent;
|
|
96
96
|
border-radius: var(--ai-radius);
|
|
97
|
-
/*
|
|
98
|
-
background:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
transition: all 0.
|
|
97
|
+
/* Pure transparent center, no fill at all */
|
|
98
|
+
background: none !important;
|
|
99
|
+
/* Conic gradient on border using border-image for absolute transparency in middle */
|
|
100
|
+
border-image: conic-gradient(var(--ai-blue), var(--ai-red), var(--ai-yellow), var(--ai-green), var(--ai-blue)) 1;
|
|
101
|
+
box-shadow: 0 0 15px rgba(66, 133, 244, 0.15);
|
|
102
|
+
transition: all 0.08s ease-out;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
.panel {
|
|
@@ -235,7 +235,8 @@
|
|
|
235
235
|
</style>
|
|
236
236
|
<div class="custom-cursor">
|
|
237
237
|
<svg viewBox="0 0 28 32" class="cursor-shape">
|
|
238
|
-
|
|
238
|
+
<!-- Rounded, professional pointer -->
|
|
239
|
+
<path d="M4,2 L4,26 L10,20 L15,30 L19,27 L14,18 L24,18 Z" stroke-linejoin="round" stroke-linecap="round" />
|
|
239
240
|
</svg>
|
|
240
241
|
</div>
|
|
241
242
|
<div class="toast" role="status">
|
|
@@ -250,7 +251,7 @@
|
|
|
250
251
|
<span class="kind"></span>
|
|
251
252
|
<strong class="label"></strong>
|
|
252
253
|
</div>
|
|
253
|
-
<button class="close" type="button" aria-label="Close AI prompt"
|
|
254
|
+
<button class="close" type="button" aria-label="Close AI prompt">×</button>
|
|
254
255
|
</div>
|
|
255
256
|
<form>
|
|
256
257
|
<textarea placeholder="Ask what to do with this selection..."></textarea>
|
package/dist/overlay.js
CHANGED
|
@@ -77,7 +77,9 @@ function s(e) {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
function c(e, t) {
|
|
80
|
-
|
|
80
|
+
if (n(e, t.blockedSelectors)) return !1;
|
|
81
|
+
let r = e.getBoundingClientRect(), i = window.innerWidth * window.innerHeight;
|
|
82
|
+
return !(r.width * r.height > i * .5 || t.allowedSelectors.length > 0 && !n(e, t.allowedSelectors));
|
|
81
83
|
}
|
|
82
84
|
function l(e) {
|
|
83
85
|
let n = (t) => {
|
|
@@ -216,7 +218,7 @@ function g(t) {
|
|
|
216
218
|
let n = document.createElement("div");
|
|
217
219
|
n.dataset.aiOverlayRoot = "true";
|
|
218
220
|
let r = document.createElement("style");
|
|
219
|
-
r.dataset.aiOverlayStyle = "true", r.textContent = "\n body.ai-overlay-active
|
|
221
|
+
r.dataset.aiOverlayStyle = "true", r.textContent = "\n body.ai-overlay-active,\n body.ai-overlay-active * {\n cursor: none !important;\n }\n ";
|
|
220
222
|
let i = n.attachShadow({ mode: "open" });
|
|
221
223
|
document.head.append(r), document.body.append(n), i.innerHTML = `
|
|
222
224
|
<style>
|
|
@@ -237,27 +239,29 @@ function g(t) {
|
|
|
237
239
|
position: fixed;
|
|
238
240
|
left: 0;
|
|
239
241
|
top: 0;
|
|
240
|
-
width:
|
|
241
|
-
height:
|
|
242
|
+
width: 24px;
|
|
243
|
+
height: 24px;
|
|
242
244
|
pointer-events: none;
|
|
243
245
|
z-index: 2147483647;
|
|
244
246
|
display: none;
|
|
245
|
-
|
|
246
|
-
margin-
|
|
247
|
-
|
|
248
|
-
filter: drop-shadow(0 0 8px rgba(66, 133, 244, 0.6));
|
|
247
|
+
margin-left: -2px;
|
|
248
|
+
margin-top: -2px;
|
|
249
|
+
filter: drop-shadow(0 4px 10px rgba(66, 133, 244, 0.3));
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
.custom-cursor.active {
|
|
252
253
|
display: block;
|
|
253
254
|
}
|
|
254
255
|
|
|
256
|
+
/* Rounded pointer shape */
|
|
255
257
|
.cursor-shape {
|
|
256
258
|
width: 100%;
|
|
257
259
|
height: 100%;
|
|
258
260
|
fill: white;
|
|
259
261
|
stroke: var(--ai-blue);
|
|
260
|
-
stroke-width:
|
|
262
|
+
stroke-width: 2.5px;
|
|
263
|
+
/* Using a circle with high radius as base for a rounded pointer */
|
|
264
|
+
stroke-linejoin: round;
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
.toast {
|
|
@@ -301,15 +305,15 @@ function g(t) {
|
|
|
301
305
|
z-index: 2147483644;
|
|
302
306
|
pointer-events: none;
|
|
303
307
|
display: none;
|
|
304
|
-
/*
|
|
305
|
-
border:
|
|
308
|
+
/* Thinner, professional 2px border */
|
|
309
|
+
border: 2px solid transparent;
|
|
306
310
|
border-radius: var(--ai-radius);
|
|
307
|
-
/*
|
|
308
|
-
background:
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
transition: all 0.
|
|
311
|
+
/* Pure transparent center, no fill at all */
|
|
312
|
+
background: none !important;
|
|
313
|
+
/* Conic gradient on border using border-image for absolute transparency in middle */
|
|
314
|
+
border-image: conic-gradient(var(--ai-blue), var(--ai-red), var(--ai-yellow), var(--ai-green), var(--ai-blue)) 1;
|
|
315
|
+
box-shadow: 0 0 15px rgba(66, 133, 244, 0.15);
|
|
316
|
+
transition: all 0.08s ease-out;
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
.panel {
|
|
@@ -445,7 +449,8 @@ function g(t) {
|
|
|
445
449
|
</style>
|
|
446
450
|
<div class="custom-cursor">
|
|
447
451
|
<svg viewBox="0 0 28 32" class="cursor-shape">
|
|
448
|
-
|
|
452
|
+
<!-- Rounded, professional pointer -->
|
|
453
|
+
<path d="M4,2 L4,26 L10,20 L15,30 L19,27 L14,18 L24,18 Z" stroke-linejoin="round" stroke-linecap="round" />
|
|
449
454
|
</svg>
|
|
450
455
|
</div>
|
|
451
456
|
<div class="toast" role="status">
|
|
@@ -460,7 +465,7 @@ function g(t) {
|
|
|
460
465
|
<span class="kind"></span>
|
|
461
466
|
<strong class="label"></strong>
|
|
462
467
|
</div>
|
|
463
|
-
<button class="close" type="button" aria-label="Close AI prompt"
|
|
468
|
+
<button class="close" type="button" aria-label="Close AI prompt">×</button>
|
|
464
469
|
</div>
|
|
465
470
|
<form>
|
|
466
471
|
<textarea placeholder="Ask what to do with this selection..."></textarea>
|