phoenix_live_view 1.2.0-rc.2 → 1.2.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/README.md +5 -5
- package/assets/js/phoenix_live_view/README.md +3 -0
- package/assets/js/phoenix_live_view/{aria.js → aria.ts} +18 -10
- package/assets/js/phoenix_live_view/{browser.js → browser.ts} +12 -8
- package/assets/js/phoenix_live_view/{dom.js → dom.ts} +107 -34
- package/assets/js/phoenix_live_view/{dom_patch.js → dom_patch.ts} +187 -124
- package/assets/js/phoenix_live_view/{dom_post_morph_restorer.js → dom_post_morph_restorer.ts} +17 -2
- package/assets/js/phoenix_live_view/{element_ref.js → element_ref.ts} +17 -11
- package/assets/js/phoenix_live_view/entry_uploader.js +4 -4
- package/assets/js/phoenix_live_view/{hooks.js → hooks.ts} +108 -91
- package/assets/js/phoenix_live_view/index.ts +14 -301
- package/assets/js/phoenix_live_view/js.js +2 -1
- package/assets/js/phoenix_live_view/js_commands.ts +12 -9
- package/assets/js/phoenix_live_view/{live_socket.js → live_socket.ts} +582 -114
- package/assets/js/phoenix_live_view/live_uploader.js +1 -1
- package/assets/js/phoenix_live_view/rendered.js +3 -0
- package/assets/js/phoenix_live_view/{utils.js → utils.ts} +35 -6
- package/assets/js/phoenix_live_view/{view.js → view.ts} +221 -110
- package/assets/js/phoenix_live_view/view_hook.ts +92 -32
- package/package.json +5 -2
- package/priv/static/phoenix_live_view.cjs.js +577 -314
- package/priv/static/phoenix_live_view.cjs.js.map +4 -4
- package/priv/static/phoenix_live_view.esm.js +577 -314
- package/priv/static/phoenix_live_view.esm.js.map +4 -4
- package/priv/static/phoenix_live_view.js +584 -314
- package/priv/static/phoenix_live_view.min.js +7 -7
- /package/assets/js/phoenix_live_view/{constants.js → constants.ts} +0 -0
|
@@ -19,7 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
// js/phoenix_live_view/index.ts
|
|
20
20
|
var phoenix_live_view_exports = {};
|
|
21
21
|
__export(phoenix_live_view_exports, {
|
|
22
|
-
LiveSocket: () =>
|
|
22
|
+
LiveSocket: () => LiveSocket,
|
|
23
23
|
ViewHook: () => ViewHook,
|
|
24
24
|
createHook: () => createHook,
|
|
25
25
|
getFileURLForUpload: () => getFileURLForUpload,
|
|
@@ -27,7 +27,7 @@ __export(phoenix_live_view_exports, {
|
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(phoenix_live_view_exports);
|
|
29
29
|
|
|
30
|
-
// js/phoenix_live_view/constants.
|
|
30
|
+
// js/phoenix_live_view/constants.ts
|
|
31
31
|
var CONSECUTIVE_RELOADS = "consecutive-reloads";
|
|
32
32
|
var MAX_RELOADS = 10;
|
|
33
33
|
var RELOAD_JITTER_MIN = 5e3;
|
|
@@ -169,12 +169,12 @@ var EntryUploader = class {
|
|
|
169
169
|
}
|
|
170
170
|
this.uploadChannel.leave();
|
|
171
171
|
this.errored = true;
|
|
172
|
-
clearTimeout(this.chunkTimer);
|
|
172
|
+
this.chunkTimer != null && clearTimeout(this.chunkTimer);
|
|
173
173
|
this.entry.error(reason);
|
|
174
174
|
}
|
|
175
175
|
upload() {
|
|
176
176
|
this.uploadChannel.onError((reason) => this.error(reason));
|
|
177
|
-
this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", (reason) => this.error(reason));
|
|
177
|
+
this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", ({ reason }) => this.error(reason));
|
|
178
178
|
}
|
|
179
179
|
isDone() {
|
|
180
180
|
return this.offset >= this.entry.file.size;
|
|
@@ -186,7 +186,7 @@ var EntryUploader = class {
|
|
|
186
186
|
this.chunkSize + this.offset
|
|
187
187
|
);
|
|
188
188
|
reader.onload = (e) => {
|
|
189
|
-
if (e.target
|
|
189
|
+
if (e.target?.error === null) {
|
|
190
190
|
this.offset += /** @type {ArrayBuffer} */
|
|
191
191
|
e.target.result.byteLength;
|
|
192
192
|
this.pushChunk(
|
|
@@ -194,7 +194,7 @@ var EntryUploader = class {
|
|
|
194
194
|
e.target.result
|
|
195
195
|
);
|
|
196
196
|
} else {
|
|
197
|
-
return logError("Read error: " + e.target
|
|
197
|
+
return logError("Read error: " + e.target?.error);
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
200
|
reader.readAsArrayBuffer(blob);
|
|
@@ -215,8 +215,23 @@ var EntryUploader = class {
|
|
|
215
215
|
}
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
-
// js/phoenix_live_view/utils.
|
|
218
|
+
// js/phoenix_live_view/utils.ts
|
|
219
219
|
var logError = (msg, obj) => console.error && console.error(msg, obj);
|
|
220
|
+
var ensureSameOrigin = (href, kind) => {
|
|
221
|
+
let url;
|
|
222
|
+
try {
|
|
223
|
+
url = new URL(href, window.location.href);
|
|
224
|
+
} catch {
|
|
225
|
+
throw new Error(
|
|
226
|
+
`expected ${kind} destination to be a valid URL, got: ${href}`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (url.origin !== window.location.origin) {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`cannot ${kind} to "${href}" because its origin does not match the current origin "${window.location.origin}". Use window.location directly for cross-origin navigation.`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
220
235
|
var isCid = (cid) => {
|
|
221
236
|
const type = typeof cid;
|
|
222
237
|
return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid);
|
|
@@ -257,12 +272,13 @@ var closure = (val) => typeof val === "function" ? val : function() {
|
|
|
257
272
|
var clone = (obj) => {
|
|
258
273
|
return JSON.parse(JSON.stringify(obj));
|
|
259
274
|
};
|
|
260
|
-
var closestPhxBinding = (
|
|
275
|
+
var closestPhxBinding = (startEl, binding, borderEl) => {
|
|
276
|
+
let el = startEl;
|
|
261
277
|
do {
|
|
262
|
-
if (el.matches(`[${binding}]`) && !el.disabled) {
|
|
278
|
+
if (el.matches(`[${binding}]`) && !("disabled" in el && el.disabled)) {
|
|
263
279
|
return el;
|
|
264
280
|
}
|
|
265
|
-
el = el.parentElement
|
|
281
|
+
el = el.parentElement;
|
|
266
282
|
} while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR)));
|
|
267
283
|
return null;
|
|
268
284
|
};
|
|
@@ -294,7 +310,7 @@ var eventContainsFiles = (e) => {
|
|
|
294
310
|
return false;
|
|
295
311
|
};
|
|
296
312
|
|
|
297
|
-
// js/phoenix_live_view/browser.
|
|
313
|
+
// js/phoenix_live_view/browser.ts
|
|
298
314
|
var Browser = {
|
|
299
315
|
canPushState() {
|
|
300
316
|
return typeof history.pushState !== "undefined";
|
|
@@ -341,7 +357,7 @@ var Browser = {
|
|
|
341
357
|
}
|
|
342
358
|
});
|
|
343
359
|
}
|
|
344
|
-
} else {
|
|
360
|
+
} else if (to) {
|
|
345
361
|
this.redirect(to);
|
|
346
362
|
}
|
|
347
363
|
},
|
|
@@ -358,7 +374,7 @@ var Browser = {
|
|
|
358
374
|
deleteCookie(name) {
|
|
359
375
|
document.cookie = `${name}=; max-age=-1; path=/`;
|
|
360
376
|
},
|
|
361
|
-
redirect(toURL, flash, navigate = (url) => {
|
|
377
|
+
redirect(toURL, flash = null, navigate = (url) => {
|
|
362
378
|
window.location.href = url;
|
|
363
379
|
}) {
|
|
364
380
|
if (flash) {
|
|
@@ -379,11 +395,21 @@ var Browser = {
|
|
|
379
395
|
};
|
|
380
396
|
var browser_default = Browser;
|
|
381
397
|
|
|
382
|
-
// js/phoenix_live_view/dom.
|
|
398
|
+
// js/phoenix_live_view/dom.ts
|
|
383
399
|
var DOM = {
|
|
384
400
|
byId(id) {
|
|
385
401
|
return document.getElementById(id) || logError(`no id found for ${id}`);
|
|
386
402
|
},
|
|
403
|
+
elementFromTarget(target) {
|
|
404
|
+
if (!(target instanceof Node)) {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
if (target.nodeType === Node.ELEMENT_NODE) {
|
|
408
|
+
return target;
|
|
409
|
+
} else {
|
|
410
|
+
return target.parentElement;
|
|
411
|
+
}
|
|
412
|
+
},
|
|
387
413
|
removeClass(el, className) {
|
|
388
414
|
el.classList.remove(className);
|
|
389
415
|
if (el.classList.length === 0) {
|
|
@@ -421,12 +447,20 @@ var DOM = {
|
|
|
421
447
|
inputsOutsideForm
|
|
422
448
|
);
|
|
423
449
|
},
|
|
424
|
-
|
|
425
|
-
return
|
|
426
|
-
doc2,
|
|
450
|
+
findComponent(viewId, cid, doc2 = document) {
|
|
451
|
+
return doc2.querySelector(
|
|
427
452
|
`[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`
|
|
428
453
|
);
|
|
429
454
|
},
|
|
455
|
+
getComponent(viewId, cid, doc2 = document) {
|
|
456
|
+
const el = this.findComponent(viewId, cid, doc2);
|
|
457
|
+
if (!el) {
|
|
458
|
+
throw new Error(
|
|
459
|
+
`no component found matching viewId ${viewId} and cid ${cid}`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
return el;
|
|
463
|
+
},
|
|
430
464
|
isPhxDestroyed(node) {
|
|
431
465
|
return node.id && DOM.private(node, "destroyed") ? true : false;
|
|
432
466
|
},
|
|
@@ -818,11 +852,23 @@ var DOM = {
|
|
|
818
852
|
focused.setSelectionRange(selectionStart, selectionEnd);
|
|
819
853
|
}
|
|
820
854
|
},
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
855
|
+
/**
|
|
856
|
+
* Returns true if the element is an input that can be focused and edited by the user,
|
|
857
|
+
* so we can skip patching it if it has focus.
|
|
858
|
+
*/
|
|
859
|
+
isEditableInput(el) {
|
|
860
|
+
return this.isFormAssociated(el) && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLInputElement && el.type === "button");
|
|
861
|
+
},
|
|
862
|
+
isFormAssociated(el) {
|
|
863
|
+
if (!(el instanceof HTMLElement))
|
|
864
|
+
return false;
|
|
865
|
+
if (el.localName) {
|
|
866
|
+
const customEl = customElements.get(el.localName);
|
|
867
|
+
if (customEl) {
|
|
868
|
+
return customEl.formAssociated === true;
|
|
869
|
+
}
|
|
824
870
|
}
|
|
825
|
-
return
|
|
871
|
+
return el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement || el instanceof HTMLButtonElement;
|
|
826
872
|
},
|
|
827
873
|
syncAttrsToProps(el) {
|
|
828
874
|
if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) {
|
|
@@ -839,13 +885,13 @@ var DOM = {
|
|
|
839
885
|
if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend", PHX_STREAM])) {
|
|
840
886
|
const toRemove = [];
|
|
841
887
|
container.childNodes.forEach((childNode) => {
|
|
842
|
-
if (!childNode.id) {
|
|
843
|
-
const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
|
|
888
|
+
if (!("id" in childNode) || !childNode.id) {
|
|
889
|
+
const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue && childNode.nodeValue.trim() === "";
|
|
844
890
|
if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {
|
|
845
891
|
logError(
|
|
846
892
|
`only HTML element tags with an id are allowed inside containers with phx-update.
|
|
847
893
|
|
|
848
|
-
removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
894
|
+
removing illegal node: "${("outerHTML" in childNode && childNode.outerHTML || childNode.nodeValue || "").trim()}"
|
|
849
895
|
|
|
850
896
|
`
|
|
851
897
|
);
|
|
@@ -873,9 +919,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
873
919
|
Object.keys(attrs).forEach(
|
|
874
920
|
(attr) => newContainer.setAttribute(attr, attrs[attr])
|
|
875
921
|
);
|
|
876
|
-
retainedAttrs.forEach(
|
|
877
|
-
|
|
878
|
-
|
|
922
|
+
retainedAttrs.forEach((attr) => {
|
|
923
|
+
const value = container.getAttribute(attr);
|
|
924
|
+
if (value !== null) {
|
|
925
|
+
newContainer.setAttribute(attr, value);
|
|
926
|
+
}
|
|
927
|
+
});
|
|
879
928
|
newContainer.innerHTML = container.innerHTML;
|
|
880
929
|
container.replaceWith(newContainer);
|
|
881
930
|
return newContainer;
|
|
@@ -1127,7 +1176,7 @@ var LiveUploader = class _LiveUploader {
|
|
|
1127
1176
|
[],
|
|
1128
1177
|
(existing) => existing.concat(newFiles)
|
|
1129
1178
|
);
|
|
1130
|
-
inputEl.value =
|
|
1179
|
+
inputEl.value = "";
|
|
1131
1180
|
} else {
|
|
1132
1181
|
if (dataTransfer && dataTransfer.files.length > 0) {
|
|
1133
1182
|
inputEl.files = dataTransfer.files;
|
|
@@ -1210,20 +1259,20 @@ var LiveUploader = class _LiveUploader {
|
|
|
1210
1259
|
}
|
|
1211
1260
|
};
|
|
1212
1261
|
|
|
1213
|
-
// js/phoenix_live_view/aria.
|
|
1262
|
+
// js/phoenix_live_view/aria.ts
|
|
1214
1263
|
var ARIA = {
|
|
1215
1264
|
anyOf(instance, classes) {
|
|
1216
|
-
return classes.
|
|
1265
|
+
return classes.some((name) => instance instanceof name);
|
|
1217
1266
|
},
|
|
1218
|
-
isFocusable(el, interactiveOnly) {
|
|
1219
|
-
return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [
|
|
1267
|
+
isFocusable(el, interactiveOnly = false) {
|
|
1268
|
+
return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !("disabled" in el && el.disabled) && this.anyOf(el, [
|
|
1220
1269
|
HTMLInputElement,
|
|
1221
1270
|
HTMLSelectElement,
|
|
1222
1271
|
HTMLTextAreaElement,
|
|
1223
1272
|
HTMLButtonElement
|
|
1224
|
-
]) || el instanceof HTMLIFrameElement || el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";
|
|
1273
|
+
]) || el instanceof HTMLIFrameElement || el instanceof HTMLElement && el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";
|
|
1225
1274
|
},
|
|
1226
|
-
attemptFocus(el, interactiveOnly) {
|
|
1275
|
+
attemptFocus(el, interactiveOnly = false) {
|
|
1227
1276
|
if (this.isFocusable(el, interactiveOnly)) {
|
|
1228
1277
|
try {
|
|
1229
1278
|
el.focus();
|
|
@@ -1240,6 +1289,7 @@ var ARIA = {
|
|
|
1240
1289
|
}
|
|
1241
1290
|
child = child.nextElementSibling;
|
|
1242
1291
|
}
|
|
1292
|
+
return false;
|
|
1243
1293
|
},
|
|
1244
1294
|
focusFirst(el) {
|
|
1245
1295
|
let child = el.firstElementChild;
|
|
@@ -1249,6 +1299,7 @@ var ARIA = {
|
|
|
1249
1299
|
}
|
|
1250
1300
|
child = child.nextElementSibling;
|
|
1251
1301
|
}
|
|
1302
|
+
return false;
|
|
1252
1303
|
},
|
|
1253
1304
|
focusLast(el) {
|
|
1254
1305
|
let child = el.lastElementChild;
|
|
@@ -1258,79 +1309,12 @@ var ARIA = {
|
|
|
1258
1309
|
}
|
|
1259
1310
|
child = child.previousElementSibling;
|
|
1260
1311
|
}
|
|
1312
|
+
return false;
|
|
1261
1313
|
}
|
|
1262
1314
|
};
|
|
1263
1315
|
var aria_default = ARIA;
|
|
1264
1316
|
|
|
1265
|
-
// js/phoenix_live_view/hooks.
|
|
1266
|
-
var Hooks = {
|
|
1267
|
-
LiveFileUpload: {
|
|
1268
|
-
activeRefs() {
|
|
1269
|
-
return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);
|
|
1270
|
-
},
|
|
1271
|
-
preflightedRefs() {
|
|
1272
|
-
return this.el.getAttribute(PHX_PREFLIGHTED_REFS);
|
|
1273
|
-
},
|
|
1274
|
-
mounted() {
|
|
1275
|
-
this.js().ignoreAttributes(this.el, ["value"]);
|
|
1276
|
-
this.preflightedWas = this.preflightedRefs();
|
|
1277
|
-
},
|
|
1278
|
-
updated() {
|
|
1279
|
-
const newPreflights = this.preflightedRefs();
|
|
1280
|
-
if (this.preflightedWas !== newPreflights) {
|
|
1281
|
-
this.preflightedWas = newPreflights;
|
|
1282
|
-
if (newPreflights === "") {
|
|
1283
|
-
this.__view().cancelSubmit(this.el.form);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
if (this.activeRefs() === "") {
|
|
1287
|
-
this.el.value = null;
|
|
1288
|
-
}
|
|
1289
|
-
this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));
|
|
1290
|
-
}
|
|
1291
|
-
},
|
|
1292
|
-
LiveImgPreview: {
|
|
1293
|
-
mounted() {
|
|
1294
|
-
this.ref = this.el.getAttribute("data-phx-entry-ref");
|
|
1295
|
-
this.inputEl = document.getElementById(
|
|
1296
|
-
this.el.getAttribute(PHX_UPLOAD_REF)
|
|
1297
|
-
);
|
|
1298
|
-
this.url = LiveUploader.getEntryDataURL(this.inputEl, this.ref);
|
|
1299
|
-
this.el.src = this.url;
|
|
1300
|
-
},
|
|
1301
|
-
destroyed() {
|
|
1302
|
-
URL.revokeObjectURL(this.url);
|
|
1303
|
-
}
|
|
1304
|
-
},
|
|
1305
|
-
FocusWrap: {
|
|
1306
|
-
mounted() {
|
|
1307
|
-
this.focusStart = this.el.firstElementChild;
|
|
1308
|
-
this.focusEnd = this.el.lastElementChild;
|
|
1309
|
-
this.focusStart.addEventListener("focus", (e) => {
|
|
1310
|
-
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
1311
|
-
const nextFocus = e.target.nextElementSibling;
|
|
1312
|
-
aria_default.attemptFocus(nextFocus) || aria_default.focusFirst(nextFocus);
|
|
1313
|
-
} else {
|
|
1314
|
-
aria_default.focusLast(this.el);
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
this.focusEnd.addEventListener("focus", (e) => {
|
|
1318
|
-
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
1319
|
-
const nextFocus = e.target.previousElementSibling;
|
|
1320
|
-
aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);
|
|
1321
|
-
} else {
|
|
1322
|
-
aria_default.focusFirst(this.el);
|
|
1323
|
-
}
|
|
1324
|
-
});
|
|
1325
|
-
if (!this.el.contains(document.activeElement)) {
|
|
1326
|
-
this.el.addEventListener("phx:show-end", () => this.el.focus());
|
|
1327
|
-
if (window.getComputedStyle(this.el).display !== "none") {
|
|
1328
|
-
aria_default.focusFirst(this.el);
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
};
|
|
1317
|
+
// js/phoenix_live_view/hooks.ts
|
|
1334
1318
|
var findScrollContainer = (el) => {
|
|
1335
1319
|
if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)
|
|
1336
1320
|
return null;
|
|
@@ -1371,7 +1355,7 @@ var isWithinViewport = (el, scrollContainer) => {
|
|
|
1371
1355
|
const rect = el.getBoundingClientRect();
|
|
1372
1356
|
return Math.ceil(rect.top) >= top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);
|
|
1373
1357
|
};
|
|
1374
|
-
|
|
1358
|
+
var InfiniteScroll = {
|
|
1375
1359
|
mounted() {
|
|
1376
1360
|
this.scrollContainer = findScrollContainer(this.el);
|
|
1377
1361
|
let scrollBefore = scrollTop(this.scrollContainer);
|
|
@@ -1447,9 +1431,9 @@ Hooks.InfiniteScroll = {
|
|
|
1447
1431
|
} else if (isScrollingDown && topOverran && rect.top <= 0) {
|
|
1448
1432
|
topOverran = false;
|
|
1449
1433
|
}
|
|
1450
|
-
if (topEvent && isScrollingUp && isAtViewportTop(firstChild, this.scrollContainer)) {
|
|
1434
|
+
if (topEvent && isScrollingUp && firstChild && isAtViewportTop(firstChild, this.scrollContainer)) {
|
|
1451
1435
|
onFirstChildAtTop(topEvent, firstChild);
|
|
1452
|
-
} else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild, this.scrollContainer)) {
|
|
1436
|
+
} else if (bottomEvent && isScrollingDown && lastChild && isAtViewportBottom(lastChild, this.scrollContainer)) {
|
|
1453
1437
|
onLastChildAtBottom(bottomEvent, lastChild);
|
|
1454
1438
|
}
|
|
1455
1439
|
scrollBefore = scrollNow;
|
|
@@ -1513,9 +1497,80 @@ Hooks.InfiniteScroll = {
|
|
|
1513
1497
|
return rect;
|
|
1514
1498
|
}
|
|
1515
1499
|
};
|
|
1500
|
+
var LiveFileUpload = {
|
|
1501
|
+
activeRefs() {
|
|
1502
|
+
return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);
|
|
1503
|
+
},
|
|
1504
|
+
preflightedRefs() {
|
|
1505
|
+
return this.el.getAttribute(PHX_PREFLIGHTED_REFS);
|
|
1506
|
+
},
|
|
1507
|
+
mounted() {
|
|
1508
|
+
this.js().ignoreAttributes(this.el, ["value"]);
|
|
1509
|
+
this.preflightedWas = this.preflightedRefs();
|
|
1510
|
+
},
|
|
1511
|
+
updated() {
|
|
1512
|
+
const newPreflights = this.preflightedRefs();
|
|
1513
|
+
if (this.preflightedWas !== newPreflights) {
|
|
1514
|
+
this.preflightedWas = newPreflights;
|
|
1515
|
+
if (newPreflights === "") {
|
|
1516
|
+
this.__view().cancelSubmit(this.el.form);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (this.activeRefs() === "") {
|
|
1520
|
+
this.el.value = "";
|
|
1521
|
+
}
|
|
1522
|
+
this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));
|
|
1523
|
+
}
|
|
1524
|
+
};
|
|
1525
|
+
var LiveImgPreview = {
|
|
1526
|
+
mounted() {
|
|
1527
|
+
this.ref = this.el.getAttribute("data-phx-entry-ref");
|
|
1528
|
+
this.inputEl = document.getElementById(
|
|
1529
|
+
this.el.getAttribute(PHX_UPLOAD_REF)
|
|
1530
|
+
);
|
|
1531
|
+
this.url = LiveUploader.getEntryDataURL(this.inputEl, this.ref);
|
|
1532
|
+
this.el.src = this.url;
|
|
1533
|
+
},
|
|
1534
|
+
destroyed() {
|
|
1535
|
+
URL.revokeObjectURL(this.url);
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
var Hooks = {
|
|
1539
|
+
LiveFileUpload,
|
|
1540
|
+
LiveImgPreview,
|
|
1541
|
+
FocusWrap: {
|
|
1542
|
+
mounted() {
|
|
1543
|
+
this.focusStart = this.el.firstElementChild;
|
|
1544
|
+
this.focusEnd = this.el.lastElementChild;
|
|
1545
|
+
this.focusStart.addEventListener("focus", (e) => {
|
|
1546
|
+
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
1547
|
+
const nextFocus = e.target.nextElementSibling;
|
|
1548
|
+
aria_default.attemptFocus(nextFocus) || aria_default.focusFirst(nextFocus);
|
|
1549
|
+
} else {
|
|
1550
|
+
aria_default.focusLast(this.el);
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
this.focusEnd.addEventListener("focus", (e) => {
|
|
1554
|
+
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
1555
|
+
const nextFocus = e.target.previousElementSibling;
|
|
1556
|
+
aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);
|
|
1557
|
+
} else {
|
|
1558
|
+
aria_default.focusFirst(this.el);
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
if (!this.el.contains(document.activeElement)) {
|
|
1562
|
+
this.el.addEventListener("phx:show-end", () => this.el.focus());
|
|
1563
|
+
if (window.getComputedStyle(this.el).display !== "none") {
|
|
1564
|
+
aria_default.focusFirst(this.el);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
},
|
|
1569
|
+
InfiniteScroll
|
|
1570
|
+
};
|
|
1516
1571
|
var hooks_default = Hooks;
|
|
1517
1572
|
|
|
1518
|
-
// js/phoenix_live_view/element_ref.
|
|
1573
|
+
// js/phoenix_live_view/element_ref.ts
|
|
1519
1574
|
var ElementRef = class {
|
|
1520
1575
|
static onUnlock(el, callback) {
|
|
1521
1576
|
if (!dom_default.isLocked(el) && !el.closest(`[${PHX_REF_LOCK}]`)) {
|
|
@@ -1611,11 +1666,11 @@ var ElementRef = class {
|
|
|
1611
1666
|
this.el.removeAttribute(PHX_REF_LOADING);
|
|
1612
1667
|
const disabledVal = this.el.getAttribute(PHX_DISABLED);
|
|
1613
1668
|
const readOnlyVal = this.el.getAttribute(PHX_READONLY);
|
|
1614
|
-
if (readOnlyVal !== null) {
|
|
1669
|
+
if (readOnlyVal !== null && "readOnly" in this.el) {
|
|
1615
1670
|
this.el.readOnly = readOnlyVal === "true" ? true : false;
|
|
1616
1671
|
this.el.removeAttribute(PHX_READONLY);
|
|
1617
1672
|
}
|
|
1618
|
-
if (disabledVal !== null) {
|
|
1673
|
+
if (disabledVal !== null && "disabled" in this.el) {
|
|
1619
1674
|
this.el.disabled = disabledVal === "true" ? true : false;
|
|
1620
1675
|
this.el.removeAttribute(PHX_DISABLED);
|
|
1621
1676
|
}
|
|
@@ -1642,6 +1697,7 @@ var ElementRef = class {
|
|
|
1642
1697
|
isLoadingUndoneBy(ref) {
|
|
1643
1698
|
return this.loadingRef === null ? false : this.loadingRef <= ref;
|
|
1644
1699
|
}
|
|
1700
|
+
/** @internal */
|
|
1645
1701
|
isLockUndoneBy(ref) {
|
|
1646
1702
|
return this.lockRef === null ? false : this.lockRef <= ref;
|
|
1647
1703
|
}
|
|
@@ -1654,7 +1710,7 @@ var ElementRef = class {
|
|
|
1654
1710
|
}
|
|
1655
1711
|
};
|
|
1656
1712
|
|
|
1657
|
-
// js/phoenix_live_view/dom_post_morph_restorer.
|
|
1713
|
+
// js/phoenix_live_view/dom_post_morph_restorer.ts
|
|
1658
1714
|
var DOMPostMorphRestorer = class {
|
|
1659
1715
|
constructor(containerBefore, containerAfter, updateType) {
|
|
1660
1716
|
const idsBefore = /* @__PURE__ */ new Set();
|
|
@@ -2245,47 +2301,47 @@ function morphdomFactory(morphAttrs2) {
|
|
|
2245
2301
|
var morphdom = morphdomFactory(morphAttrs);
|
|
2246
2302
|
var morphdom_esm_default = morphdom;
|
|
2247
2303
|
|
|
2248
|
-
// js/phoenix_live_view/dom_patch.
|
|
2304
|
+
// js/phoenix_live_view/dom_patch.ts
|
|
2249
2305
|
var DOMPatch = class {
|
|
2250
|
-
constructor(view, container,
|
|
2306
|
+
constructor(view, container, html, streams, targetCID, opts = {}) {
|
|
2251
2307
|
this.view = view;
|
|
2252
2308
|
this.liveSocket = view.liveSocket;
|
|
2253
2309
|
this.container = container;
|
|
2254
|
-
this.id = id;
|
|
2255
2310
|
this.rootID = view.root.id;
|
|
2256
2311
|
this.html = html;
|
|
2257
2312
|
this.streams = streams;
|
|
2258
2313
|
this.streamInserts = {};
|
|
2259
2314
|
this.streamComponentRestore = {};
|
|
2260
2315
|
this.targetCID = targetCID;
|
|
2261
|
-
this.cidPatch = isCid(this.targetCID);
|
|
2262
2316
|
this.pendingRemoves = [];
|
|
2263
2317
|
this.phxRemove = this.liveSocket.binding("remove");
|
|
2264
|
-
this.targetContainer =
|
|
2265
|
-
this.
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
afterdiscarded: [],
|
|
2272
|
-
afterphxChildAdded: [],
|
|
2273
|
-
aftertransitionsDiscarded: []
|
|
2274
|
-
};
|
|
2318
|
+
this.targetContainer = targetCID ? dom_default.getComponent(this.view.id, targetCID) : container;
|
|
2319
|
+
this.beforeUpdatedCallbacks = [];
|
|
2320
|
+
this.afterAddedCallbacks = [];
|
|
2321
|
+
this.afterUpdatedCallbacks = [];
|
|
2322
|
+
this.afterPhxChildAddedCallbacks = [];
|
|
2323
|
+
this.afterDiscardedCallbacks = [];
|
|
2324
|
+
this.afterTransitionsDiscardedCallbacks = [];
|
|
2275
2325
|
this.withChildren = opts.withChildren || opts.undoRef !== void 0 || false;
|
|
2276
|
-
this.undoRef = opts.undoRef;
|
|
2326
|
+
this.undoRef = opts.undoRef ?? null;
|
|
2277
2327
|
}
|
|
2278
|
-
|
|
2279
|
-
this.
|
|
2328
|
+
beforeUpdated(callback) {
|
|
2329
|
+
this.beforeUpdatedCallbacks.push(callback);
|
|
2280
2330
|
}
|
|
2281
|
-
|
|
2282
|
-
this.
|
|
2331
|
+
afterAdded(callback) {
|
|
2332
|
+
this.afterAddedCallbacks.push(callback);
|
|
2283
2333
|
}
|
|
2284
|
-
|
|
2285
|
-
this.
|
|
2334
|
+
afterUpdated(callback) {
|
|
2335
|
+
this.afterUpdatedCallbacks.push(callback);
|
|
2286
2336
|
}
|
|
2287
|
-
|
|
2288
|
-
this.
|
|
2337
|
+
afterPhxChildAdded(callback) {
|
|
2338
|
+
this.afterPhxChildAddedCallbacks.push(callback);
|
|
2339
|
+
}
|
|
2340
|
+
afterDiscarded(callback) {
|
|
2341
|
+
this.afterDiscardedCallbacks.push(callback);
|
|
2342
|
+
}
|
|
2343
|
+
afterTransitionsDiscarded(callback) {
|
|
2344
|
+
this.afterTransitionsDiscardedCallbacks.push(callback);
|
|
2289
2345
|
}
|
|
2290
2346
|
markPrunableContentForRemoval() {
|
|
2291
2347
|
const phxUpdate = this.liveSocket.binding(PHX_UPDATE);
|
|
@@ -2300,10 +2356,7 @@ var DOMPatch = class {
|
|
|
2300
2356
|
perform(isJoinPatch) {
|
|
2301
2357
|
const { view, liveSocket, html, container } = this;
|
|
2302
2358
|
let targetContainer = this.targetContainer;
|
|
2303
|
-
if (this.
|
|
2304
|
-
return;
|
|
2305
|
-
}
|
|
2306
|
-
if (this.isCIDPatch()) {
|
|
2359
|
+
if (this.targetCID) {
|
|
2307
2360
|
const closestLock = targetContainer.closest(`[${PHX_REF_LOCK}]`);
|
|
2308
2361
|
if (closestLock && !closestLock.isSameNode(targetContainer)) {
|
|
2309
2362
|
const clonedTree = dom_default.private(closestLock, PHX_REF_LOCK);
|
|
@@ -2335,6 +2388,8 @@ var DOMPatch = class {
|
|
|
2335
2388
|
// another case is the recursive patch of a stream item that was kept on reset (-> onBeforeNodeAdded)
|
|
2336
2389
|
childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,
|
|
2337
2390
|
getNodeKey: (node) => {
|
|
2391
|
+
if (!(node instanceof Element))
|
|
2392
|
+
return null;
|
|
2338
2393
|
if (dom_default.isPhxDestroyed(node)) {
|
|
2339
2394
|
return null;
|
|
2340
2395
|
}
|
|
@@ -2342,9 +2397,9 @@ var DOMPatch = class {
|
|
|
2342
2397
|
return node.id;
|
|
2343
2398
|
}
|
|
2344
2399
|
if (dom_default.private(node, "clientsideIdAttribute")) {
|
|
2345
|
-
return node.getAttribute
|
|
2400
|
+
return node.getAttribute(PHX_MAGIC_ID);
|
|
2346
2401
|
}
|
|
2347
|
-
return node.id || node.getAttribute
|
|
2402
|
+
return node.id || node.getAttribute(PHX_MAGIC_ID);
|
|
2348
2403
|
},
|
|
2349
2404
|
// skip indexing from children when container is stream
|
|
2350
2405
|
skipFromChildren: (from) => {
|
|
@@ -2365,7 +2420,7 @@ var DOMPatch = class {
|
|
|
2365
2420
|
const nonStreamChild = Array.from(parent.children).find(
|
|
2366
2421
|
(c) => !c.hasAttribute(PHX_STREAM_REF)
|
|
2367
2422
|
);
|
|
2368
|
-
parent.insertBefore(child, nonStreamChild);
|
|
2423
|
+
parent.insertBefore(child, nonStreamChild ?? null);
|
|
2369
2424
|
} else {
|
|
2370
2425
|
parent.appendChild(child);
|
|
2371
2426
|
}
|
|
@@ -2375,11 +2430,13 @@ var DOMPatch = class {
|
|
|
2375
2430
|
}
|
|
2376
2431
|
},
|
|
2377
2432
|
onBeforeNodeAdded: (el) => {
|
|
2433
|
+
if (!(el instanceof Element)) {
|
|
2434
|
+
return el;
|
|
2435
|
+
}
|
|
2378
2436
|
if (this.getStreamInsert(el)?.updateOnly && !this.streamComponentRestore[el.id]) {
|
|
2379
2437
|
return false;
|
|
2380
2438
|
}
|
|
2381
2439
|
dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);
|
|
2382
|
-
this.trackBefore("added", el);
|
|
2383
2440
|
let morphedEl = el;
|
|
2384
2441
|
if (this.streamComponentRestore[el.id]) {
|
|
2385
2442
|
morphedEl = this.streamComponentRestore[el.id];
|
|
@@ -2389,9 +2446,11 @@ var DOMPatch = class {
|
|
|
2389
2446
|
return morphedEl;
|
|
2390
2447
|
},
|
|
2391
2448
|
onNodeAdded: (el) => {
|
|
2392
|
-
if (el
|
|
2393
|
-
|
|
2449
|
+
if (!(el instanceof Element)) {
|
|
2450
|
+
added.push(el);
|
|
2451
|
+
return;
|
|
2394
2452
|
}
|
|
2453
|
+
this.maybeReOrderStream(el, true);
|
|
2395
2454
|
if (dom_default.isPortalTemplate(el)) {
|
|
2396
2455
|
portalCallbacks.push(() => this.teleport(el, morph));
|
|
2397
2456
|
}
|
|
@@ -2404,7 +2463,7 @@ var DOMPatch = class {
|
|
|
2404
2463
|
externalFormTriggered = el;
|
|
2405
2464
|
}
|
|
2406
2465
|
if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {
|
|
2407
|
-
this.
|
|
2466
|
+
this.trackAfterPhxChildAdded(el);
|
|
2408
2467
|
}
|
|
2409
2468
|
if (el.nodeName === "SCRIPT" && el.hasAttribute(PHX_RUNTIME_HOOK)) {
|
|
2410
2469
|
this.handleRuntimeHook(el, source);
|
|
@@ -2413,7 +2472,10 @@ var DOMPatch = class {
|
|
|
2413
2472
|
},
|
|
2414
2473
|
onNodeDiscarded: (el) => this.onNodeDiscarded(el),
|
|
2415
2474
|
onBeforeNodeDiscarded: (el) => {
|
|
2416
|
-
if (el
|
|
2475
|
+
if (!(el instanceof Element)) {
|
|
2476
|
+
return true;
|
|
2477
|
+
}
|
|
2478
|
+
if (el.getAttribute(PHX_PRUNE) !== null) {
|
|
2417
2479
|
return true;
|
|
2418
2480
|
}
|
|
2419
2481
|
if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [
|
|
@@ -2423,7 +2485,7 @@ var DOMPatch = class {
|
|
|
2423
2485
|
])) {
|
|
2424
2486
|
return false;
|
|
2425
2487
|
}
|
|
2426
|
-
if (el.getAttribute
|
|
2488
|
+
if (el.getAttribute(PHX_TELEPORTED_REF)) {
|
|
2427
2489
|
return false;
|
|
2428
2490
|
}
|
|
2429
2491
|
if (this.maybePendingRemove(el)) {
|
|
@@ -2434,7 +2496,7 @@ var DOMPatch = class {
|
|
|
2434
2496
|
}
|
|
2435
2497
|
if (dom_default.isPortalTemplate(el)) {
|
|
2436
2498
|
const teleportedEl = document.getElementById(
|
|
2437
|
-
el.content.firstElementChild
|
|
2499
|
+
el.content.firstElementChild?.id || ""
|
|
2438
2500
|
);
|
|
2439
2501
|
if (teleportedEl) {
|
|
2440
2502
|
teleportedEl.remove();
|
|
@@ -2465,7 +2527,7 @@ var DOMPatch = class {
|
|
|
2465
2527
|
phxViewportBottom
|
|
2466
2528
|
);
|
|
2467
2529
|
dom_default.cleanChildNodes(toEl, phxUpdate);
|
|
2468
|
-
const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.
|
|
2530
|
+
const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isEditableInput(fromEl);
|
|
2469
2531
|
const focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);
|
|
2470
2532
|
if (this.skipCIDSibling(toEl)) {
|
|
2471
2533
|
this.maybeCloneLockedElement(fromEl, isFocusedFormEl);
|
|
@@ -2486,7 +2548,7 @@ var DOMPatch = class {
|
|
|
2486
2548
|
return false;
|
|
2487
2549
|
}
|
|
2488
2550
|
if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {
|
|
2489
|
-
this.
|
|
2551
|
+
this.trackBeforeUpdated(fromEl, toEl);
|
|
2490
2552
|
dom_default.mergeAttrs(fromEl, toEl, {
|
|
2491
2553
|
isIgnored: dom_default.isIgnored(fromEl, phxUpdate)
|
|
2492
2554
|
});
|
|
@@ -2516,7 +2578,7 @@ var DOMPatch = class {
|
|
|
2516
2578
|
return false;
|
|
2517
2579
|
}
|
|
2518
2580
|
if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {
|
|
2519
|
-
this.
|
|
2581
|
+
this.trackBeforeUpdated(fromEl, toEl);
|
|
2520
2582
|
dom_default.mergeFocusedInput(fromEl, toEl);
|
|
2521
2583
|
dom_default.syncAttrsToProps(fromEl);
|
|
2522
2584
|
updates.push(fromEl);
|
|
@@ -2537,15 +2599,14 @@ var DOMPatch = class {
|
|
|
2537
2599
|
}
|
|
2538
2600
|
dom_default.syncAttrsToProps(toEl);
|
|
2539
2601
|
dom_default.applyStickyOperations(toEl);
|
|
2540
|
-
this.
|
|
2602
|
+
this.trackBeforeUpdated(fromEl, toEl);
|
|
2541
2603
|
return fromEl;
|
|
2542
2604
|
}
|
|
2543
2605
|
}
|
|
2544
2606
|
};
|
|
2545
2607
|
morphdom_esm_default(targetContainer2, source, morphCallbacks);
|
|
2546
2608
|
};
|
|
2547
|
-
this.
|
|
2548
|
-
this.trackBefore("updated", container, container);
|
|
2609
|
+
this.trackBeforeUpdated(container, container);
|
|
2549
2610
|
liveSocket.time("morphdom", () => {
|
|
2550
2611
|
this.streams.forEach(([ref, inserts, deleteIds, reset]) => {
|
|
2551
2612
|
inserts.forEach(([key, streamAt, limit, updateOnly]) => {
|
|
@@ -2581,13 +2642,14 @@ var DOMPatch = class {
|
|
|
2581
2642
|
this.view.portalElementIds.forEach((id) => {
|
|
2582
2643
|
const el = document.getElementById(id);
|
|
2583
2644
|
if (el) {
|
|
2584
|
-
const
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2645
|
+
const srcId = el.getAttribute(PHX_TELEPORTED_SRC);
|
|
2646
|
+
if (srcId) {
|
|
2647
|
+
const source = document.getElementById(srcId);
|
|
2648
|
+
if (!source) {
|
|
2649
|
+
el.remove();
|
|
2650
|
+
this.onNodeDiscarded(el);
|
|
2651
|
+
this.view.dropPortalElementId(id);
|
|
2652
|
+
}
|
|
2591
2653
|
}
|
|
2592
2654
|
}
|
|
2593
2655
|
});
|
|
@@ -2615,8 +2677,8 @@ var DOMPatch = class {
|
|
|
2615
2677
|
() => dom_default.restoreFocus(focused, selectionStart, selectionEnd)
|
|
2616
2678
|
);
|
|
2617
2679
|
dom_default.dispatchEvent(document, "phx:update");
|
|
2618
|
-
added.forEach((el) => this.
|
|
2619
|
-
updates.forEach((el) => this.
|
|
2680
|
+
added.forEach((el) => this.trackAfterAdded(el));
|
|
2681
|
+
updates.forEach((el) => this.trackAfterUpdated(el));
|
|
2620
2682
|
this.transitionPendingRemoves();
|
|
2621
2683
|
if (externalFormTriggered) {
|
|
2622
2684
|
liveSocket.unload();
|
|
@@ -2638,11 +2700,29 @@ var DOMPatch = class {
|
|
|
2638
2700
|
}
|
|
2639
2701
|
return true;
|
|
2640
2702
|
}
|
|
2703
|
+
trackBeforeUpdated(fromEl, toEl) {
|
|
2704
|
+
this.beforeUpdatedCallbacks.forEach((cb) => cb(fromEl, toEl));
|
|
2705
|
+
}
|
|
2706
|
+
trackAfterAdded(el) {
|
|
2707
|
+
this.afterAddedCallbacks.forEach((cb) => cb(el));
|
|
2708
|
+
}
|
|
2709
|
+
trackAfterUpdated(el) {
|
|
2710
|
+
this.afterUpdatedCallbacks.forEach((cb) => cb(el));
|
|
2711
|
+
}
|
|
2712
|
+
trackAfterPhxChildAdded(el) {
|
|
2713
|
+
this.afterPhxChildAddedCallbacks.forEach((cb) => cb(el));
|
|
2714
|
+
}
|
|
2715
|
+
trackAfterDiscarded(el) {
|
|
2716
|
+
this.afterDiscardedCallbacks.forEach((cb) => cb(el));
|
|
2717
|
+
}
|
|
2718
|
+
trackAfterTransitionsDiscarded(els) {
|
|
2719
|
+
this.afterTransitionsDiscardedCallbacks.forEach((cb) => cb(els));
|
|
2720
|
+
}
|
|
2641
2721
|
onNodeDiscarded(el) {
|
|
2642
2722
|
if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {
|
|
2643
2723
|
this.liveSocket.destroyViewByEl(el);
|
|
2644
2724
|
}
|
|
2645
|
-
this.
|
|
2725
|
+
this.trackAfterDiscarded(el);
|
|
2646
2726
|
}
|
|
2647
2727
|
maybePendingRemove(node) {
|
|
2648
2728
|
if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {
|
|
@@ -2677,7 +2757,7 @@ var DOMPatch = class {
|
|
|
2677
2757
|
(el2) => el2.setAttribute(PHX_STREAM_REF, ref)
|
|
2678
2758
|
);
|
|
2679
2759
|
}
|
|
2680
|
-
maybeReOrderStream(el, isNew) {
|
|
2760
|
+
maybeReOrderStream(el, isNew = false) {
|
|
2681
2761
|
const { ref, streamAt, reset } = this.getStreamInsert(el);
|
|
2682
2762
|
if (streamAt === void 0) {
|
|
2683
2763
|
return;
|
|
@@ -2733,11 +2813,13 @@ var DOMPatch = class {
|
|
|
2733
2813
|
}
|
|
2734
2814
|
maybeLimitStream(el) {
|
|
2735
2815
|
const { limit } = this.getStreamInsert(el);
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2816
|
+
if (limit !== null) {
|
|
2817
|
+
const children = Array.from(el.parentElement.children);
|
|
2818
|
+
if (limit < 0 && children.length > limit * -1) {
|
|
2819
|
+
children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));
|
|
2820
|
+
} else if (limit >= 0 && children.length > limit) {
|
|
2821
|
+
children.slice(limit).forEach((child) => this.removeStreamChildElement(child));
|
|
2822
|
+
}
|
|
2741
2823
|
}
|
|
2742
2824
|
}
|
|
2743
2825
|
transitionPendingRemoves() {
|
|
@@ -2751,7 +2833,7 @@ var DOMPatch = class {
|
|
|
2751
2833
|
}
|
|
2752
2834
|
el.remove();
|
|
2753
2835
|
});
|
|
2754
|
-
this.
|
|
2836
|
+
this.trackAfterTransitionsDiscarded(pendingRemoves);
|
|
2755
2837
|
});
|
|
2756
2838
|
}
|
|
2757
2839
|
}
|
|
@@ -2765,9 +2847,6 @@ var DOMPatch = class {
|
|
|
2765
2847
|
toEl.value = fromEl.value;
|
|
2766
2848
|
return !fromEl.isEqualNode(toEl);
|
|
2767
2849
|
}
|
|
2768
|
-
isCIDPatch() {
|
|
2769
|
-
return this.cidPatch;
|
|
2770
|
-
}
|
|
2771
2850
|
skipCIDSibling(el) {
|
|
2772
2851
|
return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);
|
|
2773
2852
|
}
|
|
@@ -2775,7 +2854,7 @@ var DOMPatch = class {
|
|
|
2775
2854
|
if (!fromEl.hasAttribute(PHX_REF_SRC))
|
|
2776
2855
|
return fromEl;
|
|
2777
2856
|
const ref = new ElementRef(fromEl);
|
|
2778
|
-
if (
|
|
2857
|
+
if (!fromEl.hasAttribute(PHX_REF_LOCK) || this.undoRef !== null && ref.isLockUndoneBy(this.undoRef)) {
|
|
2779
2858
|
return fromEl;
|
|
2780
2859
|
}
|
|
2781
2860
|
dom_default.applyStickyOperations(fromEl);
|
|
@@ -2786,24 +2865,10 @@ var DOMPatch = class {
|
|
|
2786
2865
|
return isFocusedFormEl ? fromEl : clone2;
|
|
2787
2866
|
}
|
|
2788
2867
|
copyNestedPrivateLock(fromEl, toEl) {
|
|
2789
|
-
if (this.undoRef ===
|
|
2868
|
+
if (this.undoRef === null || !dom_default.private(toEl, PHX_REF_LOCK))
|
|
2790
2869
|
return;
|
|
2791
2870
|
dom_default.putPrivate(fromEl, PHX_REF_LOCK, dom_default.private(toEl, PHX_REF_LOCK));
|
|
2792
2871
|
}
|
|
2793
|
-
targetCIDContainer(html) {
|
|
2794
|
-
if (!this.isCIDPatch()) {
|
|
2795
|
-
return;
|
|
2796
|
-
}
|
|
2797
|
-
const [first, ...rest] = dom_default.findComponentNodeList(
|
|
2798
|
-
this.view.id,
|
|
2799
|
-
this.targetCID
|
|
2800
|
-
);
|
|
2801
|
-
if (rest.length === 0 && dom_default.childNodeLength(html) === 1) {
|
|
2802
|
-
return first;
|
|
2803
|
-
} else {
|
|
2804
|
-
return first && first.parentNode;
|
|
2805
|
-
}
|
|
2806
|
-
}
|
|
2807
2872
|
indexOf(parent, child) {
|
|
2808
2873
|
return Array.from(parent.children).indexOf(child);
|
|
2809
2874
|
}
|
|
@@ -2848,7 +2913,7 @@ var DOMPatch = class {
|
|
|
2848
2913
|
if (el.hasAttribute("nonce")) {
|
|
2849
2914
|
const template = document.createElement("template");
|
|
2850
2915
|
template.innerHTML = source;
|
|
2851
|
-
nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`)
|
|
2916
|
+
nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`)?.getAttribute("nonce") ?? null;
|
|
2852
2917
|
}
|
|
2853
2918
|
const script = document.createElement("script");
|
|
2854
2919
|
script.textContent = el.textContent;
|
|
@@ -3370,7 +3435,7 @@ var JS = {
|
|
|
3370
3435
|
}
|
|
3371
3436
|
if (eventType === "change") {
|
|
3372
3437
|
let { newCid, _target } = args;
|
|
3373
|
-
_target = _target || (dom_default.
|
|
3438
|
+
_target = _target || (dom_default.isFormAssociated(sourceEl) ? sourceEl.name : void 0);
|
|
3374
3439
|
if (_target) {
|
|
3375
3440
|
pushOpts._target = _target;
|
|
3376
3441
|
}
|
|
@@ -3884,6 +3949,7 @@ var js_commands_default = (liveSocket, eventType) => {
|
|
|
3884
3949
|
});
|
|
3885
3950
|
},
|
|
3886
3951
|
navigate(href, opts = {}) {
|
|
3952
|
+
ensureSameOrigin(href, "navigate");
|
|
3887
3953
|
const customEvent = new CustomEvent("phx:exec");
|
|
3888
3954
|
liveSocket.historyRedirect(
|
|
3889
3955
|
customEvent,
|
|
@@ -3894,6 +3960,7 @@ var js_commands_default = (liveSocket, eventType) => {
|
|
|
3894
3960
|
);
|
|
3895
3961
|
},
|
|
3896
3962
|
patch(href, opts = {}) {
|
|
3963
|
+
ensureSameOrigin(href, "patch");
|
|
3897
3964
|
const customEvent = new CustomEvent("phx:exec");
|
|
3898
3965
|
liveSocket.pushHistoryPatch(
|
|
3899
3966
|
customEvent,
|
|
@@ -3916,15 +3983,19 @@ var ViewHook = class _ViewHook {
|
|
|
3916
3983
|
get liveSocket() {
|
|
3917
3984
|
return this.__liveSocket();
|
|
3918
3985
|
}
|
|
3986
|
+
/** @internal */
|
|
3919
3987
|
static makeID() {
|
|
3920
3988
|
return viewHookID++;
|
|
3921
3989
|
}
|
|
3990
|
+
/** @internal */
|
|
3922
3991
|
static elementID(el) {
|
|
3923
3992
|
return dom_default.private(el, HOOK_ID);
|
|
3924
3993
|
}
|
|
3994
|
+
/** @internal */
|
|
3925
3995
|
static deadHook(el) {
|
|
3926
3996
|
return dom_default.private(el, DEAD_HOOK) === true;
|
|
3927
3997
|
}
|
|
3998
|
+
/** @internal */
|
|
3928
3999
|
constructor(view, el, callbacks) {
|
|
3929
4000
|
this.el = el;
|
|
3930
4001
|
this.__attachView(view);
|
|
@@ -4079,7 +4150,12 @@ var ViewHook = class _ViewHook {
|
|
|
4079
4150
|
}
|
|
4080
4151
|
);
|
|
4081
4152
|
const promises = targetPair.map(({ view, targetCtx }) => {
|
|
4082
|
-
return view.pushHookEvent(
|
|
4153
|
+
return view.pushHookEvent(
|
|
4154
|
+
this.el,
|
|
4155
|
+
targetCtx,
|
|
4156
|
+
event,
|
|
4157
|
+
payload || {}
|
|
4158
|
+
);
|
|
4083
4159
|
});
|
|
4084
4160
|
return Promise.allSettled(promises);
|
|
4085
4161
|
}
|
|
@@ -4131,7 +4207,7 @@ var ViewHook = class _ViewHook {
|
|
|
4131
4207
|
}
|
|
4132
4208
|
};
|
|
4133
4209
|
|
|
4134
|
-
// js/phoenix_live_view/view.
|
|
4210
|
+
// js/phoenix_live_view/view.ts
|
|
4135
4211
|
var prependFormDataKey = (key, prefix) => {
|
|
4136
4212
|
const isArray = key.endsWith("[]");
|
|
4137
4213
|
let baseKey = isArray ? key.slice(0, -2) : key;
|
|
@@ -4146,7 +4222,8 @@ var View = class _View {
|
|
|
4146
4222
|
const liveViewEl = el.closest(PHX_VIEW_SELECTOR);
|
|
4147
4223
|
return liveViewEl ? dom_default.private(liveViewEl, "view") : null;
|
|
4148
4224
|
}
|
|
4149
|
-
constructor(el, liveSocket, parentView, flash, liveReferer) {
|
|
4225
|
+
constructor(el, liveSocket, parentView, flash = null, liveReferer = null) {
|
|
4226
|
+
this.rendered = null;
|
|
4150
4227
|
this.isDead = false;
|
|
4151
4228
|
this.liveSocket = liveSocket;
|
|
4152
4229
|
this.flash = flash;
|
|
@@ -4202,7 +4279,7 @@ var View = class _View {
|
|
|
4202
4279
|
params: this.connectParams(liveReferer),
|
|
4203
4280
|
session: this.getSession(),
|
|
4204
4281
|
static: this.getStatic(),
|
|
4205
|
-
flash: this.flash,
|
|
4282
|
+
flash: this.flash ?? void 0,
|
|
4206
4283
|
sticky: this.el.hasAttribute(PHX_STICKY)
|
|
4207
4284
|
};
|
|
4208
4285
|
});
|
|
@@ -4220,13 +4297,15 @@ var View = class _View {
|
|
|
4220
4297
|
}
|
|
4221
4298
|
connectParams(liveReferer) {
|
|
4222
4299
|
const params = this.liveSocket.params(this.el);
|
|
4223
|
-
const manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map(
|
|
4300
|
+
const manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map(
|
|
4301
|
+
(node) => "src" in node && node.src || "href" in node && node.href
|
|
4302
|
+
).filter((url) => typeof url === "string");
|
|
4224
4303
|
if (manifest.length > 0) {
|
|
4225
4304
|
params["_track_static"] = manifest;
|
|
4226
4305
|
}
|
|
4227
4306
|
params["_mounts"] = this.joinCount;
|
|
4228
4307
|
params["_mount_attempts"] = this.joinAttempts;
|
|
4229
|
-
params["_live_referer"] = liveReferer;
|
|
4308
|
+
params["_live_referer"] = liveReferer ?? void 0;
|
|
4230
4309
|
this.joinAttempts++;
|
|
4231
4310
|
return params;
|
|
4232
4311
|
}
|
|
@@ -4250,7 +4329,7 @@ var View = class _View {
|
|
|
4250
4329
|
if (this.parent) {
|
|
4251
4330
|
delete this.root.children[this.parent.id][this.id];
|
|
4252
4331
|
}
|
|
4253
|
-
clearTimeout(this.loaderTimer);
|
|
4332
|
+
this.loaderTimer != null && clearTimeout(this.loaderTimer);
|
|
4254
4333
|
const onFinished = () => {
|
|
4255
4334
|
callback();
|
|
4256
4335
|
for (const id in this.viewHooks) {
|
|
@@ -4272,7 +4351,7 @@ var View = class _View {
|
|
|
4272
4351
|
this.el.classList.add(...classes);
|
|
4273
4352
|
}
|
|
4274
4353
|
showLoader(timeout) {
|
|
4275
|
-
clearTimeout(this.loaderTimer);
|
|
4354
|
+
this.loaderTimer != null && clearTimeout(this.loaderTimer);
|
|
4276
4355
|
if (timeout) {
|
|
4277
4356
|
this.loaderTimer = setTimeout(() => this.showLoader(), timeout);
|
|
4278
4357
|
} else {
|
|
@@ -4290,8 +4369,8 @@ var View = class _View {
|
|
|
4290
4369
|
);
|
|
4291
4370
|
}
|
|
4292
4371
|
hideLoader() {
|
|
4293
|
-
clearTimeout(this.loaderTimer);
|
|
4294
|
-
clearTimeout(this.disconnectedTimer);
|
|
4372
|
+
this.loaderTimer != null && clearTimeout(this.loaderTimer);
|
|
4373
|
+
this.disconnectedTimer != null && clearTimeout(this.disconnectedTimer);
|
|
4295
4374
|
this.setContainerClasses(PHX_CONNECTED_CLASS);
|
|
4296
4375
|
this.execAll(this.binding("connected"));
|
|
4297
4376
|
}
|
|
@@ -4321,11 +4400,14 @@ var View = class _View {
|
|
|
4321
4400
|
);
|
|
4322
4401
|
}
|
|
4323
4402
|
if (isCid(phxTarget)) {
|
|
4324
|
-
const
|
|
4325
|
-
if (
|
|
4403
|
+
const target = dom_default.findComponent(this.id, phxTarget, dom);
|
|
4404
|
+
if (!target) {
|
|
4326
4405
|
logError(`no component found matching phx-target of ${phxTarget}`);
|
|
4327
4406
|
} else {
|
|
4328
|
-
callback(
|
|
4407
|
+
callback(
|
|
4408
|
+
this,
|
|
4409
|
+
typeof phxTarget === "number" ? phxTarget : parseInt(phxTarget)
|
|
4410
|
+
);
|
|
4329
4411
|
}
|
|
4330
4412
|
} else {
|
|
4331
4413
|
const targets = Array.from(dom.querySelectorAll(phxTarget));
|
|
@@ -4452,7 +4534,11 @@ var View = class _View {
|
|
|
4452
4534
|
}
|
|
4453
4535
|
}
|
|
4454
4536
|
attachTrueDocEl() {
|
|
4455
|
-
|
|
4537
|
+
const el = dom_default.byId(this.id);
|
|
4538
|
+
if (!el) {
|
|
4539
|
+
throw new Error("unable to find root element for view");
|
|
4540
|
+
}
|
|
4541
|
+
this.el = el;
|
|
4456
4542
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
4457
4543
|
}
|
|
4458
4544
|
// this is invoked for dead and live views, so we must filter by
|
|
@@ -4501,7 +4587,7 @@ var View = class _View {
|
|
|
4501
4587
|
}
|
|
4502
4588
|
}
|
|
4503
4589
|
this.attachTrueDocEl();
|
|
4504
|
-
const patch = new DOMPatch(this, this.el,
|
|
4590
|
+
const patch = new DOMPatch(this, this.el, html, streams, null);
|
|
4505
4591
|
patch.markPrunableContentForRemoval();
|
|
4506
4592
|
this.performPatch(patch, false, true);
|
|
4507
4593
|
this.joinNewChildren();
|
|
@@ -4547,7 +4633,7 @@ var View = class _View {
|
|
|
4547
4633
|
let phxChildrenAdded = false;
|
|
4548
4634
|
const updatedHookIds = /* @__PURE__ */ new Set();
|
|
4549
4635
|
this.liveSocket.triggerDOM("onPatchStart", [patch.targetContainer]);
|
|
4550
|
-
patch.
|
|
4636
|
+
patch.afterAdded((el) => {
|
|
4551
4637
|
this.liveSocket.triggerDOM("onNodeAdded", [el]);
|
|
4552
4638
|
const phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
|
|
4553
4639
|
const phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
|
|
@@ -4557,33 +4643,32 @@ var View = class _View {
|
|
|
4557
4643
|
this.maybeMounted(el);
|
|
4558
4644
|
}
|
|
4559
4645
|
});
|
|
4560
|
-
patch.
|
|
4646
|
+
patch.afterPhxChildAdded((el) => {
|
|
4561
4647
|
if (dom_default.isPhxSticky(el)) {
|
|
4562
4648
|
this.liveSocket.joinRootViews();
|
|
4563
4649
|
} else {
|
|
4564
4650
|
phxChildrenAdded = true;
|
|
4565
4651
|
}
|
|
4566
4652
|
});
|
|
4567
|
-
patch.
|
|
4653
|
+
patch.beforeUpdated((fromEl, toEl) => {
|
|
4568
4654
|
const hook = this.triggerBeforeUpdateHook(fromEl, toEl);
|
|
4569
4655
|
if (hook) {
|
|
4570
4656
|
updatedHookIds.add(fromEl.id);
|
|
4571
4657
|
}
|
|
4572
4658
|
js_default.onBeforeElUpdated(fromEl, toEl);
|
|
4573
4659
|
});
|
|
4574
|
-
patch.
|
|
4660
|
+
patch.afterUpdated((el) => {
|
|
4575
4661
|
if (updatedHookIds.has(el.id)) {
|
|
4576
4662
|
const hook = this.getHook(el);
|
|
4577
4663
|
hook && hook.__updated();
|
|
4578
4664
|
}
|
|
4579
4665
|
});
|
|
4580
|
-
patch.
|
|
4666
|
+
patch.afterDiscarded((el) => {
|
|
4581
4667
|
if (el.nodeType === Node.ELEMENT_NODE) {
|
|
4582
4668
|
removedEls.push(el);
|
|
4583
4669
|
}
|
|
4584
4670
|
});
|
|
4585
|
-
patch.
|
|
4586
|
-
"transitionsDiscarded",
|
|
4671
|
+
patch.afterTransitionsDiscarded(
|
|
4587
4672
|
(els) => this.afterElementsRemoved(els, pruneCids)
|
|
4588
4673
|
);
|
|
4589
4674
|
patch.perform(isJoinPatch);
|
|
@@ -4625,8 +4710,14 @@ var View = class _View {
|
|
|
4625
4710
|
const oldForms = this.root.formsForRecovery;
|
|
4626
4711
|
const template = document.createElement("template");
|
|
4627
4712
|
template.innerHTML = html;
|
|
4713
|
+
if (!template.content.firstElementChild) {
|
|
4714
|
+
return;
|
|
4715
|
+
}
|
|
4628
4716
|
dom_default.all(template.content, `[${PHX_PORTAL}]`).forEach((portalTemplate) => {
|
|
4629
|
-
|
|
4717
|
+
if (!(portalTemplate instanceof HTMLTemplateElement)) {
|
|
4718
|
+
return;
|
|
4719
|
+
}
|
|
4720
|
+
template.content.firstElementChild?.appendChild(
|
|
4630
4721
|
portalTemplate.content.firstElementChild
|
|
4631
4722
|
);
|
|
4632
4723
|
});
|
|
@@ -4634,8 +4725,8 @@ var View = class _View {
|
|
|
4634
4725
|
rootEl.id = this.id;
|
|
4635
4726
|
rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
4636
4727
|
rootEl.setAttribute(PHX_SESSION, this.getSession());
|
|
4637
|
-
rootEl.setAttribute(PHX_STATIC, this.getStatic());
|
|
4638
|
-
rootEl.setAttribute(PHX_PARENT_ID, this.parent
|
|
4728
|
+
rootEl.setAttribute(PHX_STATIC, this.getStatic() ?? "");
|
|
4729
|
+
this.parent && rootEl.setAttribute(PHX_PARENT_ID, this.parent.id);
|
|
4639
4730
|
const formsToRecover = (
|
|
4640
4731
|
// we go over all forms in the new DOM; because this is only the HTML for the current
|
|
4641
4732
|
// view, we can be sure that all forms are owned by this view:
|
|
@@ -4670,7 +4761,7 @@ var View = class _View {
|
|
|
4670
4761
|
if (el.id === this.id) {
|
|
4671
4762
|
return this;
|
|
4672
4763
|
} else {
|
|
4673
|
-
return this.children[el.getAttribute(PHX_PARENT_ID)]?.[el.id];
|
|
4764
|
+
return this.children && this.children[el.getAttribute(PHX_PARENT_ID)]?.[el.id];
|
|
4674
4765
|
}
|
|
4675
4766
|
}
|
|
4676
4767
|
destroyDescendent(id) {
|
|
@@ -4744,7 +4835,7 @@ var View = class _View {
|
|
|
4744
4835
|
} else if (!isEmpty(diff)) {
|
|
4745
4836
|
this.liveSocket.time("full patch complete", () => {
|
|
4746
4837
|
const [html, streams] = this.renderContainer(diff, "update");
|
|
4747
|
-
const patch = new DOMPatch(this, this.el,
|
|
4838
|
+
const patch = new DOMPatch(this, this.el, html, streams, null);
|
|
4748
4839
|
phxChildrenAdded = this.performPatch(patch, true);
|
|
4749
4840
|
});
|
|
4750
4841
|
}
|
|
@@ -4766,7 +4857,7 @@ var View = class _View {
|
|
|
4766
4857
|
if (isEmpty(diff))
|
|
4767
4858
|
return false;
|
|
4768
4859
|
const { buffer: html, streams } = this.rendered.componentToString(cid);
|
|
4769
|
-
const patch = new DOMPatch(this, this.el,
|
|
4860
|
+
const patch = new DOMPatch(this, this.el, html, streams, cid);
|
|
4770
4861
|
const childrenAdded = this.performPatch(patch, true);
|
|
4771
4862
|
return childrenAdded;
|
|
4772
4863
|
}
|
|
@@ -4896,11 +4987,12 @@ var View = class _View {
|
|
|
4896
4987
|
expandURL(to) {
|
|
4897
4988
|
return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to;
|
|
4898
4989
|
}
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4990
|
+
onRedirect({
|
|
4991
|
+
to,
|
|
4992
|
+
flash,
|
|
4993
|
+
reloadToken
|
|
4994
|
+
}) {
|
|
4995
|
+
this.liveSocket.redirect(to, flash ?? null, reloadToken ?? null);
|
|
4904
4996
|
}
|
|
4905
4997
|
isDestroyed() {
|
|
4906
4998
|
return this.destroyed;
|
|
@@ -4908,10 +5000,6 @@ var View = class _View {
|
|
|
4908
5000
|
joinDead() {
|
|
4909
5001
|
this.isDead = true;
|
|
4910
5002
|
}
|
|
4911
|
-
joinPush() {
|
|
4912
|
-
this.joinPush = this.joinPush || this.channel.join();
|
|
4913
|
-
return this.joinPush;
|
|
4914
|
-
}
|
|
4915
5003
|
join(callback) {
|
|
4916
5004
|
this.showLoader(this.liveSocket.loaderTimeout);
|
|
4917
5005
|
this.bindChannel();
|
|
@@ -4933,6 +5021,9 @@ var View = class _View {
|
|
|
4933
5021
|
});
|
|
4934
5022
|
}
|
|
4935
5023
|
onJoinError(resp) {
|
|
5024
|
+
if (resp.events) {
|
|
5025
|
+
this.liveSocket.dispatchEvents(resp.events);
|
|
5026
|
+
}
|
|
4936
5027
|
if (resp.reason === "reload") {
|
|
4937
5028
|
this.log("error", () => [
|
|
4938
5029
|
`failed mount with ${resp.status}. Falling back to page reload`,
|
|
@@ -5150,7 +5241,7 @@ var View = class _View {
|
|
|
5150
5241
|
undoElRef(el, ref, phxEvent) {
|
|
5151
5242
|
const elRef = new ElementRef(el);
|
|
5152
5243
|
elRef.maybeUndo(ref, phxEvent, (clonedTree) => {
|
|
5153
|
-
const patch = new DOMPatch(this, el,
|
|
5244
|
+
const patch = new DOMPatch(this, el, clonedTree, /* @__PURE__ */ new Set(), null, {
|
|
5154
5245
|
undoRef: ref
|
|
5155
5246
|
});
|
|
5156
5247
|
const phxChildrenAdded = this.performPatch(patch, true);
|
|
@@ -5182,10 +5273,10 @@ var View = class _View {
|
|
|
5182
5273
|
}
|
|
5183
5274
|
el.setAttribute(PHX_REF_SRC, this.refSrc());
|
|
5184
5275
|
if (loading) {
|
|
5185
|
-
el.setAttribute(PHX_REF_LOADING, newRef);
|
|
5276
|
+
el.setAttribute(PHX_REF_LOADING, newRef.toString());
|
|
5186
5277
|
}
|
|
5187
5278
|
if (lock) {
|
|
5188
|
-
el.setAttribute(PHX_REF_LOCK, newRef);
|
|
5279
|
+
el.setAttribute(PHX_REF_LOCK, newRef.toString());
|
|
5189
5280
|
}
|
|
5190
5281
|
if (!loading || opts.submitter && !(el === opts.submitter || el === opts.form)) {
|
|
5191
5282
|
continue;
|
|
@@ -5206,14 +5297,14 @@ var View = class _View {
|
|
|
5206
5297
|
const disableText = el.getAttribute(disableWith);
|
|
5207
5298
|
if (disableText !== null) {
|
|
5208
5299
|
if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {
|
|
5209
|
-
el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent);
|
|
5300
|
+
el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent || "");
|
|
5210
5301
|
}
|
|
5211
5302
|
if (disableText !== "") {
|
|
5212
5303
|
el.textContent = disableText;
|
|
5213
5304
|
}
|
|
5214
5305
|
el.setAttribute(
|
|
5215
5306
|
PHX_DISABLED,
|
|
5216
|
-
el.getAttribute(PHX_DISABLED) || el.disabled
|
|
5307
|
+
el.getAttribute(PHX_DISABLED) || ("disabled" in el ? String(el.disabled) : "")
|
|
5217
5308
|
);
|
|
5218
5309
|
el.setAttribute("disabled", "");
|
|
5219
5310
|
}
|
|
@@ -5287,7 +5378,7 @@ var View = class _View {
|
|
|
5287
5378
|
}
|
|
5288
5379
|
const cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
|
|
5289
5380
|
if (isCid(cidOrSelector)) {
|
|
5290
|
-
return parseInt(cidOrSelector);
|
|
5381
|
+
return typeof cidOrSelector === "number" ? cidOrSelector : parseInt(cidOrSelector);
|
|
5291
5382
|
} else if (targetCtx && (cidOrSelector !== null || opts.target)) {
|
|
5292
5383
|
return this.closestComponentID(targetCtx);
|
|
5293
5384
|
} else {
|
|
@@ -5337,7 +5428,9 @@ var View = class _View {
|
|
|
5337
5428
|
event,
|
|
5338
5429
|
value: payload,
|
|
5339
5430
|
cid: this.closestComponentID(targetCtx)
|
|
5340
|
-
}).then(
|
|
5431
|
+
}).then(
|
|
5432
|
+
({ resp: _resp, reply, ref }) => ({ reply, ref })
|
|
5433
|
+
);
|
|
5341
5434
|
}
|
|
5342
5435
|
extractMeta(el, meta, value) {
|
|
5343
5436
|
const prefix = this.binding("value-");
|
|
@@ -5369,7 +5462,7 @@ var View = class _View {
|
|
|
5369
5462
|
}
|
|
5370
5463
|
return meta;
|
|
5371
5464
|
}
|
|
5372
|
-
serializeForm(form, opts, onlyNames = []) {
|
|
5465
|
+
serializeForm(form, opts = {}, onlyNames = []) {
|
|
5373
5466
|
const { submitter } = opts;
|
|
5374
5467
|
let injectedElement;
|
|
5375
5468
|
if (submitter && submitter.name) {
|
|
@@ -5395,6 +5488,9 @@ var View = class _View {
|
|
|
5395
5488
|
const params = new URLSearchParams();
|
|
5396
5489
|
const { inputsUnused, onlyHiddenInputs } = Array.from(form.elements).reduce(
|
|
5397
5490
|
(acc, input) => {
|
|
5491
|
+
if (!dom_default.isFormAssociated(input)) {
|
|
5492
|
+
return acc;
|
|
5493
|
+
}
|
|
5398
5494
|
const { inputsUnused: inputsUnused2, onlyHiddenInputs: onlyHiddenInputs2 } = acc;
|
|
5399
5495
|
const key = input.name;
|
|
5400
5496
|
if (!key) {
|
|
@@ -5583,27 +5679,30 @@ var View = class _View {
|
|
|
5583
5679
|
return el.hasAttribute(this.binding(PHX_DISABLE_WITH));
|
|
5584
5680
|
};
|
|
5585
5681
|
const filterButton = (el) => el.tagName == "BUTTON";
|
|
5586
|
-
const filterInput = (el) => ["INPUT", "TEXTAREA"
|
|
5682
|
+
const filterInput = (el) => ["INPUT", "TEXTAREA"].includes(el.tagName);
|
|
5587
5683
|
const formElements = Array.from(formEl.elements);
|
|
5588
5684
|
const disables = formElements.filter(filterDisables);
|
|
5589
5685
|
const buttons = formElements.filter(filterButton).filter(filterIgnored);
|
|
5590
5686
|
const inputs = formElements.filter(filterInput).filter(filterIgnored);
|
|
5591
5687
|
buttons.forEach((button) => {
|
|
5592
|
-
button.setAttribute(PHX_DISABLED, button.disabled);
|
|
5688
|
+
button.setAttribute(PHX_DISABLED, button.disabled.toString());
|
|
5593
5689
|
button.disabled = true;
|
|
5594
5690
|
});
|
|
5595
5691
|
inputs.forEach((input) => {
|
|
5596
|
-
input.setAttribute(PHX_READONLY, input.readOnly);
|
|
5692
|
+
input.setAttribute(PHX_READONLY, input.readOnly.toString());
|
|
5597
5693
|
input.readOnly = true;
|
|
5598
|
-
if (input.files) {
|
|
5599
|
-
input.setAttribute(PHX_DISABLED, input.disabled);
|
|
5694
|
+
if (input instanceof HTMLInputElement && input.files) {
|
|
5695
|
+
input.setAttribute(PHX_DISABLED, input.disabled.toString());
|
|
5600
5696
|
input.disabled = true;
|
|
5601
5697
|
}
|
|
5602
5698
|
});
|
|
5603
5699
|
const formEls = disables.concat(buttons).concat(inputs).map((el) => {
|
|
5604
5700
|
return { el, loading: true, lock: true };
|
|
5605
5701
|
});
|
|
5606
|
-
const els = [
|
|
5702
|
+
const els = [
|
|
5703
|
+
{ el: formEl, loading: true, lock: false },
|
|
5704
|
+
...formEls
|
|
5705
|
+
].reverse();
|
|
5607
5706
|
return this.putRef(els, phxEvent, "submit", opts);
|
|
5608
5707
|
}
|
|
5609
5708
|
pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {
|
|
@@ -5735,7 +5834,7 @@ var View = class _View {
|
|
|
5735
5834
|
}
|
|
5736
5835
|
targetCtxElement(targetCtx) {
|
|
5737
5836
|
if (isCid(targetCtx)) {
|
|
5738
|
-
const
|
|
5837
|
+
const target = dom_default.findComponent(this.id, targetCtx);
|
|
5739
5838
|
return target;
|
|
5740
5839
|
} else if (targetCtx) {
|
|
5741
5840
|
return targetCtx;
|
|
@@ -5748,7 +5847,7 @@ var View = class _View {
|
|
|
5748
5847
|
const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;
|
|
5749
5848
|
const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));
|
|
5750
5849
|
const inputs = Array.from(oldForm.elements).filter(
|
|
5751
|
-
(el) => dom_default.
|
|
5850
|
+
(el) => dom_default.isFormAssociated(el) && el.name && !el.hasAttribute(phxChange)
|
|
5752
5851
|
);
|
|
5753
5852
|
if (inputs.length === 0) {
|
|
5754
5853
|
callback();
|
|
@@ -5794,7 +5893,7 @@ var View = class _View {
|
|
|
5794
5893
|
null,
|
|
5795
5894
|
"click"
|
|
5796
5895
|
) : null;
|
|
5797
|
-
const fallback = () => this.liveSocket.redirect(window.location.href);
|
|
5896
|
+
const fallback = () => this.liveSocket.redirect(window.location.href, null, null);
|
|
5798
5897
|
const url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;
|
|
5799
5898
|
this.pushWithReply(refGen, "live_patch", { url }).then(
|
|
5800
5899
|
({ resp }) => {
|
|
@@ -5823,14 +5922,14 @@ var View = class _View {
|
|
|
5823
5922
|
return dom_default.all(
|
|
5824
5923
|
document,
|
|
5825
5924
|
`#${CSS.escape(this.id)} form[${phxChange}], [${PHX_TELEPORTED_REF}="${CSS.escape(this.id)}"] form[${phxChange}]`
|
|
5826
|
-
).filter((form) => form.id).filter((form) => form.elements.length > 0).filter(
|
|
5925
|
+
).filter((form) => form instanceof HTMLFormElement).filter((form) => form.id).filter((form) => form.elements.length > 0).filter(
|
|
5827
5926
|
(form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore"
|
|
5828
5927
|
).map((form) => {
|
|
5829
5928
|
const clonedForm = form.cloneNode(true);
|
|
5830
5929
|
morphdom_esm_default(clonedForm, form, {
|
|
5831
5930
|
onBeforeElUpdated: (fromEl, toEl) => {
|
|
5832
5931
|
dom_default.copyPrivates(fromEl, toEl);
|
|
5833
|
-
if (fromEl.getAttribute("form") === form.id) {
|
|
5932
|
+
if (fromEl.getAttribute("form") === form.id && fromEl.parentNode) {
|
|
5834
5933
|
fromEl.parentNode.removeChild(fromEl);
|
|
5835
5934
|
return false;
|
|
5836
5935
|
}
|
|
@@ -5841,10 +5940,7 @@ var View = class _View {
|
|
|
5841
5940
|
`[form="${CSS.escape(form.id)}"]`
|
|
5842
5941
|
);
|
|
5843
5942
|
Array.from(externalElements).forEach((el) => {
|
|
5844
|
-
const clonedEl = (
|
|
5845
|
-
/** @type {HTMLElement} */
|
|
5846
|
-
el.cloneNode(true)
|
|
5847
|
-
);
|
|
5943
|
+
const clonedEl = el.cloneNode(true);
|
|
5848
5944
|
morphdom_esm_default(clonedEl, el);
|
|
5849
5945
|
dom_default.copyPrivates(clonedEl, el);
|
|
5850
5946
|
clonedEl.removeAttribute("form");
|
|
@@ -5858,7 +5954,7 @@ var View = class _View {
|
|
|
5858
5954
|
}
|
|
5859
5955
|
maybePushComponentsDestroyed(destroyedCIDs) {
|
|
5860
5956
|
let willDestroyCIDs = destroyedCIDs.filter((cid) => {
|
|
5861
|
-
return dom_default.
|
|
5957
|
+
return dom_default.findComponent(this.id, cid) === null;
|
|
5862
5958
|
});
|
|
5863
5959
|
const onError = (error) => {
|
|
5864
5960
|
if (!this.isDestroyed()) {
|
|
@@ -5870,7 +5966,7 @@ var View = class _View {
|
|
|
5870
5966
|
this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }).then(() => {
|
|
5871
5967
|
this.liveSocket.requestDOMUpdate(() => {
|
|
5872
5968
|
let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {
|
|
5873
|
-
return dom_default.
|
|
5969
|
+
return dom_default.findComponent(this.id, cid) === null;
|
|
5874
5970
|
});
|
|
5875
5971
|
if (completelyDestroyCIDs.length > 0) {
|
|
5876
5972
|
this.pushWithReply(null, "cids_destroyed", {
|
|
@@ -5891,7 +5987,7 @@ var View = class _View {
|
|
|
5891
5987
|
dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
|
|
5892
5988
|
const inputs = Array.from(form.elements);
|
|
5893
5989
|
inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
|
|
5894
|
-
this.liveSocket.blurActiveElement(
|
|
5990
|
+
this.liveSocket.blurActiveElement();
|
|
5895
5991
|
this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {
|
|
5896
5992
|
this.liveSocket.restorePreviouslyActiveFocus();
|
|
5897
5993
|
});
|
|
@@ -5918,10 +6014,14 @@ var View = class _View {
|
|
|
5918
6014
|
}
|
|
5919
6015
|
};
|
|
5920
6016
|
|
|
5921
|
-
// js/phoenix_live_view/live_socket.
|
|
6017
|
+
// js/phoenix_live_view/live_socket.ts
|
|
5922
6018
|
var isUsedInput = (el) => dom_default.isUsedInput(el);
|
|
5923
6019
|
var LiveSocket = class {
|
|
6020
|
+
/**
|
|
6021
|
+
* Creates a new LiveSocket instance.
|
|
6022
|
+
*/
|
|
5924
6023
|
constructor(url, phxSocket, opts = {}) {
|
|
6024
|
+
/** @internal */
|
|
5925
6025
|
this.unloaded = false;
|
|
5926
6026
|
if (!phxSocket || phxSocket.constructor.name === "Object") {
|
|
5927
6027
|
throw new Error(`
|
|
@@ -5934,7 +6034,6 @@ var LiveSocket = class {
|
|
|
5934
6034
|
}
|
|
5935
6035
|
this.socket = new phxSocket(url, opts);
|
|
5936
6036
|
this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX;
|
|
5937
|
-
this.opts = opts;
|
|
5938
6037
|
this.params = closure(opts.params || {});
|
|
5939
6038
|
this.viewLogger = opts.viewLogger;
|
|
5940
6039
|
this.metadataCallbacks = opts.metadata || {};
|
|
@@ -5975,7 +6074,7 @@ var LiveSocket = class {
|
|
|
5975
6074
|
opts.dom || {}
|
|
5976
6075
|
);
|
|
5977
6076
|
this.transitions = new TransitionSet();
|
|
5978
|
-
this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION)) || 0;
|
|
6077
|
+
this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION) || "0") || 0;
|
|
5979
6078
|
window.addEventListener("pagehide", (_e) => {
|
|
5980
6079
|
this.unloaded = true;
|
|
5981
6080
|
});
|
|
@@ -5986,47 +6085,94 @@ var LiveSocket = class {
|
|
|
5986
6085
|
});
|
|
5987
6086
|
}
|
|
5988
6087
|
// public
|
|
6088
|
+
/**
|
|
6089
|
+
* Returns the version of the LiveView client.
|
|
6090
|
+
*/
|
|
5989
6091
|
version() {
|
|
5990
|
-
return "1.2.0
|
|
6092
|
+
return "1.2.0";
|
|
5991
6093
|
}
|
|
6094
|
+
/**
|
|
6095
|
+
* Returns true if profiling is enabled. See {@link enableProfiling} and {@link disableProfiling}.
|
|
6096
|
+
*/
|
|
5992
6097
|
isProfileEnabled() {
|
|
5993
6098
|
return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
|
|
5994
6099
|
}
|
|
6100
|
+
/**
|
|
6101
|
+
* Returns true if debugging is enabled. See {@link enableDebug} and {@link disableDebug}.
|
|
6102
|
+
*/
|
|
5995
6103
|
isDebugEnabled() {
|
|
5996
6104
|
return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true";
|
|
5997
6105
|
}
|
|
6106
|
+
/**
|
|
6107
|
+
* Returns true if debugging is disabled. See {@link enableDebug} and {@link disableDebug}.
|
|
6108
|
+
*/
|
|
5998
6109
|
isDebugDisabled() {
|
|
5999
6110
|
return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false";
|
|
6000
6111
|
}
|
|
6112
|
+
/**
|
|
6113
|
+
* Enables debugging.
|
|
6114
|
+
*
|
|
6115
|
+
* When debugging is enabled, the LiveView client will log debug information to the console.
|
|
6116
|
+
* See [Debugging client events](https://phoenix-live-view.hexdocs.pm/js-interop.html#debugging-client-events) for more information.
|
|
6117
|
+
*/
|
|
6001
6118
|
enableDebug() {
|
|
6002
6119
|
this.sessionStorage.setItem(PHX_LV_DEBUG, "true");
|
|
6003
6120
|
}
|
|
6121
|
+
/**
|
|
6122
|
+
* Enables profiling.
|
|
6123
|
+
*
|
|
6124
|
+
* When profiling is enabled, the LiveView client will log profiling information to the console.
|
|
6125
|
+
*/
|
|
6004
6126
|
enableProfiling() {
|
|
6005
6127
|
this.sessionStorage.setItem(PHX_LV_PROFILE, "true");
|
|
6006
6128
|
}
|
|
6129
|
+
/**
|
|
6130
|
+
* Disables debugging.
|
|
6131
|
+
*/
|
|
6007
6132
|
disableDebug() {
|
|
6008
6133
|
this.sessionStorage.setItem(PHX_LV_DEBUG, "false");
|
|
6009
6134
|
}
|
|
6135
|
+
/**
|
|
6136
|
+
* Disables profiling.
|
|
6137
|
+
*/
|
|
6010
6138
|
disableProfiling() {
|
|
6011
6139
|
this.sessionStorage.removeItem(PHX_LV_PROFILE);
|
|
6012
6140
|
}
|
|
6141
|
+
/**
|
|
6142
|
+
* Enables latency simulation.
|
|
6143
|
+
*
|
|
6144
|
+
* When latency simulation is enabled, the LiveView client will add a delay to requests and responses from the server.
|
|
6145
|
+
* See [Simulating Latency](https://phoenix-live-view.hexdocs.pm/js-interop.html#simulating-latency) for more information.
|
|
6146
|
+
*/
|
|
6013
6147
|
enableLatencySim(upperBoundMs) {
|
|
6014
6148
|
this.enableDebug();
|
|
6015
6149
|
console.log(
|
|
6016
6150
|
"latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"
|
|
6017
6151
|
);
|
|
6018
|
-
this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs);
|
|
6152
|
+
this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs.toString());
|
|
6019
6153
|
}
|
|
6154
|
+
/**
|
|
6155
|
+
* Disables latency simulation.
|
|
6156
|
+
*/
|
|
6020
6157
|
disableLatencySim() {
|
|
6021
6158
|
this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);
|
|
6022
6159
|
}
|
|
6160
|
+
/**
|
|
6161
|
+
* Returns the current latency simulation upper bound.
|
|
6162
|
+
*/
|
|
6023
6163
|
getLatencySim() {
|
|
6024
6164
|
const str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);
|
|
6025
6165
|
return str ? parseInt(str) : null;
|
|
6026
6166
|
}
|
|
6167
|
+
/**
|
|
6168
|
+
* Returns the Phoenix Socket instance.
|
|
6169
|
+
*/
|
|
6027
6170
|
getSocket() {
|
|
6028
6171
|
return this.socket;
|
|
6029
6172
|
}
|
|
6173
|
+
/**
|
|
6174
|
+
* Connects to the LiveView server.
|
|
6175
|
+
*/
|
|
6030
6176
|
connect() {
|
|
6031
6177
|
if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {
|
|
6032
6178
|
this.enableDebug();
|
|
@@ -6049,23 +6195,29 @@ var LiveSocket = class {
|
|
|
6049
6195
|
document.addEventListener("DOMContentLoaded", () => doConnect());
|
|
6050
6196
|
}
|
|
6051
6197
|
}
|
|
6198
|
+
/**
|
|
6199
|
+
* Disconnects from the LiveView server.
|
|
6200
|
+
*/
|
|
6052
6201
|
disconnect(callback) {
|
|
6053
|
-
clearTimeout(this.reloadWithJitterTimer);
|
|
6202
|
+
this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);
|
|
6054
6203
|
if (this.serverCloseRef) {
|
|
6055
|
-
this.socket.off(this.serverCloseRef);
|
|
6204
|
+
this.socket.off([this.serverCloseRef]);
|
|
6056
6205
|
this.serverCloseRef = null;
|
|
6057
6206
|
}
|
|
6058
6207
|
this.socket.disconnect(callback);
|
|
6059
6208
|
}
|
|
6209
|
+
/**
|
|
6210
|
+
* Can be used to replace the transport used by the underlying Phoenix Socket.
|
|
6211
|
+
*/
|
|
6060
6212
|
replaceTransport(transport) {
|
|
6061
|
-
clearTimeout(this.reloadWithJitterTimer);
|
|
6213
|
+
this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);
|
|
6062
6214
|
this.socket.replaceTransport(transport);
|
|
6063
6215
|
this.connect();
|
|
6064
6216
|
}
|
|
6065
6217
|
/**
|
|
6066
|
-
*
|
|
6067
|
-
*
|
|
6068
|
-
*
|
|
6218
|
+
* Executes an encoded JS command, targeting the given element.
|
|
6219
|
+
*
|
|
6220
|
+
* See [`Phoenix.LiveView.JS`](https://phoenix-live-view.hexdocs.pm/Phoenix.LiveView.JS.html) for more information.
|
|
6069
6221
|
*/
|
|
6070
6222
|
execJS(el, encodedJS, eventType = null) {
|
|
6071
6223
|
const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
|
|
@@ -6075,12 +6227,13 @@ var LiveSocket = class {
|
|
|
6075
6227
|
* Returns an object with methods to manipulate the DOM and execute JavaScript.
|
|
6076
6228
|
* The applied changes integrate with server DOM patching.
|
|
6077
6229
|
*
|
|
6078
|
-
*
|
|
6230
|
+
* See [JavaScript interoperability](https://phoenix-live-view.hexdocs.pm/js-interop.html) for more information.
|
|
6079
6231
|
*/
|
|
6080
6232
|
js() {
|
|
6081
6233
|
return js_commands_default(this, "js");
|
|
6082
6234
|
}
|
|
6083
6235
|
// private
|
|
6236
|
+
/** @internal */
|
|
6084
6237
|
unload() {
|
|
6085
6238
|
if (this.unloaded) {
|
|
6086
6239
|
return;
|
|
@@ -6092,9 +6245,11 @@ var LiveSocket = class {
|
|
|
6092
6245
|
this.destroyAllViews();
|
|
6093
6246
|
this.disconnect();
|
|
6094
6247
|
}
|
|
6248
|
+
/** @internal */
|
|
6095
6249
|
triggerDOM(kind, args) {
|
|
6096
6250
|
this.domCallbacks[kind](...args);
|
|
6097
6251
|
}
|
|
6252
|
+
/** @internal */
|
|
6098
6253
|
time(name, func) {
|
|
6099
6254
|
if (!this.isProfileEnabled() || !console.time) {
|
|
6100
6255
|
return func();
|
|
@@ -6104,6 +6259,7 @@ var LiveSocket = class {
|
|
|
6104
6259
|
console.timeEnd(name);
|
|
6105
6260
|
return result;
|
|
6106
6261
|
}
|
|
6262
|
+
/** @internal */
|
|
6107
6263
|
log(view, kind, msgCallback) {
|
|
6108
6264
|
if (this.viewLogger) {
|
|
6109
6265
|
const [msg, obj] = msgCallback();
|
|
@@ -6113,16 +6269,20 @@ var LiveSocket = class {
|
|
|
6113
6269
|
debug(view, kind, msg, obj);
|
|
6114
6270
|
}
|
|
6115
6271
|
}
|
|
6272
|
+
/** @internal */
|
|
6116
6273
|
requestDOMUpdate(callback) {
|
|
6117
6274
|
this.transitions.after(callback);
|
|
6118
6275
|
}
|
|
6276
|
+
/** @internal */
|
|
6119
6277
|
asyncTransition(promise) {
|
|
6120
6278
|
this.transitions.addAsyncTransition(promise);
|
|
6121
6279
|
}
|
|
6280
|
+
/** @internal */
|
|
6122
6281
|
transition(time, onStart, onDone = function() {
|
|
6123
6282
|
}) {
|
|
6124
6283
|
this.transitions.addTransition(time, onStart, onDone);
|
|
6125
6284
|
}
|
|
6285
|
+
/** @internal */
|
|
6126
6286
|
onChannel(channel, event, cb) {
|
|
6127
6287
|
channel.on(event, (data) => {
|
|
6128
6288
|
const latency = this.getLatencySim();
|
|
@@ -6133,8 +6293,9 @@ var LiveSocket = class {
|
|
|
6133
6293
|
}
|
|
6134
6294
|
});
|
|
6135
6295
|
}
|
|
6296
|
+
/** @internal */
|
|
6136
6297
|
reloadWithJitter(view, log) {
|
|
6137
|
-
clearTimeout(this.reloadWithJitterTimer);
|
|
6298
|
+
this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);
|
|
6138
6299
|
this.disconnect();
|
|
6139
6300
|
const minMs = this.reloadJitterMin;
|
|
6140
6301
|
const maxMs = this.reloadJitterMax;
|
|
@@ -6162,22 +6323,25 @@ var LiveSocket = class {
|
|
|
6162
6323
|
`exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`
|
|
6163
6324
|
]);
|
|
6164
6325
|
}
|
|
6165
|
-
if (this.
|
|
6166
|
-
window.location = this.pendingLink;
|
|
6326
|
+
if (this.pendingLink !== null) {
|
|
6327
|
+
window.location.href = this.pendingLink;
|
|
6167
6328
|
} else {
|
|
6168
6329
|
window.location.reload();
|
|
6169
6330
|
}
|
|
6170
6331
|
}, afterMs);
|
|
6171
6332
|
}
|
|
6333
|
+
/** @internal */
|
|
6172
6334
|
getHookDefinition(name) {
|
|
6173
6335
|
if (!name) {
|
|
6174
6336
|
return;
|
|
6175
6337
|
}
|
|
6176
6338
|
return this.maybeInternalHook(name) || this.hooks[name] || this.maybeRuntimeHook(name);
|
|
6177
6339
|
}
|
|
6340
|
+
/** @internal */
|
|
6178
6341
|
maybeInternalHook(name) {
|
|
6179
6342
|
return name && name.startsWith("Phoenix.") && hooks_default[name.split(".")[1]];
|
|
6180
6343
|
}
|
|
6344
|
+
/** @internal */
|
|
6181
6345
|
maybeRuntimeHook(name) {
|
|
6182
6346
|
const runtimeHook = document.querySelector(
|
|
6183
6347
|
`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`
|
|
@@ -6199,21 +6363,27 @@ var LiveSocket = class {
|
|
|
6199
6363
|
runtimeHook
|
|
6200
6364
|
);
|
|
6201
6365
|
}
|
|
6366
|
+
/** @internal */
|
|
6202
6367
|
isUnloaded() {
|
|
6203
6368
|
return this.unloaded;
|
|
6204
6369
|
}
|
|
6370
|
+
/** @internal */
|
|
6205
6371
|
isConnected() {
|
|
6206
6372
|
return this.socket.isConnected();
|
|
6207
6373
|
}
|
|
6374
|
+
/** @internal */
|
|
6208
6375
|
getBindingPrefix() {
|
|
6209
6376
|
return this.bindingPrefix;
|
|
6210
6377
|
}
|
|
6378
|
+
/** @internal */
|
|
6211
6379
|
binding(kind) {
|
|
6212
6380
|
return `${this.getBindingPrefix()}${kind}`;
|
|
6213
6381
|
}
|
|
6382
|
+
/** @internal */
|
|
6214
6383
|
channel(topic, params) {
|
|
6215
6384
|
return this.socket.channel(topic, params);
|
|
6216
6385
|
}
|
|
6386
|
+
/** @internal */
|
|
6217
6387
|
joinDeadView() {
|
|
6218
6388
|
const body = document.body;
|
|
6219
6389
|
if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
|
|
@@ -6229,6 +6399,7 @@ var LiveSocket = class {
|
|
|
6229
6399
|
});
|
|
6230
6400
|
}
|
|
6231
6401
|
}
|
|
6402
|
+
/** @internal */
|
|
6232
6403
|
joinRootViews() {
|
|
6233
6404
|
let rootsFound = false;
|
|
6234
6405
|
dom_default.all(
|
|
@@ -6250,6 +6421,7 @@ var LiveSocket = class {
|
|
|
6250
6421
|
);
|
|
6251
6422
|
return rootsFound;
|
|
6252
6423
|
}
|
|
6424
|
+
/** @internal */
|
|
6253
6425
|
redirect(to, flash, reloadToken) {
|
|
6254
6426
|
if (reloadToken) {
|
|
6255
6427
|
browser_default.setCookie(PHX_RELOAD_STATUS, reloadToken, 60);
|
|
@@ -6257,7 +6429,11 @@ var LiveSocket = class {
|
|
|
6257
6429
|
this.unload();
|
|
6258
6430
|
browser_default.redirect(to, flash);
|
|
6259
6431
|
}
|
|
6432
|
+
/** @internal */
|
|
6260
6433
|
replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {
|
|
6434
|
+
if (!this.main) {
|
|
6435
|
+
return;
|
|
6436
|
+
}
|
|
6261
6437
|
const liveReferer = this.currentLocation.href;
|
|
6262
6438
|
this.outgoingMainEl = this.outgoingMainEl || this.main.el;
|
|
6263
6439
|
const stickies = dom_default.findPhxSticky(document) || [];
|
|
@@ -6284,6 +6460,7 @@ var LiveSocket = class {
|
|
|
6284
6460
|
}
|
|
6285
6461
|
});
|
|
6286
6462
|
}
|
|
6463
|
+
/** @internal */
|
|
6287
6464
|
transitionRemoves(elements, callback) {
|
|
6288
6465
|
const removeAttr = this.binding("remove");
|
|
6289
6466
|
const silenceEvents = (e) => {
|
|
@@ -6305,14 +6482,17 @@ var LiveSocket = class {
|
|
|
6305
6482
|
callback && callback();
|
|
6306
6483
|
});
|
|
6307
6484
|
}
|
|
6485
|
+
/** @internal */
|
|
6308
6486
|
isPhxView(el) {
|
|
6309
6487
|
return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;
|
|
6310
6488
|
}
|
|
6489
|
+
/** @internal */
|
|
6311
6490
|
newRootView(el, flash, liveReferer) {
|
|
6312
6491
|
const view = new View(el, this, null, flash, liveReferer);
|
|
6313
6492
|
this.roots[view.id] = view;
|
|
6314
6493
|
return view;
|
|
6315
6494
|
}
|
|
6495
|
+
/** @internal */
|
|
6316
6496
|
owner(childEl, callback) {
|
|
6317
6497
|
let view;
|
|
6318
6498
|
const viewEl = dom_default.closestViewEl(childEl);
|
|
@@ -6326,9 +6506,11 @@ var LiveSocket = class {
|
|
|
6326
6506
|
}
|
|
6327
6507
|
return view && callback ? callback(view) : view;
|
|
6328
6508
|
}
|
|
6509
|
+
/** @internal */
|
|
6329
6510
|
withinOwners(childEl, callback) {
|
|
6330
6511
|
this.owner(childEl, (view) => callback(view, childEl));
|
|
6331
6512
|
}
|
|
6513
|
+
/** @internal */
|
|
6332
6514
|
getViewByEl(el) {
|
|
6333
6515
|
const rootId = el.getAttribute(PHX_ROOT_ID);
|
|
6334
6516
|
return maybe(
|
|
@@ -6336,9 +6518,11 @@ var LiveSocket = class {
|
|
|
6336
6518
|
(root) => root.getDescendentByEl(el)
|
|
6337
6519
|
);
|
|
6338
6520
|
}
|
|
6521
|
+
/** @internal */
|
|
6339
6522
|
getRootById(id) {
|
|
6340
6523
|
return this.roots[id];
|
|
6341
6524
|
}
|
|
6525
|
+
/** @internal */
|
|
6342
6526
|
destroyAllViews() {
|
|
6343
6527
|
for (const id in this.roots) {
|
|
6344
6528
|
this.roots[id].destroy();
|
|
@@ -6346,6 +6530,7 @@ var LiveSocket = class {
|
|
|
6346
6530
|
}
|
|
6347
6531
|
this.main = null;
|
|
6348
6532
|
}
|
|
6533
|
+
/** @internal */
|
|
6349
6534
|
destroyViewByEl(el) {
|
|
6350
6535
|
const root = this.getRootById(el.getAttribute(PHX_ROOT_ID));
|
|
6351
6536
|
if (root && root.id === el.id) {
|
|
@@ -6355,28 +6540,30 @@ var LiveSocket = class {
|
|
|
6355
6540
|
root.destroyDescendent(el.id);
|
|
6356
6541
|
}
|
|
6357
6542
|
}
|
|
6543
|
+
/** @internal */
|
|
6358
6544
|
getActiveElement() {
|
|
6359
6545
|
return document.activeElement;
|
|
6360
6546
|
}
|
|
6547
|
+
/** @internal */
|
|
6361
6548
|
dropActiveElement(view) {
|
|
6362
6549
|
if (this.prevActive && view.ownsElement(this.prevActive)) {
|
|
6363
6550
|
this.prevActive = null;
|
|
6364
6551
|
}
|
|
6365
6552
|
}
|
|
6553
|
+
/** @internal */
|
|
6366
6554
|
restorePreviouslyActiveFocus() {
|
|
6367
6555
|
if (this.prevActive && this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
|
|
6368
6556
|
this.prevActive.focus();
|
|
6369
6557
|
}
|
|
6370
6558
|
}
|
|
6559
|
+
/** @internal */
|
|
6371
6560
|
blurActiveElement() {
|
|
6372
6561
|
this.prevActive = this.getActiveElement();
|
|
6373
6562
|
if (this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
|
|
6374
6563
|
this.prevActive.blur();
|
|
6375
6564
|
}
|
|
6376
6565
|
}
|
|
6377
|
-
/**
|
|
6378
|
-
* @param {{dead?: boolean}} [options={}]
|
|
6379
|
-
*/
|
|
6566
|
+
/** @internal */
|
|
6380
6567
|
bindTopLevelEvents({ dead } = {}) {
|
|
6381
6568
|
if (this.boundTopLevelEvents) {
|
|
6382
6569
|
return;
|
|
@@ -6423,7 +6610,7 @@ var LiveSocket = class {
|
|
|
6423
6610
|
{ blur: "focusout", focus: "focusin" },
|
|
6424
6611
|
(e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
6425
6612
|
if (!phxTarget) {
|
|
6426
|
-
const data = {
|
|
6613
|
+
const data = { ...this.eventMeta(type, e, targetEl) };
|
|
6427
6614
|
js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
|
|
6428
6615
|
}
|
|
6429
6616
|
}
|
|
@@ -6439,10 +6626,11 @@ var LiveSocket = class {
|
|
|
6439
6626
|
);
|
|
6440
6627
|
this.on("dragover", (e) => e.preventDefault());
|
|
6441
6628
|
this.on("dragenter", (e) => {
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6629
|
+
let target = e.target && dom_default.elementFromTarget(e.target);
|
|
6630
|
+
if (!target) {
|
|
6631
|
+
return;
|
|
6632
|
+
}
|
|
6633
|
+
const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));
|
|
6446
6634
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
6447
6635
|
return;
|
|
6448
6636
|
}
|
|
@@ -6451,10 +6639,11 @@ var LiveSocket = class {
|
|
|
6451
6639
|
}
|
|
6452
6640
|
});
|
|
6453
6641
|
this.on("dragleave", (e) => {
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6642
|
+
let target = e.target && dom_default.elementFromTarget(e.target);
|
|
6643
|
+
if (!target) {
|
|
6644
|
+
return;
|
|
6645
|
+
}
|
|
6646
|
+
const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));
|
|
6458
6647
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
6459
6648
|
return;
|
|
6460
6649
|
}
|
|
@@ -6464,15 +6653,19 @@ var LiveSocket = class {
|
|
|
6464
6653
|
}
|
|
6465
6654
|
});
|
|
6466
6655
|
this.on("drop", (e) => {
|
|
6656
|
+
let target = e.target && dom_default.elementFromTarget(e.target);
|
|
6657
|
+
if (!target) {
|
|
6658
|
+
return;
|
|
6659
|
+
}
|
|
6467
6660
|
e.preventDefault();
|
|
6468
|
-
const dropzone = closestPhxBinding(
|
|
6469
|
-
e.target,
|
|
6470
|
-
this.binding(PHX_DROP_TARGET)
|
|
6471
|
-
);
|
|
6661
|
+
const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));
|
|
6472
6662
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
6473
6663
|
return;
|
|
6474
6664
|
}
|
|
6475
6665
|
this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);
|
|
6666
|
+
if (!e.dataTransfer) {
|
|
6667
|
+
return;
|
|
6668
|
+
}
|
|
6476
6669
|
const dropTargetId = dropzone.getAttribute(this.binding(PHX_DROP_TARGET));
|
|
6477
6670
|
const dropTarget = dropTargetId && document.getElementById(dropTargetId);
|
|
6478
6671
|
const files = Array.from(e.dataTransfer.files || []);
|
|
@@ -6483,7 +6676,7 @@ var LiveSocket = class {
|
|
|
6483
6676
|
dropTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
6484
6677
|
});
|
|
6485
6678
|
this.on(PHX_TRACK_UPLOADS, (e) => {
|
|
6486
|
-
const uploadTarget = e.target;
|
|
6679
|
+
const uploadTarget = e.target && dom_default.elementFromTarget(e.target);
|
|
6487
6680
|
if (!dom_default.isUploadInput(uploadTarget)) {
|
|
6488
6681
|
return;
|
|
6489
6682
|
}
|
|
@@ -6494,47 +6687,67 @@ var LiveSocket = class {
|
|
|
6494
6687
|
uploadTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
6495
6688
|
});
|
|
6496
6689
|
}
|
|
6690
|
+
/** @internal */
|
|
6497
6691
|
eventMeta(eventName, e, targetEl) {
|
|
6498
6692
|
const callback = this.metadataCallbacks[eventName];
|
|
6499
6693
|
return callback ? callback(e, targetEl) : {};
|
|
6500
6694
|
}
|
|
6695
|
+
/** @internal */
|
|
6501
6696
|
setPendingLink(href) {
|
|
6502
6697
|
this.linkRef++;
|
|
6503
6698
|
this.pendingLink = href;
|
|
6504
6699
|
this.resetReloadStatus();
|
|
6505
6700
|
return this.linkRef;
|
|
6506
6701
|
}
|
|
6507
|
-
|
|
6508
|
-
|
|
6702
|
+
/**
|
|
6703
|
+
* @internal
|
|
6704
|
+
* anytime we are navigating or connecting, drop reload cookie in case
|
|
6705
|
+
* we issue the cookie but the next request was interrupted and the server never dropped it
|
|
6706
|
+
*/
|
|
6509
6707
|
resetReloadStatus() {
|
|
6510
6708
|
browser_default.deleteCookie(PHX_RELOAD_STATUS);
|
|
6511
6709
|
}
|
|
6710
|
+
/** @internal */
|
|
6512
6711
|
commitPendingLink(linkRef) {
|
|
6513
6712
|
if (this.linkRef !== linkRef) {
|
|
6514
6713
|
return false;
|
|
6515
|
-
}
|
|
6714
|
+
}
|
|
6715
|
+
if (this.pendingLink !== null) {
|
|
6516
6716
|
this.href = this.pendingLink;
|
|
6517
6717
|
this.pendingLink = null;
|
|
6518
|
-
return true;
|
|
6519
6718
|
}
|
|
6719
|
+
return true;
|
|
6520
6720
|
}
|
|
6721
|
+
/** @internal */
|
|
6521
6722
|
getHref() {
|
|
6522
6723
|
return this.href;
|
|
6523
6724
|
}
|
|
6725
|
+
/** @internal */
|
|
6524
6726
|
hasPendingLink() {
|
|
6525
6727
|
return !!this.pendingLink;
|
|
6526
6728
|
}
|
|
6729
|
+
/** @internal */
|
|
6527
6730
|
bind(events, callback) {
|
|
6528
6731
|
for (const event in events) {
|
|
6529
6732
|
const browserEventName = events[event];
|
|
6530
6733
|
this.on(browserEventName, (e) => {
|
|
6531
6734
|
const binding = this.binding(event);
|
|
6532
6735
|
const windowBinding = this.binding(`window-${event}`);
|
|
6533
|
-
const targetPhxEvent = e.target
|
|
6736
|
+
const targetPhxEvent = e.target instanceof Element && e.target.getAttribute(binding);
|
|
6737
|
+
if (!(e.target instanceof Element)) {
|
|
6738
|
+
return;
|
|
6739
|
+
}
|
|
6534
6740
|
if (targetPhxEvent) {
|
|
6535
6741
|
this.debounce(e.target, e, browserEventName, () => {
|
|
6536
6742
|
this.withinOwners(e.target, (view) => {
|
|
6537
|
-
callback(
|
|
6743
|
+
callback(
|
|
6744
|
+
e,
|
|
6745
|
+
event,
|
|
6746
|
+
view,
|
|
6747
|
+
e.target,
|
|
6748
|
+
targetPhxEvent,
|
|
6749
|
+
null
|
|
6750
|
+
);
|
|
6538
6751
|
});
|
|
6539
6752
|
});
|
|
6540
6753
|
} else {
|
|
@@ -6542,7 +6755,14 @@ var LiveSocket = class {
|
|
|
6542
6755
|
const phxEvent = el.getAttribute(windowBinding);
|
|
6543
6756
|
this.debounce(el, e, browserEventName, () => {
|
|
6544
6757
|
this.withinOwners(el, (view) => {
|
|
6545
|
-
callback(
|
|
6758
|
+
callback(
|
|
6759
|
+
e,
|
|
6760
|
+
event,
|
|
6761
|
+
view,
|
|
6762
|
+
el,
|
|
6763
|
+
phxEvent,
|
|
6764
|
+
"window"
|
|
6765
|
+
);
|
|
6546
6766
|
});
|
|
6547
6767
|
});
|
|
6548
6768
|
});
|
|
@@ -6550,23 +6770,31 @@ var LiveSocket = class {
|
|
|
6550
6770
|
});
|
|
6551
6771
|
}
|
|
6552
6772
|
}
|
|
6773
|
+
/** @internal */
|
|
6553
6774
|
bindClicks() {
|
|
6554
6775
|
this.on("mousedown", (e) => this.clickStartedAtTarget = e.target);
|
|
6555
|
-
this.bindClick(
|
|
6776
|
+
this.bindClick();
|
|
6556
6777
|
}
|
|
6557
|
-
|
|
6558
|
-
|
|
6778
|
+
/** @internal */
|
|
6779
|
+
bindClick() {
|
|
6780
|
+
const click = this.binding("click");
|
|
6559
6781
|
window.addEventListener(
|
|
6560
|
-
|
|
6782
|
+
"click",
|
|
6561
6783
|
(e) => {
|
|
6562
|
-
let target =
|
|
6784
|
+
let target = e.target && dom_default.elementFromTarget(e.target);
|
|
6785
|
+
if (!target) {
|
|
6786
|
+
return;
|
|
6787
|
+
}
|
|
6563
6788
|
if (e.detail === 0)
|
|
6564
|
-
this.clickStartedAtTarget =
|
|
6565
|
-
const clickStartedAtTarget = this.clickStartedAtTarget ||
|
|
6566
|
-
target = closestPhxBinding(
|
|
6789
|
+
this.clickStartedAtTarget = target;
|
|
6790
|
+
const clickStartedAtTarget = this.clickStartedAtTarget || target;
|
|
6791
|
+
target = closestPhxBinding(target, click);
|
|
6567
6792
|
this.dispatchClickAway(e, clickStartedAtTarget);
|
|
6568
6793
|
this.clickStartedAtTarget = null;
|
|
6569
|
-
|
|
6794
|
+
if (!target) {
|
|
6795
|
+
return;
|
|
6796
|
+
}
|
|
6797
|
+
const phxEvent = target.getAttribute(click);
|
|
6570
6798
|
if (!phxEvent) {
|
|
6571
6799
|
if (dom_default.isNewPageClick(e, window.location)) {
|
|
6572
6800
|
this.unload();
|
|
@@ -6591,6 +6819,7 @@ var LiveSocket = class {
|
|
|
6591
6819
|
false
|
|
6592
6820
|
);
|
|
6593
6821
|
}
|
|
6822
|
+
/** @internal */
|
|
6594
6823
|
dispatchClickAway(e, clickStartedAt) {
|
|
6595
6824
|
const phxClickAway = this.binding("click-away");
|
|
6596
6825
|
const portal = clickStartedAt.closest(`[${PHX_TELEPORTED_SRC}]`);
|
|
@@ -6621,6 +6850,7 @@ var LiveSocket = class {
|
|
|
6621
6850
|
}
|
|
6622
6851
|
});
|
|
6623
6852
|
}
|
|
6853
|
+
/** @internal */
|
|
6624
6854
|
bindNav() {
|
|
6625
6855
|
if (!browser_default.canPushState()) {
|
|
6626
6856
|
return;
|
|
@@ -6630,7 +6860,7 @@ var LiveSocket = class {
|
|
|
6630
6860
|
}
|
|
6631
6861
|
let scrollTimer = null;
|
|
6632
6862
|
window.addEventListener("scroll", (_e) => {
|
|
6633
|
-
clearTimeout(scrollTimer);
|
|
6863
|
+
scrollTimer != null && clearTimeout(scrollTimer);
|
|
6634
6864
|
scrollTimer = setTimeout(() => {
|
|
6635
6865
|
browser_default.updateCurrentState(
|
|
6636
6866
|
(state) => Object.assign(state, { scroll: window.scrollY })
|
|
@@ -6664,7 +6894,7 @@ var LiveSocket = class {
|
|
|
6664
6894
|
const callback = () => {
|
|
6665
6895
|
this.maybeScroll(scroll);
|
|
6666
6896
|
};
|
|
6667
|
-
if (this.main.isConnected() && navType === "patch" && id === this.main.id) {
|
|
6897
|
+
if (this.main && this.main.isConnected() && navType === "patch" && id === this.main.id) {
|
|
6668
6898
|
this.main.pushLinkPatch(event, href, null, callback);
|
|
6669
6899
|
} else {
|
|
6670
6900
|
this.replaceMain(href, null, callback);
|
|
@@ -6676,13 +6906,25 @@ var LiveSocket = class {
|
|
|
6676
6906
|
window.addEventListener(
|
|
6677
6907
|
"click",
|
|
6678
6908
|
(e) => {
|
|
6679
|
-
|
|
6909
|
+
let el = e.target && dom_default.elementFromTarget(e.target);
|
|
6910
|
+
if (!el) {
|
|
6911
|
+
return;
|
|
6912
|
+
}
|
|
6913
|
+
const target = closestPhxBinding(
|
|
6914
|
+
el,
|
|
6915
|
+
PHX_LIVE_LINK
|
|
6916
|
+
);
|
|
6680
6917
|
const type = target && target.getAttribute(PHX_LIVE_LINK);
|
|
6681
6918
|
if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {
|
|
6682
6919
|
return;
|
|
6683
6920
|
}
|
|
6684
6921
|
const href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;
|
|
6685
6922
|
const linkState = target.getAttribute(PHX_LINK_STATE);
|
|
6923
|
+
if (linkState !== "replace" && linkState !== "push") {
|
|
6924
|
+
throw new Error(
|
|
6925
|
+
`expected ${PHX_LINK_STATE} to be "replace" or "push", got: ${linkState}`
|
|
6926
|
+
);
|
|
6927
|
+
}
|
|
6686
6928
|
e.preventDefault();
|
|
6687
6929
|
e.stopImmediatePropagation();
|
|
6688
6930
|
if (this.pendingLink === href) {
|
|
@@ -6707,6 +6949,7 @@ var LiveSocket = class {
|
|
|
6707
6949
|
false
|
|
6708
6950
|
);
|
|
6709
6951
|
}
|
|
6952
|
+
/** @internal */
|
|
6710
6953
|
maybeScroll(scroll) {
|
|
6711
6954
|
if (typeof scroll === "number") {
|
|
6712
6955
|
requestAnimationFrame(() => {
|
|
@@ -6714,19 +6957,23 @@ var LiveSocket = class {
|
|
|
6714
6957
|
});
|
|
6715
6958
|
}
|
|
6716
6959
|
}
|
|
6960
|
+
/** @internal */
|
|
6717
6961
|
dispatchEvent(event, payload = {}) {
|
|
6718
6962
|
dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload });
|
|
6719
6963
|
}
|
|
6964
|
+
/** @internal */
|
|
6720
6965
|
dispatchEvents(events) {
|
|
6721
6966
|
events.forEach(([event, payload]) => this.dispatchEvent(event, payload));
|
|
6722
6967
|
}
|
|
6968
|
+
/** @internal */
|
|
6723
6969
|
withPageLoading(info, callback) {
|
|
6724
6970
|
dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info });
|
|
6725
6971
|
const done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });
|
|
6726
6972
|
return callback ? callback(done) : done;
|
|
6727
6973
|
}
|
|
6974
|
+
/** @internal */
|
|
6728
6975
|
pushHistoryPatch(e, href, linkState, targetEl) {
|
|
6729
|
-
if (!this.isConnected() || !this.main.isMain()) {
|
|
6976
|
+
if (!this.isConnected() || !(this.main && this.main.isMain())) {
|
|
6730
6977
|
return browser_default.redirect(href);
|
|
6731
6978
|
}
|
|
6732
6979
|
this.withPageLoading({ to: href, kind: "patch" }, (done) => {
|
|
@@ -6736,6 +6983,7 @@ var LiveSocket = class {
|
|
|
6736
6983
|
});
|
|
6737
6984
|
});
|
|
6738
6985
|
}
|
|
6986
|
+
/** @internal */
|
|
6739
6987
|
historyPatch(href, linkState, linkRef = this.setPendingLink(href)) {
|
|
6740
6988
|
if (!this.commitPendingLink(linkRef)) {
|
|
6741
6989
|
return;
|
|
@@ -6760,12 +7008,13 @@ var LiveSocket = class {
|
|
|
6760
7008
|
});
|
|
6761
7009
|
this.registerNewLocation(window.location);
|
|
6762
7010
|
}
|
|
7011
|
+
/** @internal */
|
|
6763
7012
|
historyRedirect(e, href, linkState, flash, targetEl) {
|
|
6764
7013
|
const clickLoading = targetEl && e.isTrusted && e.type !== "popstate";
|
|
6765
7014
|
if (clickLoading) {
|
|
6766
7015
|
targetEl.classList.add("phx-click-loading");
|
|
6767
7016
|
}
|
|
6768
|
-
if (!this.isConnected() || !this.main.isMain()) {
|
|
7017
|
+
if (!this.isConnected() || !(this.main && this.main.isMain())) {
|
|
6769
7018
|
return browser_default.redirect(href, flash);
|
|
6770
7019
|
}
|
|
6771
7020
|
if (/^\/$|^\/[^\/]+.*$/.test(href)) {
|
|
@@ -6807,6 +7056,7 @@ var LiveSocket = class {
|
|
|
6807
7056
|
});
|
|
6808
7057
|
});
|
|
6809
7058
|
}
|
|
7059
|
+
/** @internal */
|
|
6810
7060
|
registerNewLocation(newLocation) {
|
|
6811
7061
|
const { pathname, search } = this.currentLocation;
|
|
6812
7062
|
if (pathname + search === newLocation.pathname + newLocation.search) {
|
|
@@ -6816,10 +7066,13 @@ var LiveSocket = class {
|
|
|
6816
7066
|
return true;
|
|
6817
7067
|
}
|
|
6818
7068
|
}
|
|
7069
|
+
/** @internal */
|
|
6819
7070
|
bindForms() {
|
|
6820
7071
|
let iterations = 0;
|
|
6821
7072
|
let externalFormSubmitted = false;
|
|
6822
7073
|
this.on("submit", (e) => {
|
|
7074
|
+
if (!(e.target instanceof HTMLFormElement))
|
|
7075
|
+
return;
|
|
6823
7076
|
const phxSubmit = e.target.getAttribute(this.binding("submit"));
|
|
6824
7077
|
const phxChange = e.target.getAttribute(this.binding("change"));
|
|
6825
7078
|
if (!externalFormSubmitted && phxChange && !phxSubmit) {
|
|
@@ -6837,6 +7090,8 @@ var LiveSocket = class {
|
|
|
6837
7090
|
}
|
|
6838
7091
|
});
|
|
6839
7092
|
this.on("submit", (e) => {
|
|
7093
|
+
if (!(e.target instanceof HTMLFormElement))
|
|
7094
|
+
return;
|
|
6840
7095
|
const phxEvent = e.target.getAttribute(this.binding("submit"));
|
|
6841
7096
|
if (!phxEvent) {
|
|
6842
7097
|
if (dom_default.isUnloadableFormSubmit(e)) {
|
|
@@ -6855,7 +7110,10 @@ var LiveSocket = class {
|
|
|
6855
7110
|
});
|
|
6856
7111
|
for (const type of ["change", "input"]) {
|
|
6857
7112
|
this.on(type, (e) => {
|
|
6858
|
-
if (
|
|
7113
|
+
if (!dom_default.isFormAssociated(e.target)) {
|
|
7114
|
+
return;
|
|
7115
|
+
}
|
|
7116
|
+
if (e instanceof CustomEvent && e.target.form === void 0) {
|
|
6859
7117
|
if (e.detail && e.detail.dispatcher) {
|
|
6860
7118
|
throw new Error(
|
|
6861
7119
|
`dispatching a custom ${type} event is only supported on input elements inside a form`
|
|
@@ -6863,9 +7121,9 @@ var LiveSocket = class {
|
|
|
6863
7121
|
}
|
|
6864
7122
|
return;
|
|
6865
7123
|
}
|
|
6866
|
-
const phxChange = this.binding("change");
|
|
6867
7124
|
const input = e.target;
|
|
6868
|
-
|
|
7125
|
+
const phxChange = this.binding("change");
|
|
7126
|
+
if (this.blockPhxChangeWhileComposing && e instanceof InputEvent && e.isComposing) {
|
|
6869
7127
|
const key = `composition-listener-${type}`;
|
|
6870
7128
|
if (!dom_default.private(input, key)) {
|
|
6871
7129
|
dom_default.putPrivate(input, key, true);
|
|
@@ -6905,7 +7163,7 @@ var LiveSocket = class {
|
|
|
6905
7163
|
dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);
|
|
6906
7164
|
js_default.exec(e, "change", phxEvent, view, input, [
|
|
6907
7165
|
"push",
|
|
6908
|
-
{ _target:
|
|
7166
|
+
{ _target: input.name, dispatcher }
|
|
6909
7167
|
]);
|
|
6910
7168
|
});
|
|
6911
7169
|
});
|
|
@@ -6914,7 +7172,9 @@ var LiveSocket = class {
|
|
|
6914
7172
|
this.on("reset", (e) => {
|
|
6915
7173
|
const form = e.target;
|
|
6916
7174
|
dom_default.resetForm(form);
|
|
6917
|
-
const input = Array.from(form.elements).find(
|
|
7175
|
+
const input = Array.from(form.elements).find(
|
|
7176
|
+
(el) => "type" in el && el.type === "reset"
|
|
7177
|
+
);
|
|
6918
7178
|
if (input) {
|
|
6919
7179
|
window.requestAnimationFrame(() => {
|
|
6920
7180
|
input.dispatchEvent(
|
|
@@ -6924,6 +7184,7 @@ var LiveSocket = class {
|
|
|
6924
7184
|
}
|
|
6925
7185
|
});
|
|
6926
7186
|
}
|
|
7187
|
+
/** @internal */
|
|
6927
7188
|
debounce(el, event, eventType, callback) {
|
|
6928
7189
|
if (eventType === "blur" || eventType === "focusout") {
|
|
6929
7190
|
return callback();
|
|
@@ -6948,11 +7209,13 @@ var LiveSocket = class {
|
|
|
6948
7209
|
);
|
|
6949
7210
|
});
|
|
6950
7211
|
}
|
|
7212
|
+
/** @internal */
|
|
6951
7213
|
silenceEvents(callback) {
|
|
6952
7214
|
this.silenced = true;
|
|
6953
7215
|
callback();
|
|
6954
7216
|
this.silenced = false;
|
|
6955
7217
|
}
|
|
7218
|
+
/** @internal */
|
|
6956
7219
|
on(event, callback) {
|
|
6957
7220
|
this.boundEventNames.add(event);
|
|
6958
7221
|
window.addEventListener(event, (e) => {
|
|
@@ -6961,6 +7224,7 @@ var LiveSocket = class {
|
|
|
6961
7224
|
}
|
|
6962
7225
|
});
|
|
6963
7226
|
}
|
|
7227
|
+
/** @internal */
|
|
6964
7228
|
jsQuerySelectorAll(sourceEl, query, defaultQuery) {
|
|
6965
7229
|
const all = this.domCallbacks.jsQuerySelectorAll;
|
|
6966
7230
|
return all ? all(sourceEl, query, defaultQuery) : defaultQuery();
|
|
@@ -7022,7 +7286,6 @@ var TransitionSet = class {
|
|
|
7022
7286
|
};
|
|
7023
7287
|
|
|
7024
7288
|
// js/phoenix_live_view/index.ts
|
|
7025
|
-
var LiveSocket2 = LiveSocket;
|
|
7026
7289
|
function createHook(el, callbacks) {
|
|
7027
7290
|
let existingHook = dom_default.getCustomElHook(el);
|
|
7028
7291
|
if (existingHook) {
|