phoenix_live_view 0.16.3 → 0.17.2
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/CHANGELOG.md +128 -7
- package/assets/js/phoenix_live_view/constants.js +2 -2
- package/assets/js/phoenix_live_view/dom.js +49 -13
- package/assets/js/phoenix_live_view/dom_patch.js +31 -11
- package/assets/js/phoenix_live_view/js.js +169 -0
- package/assets/js/phoenix_live_view/live_socket.js +143 -50
- package/assets/js/phoenix_live_view/view.js +113 -87
- package/assets/js/phoenix_live_view/view_hook.js +2 -2
- package/package.json +5 -3
- package/priv/static/phoenix_live_view.cjs.js +3737 -0
- package/priv/static/phoenix_live_view.cjs.js.map +7 -0
- package/priv/static/phoenix_live_view.esm.js +495 -167
- package/priv/static/phoenix_live_view.esm.js.map +3 -3
- package/priv/static/phoenix_live_view.js +495 -167
- package/priv/static/phoenix_live_view.min.js +6 -6
|
@@ -46,6 +46,7 @@ import DOMPatch from "./dom_patch"
|
|
|
46
46
|
import LiveUploader from "./live_uploader"
|
|
47
47
|
import Rendered from "./rendered"
|
|
48
48
|
import ViewHook from "./view_hook"
|
|
49
|
+
import JS from "./js"
|
|
49
50
|
|
|
50
51
|
let serializeForm = (form, meta = {}) => {
|
|
51
52
|
let formData = new FormData(form)
|
|
@@ -83,8 +84,8 @@ export default class View {
|
|
|
83
84
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0
|
|
84
85
|
this.joinPending = true
|
|
85
86
|
this.destroyed = false
|
|
86
|
-
this.joinCallback = function
|
|
87
|
-
this.stopCallback = function
|
|
87
|
+
this.joinCallback = function(onDone){ onDone && onDone() }
|
|
88
|
+
this.stopCallback = function(){ }
|
|
88
89
|
this.pendingJoinOps = this.parent ? null : []
|
|
89
90
|
this.viewHooks = {}
|
|
90
91
|
this.uploaders = {}
|
|
@@ -166,8 +167,6 @@ export default class View {
|
|
|
166
167
|
this.el.classList.add(...classes)
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
isLoading(){ return this.el.classList.contains(PHX_DISCONNECTED_CLASS) }
|
|
170
|
-
|
|
171
170
|
showLoader(timeout){
|
|
172
171
|
clearTimeout(this.loaderTimer)
|
|
173
172
|
if(timeout){
|
|
@@ -191,17 +190,21 @@ export default class View {
|
|
|
191
190
|
this.liveSocket.log(this, kind, msgCallback)
|
|
192
191
|
}
|
|
193
192
|
|
|
193
|
+
transition(time, onDone = function(){}){
|
|
194
|
+
this.liveSocket.transition(time, onDone)
|
|
195
|
+
}
|
|
196
|
+
|
|
194
197
|
withinTargets(phxTarget, callback){
|
|
195
|
-
if(phxTarget instanceof HTMLElement){
|
|
198
|
+
if(phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement){
|
|
196
199
|
return this.liveSocket.owner(phxTarget, view => callback(view, phxTarget))
|
|
197
200
|
}
|
|
198
201
|
|
|
199
|
-
if(/^(0|[1-9]\d*)$/.test(phxTarget)){
|
|
202
|
+
if(typeof(phxTarget) === "number" || /^(0|[1-9]\d*)$/.test(phxTarget)){
|
|
200
203
|
let targets = DOM.findComponentNodeList(this.el, phxTarget)
|
|
201
204
|
if(targets.length === 0){
|
|
202
205
|
logError(`no component found matching phx-target of ${phxTarget}`)
|
|
203
206
|
} else {
|
|
204
|
-
callback(this,
|
|
207
|
+
callback(this, parseInt(phxTarget))
|
|
205
208
|
}
|
|
206
209
|
} else {
|
|
207
210
|
let targets = Array.from(document.querySelectorAll(phxTarget))
|
|
@@ -289,12 +292,6 @@ export default class View {
|
|
|
289
292
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id)
|
|
290
293
|
}
|
|
291
294
|
|
|
292
|
-
dispatchEvents(events){
|
|
293
|
-
events.forEach(([event, payload]) => {
|
|
294
|
-
window.dispatchEvent(new CustomEvent(`phx:hook:${event}`, {detail: payload}))
|
|
295
|
-
})
|
|
296
|
-
}
|
|
297
|
-
|
|
298
295
|
applyJoinPatch(live_patch, html, events){
|
|
299
296
|
this.attachTrueDocEl()
|
|
300
297
|
let patch = new DOMPatch(this, this.el, this.id, html, null)
|
|
@@ -307,7 +304,7 @@ export default class View {
|
|
|
307
304
|
})
|
|
308
305
|
|
|
309
306
|
this.joinPending = false
|
|
310
|
-
this.dispatchEvents(events)
|
|
307
|
+
this.liveSocket.dispatchEvents(events)
|
|
311
308
|
this.applyPendingUpdates()
|
|
312
309
|
|
|
313
310
|
if(live_patch){
|
|
@@ -330,7 +327,7 @@ export default class View {
|
|
|
330
327
|
}
|
|
331
328
|
|
|
332
329
|
performPatch(patch, pruneCids){
|
|
333
|
-
let
|
|
330
|
+
let removedEls = []
|
|
334
331
|
let phxChildrenAdded = false
|
|
335
332
|
let updatedHookIds = new Set()
|
|
336
333
|
|
|
@@ -353,22 +350,33 @@ export default class View {
|
|
|
353
350
|
})
|
|
354
351
|
|
|
355
352
|
patch.after("discarded", (el) => {
|
|
356
|
-
|
|
357
|
-
if(isCid(cid) && destroyedCIDs.indexOf(cid) === -1){ destroyedCIDs.push(cid) }
|
|
358
|
-
let hook = this.getHook(el)
|
|
359
|
-
hook && this.destroyHook(hook)
|
|
353
|
+
if(el.nodeType === Node.ELEMENT_NODE){ removedEls.push(el) }
|
|
360
354
|
})
|
|
361
355
|
|
|
356
|
+
patch.after("transitionsDiscarded", els => this.afterElementsRemoved(els, pruneCids))
|
|
362
357
|
patch.perform()
|
|
358
|
+
this.afterElementsRemoved(removedEls, pruneCids)
|
|
359
|
+
|
|
360
|
+
return phxChildrenAdded
|
|
361
|
+
}
|
|
363
362
|
|
|
363
|
+
afterElementsRemoved(elements, pruneCids){
|
|
364
|
+
let destroyedCIDs = []
|
|
365
|
+
elements.forEach(parent => {
|
|
366
|
+
let components = DOM.all(parent, `[${PHX_COMPONENT}]`)
|
|
367
|
+
components.concat(parent).forEach(el => {
|
|
368
|
+
let cid = this.componentID(el)
|
|
369
|
+
if(isCid(cid) && destroyedCIDs.indexOf(cid) === -1){ destroyedCIDs.push(cid) }
|
|
370
|
+
let hook = this.getHook(el)
|
|
371
|
+
hook && this.destroyHook(hook)
|
|
372
|
+
})
|
|
373
|
+
})
|
|
364
374
|
// We should not pruneCids on joins. Otherwise, in case of
|
|
365
375
|
// rejoins, we may notify cids that no longer belong to the
|
|
366
376
|
// current LiveView to be removed.
|
|
367
377
|
if(pruneCids){
|
|
368
378
|
this.maybePushComponentsDestroyed(destroyedCIDs)
|
|
369
379
|
}
|
|
370
|
-
|
|
371
|
-
return phxChildrenAdded
|
|
372
380
|
}
|
|
373
381
|
|
|
374
382
|
joinNewChildren(){
|
|
@@ -419,11 +427,12 @@ export default class View {
|
|
|
419
427
|
}
|
|
420
428
|
|
|
421
429
|
onAllChildJoinsComplete(){
|
|
422
|
-
this.joinCallback()
|
|
423
|
-
|
|
424
|
-
|
|
430
|
+
this.joinCallback(() => {
|
|
431
|
+
this.pendingJoinOps.forEach(([view, op]) => {
|
|
432
|
+
if(!view.isDestroyed()){ op() }
|
|
433
|
+
})
|
|
434
|
+
this.pendingJoinOps = []
|
|
425
435
|
})
|
|
426
|
-
this.pendingJoinOps = []
|
|
427
436
|
}
|
|
428
437
|
|
|
429
438
|
update(diff, events){
|
|
@@ -452,7 +461,7 @@ export default class View {
|
|
|
452
461
|
})
|
|
453
462
|
}
|
|
454
463
|
|
|
455
|
-
this.dispatchEvents(events)
|
|
464
|
+
this.liveSocket.dispatchEvents(events)
|
|
456
465
|
if(phxChildrenAdded){ this.joinNewChildren() }
|
|
457
466
|
}
|
|
458
467
|
|
|
@@ -509,7 +518,7 @@ export default class View {
|
|
|
509
518
|
if(this.isJoinPending()){
|
|
510
519
|
this.root.pendingJoinOps.push([this, () => cb(resp)])
|
|
511
520
|
} else {
|
|
512
|
-
cb(resp)
|
|
521
|
+
this.liveSocket.requestDOMUpdate(() => cb(resp))
|
|
513
522
|
}
|
|
514
523
|
})
|
|
515
524
|
}
|
|
@@ -518,7 +527,9 @@ export default class View {
|
|
|
518
527
|
// The diff event should be handled by the regular update operations.
|
|
519
528
|
// All other operations are queued to be applied only after join.
|
|
520
529
|
this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {
|
|
521
|
-
this.
|
|
530
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
531
|
+
this.applyDiff("update", rawDiff, ({diff, events}) => this.update(diff, events))
|
|
532
|
+
})
|
|
522
533
|
})
|
|
523
534
|
this.onChannel("redirect", ({to, flash}) => this.onRedirect({to, flash}))
|
|
524
535
|
this.onChannel("live_patch", (redir) => this.onLivePatch(redir))
|
|
@@ -557,10 +568,17 @@ export default class View {
|
|
|
557
568
|
if(!this.parent){
|
|
558
569
|
this.stopCallback = this.liveSocket.withPageLoading({to: this.href, kind: "initial"})
|
|
559
570
|
}
|
|
560
|
-
this.joinCallback = () =>
|
|
571
|
+
this.joinCallback = (onDone) => {
|
|
572
|
+
onDone = onDone || function(){}
|
|
573
|
+
callback ? callback(this.joinCount, onDone) : onDone()
|
|
574
|
+
}
|
|
561
575
|
this.liveSocket.wrapPush(this, {timeout: false}, () => {
|
|
562
576
|
return this.channel.join()
|
|
563
|
-
.receive("ok", data =>
|
|
577
|
+
.receive("ok", data => {
|
|
578
|
+
if(!this.isDestroyed()){
|
|
579
|
+
this.liveSocket.requestDOMUpdate(() => this.onJoin(data))
|
|
580
|
+
}
|
|
581
|
+
})
|
|
564
582
|
.receive("error", resp => !this.isDestroyed() && this.onJoinError(resp))
|
|
565
583
|
.receive("timeout", () => !this.isDestroyed() && this.onJoinError({reason: "timeout"}))
|
|
566
584
|
})
|
|
@@ -612,9 +630,9 @@ export default class View {
|
|
|
612
630
|
pushWithReply(refGenerator, event, payload, onReply = function (){ }){
|
|
613
631
|
if(!this.isConnected()){ return }
|
|
614
632
|
|
|
615
|
-
let [ref, [el]] = refGenerator ? refGenerator() : [null, []]
|
|
616
|
-
let onLoadingDone = function
|
|
617
|
-
if(el && (el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null)){
|
|
633
|
+
let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}]
|
|
634
|
+
let onLoadingDone = function(){ }
|
|
635
|
+
if(opts.page_loading || (el && (el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null))){
|
|
618
636
|
onLoadingDone = this.liveSocket.withPageLoading({kind: "element", target: el})
|
|
619
637
|
}
|
|
620
638
|
|
|
@@ -622,18 +640,20 @@ export default class View {
|
|
|
622
640
|
return (
|
|
623
641
|
this.liveSocket.wrapPush(this, {timeout: true}, () => {
|
|
624
642
|
return this.channel.push(event, payload, PUSH_TIMEOUT).receive("ok", resp => {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
this.update(diff, events)
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
643
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
644
|
+
let hookReply = null
|
|
645
|
+
if(ref !== null){ this.undoRefs(ref) }
|
|
646
|
+
if(resp.diff){
|
|
647
|
+
hookReply = this.applyDiff("update", resp.diff, ({diff, events}) => {
|
|
648
|
+
this.update(diff, events)
|
|
649
|
+
})
|
|
650
|
+
}
|
|
651
|
+
if(resp.redirect){ this.onRedirect(resp.redirect) }
|
|
652
|
+
if(resp.live_patch){ this.onLivePatch(resp.live_patch) }
|
|
653
|
+
if(resp.live_redirect){ this.onLiveRedirect(resp.live_redirect) }
|
|
654
|
+
onLoadingDone()
|
|
655
|
+
onReply(resp, hookReply)
|
|
656
|
+
})
|
|
637
657
|
})
|
|
638
658
|
})
|
|
639
659
|
)
|
|
@@ -671,9 +691,10 @@ export default class View {
|
|
|
671
691
|
})
|
|
672
692
|
}
|
|
673
693
|
|
|
674
|
-
putRef(elements, event){
|
|
694
|
+
putRef(elements, event, opts = {}){
|
|
675
695
|
let newRef = this.ref++
|
|
676
696
|
let disableWith = this.binding(PHX_DISABLE_WITH)
|
|
697
|
+
if(opts.loading){ elements = elements.concat(DOM.all(document, opts.loading))}
|
|
677
698
|
|
|
678
699
|
elements.forEach(el => {
|
|
679
700
|
el.classList.add(`phx-${event}-loading`)
|
|
@@ -686,7 +707,7 @@ export default class View {
|
|
|
686
707
|
el.innerText = disableText
|
|
687
708
|
}
|
|
688
709
|
})
|
|
689
|
-
return [newRef, elements]
|
|
710
|
+
return [newRef, elements, opts]
|
|
690
711
|
}
|
|
691
712
|
|
|
692
713
|
componentID(el){
|
|
@@ -695,7 +716,9 @@ export default class View {
|
|
|
695
716
|
}
|
|
696
717
|
|
|
697
718
|
targetComponentID(target, targetCtx){
|
|
698
|
-
if(
|
|
719
|
+
if(isCid(targetCtx)){
|
|
720
|
+
return targetCtx
|
|
721
|
+
} else if(target.getAttribute(this.binding("target"))){
|
|
699
722
|
return this.closestComponentID(targetCtx)
|
|
700
723
|
} else {
|
|
701
724
|
return null
|
|
@@ -703,7 +726,9 @@ export default class View {
|
|
|
703
726
|
}
|
|
704
727
|
|
|
705
728
|
closestComponentID(targetCtx){
|
|
706
|
-
if(targetCtx){
|
|
729
|
+
if(isCid(targetCtx)){
|
|
730
|
+
return targetCtx
|
|
731
|
+
} else if(targetCtx){
|
|
707
732
|
return maybe(targetCtx.closest(`[${PHX_COMPONENT}]`), el => this.ownsElement(el) && this.componentID(el))
|
|
708
733
|
} else {
|
|
709
734
|
return null
|
|
@@ -715,8 +740,8 @@ export default class View {
|
|
|
715
740
|
this.log("hook", () => ["unable to push hook event. LiveView not connected", event, payload])
|
|
716
741
|
return false
|
|
717
742
|
}
|
|
718
|
-
let [ref, els] = this.putRef([], "hook")
|
|
719
|
-
this.pushWithReply(() => [ref, els], "event", {
|
|
743
|
+
let [ref, els, opts] = this.putRef([], "hook")
|
|
744
|
+
this.pushWithReply(() => [ref, els, opts], "event", {
|
|
720
745
|
type: "hook",
|
|
721
746
|
event: event,
|
|
722
747
|
value: payload,
|
|
@@ -726,40 +751,37 @@ export default class View {
|
|
|
726
751
|
return ref
|
|
727
752
|
}
|
|
728
753
|
|
|
729
|
-
extractMeta(el, meta){
|
|
754
|
+
extractMeta(el, meta, value){
|
|
730
755
|
let prefix = this.binding("value-")
|
|
731
756
|
for(let i = 0; i < el.attributes.length; i++){
|
|
757
|
+
if(!meta){ meta = {} }
|
|
732
758
|
let name = el.attributes[i].name
|
|
733
759
|
if(name.startsWith(prefix)){ meta[name.replace(prefix, "")] = el.getAttribute(name) }
|
|
734
760
|
}
|
|
735
761
|
if(el.value !== undefined){
|
|
762
|
+
if(!meta){ meta = {} }
|
|
736
763
|
meta.value = el.value
|
|
737
764
|
|
|
738
765
|
if(el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked){
|
|
739
766
|
delete meta.value
|
|
740
767
|
}
|
|
741
768
|
}
|
|
769
|
+
if(value){
|
|
770
|
+
if(!meta){ meta = {} }
|
|
771
|
+
for(let key in value){ meta[key] = value[key] }
|
|
772
|
+
}
|
|
742
773
|
return meta
|
|
743
774
|
}
|
|
744
775
|
|
|
745
|
-
pushEvent(type, el, targetCtx, phxEvent, meta){
|
|
746
|
-
this.pushWithReply(() => this.putRef([el], type), "event", {
|
|
776
|
+
pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}){
|
|
777
|
+
this.pushWithReply(() => this.putRef([el], type, opts), "event", {
|
|
747
778
|
type: type,
|
|
748
779
|
event: phxEvent,
|
|
749
|
-
value: this.extractMeta(el, meta),
|
|
780
|
+
value: this.extractMeta(el, meta, opts.value),
|
|
750
781
|
cid: this.targetComponentID(el, targetCtx)
|
|
751
782
|
})
|
|
752
783
|
}
|
|
753
784
|
|
|
754
|
-
pushKey(keyElement, targetCtx, kind, phxEvent, meta){
|
|
755
|
-
this.pushWithReply(() => this.putRef([keyElement], kind), "event", {
|
|
756
|
-
type: kind,
|
|
757
|
-
event: phxEvent,
|
|
758
|
-
value: this.extractMeta(keyElement, meta),
|
|
759
|
-
cid: this.targetComponentID(keyElement, targetCtx)
|
|
760
|
-
})
|
|
761
|
-
}
|
|
762
|
-
|
|
763
785
|
pushFileProgress(fileEl, entryRef, progress, onReply = function (){ }){
|
|
764
786
|
this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {
|
|
765
787
|
view.pushWithReply(null, "progress", {
|
|
@@ -772,12 +794,12 @@ export default class View {
|
|
|
772
794
|
})
|
|
773
795
|
}
|
|
774
796
|
|
|
775
|
-
pushInput(inputEl, targetCtx, forceCid, phxEvent,
|
|
797
|
+
pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback){
|
|
776
798
|
let uploads
|
|
777
799
|
let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx)
|
|
778
|
-
let refGenerator = () => this.putRef([inputEl, inputEl.form], "change")
|
|
779
|
-
let formData = serializeForm(inputEl.form, {_target:
|
|
780
|
-
if(inputEl.files && inputEl.files.length > 0){
|
|
800
|
+
let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts)
|
|
801
|
+
let formData = serializeForm(inputEl.form, {_target: opts._target})
|
|
802
|
+
if(DOM.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0){
|
|
781
803
|
LiveUploader.trackFiles(inputEl, Array.from(inputEl.files))
|
|
782
804
|
}
|
|
783
805
|
uploads = LiveUploader.serializeUploads(inputEl)
|
|
@@ -807,19 +829,19 @@ export default class View {
|
|
|
807
829
|
triggerAwaitingSubmit(formEl){
|
|
808
830
|
let awaitingSubmit = this.getScheduledSubmit(formEl)
|
|
809
831
|
if(awaitingSubmit){
|
|
810
|
-
let [_el, _ref, callback] = awaitingSubmit
|
|
832
|
+
let [_el, _ref, _opts, callback] = awaitingSubmit
|
|
811
833
|
this.cancelSubmit(formEl)
|
|
812
834
|
callback()
|
|
813
835
|
}
|
|
814
836
|
}
|
|
815
837
|
|
|
816
838
|
getScheduledSubmit(formEl){
|
|
817
|
-
return this.formSubmits.find(([el, _callback]) => el.isSameNode(formEl))
|
|
839
|
+
return this.formSubmits.find(([el, _ref, _opts, _callback]) => el.isSameNode(formEl))
|
|
818
840
|
}
|
|
819
841
|
|
|
820
|
-
scheduleSubmit(formEl, ref, callback){
|
|
842
|
+
scheduleSubmit(formEl, ref, opts, callback){
|
|
821
843
|
if(this.getScheduledSubmit(formEl)){ return true }
|
|
822
|
-
this.formSubmits.push([formEl, ref, callback])
|
|
844
|
+
this.formSubmits.push([formEl, ref, opts, callback])
|
|
823
845
|
}
|
|
824
846
|
|
|
825
847
|
cancelSubmit(formEl){
|
|
@@ -833,7 +855,7 @@ export default class View {
|
|
|
833
855
|
})
|
|
834
856
|
}
|
|
835
857
|
|
|
836
|
-
pushFormSubmit(formEl, targetCtx, phxEvent, onReply){
|
|
858
|
+
pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply){
|
|
837
859
|
let filterIgnored = el => {
|
|
838
860
|
let userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form)
|
|
839
861
|
return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form))
|
|
@@ -864,16 +886,17 @@ export default class View {
|
|
|
864
886
|
}
|
|
865
887
|
})
|
|
866
888
|
formEl.setAttribute(this.binding(PHX_PAGE_LOADING), "")
|
|
867
|
-
return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit")
|
|
889
|
+
return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts)
|
|
868
890
|
}
|
|
869
891
|
|
|
870
892
|
let cid = this.targetComponentID(formEl, targetCtx)
|
|
871
893
|
if(LiveUploader.hasUploadsInProgress(formEl)){
|
|
872
894
|
let [ref, _els] = refGenerator()
|
|
873
|
-
|
|
895
|
+
let push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply)
|
|
896
|
+
return this.scheduleSubmit(formEl, ref, opts, push)
|
|
874
897
|
} else if(LiveUploader.inputsAwaitingPreflight(formEl).length > 0){
|
|
875
898
|
let [ref, els] = refGenerator()
|
|
876
|
-
let proxyRefGen = () => [ref, els]
|
|
899
|
+
let proxyRefGen = () => [ref, els, opts]
|
|
877
900
|
this.uploadFiles(formEl, targetCtx, ref, cid, (_uploads) => {
|
|
878
901
|
let formData = serializeForm(formEl, {})
|
|
879
902
|
this.pushWithReply(proxyRefGen, "event", {
|
|
@@ -946,7 +969,8 @@ export default class View {
|
|
|
946
969
|
this.liveSocket.withinOwners(form, (view, targetCtx) => {
|
|
947
970
|
let input = form.elements[0]
|
|
948
971
|
let phxEvent = form.getAttribute(this.binding(PHX_AUTO_RECOVER)) || form.getAttribute(this.binding("change"))
|
|
949
|
-
|
|
972
|
+
|
|
973
|
+
JS.exec("change", phxEvent, view, input, ["push", {_target: input.name, newCid: newCid, callback: callback}])
|
|
950
974
|
})
|
|
951
975
|
}
|
|
952
976
|
|
|
@@ -955,15 +979,17 @@ export default class View {
|
|
|
955
979
|
let refGen = targetEl ? () => this.putRef([targetEl], "click") : null
|
|
956
980
|
|
|
957
981
|
this.pushWithReply(refGen, "live_patch", {url: href}, resp => {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
this.
|
|
982
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
983
|
+
if(resp.link_redirect){
|
|
984
|
+
this.liveSocket.replaceMain(href, null, callback, linkRef)
|
|
985
|
+
} else {
|
|
986
|
+
if(this.liveSocket.commitPendingLink(linkRef)){
|
|
987
|
+
this.href = href
|
|
988
|
+
}
|
|
989
|
+
this.applyPendingUpdates()
|
|
990
|
+
callback && callback(linkRef)
|
|
963
991
|
}
|
|
964
|
-
|
|
965
|
-
callback && callback(linkRef)
|
|
966
|
-
}
|
|
992
|
+
})
|
|
967
993
|
}).receive("timeout", () => this.liveSocket.redirect(window.location.href))
|
|
968
994
|
}
|
|
969
995
|
|
|
@@ -1023,10 +1049,10 @@ export default class View {
|
|
|
1023
1049
|
maybe(el.closest(PHX_VIEW_SELECTOR), node => node.id) === this.id
|
|
1024
1050
|
}
|
|
1025
1051
|
|
|
1026
|
-
submitForm(form, targetCtx, phxEvent){
|
|
1052
|
+
submitForm(form, targetCtx, phxEvent, opts = {}){
|
|
1027
1053
|
DOM.putPrivate(form, PHX_HAS_SUBMITTED, true)
|
|
1028
1054
|
this.liveSocket.blurActiveElement(this)
|
|
1029
|
-
this.pushFormSubmit(form, targetCtx, phxEvent, () => {
|
|
1055
|
+
this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
|
|
1030
1056
|
this.liveSocket.restorePreviouslyActiveFocus()
|
|
1031
1057
|
})
|
|
1032
1058
|
}
|
|
@@ -41,14 +41,14 @@ export default class ViewHook {
|
|
|
41
41
|
|
|
42
42
|
handleEvent(event, callback){
|
|
43
43
|
let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail)
|
|
44
|
-
window.addEventListener(`phx
|
|
44
|
+
window.addEventListener(`phx:${event}`, callbackRef)
|
|
45
45
|
this.__listeners.add(callbackRef)
|
|
46
46
|
return callbackRef
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
removeHandleEvent(callbackRef){
|
|
50
50
|
let event = callbackRef(null, true)
|
|
51
|
-
window.removeEventListener(`phx
|
|
51
|
+
window.removeEventListener(`phx:${event}`, callbackRef)
|
|
52
52
|
this.__listeners.delete(callbackRef)
|
|
53
53
|
}
|
|
54
54
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phoenix_live_view",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.2",
|
|
4
4
|
"description": "The Phoenix LiveView JavaScript client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "./priv/static/phoenix_live_view.esm.js",
|
|
7
|
+
"main": "./priv/static/phoenix_live_view.cjs.js",
|
|
7
8
|
"unpkg": "./priv/static/phoenix_live_view.min.js",
|
|
8
9
|
"jsdelivr": "./priv/static/phoenix_live_view.min.js",
|
|
9
10
|
"exports": {
|
|
10
|
-
"import": "./priv/static/phoenix_live_view.esm.js"
|
|
11
|
+
"import": "./priv/static/phoenix_live_view.esm.js",
|
|
12
|
+
"require": "./priv/static/phoenix_live_view.cjs.js"
|
|
11
13
|
},
|
|
12
14
|
"author": "Chris McCord <chris@chrismccord.com> (http://www.phoenixframework.org)",
|
|
13
15
|
"repository": {
|
|
@@ -21,4 +23,4 @@
|
|
|
21
23
|
"priv/static/*",
|
|
22
24
|
"assets/js/phoenix_live_view/*"
|
|
23
25
|
]
|
|
24
|
-
}
|
|
26
|
+
}
|