@gemboss/gem-framework 0.18.16 → 0.20.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.
Files changed (68) hide show
  1. package/README.md +109 -1
  2. package/dist/SOURCE.json +3 -3
  3. package/dist/gem-framework.css +23 -1
  4. package/dist/gem-runtime.js +97 -54
  5. package/dist/index.js +2511 -44
  6. package/dist/motion/core.d.ts +208 -0
  7. package/dist/motion/core.js +1 -0
  8. package/dist/motion/orbit.d.ts +4 -0
  9. package/dist/motion/orbit.js +1 -0
  10. package/dist/motion/quick-view.d.ts +4 -0
  11. package/dist/motion/quick-view.js +1 -0
  12. package/dist/motion/rail.d.ts +5 -0
  13. package/dist/motion/rail.js +1 -0
  14. package/dist/orbit-base.css +39 -0
  15. package/dist/plugins/before_after.js +1 -1
  16. package/dist/plugins/bundle.js +1 -1
  17. package/dist/plugins/carousel.js +1 -1
  18. package/dist/plugins/cart-drawer.js +1 -1
  19. package/dist/plugins/context-adapter.js +1 -1
  20. package/dist/plugins/countdown.js +1 -1
  21. package/dist/plugins/delivery-estimate.d.ts +9 -0
  22. package/dist/plugins/delivery-estimate.js +1 -0
  23. package/dist/plugins/disclosure.js +1 -1
  24. package/dist/plugins/hero-slideshow.js +1 -1
  25. package/dist/plugins/img-in.js +1 -1
  26. package/dist/plugins/localization.js +1 -1
  27. package/dist/plugins/media-gallery.js +1 -1
  28. package/dist/plugins/mobile-menu.js +1 -1
  29. package/dist/plugins/offer-engine.js +1 -1
  30. package/dist/plugins/orbit.d.ts +9 -0
  31. package/dist/plugins/orbit.js +1 -0
  32. package/dist/plugins/personalize.d.ts +9 -0
  33. package/dist/plugins/personalize.js +1 -0
  34. package/dist/plugins/predictive-search.js +1 -1
  35. package/dist/plugins/print-preview.d.ts +9 -0
  36. package/dist/plugins/print-preview.js +1 -0
  37. package/dist/plugins/promo-popup.js +1 -1
  38. package/dist/plugins/quantity-input.js +1 -1
  39. package/dist/plugins/quick-view.js +1 -69
  40. package/dist/plugins/rail.d.ts +9 -0
  41. package/dist/plugins/rail.js +1 -0
  42. package/dist/plugins/recently-viewed.js +1 -1
  43. package/dist/plugins/reveal-on-scroll.js +1 -1
  44. package/dist/plugins/reviews.js +1 -1
  45. package/dist/plugins/runtime-slot-loader.js +1 -1
  46. package/dist/plugins/seasonal-effects.js +1 -1
  47. package/dist/plugins/size-guide.d.ts +9 -0
  48. package/dist/plugins/size-guide.js +38 -0
  49. package/dist/plugins/sticky-atc.js +1 -1
  50. package/dist/plugins/tabs.js +1 -1
  51. package/dist/plugins/variant-selects.js +1 -1
  52. package/dist/pod/core.d.ts +26 -0
  53. package/dist/pod/core.js +1 -0
  54. package/dist/pod/delivery-estimate.d.ts +28 -0
  55. package/dist/pod/delivery-estimate.js +1 -0
  56. package/dist/pod/personalize.d.ts +25 -0
  57. package/dist/pod/personalize.js +1 -0
  58. package/dist/pod/print-preview.d.ts +8 -0
  59. package/dist/pod/print-preview.js +1 -0
  60. package/dist/pod-buybox.css +55 -0
  61. package/dist/popup-shell.css +15 -0
  62. package/dist/primitives.css +4 -1
  63. package/dist/rail-base.css +48 -0
  64. package/dist/runtime-core.d.ts +2 -0
  65. package/dist/runtime-core.js +26 -15
  66. package/dist/section-gate.js +2522 -36
  67. package/dist/tokens.css +4 -0
  68. package/package.json +20 -1
@@ -4,7 +4,8 @@
4
4
  // that body the names it expects (`document`, `window`, `target`, `mark`, `canListen`, `registerPlugin`) scoped to
5
5
  // one root, and keeps a ledger of what the body did so unmount() can undo it:
6
6
  // - listeners (the module wraps every `x.addEventListener(` of the body as `__gemListen(x, `), timers,
7
- // animation frames and IntersectionObservers made through `window` / `target`;
7
+ // animation frames and Intersection / Resize observers made through `window` / `target`;
8
+ // - what the body hands to onUnmount(fn) (0.19.0);
8
9
  // - the `data-gem-bound-<key>` marks it set, so the same root can be mounted again after an unmount.
9
10
  // Importing this file does nothing: no global is read or written until mount() is called.
10
11
 
@@ -52,6 +53,21 @@ function scopedDocument(root, doc) {
52
53
  });
53
54
  }
54
55
 
56
+ // An observer class whose instances the ledger disconnects at unmount.
57
+ function trackedObserver(Base, ledger) {
58
+ if (typeof Base !== "function") return undefined;
59
+ return class extends Base {
60
+ constructor(callback, init) {
61
+ super(callback, init);
62
+ ledger.observers.add(this);
63
+ }
64
+ disconnect() {
65
+ ledger.observers.delete(this);
66
+ super.disconnect();
67
+ }
68
+ };
69
+ }
70
+
55
71
  // `window` / `target` for a plugin: the real window, except that timers, frames and observers made through it are
56
72
  // remembered so unmount() can stop them.
57
73
  function trackedWindow(win, ledger) {
@@ -75,18 +91,9 @@ function trackedWindow(win, ledger) {
75
91
  return id;
76
92
  }
77
93
  : undefined,
78
- IntersectionObserver: typeof win.IntersectionObserver === "function"
79
- ? class extends win.IntersectionObserver {
80
- constructor(callback, init) {
81
- super(callback, init);
82
- ledger.observers.add(this);
83
- }
84
- disconnect() {
85
- ledger.observers.delete(this);
86
- super.disconnect();
87
- }
88
- }
89
- : undefined,
94
+ IntersectionObserver: trackedObserver(win.IntersectionObserver, ledger),
95
+ // 0.19.0: the motion effects watch their root's size.
96
+ ResizeObserver: trackedObserver(win.ResizeObserver, ledger),
90
97
  };
91
98
  return new Proxy(win, {
92
99
  get: (real, prop) => (Object.prototype.hasOwnProperty.call(own, prop) ? own[prop] : bindMethod(real, Reflect.get(real, prop), prop)),
@@ -116,7 +123,7 @@ export function mountPlugin(key, install, root, options = {}, guard) {
116
123
  const doc = scope.nodeType === 9 ? scope : scope.ownerDocument || globalThis.document;
117
124
  const win = options.window || (doc && doc.defaultView) || globalThis;
118
125
  const api = options.api || (doc === globalThis.document ? gemApi() : createGemApi(doc));
119
- const ledger = { listeners: [], marks: [], timeouts: new Set(), intervals: new Set(), frames: new Set(), observers: new Set() };
126
+ const ledger = { listeners: [], marks: [], timeouts: new Set(), intervals: new Set(), frames: new Set(), observers: new Set(), cleanups: [] };
120
127
  const window = trackedWindow(win, ledger);
121
128
  const document = scope === doc ? doc : scopedDocument(scope, doc);
122
129
  // `data-gem-bound-<key>` with ANY value means bound, including one the markup carries to claim an element for its own
@@ -140,7 +147,11 @@ export function mountPlugin(key, install, root, options = {}, guard) {
140
147
  };
141
148
  const unguarded = guard ? Array.from(document.querySelectorAll(guard.selector)).filter((element) => !element[guard.prop]) : [];
142
149
 
150
+ // 0.19.0: a plugin hands back what is not a listener, timer or observer (the motion effects' scheduler tasks, host API).
151
+ const onUnmount = (fn) => { if (typeof fn === "function") ledger.cleanups.push(fn); };
152
+
143
153
  const teardown = () => {
154
+ ledger.cleanups.splice(0).reverse().forEach((fn) => fn());
144
155
  ledger.timeouts.forEach((id) => win.clearTimeout(id));
145
156
  ledger.intervals.forEach((id) => win.clearInterval(id));
146
157
  ledger.frames.forEach((id) => win.cancelAnimationFrame && win.cancelAnimationFrame(id));
@@ -150,7 +161,7 @@ export function mountPlugin(key, install, root, options = {}, guard) {
150
161
  if (guard) unguarded.forEach((element) => { delete element[guard.prop]; });
151
162
  };
152
163
  try {
153
- install({ document, window, target: window, mark, canListen, listen, registerPlugin, registerNoopPlugin });
164
+ install({ document, window, target: window, mark, canListen, listen, registerPlugin, registerNoopPlugin, onUnmount });
154
165
  if (typeof setup === "function") {
155
166
  setup({ api, config: { planId: "gem-plugin-module", plugins: [{ key, loadStrategy: "mount", dependsOn: [] }] }, reason: "mount" });
156
167
  }