qapture2 0.7.3 → 0.7.5
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/README.md +9 -3
- package/dist/{chunk-C5WJFSMN.cjs → chunk-COQKFGKZ.cjs} +58 -36
- package/dist/{chunk-BM3ESR2O.js → chunk-FBFESAG6.js} +58 -36
- package/dist/index.cjs +5 -5
- package/dist/index.js +1 -1
- package/dist/next.cjs +4 -4
- package/dist/next.js +1 -1
- package/dist/standalone.cjs +2 -2
- package/dist/standalone.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -351,9 +351,15 @@ Because by default it is. The DOM engine re-draws your page; fonts shift,
|
|
|
351
351
|
shadows and gradients flatten, `<canvas>` and video come out blank. From
|
|
352
352
|
v0.7.3 a redrawn capture says so under the preview and offers a one-tap **Use
|
|
353
353
|
real screenshots**, which grants tab-share and re-shoots the same selection
|
|
354
|
-
with the exact engine below.
|
|
355
|
-
|
|
356
|
-
|
|
354
|
+
with the exact engine below.
|
|
355
|
+
|
|
356
|
+
That upgrade is Chromium-only, because it depends on `preferCurrentTab`. On
|
|
357
|
+
Safari and Firefox the redraw is the only engine there is — so from v0.7.4 the
|
|
358
|
+
card says so outright and points you at Chrome, rather than leaving you to
|
|
359
|
+
conclude the tool is broken. **If your app draws anything with inline SVG, a
|
|
360
|
+
`<canvas>`, or video, do your screenshot QA in Chrome.** A redraw will render
|
|
361
|
+
an SVG chart as bare outlines and a canvas as a blank box, every time, in any
|
|
362
|
+
tool built this way.
|
|
357
363
|
|
|
358
364
|
### `exact` — opt-in, pixel-for-pixel
|
|
359
365
|
|
|
@@ -1784,6 +1784,8 @@ var STR = {
|
|
|
1784
1784
|
exact_hint: "Screenshots become a real photo of the tab instead of a redraw. Asks once to share this tab; nothing leaves your device.",
|
|
1785
1785
|
redraw_notice: "This is a redraw of the page, not a real photo.",
|
|
1786
1786
|
redraw_action: "Use real screenshots",
|
|
1787
|
+
redraw_no_engine: "This browser cannot photograph a tab, so charts and canvases may come out wrong. Open the app in Chrome, Edge or Brave for true screenshots.",
|
|
1788
|
+
fab_title: "Qapture \u2014 click to open, drag to move it out of the way",
|
|
1787
1789
|
exact_on: "Pixel-exact screenshots on",
|
|
1788
1790
|
exact_off: "Back to redrawn screenshots",
|
|
1789
1791
|
exact_declined: "Staying on redrawn screenshots",
|
|
@@ -1980,6 +1982,8 @@ var STR = {
|
|
|
1980
1982
|
exact_hint: "\u062A\u0635\u0628\u062D \u0627\u0644\u0644\u0642\u0637\u0629 \u0635\u0648\u0631\u0629 \u062D\u0642\u064A\u0642\u064A\u0629 \u0644\u0644\u062A\u0628\u0648\u064A\u0628 \u0628\u062F\u0644 \u0625\u0639\u0627\u062F\u0629 \u0631\u0633\u0645\u0647. \u064A\u064F\u0637\u0644\u0628 \u0627\u0644\u0625\u0630\u0646 \u0645\u0631\u0629 \u0648\u0627\u062D\u062F\u0629\u060C \u0648\u0644\u0627 \u0634\u064A\u0621 \u064A\u063A\u0627\u062F\u0631 \u062C\u0647\u0627\u0632\u0643.",
|
|
1981
1983
|
redraw_notice: "\u0647\u0630\u0647 \u0625\u0639\u0627\u062F\u0629 \u0631\u0633\u0645 \u0644\u0644\u0635\u0641\u062D\u0629\u060C \u0648\u0644\u064A\u0633\u062A \u0635\u0648\u0631\u0629 \u062D\u0642\u064A\u0642\u064A\u0629.",
|
|
1982
1984
|
redraw_action: "\u0627\u0633\u062A\u062E\u062F\u0645 \u0644\u0642\u0637\u0627\u062A \u062D\u0642\u064A\u0642\u064A\u0629",
|
|
1985
|
+
redraw_no_engine: "\u0644\u0627 \u064A\u0633\u062A\u0637\u064A\u0639 \u0647\u0630\u0627 \u0627\u0644\u0645\u062A\u0635\u0641\u062D \u062A\u0635\u0648\u064A\u0631 \u0627\u0644\u062A\u0628\u0648\u064A\u0628\u060C \u0644\u0630\u0627 \u0642\u062F \u062A\u0638\u0647\u0631 \u0627\u0644\u0645\u062E\u0637\u0637\u0627\u062A \u0648\u0627\u0644\u0644\u0648\u062D\u0627\u062A \u0628\u0634\u0643\u0644 \u062E\u0627\u0637\u0626. \u0627\u0641\u062A\u062D \u0627\u0644\u062A\u0637\u0628\u064A\u0642 \u0641\u064A Chrome \u0623\u0648 Edge \u0623\u0648 Brave \u0644\u0644\u062D\u0635\u0648\u0644 \u0639\u0644\u0649 \u0644\u0642\u0637\u0627\u062A \u062D\u0642\u064A\u0642\u064A\u0629.",
|
|
1986
|
+
fab_title: "Qapture \u2014 \u0627\u0636\u063A\u0637 \u0644\u0644\u0641\u062A\u062D\u060C \u0648\u0627\u0633\u062D\u0628 \u0644\u062A\u062D\u0631\u064A\u0643\u0647 \u0645\u0646 \u0645\u0643\u0627\u0646\u0647",
|
|
1983
1987
|
exact_on: "\u062A\u0645 \u062A\u0641\u0639\u064A\u0644 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u0637\u0627\u0628\u0642\u0629",
|
|
1984
1988
|
exact_off: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u064F\u0639\u0627\u062F \u0631\u0633\u0645\u0647\u0627",
|
|
1985
1989
|
exact_declined: "\u0633\u0646\u0628\u0642\u0649 \u0639\u0644\u0649 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u064F\u0639\u0627\u062F \u0631\u0633\u0645\u0647\u0627",
|
|
@@ -5304,29 +5308,6 @@ function Icon({
|
|
|
5304
5308
|
function renderSvgElement(tag, attrs, key) {
|
|
5305
5309
|
return React__default.default.createElement(tag, { key, ...attrs });
|
|
5306
5310
|
}
|
|
5307
|
-
function isCoarsePointer() {
|
|
5308
|
-
if (typeof window === "undefined") return false;
|
|
5309
|
-
try {
|
|
5310
|
-
if (window.matchMedia && window.matchMedia("(pointer: coarse)").matches) return true;
|
|
5311
|
-
} catch {
|
|
5312
|
-
}
|
|
5313
|
-
return typeof navigator !== "undefined" && (navigator.maxTouchPoints || 0) > 0;
|
|
5314
|
-
}
|
|
5315
|
-
function useCoarsePointer() {
|
|
5316
|
-
const [coarse, setCoarse] = React.useState(() => isCoarsePointer());
|
|
5317
|
-
React.useEffect(() => {
|
|
5318
|
-
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
5319
|
-
const mq = window.matchMedia("(pointer: coarse)");
|
|
5320
|
-
const on = () => setCoarse(isCoarsePointer());
|
|
5321
|
-
if (mq.addEventListener) mq.addEventListener("change", on);
|
|
5322
|
-
else if (mq.addListener) mq.addListener(on);
|
|
5323
|
-
return () => {
|
|
5324
|
-
if (mq.removeEventListener) mq.removeEventListener("change", on);
|
|
5325
|
-
else if (mq.removeListener) mq.removeListener(on);
|
|
5326
|
-
};
|
|
5327
|
-
}, []);
|
|
5328
|
-
return coarse;
|
|
5329
|
-
}
|
|
5330
5311
|
var DEFAULT_LEFT = "calc(1.25rem + env(safe-area-inset-left))";
|
|
5331
5312
|
var DEFAULT_BOTTOM = "calc(5rem + env(safe-area-inset-bottom))";
|
|
5332
5313
|
var FAB_SIZE_PX = 56;
|
|
@@ -5383,8 +5364,7 @@ function clampFabPos(p, w = FAB_SIZE_PX, h = FAB_SIZE_PX) {
|
|
|
5383
5364
|
};
|
|
5384
5365
|
}
|
|
5385
5366
|
function QaFab() {
|
|
5386
|
-
const { isOpen, setIsOpen, notes, captureActive, namespace } = useQa();
|
|
5387
|
-
const coarse = useCoarsePointer();
|
|
5367
|
+
const { isOpen, setIsOpen, notes, captureActive, namespace, t } = useQa();
|
|
5388
5368
|
const [pos, setPos] = React.useState(() => loadFabPos(namespace));
|
|
5389
5369
|
const dragRef = React.useRef(null);
|
|
5390
5370
|
const didDragRef = React.useRef(false);
|
|
@@ -5402,6 +5382,7 @@ function QaFab() {
|
|
|
5402
5382
|
if (captureActive) return null;
|
|
5403
5383
|
const onPointerDown = (e) => {
|
|
5404
5384
|
if (dragRef.current) return;
|
|
5385
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
5405
5386
|
didDragRef.current = false;
|
|
5406
5387
|
const target = e.currentTarget;
|
|
5407
5388
|
const rect = target.getBoundingClientRect();
|
|
@@ -5463,7 +5444,7 @@ function QaFab() {
|
|
|
5463
5444
|
}
|
|
5464
5445
|
setIsOpen(!isOpen);
|
|
5465
5446
|
};
|
|
5466
|
-
const applied =
|
|
5447
|
+
const applied = pos ? clampFabPos(pos) : null;
|
|
5467
5448
|
const fabStyle = {
|
|
5468
5449
|
left: applied ? `${applied.left}px` : DEFAULT_LEFT,
|
|
5469
5450
|
bottom: applied ? `${applied.bottom}px` : DEFAULT_BOTTOM,
|
|
@@ -5478,13 +5459,13 @@ function QaFab() {
|
|
|
5478
5459
|
"data-qa-overlay": "true",
|
|
5479
5460
|
dir: "ltr",
|
|
5480
5461
|
onClick: handleClick,
|
|
5481
|
-
onPointerDown
|
|
5482
|
-
onPointerMove
|
|
5483
|
-
onPointerUp
|
|
5484
|
-
onPointerCancel
|
|
5462
|
+
onPointerDown,
|
|
5463
|
+
onPointerMove,
|
|
5464
|
+
onPointerUp,
|
|
5465
|
+
onPointerCancel,
|
|
5485
5466
|
"aria-label": "Qapture \u2014 testing notes",
|
|
5486
|
-
title: "
|
|
5487
|
-
className:
|
|
5467
|
+
title: t("fab_title"),
|
|
5468
|
+
className: "qa-fixed qa-flex qa-items-center qa-justify-center qa-rounded-full qa-bg-accent qa-elev-2 qa-print-hidden qa-fab-btn qa-touch-none",
|
|
5488
5469
|
style: fabStyle,
|
|
5489
5470
|
children: [
|
|
5490
5471
|
!isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7801,6 +7782,29 @@ function GuideSection() {
|
|
|
7801
7782
|
))
|
|
7802
7783
|
] });
|
|
7803
7784
|
}
|
|
7785
|
+
function isCoarsePointer() {
|
|
7786
|
+
if (typeof window === "undefined") return false;
|
|
7787
|
+
try {
|
|
7788
|
+
if (window.matchMedia && window.matchMedia("(pointer: coarse)").matches) return true;
|
|
7789
|
+
} catch {
|
|
7790
|
+
}
|
|
7791
|
+
return typeof navigator !== "undefined" && (navigator.maxTouchPoints || 0) > 0;
|
|
7792
|
+
}
|
|
7793
|
+
function useCoarsePointer() {
|
|
7794
|
+
const [coarse, setCoarse] = React.useState(() => isCoarsePointer());
|
|
7795
|
+
React.useEffect(() => {
|
|
7796
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
7797
|
+
const mq = window.matchMedia("(pointer: coarse)");
|
|
7798
|
+
const on = () => setCoarse(isCoarsePointer());
|
|
7799
|
+
if (mq.addEventListener) mq.addEventListener("change", on);
|
|
7800
|
+
else if (mq.addListener) mq.addListener(on);
|
|
7801
|
+
return () => {
|
|
7802
|
+
if (mq.removeEventListener) mq.removeEventListener("change", on);
|
|
7803
|
+
else if (mq.removeListener) mq.removeListener(on);
|
|
7804
|
+
};
|
|
7805
|
+
}, []);
|
|
7806
|
+
return coarse;
|
|
7807
|
+
}
|
|
7804
7808
|
var TABS = [
|
|
7805
7809
|
{ key: "notes", labelKey: "tab_notes", icon: "StickyNote" },
|
|
7806
7810
|
{ key: "logins", labelKey: "tab_logins", icon: "KeyRound" },
|
|
@@ -9758,7 +9762,7 @@ function CaptureMode() {
|
|
|
9758
9762
|
)
|
|
9759
9763
|
] })
|
|
9760
9764
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "qa-py-4 qa-text-xs qa-text-slate-400", children: t("no_shot") }),
|
|
9761
|
-
shotUrl && shotEngine === "dom" && exactShots.
|
|
9765
|
+
shotUrl && shotEngine === "dom" && (exactShots.status !== "live" && exactShots.supported ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9762
9766
|
"span",
|
|
9763
9767
|
{
|
|
9764
9768
|
"data-qa-redraw-offer": "true",
|
|
@@ -9784,7 +9788,25 @@ function CaptureMode() {
|
|
|
9784
9788
|
)
|
|
9785
9789
|
]
|
|
9786
9790
|
}
|
|
9787
|
-
)
|
|
9791
|
+
) : !exactShots.supported ? (
|
|
9792
|
+
// Safari and Firefox have no way to photograph the tab, so
|
|
9793
|
+
// there is nothing to offer — but saying NOTHING was the real
|
|
9794
|
+
// failure. A tester watching an SVG chart come back as bare
|
|
9795
|
+
// outlines concludes the tool is broken and files it as a bug,
|
|
9796
|
+
// over and over. Name the limit and name the way out.
|
|
9797
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9798
|
+
"span",
|
|
9799
|
+
{
|
|
9800
|
+
"data-qa-redraw-note": "true",
|
|
9801
|
+
className: "qa-mt-1.5 qa-block qa-text-center qa-text-10 qa-text-mid",
|
|
9802
|
+
children: [
|
|
9803
|
+
t("redraw_notice"),
|
|
9804
|
+
" ",
|
|
9805
|
+
t("redraw_no_engine")
|
|
9806
|
+
]
|
|
9807
|
+
}
|
|
9808
|
+
)
|
|
9809
|
+
) : null)
|
|
9788
9810
|
]
|
|
9789
9811
|
}
|
|
9790
9812
|
),
|
|
@@ -10079,5 +10101,5 @@ function Qapture({ config }) {
|
|
|
10079
10101
|
exports.Qapture = Qapture;
|
|
10080
10102
|
exports.deleteQaDatabase = deleteQaDatabase;
|
|
10081
10103
|
exports.initQaStudio = initQaStudio;
|
|
10082
|
-
//# sourceMappingURL=chunk-
|
|
10083
|
-
//# sourceMappingURL=chunk-
|
|
10104
|
+
//# sourceMappingURL=chunk-COQKFGKZ.cjs.map
|
|
10105
|
+
//# sourceMappingURL=chunk-COQKFGKZ.cjs.map
|
|
@@ -1777,6 +1777,8 @@ var STR = {
|
|
|
1777
1777
|
exact_hint: "Screenshots become a real photo of the tab instead of a redraw. Asks once to share this tab; nothing leaves your device.",
|
|
1778
1778
|
redraw_notice: "This is a redraw of the page, not a real photo.",
|
|
1779
1779
|
redraw_action: "Use real screenshots",
|
|
1780
|
+
redraw_no_engine: "This browser cannot photograph a tab, so charts and canvases may come out wrong. Open the app in Chrome, Edge or Brave for true screenshots.",
|
|
1781
|
+
fab_title: "Qapture \u2014 click to open, drag to move it out of the way",
|
|
1780
1782
|
exact_on: "Pixel-exact screenshots on",
|
|
1781
1783
|
exact_off: "Back to redrawn screenshots",
|
|
1782
1784
|
exact_declined: "Staying on redrawn screenshots",
|
|
@@ -1973,6 +1975,8 @@ var STR = {
|
|
|
1973
1975
|
exact_hint: "\u062A\u0635\u0628\u062D \u0627\u0644\u0644\u0642\u0637\u0629 \u0635\u0648\u0631\u0629 \u062D\u0642\u064A\u0642\u064A\u0629 \u0644\u0644\u062A\u0628\u0648\u064A\u0628 \u0628\u062F\u0644 \u0625\u0639\u0627\u062F\u0629 \u0631\u0633\u0645\u0647. \u064A\u064F\u0637\u0644\u0628 \u0627\u0644\u0625\u0630\u0646 \u0645\u0631\u0629 \u0648\u0627\u062D\u062F\u0629\u060C \u0648\u0644\u0627 \u0634\u064A\u0621 \u064A\u063A\u0627\u062F\u0631 \u062C\u0647\u0627\u0632\u0643.",
|
|
1974
1976
|
redraw_notice: "\u0647\u0630\u0647 \u0625\u0639\u0627\u062F\u0629 \u0631\u0633\u0645 \u0644\u0644\u0635\u0641\u062D\u0629\u060C \u0648\u0644\u064A\u0633\u062A \u0635\u0648\u0631\u0629 \u062D\u0642\u064A\u0642\u064A\u0629.",
|
|
1975
1977
|
redraw_action: "\u0627\u0633\u062A\u062E\u062F\u0645 \u0644\u0642\u0637\u0627\u062A \u062D\u0642\u064A\u0642\u064A\u0629",
|
|
1978
|
+
redraw_no_engine: "\u0644\u0627 \u064A\u0633\u062A\u0637\u064A\u0639 \u0647\u0630\u0627 \u0627\u0644\u0645\u062A\u0635\u0641\u062D \u062A\u0635\u0648\u064A\u0631 \u0627\u0644\u062A\u0628\u0648\u064A\u0628\u060C \u0644\u0630\u0627 \u0642\u062F \u062A\u0638\u0647\u0631 \u0627\u0644\u0645\u062E\u0637\u0637\u0627\u062A \u0648\u0627\u0644\u0644\u0648\u062D\u0627\u062A \u0628\u0634\u0643\u0644 \u062E\u0627\u0637\u0626. \u0627\u0641\u062A\u062D \u0627\u0644\u062A\u0637\u0628\u064A\u0642 \u0641\u064A Chrome \u0623\u0648 Edge \u0623\u0648 Brave \u0644\u0644\u062D\u0635\u0648\u0644 \u0639\u0644\u0649 \u0644\u0642\u0637\u0627\u062A \u062D\u0642\u064A\u0642\u064A\u0629.",
|
|
1979
|
+
fab_title: "Qapture \u2014 \u0627\u0636\u063A\u0637 \u0644\u0644\u0641\u062A\u062D\u060C \u0648\u0627\u0633\u062D\u0628 \u0644\u062A\u062D\u0631\u064A\u0643\u0647 \u0645\u0646 \u0645\u0643\u0627\u0646\u0647",
|
|
1976
1980
|
exact_on: "\u062A\u0645 \u062A\u0641\u0639\u064A\u0644 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u0637\u0627\u0628\u0642\u0629",
|
|
1977
1981
|
exact_off: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u064F\u0639\u0627\u062F \u0631\u0633\u0645\u0647\u0627",
|
|
1978
1982
|
exact_declined: "\u0633\u0646\u0628\u0642\u0649 \u0639\u0644\u0649 \u0627\u0644\u0644\u0642\u0637\u0627\u062A \u0627\u0644\u0645\u064F\u0639\u0627\u062F \u0631\u0633\u0645\u0647\u0627",
|
|
@@ -5297,29 +5301,6 @@ function Icon({
|
|
|
5297
5301
|
function renderSvgElement(tag, attrs, key) {
|
|
5298
5302
|
return React.createElement(tag, { key, ...attrs });
|
|
5299
5303
|
}
|
|
5300
|
-
function isCoarsePointer() {
|
|
5301
|
-
if (typeof window === "undefined") return false;
|
|
5302
|
-
try {
|
|
5303
|
-
if (window.matchMedia && window.matchMedia("(pointer: coarse)").matches) return true;
|
|
5304
|
-
} catch {
|
|
5305
|
-
}
|
|
5306
|
-
return typeof navigator !== "undefined" && (navigator.maxTouchPoints || 0) > 0;
|
|
5307
|
-
}
|
|
5308
|
-
function useCoarsePointer() {
|
|
5309
|
-
const [coarse, setCoarse] = useState(() => isCoarsePointer());
|
|
5310
|
-
useEffect(() => {
|
|
5311
|
-
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
5312
|
-
const mq = window.matchMedia("(pointer: coarse)");
|
|
5313
|
-
const on = () => setCoarse(isCoarsePointer());
|
|
5314
|
-
if (mq.addEventListener) mq.addEventListener("change", on);
|
|
5315
|
-
else if (mq.addListener) mq.addListener(on);
|
|
5316
|
-
return () => {
|
|
5317
|
-
if (mq.removeEventListener) mq.removeEventListener("change", on);
|
|
5318
|
-
else if (mq.removeListener) mq.removeListener(on);
|
|
5319
|
-
};
|
|
5320
|
-
}, []);
|
|
5321
|
-
return coarse;
|
|
5322
|
-
}
|
|
5323
5304
|
var DEFAULT_LEFT = "calc(1.25rem + env(safe-area-inset-left))";
|
|
5324
5305
|
var DEFAULT_BOTTOM = "calc(5rem + env(safe-area-inset-bottom))";
|
|
5325
5306
|
var FAB_SIZE_PX = 56;
|
|
@@ -5376,8 +5357,7 @@ function clampFabPos(p, w = FAB_SIZE_PX, h = FAB_SIZE_PX) {
|
|
|
5376
5357
|
};
|
|
5377
5358
|
}
|
|
5378
5359
|
function QaFab() {
|
|
5379
|
-
const { isOpen, setIsOpen, notes, captureActive, namespace } = useQa();
|
|
5380
|
-
const coarse = useCoarsePointer();
|
|
5360
|
+
const { isOpen, setIsOpen, notes, captureActive, namespace, t } = useQa();
|
|
5381
5361
|
const [pos, setPos] = useState(() => loadFabPos(namespace));
|
|
5382
5362
|
const dragRef = useRef(null);
|
|
5383
5363
|
const didDragRef = useRef(false);
|
|
@@ -5395,6 +5375,7 @@ function QaFab() {
|
|
|
5395
5375
|
if (captureActive) return null;
|
|
5396
5376
|
const onPointerDown = (e) => {
|
|
5397
5377
|
if (dragRef.current) return;
|
|
5378
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
5398
5379
|
didDragRef.current = false;
|
|
5399
5380
|
const target = e.currentTarget;
|
|
5400
5381
|
const rect = target.getBoundingClientRect();
|
|
@@ -5456,7 +5437,7 @@ function QaFab() {
|
|
|
5456
5437
|
}
|
|
5457
5438
|
setIsOpen(!isOpen);
|
|
5458
5439
|
};
|
|
5459
|
-
const applied =
|
|
5440
|
+
const applied = pos ? clampFabPos(pos) : null;
|
|
5460
5441
|
const fabStyle = {
|
|
5461
5442
|
left: applied ? `${applied.left}px` : DEFAULT_LEFT,
|
|
5462
5443
|
bottom: applied ? `${applied.bottom}px` : DEFAULT_BOTTOM,
|
|
@@ -5471,13 +5452,13 @@ function QaFab() {
|
|
|
5471
5452
|
"data-qa-overlay": "true",
|
|
5472
5453
|
dir: "ltr",
|
|
5473
5454
|
onClick: handleClick,
|
|
5474
|
-
onPointerDown
|
|
5475
|
-
onPointerMove
|
|
5476
|
-
onPointerUp
|
|
5477
|
-
onPointerCancel
|
|
5455
|
+
onPointerDown,
|
|
5456
|
+
onPointerMove,
|
|
5457
|
+
onPointerUp,
|
|
5458
|
+
onPointerCancel,
|
|
5478
5459
|
"aria-label": "Qapture \u2014 testing notes",
|
|
5479
|
-
title: "
|
|
5480
|
-
className:
|
|
5460
|
+
title: t("fab_title"),
|
|
5461
|
+
className: "qa-fixed qa-flex qa-items-center qa-justify-center qa-rounded-full qa-bg-accent qa-elev-2 qa-print-hidden qa-fab-btn qa-touch-none",
|
|
5481
5462
|
style: fabStyle,
|
|
5482
5463
|
children: [
|
|
5483
5464
|
!isOpen && /* @__PURE__ */ jsx(
|
|
@@ -7794,6 +7775,29 @@ function GuideSection() {
|
|
|
7794
7775
|
))
|
|
7795
7776
|
] });
|
|
7796
7777
|
}
|
|
7778
|
+
function isCoarsePointer() {
|
|
7779
|
+
if (typeof window === "undefined") return false;
|
|
7780
|
+
try {
|
|
7781
|
+
if (window.matchMedia && window.matchMedia("(pointer: coarse)").matches) return true;
|
|
7782
|
+
} catch {
|
|
7783
|
+
}
|
|
7784
|
+
return typeof navigator !== "undefined" && (navigator.maxTouchPoints || 0) > 0;
|
|
7785
|
+
}
|
|
7786
|
+
function useCoarsePointer() {
|
|
7787
|
+
const [coarse, setCoarse] = useState(() => isCoarsePointer());
|
|
7788
|
+
useEffect(() => {
|
|
7789
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
7790
|
+
const mq = window.matchMedia("(pointer: coarse)");
|
|
7791
|
+
const on = () => setCoarse(isCoarsePointer());
|
|
7792
|
+
if (mq.addEventListener) mq.addEventListener("change", on);
|
|
7793
|
+
else if (mq.addListener) mq.addListener(on);
|
|
7794
|
+
return () => {
|
|
7795
|
+
if (mq.removeEventListener) mq.removeEventListener("change", on);
|
|
7796
|
+
else if (mq.removeListener) mq.removeListener(on);
|
|
7797
|
+
};
|
|
7798
|
+
}, []);
|
|
7799
|
+
return coarse;
|
|
7800
|
+
}
|
|
7797
7801
|
var TABS = [
|
|
7798
7802
|
{ key: "notes", labelKey: "tab_notes", icon: "StickyNote" },
|
|
7799
7803
|
{ key: "logins", labelKey: "tab_logins", icon: "KeyRound" },
|
|
@@ -9751,7 +9755,7 @@ function CaptureMode() {
|
|
|
9751
9755
|
)
|
|
9752
9756
|
] })
|
|
9753
9757
|
) : /* @__PURE__ */ jsx("span", { className: "qa-py-4 qa-text-xs qa-text-slate-400", children: t("no_shot") }),
|
|
9754
|
-
shotUrl && shotEngine === "dom" && exactShots.
|
|
9758
|
+
shotUrl && shotEngine === "dom" && (exactShots.status !== "live" && exactShots.supported ? /* @__PURE__ */ jsxs(
|
|
9755
9759
|
"span",
|
|
9756
9760
|
{
|
|
9757
9761
|
"data-qa-redraw-offer": "true",
|
|
@@ -9777,7 +9781,25 @@ function CaptureMode() {
|
|
|
9777
9781
|
)
|
|
9778
9782
|
]
|
|
9779
9783
|
}
|
|
9780
|
-
)
|
|
9784
|
+
) : !exactShots.supported ? (
|
|
9785
|
+
// Safari and Firefox have no way to photograph the tab, so
|
|
9786
|
+
// there is nothing to offer — but saying NOTHING was the real
|
|
9787
|
+
// failure. A tester watching an SVG chart come back as bare
|
|
9788
|
+
// outlines concludes the tool is broken and files it as a bug,
|
|
9789
|
+
// over and over. Name the limit and name the way out.
|
|
9790
|
+
/* @__PURE__ */ jsxs(
|
|
9791
|
+
"span",
|
|
9792
|
+
{
|
|
9793
|
+
"data-qa-redraw-note": "true",
|
|
9794
|
+
className: "qa-mt-1.5 qa-block qa-text-center qa-text-10 qa-text-mid",
|
|
9795
|
+
children: [
|
|
9796
|
+
t("redraw_notice"),
|
|
9797
|
+
" ",
|
|
9798
|
+
t("redraw_no_engine")
|
|
9799
|
+
]
|
|
9800
|
+
}
|
|
9801
|
+
)
|
|
9802
|
+
) : null)
|
|
9781
9803
|
]
|
|
9782
9804
|
}
|
|
9783
9805
|
),
|
|
@@ -10070,5 +10092,5 @@ function Qapture({ config }) {
|
|
|
10070
10092
|
}
|
|
10071
10093
|
|
|
10072
10094
|
export { Qapture, deleteQaDatabase, initQaStudio };
|
|
10073
|
-
//# sourceMappingURL=chunk-
|
|
10074
|
-
//# sourceMappingURL=chunk-
|
|
10095
|
+
//# sourceMappingURL=chunk-FBFESAG6.js.map
|
|
10096
|
+
//# sourceMappingURL=chunk-FBFESAG6.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkCOQKFGKZ_cjs = require('./chunk-COQKFGKZ.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "QaStudio", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkCOQKFGKZ_cjs.Qapture; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "Qapture", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkCOQKFGKZ_cjs.Qapture; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "deleteQaDatabase", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkCOQKFGKZ_cjs.deleteQaDatabase; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "initQaStudio", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkCOQKFGKZ_cjs.initQaStudio; }
|
|
22
22
|
});
|
|
23
23
|
//# sourceMappingURL=index.cjs.map
|
|
24
24
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.js
CHANGED
package/dist/next.cjs
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkCOQKFGKZ_cjs = require('./chunk-COQKFGKZ.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "QaStudio", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkCOQKFGKZ_cjs.Qapture; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "Qapture", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkCOQKFGKZ_cjs.Qapture; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "initQaStudio", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkCOQKFGKZ_cjs.initQaStudio; }
|
|
19
19
|
});
|
|
20
20
|
//# sourceMappingURL=next.cjs.map
|
|
21
21
|
//# sourceMappingURL=next.cjs.map
|
package/dist/next.js
CHANGED
package/dist/standalone.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkCOQKFGKZ_cjs = require('./chunk-COQKFGKZ.cjs');
|
|
4
4
|
|
|
5
5
|
// src/standalone.ts
|
|
6
6
|
if (typeof window !== "undefined" && typeof customElements !== "undefined" && !customElements.get("qapture-widget")) {
|
|
@@ -38,7 +38,7 @@ if (typeof window !== "undefined" && typeof customElements !== "undefined" && !c
|
|
|
38
38
|
|
|
39
39
|
Object.defineProperty(exports, "initQaStudio", {
|
|
40
40
|
enumerable: true,
|
|
41
|
-
get: function () { return
|
|
41
|
+
get: function () { return chunkCOQKFGKZ_cjs.initQaStudio; }
|
|
42
42
|
});
|
|
43
43
|
//# sourceMappingURL=standalone.cjs.map
|
|
44
44
|
//# sourceMappingURL=standalone.cjs.map
|
package/dist/standalone.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qapture2",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "Drop-in, AI-aware in-browser QA capture widget. A tester annotates the live app (element/region + auto-screenshot + note), tracks a graded testing journey, and exports a ZIP your own coding agent reads. Ships zero AI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"browser-test": "node scripts/browser-test.mjs",
|
|
91
91
|
"capture-accuracy-test": "node scripts/capture-accuracy-test.mjs",
|
|
92
92
|
"element-capture-test": "node scripts/element-capture-test.mjs",
|
|
93
|
+
"svg-vars-test": "node scripts/svg-vars-test.mjs",
|
|
93
94
|
"loop-features-test": "node scripts/loop-features-test.mjs",
|
|
94
95
|
"walk-test": "node scripts/walk-test.mjs",
|
|
95
96
|
"modern-css-test": "node scripts/modern-css-test.mjs",
|