impact-nova 2.5.22 → 2.6.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/dist/components/data/ag-grid-react/ag-grid.types.d.ts +2 -0
- package/dist/components/data/ag-grid-react/headers/components/header-info.d.ts +9 -3
- package/dist/components/data/ag-grid-react/headers/components/header-info.js +69 -61
- package/dist/components/data/ag-grid-react/headers/components/info-modal.js +8 -8
- package/dist/components/flows/guidance/guidance-layer.js +34 -31
- package/dist/components/flows/guidance/hooks/useGuidanceOverlayGeometry.js +29 -20
- package/dist/components/flows/guidance/renderers/announcement-renderer.d.ts +1 -1
- package/dist/components/flows/guidance/renderers/announcement-renderer.js +74 -28
- package/dist/components/flows/guidance/renderers/guidance-action-tap-icon.d.ts +5 -0
- package/dist/components/flows/guidance/renderers/guidance-action-tap-icon.js +68 -0
- package/dist/components/flows/guidance/renderers/guidance-announcement-surface.d.ts +5 -0
- package/dist/components/flows/guidance/renderers/guidance-announcement-surface.js +76 -0
- package/dist/components/flows/guidance/renderers/guidance-card-shared.d.ts +43 -2
- package/dist/components/flows/guidance/renderers/guidance-card-shared.js +322 -99
- package/dist/components/flows/guidance/renderers/guidance-renderer-shared.d.ts +3 -0
- package/dist/components/flows/guidance/renderers/guidance-renderer-shared.js +189 -148
- package/dist/components/flows/guidance/renderers/guidance-shortcut-display.d.ts +9 -0
- package/dist/components/flows/guidance/renderers/guidance-shortcut-display.js +36 -0
- package/dist/components/flows/guidance/renderers/guidance-tour-overlay.d.ts +2 -1
- package/dist/components/flows/guidance/renderers/guidance-tour-overlay.js +152 -89
- package/dist/i18n/defaultMessages.d.ts +6 -0
- package/dist/i18n/defaultMessages.js +13 -9
- package/dist/i18n/locales/de.js +4 -0
- package/dist/i18n/locales/es.js +4 -0
- package/dist/i18n/locales/hi.js +4 -0
- package/dist/i18n/locales/kn.js +4 -0
- package/dist/impact-nova-tokens.scss +22 -0
- package/dist/impact-nova.css +1 -1
- package/dist/lib/guidance/engine/guidance-engine.d.ts +9 -0
- package/dist/lib/guidance/engine/guidance-engine.js +127 -65
- package/dist/lib/guidance/engine/manifest-validator.js +37 -30
- package/dist/lib/guidance/targets/target-resolver.d.ts +1 -1
- package/dist/lib/guidance/targets/target-resolver.js +32 -30
- package/dist/lib/guidance/types/guidance.types.d.ts +41 -0
- package/dist/llms/rules/installation.js +1 -1
- package/dist/llms/rules/requirements.js +1 -1
- package/package.json +2 -1
|
@@ -6,6 +6,7 @@ import { GuidanceTargetRefRegistry } from '../targets/ref-registry';
|
|
|
6
6
|
type Listener = () => void;
|
|
7
7
|
export declare class GuidanceEngine {
|
|
8
8
|
private sessionState;
|
|
9
|
+
private activationToken;
|
|
9
10
|
private readonly listeners;
|
|
10
11
|
private readonly eventHandlers;
|
|
11
12
|
private readonly guideRegistry;
|
|
@@ -47,9 +48,17 @@ export declare class GuidanceEngine {
|
|
|
47
48
|
private resolveGuideStartStepIndex;
|
|
48
49
|
dismiss(dismissMode?: 'session' | 'forever' | 'snoozed'): Promise<void>;
|
|
49
50
|
snooze(guideId?: string): Promise<void>;
|
|
51
|
+
goToPreviousStep(): Promise<void>;
|
|
52
|
+
goToStep(stepId: string): Promise<void>;
|
|
50
53
|
advanceStep(): Promise<void>;
|
|
51
54
|
retryCurrentStep(): Promise<void>;
|
|
52
55
|
skipStep(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Leaves a step whose target will not appear, including while the engine is
|
|
58
|
+
* still waiting for that target.
|
|
59
|
+
*/
|
|
60
|
+
continuePastUnavailableStep(): Promise<void>;
|
|
61
|
+
private moveToFollowingStep;
|
|
53
62
|
getRenderInstruction(): RenderInstruction | null;
|
|
54
63
|
private syncRenderInstructionCache;
|
|
55
64
|
evaluateTriggers(routeScope?: string): Promise<void>;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { GuideRegistry as
|
|
2
|
-
import { getStepIndex as u, getNextStepId as
|
|
1
|
+
import { GuideRegistry as S } from "./guide-registry.js";
|
|
2
|
+
import { getStepIndex as u, getNextStepId as c, getStepById as g, resolveLocalizedStepContent as f } from "./step-navigation.js";
|
|
3
3
|
import { TriggerPluginRegistry as v } from "../triggers/trigger-registry.js";
|
|
4
4
|
import { registerBuiltInTriggerPlugins as w } from "../triggers/built-in-triggers.js";
|
|
5
|
-
import { TargetResolver as m, resolveTargetSynchronously as
|
|
5
|
+
import { TargetResolver as m, resolveTargetSynchronously as I, waitForTargetResolved as y } from "../targets/target-resolver.js";
|
|
6
6
|
import { GuidanceTargetRefRegistry as R } from "../targets/ref-registry.js";
|
|
7
|
-
import { buildGuidanceStorageKey as
|
|
7
|
+
import { buildGuidanceStorageKey as r, buildSessionStatsKey as h, createDefaultSessionStats as G } from "../storage/storage-keys.js";
|
|
8
8
|
class _ {
|
|
9
9
|
sessionState = { status: "idle" };
|
|
10
|
+
activationToken = 0;
|
|
10
11
|
listeners = /* @__PURE__ */ new Set();
|
|
11
12
|
eventHandlers = /* @__PURE__ */ new Map();
|
|
12
|
-
guideRegistry = new
|
|
13
|
+
guideRegistry = new S();
|
|
13
14
|
triggerRegistry = new v();
|
|
14
15
|
targetRefRegistry = new R();
|
|
15
16
|
targetResolver;
|
|
@@ -127,7 +128,7 @@ class _ {
|
|
|
127
128
|
const e = this.sessionState.guideId;
|
|
128
129
|
if (e) {
|
|
129
130
|
if (t === "forever" && await this.config.storage.set({
|
|
130
|
-
[
|
|
131
|
+
[r(this.config.tenantId, e, "dismissed")]: {
|
|
131
132
|
dismissed: !0,
|
|
132
133
|
timestamp: Date.now()
|
|
133
134
|
}
|
|
@@ -141,6 +142,26 @@ class _ {
|
|
|
141
142
|
async snooze(t) {
|
|
142
143
|
(t ?? this.sessionState.guideId) && await this.dismiss("snoozed");
|
|
143
144
|
}
|
|
145
|
+
async goToPreviousStep() {
|
|
146
|
+
const t = this.sessionState.guideId, e = this.sessionState.stepId;
|
|
147
|
+
if (!t || !e || this.sessionState.status !== "active")
|
|
148
|
+
return;
|
|
149
|
+
const s = this.guideRegistry.get(t);
|
|
150
|
+
if (!s)
|
|
151
|
+
return;
|
|
152
|
+
const i = u(s, e);
|
|
153
|
+
i <= 0 || s.steps[i - 1]?.advanceOn !== "click-next" || await this.activateGuide(s, i - 1);
|
|
154
|
+
}
|
|
155
|
+
async goToStep(t) {
|
|
156
|
+
const e = this.sessionState.guideId;
|
|
157
|
+
if (!e || this.sessionState.status !== "active")
|
|
158
|
+
return;
|
|
159
|
+
const s = this.guideRegistry.get(e);
|
|
160
|
+
if (!s)
|
|
161
|
+
return;
|
|
162
|
+
const i = u(s, t);
|
|
163
|
+
i < 0 || await this.activateGuide(s, i);
|
|
164
|
+
}
|
|
144
165
|
async advanceStep() {
|
|
145
166
|
const t = this.sessionState.guideId, e = this.sessionState.stepId;
|
|
146
167
|
if (!t || !e || this.sessionState.status !== "active")
|
|
@@ -149,10 +170,10 @@ class _ {
|
|
|
149
170
|
if (!s)
|
|
150
171
|
return;
|
|
151
172
|
this.track("step.completed", { guideId: t, stepId: e });
|
|
152
|
-
const i = await
|
|
173
|
+
const i = await c(
|
|
153
174
|
s,
|
|
154
175
|
e,
|
|
155
|
-
(
|
|
176
|
+
(a) => this.triggerRegistry.evaluateExpression(a, this.buildTriggerContext())
|
|
156
177
|
);
|
|
157
178
|
if (!i) {
|
|
158
179
|
await this.completeGuide(t);
|
|
@@ -173,7 +194,38 @@ class _ {
|
|
|
173
194
|
}
|
|
174
195
|
async skipStep() {
|
|
175
196
|
const t = this.sessionState.guideId, e = this.sessionState.stepId;
|
|
176
|
-
!t || !e ||
|
|
197
|
+
if (!t || !e || this.sessionState.status !== "active")
|
|
198
|
+
return;
|
|
199
|
+
const s = this.guideRegistry.get(t);
|
|
200
|
+
!s || !g(s, e)?.skippable || await this.moveToFollowingStep();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Leaves a step whose target will not appear, including while the engine is
|
|
204
|
+
* still waiting for that target.
|
|
205
|
+
*/
|
|
206
|
+
async continuePastUnavailableStep() {
|
|
207
|
+
const t = this.sessionState.status;
|
|
208
|
+
t !== "evaluating" && t !== "blocked" && t !== "active" || (this.activationToken += 1, await this.moveToFollowingStep());
|
|
209
|
+
}
|
|
210
|
+
async moveToFollowingStep() {
|
|
211
|
+
const t = this.sessionState.guideId, e = this.sessionState.stepId;
|
|
212
|
+
if (!t || !e)
|
|
213
|
+
return;
|
|
214
|
+
const s = this.guideRegistry.get(t);
|
|
215
|
+
if (!s)
|
|
216
|
+
return;
|
|
217
|
+
this.track("step.skipped", { guideId: t, stepId: e });
|
|
218
|
+
const i = await c(
|
|
219
|
+
s,
|
|
220
|
+
e,
|
|
221
|
+
(a) => this.triggerRegistry.evaluateExpression(a, this.buildTriggerContext())
|
|
222
|
+
);
|
|
223
|
+
if (!i) {
|
|
224
|
+
await this.completeGuide(t);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const n = u(s, i);
|
|
228
|
+
await this.activateGuide(s, n);
|
|
177
229
|
}
|
|
178
230
|
getRenderInstruction() {
|
|
179
231
|
return this.cachedRenderInstruction;
|
|
@@ -183,11 +235,12 @@ class _ {
|
|
|
183
235
|
this.cachedRenderInstruction = null;
|
|
184
236
|
return;
|
|
185
237
|
}
|
|
186
|
-
const t = this.guideRegistry.get(this.sessionState.guideId), e = t ?
|
|
238
|
+
const t = this.guideRegistry.get(this.sessionState.guideId), e = t ? g(t, this.sessionState.stepId) : void 0;
|
|
187
239
|
if (!t || !e) {
|
|
188
240
|
this.cachedRenderInstruction = null;
|
|
189
241
|
return;
|
|
190
242
|
}
|
|
243
|
+
const s = this.sessionState.stepIndex > 0 ? t.steps[this.sessionState.stepIndex - 1] : void 0;
|
|
191
244
|
this.cachedRenderInstruction = {
|
|
192
245
|
guideId: t.id,
|
|
193
246
|
stepId: e.id,
|
|
@@ -197,7 +250,11 @@ class _ {
|
|
|
197
250
|
content: f(t, e, this.config.locale),
|
|
198
251
|
target: this.sessionState.resolvedTarget ?? null,
|
|
199
252
|
skippable: e.skippable,
|
|
200
|
-
advanceOn: e.advanceOn
|
|
253
|
+
advanceOn: e.advanceOn,
|
|
254
|
+
canGoBack: s?.advanceOn === "click-next",
|
|
255
|
+
placement: e.placement ?? "auto",
|
|
256
|
+
modalBehavior: e.modalBehavior,
|
|
257
|
+
interactionFooter: e.interactionFooter
|
|
201
258
|
};
|
|
202
259
|
}
|
|
203
260
|
async evaluateTriggers(t) {
|
|
@@ -207,106 +264,111 @@ class _ {
|
|
|
207
264
|
if (e.guidesShownThisSession >= this.config.maxGuidesPerSession || e.lastGuideEndedAt && Date.now() - e.lastGuideEndedAt < this.config.cooldownBetweenGuides)
|
|
208
265
|
return;
|
|
209
266
|
const s = t ? this.guideRegistry.getForRoute(t) : [], i = s.length > 0 ? s : this.guideRegistry.getAll();
|
|
210
|
-
await this.hydrateVisitCounts(i.map((
|
|
267
|
+
await this.hydrateVisitCounts(i.map((d) => d.id));
|
|
211
268
|
const n = [];
|
|
212
|
-
for (const
|
|
213
|
-
i.map((
|
|
269
|
+
for (const d of this.guideRegistry.getSortedByPriority(
|
|
270
|
+
i.map((o) => o.id)
|
|
214
271
|
))
|
|
215
|
-
await this.isGuideEligible(
|
|
272
|
+
await this.isGuideEligible(d, e) && n.push(d);
|
|
216
273
|
if (!n.length)
|
|
217
274
|
return;
|
|
218
|
-
const
|
|
275
|
+
const a = n[0];
|
|
219
276
|
this.log("evaluateTriggers.start", {
|
|
220
|
-
guideId:
|
|
277
|
+
guideId: a.id,
|
|
221
278
|
routePath: this.routePath
|
|
222
|
-
}), this.track("guide.triggered", { guideId:
|
|
279
|
+
}), this.track("guide.triggered", { guideId: a.id }), await this.start(a.id);
|
|
223
280
|
}
|
|
224
281
|
async activateGuide(t, e) {
|
|
225
|
-
const s = t.steps[e];
|
|
226
|
-
if (!
|
|
282
|
+
const s = ++this.activationToken, i = t.steps[e];
|
|
283
|
+
if (!i) {
|
|
227
284
|
await this.completeGuide(t.id);
|
|
228
285
|
return;
|
|
229
286
|
}
|
|
230
|
-
let
|
|
231
|
-
if (
|
|
232
|
-
if (
|
|
287
|
+
let n = null;
|
|
288
|
+
if (i.target) {
|
|
289
|
+
if (n = I(
|
|
233
290
|
this.targetResolver,
|
|
234
|
-
|
|
235
|
-
),
|
|
291
|
+
i.target
|
|
292
|
+
), n?.element || (this.setSession({
|
|
236
293
|
status: "evaluating",
|
|
237
294
|
guideId: t.id,
|
|
238
295
|
stepIndex: e,
|
|
239
|
-
stepId:
|
|
240
|
-
}),
|
|
296
|
+
stepId: i.id
|
|
297
|
+
}), n = await y(
|
|
241
298
|
this.targetResolver,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
299
|
+
i.target,
|
|
300
|
+
i.timeout ?? 5e3,
|
|
301
|
+
() => s !== this.activationToken
|
|
302
|
+
)), s !== this.activationToken)
|
|
303
|
+
return;
|
|
304
|
+
if (!n?.element) {
|
|
245
305
|
this.log("activateGuide.blocked", {
|
|
246
306
|
guideId: t.id,
|
|
247
|
-
stepId:
|
|
307
|
+
stepId: i.id,
|
|
248
308
|
stepIndex: e,
|
|
249
|
-
reason:
|
|
250
|
-
targetId:
|
|
309
|
+
reason: n ? "target_not_visible" : "target_not_found",
|
|
310
|
+
targetId: i.target?.targetId
|
|
251
311
|
}), this.setSession({
|
|
252
312
|
status: "blocked",
|
|
253
313
|
guideId: t.id,
|
|
254
314
|
stepIndex: e,
|
|
255
|
-
stepId:
|
|
256
|
-
reason:
|
|
315
|
+
stepId: i.id,
|
|
316
|
+
reason: n ? "target_not_visible" : "target_not_found"
|
|
257
317
|
});
|
|
258
318
|
return;
|
|
259
319
|
}
|
|
260
|
-
} else if (
|
|
320
|
+
} else if (i.renderer !== "announcement") {
|
|
261
321
|
this.log("activateGuide.blocked", {
|
|
262
322
|
guideId: t.id,
|
|
263
|
-
stepId:
|
|
323
|
+
stepId: i.id,
|
|
264
324
|
stepIndex: e,
|
|
265
325
|
reason: "target_not_found"
|
|
266
326
|
}), this.setSession({
|
|
267
327
|
status: "blocked",
|
|
268
328
|
guideId: t.id,
|
|
269
329
|
stepIndex: e,
|
|
270
|
-
stepId:
|
|
330
|
+
stepId: i.id,
|
|
271
331
|
reason: "target_not_found"
|
|
272
332
|
});
|
|
273
333
|
return;
|
|
274
334
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
335
|
+
if (s !== this.activationToken)
|
|
336
|
+
return;
|
|
337
|
+
const a = this.sessionState;
|
|
338
|
+
if (a.status === "idle" || a.guideId !== t.id) {
|
|
339
|
+
this.log("guideStart", { guideId: t.id, stepId: i.id }), this.emitEvent("guideStart", { guideId: t.id, stepId: i.id }), this.track("guide.started", { guideId: t.id });
|
|
278
340
|
const o = await this.loadSessionStats();
|
|
279
341
|
o.guidesShownThisSession += 1, await this.saveSessionStats(o), await this.incrementVisitCount(t.id);
|
|
280
342
|
}
|
|
281
|
-
this.emitEvent("stepChange", { guideId: t.id, stepId:
|
|
343
|
+
this.emitEvent("stepChange", { guideId: t.id, stepId: i.id }), this.track("step.viewed", { guideId: t.id, stepId: i.id }), this.log("step.active", {
|
|
282
344
|
guideId: t.id,
|
|
283
|
-
stepId:
|
|
345
|
+
stepId: i.id,
|
|
284
346
|
stepIndex: e,
|
|
285
|
-
hasTarget: !!
|
|
347
|
+
hasTarget: !!i.target
|
|
286
348
|
}), this.setSession({
|
|
287
349
|
status: "active",
|
|
288
350
|
guideId: t.id,
|
|
289
351
|
stepIndex: e,
|
|
290
|
-
stepId:
|
|
291
|
-
resolvedTarget:
|
|
292
|
-
...
|
|
293
|
-
rect:
|
|
352
|
+
stepId: i.id,
|
|
353
|
+
resolvedTarget: n?.element ? {
|
|
354
|
+
...n,
|
|
355
|
+
rect: n.element.getBoundingClientRect()
|
|
294
356
|
} : void 0
|
|
295
357
|
}), t.persistence.resumeOnRefresh && await this.config.storage.set({
|
|
296
|
-
[
|
|
297
|
-
stepId:
|
|
358
|
+
[r(this.config.tenantId, t.id, "lastStep")]: {
|
|
359
|
+
stepId: i.id,
|
|
298
360
|
timestamp: Date.now()
|
|
299
361
|
}
|
|
300
362
|
});
|
|
301
363
|
}
|
|
302
364
|
async completeGuide(t) {
|
|
303
365
|
this.guideRegistry.get(t)?.persistence.mode === "showOnce" && await this.config.storage.set({
|
|
304
|
-
[
|
|
366
|
+
[r(this.config.tenantId, t, "dismissed")]: {
|
|
305
367
|
dismissed: !0,
|
|
306
368
|
timestamp: Date.now()
|
|
307
369
|
}
|
|
308
370
|
}), await this.config.storage.delete([
|
|
309
|
-
|
|
371
|
+
r(this.config.tenantId, t, "lastStep")
|
|
310
372
|
]);
|
|
311
373
|
const s = await this.loadSessionStats();
|
|
312
374
|
s.lastGuideEndedAt = Date.now(), await this.saveSessionStats(s), this.emitEvent("guideEnd", { guideId: t, reason: "completed" }), this.track("guide.completed", { guideId: t }), this.setSession({ status: "completed", guideId: t }), await this.dequeueNextGuide();
|
|
@@ -321,19 +383,19 @@ class _ {
|
|
|
321
383
|
return this.isGuideEligible(s, i);
|
|
322
384
|
}
|
|
323
385
|
async isGuideEligible(t, e) {
|
|
324
|
-
const s =
|
|
386
|
+
const s = r(
|
|
325
387
|
this.config.tenantId,
|
|
326
388
|
t.id,
|
|
327
389
|
"dismissed"
|
|
328
390
|
);
|
|
329
391
|
if ((await this.config.storage.get([s]))[s]?.dismissed && t.persistence.mode !== "replayable")
|
|
330
392
|
return !1;
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
393
|
+
const a = e.snoozedUntil[t.id];
|
|
394
|
+
if (a && Date.now() < a || (e.dismissedCounts[t.id] ?? 0) >= 3 && t.persistence.mode === "showOnce")
|
|
333
395
|
return !1;
|
|
334
396
|
if (t.persistence.schedule) {
|
|
335
|
-
const
|
|
336
|
-
if (
|
|
397
|
+
const o = Date.now(), l = Date.parse(t.persistence.schedule.start), p = Date.parse(t.persistence.schedule.end);
|
|
398
|
+
if (o < l || o > p)
|
|
337
399
|
return !1;
|
|
338
400
|
}
|
|
339
401
|
return this.triggerRegistry.evaluateAll(
|
|
@@ -371,31 +433,31 @@ class _ {
|
|
|
371
433
|
await this.start(t);
|
|
372
434
|
}
|
|
373
435
|
async loadSessionStats() {
|
|
374
|
-
const t =
|
|
436
|
+
const t = h(this.config.tenantId);
|
|
375
437
|
return (await this.config.storage.get([t]))[t] ?? G();
|
|
376
438
|
}
|
|
377
439
|
async saveSessionStats(t) {
|
|
378
440
|
await this.config.storage.set({
|
|
379
|
-
[
|
|
441
|
+
[h(this.config.tenantId)]: t
|
|
380
442
|
});
|
|
381
443
|
}
|
|
382
444
|
async hydrateVisitCounts(t) {
|
|
383
445
|
if (!t.length)
|
|
384
446
|
return;
|
|
385
447
|
const e = t.map(
|
|
386
|
-
(i) =>
|
|
448
|
+
(i) => r(this.config.tenantId, i, "visitCount")
|
|
387
449
|
), s = await this.config.storage.get(e);
|
|
388
450
|
for (const i of t) {
|
|
389
|
-
const n =
|
|
451
|
+
const n = r(
|
|
390
452
|
this.config.tenantId,
|
|
391
453
|
i,
|
|
392
454
|
"visitCount"
|
|
393
|
-
),
|
|
394
|
-
typeof
|
|
455
|
+
), a = s[n];
|
|
456
|
+
typeof a == "number" && (this.visitCounts[i] = a);
|
|
395
457
|
}
|
|
396
458
|
}
|
|
397
459
|
async incrementVisitCount(t) {
|
|
398
|
-
const e =
|
|
460
|
+
const e = r(
|
|
399
461
|
this.config.tenantId,
|
|
400
462
|
t,
|
|
401
463
|
"visitCount"
|
|
@@ -413,7 +475,7 @@ class _ {
|
|
|
413
475
|
}
|
|
414
476
|
async clearPersistedLastStep(t) {
|
|
415
477
|
await this.config.storage.delete([
|
|
416
|
-
|
|
478
|
+
r(this.config.tenantId, t, "lastStep")
|
|
417
479
|
]);
|
|
418
480
|
}
|
|
419
481
|
scheduleEvaluation() {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
function
|
|
1
|
+
function c(t) {
|
|
2
2
|
return {
|
|
3
3
|
...t,
|
|
4
|
-
title:
|
|
5
|
-
body:
|
|
6
|
-
|
|
4
|
+
title: o(t.title),
|
|
5
|
+
body: o(t.body),
|
|
6
|
+
badge: d(t.badge),
|
|
7
|
+
footer: t.footer ? o(t.footer) : void 0,
|
|
7
8
|
media: t.media ? {
|
|
8
9
|
...t.media,
|
|
9
10
|
src: l(t.media.src)
|
|
10
11
|
} : void 0,
|
|
11
12
|
actions: t.actions?.map((i) => ({
|
|
12
13
|
...i,
|
|
13
|
-
label:
|
|
14
|
+
label: o(i.label)
|
|
14
15
|
}))
|
|
15
16
|
};
|
|
16
17
|
}
|
|
@@ -19,17 +20,23 @@ function p(t) {
|
|
|
19
20
|
...t,
|
|
20
21
|
steps: t.steps.map((i) => ({
|
|
21
22
|
...i,
|
|
22
|
-
content:
|
|
23
|
+
content: c(i.content)
|
|
23
24
|
})),
|
|
24
25
|
locale: Object.fromEntries(
|
|
25
26
|
Object.entries(t.locale).map(([i, n]) => [
|
|
26
27
|
i,
|
|
27
|
-
n.map((
|
|
28
|
+
n.map((e) => c(e))
|
|
28
29
|
])
|
|
29
30
|
)
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
|
-
function
|
|
33
|
+
function d(t) {
|
|
34
|
+
if (!t)
|
|
35
|
+
return;
|
|
36
|
+
const i = o(t);
|
|
37
|
+
return i.length > 0 ? i : void 0;
|
|
38
|
+
}
|
|
39
|
+
function o(t) {
|
|
33
40
|
return t.replace(/<[^>]*>/g, "").replace(/javascript:/gi, "").trim();
|
|
34
41
|
}
|
|
35
42
|
function l(t) {
|
|
@@ -44,18 +51,18 @@ function l(t) {
|
|
|
44
51
|
}
|
|
45
52
|
return "";
|
|
46
53
|
}
|
|
47
|
-
function
|
|
54
|
+
function h(t) {
|
|
48
55
|
const i = [];
|
|
49
56
|
t.schemaVersion !== 1 && i.push(`Unsupported schemaVersion: ${t.schemaVersion}`), t.id || i.push("Guide manifest requires id"), t.steps.length || i.push("Guide manifest requires at least one step");
|
|
50
57
|
const n = /* @__PURE__ */ new Set();
|
|
51
|
-
for (const
|
|
52
|
-
n.has(
|
|
58
|
+
for (const e of t.steps)
|
|
59
|
+
n.has(e.id) && i.push(`Duplicate step id: ${e.id}`), n.add(e.id), (e.content.body.includes("<script") || e.content.body.includes("javascript:")) && i.push(`Step ${e.id} body contains disallowed content`);
|
|
53
60
|
if (t.transitions?.length) {
|
|
54
|
-
const
|
|
55
|
-
|
|
61
|
+
const e = f(t);
|
|
62
|
+
e && i.push(e);
|
|
56
63
|
}
|
|
57
|
-
for (const
|
|
58
|
-
const s = u(
|
|
64
|
+
for (const e of t.triggers) {
|
|
65
|
+
const s = u(e);
|
|
59
66
|
s && i.push(s);
|
|
60
67
|
}
|
|
61
68
|
return i;
|
|
@@ -73,30 +80,30 @@ function u(t) {
|
|
|
73
80
|
}
|
|
74
81
|
return t.plugin ? null : "Trigger plugin key is required";
|
|
75
82
|
}
|
|
76
|
-
function
|
|
83
|
+
function f(t) {
|
|
77
84
|
const i = /* @__PURE__ */ new Map();
|
|
78
|
-
for (const
|
|
79
|
-
const
|
|
80
|
-
|
|
85
|
+
for (const r of t.transitions ?? []) {
|
|
86
|
+
const a = i.get(r.from) ?? [];
|
|
87
|
+
a.push(r.to), i.set(r.from, a);
|
|
81
88
|
}
|
|
82
|
-
const n = /* @__PURE__ */ new Set(),
|
|
83
|
-
if (n.has(
|
|
89
|
+
const n = /* @__PURE__ */ new Set(), e = /* @__PURE__ */ new Set(), s = (r) => {
|
|
90
|
+
if (n.has(r))
|
|
84
91
|
return !0;
|
|
85
|
-
if (
|
|
92
|
+
if (e.has(r))
|
|
86
93
|
return !1;
|
|
87
|
-
n.add(
|
|
88
|
-
for (const
|
|
89
|
-
if (s(
|
|
94
|
+
n.add(r);
|
|
95
|
+
for (const a of i.get(r) ?? [])
|
|
96
|
+
if (s(a))
|
|
90
97
|
return !0;
|
|
91
|
-
return n.delete(
|
|
98
|
+
return n.delete(r), e.add(r), !1;
|
|
92
99
|
};
|
|
93
|
-
for (const
|
|
94
|
-
if (s(
|
|
100
|
+
for (const r of t.steps)
|
|
101
|
+
if (s(r.id))
|
|
95
102
|
return "Guide transitions contain a cycle";
|
|
96
103
|
return null;
|
|
97
104
|
}
|
|
98
105
|
export {
|
|
99
106
|
p as sanitizeGuideManifest,
|
|
100
|
-
|
|
101
|
-
|
|
107
|
+
c as sanitizeStepContent,
|
|
108
|
+
h as validateGuideManifest
|
|
102
109
|
};
|
|
@@ -9,5 +9,5 @@ export declare class TargetResolver {
|
|
|
9
9
|
resolve(descriptor: TargetDescriptor, scopeRoot?: HTMLElement | null, adapterType?: string, adapterConfig?: Record<string, unknown>): ResolvedTarget | null;
|
|
10
10
|
}
|
|
11
11
|
export declare function resolveTargetSynchronously(resolver: TargetResolver, descriptor: TargetDescriptor): ResolvedTarget | null;
|
|
12
|
-
export declare function waitForTargetResolved(resolver: TargetResolver, descriptor: TargetDescriptor, timeoutMs?: number): Promise<ResolvedTarget | null>;
|
|
12
|
+
export declare function waitForTargetResolved(resolver: TargetResolver, descriptor: TargetDescriptor, timeoutMs?: number, isCancelled?: () => boolean): Promise<ResolvedTarget | null>;
|
|
13
13
|
export declare function waitForTargetVisible(element: HTMLElement, timeoutMs?: number): Promise<boolean>;
|
|
@@ -10,18 +10,18 @@ class f {
|
|
|
10
10
|
unregisterAdapter(e) {
|
|
11
11
|
this.adapterPlugins.delete(e);
|
|
12
12
|
}
|
|
13
|
-
resolve(e, t,
|
|
14
|
-
if (
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
13
|
+
resolve(e, t, s, n) {
|
|
14
|
+
if (s) {
|
|
15
|
+
const i = this.adapterPlugins.get(s);
|
|
16
|
+
if (i?.resolve) {
|
|
17
17
|
const o = {
|
|
18
18
|
targetDescriptor: e,
|
|
19
19
|
scopeRoot: t
|
|
20
20
|
};
|
|
21
21
|
try {
|
|
22
|
-
const l =
|
|
22
|
+
const l = i.resolve(
|
|
23
23
|
o,
|
|
24
|
-
|
|
24
|
+
n ?? {}
|
|
25
25
|
);
|
|
26
26
|
if (l && !(l instanceof Promise))
|
|
27
27
|
return l;
|
|
@@ -33,48 +33,50 @@ class f {
|
|
|
33
33
|
return this.refRegistry.resolveDescriptor(e, t);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
const
|
|
37
|
-
function
|
|
38
|
-
const e =
|
|
36
|
+
const u = 16;
|
|
37
|
+
function c(r) {
|
|
38
|
+
const e = r.getBoundingClientRect();
|
|
39
39
|
return e.width > 0 && e.height > 0;
|
|
40
40
|
}
|
|
41
|
-
function d(
|
|
42
|
-
const t =
|
|
43
|
-
return !t?.element || e.waitUntil === "visible" && !
|
|
41
|
+
function d(r, e) {
|
|
42
|
+
const t = r.resolve(e);
|
|
43
|
+
return !t?.element || e.waitUntil === "visible" && !c(t.element) ? null : t;
|
|
44
44
|
}
|
|
45
|
-
async function w(
|
|
45
|
+
async function w(r, e, t = 5e3, s) {
|
|
46
46
|
const n = Date.now();
|
|
47
47
|
for (; Date.now() - n < t; ) {
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
if (s?.())
|
|
49
|
+
return null;
|
|
50
|
+
const i = r.resolve(e);
|
|
51
|
+
if (i?.element)
|
|
50
52
|
if (e.waitUntil === "visible") {
|
|
51
|
-
const
|
|
53
|
+
const o = t - (Date.now() - n);
|
|
52
54
|
if (await g(
|
|
53
|
-
|
|
54
|
-
Math.max(
|
|
55
|
+
i.element,
|
|
56
|
+
Math.max(o, u)
|
|
55
57
|
))
|
|
56
|
-
return
|
|
58
|
+
return i;
|
|
57
59
|
} else
|
|
58
|
-
return
|
|
59
|
-
await new Promise((
|
|
60
|
-
window.setTimeout(
|
|
60
|
+
return i;
|
|
61
|
+
await new Promise((o) => {
|
|
62
|
+
window.setTimeout(o, u);
|
|
61
63
|
});
|
|
62
64
|
}
|
|
63
65
|
return null;
|
|
64
66
|
}
|
|
65
|
-
function g(
|
|
67
|
+
function g(r, e = 5e3) {
|
|
66
68
|
if (typeof window > "u" || typeof IntersectionObserver > "u")
|
|
67
69
|
return Promise.resolve(!0);
|
|
68
|
-
const t =
|
|
69
|
-
return t.width > 0 && t.height > 0 ? Promise.resolve(!0) : new Promise((
|
|
70
|
-
const
|
|
70
|
+
const t = r.getBoundingClientRect();
|
|
71
|
+
return t.width > 0 && t.height > 0 ? Promise.resolve(!0) : new Promise((s) => {
|
|
72
|
+
const n = new IntersectionObserver((o) => {
|
|
71
73
|
o.some(
|
|
72
74
|
(a) => a.isIntersecting && a.intersectionRatio > 0
|
|
73
|
-
) && (
|
|
74
|
-
}),
|
|
75
|
-
|
|
75
|
+
) && (n.disconnect(), clearTimeout(i), s(!0));
|
|
76
|
+
}), i = setTimeout(() => {
|
|
77
|
+
n.disconnect(), s(!1);
|
|
76
78
|
}, e);
|
|
77
|
-
|
|
79
|
+
n.observe(r);
|
|
78
80
|
});
|
|
79
81
|
}
|
|
80
82
|
export {
|