@magicfeedback/popup-sdk 1.7.2 → 1.8.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/index.mjs CHANGED
@@ -860,7 +860,7 @@ function createReactNativeRenderer() {
860
860
  }
861
861
 
862
862
  // src/ui/preload.ts
863
- var defaultLoader = () => import("./renderPopup-5QXL6EJW.mjs");
863
+ var defaultLoader = () => import("./renderPopup-HTNVACFV.mjs");
864
864
  var pending = null;
865
865
  function preloadRenderPopup(loader = defaultLoader) {
866
866
  if (pending) return pending;
@@ -933,7 +933,7 @@ var BrowserPopupRenderer = class {
933
933
  if (!this.container) return;
934
934
  this.visible = true;
935
935
  const container = this.container;
936
- void import("./renderPopup-5QXL6EJW.mjs").then(({ renderPopup }) => {
936
+ void import("./renderPopup-HTNVACFV.mjs").then(({ renderPopup }) => {
937
937
  renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
938
938
  });
939
939
  }
@@ -2371,6 +2371,9 @@ var DeepdotsPopups = class {
2371
2371
  this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
2372
2372
  }
2373
2373
  shouldShow(def, pathUrl, skipPathCheck = false) {
2374
+ if (this.isPathExcluded(def, pathUrl)) {
2375
+ return false;
2376
+ }
2374
2377
  if (!skipPathCheck && !this.matchesSegmentsPath(def, pathUrl)) {
2375
2378
  return false;
2376
2379
  }
@@ -2401,40 +2404,85 @@ var DeepdotsPopups = class {
2401
2404
  }
2402
2405
  return matches;
2403
2406
  }
2407
+ /** `segments.path`: rutas donde el popup PUEDE mostrarse. Sin lista, en todas. */
2404
2408
  matchesSegmentsPath(def, pathUrl) {
2405
2409
  const paths = def.segments?.path;
2406
- if (!paths || paths.length === 0) return true;
2407
- if (typeof window === "undefined" || !window.location) {
2410
+ if (!Array.isArray(paths) || paths.length === 0) return true;
2411
+ const location = this.resolveCurrentLocation(pathUrl);
2412
+ if (!location) {
2408
2413
  this.debug("No window.location available for path comparison", { popupId: def.id, paths });
2409
2414
  return true;
2410
2415
  }
2411
- const normalizedHref = this.normalizeUrl(pathUrl || window.location.href || "");
2412
- const currentUrl = this.safeParseUrl(normalizedHref);
2413
- const normalizedPath = this.normalizeUrl(currentUrl?.pathname || window.location.pathname || "");
2414
2416
  const matches = paths.some((rawCandidate) => {
2415
- const candidate = this.normalizeUrl(rawCandidate);
2416
- let match = false;
2417
- if (candidate.startsWith("http://") || candidate.startsWith("https://")) {
2418
- match = normalizedHref === candidate;
2419
- } else if (candidate.startsWith("/")) {
2420
- match = normalizedHref.includes(candidate);
2421
- } else {
2422
- match = normalizedPath === candidate;
2423
- }
2417
+ const match = this.matchesPathCandidate(rawCandidate, location);
2424
2418
  this.debug("Path comparison", {
2425
2419
  popupId: def.id,
2426
- candidate,
2427
- currentPath: normalizedPath,
2428
- currentHref: normalizedHref,
2420
+ candidate: rawCandidate,
2421
+ currentPath: location.path,
2422
+ currentHref: location.href,
2429
2423
  match
2430
2424
  });
2431
2425
  return match;
2432
2426
  });
2433
2427
  if (!matches) {
2434
- this.debug("No path match for popup", { popupId: def.id, paths, currentPath: normalizedPath });
2428
+ this.debug("No path match for popup", { popupId: def.id, paths, currentPath: location.path });
2435
2429
  }
2436
2430
  return matches;
2437
2431
  }
2432
+ /**
2433
+ * `segments.excludedPaths`: rutas donde el popup NO debe mostrarse. Gana sobre
2434
+ * `segments.path` (`path: ['/']` + `excludedPaths: ['/cart']` = en todas menos el
2435
+ * carrito) y se aplica también cuando no hay `path` (= en todas menos las excluidas).
2436
+ */
2437
+ isPathExcluded(def, pathUrl) {
2438
+ const excluded = def.segments?.excludedPaths;
2439
+ if (!Array.isArray(excluded) || excluded.length === 0) return false;
2440
+ const location = this.resolveCurrentLocation(pathUrl);
2441
+ if (!location) {
2442
+ this.debug("No window.location available for excluded path comparison", { popupId: def.id, excluded });
2443
+ return false;
2444
+ }
2445
+ const hit = excluded.find((rawCandidate) => this.matchesPathCandidate(rawCandidate, location));
2446
+ if (hit !== void 0) {
2447
+ this.debug("Popup excluded by path", {
2448
+ popupId: def.id,
2449
+ candidate: hit,
2450
+ currentPath: location.path,
2451
+ currentHref: location.href
2452
+ });
2453
+ return true;
2454
+ }
2455
+ return false;
2456
+ }
2457
+ /**
2458
+ * Compara UN candidato de `segments.path`/`segments.excludedPaths` con la ruta
2459
+ * actual. Mismas reglas para incluir y para excluir:
2460
+ * - URL absoluta → href completo exacto
2461
+ * - empieza por / → subcadena del href (así entran las rutas con hash: `/#/home`)
2462
+ * - resto → pathname exacto
2463
+ * Ignora entradas que no sean string: el backend puede colar un `null` en la lista
2464
+ * y no puede tumbar la evaluación del trigger entero (mismo fallo que hubo con
2465
+ * `segments.lang`).
2466
+ */
2467
+ matchesPathCandidate(rawCandidate, location) {
2468
+ if (typeof rawCandidate !== "string") return false;
2469
+ const candidate = this.normalizeUrl(rawCandidate);
2470
+ if (!candidate) return false;
2471
+ if (candidate.startsWith("http://") || candidate.startsWith("https://")) {
2472
+ return location.href === candidate;
2473
+ }
2474
+ if (candidate.startsWith("/")) {
2475
+ return location.href.includes(candidate);
2476
+ }
2477
+ return location.path === candidate;
2478
+ }
2479
+ /** href + pathname normalizados de la ruta a evaluar, o null si no hay `window.location`. */
2480
+ resolveCurrentLocation(pathUrl) {
2481
+ if (typeof window === "undefined" || !window.location) return null;
2482
+ const href = this.normalizeUrl(pathUrl || window.location.href || "");
2483
+ const parsed = this.safeParseUrl(href);
2484
+ return { href, path: this.normalizeUrl(parsed?.pathname || window.location.pathname || "") };
2485
+ }
2438
2486
  evaluateCooldown(def, condition) {
2439
2487
  switch (condition.answered) {
2440
2488
  case "SHOWED":
@@ -2731,7 +2779,7 @@ var DeepdotsPopups = class {
2731
2779
  }
2732
2780
  if (!this.popupContainer) return;
2733
2781
  const container = this.popupContainer;
2734
- void import("./renderPopup-5QXL6EJW.mjs").then(({ renderPopup }) => {
2782
+ void import("./renderPopup-HTNVACFV.mjs").then(({ renderPopup }) => {
2735
2783
  renderPopup(
2736
2784
  container,
2737
2785
  surveyId,