phoenix_live_view 0.18.2 → 0.18.4

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.
@@ -463,7 +463,7 @@ var DOM = {
463
463
  if (!input) {
464
464
  return;
465
465
  }
466
- if (!(this.private(input, PHX_HAS_FOCUSED) || this.private(input.form, PHX_HAS_SUBMITTED))) {
466
+ if (!(this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED))) {
467
467
  el.classList.add(PHX_NO_FEEDBACK_CLASS);
468
468
  }
469
469
  },
@@ -1656,7 +1656,7 @@ var DOMPatch = class {
1656
1656
  dom_default.copyPrivates(toEl, fromEl);
1657
1657
  dom_default.discardError(targetContainer, toEl, phxFeedbackFor);
1658
1658
  let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
1659
- if (isFocusedFormEl) {
1659
+ if (isFocusedFormEl && fromEl.type !== "hidden") {
1660
1660
  this.trackBefore("updated", fromEl, toEl);
1661
1661
  dom_default.mergeFocusedInput(fromEl, toEl);
1662
1662
  dom_default.syncAttrsToProps(fromEl);
@@ -1701,7 +1701,7 @@ var DOMPatch = class {
1701
1701
  });
1702
1702
  }
1703
1703
  if (externalFormTriggered) {
1704
- liveSocket.disconnect();
1704
+ liveSocket.unload();
1705
1705
  externalFormTriggered.submit();
1706
1706
  }
1707
1707
  return true;
@@ -2071,7 +2071,7 @@ var JS = {
2071
2071
  view.withinTargets(phxTarget, (targetView, targetCtx) => {
2072
2072
  if (eventType === "change") {
2073
2073
  let { newCid, _target, callback } = args;
2074
- _target = _target || (sourceEl instanceof HTMLInputElement ? sourceEl.name : void 0);
2074
+ _target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
2075
2075
  if (_target) {
2076
2076
  pushOpts._target = _target;
2077
2077
  }
@@ -2308,7 +2308,7 @@ var View = class {
2308
2308
  this.href = href;
2309
2309
  }
2310
2310
  isMain() {
2311
- return this.el.getAttribute(PHX_MAIN) !== null;
2311
+ return this.el.hasAttribute(PHX_MAIN);
2312
2312
  }
2313
2313
  connectParams(liveReferer) {
2314
2314
  let params = this.liveSocket.params(this.el);
@@ -2406,10 +2406,10 @@ var View = class {
2406
2406
  applyDiff(type, rawDiff, callback) {
2407
2407
  this.log(type, () => ["", clone(rawDiff)]);
2408
2408
  let { diff, reply, events, title } = Rendered.extract(rawDiff);
2409
+ callback({ diff, reply, events });
2409
2410
  if (title) {
2410
- dom_default.putTitle(title);
2411
+ window.requestAnimationFrame(() => dom_default.putTitle(title));
2411
2412
  }
2412
- callback({ diff, reply, events });
2413
2413
  }
2414
2414
  onJoin(resp) {
2415
2415
  let { rendered, container } = resp;
@@ -2711,6 +2711,13 @@ var View = class {
2711
2711
  applyPendingUpdates() {
2712
2712
  this.pendingDiffs.forEach(({ diff, events }) => this.update(diff, events));
2713
2713
  this.pendingDiffs = [];
2714
+ this.eachChild((child) => child.applyPendingUpdates());
2715
+ }
2716
+ eachChild(callback) {
2717
+ let children = this.root.children[this.id] || {};
2718
+ for (let id in children) {
2719
+ callback(this.getChildById(id));
2720
+ }
2714
2721
  }
2715
2722
  onChannel(event, cb) {
2716
2723
  this.liveSocket.onChannel(this.channel, event, (resp) => {
@@ -2734,9 +2741,7 @@ var View = class {
2734
2741
  this.channel.onClose((reason) => this.onClose(reason));
2735
2742
  }
2736
2743
  destroyAllChildren() {
2737
- for (let id in this.root.children[this.id]) {
2738
- this.getChildById(id).destroy();
2739
- }
2744
+ this.eachChild((child) => child.destroy());
2740
2745
  }
2741
2746
  onLiveRedirect(redir) {
2742
2747
  let { to, kind, flash } = redir;
@@ -3258,12 +3263,14 @@ var View = class {
3258
3263
  }
3259
3264
  }
3260
3265
  ownsElement(el) {
3261
- return this.isDead || el.getAttribute(PHX_PARENT_ID) === this.id || maybe(el.closest(PHX_VIEW_SELECTOR), (node) => node.id) === this.id;
3266
+ let parentViewEl = el.closest(PHX_VIEW_SELECTOR);
3267
+ return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;
3262
3268
  }
3263
3269
  submitForm(form, targetCtx, phxEvent, opts = {}) {
3264
3270
  dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
3265
3271
  let phxFeedback = this.liveSocket.binding(PHX_FEEDBACK_FOR);
3266
3272
  let inputs = Array.from(form.elements);
3273
+ inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
3267
3274
  this.liveSocket.blurActiveElement(this);
3268
3275
  this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
3269
3276
  inputs.forEach((input) => dom_default.showError(input, phxFeedback));
@@ -3375,8 +3382,9 @@ var LiveSocket = class {
3375
3382
  } else if (this.main) {
3376
3383
  this.socket.connect();
3377
3384
  } else {
3378
- this.joinDeadView();
3385
+ this.bindTopLevelEvents({ dead: true });
3379
3386
  }
3387
+ this.joinDeadView();
3380
3388
  };
3381
3389
  if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {
3382
3390
  doConnect();
@@ -3396,6 +3404,17 @@ var LiveSocket = class {
3396
3404
  execJS(el, encodedJS, eventType = null) {
3397
3405
  this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
3398
3406
  }
3407
+ unload() {
3408
+ if (this.unloaded) {
3409
+ return;
3410
+ }
3411
+ if (this.main && this.isConnected()) {
3412
+ this.log(this.main, "socket", () => ["disconnect for page nav"]);
3413
+ }
3414
+ this.unloaded = true;
3415
+ this.destroyAllViews();
3416
+ this.disconnect();
3417
+ }
3399
3418
  triggerDOM(kind, args) {
3400
3419
  this.domCallbacks[kind](...args);
3401
3420
  }
@@ -3509,12 +3528,16 @@ var LiveSocket = class {
3509
3528
  return this.socket.channel(topic, params);
3510
3529
  }
3511
3530
  joinDeadView() {
3512
- this.bindTopLevelEvents({ dead: true });
3513
- let view = this.newRootView(document.body);
3514
- view.setHref(this.getHref());
3515
- view.joinDead();
3516
- this.main = view;
3517
- window.requestAnimationFrame(() => view.execNewMounted());
3531
+ let body = document.body;
3532
+ if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
3533
+ let view = this.newRootView(body);
3534
+ view.setHref(this.getHref());
3535
+ view.joinDead();
3536
+ if (!this.main) {
3537
+ this.main = view;
3538
+ }
3539
+ window.requestAnimationFrame(() => view.execNewMounted());
3540
+ }
3518
3541
  }
3519
3542
  joinRootViews() {
3520
3543
  let rootsFound = false;
@@ -3523,7 +3546,7 @@ var LiveSocket = class {
3523
3546
  let view = this.newRootView(rootEl);
3524
3547
  view.setHref(this.getHref());
3525
3548
  view.join();
3526
- if (rootEl.getAttribute(PHX_MAIN)) {
3549
+ if (rootEl.hasAttribute(PHX_MAIN)) {
3527
3550
  this.main = view;
3528
3551
  }
3529
3552
  }
@@ -3649,8 +3672,11 @@ var LiveSocket = class {
3649
3672
  }
3650
3673
  this.boundTopLevelEvents = true;
3651
3674
  this.socket.onClose((event) => {
3675
+ if (event && event.code === 1001) {
3676
+ return this.unload();
3677
+ }
3652
3678
  if (event && event.code === 1e3 && this.main) {
3653
- this.reloadWithJitter(this.main);
3679
+ return this.reloadWithJitter(this.main);
3654
3680
  }
3655
3681
  });
3656
3682
  document.body.addEventListener("click", function() {
@@ -3783,6 +3809,9 @@ var LiveSocket = class {
3783
3809
  }
3784
3810
  let phxEvent = target && target.getAttribute(click);
3785
3811
  if (!phxEvent) {
3812
+ if (!capture && e.target.href !== void 0) {
3813
+ this.unload();
3814
+ }
3786
3815
  return;
3787
3816
  }
3788
3817
  if (target.getAttribute("href") === "#") {
@@ -3907,7 +3936,7 @@ var LiveSocket = class {
3907
3936
  if (!this.isConnected()) {
3908
3937
  return browser_default.redirect(href, flash);
3909
3938
  }
3910
- if (/^\/[^\/]+.*$/.test(href)) {
3939
+ if (/^\/$|^\/[^\/]+.*$/.test(href)) {
3911
3940
  let { protocol, host } = window.location;
3912
3941
  href = `${protocol}//${host}${href}`;
3913
3942
  }
@@ -3941,6 +3970,7 @@ var LiveSocket = class {
3941
3970
  if (!externalFormSubmitted && phxChange && !phxSubmit) {
3942
3971
  externalFormSubmitted = true;
3943
3972
  e.preventDefault();
3973
+ this.unload();
3944
3974
  this.withinOwners(e.target, (view) => {
3945
3975
  view.disableForm(e.target);
3946
3976
  window.requestAnimationFrame(() => e.target.submit());
@@ -3950,7 +3980,7 @@ var LiveSocket = class {
3950
3980
  this.on("submit", (e) => {
3951
3981
  let phxEvent = e.target.getAttribute(this.binding("submit"));
3952
3982
  if (!phxEvent) {
3953
- return;
3983
+ return this.unload();
3954
3984
  }
3955
3985
  e.preventDefault();
3956
3986
  e.target.disabled = true;