@loupekit/sdk 0.9.3-next.38 → 0.9.3
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/index.global.js +6 -64
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +6 -64
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.global.js
CHANGED
|
@@ -335,14 +335,6 @@ var Loupe = (() => {
|
|
|
335
335
|
page stays visible and tappable; the list returns when the tool closes. */
|
|
336
336
|
.dock.inspecting { height: auto !important; }
|
|
337
337
|
.dock.inspecting .listhead, .dock.inspecting .list { display: none; }
|
|
338
|
-
/* The composer is a bottom sheet on a phone: full width, thumb-reachable, and it
|
|
339
|
-
scrolls when the on-screen keyboard is up. JS sets its position inline (hence the
|
|
340
|
-
!important) \u2014 on small screens the sheet wins. */
|
|
341
|
-
.composer {
|
|
342
|
-
top: auto !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
|
|
343
|
-
width: auto !important; max-height: 80vh; overflow-y: auto;
|
|
344
|
-
border-radius: 16px 16px 0 0; padding-bottom: 16px;
|
|
345
|
-
}
|
|
346
338
|
}
|
|
347
339
|
`
|
|
348
340
|
);
|
|
@@ -2466,26 +2458,6 @@ var Loupe = (() => {
|
|
|
2466
2458
|
for (let i = 0; i < s.length; i++) h = h * 31 + s.charCodeAt(i) | 0;
|
|
2467
2459
|
return h;
|
|
2468
2460
|
}
|
|
2469
|
-
function isTouchDevice() {
|
|
2470
|
-
try {
|
|
2471
|
-
return typeof window.matchMedia === "function" && window.matchMedia("(pointer: coarse)").matches;
|
|
2472
|
-
} catch {
|
|
2473
|
-
return false;
|
|
2474
|
-
}
|
|
2475
|
-
}
|
|
2476
|
-
function dataUrlToFile(dataUrl, name) {
|
|
2477
|
-
const m = /^data:([^;,]+)(;base64)?,([\s\S]*)$/.exec(dataUrl);
|
|
2478
|
-
if (!m) return null;
|
|
2479
|
-
const [, type, b64, payload = ""] = m;
|
|
2480
|
-
try {
|
|
2481
|
-
const raw = b64 ? atob(payload) : decodeURIComponent(payload);
|
|
2482
|
-
const bytes = new Uint8Array(raw.length);
|
|
2483
|
-
for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
|
|
2484
|
-
return new File([bytes], name, { type: type || "image/png" });
|
|
2485
|
-
} catch {
|
|
2486
|
-
return null;
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
2461
|
var LoupeApp = class {
|
|
2490
2462
|
constructor(cfg) {
|
|
2491
2463
|
this.comments = [];
|
|
@@ -2854,7 +2826,7 @@ var Loupe = (() => {
|
|
|
2854
2826
|
const recordBtn = this.toolBtn(RECORD_ICON, "Record", "record");
|
|
2855
2827
|
recordBtn.title = "Drag a box, record a screen video of it, and comment";
|
|
2856
2828
|
recordBtn.onclick = () => this.setMode(this.mode === "record" ? "off" : "record");
|
|
2857
|
-
const canRecord =
|
|
2829
|
+
const canRecord = typeof navigator.mediaDevices?.getDisplayMedia === "function";
|
|
2858
2830
|
tools.append(inspectBtn, freeBtn, regionBtn, ...canRecord ? [recordBtn] : []);
|
|
2859
2831
|
const listHead = el("div", "listhead");
|
|
2860
2832
|
listHead.append(document.createTextNode("Comments"));
|
|
@@ -3002,34 +2974,6 @@ var Loupe = (() => {
|
|
|
3002
2974
|
const region = { x: vp.x + window.scrollX, y: vp.y + window.scrollY, w: vp.w, h: vp.h, rel };
|
|
3003
2975
|
return { region, element: centerEl };
|
|
3004
2976
|
}
|
|
3005
|
-
/**
|
|
3006
|
-
* Touch path for the Region tool: capture what is on screen right now and open the
|
|
3007
|
-
* composer with it already attached. The reporter scrolls to the part of the page they
|
|
3008
|
-
* mean FIRST, then taps Region — no drag, so nothing fights the page scroll.
|
|
3009
|
-
*/
|
|
3010
|
-
async captureViewportForComposer() {
|
|
3011
|
-
const vp = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };
|
|
3012
|
-
const capture = this.cfg.captureRegion ?? captureRegionScreenshot;
|
|
3013
|
-
let shot;
|
|
3014
|
-
try {
|
|
3015
|
-
shot = await capture(vp);
|
|
3016
|
-
} catch {
|
|
3017
|
-
shot = void 0;
|
|
3018
|
-
}
|
|
3019
|
-
const file = shot ? dataUrlToFile(shot, "screenshot.png") : null;
|
|
3020
|
-
const docX = window.scrollX + vp.w / 2;
|
|
3021
|
-
const docY = window.scrollY + vp.h / 2;
|
|
3022
|
-
const docW = Math.max(1, document.documentElement.scrollWidth);
|
|
3023
|
-
const docH = Math.max(1, document.documentElement.scrollHeight);
|
|
3024
|
-
const offset = { x: clamp(docX / docW), y: clamp(docY / docH) };
|
|
3025
|
-
this.setMode("off");
|
|
3026
|
-
this.openComposer(
|
|
3027
|
-
{ kind: "free", offset, point: { x: docX, y: docY }, label: "Screenshot \xB7 attached" },
|
|
3028
|
-
8,
|
|
3029
|
-
window.innerHeight / 2,
|
|
3030
|
-
file ? [file] : []
|
|
3031
|
-
);
|
|
3032
|
-
}
|
|
3033
2977
|
/** Capture the selected viewport rect, then open the composer for a region comment. */
|
|
3034
2978
|
async finishRegion(vp) {
|
|
3035
2979
|
this.selbox.style.display = "none";
|
|
@@ -3113,6 +3057,7 @@ var Loupe = (() => {
|
|
|
3113
3057
|
document.removeEventListener("click", this.onClick, true);
|
|
3114
3058
|
document.removeEventListener("click", this.onFreeClick, true);
|
|
3115
3059
|
document.removeEventListener("pointerdown", this.onRegionDown, true);
|
|
3060
|
+
document.documentElement.style.touchAction = mode === "region" || mode === "record" ? "none" : "";
|
|
3116
3061
|
if (mode === "off") return;
|
|
3117
3062
|
document.addEventListener("keydown", this.onKey, true);
|
|
3118
3063
|
this.closeComposer();
|
|
@@ -3122,14 +3067,12 @@ var Loupe = (() => {
|
|
|
3122
3067
|
document.addEventListener("click", this.onClick, true);
|
|
3123
3068
|
} else if (mode === "free") {
|
|
3124
3069
|
document.addEventListener("click", this.onFreeClick, true);
|
|
3125
|
-
} else if (mode === "region" && isTouchDevice()) {
|
|
3126
|
-
void this.captureViewportForComposer();
|
|
3127
3070
|
} else if (mode === "region" || mode === "record") {
|
|
3128
3071
|
document.addEventListener("pointerdown", this.onRegionDown, true);
|
|
3129
3072
|
}
|
|
3130
3073
|
}
|
|
3131
3074
|
// ---- composer -------------------------------------------------------------
|
|
3132
|
-
openComposer(target, x, y
|
|
3075
|
+
openComposer(target, x, y) {
|
|
3133
3076
|
this.pending = target;
|
|
3134
3077
|
const isRecording = target.kind === "region" && !!target.recording;
|
|
3135
3078
|
const c = this.composer;
|
|
@@ -3137,14 +3080,14 @@ var Loupe = (() => {
|
|
|
3137
3080
|
const label = el(
|
|
3138
3081
|
"div",
|
|
3139
3082
|
"target",
|
|
3140
|
-
target.kind === "element" ? describe(target.element) : target.kind === "region" ? isRecording ? `\u23FA Recording \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : `Region \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` :
|
|
3083
|
+
target.kind === "element" ? describe(target.element) : target.kind === "region" ? isRecording ? `\u23FA Recording \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : `Region \xB7 ${Math.round(target.region.w)}\xD7${Math.round(target.region.h)} px` : "Free note \xB7 anywhere on the page"
|
|
3141
3084
|
);
|
|
3142
3085
|
const title = el("input", "title");
|
|
3143
3086
|
title.type = "text";
|
|
3144
3087
|
title.placeholder = "Title \u2014 one line: what's wrong, or what you need";
|
|
3145
3088
|
const ta = el("textarea");
|
|
3146
3089
|
ta.placeholder = isRecording ? "Describe the issue in this recording\u2026" : target.kind === "region" ? "Describe the issue in this area\u2026" : target.kind === "free" ? "Describe this note\u2026" : "Describe what should change here\u2026";
|
|
3147
|
-
const files =
|
|
3090
|
+
const files = [];
|
|
3148
3091
|
const attach = el("div", "attach");
|
|
3149
3092
|
const pick = el("button", "pick", "\uFF0B Attach images / videos");
|
|
3150
3093
|
const input = document.createElement("input");
|
|
@@ -3186,7 +3129,6 @@ var Loupe = (() => {
|
|
|
3186
3129
|
};
|
|
3187
3130
|
pick.onclick = () => input.click();
|
|
3188
3131
|
attach.append(pick, input, chips, err);
|
|
3189
|
-
if (files.length) drawChips();
|
|
3190
3132
|
const row = el("div", "row");
|
|
3191
3133
|
let box = null;
|
|
3192
3134
|
if (target.kind !== "free" && !isRecording) {
|
|
@@ -3218,7 +3160,7 @@ var Loupe = (() => {
|
|
|
3218
3160
|
const left = Math.min(Math.max(8, x + 12), window.innerWidth - w - 8);
|
|
3219
3161
|
const top = Math.min(Math.max(8, y + 12), window.innerHeight - h - 8);
|
|
3220
3162
|
Object.assign(c.style, { display: "block", left: left + "px", top: top + "px" });
|
|
3221
|
-
|
|
3163
|
+
ta.focus();
|
|
3222
3164
|
}
|
|
3223
3165
|
closeComposer() {
|
|
3224
3166
|
this.composer.style.display = "none";
|