@mahmulp/feedback-sdk 0.1.0 → 0.2.0
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/LICENSE +21 -21
- package/README.md +111 -110
- package/dist/index.cjs +133 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.global.js +14 -28
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +133 -39
- package/dist/index.js.map +1 -1
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.js.map +1 -1
- package/dist/svelte.js +133 -39
- package/dist/svelte.js.map +1 -1
- package/package.json +5 -7
package/dist/mock.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.cjs","sourcesContent":["import type {\
|
|
1
|
+
{"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.cjs","sourcesContent":["import type {\n CreateFeedbackInput,\n Feedback,\n FeedbackAuthor,\n FeedbackCoordinates,\n FeedbackStatus,\n FeedbackTransport,\n ListFeedbackQuery,\n ListFeedbackResult,\n} from \"./types.js\";\n\n/**\n * In-memory transport for local development / demos / tests.\n *\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\n *\n * No persistence, no network. Useful before the API is wired up.\n */\n\nexport interface MockTransportOptions {\n /** Optional initial feedback records (e.g. seeded from a fixture). */\n initial?: Feedback[];\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\n generateId?: () => string;\n /** Optional fake latency in ms, applied to every call. */\n latencyMs?: number;\n}\n\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\n /** Direct read of the in-memory store for tests / debugging. */\n _all(): Feedback[];\n _reset(): void;\n} {\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\n const genId = options.generateId ?? defaultGenerateId;\n const latency = options.latencyMs ?? 0;\n\n async function delay() {\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\n }\n\n return {\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\n await delay();\n // When `projectId` is empty, the SDK is relying on the API to scope by\n // key — return every record. When set, scope by it.\n const filtered = items\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\n .filter((f) => (query.status ? f.status === query.status : true))\n .map(clone);\n return { items: filtered };\n },\n\n async create(input: CreateFeedbackInput): Promise<Feedback> {\n await delay();\n const now = new Date().toISOString();\n const id = genId();\n const fb: Feedback = {\n id,\n projectId: input.projectId,\n pageUrl: input.pageUrl,\n selector: input.selector,\n coordinates: { ...input.coordinates },\n viewport: { ...input.viewport },\n status: \"open\",\n thread: input.comment\n ? [\n {\n id: `cm_${id}_0`,\n author: { ...input.comment.author },\n body: input.comment.body,\n createdAt: now,\n },\n ]\n : [],\n createdAt: now,\n updatedAt: now,\n };\n items.push(fb);\n return clone(fb);\n },\n\n async reply(\n feedbackId: string,\n comment: { author: FeedbackAuthor; body: string }\n ): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n const now = new Date().toISOString();\n fb.thread.push({\n id: `cm_${feedbackId}_${fb.thread.length}`,\n author: { ...comment.author },\n body: comment.body,\n createdAt: now,\n });\n fb.updatedAt = now;\n return clone(fb);\n },\n\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.status = status;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.coordinates = { ...coordinates };\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n _all() {\n return items.map(clone);\n },\n _reset() {\n items.length = 0;\n },\n };\n}\n\nfunction defaultGenerateId(): string {\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction clone<T>(value: T): T {\n // Structured clone is fine here; the records are plain JSON shapes.\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"]}
|
package/dist/mock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.js","sourcesContent":["import type {\
|
|
1
|
+
{"version":3,"sources":["../src/mock.ts"],"names":[],"mappings":"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","file":"mock.js","sourcesContent":["import type {\n CreateFeedbackInput,\n Feedback,\n FeedbackAuthor,\n FeedbackCoordinates,\n FeedbackStatus,\n FeedbackTransport,\n ListFeedbackQuery,\n ListFeedbackResult,\n} from \"./types.js\";\n\n/**\n * In-memory transport for local development / demos / tests.\n *\n * import { createMockTransport } from '@mahmulp/feedback-sdk/mock'\n *\n * No persistence, no network. Useful before the API is wired up.\n */\n\nexport interface MockTransportOptions {\n /** Optional initial feedback records (e.g. seeded from a fixture). */\n initial?: Feedback[];\n /** Override id generation (defaults to `fb_<timestamp>_<rand>`). */\n generateId?: () => string;\n /** Optional fake latency in ms, applied to every call. */\n latencyMs?: number;\n}\n\nexport function createMockTransport(options: MockTransportOptions = {}): FeedbackTransport & {\n /** Direct read of the in-memory store for tests / debugging. */\n _all(): Feedback[];\n _reset(): void;\n} {\n const items: Feedback[] = options.initial ? options.initial.map(clone) : [];\n const genId = options.generateId ?? defaultGenerateId;\n const latency = options.latencyMs ?? 0;\n\n async function delay() {\n if (latency > 0) await new Promise((r) => setTimeout(r, latency));\n }\n\n return {\n async list(query: ListFeedbackQuery): Promise<ListFeedbackResult> {\n await delay();\n // When `projectId` is empty, the SDK is relying on the API to scope by\n // key — return every record. When set, scope by it.\n const filtered = items\n .filter((f) => (query.projectId ? f.projectId === query.projectId : true))\n .filter((f) => (query.pageUrl ? f.pageUrl === query.pageUrl : true))\n .filter((f) => (query.status ? f.status === query.status : true))\n .map(clone);\n return { items: filtered };\n },\n\n async create(input: CreateFeedbackInput): Promise<Feedback> {\n await delay();\n const now = new Date().toISOString();\n const id = genId();\n const fb: Feedback = {\n id,\n projectId: input.projectId,\n pageUrl: input.pageUrl,\n selector: input.selector,\n coordinates: { ...input.coordinates },\n viewport: { ...input.viewport },\n status: \"open\",\n thread: input.comment\n ? [\n {\n id: `cm_${id}_0`,\n author: { ...input.comment.author },\n body: input.comment.body,\n createdAt: now,\n },\n ]\n : [],\n createdAt: now,\n updatedAt: now,\n };\n items.push(fb);\n return clone(fb);\n },\n\n async reply(\n feedbackId: string,\n comment: { author: FeedbackAuthor; body: string }\n ): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n const now = new Date().toISOString();\n fb.thread.push({\n id: `cm_${feedbackId}_${fb.thread.length}`,\n author: { ...comment.author },\n body: comment.body,\n createdAt: now,\n });\n fb.updatedAt = now;\n return clone(fb);\n },\n\n async setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.status = status;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async move(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.coordinates = { ...coordinates };\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n async uploadScreenshot(feedbackId: string, _blob: Blob): Promise<Feedback> {\n await delay();\n const fb = items.find((f) => f.id === feedbackId);\n if (!fb) throw new Error(`feedback not found: ${feedbackId}`);\n fb.screenshotKey = `screenshots/${feedbackId}.png`;\n fb.updatedAt = new Date().toISOString();\n return clone(fb);\n },\n\n _all() {\n return items.map(clone);\n },\n _reset() {\n items.length = 0;\n },\n };\n}\n\nfunction defaultGenerateId(): string {\n return `fb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction clone<T>(value: T): T {\n // Structured clone is fine here; the records are plain JSON shapes.\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"]}
|
package/dist/svelte.js
CHANGED
|
@@ -182,7 +182,10 @@ var LauncherManager = class {
|
|
|
182
182
|
__publicField(this, "state", {
|
|
183
183
|
enabled: false,
|
|
184
184
|
pinsVisible: true,
|
|
185
|
-
|
|
185
|
+
// Start collapsed — only the small reveal bubble is visible until the
|
|
186
|
+
// user clicks it. Less visual weight on the prototype out of the box;
|
|
187
|
+
// user opts in by clicking the bubble icon in the bottom-right.
|
|
188
|
+
launcherVisible: false
|
|
186
189
|
});
|
|
187
190
|
this.launcherEl = document.createElement("div");
|
|
188
191
|
this.launcherEl.className = "launcher";
|
|
@@ -234,6 +237,7 @@ var LauncherManager = class {
|
|
|
234
237
|
/** True when an event originated from the launcher's own UI. */
|
|
235
238
|
ownsNode(node) {
|
|
236
239
|
if (!node) return false;
|
|
240
|
+
if (typeof Node === "undefined" || !(node instanceof Node)) return false;
|
|
237
241
|
return this.launcherEl.contains(node) || this.revealEl.contains(node);
|
|
238
242
|
}
|
|
239
243
|
destroy() {
|
|
@@ -315,11 +319,34 @@ var PopoverManager = class {
|
|
|
315
319
|
});
|
|
316
320
|
return el;
|
|
317
321
|
}
|
|
322
|
+
/** True when a thread for this feedback is already open. */
|
|
323
|
+
isThreadOpenFor(feedbackId) {
|
|
324
|
+
return this.current?.type === "thread" && this.current.feedbackId === feedbackId;
|
|
325
|
+
}
|
|
318
326
|
showThread(feedback2, anchor, cb) {
|
|
327
|
+
if (this.current?.type === "thread" && this.current.feedbackId === feedback2.id) {
|
|
328
|
+
const fresh = this.buildThread(feedback2, cb);
|
|
329
|
+
this.current.el.replaceWith(fresh);
|
|
330
|
+
this.current = {
|
|
331
|
+
type: "thread",
|
|
332
|
+
el: fresh,
|
|
333
|
+
pageX: anchor.pageX,
|
|
334
|
+
pageY: anchor.pageY,
|
|
335
|
+
feedbackId: feedback2.id
|
|
336
|
+
};
|
|
337
|
+
this.repositionInternal();
|
|
338
|
+
return fresh;
|
|
339
|
+
}
|
|
319
340
|
this.hide();
|
|
320
341
|
const el = this.buildThread(feedback2, cb);
|
|
321
342
|
this.layer.appendChild(el);
|
|
322
|
-
this.current = {
|
|
343
|
+
this.current = {
|
|
344
|
+
type: "thread",
|
|
345
|
+
el,
|
|
346
|
+
pageX: anchor.pageX,
|
|
347
|
+
pageY: anchor.pageY,
|
|
348
|
+
feedbackId: feedback2.id
|
|
349
|
+
};
|
|
323
350
|
this.repositionInternal();
|
|
324
351
|
return el;
|
|
325
352
|
}
|
|
@@ -1027,33 +1054,65 @@ var Overlay = class {
|
|
|
1027
1054
|
});
|
|
1028
1055
|
}
|
|
1029
1056
|
layoutPins() {
|
|
1030
|
-
const
|
|
1057
|
+
const existing = /* @__PURE__ */ new Map();
|
|
1058
|
+
for (const node of Array.from(this.pinLayer.children)) {
|
|
1059
|
+
const id = node.dataset.feedbackId;
|
|
1060
|
+
if (id) existing.set(id, node);
|
|
1061
|
+
}
|
|
1062
|
+
const desiredOrder = [];
|
|
1063
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1031
1064
|
for (const fb of this.pendingFeedback) {
|
|
1065
|
+
seen.add(fb.id);
|
|
1032
1066
|
const target = findElement(fb.selector);
|
|
1033
1067
|
const projected = projectCoordinates(target, fb.coordinates);
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
if (
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1068
|
+
const left = `${projected.x - window.scrollX}px`;
|
|
1069
|
+
const top = `${projected.y - window.scrollY}px`;
|
|
1070
|
+
let pin = existing.get(fb.id);
|
|
1071
|
+
if (pin) {
|
|
1072
|
+
const classes = ["pin"];
|
|
1073
|
+
if (projected.orphaned) classes.push("orphaned");
|
|
1074
|
+
if (fb.status === "resolved") classes.push("resolved");
|
|
1075
|
+
if (fb.status === "archived") classes.push("archived");
|
|
1076
|
+
if (pin.classList.contains("dragging")) classes.push("dragging");
|
|
1077
|
+
pin.className = classes.join(" ");
|
|
1078
|
+
if (pin.style.left !== left) pin.style.left = left;
|
|
1079
|
+
if (pin.style.top !== top) pin.style.top = top;
|
|
1080
|
+
const label = pin.firstElementChild;
|
|
1081
|
+
const nextLabel = String(fb.thread.length || 1);
|
|
1082
|
+
if (label && label.textContent !== nextLabel) label.textContent = nextLabel;
|
|
1083
|
+
} else {
|
|
1084
|
+
pin = document.createElement("button");
|
|
1085
|
+
pin.type = "button";
|
|
1086
|
+
const classes = ["pin"];
|
|
1087
|
+
if (projected.orphaned) classes.push("orphaned");
|
|
1088
|
+
if (fb.status === "resolved") classes.push("resolved");
|
|
1089
|
+
if (fb.status === "archived") classes.push("archived");
|
|
1090
|
+
pin.className = classes.join(" ");
|
|
1091
|
+
pin.dataset.feedbackId = fb.id;
|
|
1092
|
+
pin.setAttribute("aria-label", `Feedback ${fb.id}`);
|
|
1093
|
+
pin.style.left = left;
|
|
1094
|
+
pin.style.top = top;
|
|
1095
|
+
const label = document.createElement("span");
|
|
1096
|
+
label.textContent = String(fb.thread.length || 1);
|
|
1097
|
+
pin.appendChild(label);
|
|
1098
|
+
pin.addEventListener("click", (e) => {
|
|
1099
|
+
e.stopPropagation();
|
|
1100
|
+
if (this.draggingPin === fb.id) return;
|
|
1101
|
+
const fresh = this.pendingFeedback.find((f) => f.id === fb.id) ?? fb;
|
|
1102
|
+
this.onPinClick?.(fresh);
|
|
1103
|
+
});
|
|
1104
|
+
this.attachDragHandlers(pin, fb);
|
|
1105
|
+
}
|
|
1106
|
+
desiredOrder.push(pin);
|
|
1107
|
+
}
|
|
1108
|
+
for (const [id, node] of existing) {
|
|
1109
|
+
if (!seen.has(id)) node.remove();
|
|
1110
|
+
}
|
|
1111
|
+
for (let i = 0; i < desiredOrder.length; i++) {
|
|
1112
|
+
const want = desiredOrder[i];
|
|
1113
|
+
const have = this.pinLayer.children[i];
|
|
1114
|
+
if (have !== want) this.pinLayer.insertBefore(want, have ?? null);
|
|
1055
1115
|
}
|
|
1056
|
-
this.pinLayer.replaceChildren(next);
|
|
1057
1116
|
}
|
|
1058
1117
|
destroy() {
|
|
1059
1118
|
if (this.rafHandle !== null) {
|
|
@@ -1172,8 +1231,6 @@ async function captureViewport(options = {}) {
|
|
|
1172
1231
|
const html2canvas = await loadHtml2Canvas();
|
|
1173
1232
|
if (!html2canvas) return null;
|
|
1174
1233
|
const host = document.querySelector(`[${HOST_ATTR2}]`);
|
|
1175
|
-
const previousVisibility = host?.style.visibility ?? "";
|
|
1176
|
-
if (host) host.style.visibility = "hidden";
|
|
1177
1234
|
try {
|
|
1178
1235
|
const canvas = await html2canvas(document.documentElement, {
|
|
1179
1236
|
backgroundColor: null,
|
|
@@ -1186,23 +1243,37 @@ async function captureViewport(options = {}) {
|
|
|
1186
1243
|
windowHeight: window.innerHeight,
|
|
1187
1244
|
logging: false,
|
|
1188
1245
|
useCORS: true,
|
|
1189
|
-
allowTaint: false
|
|
1246
|
+
allowTaint: false,
|
|
1247
|
+
ignoreElements: (el) => {
|
|
1248
|
+
if (host && (el === host || host.contains(el))) return true;
|
|
1249
|
+
if (el instanceof HTMLElement && el.hasAttribute(HOST_ATTR2)) return true;
|
|
1250
|
+
return false;
|
|
1251
|
+
}
|
|
1190
1252
|
});
|
|
1191
1253
|
return await canvasToBlob(canvas, opts.mimeType, opts.quality);
|
|
1192
|
-
} catch {
|
|
1254
|
+
} catch (err) {
|
|
1255
|
+
if (typeof console !== "undefined") {
|
|
1256
|
+
console.warn("[feedback-sdk] screenshot capture failed:", err);
|
|
1257
|
+
}
|
|
1193
1258
|
return null;
|
|
1194
|
-
} finally {
|
|
1195
|
-
if (host) host.style.visibility = previousVisibility;
|
|
1196
1259
|
}
|
|
1197
1260
|
}
|
|
1198
1261
|
var html2canvasPromise = null;
|
|
1262
|
+
var html2canvasMissingWarned = false;
|
|
1199
1263
|
async function loadHtml2Canvas() {
|
|
1200
1264
|
if (html2canvasPromise) return html2canvasPromise;
|
|
1201
1265
|
html2canvasPromise = (async () => {
|
|
1202
1266
|
try {
|
|
1203
|
-
const mod = await import('html2canvas');
|
|
1267
|
+
const mod = await import('html2canvas-pro');
|
|
1204
1268
|
return mod.default ?? mod ?? null;
|
|
1205
|
-
} catch {
|
|
1269
|
+
} catch (err) {
|
|
1270
|
+
if (!html2canvasMissingWarned && typeof console !== "undefined") {
|
|
1271
|
+
html2canvasMissingWarned = true;
|
|
1272
|
+
console.warn(
|
|
1273
|
+
"[feedback-sdk] screenshot capture disabled: failed to load `html2canvas-pro`. This shouldn't normally happen \u2014 html2canvas-pro is a direct dependency of the SDK. Pass `captureScreenshots: false` to silence this warning if intended.",
|
|
1274
|
+
err
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1206
1277
|
return null;
|
|
1207
1278
|
}
|
|
1208
1279
|
})();
|
|
@@ -1495,8 +1566,6 @@ function initFeedback(options) {
|
|
|
1495
1566
|
const updated = await transport.reply(fb.id, { author, body });
|
|
1496
1567
|
setAuthor(author);
|
|
1497
1568
|
replaceFeedback(updated);
|
|
1498
|
-
overlay.popoverManager().hide();
|
|
1499
|
-
activeThreadId = null;
|
|
1500
1569
|
openThread(updated);
|
|
1501
1570
|
} catch (err) {
|
|
1502
1571
|
reportError(err);
|
|
@@ -1506,8 +1575,6 @@ function initFeedback(options) {
|
|
|
1506
1575
|
try {
|
|
1507
1576
|
const updated = await transport.setStatus(fb.id, status);
|
|
1508
1577
|
replaceFeedback(updated);
|
|
1509
|
-
overlay.popoverManager().hide();
|
|
1510
|
-
activeThreadId = null;
|
|
1511
1578
|
openThread(updated);
|
|
1512
1579
|
} catch (err) {
|
|
1513
1580
|
reportError(err);
|
|
@@ -1555,7 +1622,8 @@ function initFeedback(options) {
|
|
|
1555
1622
|
}
|
|
1556
1623
|
async function refresh() {
|
|
1557
1624
|
try {
|
|
1558
|
-
const
|
|
1625
|
+
const pageUrl = getPageUrl();
|
|
1626
|
+
const result = await transport.list({ projectId: "", pageUrl });
|
|
1559
1627
|
state.feedbacks = result.items;
|
|
1560
1628
|
overlay.renderPins(state.feedbacks, openThread, onPinDragEnd);
|
|
1561
1629
|
} catch (err) {
|
|
@@ -1585,12 +1653,35 @@ function initFeedback(options) {
|
|
|
1585
1653
|
document.addEventListener("keydown", onKeyDown, true);
|
|
1586
1654
|
window.addEventListener("scroll", onWindowReposition, true);
|
|
1587
1655
|
window.addEventListener("resize", onWindowReposition);
|
|
1656
|
+
let lastSeenUrl = getPageUrl();
|
|
1657
|
+
function onMaybeNavigate() {
|
|
1658
|
+
const next = getPageUrl();
|
|
1659
|
+
if (next === lastSeenUrl) return;
|
|
1660
|
+
lastSeenUrl = next;
|
|
1661
|
+
void refresh();
|
|
1662
|
+
}
|
|
1663
|
+
const originalPushState = history.pushState.bind(history);
|
|
1664
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1665
|
+
history.pushState = function patchedPushState(...args) {
|
|
1666
|
+
const result = originalPushState(...args);
|
|
1667
|
+
queueMicrotask(onMaybeNavigate);
|
|
1668
|
+
return result;
|
|
1669
|
+
};
|
|
1670
|
+
history.replaceState = function patchedReplaceState(...args) {
|
|
1671
|
+
const result = originalReplaceState(...args);
|
|
1672
|
+
queueMicrotask(onMaybeNavigate);
|
|
1673
|
+
return result;
|
|
1674
|
+
};
|
|
1675
|
+
window.addEventListener("popstate", onMaybeNavigate);
|
|
1588
1676
|
void refresh();
|
|
1589
1677
|
overlay.setEnabledStyles(state.enabled);
|
|
1590
1678
|
const wantsLauncher = options.showLauncher !== false;
|
|
1591
1679
|
const launcherState = {
|
|
1592
1680
|
pinsVisible: options.pinsVisible !== false,
|
|
1593
|
-
|
|
1681
|
+
// Default to a collapsed launcher. The user reveals it by clicking the
|
|
1682
|
+
// small bubble button in the bottom-right corner. This keeps the SDK's
|
|
1683
|
+
// visual footprint near zero on first paint of the prototype.
|
|
1684
|
+
launcherVisible: false
|
|
1594
1685
|
};
|
|
1595
1686
|
overlay.setPinsVisible(launcherState.pinsVisible);
|
|
1596
1687
|
function syncLauncher() {
|
|
@@ -1647,6 +1738,9 @@ function initFeedback(options) {
|
|
|
1647
1738
|
document.removeEventListener("keydown", onKeyDown, true);
|
|
1648
1739
|
window.removeEventListener("scroll", onWindowReposition, true);
|
|
1649
1740
|
window.removeEventListener("resize", onWindowReposition);
|
|
1741
|
+
window.removeEventListener("popstate", onMaybeNavigate);
|
|
1742
|
+
history.pushState = originalPushState;
|
|
1743
|
+
history.replaceState = originalReplaceState;
|
|
1650
1744
|
overlay.destroy();
|
|
1651
1745
|
}
|
|
1652
1746
|
};
|