phoenix_live_view 1.1.30 → 1.1.32

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.
@@ -144,7 +144,7 @@ var EntryUploader = class {
144
144
  }
145
145
  upload() {
146
146
  this.uploadChannel.onError((reason) => this.error(reason));
147
- this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", (reason) => this.error(reason));
147
+ this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", ({ reason }) => this.error(reason));
148
148
  }
149
149
  isDone() {
150
150
  return this.offset >= this.entry.file.size;
@@ -187,6 +187,21 @@ var EntryUploader = class {
187
187
 
188
188
  // js/phoenix_live_view/utils.js
189
189
  var logError = (msg, obj) => console.error && console.error(msg, obj);
190
+ var ensureSameOrigin = (href, kind) => {
191
+ let url;
192
+ try {
193
+ url = new URL(href, window.location.href);
194
+ } catch {
195
+ throw new Error(
196
+ `expected ${kind} destination to be a valid URL, got: ${href}`
197
+ );
198
+ }
199
+ if (url.origin !== window.location.origin) {
200
+ throw new Error(
201
+ `cannot ${kind} to "${href}" because its origin does not match the current origin "${window.location.origin}". Use window.location directly for cross-origin navigation.`
202
+ );
203
+ }
204
+ };
190
205
  var isCid = (cid) => {
191
206
  const type = typeof cid;
192
207
  return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid);
@@ -607,7 +622,9 @@ var DOM = {
607
622
  if (this.once(el, "bind-debounce")) {
608
623
  el.addEventListener("blur", () => {
609
624
  clearTimeout(this.private(el, THROTTLED));
610
- this.triggerCycle(el, DEBOUNCE_TRIGGER);
625
+ if (asyncFilter()) {
626
+ this.triggerCycle(el, DEBOUNCE_TRIGGER);
627
+ }
611
628
  });
612
629
  }
613
630
  }
@@ -2713,7 +2730,7 @@ var DOMPatch = class {
2713
2730
  transitionPendingRemoves() {
2714
2731
  const { pendingRemoves, liveSocket } = this;
2715
2732
  if (pendingRemoves.length > 0) {
2716
- liveSocket.transitionRemoves(pendingRemoves, () => {
2733
+ liveSocket.transitionRemoves(pendingRemoves, this.view, () => {
2717
2734
  pendingRemoves.forEach((el) => {
2718
2735
  const child = dom_default.firstPhxChild(el);
2719
2736
  if (child) {
@@ -3854,6 +3871,7 @@ var js_commands_default = (liveSocket, eventType) => {
3854
3871
  });
3855
3872
  },
3856
3873
  navigate(href, opts = {}) {
3874
+ ensureSameOrigin(href, "navigate");
3857
3875
  const customEvent = new CustomEvent("phx:exec");
3858
3876
  liveSocket.historyRedirect(
3859
3877
  customEvent,
@@ -3864,6 +3882,7 @@ var js_commands_default = (liveSocket, eventType) => {
3864
3882
  );
3865
3883
  },
3866
3884
  patch(href, opts = {}) {
3885
+ ensureSameOrigin(href, "patch");
3867
3886
  const customEvent = new CustomEvent("phx:exec");
3868
3887
  liveSocket.pushHistoryPatch(
3869
3888
  customEvent,
@@ -4403,6 +4422,7 @@ var View = class _View {
4403
4422
  if (container) {
4404
4423
  const [tag, attrs] = container;
4405
4424
  this.el = dom_default.replaceRootContainer(this.el, tag, attrs);
4425
+ dom_default.putPrivate(this.el, "view", this);
4406
4426
  }
4407
4427
  this.childJoins = 0;
4408
4428
  this.joinPending = true;
@@ -4485,6 +4505,7 @@ var View = class _View {
4485
4505
  }
4486
4506
  attachTrueDocEl() {
4487
4507
  this.el = dom_default.byId(this.id);
4508
+ dom_default.putPrivate(this.el, "view", this);
4488
4509
  this.el.setAttribute(PHX_ROOT_ID, this.root.id);
4489
4510
  }
4490
4511
  // this is invoked for dead and live views, so we must filter by
@@ -4668,6 +4689,7 @@ var View = class _View {
4668
4689
  rootEl.setAttribute(PHX_SESSION, this.getSession());
4669
4690
  rootEl.setAttribute(PHX_STATIC, this.getStatic());
4670
4691
  rootEl.setAttribute(PHX_PARENT_ID, this.parent ? this.parent.id : null);
4692
+ dom_default.putPrivate(rootEl, "view", this);
4671
4693
  const formsToRecover = (
4672
4694
  // we go over all forms in the new DOM; because this is only the HTML for the current
4673
4695
  // view, we can be sure that all forms are owned by this view:
@@ -5948,7 +5970,7 @@ var LiveSocket = class {
5948
5970
  }
5949
5971
  // public
5950
5972
  version() {
5951
- return "1.1.30";
5973
+ return "1.1.32";
5952
5974
  }
5953
5975
  isProfileEnabled() {
5954
5976
  return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
@@ -6227,11 +6249,12 @@ var LiveSocket = class {
6227
6249
  `[${this.binding("remove")}]`
6228
6250
  ).filter((el) => !dom_default.isChildOfAny(el, stickies));
6229
6251
  const newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");
6230
- this.main.showLoader(this.loaderTimeout);
6231
- this.main.destroy();
6252
+ const oldMainView = this.main;
6253
+ oldMainView.showLoader(this.loaderTimeout);
6254
+ oldMainView.destroy();
6232
6255
  this.main = this.newRootView(newMainEl, flash, liveReferer);
6233
6256
  this.main.setRedirect(href);
6234
- this.transitionRemoves(removeEls);
6257
+ this.transitionRemoves(removeEls, oldMainView);
6235
6258
  this.main.join((joinCount, onDone) => {
6236
6259
  if (joinCount === 1 && this.commitPendingLink(linkRef)) {
6237
6260
  this.requestDOMUpdate(() => {
@@ -6245,7 +6268,7 @@ var LiveSocket = class {
6245
6268
  }
6246
6269
  });
6247
6270
  }
6248
- transitionRemoves(elements, callback) {
6271
+ transitionRemoves(elements, view, callback) {
6249
6272
  const removeAttr = this.binding("remove");
6250
6273
  const silenceEvents = (e) => {
6251
6274
  e.preventDefault();
@@ -6255,7 +6278,8 @@ var LiveSocket = class {
6255
6278
  for (const event of this.boundEventNames) {
6256
6279
  el.addEventListener(event, silenceEvents, true);
6257
6280
  }
6258
- this.execJS(el, el.getAttribute(removeAttr), "remove");
6281
+ const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
6282
+ js_default.exec(e, "remove", el.getAttribute(removeAttr), view, el);
6259
6283
  });
6260
6284
  this.requestDOMUpdate(() => {
6261
6285
  elements.forEach((el) => {
@@ -6278,7 +6302,7 @@ var LiveSocket = class {
6278
6302
  let view;
6279
6303
  const viewEl = dom_default.closestViewEl(childEl);
6280
6304
  if (viewEl) {
6281
- view = this.getViewByEl(viewEl);
6305
+ view = dom_default.private(viewEl, "view");
6282
6306
  } else {
6283
6307
  if (!childEl.isConnected) {
6284
6308
  return null;