phoenix_live_view 0.18.3 → 0.18.5
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/assets/js/phoenix_live_view/dom.js +6 -1
- package/assets/js/phoenix_live_view/dom_patch.js +2 -2
- package/assets/js/phoenix_live_view/js.js +1 -1
- package/assets/js/phoenix_live_view/live_socket.js +30 -14
- package/assets/js/phoenix_live_view/view.js +14 -10
- package/assets/package.json +24 -0
- package/package.json +1 -1
- package/priv/static/phoenix_live_view.cjs.js +55 -22
- package/priv/static/phoenix_live_view.cjs.js.map +2 -2
- package/priv/static/phoenix_live_view.esm.js +55 -22
- package/priv/static/phoenix_live_view.esm.js.map +2 -2
- package/priv/static/phoenix_live_view.js +55 -22
- package/priv/static/phoenix_live_view.min.js +4 -4
|
@@ -58,6 +58,11 @@ let DOM = {
|
|
|
58
58
|
return node.id && DOM.private(node, "destroyed") ? true : false
|
|
59
59
|
},
|
|
60
60
|
|
|
61
|
+
isExternalClick(e){
|
|
62
|
+
return(e.ctrlKey || e.shiftKey || e.metaKey || (e.button && e.button === 1)
|
|
63
|
+
|| e.target.getAttribute("target") === "_blank")
|
|
64
|
+
},
|
|
65
|
+
|
|
61
66
|
markPhxChildDestroyed(el){
|
|
62
67
|
if(this.isPhxChild(el)){ el.setAttribute(PHX_SESSION, "") }
|
|
63
68
|
this.putPrivate(el, "destroyed", true)
|
|
@@ -231,7 +236,7 @@ let DOM = {
|
|
|
231
236
|
let input = field && container.querySelector(`[id="${field}"], [name="${field}"], [name="${field}[]"]`)
|
|
232
237
|
if(!input){ return }
|
|
233
238
|
|
|
234
|
-
if(!(this.private(input, PHX_HAS_FOCUSED) || this.private(input
|
|
239
|
+
if(!(this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED))){
|
|
235
240
|
el.classList.add(PHX_NO_FEEDBACK_CLASS)
|
|
236
241
|
}
|
|
237
242
|
},
|
|
@@ -176,7 +176,7 @@ export default class DOMPatch {
|
|
|
176
176
|
DOM.discardError(targetContainer, toEl, phxFeedbackFor)
|
|
177
177
|
|
|
178
178
|
let isFocusedFormEl = focused && fromEl.isSameNode(focused) && DOM.isFormInput(fromEl)
|
|
179
|
-
if(isFocusedFormEl){
|
|
179
|
+
if(isFocusedFormEl && fromEl.type !== "hidden"){
|
|
180
180
|
this.trackBefore("updated", fromEl, toEl)
|
|
181
181
|
DOM.mergeFocusedInput(fromEl, toEl)
|
|
182
182
|
DOM.syncAttrsToProps(fromEl)
|
|
@@ -222,7 +222,7 @@ export default class DOMPatch {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
if(externalFormTriggered){
|
|
225
|
-
liveSocket.
|
|
225
|
+
liveSocket.unload()
|
|
226
226
|
externalFormTriggered.submit()
|
|
227
227
|
}
|
|
228
228
|
return true
|
|
@@ -43,7 +43,7 @@ let JS = {
|
|
|
43
43
|
view.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
44
44
|
if(eventType === "change"){
|
|
45
45
|
let {newCid, _target, callback} = args
|
|
46
|
-
_target = _target || (sourceEl
|
|
46
|
+
_target = _target || (DOM.isFormInput(sourceEl) ? sourceEl.name : undefined)
|
|
47
47
|
if(_target){ pushOpts._target = _target }
|
|
48
48
|
targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback)
|
|
49
49
|
} else if(eventType === "submit"){
|
|
@@ -210,8 +210,9 @@ export default class LiveSocket {
|
|
|
210
210
|
} else if(this.main){
|
|
211
211
|
this.socket.connect()
|
|
212
212
|
} else {
|
|
213
|
-
this.
|
|
213
|
+
this.bindTopLevelEvents({dead: true})
|
|
214
214
|
}
|
|
215
|
+
this.joinDeadView()
|
|
215
216
|
}
|
|
216
217
|
if(["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0){
|
|
217
218
|
doConnect()
|
|
@@ -237,6 +238,14 @@ export default class LiveSocket {
|
|
|
237
238
|
|
|
238
239
|
// private
|
|
239
240
|
|
|
241
|
+
unload(){
|
|
242
|
+
if(this.unloaded){ return }
|
|
243
|
+
if(this.main && this.isConnected()){ this.log(this.main, "socket", () => ["disconnect for page nav"]) }
|
|
244
|
+
this.unloaded = true
|
|
245
|
+
this.destroyAllViews()
|
|
246
|
+
this.disconnect()
|
|
247
|
+
}
|
|
248
|
+
|
|
240
249
|
triggerDOM(kind, args){ this.domCallbacks[kind](...args) }
|
|
241
250
|
|
|
242
251
|
time(name, func){
|
|
@@ -345,12 +354,14 @@ export default class LiveSocket {
|
|
|
345
354
|
channel(topic, params){ return this.socket.channel(topic, params) }
|
|
346
355
|
|
|
347
356
|
joinDeadView(){
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
357
|
+
let body = document.body
|
|
358
|
+
if(body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)){
|
|
359
|
+
let view = this.newRootView(body)
|
|
360
|
+
view.setHref(this.getHref())
|
|
361
|
+
view.joinDead()
|
|
362
|
+
if(!this.main){ this.main = view }
|
|
363
|
+
window.requestAnimationFrame(() => view.execNewMounted())
|
|
364
|
+
}
|
|
354
365
|
}
|
|
355
366
|
|
|
356
367
|
joinRootViews(){
|
|
@@ -360,7 +371,7 @@ export default class LiveSocket {
|
|
|
360
371
|
let view = this.newRootView(rootEl)
|
|
361
372
|
view.setHref(this.getHref())
|
|
362
373
|
view.join()
|
|
363
|
-
if(rootEl.
|
|
374
|
+
if(rootEl.hasAttribute(PHX_MAIN)){ this.main = view }
|
|
364
375
|
}
|
|
365
376
|
rootsFound = true
|
|
366
377
|
})
|
|
@@ -491,9 +502,10 @@ export default class LiveSocket {
|
|
|
491
502
|
this.boundTopLevelEvents = true
|
|
492
503
|
// enter failsafe reload if server has gone away intentionally, such as "disconnect" broadcast
|
|
493
504
|
this.socket.onClose(event => {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
505
|
+
// unload when navigating href or form submit (such as for firefox)
|
|
506
|
+
if(event && event.code === 1001){ return this.unload() }
|
|
507
|
+
// failsafe reload if normal closure and we still have a main LV
|
|
508
|
+
if(event && event.code === 1000 && this.main){ return this.reloadWithJitter(this.main) }
|
|
497
509
|
})
|
|
498
510
|
document.body.addEventListener("click", function (){ }) // ensure all click events bubble for mobile Safari
|
|
499
511
|
window.addEventListener("pageshow", e => {
|
|
@@ -621,7 +633,10 @@ export default class LiveSocket {
|
|
|
621
633
|
this.clickStartedAtTarget = null
|
|
622
634
|
}
|
|
623
635
|
let phxEvent = target && target.getAttribute(click)
|
|
624
|
-
if(!phxEvent){
|
|
636
|
+
if(!phxEvent){
|
|
637
|
+
if(!capture && e.target.href !== undefined && DOM.isExternalClick(e)){ this.unload() }
|
|
638
|
+
return
|
|
639
|
+
}
|
|
625
640
|
if(target.getAttribute("href") === "#"){ e.preventDefault() }
|
|
626
641
|
|
|
627
642
|
this.debounce(target, e, "click", () => {
|
|
@@ -739,7 +754,7 @@ export default class LiveSocket {
|
|
|
739
754
|
historyRedirect(href, linkState, flash){
|
|
740
755
|
// convert to full href if only path prefix
|
|
741
756
|
if(!this.isConnected()){ return Browser.redirect(href, flash) }
|
|
742
|
-
if(
|
|
757
|
+
if(/^\/$|^\/[^\/]+.*$/.test(href)){
|
|
743
758
|
let {protocol, host} = window.location
|
|
744
759
|
href = `${protocol}//${host}${href}`
|
|
745
760
|
}
|
|
@@ -778,6 +793,7 @@ export default class LiveSocket {
|
|
|
778
793
|
if(!externalFormSubmitted && phxChange && !phxSubmit){
|
|
779
794
|
externalFormSubmitted = true
|
|
780
795
|
e.preventDefault()
|
|
796
|
+
this.unload()
|
|
781
797
|
this.withinOwners(e.target, view => {
|
|
782
798
|
view.disableForm(e.target)
|
|
783
799
|
window.requestAnimationFrame(() => e.target.submit()) // safari needs next tick
|
|
@@ -787,7 +803,7 @@ export default class LiveSocket {
|
|
|
787
803
|
|
|
788
804
|
this.on("submit", e => {
|
|
789
805
|
let phxEvent = e.target.getAttribute(this.binding("submit"))
|
|
790
|
-
if(!phxEvent){ return }
|
|
806
|
+
if(!phxEvent){ return this.unload() }
|
|
791
807
|
e.preventDefault()
|
|
792
808
|
e.target.disabled = true
|
|
793
809
|
this.withinOwners(e.target, view => {
|
|
@@ -119,7 +119,7 @@ export default class View {
|
|
|
119
119
|
this.href = href
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
isMain(){ return this.el.
|
|
122
|
+
isMain(){ return this.el.hasAttribute(PHX_MAIN) }
|
|
123
123
|
|
|
124
124
|
connectParams(liveReferer){
|
|
125
125
|
let params = this.liveSocket.params(this.el)
|
|
@@ -228,9 +228,8 @@ export default class View {
|
|
|
228
228
|
applyDiff(type, rawDiff, callback){
|
|
229
229
|
this.log(type, () => ["", clone(rawDiff)])
|
|
230
230
|
let {diff, reply, events, title} = Rendered.extract(rawDiff)
|
|
231
|
-
if(title){ DOM.putTitle(title) }
|
|
232
|
-
|
|
233
231
|
callback({diff, reply, events})
|
|
232
|
+
if(title){ window.requestAnimationFrame(() => DOM.putTitle(title)) }
|
|
234
233
|
}
|
|
235
234
|
|
|
236
235
|
onJoin(resp){
|
|
@@ -553,6 +552,12 @@ export default class View {
|
|
|
553
552
|
applyPendingUpdates(){
|
|
554
553
|
this.pendingDiffs.forEach(({diff, events}) => this.update(diff, events))
|
|
555
554
|
this.pendingDiffs = []
|
|
555
|
+
this.eachChild(child => child.applyPendingUpdates())
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
eachChild(callback){
|
|
559
|
+
let children = this.root.children[this.id] || {}
|
|
560
|
+
for(let id in children){ callback(this.getChildById(id)) }
|
|
556
561
|
}
|
|
557
562
|
|
|
558
563
|
onChannel(event, cb){
|
|
@@ -580,11 +585,7 @@ export default class View {
|
|
|
580
585
|
this.channel.onClose(reason => this.onClose(reason))
|
|
581
586
|
}
|
|
582
587
|
|
|
583
|
-
destroyAllChildren(){
|
|
584
|
-
for(let id in this.root.children[this.id]){
|
|
585
|
-
this.getChildById(id).destroy()
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
+
destroyAllChildren(){ this.eachChild(child => child.destroy()) }
|
|
588
589
|
|
|
589
590
|
onLiveRedirect(redir){
|
|
590
591
|
let {to, kind, flash} = redir
|
|
@@ -1115,14 +1116,17 @@ export default class View {
|
|
|
1115
1116
|
}
|
|
1116
1117
|
|
|
1117
1118
|
ownsElement(el){
|
|
1118
|
-
|
|
1119
|
-
|
|
1119
|
+
let parentViewEl = el.closest(PHX_VIEW_SELECTOR)
|
|
1120
|
+
return el.getAttribute(PHX_PARENT_ID) === this.id ||
|
|
1121
|
+
(parentViewEl && parentViewEl.id === this.id) ||
|
|
1122
|
+
(!parentViewEl && this.isDead)
|
|
1120
1123
|
}
|
|
1121
1124
|
|
|
1122
1125
|
submitForm(form, targetCtx, phxEvent, opts = {}){
|
|
1123
1126
|
DOM.putPrivate(form, PHX_HAS_SUBMITTED, true)
|
|
1124
1127
|
let phxFeedback = this.liveSocket.binding(PHX_FEEDBACK_FOR)
|
|
1125
1128
|
let inputs = Array.from(form.elements)
|
|
1129
|
+
inputs.forEach(input => DOM.putPrivate(input, PHX_HAS_SUBMITTED, true))
|
|
1126
1130
|
this.liveSocket.blurActiveElement(this)
|
|
1127
1131
|
this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
|
|
1128
1132
|
inputs.forEach(input => DOM.showError(input, phxFeedback))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "phoenix_live_view",
|
|
3
|
+
"version": "0.18.5",
|
|
4
|
+
"description": "The Phoenix LiveView JavaScript client.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {},
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "jest",
|
|
9
|
+
"test.coverage": "jest --coverage",
|
|
10
|
+
"test.watch": "jest --watch"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"morphdom": "2.6.1"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@babel/cli": "7.14.3",
|
|
17
|
+
"@babel/core": "7.14.3",
|
|
18
|
+
"@babel/preset-env": "7.14.2",
|
|
19
|
+
"eslint": "7.27.0",
|
|
20
|
+
"eslint-plugin-jest": "24.3.6",
|
|
21
|
+
"jest": "^27.0.1",
|
|
22
|
+
"phoenix": "1.5.9"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -302,6 +302,9 @@ var DOM = {
|
|
|
302
302
|
isPhxDestroyed(node) {
|
|
303
303
|
return node.id && DOM.private(node, "destroyed") ? true : false;
|
|
304
304
|
},
|
|
305
|
+
isExternalClick(e) {
|
|
306
|
+
return e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1 || e.target.getAttribute("target") === "_blank";
|
|
307
|
+
},
|
|
305
308
|
markPhxChildDestroyed(el) {
|
|
306
309
|
if (this.isPhxChild(el)) {
|
|
307
310
|
el.setAttribute(PHX_SESSION, "");
|
|
@@ -476,7 +479,7 @@ var DOM = {
|
|
|
476
479
|
if (!input) {
|
|
477
480
|
return;
|
|
478
481
|
}
|
|
479
|
-
if (!(this.private(input, PHX_HAS_FOCUSED) || this.private(input
|
|
482
|
+
if (!(this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED))) {
|
|
480
483
|
el.classList.add(PHX_NO_FEEDBACK_CLASS);
|
|
481
484
|
}
|
|
482
485
|
},
|
|
@@ -1669,7 +1672,7 @@ var DOMPatch = class {
|
|
|
1669
1672
|
dom_default.copyPrivates(toEl, fromEl);
|
|
1670
1673
|
dom_default.discardError(targetContainer, toEl, phxFeedbackFor);
|
|
1671
1674
|
let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
|
|
1672
|
-
if (isFocusedFormEl) {
|
|
1675
|
+
if (isFocusedFormEl && fromEl.type !== "hidden") {
|
|
1673
1676
|
this.trackBefore("updated", fromEl, toEl);
|
|
1674
1677
|
dom_default.mergeFocusedInput(fromEl, toEl);
|
|
1675
1678
|
dom_default.syncAttrsToProps(fromEl);
|
|
@@ -1714,7 +1717,7 @@ var DOMPatch = class {
|
|
|
1714
1717
|
});
|
|
1715
1718
|
}
|
|
1716
1719
|
if (externalFormTriggered) {
|
|
1717
|
-
liveSocket.
|
|
1720
|
+
liveSocket.unload();
|
|
1718
1721
|
externalFormTriggered.submit();
|
|
1719
1722
|
}
|
|
1720
1723
|
return true;
|
|
@@ -2084,7 +2087,7 @@ var JS = {
|
|
|
2084
2087
|
view.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
2085
2088
|
if (eventType === "change") {
|
|
2086
2089
|
let { newCid, _target, callback } = args;
|
|
2087
|
-
_target = _target || (sourceEl
|
|
2090
|
+
_target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
|
|
2088
2091
|
if (_target) {
|
|
2089
2092
|
pushOpts._target = _target;
|
|
2090
2093
|
}
|
|
@@ -2321,7 +2324,7 @@ var View = class {
|
|
|
2321
2324
|
this.href = href;
|
|
2322
2325
|
}
|
|
2323
2326
|
isMain() {
|
|
2324
|
-
return this.el.
|
|
2327
|
+
return this.el.hasAttribute(PHX_MAIN);
|
|
2325
2328
|
}
|
|
2326
2329
|
connectParams(liveReferer) {
|
|
2327
2330
|
let params = this.liveSocket.params(this.el);
|
|
@@ -2419,10 +2422,10 @@ var View = class {
|
|
|
2419
2422
|
applyDiff(type, rawDiff, callback) {
|
|
2420
2423
|
this.log(type, () => ["", clone(rawDiff)]);
|
|
2421
2424
|
let { diff, reply, events, title } = Rendered.extract(rawDiff);
|
|
2425
|
+
callback({ diff, reply, events });
|
|
2422
2426
|
if (title) {
|
|
2423
|
-
dom_default.putTitle(title);
|
|
2427
|
+
window.requestAnimationFrame(() => dom_default.putTitle(title));
|
|
2424
2428
|
}
|
|
2425
|
-
callback({ diff, reply, events });
|
|
2426
2429
|
}
|
|
2427
2430
|
onJoin(resp) {
|
|
2428
2431
|
let { rendered, container } = resp;
|
|
@@ -2724,6 +2727,13 @@ var View = class {
|
|
|
2724
2727
|
applyPendingUpdates() {
|
|
2725
2728
|
this.pendingDiffs.forEach(({ diff, events }) => this.update(diff, events));
|
|
2726
2729
|
this.pendingDiffs = [];
|
|
2730
|
+
this.eachChild((child) => child.applyPendingUpdates());
|
|
2731
|
+
}
|
|
2732
|
+
eachChild(callback) {
|
|
2733
|
+
let children = this.root.children[this.id] || {};
|
|
2734
|
+
for (let id in children) {
|
|
2735
|
+
callback(this.getChildById(id));
|
|
2736
|
+
}
|
|
2727
2737
|
}
|
|
2728
2738
|
onChannel(event, cb) {
|
|
2729
2739
|
this.liveSocket.onChannel(this.channel, event, (resp) => {
|
|
@@ -2747,9 +2757,7 @@ var View = class {
|
|
|
2747
2757
|
this.channel.onClose((reason) => this.onClose(reason));
|
|
2748
2758
|
}
|
|
2749
2759
|
destroyAllChildren() {
|
|
2750
|
-
|
|
2751
|
-
this.getChildById(id).destroy();
|
|
2752
|
-
}
|
|
2760
|
+
this.eachChild((child) => child.destroy());
|
|
2753
2761
|
}
|
|
2754
2762
|
onLiveRedirect(redir) {
|
|
2755
2763
|
let { to, kind, flash } = redir;
|
|
@@ -3271,12 +3279,14 @@ var View = class {
|
|
|
3271
3279
|
}
|
|
3272
3280
|
}
|
|
3273
3281
|
ownsElement(el) {
|
|
3274
|
-
|
|
3282
|
+
let parentViewEl = el.closest(PHX_VIEW_SELECTOR);
|
|
3283
|
+
return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;
|
|
3275
3284
|
}
|
|
3276
3285
|
submitForm(form, targetCtx, phxEvent, opts = {}) {
|
|
3277
3286
|
dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
|
|
3278
3287
|
let phxFeedback = this.liveSocket.binding(PHX_FEEDBACK_FOR);
|
|
3279
3288
|
let inputs = Array.from(form.elements);
|
|
3289
|
+
inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
|
|
3280
3290
|
this.liveSocket.blurActiveElement(this);
|
|
3281
3291
|
this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
|
|
3282
3292
|
inputs.forEach((input) => dom_default.showError(input, phxFeedback));
|
|
@@ -3388,8 +3398,9 @@ var LiveSocket = class {
|
|
|
3388
3398
|
} else if (this.main) {
|
|
3389
3399
|
this.socket.connect();
|
|
3390
3400
|
} else {
|
|
3391
|
-
this.
|
|
3401
|
+
this.bindTopLevelEvents({ dead: true });
|
|
3392
3402
|
}
|
|
3403
|
+
this.joinDeadView();
|
|
3393
3404
|
};
|
|
3394
3405
|
if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {
|
|
3395
3406
|
doConnect();
|
|
@@ -3409,6 +3420,17 @@ var LiveSocket = class {
|
|
|
3409
3420
|
execJS(el, encodedJS, eventType = null) {
|
|
3410
3421
|
this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
|
|
3411
3422
|
}
|
|
3423
|
+
unload() {
|
|
3424
|
+
if (this.unloaded) {
|
|
3425
|
+
return;
|
|
3426
|
+
}
|
|
3427
|
+
if (this.main && this.isConnected()) {
|
|
3428
|
+
this.log(this.main, "socket", () => ["disconnect for page nav"]);
|
|
3429
|
+
}
|
|
3430
|
+
this.unloaded = true;
|
|
3431
|
+
this.destroyAllViews();
|
|
3432
|
+
this.disconnect();
|
|
3433
|
+
}
|
|
3412
3434
|
triggerDOM(kind, args) {
|
|
3413
3435
|
this.domCallbacks[kind](...args);
|
|
3414
3436
|
}
|
|
@@ -3522,12 +3544,16 @@ var LiveSocket = class {
|
|
|
3522
3544
|
return this.socket.channel(topic, params);
|
|
3523
3545
|
}
|
|
3524
3546
|
joinDeadView() {
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3547
|
+
let body = document.body;
|
|
3548
|
+
if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
|
|
3549
|
+
let view = this.newRootView(body);
|
|
3550
|
+
view.setHref(this.getHref());
|
|
3551
|
+
view.joinDead();
|
|
3552
|
+
if (!this.main) {
|
|
3553
|
+
this.main = view;
|
|
3554
|
+
}
|
|
3555
|
+
window.requestAnimationFrame(() => view.execNewMounted());
|
|
3556
|
+
}
|
|
3531
3557
|
}
|
|
3532
3558
|
joinRootViews() {
|
|
3533
3559
|
let rootsFound = false;
|
|
@@ -3536,7 +3562,7 @@ var LiveSocket = class {
|
|
|
3536
3562
|
let view = this.newRootView(rootEl);
|
|
3537
3563
|
view.setHref(this.getHref());
|
|
3538
3564
|
view.join();
|
|
3539
|
-
if (rootEl.
|
|
3565
|
+
if (rootEl.hasAttribute(PHX_MAIN)) {
|
|
3540
3566
|
this.main = view;
|
|
3541
3567
|
}
|
|
3542
3568
|
}
|
|
@@ -3662,8 +3688,11 @@ var LiveSocket = class {
|
|
|
3662
3688
|
}
|
|
3663
3689
|
this.boundTopLevelEvents = true;
|
|
3664
3690
|
this.socket.onClose((event) => {
|
|
3691
|
+
if (event && event.code === 1001) {
|
|
3692
|
+
return this.unload();
|
|
3693
|
+
}
|
|
3665
3694
|
if (event && event.code === 1e3 && this.main) {
|
|
3666
|
-
this.reloadWithJitter(this.main);
|
|
3695
|
+
return this.reloadWithJitter(this.main);
|
|
3667
3696
|
}
|
|
3668
3697
|
});
|
|
3669
3698
|
document.body.addEventListener("click", function() {
|
|
@@ -3796,6 +3825,9 @@ var LiveSocket = class {
|
|
|
3796
3825
|
}
|
|
3797
3826
|
let phxEvent = target && target.getAttribute(click);
|
|
3798
3827
|
if (!phxEvent) {
|
|
3828
|
+
if (!capture && e.target.href !== void 0 && dom_default.isExternalClick(e)) {
|
|
3829
|
+
this.unload();
|
|
3830
|
+
}
|
|
3799
3831
|
return;
|
|
3800
3832
|
}
|
|
3801
3833
|
if (target.getAttribute("href") === "#") {
|
|
@@ -3920,7 +3952,7 @@ var LiveSocket = class {
|
|
|
3920
3952
|
if (!this.isConnected()) {
|
|
3921
3953
|
return browser_default.redirect(href, flash);
|
|
3922
3954
|
}
|
|
3923
|
-
if (
|
|
3955
|
+
if (/^\/$|^\/[^\/]+.*$/.test(href)) {
|
|
3924
3956
|
let { protocol, host } = window.location;
|
|
3925
3957
|
href = `${protocol}//${host}${href}`;
|
|
3926
3958
|
}
|
|
@@ -3954,6 +3986,7 @@ var LiveSocket = class {
|
|
|
3954
3986
|
if (!externalFormSubmitted && phxChange && !phxSubmit) {
|
|
3955
3987
|
externalFormSubmitted = true;
|
|
3956
3988
|
e.preventDefault();
|
|
3989
|
+
this.unload();
|
|
3957
3990
|
this.withinOwners(e.target, (view) => {
|
|
3958
3991
|
view.disableForm(e.target);
|
|
3959
3992
|
window.requestAnimationFrame(() => e.target.submit());
|
|
@@ -3963,7 +3996,7 @@ var LiveSocket = class {
|
|
|
3963
3996
|
this.on("submit", (e) => {
|
|
3964
3997
|
let phxEvent = e.target.getAttribute(this.binding("submit"));
|
|
3965
3998
|
if (!phxEvent) {
|
|
3966
|
-
return;
|
|
3999
|
+
return this.unload();
|
|
3967
4000
|
}
|
|
3968
4001
|
e.preventDefault();
|
|
3969
4002
|
e.target.disabled = true;
|