pyview-web 0.3.0__py3-none-any.whl → 0.8.0a2__py3-none-any.whl
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.
- pyview/__init__.py +16 -6
- pyview/assets/js/app.js +1 -0
- pyview/assets/js/uploaders.js +221 -0
- pyview/assets/package-lock.json +16 -14
- pyview/assets/package.json +2 -2
- pyview/async_stream_runner.py +2 -1
- pyview/auth/__init__.py +3 -1
- pyview/auth/provider.py +6 -6
- pyview/auth/required.py +7 -10
- pyview/binding/__init__.py +47 -0
- pyview/binding/binder.py +134 -0
- pyview/binding/context.py +33 -0
- pyview/binding/converters.py +191 -0
- pyview/binding/helpers.py +78 -0
- pyview/binding/injectables.py +119 -0
- pyview/binding/params.py +105 -0
- pyview/binding/result.py +32 -0
- pyview/changesets/__init__.py +2 -0
- pyview/changesets/changesets.py +8 -3
- pyview/cli/commands/create_view.py +4 -3
- pyview/cli/main.py +1 -1
- pyview/components/__init__.py +72 -0
- pyview/components/base.py +212 -0
- pyview/components/lifecycle.py +85 -0
- pyview/components/manager.py +366 -0
- pyview/components/renderer.py +14 -0
- pyview/components/slots.py +73 -0
- pyview/csrf.py +4 -2
- pyview/events/AutoEventDispatch.py +98 -0
- pyview/events/BaseEventHandler.py +51 -8
- pyview/events/__init__.py +2 -1
- pyview/instrumentation/__init__.py +3 -3
- pyview/instrumentation/interfaces.py +57 -33
- pyview/instrumentation/noop.py +21 -18
- pyview/js.py +20 -23
- pyview/live_routes.py +5 -3
- pyview/live_socket.py +167 -44
- pyview/live_view.py +24 -12
- pyview/meta.py +14 -2
- pyview/phx_message.py +7 -8
- pyview/playground/__init__.py +10 -0
- pyview/playground/builder.py +118 -0
- pyview/playground/favicon.py +39 -0
- pyview/pyview.py +54 -20
- pyview/session.py +2 -0
- pyview/static/assets/app.js +2088 -806
- pyview/static/assets/uploaders.js +221 -0
- pyview/stream.py +308 -0
- pyview/template/__init__.py +11 -1
- pyview/template/live_template.py +12 -8
- pyview/template/live_view_template.py +338 -0
- pyview/template/render_diff.py +33 -7
- pyview/template/root_template.py +21 -9
- pyview/template/serializer.py +2 -5
- pyview/template/template_view.py +170 -0
- pyview/template/utils.py +3 -2
- pyview/uploads.py +344 -55
- pyview/vendor/flet/pubsub/__init__.py +3 -1
- pyview/vendor/flet/pubsub/pub_sub.py +10 -18
- pyview/vendor/ibis/__init__.py +3 -7
- pyview/vendor/ibis/compiler.py +25 -32
- pyview/vendor/ibis/context.py +13 -15
- pyview/vendor/ibis/errors.py +0 -6
- pyview/vendor/ibis/filters.py +70 -76
- pyview/vendor/ibis/loaders.py +6 -7
- pyview/vendor/ibis/nodes.py +40 -42
- pyview/vendor/ibis/template.py +4 -5
- pyview/vendor/ibis/tree.py +62 -3
- pyview/vendor/ibis/utils.py +14 -15
- pyview/ws_handler.py +116 -86
- {pyview_web-0.3.0.dist-info → pyview_web-0.8.0a2.dist-info}/METADATA +39 -33
- pyview_web-0.8.0a2.dist-info/RECORD +80 -0
- pyview_web-0.8.0a2.dist-info/WHEEL +4 -0
- pyview_web-0.8.0a2.dist-info/entry_points.txt +3 -0
- pyview_web-0.3.0.dist-info/LICENSE +0 -21
- pyview_web-0.3.0.dist-info/RECORD +0 -58
- pyview_web-0.3.0.dist-info/WHEEL +0 -4
- pyview_web-0.3.0.dist-info/entry_points.txt +0 -3
pyview/static/assets/app.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
8
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
9
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -19,6 +21,19 @@
|
|
|
19
21
|
}
|
|
20
22
|
return a;
|
|
21
23
|
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __objRest = (source, exclude) => {
|
|
26
|
+
var target = {};
|
|
27
|
+
for (var prop in source)
|
|
28
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
if (source != null && __getOwnPropSymbols)
|
|
31
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
+
target[prop] = source[prop];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
};
|
|
22
37
|
var __commonJS = (cb, mod) => function __require() {
|
|
23
38
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
24
39
|
};
|
|
@@ -39,9 +54,9 @@
|
|
|
39
54
|
mod
|
|
40
55
|
));
|
|
41
56
|
|
|
42
|
-
//
|
|
57
|
+
// node_modules/nprogress/nprogress.js
|
|
43
58
|
var require_nprogress = __commonJS({
|
|
44
|
-
"
|
|
59
|
+
"node_modules/nprogress/nprogress.js"(exports, module) {
|
|
45
60
|
(function(root, factory) {
|
|
46
61
|
if (typeof define === "function" && define.amd) {
|
|
47
62
|
define(factory);
|
|
@@ -316,7 +331,7 @@
|
|
|
316
331
|
}
|
|
317
332
|
});
|
|
318
333
|
|
|
319
|
-
//
|
|
334
|
+
// node_modules/phoenix_html/priv/static/phoenix_html.js
|
|
320
335
|
(function() {
|
|
321
336
|
var PolyfillEvent = eventConstructor();
|
|
322
337
|
function eventConstructor() {
|
|
@@ -383,7 +398,7 @@
|
|
|
383
398
|
}, false);
|
|
384
399
|
})();
|
|
385
400
|
|
|
386
|
-
//
|
|
401
|
+
// node_modules/phoenix/priv/static/phoenix.mjs
|
|
387
402
|
var closure = (value) => {
|
|
388
403
|
if (typeof value === "function") {
|
|
389
404
|
return value;
|
|
@@ -396,7 +411,7 @@
|
|
|
396
411
|
};
|
|
397
412
|
var globalSelf = typeof self !== "undefined" ? self : null;
|
|
398
413
|
var phxWindow = typeof window !== "undefined" ? window : null;
|
|
399
|
-
var global = globalSelf || phxWindow ||
|
|
414
|
+
var global = globalSelf || phxWindow || globalThis;
|
|
400
415
|
var DEFAULT_VSN = "2.0.0";
|
|
401
416
|
var SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };
|
|
402
417
|
var DEFAULT_TIMEOUT = 1e4;
|
|
@@ -422,6 +437,7 @@
|
|
|
422
437
|
var XHR_STATES = {
|
|
423
438
|
complete: 4
|
|
424
439
|
};
|
|
440
|
+
var AUTH_TOKEN_PREFIX = "base64url.bearer.phx.";
|
|
425
441
|
var Push = class {
|
|
426
442
|
constructor(channel, event, payload, timeout) {
|
|
427
443
|
this.channel = channel;
|
|
@@ -435,11 +451,18 @@
|
|
|
435
451
|
this.recHooks = [];
|
|
436
452
|
this.sent = false;
|
|
437
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
*
|
|
456
|
+
* @param {number} timeout
|
|
457
|
+
*/
|
|
438
458
|
resend(timeout) {
|
|
439
459
|
this.timeout = timeout;
|
|
440
460
|
this.reset();
|
|
441
461
|
this.send();
|
|
442
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
*
|
|
465
|
+
*/
|
|
443
466
|
send() {
|
|
444
467
|
if (this.hasReceived("timeout")) {
|
|
445
468
|
return;
|
|
@@ -454,6 +477,11 @@
|
|
|
454
477
|
join_ref: this.channel.joinRef()
|
|
455
478
|
});
|
|
456
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
*
|
|
482
|
+
* @param {*} status
|
|
483
|
+
* @param {*} callback
|
|
484
|
+
*/
|
|
457
485
|
receive(status, callback) {
|
|
458
486
|
if (this.hasReceived(status)) {
|
|
459
487
|
callback(this.receivedResp.response);
|
|
@@ -461,6 +489,9 @@
|
|
|
461
489
|
this.recHooks.push({ status, callback });
|
|
462
490
|
return this;
|
|
463
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* @private
|
|
494
|
+
*/
|
|
464
495
|
reset() {
|
|
465
496
|
this.cancelRefEvent();
|
|
466
497
|
this.ref = null;
|
|
@@ -468,19 +499,31 @@
|
|
|
468
499
|
this.receivedResp = null;
|
|
469
500
|
this.sent = false;
|
|
470
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* @private
|
|
504
|
+
*/
|
|
471
505
|
matchReceive({ status, response, _ref }) {
|
|
472
506
|
this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));
|
|
473
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* @private
|
|
510
|
+
*/
|
|
474
511
|
cancelRefEvent() {
|
|
475
512
|
if (!this.refEvent) {
|
|
476
513
|
return;
|
|
477
514
|
}
|
|
478
515
|
this.channel.off(this.refEvent);
|
|
479
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* @private
|
|
519
|
+
*/
|
|
480
520
|
cancelTimeout() {
|
|
481
521
|
clearTimeout(this.timeoutTimer);
|
|
482
522
|
this.timeoutTimer = null;
|
|
483
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* @private
|
|
526
|
+
*/
|
|
484
527
|
startTimeout() {
|
|
485
528
|
if (this.timeoutTimer) {
|
|
486
529
|
this.cancelTimeout();
|
|
@@ -497,9 +540,15 @@
|
|
|
497
540
|
this.trigger("timeout", {});
|
|
498
541
|
}, this.timeout);
|
|
499
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* @private
|
|
545
|
+
*/
|
|
500
546
|
hasReceived(status) {
|
|
501
547
|
return this.receivedResp && this.receivedResp.status === status;
|
|
502
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* @private
|
|
551
|
+
*/
|
|
503
552
|
trigger(status, response) {
|
|
504
553
|
this.channel.trigger(this.refEvent, { status, response });
|
|
505
554
|
}
|
|
@@ -515,6 +564,9 @@
|
|
|
515
564
|
this.tries = 0;
|
|
516
565
|
clearTimeout(this.timer);
|
|
517
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Cancels any previous scheduleTimeout and schedules callback
|
|
569
|
+
*/
|
|
518
570
|
scheduleTimeout() {
|
|
519
571
|
clearTimeout(this.timer);
|
|
520
572
|
this.timer = setTimeout(() => {
|
|
@@ -542,12 +594,14 @@
|
|
|
542
594
|
}
|
|
543
595
|
}, this.socket.rejoinAfterMs);
|
|
544
596
|
this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));
|
|
545
|
-
this.stateChangeRefs.push(
|
|
546
|
-
this.
|
|
547
|
-
|
|
548
|
-
this.
|
|
549
|
-
|
|
550
|
-
|
|
597
|
+
this.stateChangeRefs.push(
|
|
598
|
+
this.socket.onOpen(() => {
|
|
599
|
+
this.rejoinTimer.reset();
|
|
600
|
+
if (this.isErrored()) {
|
|
601
|
+
this.rejoin();
|
|
602
|
+
}
|
|
603
|
+
})
|
|
604
|
+
);
|
|
551
605
|
this.joinPush.receive("ok", () => {
|
|
552
606
|
this.state = CHANNEL_STATES.joined;
|
|
553
607
|
this.rejoinTimer.reset();
|
|
@@ -593,6 +647,11 @@
|
|
|
593
647
|
this.trigger(this.replyEventName(ref), payload);
|
|
594
648
|
});
|
|
595
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* Join the channel
|
|
652
|
+
* @param {integer} timeout
|
|
653
|
+
* @returns {Push}
|
|
654
|
+
*/
|
|
596
655
|
join(timeout = this.timeout) {
|
|
597
656
|
if (this.joinedOnce) {
|
|
598
657
|
throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");
|
|
@@ -603,25 +662,87 @@
|
|
|
603
662
|
return this.joinPush;
|
|
604
663
|
}
|
|
605
664
|
}
|
|
665
|
+
/**
|
|
666
|
+
* Hook into channel close
|
|
667
|
+
* @param {Function} callback
|
|
668
|
+
*/
|
|
606
669
|
onClose(callback) {
|
|
607
670
|
this.on(CHANNEL_EVENTS.close, callback);
|
|
608
671
|
}
|
|
672
|
+
/**
|
|
673
|
+
* Hook into channel errors
|
|
674
|
+
* @param {Function} callback
|
|
675
|
+
*/
|
|
609
676
|
onError(callback) {
|
|
610
677
|
return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));
|
|
611
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* Subscribes on channel events
|
|
681
|
+
*
|
|
682
|
+
* Subscription returns a ref counter, which can be used later to
|
|
683
|
+
* unsubscribe the exact event listener
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* const ref1 = channel.on("event", do_stuff)
|
|
687
|
+
* const ref2 = channel.on("event", do_other_stuff)
|
|
688
|
+
* channel.off("event", ref1)
|
|
689
|
+
* // Since unsubscription, do_stuff won't fire,
|
|
690
|
+
* // while do_other_stuff will keep firing on the "event"
|
|
691
|
+
*
|
|
692
|
+
* @param {string} event
|
|
693
|
+
* @param {Function} callback
|
|
694
|
+
* @returns {integer} ref
|
|
695
|
+
*/
|
|
612
696
|
on(event, callback) {
|
|
613
697
|
let ref = this.bindingRef++;
|
|
614
698
|
this.bindings.push({ event, ref, callback });
|
|
615
699
|
return ref;
|
|
616
700
|
}
|
|
701
|
+
/**
|
|
702
|
+
* Unsubscribes off of channel events
|
|
703
|
+
*
|
|
704
|
+
* Use the ref returned from a channel.on() to unsubscribe one
|
|
705
|
+
* handler, or pass nothing for the ref to unsubscribe all
|
|
706
|
+
* handlers for the given event.
|
|
707
|
+
*
|
|
708
|
+
* @example
|
|
709
|
+
* // Unsubscribe the do_stuff handler
|
|
710
|
+
* const ref1 = channel.on("event", do_stuff)
|
|
711
|
+
* channel.off("event", ref1)
|
|
712
|
+
*
|
|
713
|
+
* // Unsubscribe all handlers from event
|
|
714
|
+
* channel.off("event")
|
|
715
|
+
*
|
|
716
|
+
* @param {string} event
|
|
717
|
+
* @param {integer} ref
|
|
718
|
+
*/
|
|
617
719
|
off(event, ref) {
|
|
618
720
|
this.bindings = this.bindings.filter((bind) => {
|
|
619
721
|
return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref));
|
|
620
722
|
});
|
|
621
723
|
}
|
|
724
|
+
/**
|
|
725
|
+
* @private
|
|
726
|
+
*/
|
|
622
727
|
canPush() {
|
|
623
728
|
return this.socket.isConnected() && this.isJoined();
|
|
624
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Sends a message `event` to phoenix with the payload `payload`.
|
|
732
|
+
* Phoenix receives this in the `handle_in(event, payload, socket)`
|
|
733
|
+
* function. if phoenix replies or it times out (default 10000ms),
|
|
734
|
+
* then optionally the reply can be received.
|
|
735
|
+
*
|
|
736
|
+
* @example
|
|
737
|
+
* channel.push("event")
|
|
738
|
+
* .receive("ok", payload => console.log("phoenix replied:", payload))
|
|
739
|
+
* .receive("error", err => console.log("phoenix errored", err))
|
|
740
|
+
* .receive("timeout", () => console.log("timed out pushing"))
|
|
741
|
+
* @param {string} event
|
|
742
|
+
* @param {Object} payload
|
|
743
|
+
* @param {number} [timeout]
|
|
744
|
+
* @returns {Push}
|
|
745
|
+
*/
|
|
625
746
|
push(event, payload, timeout = this.timeout) {
|
|
626
747
|
payload = payload || {};
|
|
627
748
|
if (!this.joinedOnce) {
|
|
@@ -638,6 +759,22 @@
|
|
|
638
759
|
}
|
|
639
760
|
return pushEvent;
|
|
640
761
|
}
|
|
762
|
+
/** Leaves the channel
|
|
763
|
+
*
|
|
764
|
+
* Unsubscribes from server events, and
|
|
765
|
+
* instructs channel to terminate on server
|
|
766
|
+
*
|
|
767
|
+
* Triggers onClose() hooks
|
|
768
|
+
*
|
|
769
|
+
* To receive leave acknowledgements, use the `receive`
|
|
770
|
+
* hook to bind to the server ack, ie:
|
|
771
|
+
*
|
|
772
|
+
* @example
|
|
773
|
+
* channel.leave().receive("ok", () => alert("left!") )
|
|
774
|
+
*
|
|
775
|
+
* @param {integer} timeout
|
|
776
|
+
* @returns {Push}
|
|
777
|
+
*/
|
|
641
778
|
leave(timeout = this.timeout) {
|
|
642
779
|
this.rejoinTimer.reset();
|
|
643
780
|
this.joinPush.cancelTimeout();
|
|
@@ -655,9 +792,24 @@
|
|
|
655
792
|
}
|
|
656
793
|
return leavePush;
|
|
657
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* Overridable message hook
|
|
797
|
+
*
|
|
798
|
+
* Receives all events for specialized message handling
|
|
799
|
+
* before dispatching to the channel callbacks.
|
|
800
|
+
*
|
|
801
|
+
* Must return the payload, modified or unmodified
|
|
802
|
+
* @param {string} event
|
|
803
|
+
* @param {Object} payload
|
|
804
|
+
* @param {integer} ref
|
|
805
|
+
* @returns {Object}
|
|
806
|
+
*/
|
|
658
807
|
onMessage(_event, payload, _ref) {
|
|
659
808
|
return payload;
|
|
660
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* @private
|
|
812
|
+
*/
|
|
661
813
|
isMember(topic, event, payload, joinRef) {
|
|
662
814
|
if (this.topic !== topic) {
|
|
663
815
|
return false;
|
|
@@ -670,9 +822,15 @@
|
|
|
670
822
|
return true;
|
|
671
823
|
}
|
|
672
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* @private
|
|
827
|
+
*/
|
|
673
828
|
joinRef() {
|
|
674
829
|
return this.joinPush.ref;
|
|
675
830
|
}
|
|
831
|
+
/**
|
|
832
|
+
* @private
|
|
833
|
+
*/
|
|
676
834
|
rejoin(timeout = this.timeout) {
|
|
677
835
|
if (this.isLeaving()) {
|
|
678
836
|
return;
|
|
@@ -681,6 +839,9 @@
|
|
|
681
839
|
this.state = CHANNEL_STATES.joining;
|
|
682
840
|
this.joinPush.resend(timeout);
|
|
683
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* @private
|
|
844
|
+
*/
|
|
684
845
|
trigger(event, payload, ref, joinRef) {
|
|
685
846
|
let handledPayload = this.onMessage(event, payload, ref, joinRef);
|
|
686
847
|
if (payload && !handledPayload) {
|
|
@@ -692,34 +853,77 @@
|
|
|
692
853
|
bind.callback(handledPayload, ref, joinRef || this.joinRef());
|
|
693
854
|
}
|
|
694
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* @private
|
|
858
|
+
*/
|
|
695
859
|
replyEventName(ref) {
|
|
696
860
|
return `chan_reply_${ref}`;
|
|
697
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* @private
|
|
864
|
+
*/
|
|
698
865
|
isClosed() {
|
|
699
866
|
return this.state === CHANNEL_STATES.closed;
|
|
700
867
|
}
|
|
868
|
+
/**
|
|
869
|
+
* @private
|
|
870
|
+
*/
|
|
701
871
|
isErrored() {
|
|
702
872
|
return this.state === CHANNEL_STATES.errored;
|
|
703
873
|
}
|
|
874
|
+
/**
|
|
875
|
+
* @private
|
|
876
|
+
*/
|
|
704
877
|
isJoined() {
|
|
705
878
|
return this.state === CHANNEL_STATES.joined;
|
|
706
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* @private
|
|
882
|
+
*/
|
|
707
883
|
isJoining() {
|
|
708
884
|
return this.state === CHANNEL_STATES.joining;
|
|
709
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* @private
|
|
888
|
+
*/
|
|
710
889
|
isLeaving() {
|
|
711
890
|
return this.state === CHANNEL_STATES.leaving;
|
|
712
891
|
}
|
|
713
892
|
};
|
|
714
893
|
var Ajax = class {
|
|
715
|
-
static request(method, endPoint,
|
|
894
|
+
static request(method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
716
895
|
if (global.XDomainRequest) {
|
|
717
896
|
let req = new global.XDomainRequest();
|
|
718
897
|
return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);
|
|
719
|
-
} else {
|
|
898
|
+
} else if (global.XMLHttpRequest) {
|
|
720
899
|
let req = new global.XMLHttpRequest();
|
|
721
|
-
return this.xhrRequest(req, method, endPoint,
|
|
900
|
+
return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback);
|
|
901
|
+
} else if (global.fetch && global.AbortController) {
|
|
902
|
+
return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback);
|
|
903
|
+
} else {
|
|
904
|
+
throw new Error("No suitable XMLHttpRequest implementation found");
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
908
|
+
let options = {
|
|
909
|
+
method,
|
|
910
|
+
headers,
|
|
911
|
+
body
|
|
912
|
+
};
|
|
913
|
+
let controller = null;
|
|
914
|
+
if (timeout) {
|
|
915
|
+
controller = new AbortController();
|
|
916
|
+
const _timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
917
|
+
options.signal = controller.signal;
|
|
722
918
|
}
|
|
919
|
+
global.fetch(endPoint, options).then((response) => response.text()).then((data) => this.parseJSON(data)).then((data) => callback && callback(data)).catch((err) => {
|
|
920
|
+
if (err.name === "AbortError" && ontimeout) {
|
|
921
|
+
ontimeout();
|
|
922
|
+
} else {
|
|
923
|
+
callback && callback(null);
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
return controller;
|
|
723
927
|
}
|
|
724
928
|
static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {
|
|
725
929
|
req.timeout = timeout;
|
|
@@ -736,10 +940,12 @@
|
|
|
736
940
|
req.send(body);
|
|
737
941
|
return req;
|
|
738
942
|
}
|
|
739
|
-
static xhrRequest(req, method, endPoint,
|
|
943
|
+
static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
740
944
|
req.open(method, endPoint, true);
|
|
741
945
|
req.timeout = timeout;
|
|
742
|
-
|
|
946
|
+
for (let [key, value] of Object.entries(headers)) {
|
|
947
|
+
req.setRequestHeader(key, value);
|
|
948
|
+
}
|
|
743
949
|
req.onerror = () => callback && callback(null);
|
|
744
950
|
req.onreadystatechange = () => {
|
|
745
951
|
if (req.readyState === XHR_STATES.complete && callback) {
|
|
@@ -788,12 +994,28 @@
|
|
|
788
994
|
return `${url}${prefix}${this.serialize(params)}`;
|
|
789
995
|
}
|
|
790
996
|
};
|
|
997
|
+
var arrayBufferToBase64 = (buffer) => {
|
|
998
|
+
let binary = "";
|
|
999
|
+
let bytes = new Uint8Array(buffer);
|
|
1000
|
+
let len = bytes.byteLength;
|
|
1001
|
+
for (let i = 0; i < len; i++) {
|
|
1002
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1003
|
+
}
|
|
1004
|
+
return btoa(binary);
|
|
1005
|
+
};
|
|
791
1006
|
var LongPoll = class {
|
|
792
|
-
constructor(endPoint) {
|
|
1007
|
+
constructor(endPoint, protocols) {
|
|
1008
|
+
if (protocols && protocols.length === 2 && protocols[1].startsWith(AUTH_TOKEN_PREFIX)) {
|
|
1009
|
+
this.authToken = atob(protocols[1].slice(AUTH_TOKEN_PREFIX.length));
|
|
1010
|
+
}
|
|
793
1011
|
this.endPoint = null;
|
|
794
1012
|
this.token = null;
|
|
795
1013
|
this.skipHeartbeat = true;
|
|
796
1014
|
this.reqs = /* @__PURE__ */ new Set();
|
|
1015
|
+
this.awaitingBatchAck = false;
|
|
1016
|
+
this.currentBatch = null;
|
|
1017
|
+
this.currentBatchTimer = null;
|
|
1018
|
+
this.batchBuffer = [];
|
|
797
1019
|
this.onopen = function() {
|
|
798
1020
|
};
|
|
799
1021
|
this.onerror = function() {
|
|
@@ -804,7 +1026,7 @@
|
|
|
804
1026
|
};
|
|
805
1027
|
this.pollEndpoint = this.normalizeEndpoint(endPoint);
|
|
806
1028
|
this.readyState = SOCKET_STATES.connecting;
|
|
807
|
-
this.poll();
|
|
1029
|
+
setTimeout(() => this.poll(), 0);
|
|
808
1030
|
}
|
|
809
1031
|
normalizeEndpoint(endPoint) {
|
|
810
1032
|
return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);
|
|
@@ -824,9 +1046,18 @@
|
|
|
824
1046
|
return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;
|
|
825
1047
|
}
|
|
826
1048
|
poll() {
|
|
827
|
-
|
|
1049
|
+
const headers = { "Accept": "application/json" };
|
|
1050
|
+
if (this.authToken) {
|
|
1051
|
+
headers["X-Phoenix-AuthToken"] = this.authToken;
|
|
1052
|
+
}
|
|
1053
|
+
this.ajax("GET", headers, null, () => this.ontimeout(), (resp) => {
|
|
828
1054
|
if (resp) {
|
|
829
1055
|
var { status, token, messages } = resp;
|
|
1056
|
+
if (status === 410 && this.token !== null) {
|
|
1057
|
+
this.onerror(410);
|
|
1058
|
+
this.closeAndRetry(3410, "session_gone", false);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
830
1061
|
this.token = token;
|
|
831
1062
|
} else {
|
|
832
1063
|
status = 0;
|
|
@@ -860,11 +1091,35 @@
|
|
|
860
1091
|
}
|
|
861
1092
|
});
|
|
862
1093
|
}
|
|
1094
|
+
// we collect all pushes within the current event loop by
|
|
1095
|
+
// setTimeout 0, which optimizes back-to-back procedural
|
|
1096
|
+
// pushes against an empty buffer
|
|
863
1097
|
send(body) {
|
|
864
|
-
|
|
1098
|
+
if (typeof body !== "string") {
|
|
1099
|
+
body = arrayBufferToBase64(body);
|
|
1100
|
+
}
|
|
1101
|
+
if (this.currentBatch) {
|
|
1102
|
+
this.currentBatch.push(body);
|
|
1103
|
+
} else if (this.awaitingBatchAck) {
|
|
1104
|
+
this.batchBuffer.push(body);
|
|
1105
|
+
} else {
|
|
1106
|
+
this.currentBatch = [body];
|
|
1107
|
+
this.currentBatchTimer = setTimeout(() => {
|
|
1108
|
+
this.batchSend(this.currentBatch);
|
|
1109
|
+
this.currentBatch = null;
|
|
1110
|
+
}, 0);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
batchSend(messages) {
|
|
1114
|
+
this.awaitingBatchAck = true;
|
|
1115
|
+
this.ajax("POST", { "Content-Type": "application/x-ndjson" }, messages.join("\n"), () => this.onerror("timeout"), (resp) => {
|
|
1116
|
+
this.awaitingBatchAck = false;
|
|
865
1117
|
if (!resp || resp.status !== 200) {
|
|
866
1118
|
this.onerror(resp && resp.status);
|
|
867
1119
|
this.closeAndRetry(1011, "internal server error", false);
|
|
1120
|
+
} else if (this.batchBuffer.length > 0) {
|
|
1121
|
+
this.batchSend(this.batchBuffer);
|
|
1122
|
+
this.batchBuffer = [];
|
|
868
1123
|
}
|
|
869
1124
|
});
|
|
870
1125
|
}
|
|
@@ -874,19 +1129,22 @@
|
|
|
874
1129
|
}
|
|
875
1130
|
this.readyState = SOCKET_STATES.closed;
|
|
876
1131
|
let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean });
|
|
1132
|
+
this.batchBuffer = [];
|
|
1133
|
+
clearTimeout(this.currentBatchTimer);
|
|
1134
|
+
this.currentBatchTimer = null;
|
|
877
1135
|
if (typeof CloseEvent !== "undefined") {
|
|
878
1136
|
this.onclose(new CloseEvent("close", opts));
|
|
879
1137
|
} else {
|
|
880
1138
|
this.onclose(opts);
|
|
881
1139
|
}
|
|
882
1140
|
}
|
|
883
|
-
ajax(method, body, onCallerTimeout, callback) {
|
|
1141
|
+
ajax(method, headers, body, onCallerTimeout, callback) {
|
|
884
1142
|
let req;
|
|
885
1143
|
let ontimeout = () => {
|
|
886
1144
|
this.reqs.delete(req);
|
|
887
1145
|
onCallerTimeout();
|
|
888
1146
|
};
|
|
889
|
-
req = Ajax.request(method, this.endpointURL(),
|
|
1147
|
+
req = Ajax.request(method, this.endpointURL(), headers, body, this.timeout, ontimeout, (resp) => {
|
|
890
1148
|
this.reqs.delete(req);
|
|
891
1149
|
if (this.isActive()) {
|
|
892
1150
|
callback(resp);
|
|
@@ -915,6 +1173,7 @@
|
|
|
915
1173
|
return callback({ join_ref, ref, topic, event, payload });
|
|
916
1174
|
}
|
|
917
1175
|
},
|
|
1176
|
+
// private
|
|
918
1177
|
binaryEncode(message) {
|
|
919
1178
|
let { join_ref, ref, event, topic, payload } = message;
|
|
920
1179
|
let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length;
|
|
@@ -998,14 +1257,21 @@
|
|
|
998
1257
|
this.channels = [];
|
|
999
1258
|
this.sendBuffer = [];
|
|
1000
1259
|
this.ref = 0;
|
|
1260
|
+
this.fallbackRef = null;
|
|
1001
1261
|
this.timeout = opts.timeout || DEFAULT_TIMEOUT;
|
|
1002
1262
|
this.transport = opts.transport || global.WebSocket || LongPoll;
|
|
1263
|
+
this.primaryPassedHealthCheck = false;
|
|
1264
|
+
this.longPollFallbackMs = opts.longPollFallbackMs;
|
|
1265
|
+
this.fallbackTimer = null;
|
|
1266
|
+
this.sessionStore = opts.sessionStorage || global && global.sessionStorage;
|
|
1003
1267
|
this.establishedConnections = 0;
|
|
1004
1268
|
this.defaultEncoder = serializer_default.encode.bind(serializer_default);
|
|
1005
1269
|
this.defaultDecoder = serializer_default.decode.bind(serializer_default);
|
|
1006
1270
|
this.closeWasClean = false;
|
|
1271
|
+
this.disconnecting = false;
|
|
1007
1272
|
this.binaryType = opts.binaryType || "arraybuffer";
|
|
1008
1273
|
this.connectClock = 1;
|
|
1274
|
+
this.pageHidden = false;
|
|
1009
1275
|
if (this.transport !== LongPoll) {
|
|
1010
1276
|
this.encode = opts.encode || this.defaultEncoder;
|
|
1011
1277
|
this.decode = opts.decode || this.defaultDecoder;
|
|
@@ -1027,6 +1293,16 @@
|
|
|
1027
1293
|
this.connect();
|
|
1028
1294
|
}
|
|
1029
1295
|
});
|
|
1296
|
+
phxWindow.addEventListener("visibilitychange", () => {
|
|
1297
|
+
if (document.visibilityState === "hidden") {
|
|
1298
|
+
this.pageHidden = true;
|
|
1299
|
+
} else {
|
|
1300
|
+
this.pageHidden = false;
|
|
1301
|
+
if (!this.isConnected()) {
|
|
1302
|
+
this.teardown(() => this.connect());
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
});
|
|
1030
1306
|
}
|
|
1031
1307
|
this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4;
|
|
1032
1308
|
this.rejoinAfterMs = (tries) => {
|
|
@@ -1044,6 +1320,11 @@
|
|
|
1044
1320
|
}
|
|
1045
1321
|
};
|
|
1046
1322
|
this.logger = opts.logger || null;
|
|
1323
|
+
if (!this.logger && opts.debug) {
|
|
1324
|
+
this.logger = (kind, msg, data) => {
|
|
1325
|
+
console.log(`${kind}: ${msg}`, data);
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1047
1328
|
this.longpollerTimeout = opts.longpollerTimeout || 2e4;
|
|
1048
1329
|
this.params = closure(opts.params || {});
|
|
1049
1330
|
this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;
|
|
@@ -1052,28 +1333,56 @@
|
|
|
1052
1333
|
this.heartbeatTimer = null;
|
|
1053
1334
|
this.pendingHeartbeatRef = null;
|
|
1054
1335
|
this.reconnectTimer = new Timer(() => {
|
|
1336
|
+
if (this.pageHidden) {
|
|
1337
|
+
this.log("Not reconnecting as page is hidden!");
|
|
1338
|
+
this.teardown();
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1055
1341
|
this.teardown(() => this.connect());
|
|
1056
1342
|
}, this.reconnectAfterMs);
|
|
1343
|
+
this.authToken = opts.authToken;
|
|
1057
1344
|
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Returns the LongPoll transport reference
|
|
1347
|
+
*/
|
|
1058
1348
|
getLongPollTransport() {
|
|
1059
1349
|
return LongPoll;
|
|
1060
1350
|
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Disconnects and replaces the active transport
|
|
1353
|
+
*
|
|
1354
|
+
* @param {Function} newTransport - The new transport class to instantiate
|
|
1355
|
+
*
|
|
1356
|
+
*/
|
|
1061
1357
|
replaceTransport(newTransport) {
|
|
1062
1358
|
this.connectClock++;
|
|
1063
1359
|
this.closeWasClean = true;
|
|
1360
|
+
clearTimeout(this.fallbackTimer);
|
|
1064
1361
|
this.reconnectTimer.reset();
|
|
1065
|
-
this.sendBuffer = [];
|
|
1066
1362
|
if (this.conn) {
|
|
1067
1363
|
this.conn.close();
|
|
1068
1364
|
this.conn = null;
|
|
1069
1365
|
}
|
|
1070
1366
|
this.transport = newTransport;
|
|
1071
1367
|
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Returns the socket protocol
|
|
1370
|
+
*
|
|
1371
|
+
* @returns {string}
|
|
1372
|
+
*/
|
|
1072
1373
|
protocol() {
|
|
1073
1374
|
return location.protocol.match(/^https/) ? "wss" : "ws";
|
|
1074
1375
|
}
|
|
1376
|
+
/**
|
|
1377
|
+
* The fully qualified socket url
|
|
1378
|
+
*
|
|
1379
|
+
* @returns {string}
|
|
1380
|
+
*/
|
|
1075
1381
|
endPointURL() {
|
|
1076
|
-
let uri = Ajax.appendParams(
|
|
1382
|
+
let uri = Ajax.appendParams(
|
|
1383
|
+
Ajax.appendParams(this.endPoint, this.params()),
|
|
1384
|
+
{ vsn: this.vsn }
|
|
1385
|
+
);
|
|
1077
1386
|
if (uri.charAt(0) !== "/") {
|
|
1078
1387
|
return uri;
|
|
1079
1388
|
}
|
|
@@ -1082,56 +1391,110 @@
|
|
|
1082
1391
|
}
|
|
1083
1392
|
return `${this.protocol()}://${location.host}${uri}`;
|
|
1084
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Disconnects the socket
|
|
1396
|
+
*
|
|
1397
|
+
* See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
|
|
1398
|
+
*
|
|
1399
|
+
* @param {Function} callback - Optional callback which is called after socket is disconnected.
|
|
1400
|
+
* @param {integer} code - A status code for disconnection (Optional).
|
|
1401
|
+
* @param {string} reason - A textual description of the reason to disconnect. (Optional)
|
|
1402
|
+
*/
|
|
1085
1403
|
disconnect(callback, code, reason) {
|
|
1086
1404
|
this.connectClock++;
|
|
1405
|
+
this.disconnecting = true;
|
|
1087
1406
|
this.closeWasClean = true;
|
|
1407
|
+
clearTimeout(this.fallbackTimer);
|
|
1088
1408
|
this.reconnectTimer.reset();
|
|
1089
|
-
this.teardown(
|
|
1090
|
-
|
|
1409
|
+
this.teardown(() => {
|
|
1410
|
+
this.disconnecting = false;
|
|
1411
|
+
callback && callback();
|
|
1412
|
+
}, code, reason);
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
*
|
|
1416
|
+
* @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
|
|
1417
|
+
*
|
|
1418
|
+
* Passing params to connect is deprecated; pass them in the Socket constructor instead:
|
|
1419
|
+
* `new Socket("/socket", {params: {user_id: userToken}})`.
|
|
1420
|
+
*/
|
|
1091
1421
|
connect(params) {
|
|
1092
1422
|
if (params) {
|
|
1093
1423
|
console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");
|
|
1094
1424
|
this.params = closure(params);
|
|
1095
1425
|
}
|
|
1096
|
-
if (this.conn) {
|
|
1426
|
+
if (this.conn && !this.disconnecting) {
|
|
1097
1427
|
return;
|
|
1098
1428
|
}
|
|
1099
|
-
this.
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
this.conn.onopen = () => this.onConnOpen();
|
|
1105
|
-
this.conn.onerror = (error) => this.onConnError(error);
|
|
1106
|
-
this.conn.onmessage = (event) => this.onConnMessage(event);
|
|
1107
|
-
this.conn.onclose = (event) => this.onConnClose(event);
|
|
1429
|
+
if (this.longPollFallbackMs && this.transport !== LongPoll) {
|
|
1430
|
+
this.connectWithFallback(LongPoll, this.longPollFallbackMs);
|
|
1431
|
+
} else {
|
|
1432
|
+
this.transportConnect();
|
|
1433
|
+
}
|
|
1108
1434
|
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Logs the message. Override `this.logger` for specialized logging. noops by default
|
|
1437
|
+
* @param {string} kind
|
|
1438
|
+
* @param {string} msg
|
|
1439
|
+
* @param {Object} data
|
|
1440
|
+
*/
|
|
1109
1441
|
log(kind, msg, data) {
|
|
1110
|
-
this.logger(kind, msg, data);
|
|
1442
|
+
this.logger && this.logger(kind, msg, data);
|
|
1111
1443
|
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Returns true if a logger has been set on this socket.
|
|
1446
|
+
*/
|
|
1112
1447
|
hasLogger() {
|
|
1113
1448
|
return this.logger !== null;
|
|
1114
1449
|
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Registers callbacks for connection open events
|
|
1452
|
+
*
|
|
1453
|
+
* @example socket.onOpen(function(){ console.info("the socket was opened") })
|
|
1454
|
+
*
|
|
1455
|
+
* @param {Function} callback
|
|
1456
|
+
*/
|
|
1115
1457
|
onOpen(callback) {
|
|
1116
1458
|
let ref = this.makeRef();
|
|
1117
1459
|
this.stateChangeCallbacks.open.push([ref, callback]);
|
|
1118
1460
|
return ref;
|
|
1119
1461
|
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Registers callbacks for connection close events
|
|
1464
|
+
* @param {Function} callback
|
|
1465
|
+
*/
|
|
1120
1466
|
onClose(callback) {
|
|
1121
1467
|
let ref = this.makeRef();
|
|
1122
1468
|
this.stateChangeCallbacks.close.push([ref, callback]);
|
|
1123
1469
|
return ref;
|
|
1124
1470
|
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Registers callbacks for connection error events
|
|
1473
|
+
*
|
|
1474
|
+
* @example socket.onError(function(error){ alert("An error occurred") })
|
|
1475
|
+
*
|
|
1476
|
+
* @param {Function} callback
|
|
1477
|
+
*/
|
|
1125
1478
|
onError(callback) {
|
|
1126
1479
|
let ref = this.makeRef();
|
|
1127
1480
|
this.stateChangeCallbacks.error.push([ref, callback]);
|
|
1128
1481
|
return ref;
|
|
1129
1482
|
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Registers callbacks for connection message events
|
|
1485
|
+
* @param {Function} callback
|
|
1486
|
+
*/
|
|
1130
1487
|
onMessage(callback) {
|
|
1131
1488
|
let ref = this.makeRef();
|
|
1132
1489
|
this.stateChangeCallbacks.message.push([ref, callback]);
|
|
1133
1490
|
return ref;
|
|
1134
1491
|
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Pings the server and invokes the callback with the RTT in milliseconds
|
|
1494
|
+
* @param {Function} callback
|
|
1495
|
+
*
|
|
1496
|
+
* Returns true if the ping was pushed or false if unable to be pushed.
|
|
1497
|
+
*/
|
|
1135
1498
|
ping(callback) {
|
|
1136
1499
|
if (!this.isConnected()) {
|
|
1137
1500
|
return false;
|
|
@@ -1147,20 +1510,92 @@
|
|
|
1147
1510
|
});
|
|
1148
1511
|
return true;
|
|
1149
1512
|
}
|
|
1513
|
+
/**
|
|
1514
|
+
* @private
|
|
1515
|
+
*/
|
|
1516
|
+
transportConnect() {
|
|
1517
|
+
this.connectClock++;
|
|
1518
|
+
this.closeWasClean = false;
|
|
1519
|
+
let protocols = void 0;
|
|
1520
|
+
if (this.authToken) {
|
|
1521
|
+
protocols = ["phoenix", `${AUTH_TOKEN_PREFIX}${btoa(this.authToken).replace(/=/g, "")}`];
|
|
1522
|
+
}
|
|
1523
|
+
this.conn = new this.transport(this.endPointURL(), protocols);
|
|
1524
|
+
this.conn.binaryType = this.binaryType;
|
|
1525
|
+
this.conn.timeout = this.longpollerTimeout;
|
|
1526
|
+
this.conn.onopen = () => this.onConnOpen();
|
|
1527
|
+
this.conn.onerror = (error) => this.onConnError(error);
|
|
1528
|
+
this.conn.onmessage = (event) => this.onConnMessage(event);
|
|
1529
|
+
this.conn.onclose = (event) => this.onConnClose(event);
|
|
1530
|
+
}
|
|
1531
|
+
getSession(key) {
|
|
1532
|
+
return this.sessionStore && this.sessionStore.getItem(key);
|
|
1533
|
+
}
|
|
1534
|
+
storeSession(key, val) {
|
|
1535
|
+
this.sessionStore && this.sessionStore.setItem(key, val);
|
|
1536
|
+
}
|
|
1537
|
+
connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {
|
|
1538
|
+
clearTimeout(this.fallbackTimer);
|
|
1539
|
+
let established = false;
|
|
1540
|
+
let primaryTransport = true;
|
|
1541
|
+
let openRef, errorRef;
|
|
1542
|
+
let fallback = (reason) => {
|
|
1543
|
+
this.log("transport", `falling back to ${fallbackTransport.name}...`, reason);
|
|
1544
|
+
this.off([openRef, errorRef]);
|
|
1545
|
+
primaryTransport = false;
|
|
1546
|
+
this.replaceTransport(fallbackTransport);
|
|
1547
|
+
this.transportConnect();
|
|
1548
|
+
};
|
|
1549
|
+
if (this.getSession(`phx:fallback:${fallbackTransport.name}`)) {
|
|
1550
|
+
return fallback("memorized");
|
|
1551
|
+
}
|
|
1552
|
+
this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
|
|
1553
|
+
errorRef = this.onError((reason) => {
|
|
1554
|
+
this.log("transport", "error", reason);
|
|
1555
|
+
if (primaryTransport && !established) {
|
|
1556
|
+
clearTimeout(this.fallbackTimer);
|
|
1557
|
+
fallback(reason);
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
if (this.fallbackRef) {
|
|
1561
|
+
this.off([this.fallbackRef]);
|
|
1562
|
+
}
|
|
1563
|
+
this.fallbackRef = this.onOpen(() => {
|
|
1564
|
+
established = true;
|
|
1565
|
+
if (!primaryTransport) {
|
|
1566
|
+
if (!this.primaryPassedHealthCheck) {
|
|
1567
|
+
this.storeSession(`phx:fallback:${fallbackTransport.name}`, "true");
|
|
1568
|
+
}
|
|
1569
|
+
return this.log("transport", `established ${fallbackTransport.name} fallback`);
|
|
1570
|
+
}
|
|
1571
|
+
clearTimeout(this.fallbackTimer);
|
|
1572
|
+
this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
|
|
1573
|
+
this.ping((rtt) => {
|
|
1574
|
+
this.log("transport", "connected to primary after", rtt);
|
|
1575
|
+
this.primaryPassedHealthCheck = true;
|
|
1576
|
+
clearTimeout(this.fallbackTimer);
|
|
1577
|
+
});
|
|
1578
|
+
});
|
|
1579
|
+
this.transportConnect();
|
|
1580
|
+
}
|
|
1150
1581
|
clearHeartbeats() {
|
|
1151
1582
|
clearTimeout(this.heartbeatTimer);
|
|
1152
1583
|
clearTimeout(this.heartbeatTimeoutTimer);
|
|
1153
1584
|
}
|
|
1154
1585
|
onConnOpen() {
|
|
1155
1586
|
if (this.hasLogger())
|
|
1156
|
-
this.log("transport",
|
|
1587
|
+
this.log("transport", `${this.transport.name} connected to ${this.endPointURL()}`);
|
|
1157
1588
|
this.closeWasClean = false;
|
|
1589
|
+
this.disconnecting = false;
|
|
1158
1590
|
this.establishedConnections++;
|
|
1159
1591
|
this.flushSendBuffer();
|
|
1160
1592
|
this.reconnectTimer.reset();
|
|
1161
1593
|
this.resetHeartbeat();
|
|
1162
1594
|
this.stateChangeCallbacks.open.forEach(([, callback]) => callback());
|
|
1163
1595
|
}
|
|
1596
|
+
/**
|
|
1597
|
+
* @private
|
|
1598
|
+
*/
|
|
1164
1599
|
heartbeatTimeout() {
|
|
1165
1600
|
if (this.pendingHeartbeatRef) {
|
|
1166
1601
|
this.pendingHeartbeatRef = null;
|
|
@@ -1184,7 +1619,11 @@
|
|
|
1184
1619
|
if (!this.conn) {
|
|
1185
1620
|
return callback && callback();
|
|
1186
1621
|
}
|
|
1622
|
+
let connectClock = this.connectClock;
|
|
1187
1623
|
this.waitForBufferDone(() => {
|
|
1624
|
+
if (connectClock !== this.connectClock) {
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1188
1627
|
if (this.conn) {
|
|
1189
1628
|
if (code) {
|
|
1190
1629
|
this.conn.close(code, reason || "");
|
|
@@ -1193,6 +1632,9 @@
|
|
|
1193
1632
|
}
|
|
1194
1633
|
}
|
|
1195
1634
|
this.waitForSocketClosed(() => {
|
|
1635
|
+
if (connectClock !== this.connectClock) {
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1196
1638
|
if (this.conn) {
|
|
1197
1639
|
this.conn.onopen = function() {
|
|
1198
1640
|
};
|
|
@@ -1227,6 +1669,9 @@
|
|
|
1227
1669
|
}, 150 * tries);
|
|
1228
1670
|
}
|
|
1229
1671
|
onConnClose(event) {
|
|
1672
|
+
if (this.conn)
|
|
1673
|
+
this.conn.onclose = () => {
|
|
1674
|
+
};
|
|
1230
1675
|
let closeCode = event && event.code;
|
|
1231
1676
|
if (this.hasLogger())
|
|
1232
1677
|
this.log("transport", "close", event);
|
|
@@ -1237,6 +1682,9 @@
|
|
|
1237
1682
|
}
|
|
1238
1683
|
this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));
|
|
1239
1684
|
}
|
|
1685
|
+
/**
|
|
1686
|
+
* @private
|
|
1687
|
+
*/
|
|
1240
1688
|
onConnError(error) {
|
|
1241
1689
|
if (this.hasLogger())
|
|
1242
1690
|
this.log("transport", error);
|
|
@@ -1249,6 +1697,9 @@
|
|
|
1249
1697
|
this.triggerChanError();
|
|
1250
1698
|
}
|
|
1251
1699
|
}
|
|
1700
|
+
/**
|
|
1701
|
+
* @private
|
|
1702
|
+
*/
|
|
1252
1703
|
triggerChanError() {
|
|
1253
1704
|
this.channels.forEach((channel) => {
|
|
1254
1705
|
if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {
|
|
@@ -1256,6 +1707,9 @@
|
|
|
1256
1707
|
}
|
|
1257
1708
|
});
|
|
1258
1709
|
}
|
|
1710
|
+
/**
|
|
1711
|
+
* @returns {string}
|
|
1712
|
+
*/
|
|
1259
1713
|
connectionState() {
|
|
1260
1714
|
switch (this.conn && this.conn.readyState) {
|
|
1261
1715
|
case SOCKET_STATES.connecting:
|
|
@@ -1268,13 +1722,27 @@
|
|
|
1268
1722
|
return "closed";
|
|
1269
1723
|
}
|
|
1270
1724
|
}
|
|
1725
|
+
/**
|
|
1726
|
+
* @returns {boolean}
|
|
1727
|
+
*/
|
|
1271
1728
|
isConnected() {
|
|
1272
1729
|
return this.connectionState() === "open";
|
|
1273
1730
|
}
|
|
1731
|
+
/**
|
|
1732
|
+
* @private
|
|
1733
|
+
*
|
|
1734
|
+
* @param {Channel}
|
|
1735
|
+
*/
|
|
1274
1736
|
remove(channel) {
|
|
1275
1737
|
this.off(channel.stateChangeRefs);
|
|
1276
|
-
this.channels = this.channels.filter((c) => c
|
|
1277
|
-
}
|
|
1738
|
+
this.channels = this.channels.filter((c) => c !== channel);
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
|
|
1742
|
+
*
|
|
1743
|
+
* @param {refs} - list of refs returned by calls to
|
|
1744
|
+
* `onOpen`, `onClose`, `onError,` and `onMessage`
|
|
1745
|
+
*/
|
|
1278
1746
|
off(refs) {
|
|
1279
1747
|
for (let key in this.stateChangeCallbacks) {
|
|
1280
1748
|
this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {
|
|
@@ -1282,11 +1750,21 @@
|
|
|
1282
1750
|
});
|
|
1283
1751
|
}
|
|
1284
1752
|
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Initiates a new channel for the given topic
|
|
1755
|
+
*
|
|
1756
|
+
* @param {string} topic
|
|
1757
|
+
* @param {Object} chanParams - Parameters for the channel
|
|
1758
|
+
* @returns {Channel}
|
|
1759
|
+
*/
|
|
1285
1760
|
channel(topic, chanParams = {}) {
|
|
1286
1761
|
let chan = new Channel(topic, chanParams, this);
|
|
1287
1762
|
this.channels.push(chan);
|
|
1288
1763
|
return chan;
|
|
1289
1764
|
}
|
|
1765
|
+
/**
|
|
1766
|
+
* @param {Object} data
|
|
1767
|
+
*/
|
|
1290
1768
|
push(data) {
|
|
1291
1769
|
if (this.hasLogger()) {
|
|
1292
1770
|
let { topic, event, payload, ref, join_ref } = data;
|
|
@@ -1298,6 +1776,10 @@
|
|
|
1298
1776
|
this.sendBuffer.push(() => this.encode(data, (result) => this.conn.send(result)));
|
|
1299
1777
|
}
|
|
1300
1778
|
}
|
|
1779
|
+
/**
|
|
1780
|
+
* Return the next message ref, accounting for overflows
|
|
1781
|
+
* @returns {string}
|
|
1782
|
+
*/
|
|
1301
1783
|
makeRef() {
|
|
1302
1784
|
let newRef = this.ref + 1;
|
|
1303
1785
|
if (newRef === this.ref) {
|
|
@@ -1354,7 +1836,7 @@
|
|
|
1354
1836
|
}
|
|
1355
1837
|
};
|
|
1356
1838
|
|
|
1357
|
-
//
|
|
1839
|
+
// node_modules/phoenix_live_view/priv/static/phoenix_live_view.esm.js
|
|
1358
1840
|
var CONSECUTIVE_RELOADS = "consecutive-reloads";
|
|
1359
1841
|
var MAX_RELOADS = 10;
|
|
1360
1842
|
var RELOAD_JITTER_MIN = 5e3;
|
|
@@ -1367,7 +1849,8 @@
|
|
|
1367
1849
|
"phx-keydown-loading",
|
|
1368
1850
|
"phx-keyup-loading",
|
|
1369
1851
|
"phx-blur-loading",
|
|
1370
|
-
"phx-focus-loading"
|
|
1852
|
+
"phx-focus-loading",
|
|
1853
|
+
"phx-hook-loading"
|
|
1371
1854
|
];
|
|
1372
1855
|
var PHX_COMPONENT = "data-phx-component";
|
|
1373
1856
|
var PHX_LIVE_LINK = "data-phx-link";
|
|
@@ -1383,17 +1866,23 @@
|
|
|
1383
1866
|
var PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";
|
|
1384
1867
|
var PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";
|
|
1385
1868
|
var PHX_SKIP = "data-phx-skip";
|
|
1869
|
+
var PHX_MAGIC_ID = "data-phx-id";
|
|
1386
1870
|
var PHX_PRUNE = "data-phx-prune";
|
|
1387
1871
|
var PHX_PAGE_LOADING = "page-loading";
|
|
1388
1872
|
var PHX_CONNECTED_CLASS = "phx-connected";
|
|
1389
|
-
var
|
|
1873
|
+
var PHX_LOADING_CLASS = "phx-loading";
|
|
1390
1874
|
var PHX_NO_FEEDBACK_CLASS = "phx-no-feedback";
|
|
1391
1875
|
var PHX_ERROR_CLASS = "phx-error";
|
|
1876
|
+
var PHX_CLIENT_ERROR_CLASS = "phx-client-error";
|
|
1877
|
+
var PHX_SERVER_ERROR_CLASS = "phx-server-error";
|
|
1392
1878
|
var PHX_PARENT_ID = "data-phx-parent-id";
|
|
1393
1879
|
var PHX_MAIN = "data-phx-main";
|
|
1394
1880
|
var PHX_ROOT_ID = "data-phx-root-id";
|
|
1881
|
+
var PHX_VIEWPORT_TOP = "viewport-top";
|
|
1882
|
+
var PHX_VIEWPORT_BOTTOM = "viewport-bottom";
|
|
1395
1883
|
var PHX_TRIGGER_ACTION = "trigger-action";
|
|
1396
1884
|
var PHX_FEEDBACK_FOR = "feedback-for";
|
|
1885
|
+
var PHX_FEEDBACK_GROUP = "feedback-group";
|
|
1397
1886
|
var PHX_HAS_FOCUSED = "phx-has-focused";
|
|
1398
1887
|
var FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url", "date", "time", "datetime-local", "color", "range"];
|
|
1399
1888
|
var CHECKABLE_INPUTS = ["checkbox", "radio"];
|
|
@@ -1410,6 +1899,8 @@
|
|
|
1410
1899
|
var PHX_DEBOUNCE = "debounce";
|
|
1411
1900
|
var PHX_THROTTLE = "throttle";
|
|
1412
1901
|
var PHX_UPDATE = "update";
|
|
1902
|
+
var PHX_STREAM = "stream";
|
|
1903
|
+
var PHX_STREAM_REF = "data-phx-stream";
|
|
1413
1904
|
var PHX_KEY = "key";
|
|
1414
1905
|
var PHX_PRIVATE = "phxPrivate";
|
|
1415
1906
|
var PHX_AUTO_RECOVER = "auto-recover";
|
|
@@ -1431,11 +1922,13 @@
|
|
|
1431
1922
|
};
|
|
1432
1923
|
var DYNAMICS = "d";
|
|
1433
1924
|
var STATIC = "s";
|
|
1925
|
+
var ROOT = "r";
|
|
1434
1926
|
var COMPONENTS = "c";
|
|
1435
1927
|
var EVENTS = "e";
|
|
1436
1928
|
var REPLY = "r";
|
|
1437
1929
|
var TITLE = "t";
|
|
1438
1930
|
var TEMPLATES = "p";
|
|
1931
|
+
var STREAM = "stream";
|
|
1439
1932
|
var EntryUploader = class {
|
|
1440
1933
|
constructor(entry, chunkSize, liveSocket2) {
|
|
1441
1934
|
this.liveSocket = liveSocket2;
|
|
@@ -1443,11 +1936,16 @@
|
|
|
1443
1936
|
this.offset = 0;
|
|
1444
1937
|
this.chunkSize = chunkSize;
|
|
1445
1938
|
this.chunkTimer = null;
|
|
1939
|
+
this.errored = false;
|
|
1446
1940
|
this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, { token: entry.metadata() });
|
|
1447
1941
|
}
|
|
1448
1942
|
error(reason) {
|
|
1449
|
-
|
|
1943
|
+
if (this.errored) {
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1450
1946
|
this.uploadChannel.leave();
|
|
1947
|
+
this.errored = true;
|
|
1948
|
+
clearTimeout(this.chunkTimer);
|
|
1451
1949
|
this.entry.error(reason);
|
|
1452
1950
|
}
|
|
1453
1951
|
upload() {
|
|
@@ -1479,7 +1977,7 @@
|
|
|
1479
1977
|
if (!this.isDone()) {
|
|
1480
1978
|
this.chunkTimer = setTimeout(() => this.readNextChunk(), this.liveSocket.getLatencySim() || 0);
|
|
1481
1979
|
}
|
|
1482
|
-
});
|
|
1980
|
+
}).receive("error", ({ reason }) => this.error(reason));
|
|
1483
1981
|
}
|
|
1484
1982
|
};
|
|
1485
1983
|
var logError = (msg, obj) => console.error && console.error(msg, obj);
|
|
@@ -1603,122 +2101,456 @@
|
|
|
1603
2101
|
}
|
|
1604
2102
|
};
|
|
1605
2103
|
var browser_default = Browser;
|
|
1606
|
-
var
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
2104
|
+
var ARIA = {
|
|
2105
|
+
focusMain() {
|
|
2106
|
+
let target = document.querySelector("main h1, main, h1");
|
|
2107
|
+
if (target) {
|
|
2108
|
+
let origTabIndex = target.tabIndex;
|
|
2109
|
+
target.tabIndex = -1;
|
|
2110
|
+
target.focus();
|
|
2111
|
+
target.tabIndex = origTabIndex;
|
|
1614
2112
|
}
|
|
1615
2113
|
},
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
2114
|
+
anyOf(instance, classes) {
|
|
2115
|
+
return classes.find((name) => instance instanceof name);
|
|
2116
|
+
},
|
|
2117
|
+
isFocusable(el, interactiveOnly) {
|
|
2118
|
+
return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, HTMLButtonElement]) || el instanceof HTMLIFrameElement || (el.tabIndex > 0 || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true");
|
|
2119
|
+
},
|
|
2120
|
+
attemptFocus(el, interactiveOnly) {
|
|
2121
|
+
if (this.isFocusable(el, interactiveOnly)) {
|
|
2122
|
+
try {
|
|
2123
|
+
el.focus();
|
|
2124
|
+
} catch (e) {
|
|
2125
|
+
}
|
|
1619
2126
|
}
|
|
1620
|
-
|
|
1621
|
-
return callback ? array.forEach(callback) : array;
|
|
2127
|
+
return !!document.activeElement && document.activeElement.isSameNode(el);
|
|
1622
2128
|
},
|
|
1623
|
-
|
|
1624
|
-
let
|
|
1625
|
-
|
|
1626
|
-
|
|
2129
|
+
focusFirstInteractive(el) {
|
|
2130
|
+
let child = el.firstElementChild;
|
|
2131
|
+
while (child) {
|
|
2132
|
+
if (this.attemptFocus(child, true) || this.focusFirstInteractive(child, true)) {
|
|
2133
|
+
return true;
|
|
2134
|
+
}
|
|
2135
|
+
child = child.nextElementSibling;
|
|
2136
|
+
}
|
|
1627
2137
|
},
|
|
1628
|
-
|
|
1629
|
-
|
|
2138
|
+
focusFirst(el) {
|
|
2139
|
+
let child = el.firstElementChild;
|
|
2140
|
+
while (child) {
|
|
2141
|
+
if (this.attemptFocus(child) || this.focusFirst(child)) {
|
|
2142
|
+
return true;
|
|
2143
|
+
}
|
|
2144
|
+
child = child.nextElementSibling;
|
|
2145
|
+
}
|
|
1630
2146
|
},
|
|
1631
|
-
|
|
1632
|
-
|
|
2147
|
+
focusLast(el) {
|
|
2148
|
+
let child = el.lastElementChild;
|
|
2149
|
+
while (child) {
|
|
2150
|
+
if (this.attemptFocus(child) || this.focusLast(child)) {
|
|
2151
|
+
return true;
|
|
2152
|
+
}
|
|
2153
|
+
child = child.previousElementSibling;
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
var aria_default = ARIA;
|
|
2158
|
+
var focusStack = [];
|
|
2159
|
+
var default_transition_time = 200;
|
|
2160
|
+
var JS = {
|
|
2161
|
+
exec(eventType, phxEvent, view, sourceEl, defaults) {
|
|
2162
|
+
let [defaultKind, defaultArgs] = defaults || [null, { callback: defaults && defaults.callback }];
|
|
2163
|
+
let commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];
|
|
2164
|
+
commands.forEach(([kind, args]) => {
|
|
2165
|
+
if (kind === defaultKind && defaultArgs.data) {
|
|
2166
|
+
args.data = Object.assign(args.data || {}, defaultArgs.data);
|
|
2167
|
+
args.callback = args.callback || defaultArgs.callback;
|
|
2168
|
+
}
|
|
2169
|
+
this.filterToEls(sourceEl, args).forEach((el) => {
|
|
2170
|
+
this[`exec_${kind}`](eventType, phxEvent, view, sourceEl, el, args);
|
|
2171
|
+
});
|
|
2172
|
+
});
|
|
1633
2173
|
},
|
|
1634
|
-
|
|
1635
|
-
return
|
|
2174
|
+
isVisible(el) {
|
|
2175
|
+
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);
|
|
1636
2176
|
},
|
|
1637
|
-
|
|
1638
|
-
|
|
2177
|
+
isInViewport(el) {
|
|
2178
|
+
const rect = el.getBoundingClientRect();
|
|
2179
|
+
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
2180
|
+
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
2181
|
+
return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;
|
|
1639
2182
|
},
|
|
1640
|
-
|
|
1641
|
-
let
|
|
1642
|
-
|
|
2183
|
+
exec_exec(eventType, phxEvent, view, sourceEl, el, { attr, to }) {
|
|
2184
|
+
let nodes = to ? dom_default.all(document, to) : [sourceEl];
|
|
2185
|
+
nodes.forEach((node) => {
|
|
2186
|
+
let encodedJS = node.getAttribute(attr);
|
|
2187
|
+
if (!encodedJS) {
|
|
2188
|
+
throw new Error(`expected ${attr} to contain JS command on "${to}"`);
|
|
2189
|
+
}
|
|
2190
|
+
view.liveSocket.execJS(node, encodedJS, eventType);
|
|
2191
|
+
});
|
|
1643
2192
|
},
|
|
1644
|
-
|
|
1645
|
-
|
|
2193
|
+
exec_dispatch(eventType, phxEvent, view, sourceEl, el, { to, event, detail, bubbles }) {
|
|
2194
|
+
detail = detail || {};
|
|
2195
|
+
detail.dispatcher = sourceEl;
|
|
2196
|
+
dom_default.dispatchEvent(el, event, { detail, bubbles });
|
|
1646
2197
|
},
|
|
1647
|
-
|
|
1648
|
-
let
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
return true;
|
|
2198
|
+
exec_push(eventType, phxEvent, view, sourceEl, el, args) {
|
|
2199
|
+
let { event, data, target, page_loading, loading, value, dispatcher, callback } = args;
|
|
2200
|
+
let pushOpts = { loading, value, target, page_loading: !!page_loading };
|
|
2201
|
+
let targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;
|
|
2202
|
+
let phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
|
|
2203
|
+
view.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
2204
|
+
if (!targetView.isConnected()) {
|
|
2205
|
+
return;
|
|
1656
2206
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
2207
|
+
if (eventType === "change") {
|
|
2208
|
+
let { newCid, _target } = args;
|
|
2209
|
+
_target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
|
|
2210
|
+
if (_target) {
|
|
2211
|
+
pushOpts._target = _target;
|
|
2212
|
+
}
|
|
2213
|
+
targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback);
|
|
2214
|
+
} else if (eventType === "submit") {
|
|
2215
|
+
let { submitter } = args;
|
|
2216
|
+
targetView.submitForm(sourceEl, targetCtx, event || phxEvent, submitter, pushOpts, callback);
|
|
2217
|
+
} else {
|
|
2218
|
+
targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data, pushOpts, callback);
|
|
1661
2219
|
}
|
|
1662
|
-
}
|
|
1663
|
-
return true;
|
|
2220
|
+
});
|
|
1664
2221
|
},
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
el.setAttribute(PHX_SESSION, "");
|
|
1668
|
-
}
|
|
1669
|
-
this.putPrivate(el, "destroyed", true);
|
|
2222
|
+
exec_navigate(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
2223
|
+
view.liveSocket.historyRedirect(href, replace ? "replace" : "push");
|
|
1670
2224
|
},
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
template.innerHTML = html;
|
|
1674
|
-
return this.findPhxChildren(template.content, parentId);
|
|
2225
|
+
exec_patch(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
2226
|
+
view.liveSocket.pushHistoryPatch(href, replace ? "replace" : "push", sourceEl);
|
|
1675
2227
|
},
|
|
1676
|
-
|
|
1677
|
-
|
|
2228
|
+
exec_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
2229
|
+
window.requestAnimationFrame(() => aria_default.attemptFocus(el));
|
|
1678
2230
|
},
|
|
1679
|
-
|
|
1680
|
-
|
|
2231
|
+
exec_focus_first(eventType, phxEvent, view, sourceEl, el) {
|
|
2232
|
+
window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el));
|
|
1681
2233
|
},
|
|
1682
|
-
|
|
1683
|
-
|
|
2234
|
+
exec_push_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
2235
|
+
window.requestAnimationFrame(() => focusStack.push(el || sourceEl));
|
|
1684
2236
|
},
|
|
1685
|
-
|
|
1686
|
-
|
|
2237
|
+
exec_pop_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
2238
|
+
window.requestAnimationFrame(() => {
|
|
2239
|
+
const el2 = focusStack.pop();
|
|
2240
|
+
if (el2) {
|
|
2241
|
+
el2.focus();
|
|
2242
|
+
}
|
|
2243
|
+
});
|
|
1687
2244
|
},
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
let parentCids = cids.reduce((acc, cid) => {
|
|
1691
|
-
let selector = `[${PHX_COMPONENT}="${cid}"] [${PHX_COMPONENT}]`;
|
|
1692
|
-
this.filterWithinSameLiveView(this.all(node, selector), node).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => acc.delete(childCID));
|
|
1693
|
-
return acc;
|
|
1694
|
-
}, initial);
|
|
1695
|
-
return parentCids.size === 0 ? new Set(cids) : parentCids;
|
|
2245
|
+
exec_add_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
|
|
2246
|
+
this.addOrRemoveClasses(el, names, [], transition, time, view);
|
|
1696
2247
|
},
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
return nodes.filter((el) => this.withinSameLiveView(el, parent));
|
|
1700
|
-
} else {
|
|
1701
|
-
return nodes;
|
|
1702
|
-
}
|
|
2248
|
+
exec_remove_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
|
|
2249
|
+
this.addOrRemoveClasses(el, [], names, transition, time, view);
|
|
1703
2250
|
},
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
if (
|
|
1710
|
-
|
|
2251
|
+
exec_toggle_class(eventType, phxEvent, view, sourceEl, el, { to, names, transition, time }) {
|
|
2252
|
+
this.toggleClasses(el, names, transition, time, view);
|
|
2253
|
+
},
|
|
2254
|
+
exec_toggle_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {
|
|
2255
|
+
if (el.hasAttribute(attr)) {
|
|
2256
|
+
if (val2 !== void 0) {
|
|
2257
|
+
if (el.getAttribute(attr) === val1) {
|
|
2258
|
+
this.setOrRemoveAttrs(el, [[attr, val2]], []);
|
|
2259
|
+
} else {
|
|
2260
|
+
this.setOrRemoveAttrs(el, [[attr, val1]], []);
|
|
2261
|
+
}
|
|
2262
|
+
} else {
|
|
2263
|
+
this.setOrRemoveAttrs(el, [], [attr]);
|
|
1711
2264
|
}
|
|
2265
|
+
} else {
|
|
2266
|
+
this.setOrRemoveAttrs(el, [[attr, val1]], []);
|
|
1712
2267
|
}
|
|
1713
2268
|
},
|
|
1714
|
-
|
|
1715
|
-
|
|
2269
|
+
exec_transition(eventType, phxEvent, view, sourceEl, el, { time, transition }) {
|
|
2270
|
+
this.addOrRemoveClasses(el, [], [], transition, time, view);
|
|
1716
2271
|
},
|
|
1717
|
-
|
|
1718
|
-
el
|
|
2272
|
+
exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time }) {
|
|
2273
|
+
this.toggle(eventType, view, el, display, ins, outs, time);
|
|
1719
2274
|
},
|
|
1720
|
-
|
|
1721
|
-
|
|
2275
|
+
exec_show(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
|
|
2276
|
+
this.show(eventType, view, el, display, transition, time);
|
|
2277
|
+
},
|
|
2278
|
+
exec_hide(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
|
|
2279
|
+
this.hide(eventType, view, el, display, transition, time);
|
|
2280
|
+
},
|
|
2281
|
+
exec_set_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
|
|
2282
|
+
this.setOrRemoveAttrs(el, [[attr, val]], []);
|
|
2283
|
+
},
|
|
2284
|
+
exec_remove_attr(eventType, phxEvent, view, sourceEl, el, { attr }) {
|
|
2285
|
+
this.setOrRemoveAttrs(el, [], [attr]);
|
|
2286
|
+
},
|
|
2287
|
+
show(eventType, view, el, display, transition, time) {
|
|
2288
|
+
if (!this.isVisible(el)) {
|
|
2289
|
+
this.toggle(eventType, view, el, display, transition, null, time);
|
|
2290
|
+
}
|
|
2291
|
+
},
|
|
2292
|
+
hide(eventType, view, el, display, transition, time) {
|
|
2293
|
+
if (this.isVisible(el)) {
|
|
2294
|
+
this.toggle(eventType, view, el, display, null, transition, time);
|
|
2295
|
+
}
|
|
2296
|
+
},
|
|
2297
|
+
toggle(eventType, view, el, display, ins, outs, time) {
|
|
2298
|
+
time = time || default_transition_time;
|
|
2299
|
+
let [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
|
|
2300
|
+
let [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
|
|
2301
|
+
if (inClasses.length > 0 || outClasses.length > 0) {
|
|
2302
|
+
if (this.isVisible(el)) {
|
|
2303
|
+
let onStart = () => {
|
|
2304
|
+
this.addOrRemoveClasses(el, outStartClasses, inClasses.concat(inStartClasses).concat(inEndClasses));
|
|
2305
|
+
window.requestAnimationFrame(() => {
|
|
2306
|
+
this.addOrRemoveClasses(el, outClasses, []);
|
|
2307
|
+
window.requestAnimationFrame(() => this.addOrRemoveClasses(el, outEndClasses, outStartClasses));
|
|
2308
|
+
});
|
|
2309
|
+
};
|
|
2310
|
+
el.dispatchEvent(new Event("phx:hide-start"));
|
|
2311
|
+
view.transition(time, onStart, () => {
|
|
2312
|
+
this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));
|
|
2313
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
|
|
2314
|
+
el.dispatchEvent(new Event("phx:hide-end"));
|
|
2315
|
+
});
|
|
2316
|
+
} else {
|
|
2317
|
+
if (eventType === "remove") {
|
|
2318
|
+
return;
|
|
2319
|
+
}
|
|
2320
|
+
let onStart = () => {
|
|
2321
|
+
this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses));
|
|
2322
|
+
let stickyDisplay = display || this.defaultDisplay(el);
|
|
2323
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
|
|
2324
|
+
window.requestAnimationFrame(() => {
|
|
2325
|
+
this.addOrRemoveClasses(el, inClasses, []);
|
|
2326
|
+
window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses));
|
|
2327
|
+
});
|
|
2328
|
+
};
|
|
2329
|
+
el.dispatchEvent(new Event("phx:show-start"));
|
|
2330
|
+
view.transition(time, onStart, () => {
|
|
2331
|
+
this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));
|
|
2332
|
+
el.dispatchEvent(new Event("phx:show-end"));
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
} else {
|
|
2336
|
+
if (this.isVisible(el)) {
|
|
2337
|
+
window.requestAnimationFrame(() => {
|
|
2338
|
+
el.dispatchEvent(new Event("phx:hide-start"));
|
|
2339
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
|
|
2340
|
+
el.dispatchEvent(new Event("phx:hide-end"));
|
|
2341
|
+
});
|
|
2342
|
+
} else {
|
|
2343
|
+
window.requestAnimationFrame(() => {
|
|
2344
|
+
el.dispatchEvent(new Event("phx:show-start"));
|
|
2345
|
+
let stickyDisplay = display || this.defaultDisplay(el);
|
|
2346
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
|
|
2347
|
+
el.dispatchEvent(new Event("phx:show-end"));
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
},
|
|
2352
|
+
toggleClasses(el, classes, transition, time, view) {
|
|
2353
|
+
window.requestAnimationFrame(() => {
|
|
2354
|
+
let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
|
|
2355
|
+
let newAdds = classes.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
|
|
2356
|
+
let newRemoves = classes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
|
|
2357
|
+
this.addOrRemoveClasses(el, newAdds, newRemoves, transition, time, view);
|
|
2358
|
+
});
|
|
2359
|
+
},
|
|
2360
|
+
addOrRemoveClasses(el, adds, removes, transition, time, view) {
|
|
2361
|
+
time = time || default_transition_time;
|
|
2362
|
+
let [transitionRun, transitionStart, transitionEnd] = transition || [[], [], []];
|
|
2363
|
+
if (transitionRun.length > 0) {
|
|
2364
|
+
let onStart = () => {
|
|
2365
|
+
this.addOrRemoveClasses(el, transitionStart, [].concat(transitionRun).concat(transitionEnd));
|
|
2366
|
+
window.requestAnimationFrame(() => {
|
|
2367
|
+
this.addOrRemoveClasses(el, transitionRun, []);
|
|
2368
|
+
window.requestAnimationFrame(() => this.addOrRemoveClasses(el, transitionEnd, transitionStart));
|
|
2369
|
+
});
|
|
2370
|
+
};
|
|
2371
|
+
let onDone = () => this.addOrRemoveClasses(el, adds.concat(transitionEnd), removes.concat(transitionRun).concat(transitionStart));
|
|
2372
|
+
return view.transition(time, onStart, onDone);
|
|
2373
|
+
}
|
|
2374
|
+
window.requestAnimationFrame(() => {
|
|
2375
|
+
let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
|
|
2376
|
+
let keepAdds = adds.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
|
|
2377
|
+
let keepRemoves = removes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
|
|
2378
|
+
let newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);
|
|
2379
|
+
let newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);
|
|
2380
|
+
dom_default.putSticky(el, "classes", (currentEl) => {
|
|
2381
|
+
currentEl.classList.remove(...newRemoves);
|
|
2382
|
+
currentEl.classList.add(...newAdds);
|
|
2383
|
+
return [newAdds, newRemoves];
|
|
2384
|
+
});
|
|
2385
|
+
});
|
|
2386
|
+
},
|
|
2387
|
+
setOrRemoveAttrs(el, sets, removes) {
|
|
2388
|
+
let [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);
|
|
2389
|
+
let alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);
|
|
2390
|
+
let newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);
|
|
2391
|
+
let newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes);
|
|
2392
|
+
dom_default.putSticky(el, "attrs", (currentEl) => {
|
|
2393
|
+
newRemoves.forEach((attr) => currentEl.removeAttribute(attr));
|
|
2394
|
+
newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val));
|
|
2395
|
+
return [newSets, newRemoves];
|
|
2396
|
+
});
|
|
2397
|
+
},
|
|
2398
|
+
hasAllClasses(el, classes) {
|
|
2399
|
+
return classes.every((name) => el.classList.contains(name));
|
|
2400
|
+
},
|
|
2401
|
+
isToggledOut(el, outClasses) {
|
|
2402
|
+
return !this.isVisible(el) || this.hasAllClasses(el, outClasses);
|
|
2403
|
+
},
|
|
2404
|
+
filterToEls(sourceEl, { to }) {
|
|
2405
|
+
return to ? dom_default.all(document, to) : [sourceEl];
|
|
2406
|
+
},
|
|
2407
|
+
defaultDisplay(el) {
|
|
2408
|
+
return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";
|
|
2409
|
+
}
|
|
2410
|
+
};
|
|
2411
|
+
var js_default = JS;
|
|
2412
|
+
var DOM = {
|
|
2413
|
+
byId(id) {
|
|
2414
|
+
return document.getElementById(id) || logError(`no id found for ${id}`);
|
|
2415
|
+
},
|
|
2416
|
+
removeClass(el, className) {
|
|
2417
|
+
el.classList.remove(className);
|
|
2418
|
+
if (el.classList.length === 0) {
|
|
2419
|
+
el.removeAttribute("class");
|
|
2420
|
+
}
|
|
2421
|
+
},
|
|
2422
|
+
all(node, query, callback) {
|
|
2423
|
+
if (!node) {
|
|
2424
|
+
return [];
|
|
2425
|
+
}
|
|
2426
|
+
let array = Array.from(node.querySelectorAll(query));
|
|
2427
|
+
return callback ? array.forEach(callback) : array;
|
|
2428
|
+
},
|
|
2429
|
+
childNodeLength(html) {
|
|
2430
|
+
let template = document.createElement("template");
|
|
2431
|
+
template.innerHTML = html;
|
|
2432
|
+
return template.content.childElementCount;
|
|
2433
|
+
},
|
|
2434
|
+
isUploadInput(el) {
|
|
2435
|
+
return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null;
|
|
2436
|
+
},
|
|
2437
|
+
isAutoUpload(inputEl) {
|
|
2438
|
+
return inputEl.hasAttribute("data-phx-auto-upload");
|
|
2439
|
+
},
|
|
2440
|
+
findUploadInputs(node) {
|
|
2441
|
+
const formId = node.id;
|
|
2442
|
+
const inputsOutsideForm = this.all(document, `input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`);
|
|
2443
|
+
return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(inputsOutsideForm);
|
|
2444
|
+
},
|
|
2445
|
+
findComponentNodeList(node, cid) {
|
|
2446
|
+
return this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node);
|
|
2447
|
+
},
|
|
2448
|
+
isPhxDestroyed(node) {
|
|
2449
|
+
return node.id && DOM.private(node, "destroyed") ? true : false;
|
|
2450
|
+
},
|
|
2451
|
+
wantsNewTab(e) {
|
|
2452
|
+
let wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;
|
|
2453
|
+
let isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");
|
|
2454
|
+
let isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";
|
|
2455
|
+
let isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");
|
|
2456
|
+
return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;
|
|
2457
|
+
},
|
|
2458
|
+
isUnloadableFormSubmit(e) {
|
|
2459
|
+
let isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";
|
|
2460
|
+
if (isDialogSubmit) {
|
|
2461
|
+
return false;
|
|
2462
|
+
} else {
|
|
2463
|
+
return !e.defaultPrevented && !this.wantsNewTab(e);
|
|
2464
|
+
}
|
|
2465
|
+
},
|
|
2466
|
+
isNewPageClick(e, currentLocation) {
|
|
2467
|
+
let href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;
|
|
2468
|
+
let url;
|
|
2469
|
+
if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {
|
|
2470
|
+
return false;
|
|
2471
|
+
}
|
|
2472
|
+
if (href.startsWith("mailto:") || href.startsWith("tel:")) {
|
|
2473
|
+
return false;
|
|
2474
|
+
}
|
|
2475
|
+
if (e.target.isContentEditable) {
|
|
2476
|
+
return false;
|
|
2477
|
+
}
|
|
2478
|
+
try {
|
|
2479
|
+
url = new URL(href);
|
|
2480
|
+
} catch (e2) {
|
|
2481
|
+
try {
|
|
2482
|
+
url = new URL(href, currentLocation);
|
|
2483
|
+
} catch (e3) {
|
|
2484
|
+
return true;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) {
|
|
2488
|
+
if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) {
|
|
2489
|
+
return url.hash === "" && !url.href.endsWith("#");
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
return url.protocol.startsWith("http");
|
|
2493
|
+
},
|
|
2494
|
+
markPhxChildDestroyed(el) {
|
|
2495
|
+
if (this.isPhxChild(el)) {
|
|
2496
|
+
el.setAttribute(PHX_SESSION, "");
|
|
2497
|
+
}
|
|
2498
|
+
this.putPrivate(el, "destroyed", true);
|
|
2499
|
+
},
|
|
2500
|
+
findPhxChildrenInFragment(html, parentId) {
|
|
2501
|
+
let template = document.createElement("template");
|
|
2502
|
+
template.innerHTML = html;
|
|
2503
|
+
return this.findPhxChildren(template.content, parentId);
|
|
2504
|
+
},
|
|
2505
|
+
isIgnored(el, phxUpdate) {
|
|
2506
|
+
return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore";
|
|
2507
|
+
},
|
|
2508
|
+
isPhxUpdate(el, phxUpdate, updateTypes) {
|
|
2509
|
+
return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0;
|
|
2510
|
+
},
|
|
2511
|
+
findPhxSticky(el) {
|
|
2512
|
+
return this.all(el, `[${PHX_STICKY}]`);
|
|
2513
|
+
},
|
|
2514
|
+
findPhxChildren(el, parentId) {
|
|
2515
|
+
return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`);
|
|
2516
|
+
},
|
|
2517
|
+
findExistingParentCIDs(node, cids) {
|
|
2518
|
+
let parentCids = /* @__PURE__ */ new Set();
|
|
2519
|
+
let childrenCids = /* @__PURE__ */ new Set();
|
|
2520
|
+
cids.forEach((cid) => {
|
|
2521
|
+
this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node).forEach((parent) => {
|
|
2522
|
+
parentCids.add(cid);
|
|
2523
|
+
this.all(parent, `[${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));
|
|
2524
|
+
});
|
|
2525
|
+
});
|
|
2526
|
+
childrenCids.forEach((childCid) => parentCids.delete(childCid));
|
|
2527
|
+
return parentCids;
|
|
2528
|
+
},
|
|
2529
|
+
filterWithinSameLiveView(nodes, parent) {
|
|
2530
|
+
if (parent.querySelector(PHX_VIEW_SELECTOR)) {
|
|
2531
|
+
return nodes.filter((el) => this.withinSameLiveView(el, parent));
|
|
2532
|
+
} else {
|
|
2533
|
+
return nodes;
|
|
2534
|
+
}
|
|
2535
|
+
},
|
|
2536
|
+
withinSameLiveView(node, parent) {
|
|
2537
|
+
while (node = node.parentNode) {
|
|
2538
|
+
if (node.isSameNode(parent)) {
|
|
2539
|
+
return true;
|
|
2540
|
+
}
|
|
2541
|
+
if (node.getAttribute(PHX_SESSION) !== null) {
|
|
2542
|
+
return false;
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
},
|
|
2546
|
+
private(el, key) {
|
|
2547
|
+
return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];
|
|
2548
|
+
},
|
|
2549
|
+
deletePrivate(el, key) {
|
|
2550
|
+
el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key];
|
|
2551
|
+
},
|
|
2552
|
+
putPrivate(el, key, value) {
|
|
2553
|
+
if (!el[PHX_PRIVATE]) {
|
|
1722
2554
|
el[PHX_PRIVATE] = {};
|
|
1723
2555
|
}
|
|
1724
2556
|
el[PHX_PRIVATE][key] = value;
|
|
@@ -1760,7 +2592,11 @@
|
|
|
1760
2592
|
return callback();
|
|
1761
2593
|
case "blur":
|
|
1762
2594
|
if (this.once(el, "debounce-blur")) {
|
|
1763
|
-
el.addEventListener("blur", () =>
|
|
2595
|
+
el.addEventListener("blur", () => {
|
|
2596
|
+
if (asyncFilter()) {
|
|
2597
|
+
callback();
|
|
2598
|
+
}
|
|
2599
|
+
});
|
|
1764
2600
|
}
|
|
1765
2601
|
return;
|
|
1766
2602
|
default:
|
|
@@ -1781,12 +2617,12 @@
|
|
|
1781
2617
|
return false;
|
|
1782
2618
|
} else {
|
|
1783
2619
|
callback();
|
|
1784
|
-
|
|
1785
|
-
setTimeout(() => {
|
|
2620
|
+
const t = setTimeout(() => {
|
|
1786
2621
|
if (asyncFilter()) {
|
|
1787
2622
|
this.triggerCycle(el, DEBOUNCE_TRIGGER);
|
|
1788
2623
|
}
|
|
1789
2624
|
}, timeout);
|
|
2625
|
+
this.putPrivate(el, THROTTLED, t);
|
|
1790
2626
|
}
|
|
1791
2627
|
} else {
|
|
1792
2628
|
setTimeout(() => {
|
|
@@ -1806,7 +2642,10 @@
|
|
|
1806
2642
|
});
|
|
1807
2643
|
}
|
|
1808
2644
|
if (this.once(el, "bind-debounce")) {
|
|
1809
|
-
el.addEventListener("blur", () =>
|
|
2645
|
+
el.addEventListener("blur", () => {
|
|
2646
|
+
clearTimeout(this.private(el, THROTTLED));
|
|
2647
|
+
this.triggerCycle(el, DEBOUNCE_TRIGGER);
|
|
2648
|
+
});
|
|
1810
2649
|
}
|
|
1811
2650
|
}
|
|
1812
2651
|
},
|
|
@@ -1834,20 +2673,72 @@
|
|
|
1834
2673
|
this.putPrivate(el, key, [currentCycle, trigger]);
|
|
1835
2674
|
return currentCycle;
|
|
1836
2675
|
},
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
if (!input) {
|
|
1841
|
-
return;
|
|
2676
|
+
maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom) {
|
|
2677
|
+
if (el.hasAttribute && (el.hasAttribute(phxViewportTop) || el.hasAttribute(phxViewportBottom))) {
|
|
2678
|
+
el.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll");
|
|
1842
2679
|
}
|
|
1843
|
-
|
|
1844
|
-
|
|
2680
|
+
},
|
|
2681
|
+
isFeedbackContainer(el, phxFeedbackFor) {
|
|
2682
|
+
return el.hasAttribute && el.hasAttribute(phxFeedbackFor);
|
|
2683
|
+
},
|
|
2684
|
+
maybeHideFeedback(container, feedbackContainers, phxFeedbackFor, phxFeedbackGroup) {
|
|
2685
|
+
const feedbackResults = {};
|
|
2686
|
+
feedbackContainers.forEach((el) => {
|
|
2687
|
+
if (!container.contains(el))
|
|
2688
|
+
return;
|
|
2689
|
+
const feedback = el.getAttribute(phxFeedbackFor);
|
|
2690
|
+
if (!feedback) {
|
|
2691
|
+
js_default.addOrRemoveClasses(el, [], [PHX_NO_FEEDBACK_CLASS]);
|
|
2692
|
+
return;
|
|
2693
|
+
}
|
|
2694
|
+
if (feedbackResults[feedback] === true) {
|
|
2695
|
+
this.hideFeedback(el);
|
|
2696
|
+
return;
|
|
2697
|
+
}
|
|
2698
|
+
feedbackResults[feedback] = this.shouldHideFeedback(container, feedback, phxFeedbackGroup);
|
|
2699
|
+
if (feedbackResults[feedback] === true) {
|
|
2700
|
+
this.hideFeedback(el);
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
},
|
|
2704
|
+
hideFeedback(container) {
|
|
2705
|
+
js_default.addOrRemoveClasses(container, [PHX_NO_FEEDBACK_CLASS], []);
|
|
2706
|
+
},
|
|
2707
|
+
shouldHideFeedback(container, nameOrGroup, phxFeedbackGroup) {
|
|
2708
|
+
const query = `[name="${nameOrGroup}"],
|
|
2709
|
+
[name="${nameOrGroup}[]"],
|
|
2710
|
+
[${phxFeedbackGroup}="${nameOrGroup}"]`;
|
|
2711
|
+
let focused = false;
|
|
2712
|
+
DOM.all(container, query, (input) => {
|
|
2713
|
+
if (this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED)) {
|
|
2714
|
+
focused = true;
|
|
2715
|
+
}
|
|
2716
|
+
});
|
|
2717
|
+
return !focused;
|
|
2718
|
+
},
|
|
2719
|
+
feedbackSelector(input, phxFeedbackFor, phxFeedbackGroup) {
|
|
2720
|
+
let query = `[${phxFeedbackFor}="${input.name}"],
|
|
2721
|
+
[${phxFeedbackFor}="${input.name.replace(/\[\]$/, "")}"]`;
|
|
2722
|
+
if (input.getAttribute(phxFeedbackGroup)) {
|
|
2723
|
+
query += `,[${phxFeedbackFor}="${input.getAttribute(phxFeedbackGroup)}"]`;
|
|
1845
2724
|
}
|
|
2725
|
+
return query;
|
|
2726
|
+
},
|
|
2727
|
+
resetForm(form, phxFeedbackFor, phxFeedbackGroup) {
|
|
2728
|
+
Array.from(form.elements).forEach((input) => {
|
|
2729
|
+
let query = this.feedbackSelector(input, phxFeedbackFor, phxFeedbackGroup);
|
|
2730
|
+
this.deletePrivate(input, PHX_HAS_FOCUSED);
|
|
2731
|
+
this.deletePrivate(input, PHX_HAS_SUBMITTED);
|
|
2732
|
+
this.all(document, query, (feedbackEl) => {
|
|
2733
|
+
js_default.addOrRemoveClasses(feedbackEl, [PHX_NO_FEEDBACK_CLASS], []);
|
|
2734
|
+
});
|
|
2735
|
+
});
|
|
1846
2736
|
},
|
|
1847
|
-
showError(inputEl, phxFeedbackFor) {
|
|
1848
|
-
if (inputEl.
|
|
1849
|
-
this.
|
|
1850
|
-
|
|
2737
|
+
showError(inputEl, phxFeedbackFor, phxFeedbackGroup) {
|
|
2738
|
+
if (inputEl.name) {
|
|
2739
|
+
let query = this.feedbackSelector(inputEl, phxFeedbackFor, phxFeedbackGroup);
|
|
2740
|
+
this.all(document, query, (el) => {
|
|
2741
|
+
js_default.addOrRemoveClasses(el, [], [PHX_NO_FEEDBACK_CLASS]);
|
|
1851
2742
|
});
|
|
1852
2743
|
}
|
|
1853
2744
|
},
|
|
@@ -1857,11 +2748,19 @@
|
|
|
1857
2748
|
isPhxSticky(node) {
|
|
1858
2749
|
return node.getAttribute && node.getAttribute(PHX_STICKY) !== null;
|
|
1859
2750
|
},
|
|
2751
|
+
isChildOfAny(el, parents) {
|
|
2752
|
+
return !!parents.find((parent) => parent.contains(el));
|
|
2753
|
+
},
|
|
1860
2754
|
firstPhxChild(el) {
|
|
1861
2755
|
return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];
|
|
1862
2756
|
},
|
|
1863
2757
|
dispatchEvent(target, name, opts = {}) {
|
|
1864
|
-
let
|
|
2758
|
+
let defaultBubble = true;
|
|
2759
|
+
let isUploadTarget = target.nodeName === "INPUT" && target.type === "file";
|
|
2760
|
+
if (isUploadTarget && name === "click") {
|
|
2761
|
+
defaultBubble = false;
|
|
2762
|
+
}
|
|
2763
|
+
let bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;
|
|
1865
2764
|
let eventOpts = { bubbles, cancelable: true, detail: opts.detail || {} };
|
|
1866
2765
|
let event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts);
|
|
1867
2766
|
target.dispatchEvent(event);
|
|
@@ -1876,20 +2775,27 @@
|
|
|
1876
2775
|
}
|
|
1877
2776
|
},
|
|
1878
2777
|
mergeAttrs(target, source, opts = {}) {
|
|
1879
|
-
let exclude = opts.exclude || [];
|
|
2778
|
+
let exclude = new Set(opts.exclude || []);
|
|
1880
2779
|
let isIgnored = opts.isIgnored;
|
|
1881
2780
|
let sourceAttrs = source.attributes;
|
|
1882
2781
|
for (let i = sourceAttrs.length - 1; i >= 0; i--) {
|
|
1883
2782
|
let name = sourceAttrs[i].name;
|
|
1884
|
-
if (exclude.
|
|
1885
|
-
|
|
1886
|
-
|
|
2783
|
+
if (!exclude.has(name)) {
|
|
2784
|
+
const sourceValue = source.getAttribute(name);
|
|
2785
|
+
if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {
|
|
2786
|
+
target.setAttribute(name, sourceValue);
|
|
2787
|
+
}
|
|
2788
|
+
} else {
|
|
2789
|
+
if (name === "value" && target.value === source.value) {
|
|
2790
|
+
target.setAttribute("value", source.getAttribute(name));
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
1887
2793
|
}
|
|
1888
2794
|
let targetAttrs = target.attributes;
|
|
1889
2795
|
for (let i = targetAttrs.length - 1; i >= 0; i--) {
|
|
1890
2796
|
let name = targetAttrs[i].name;
|
|
1891
2797
|
if (isIgnored) {
|
|
1892
|
-
if (name.startsWith("data-") && !source.hasAttribute(name)) {
|
|
2798
|
+
if (name.startsWith("data-") && !source.hasAttribute(name) && ![PHX_REF, PHX_REF_SRC].includes(name)) {
|
|
1893
2799
|
target.removeAttribute(name);
|
|
1894
2800
|
}
|
|
1895
2801
|
} else {
|
|
@@ -1913,13 +2819,13 @@
|
|
|
1913
2819
|
return el.setSelectionRange && (el.type === "text" || el.type === "textarea");
|
|
1914
2820
|
},
|
|
1915
2821
|
restoreFocus(focused, selectionStart, selectionEnd) {
|
|
2822
|
+
if (focused instanceof HTMLSelectElement) {
|
|
2823
|
+
focused.focus();
|
|
2824
|
+
}
|
|
1916
2825
|
if (!DOM.isTextualInput(focused)) {
|
|
1917
2826
|
return;
|
|
1918
2827
|
}
|
|
1919
2828
|
let wasFocused = focused.matches(":focus");
|
|
1920
|
-
if (focused.readOnly) {
|
|
1921
|
-
focused.blur();
|
|
1922
|
-
}
|
|
1923
2829
|
if (!wasFocused) {
|
|
1924
2830
|
focused.focus();
|
|
1925
2831
|
}
|
|
@@ -1968,7 +2874,7 @@
|
|
|
1968
2874
|
container.childNodes.forEach((childNode) => {
|
|
1969
2875
|
if (!childNode.id) {
|
|
1970
2876
|
let isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
|
|
1971
|
-
if (!isEmptyTextNode) {
|
|
2877
|
+
if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {
|
|
1972
2878
|
logError(`only HTML element tags with an id are allowed inside containers with phx-update.
|
|
1973
2879
|
|
|
1974
2880
|
removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
@@ -2043,7 +2949,13 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2043
2949
|
let isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
|
|
2044
2950
|
return isPreflighted && this.isActive(fileEl, file);
|
|
2045
2951
|
}
|
|
2046
|
-
|
|
2952
|
+
static isPreflightInProgress(file) {
|
|
2953
|
+
return file._preflightInProgress === true;
|
|
2954
|
+
}
|
|
2955
|
+
static markPreflightInProgress(file) {
|
|
2956
|
+
file._preflightInProgress = true;
|
|
2957
|
+
}
|
|
2958
|
+
constructor(fileEl, file, view, autoUpload) {
|
|
2047
2959
|
this.ref = LiveUploader.genFileRef(file);
|
|
2048
2960
|
this.fileEl = fileEl;
|
|
2049
2961
|
this.file = file;
|
|
@@ -2057,6 +2969,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2057
2969
|
};
|
|
2058
2970
|
this._onElUpdated = this.onElUpdated.bind(this);
|
|
2059
2971
|
this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
2972
|
+
this.autoUpload = autoUpload;
|
|
2060
2973
|
}
|
|
2061
2974
|
metadata() {
|
|
2062
2975
|
return this.meta;
|
|
@@ -2078,7 +2991,11 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2078
2991
|
}
|
|
2079
2992
|
}
|
|
2080
2993
|
}
|
|
2994
|
+
isCancelled() {
|
|
2995
|
+
return this._isCancelled;
|
|
2996
|
+
}
|
|
2081
2997
|
cancel() {
|
|
2998
|
+
this.file._preflightInProgress = false;
|
|
2082
2999
|
this._isCancelled = true;
|
|
2083
3000
|
this._isDone = true;
|
|
2084
3001
|
this._onDone();
|
|
@@ -2089,7 +3006,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2089
3006
|
error(reason = "failed") {
|
|
2090
3007
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
2091
3008
|
this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });
|
|
2092
|
-
|
|
3009
|
+
if (!this.isAutoUpload()) {
|
|
3010
|
+
LiveUploader.clearFiles(this.fileEl);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
isAutoUpload() {
|
|
3014
|
+
return this.autoUpload;
|
|
2093
3015
|
}
|
|
2094
3016
|
onDone(callback) {
|
|
2095
3017
|
this._onDone = () => {
|
|
@@ -2100,6 +3022,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2100
3022
|
onElUpdated() {
|
|
2101
3023
|
let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
|
|
2102
3024
|
if (activeRefs.indexOf(this.ref) === -1) {
|
|
3025
|
+
LiveUploader.untrackFile(this.fileEl, this.file);
|
|
2103
3026
|
this.cancel();
|
|
2104
3027
|
}
|
|
2105
3028
|
}
|
|
@@ -2110,7 +3033,8 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2110
3033
|
relative_path: this.file.webkitRelativePath,
|
|
2111
3034
|
size: this.file.size,
|
|
2112
3035
|
type: this.file.type,
|
|
2113
|
-
ref: this.ref
|
|
3036
|
+
ref: this.ref,
|
|
3037
|
+
meta: typeof this.file.meta === "function" ? this.file.meta() : void 0
|
|
2114
3038
|
};
|
|
2115
3039
|
}
|
|
2116
3040
|
uploader(uploaders) {
|
|
@@ -2165,6 +3089,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2165
3089
|
entry.relative_path = file.webkitRelativePath;
|
|
2166
3090
|
entry.type = file.type;
|
|
2167
3091
|
entry.size = file.size;
|
|
3092
|
+
if (typeof file.meta === "function") {
|
|
3093
|
+
entry.meta = file.meta();
|
|
3094
|
+
}
|
|
2168
3095
|
fileData[uploadRef].push(entry);
|
|
2169
3096
|
});
|
|
2170
3097
|
return fileData;
|
|
@@ -2177,12 +3104,15 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2177
3104
|
static untrackFile(inputEl, file) {
|
|
2178
3105
|
dom_default.putPrivate(inputEl, "files", dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file)));
|
|
2179
3106
|
}
|
|
2180
|
-
static trackFiles(inputEl, files) {
|
|
3107
|
+
static trackFiles(inputEl, files, dataTransfer) {
|
|
2181
3108
|
if (inputEl.getAttribute("multiple") !== null) {
|
|
2182
3109
|
let newFiles = files.filter((file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file)));
|
|
2183
|
-
dom_default.
|
|
3110
|
+
dom_default.updatePrivate(inputEl, "files", [], (existing) => existing.concat(newFiles));
|
|
2184
3111
|
inputEl.value = null;
|
|
2185
3112
|
} else {
|
|
3113
|
+
if (dataTransfer && dataTransfer.files.length > 0) {
|
|
3114
|
+
inputEl.files = dataTransfer.files;
|
|
3115
|
+
}
|
|
2186
3116
|
dom_default.putPrivate(inputEl, "files", files);
|
|
2187
3117
|
}
|
|
2188
3118
|
}
|
|
@@ -2198,29 +3128,47 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2198
3128
|
return Array.from(fileInputs).filter((input) => this.filesAwaitingPreflight(input).length > 0);
|
|
2199
3129
|
}
|
|
2200
3130
|
static filesAwaitingPreflight(input) {
|
|
2201
|
-
return this.activeFiles(input).filter((f) => !UploadEntry.isPreflighted(input, f));
|
|
3131
|
+
return this.activeFiles(input).filter((f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f));
|
|
3132
|
+
}
|
|
3133
|
+
static markPreflightInProgress(entries) {
|
|
3134
|
+
entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));
|
|
2202
3135
|
}
|
|
2203
3136
|
constructor(inputEl, view, onComplete) {
|
|
3137
|
+
this.autoUpload = dom_default.isAutoUpload(inputEl);
|
|
2204
3138
|
this.view = view;
|
|
2205
3139
|
this.onComplete = onComplete;
|
|
2206
|
-
this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view));
|
|
3140
|
+
this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));
|
|
3141
|
+
LiveUploader.markPreflightInProgress(this._entries);
|
|
2207
3142
|
this.numEntriesInProgress = this._entries.length;
|
|
2208
3143
|
}
|
|
3144
|
+
isAutoUpload() {
|
|
3145
|
+
return this.autoUpload;
|
|
3146
|
+
}
|
|
2209
3147
|
entries() {
|
|
2210
3148
|
return this._entries;
|
|
2211
3149
|
}
|
|
2212
3150
|
initAdapterUpload(resp, onError, liveSocket2) {
|
|
2213
3151
|
this._entries = this._entries.map((entry) => {
|
|
2214
|
-
entry.
|
|
2215
|
-
entry.onDone(() => {
|
|
3152
|
+
if (entry.isCancelled()) {
|
|
2216
3153
|
this.numEntriesInProgress--;
|
|
2217
3154
|
if (this.numEntriesInProgress === 0) {
|
|
2218
3155
|
this.onComplete();
|
|
2219
3156
|
}
|
|
2220
|
-
}
|
|
3157
|
+
} else {
|
|
3158
|
+
entry.zipPostFlight(resp);
|
|
3159
|
+
entry.onDone(() => {
|
|
3160
|
+
this.numEntriesInProgress--;
|
|
3161
|
+
if (this.numEntriesInProgress === 0) {
|
|
3162
|
+
this.onComplete();
|
|
3163
|
+
}
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
2221
3166
|
return entry;
|
|
2222
3167
|
});
|
|
2223
3168
|
let groupedEntries = this._entries.reduce((acc, entry) => {
|
|
3169
|
+
if (!entry.meta) {
|
|
3170
|
+
return acc;
|
|
3171
|
+
}
|
|
2224
3172
|
let { name, callback } = entry.uploader(liveSocket2.uploaders);
|
|
2225
3173
|
acc[name] = acc[name] || { callback, entries: [] };
|
|
2226
3174
|
acc[name].entries.push(entry);
|
|
@@ -2232,60 +3180,6 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2232
3180
|
}
|
|
2233
3181
|
}
|
|
2234
3182
|
};
|
|
2235
|
-
var ARIA = {
|
|
2236
|
-
focusMain() {
|
|
2237
|
-
let target = document.querySelector("main h1, main, h1");
|
|
2238
|
-
if (target) {
|
|
2239
|
-
let origTabIndex = target.tabIndex;
|
|
2240
|
-
target.tabIndex = -1;
|
|
2241
|
-
target.focus();
|
|
2242
|
-
target.tabIndex = origTabIndex;
|
|
2243
|
-
}
|
|
2244
|
-
},
|
|
2245
|
-
anyOf(instance, classes) {
|
|
2246
|
-
return classes.find((name) => instance instanceof name);
|
|
2247
|
-
},
|
|
2248
|
-
isFocusable(el, interactiveOnly) {
|
|
2249
|
-
return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, HTMLButtonElement]) || el instanceof HTMLIFrameElement || (el.tabIndex > 0 || !interactiveOnly && el.tabIndex === 0 && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true");
|
|
2250
|
-
},
|
|
2251
|
-
attemptFocus(el, interactiveOnly) {
|
|
2252
|
-
if (this.isFocusable(el, interactiveOnly)) {
|
|
2253
|
-
try {
|
|
2254
|
-
el.focus();
|
|
2255
|
-
} catch (e) {
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
return !!document.activeElement && document.activeElement.isSameNode(el);
|
|
2259
|
-
},
|
|
2260
|
-
focusFirstInteractive(el) {
|
|
2261
|
-
let child = el.firstElementChild;
|
|
2262
|
-
while (child) {
|
|
2263
|
-
if (this.attemptFocus(child, true) || this.focusFirstInteractive(child, true)) {
|
|
2264
|
-
return true;
|
|
2265
|
-
}
|
|
2266
|
-
child = child.nextElementSibling;
|
|
2267
|
-
}
|
|
2268
|
-
},
|
|
2269
|
-
focusFirst(el) {
|
|
2270
|
-
let child = el.firstElementChild;
|
|
2271
|
-
while (child) {
|
|
2272
|
-
if (this.attemptFocus(child) || this.focusFirst(child)) {
|
|
2273
|
-
return true;
|
|
2274
|
-
}
|
|
2275
|
-
child = child.nextElementSibling;
|
|
2276
|
-
}
|
|
2277
|
-
},
|
|
2278
|
-
focusLast(el) {
|
|
2279
|
-
let child = el.lastElementChild;
|
|
2280
|
-
while (child) {
|
|
2281
|
-
if (this.attemptFocus(child) || this.focusLast(child)) {
|
|
2282
|
-
return true;
|
|
2283
|
-
}
|
|
2284
|
-
child = child.previousElementSibling;
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
};
|
|
2288
|
-
var aria_default = ARIA;
|
|
2289
3183
|
var Hooks = {
|
|
2290
3184
|
LiveFileUpload: {
|
|
2291
3185
|
activeRefs() {
|
|
@@ -2337,6 +3231,143 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2337
3231
|
}
|
|
2338
3232
|
}
|
|
2339
3233
|
};
|
|
3234
|
+
var findScrollContainer = (el) => {
|
|
3235
|
+
if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)
|
|
3236
|
+
return null;
|
|
3237
|
+
if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)
|
|
3238
|
+
return el;
|
|
3239
|
+
return findScrollContainer(el.parentElement);
|
|
3240
|
+
};
|
|
3241
|
+
var scrollTop = (scrollContainer) => {
|
|
3242
|
+
if (scrollContainer) {
|
|
3243
|
+
return scrollContainer.scrollTop;
|
|
3244
|
+
} else {
|
|
3245
|
+
return document.documentElement.scrollTop || document.body.scrollTop;
|
|
3246
|
+
}
|
|
3247
|
+
};
|
|
3248
|
+
var bottom = (scrollContainer) => {
|
|
3249
|
+
if (scrollContainer) {
|
|
3250
|
+
return scrollContainer.getBoundingClientRect().bottom;
|
|
3251
|
+
} else {
|
|
3252
|
+
return window.innerHeight || document.documentElement.clientHeight;
|
|
3253
|
+
}
|
|
3254
|
+
};
|
|
3255
|
+
var top = (scrollContainer) => {
|
|
3256
|
+
if (scrollContainer) {
|
|
3257
|
+
return scrollContainer.getBoundingClientRect().top;
|
|
3258
|
+
} else {
|
|
3259
|
+
return 0;
|
|
3260
|
+
}
|
|
3261
|
+
};
|
|
3262
|
+
var isAtViewportTop = (el, scrollContainer) => {
|
|
3263
|
+
let rect = el.getBoundingClientRect();
|
|
3264
|
+
return rect.top >= top(scrollContainer) && rect.left >= 0 && rect.top <= bottom(scrollContainer);
|
|
3265
|
+
};
|
|
3266
|
+
var isAtViewportBottom = (el, scrollContainer) => {
|
|
3267
|
+
let rect = el.getBoundingClientRect();
|
|
3268
|
+
return rect.right >= top(scrollContainer) && rect.left >= 0 && rect.bottom <= bottom(scrollContainer);
|
|
3269
|
+
};
|
|
3270
|
+
var isWithinViewport = (el, scrollContainer) => {
|
|
3271
|
+
let rect = el.getBoundingClientRect();
|
|
3272
|
+
return rect.top >= top(scrollContainer) && rect.left >= 0 && rect.top <= bottom(scrollContainer);
|
|
3273
|
+
};
|
|
3274
|
+
Hooks.InfiniteScroll = {
|
|
3275
|
+
mounted() {
|
|
3276
|
+
this.scrollContainer = findScrollContainer(this.el);
|
|
3277
|
+
let scrollBefore = scrollTop(this.scrollContainer);
|
|
3278
|
+
let topOverran = false;
|
|
3279
|
+
let throttleInterval = 500;
|
|
3280
|
+
let pendingOp = null;
|
|
3281
|
+
let onTopOverrun = this.throttle(throttleInterval, (topEvent, firstChild) => {
|
|
3282
|
+
pendingOp = () => true;
|
|
3283
|
+
this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id, _overran: true }, () => {
|
|
3284
|
+
pendingOp = null;
|
|
3285
|
+
});
|
|
3286
|
+
});
|
|
3287
|
+
let onFirstChildAtTop = this.throttle(throttleInterval, (topEvent, firstChild) => {
|
|
3288
|
+
pendingOp = () => firstChild.scrollIntoView({ block: "start" });
|
|
3289
|
+
this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id }, () => {
|
|
3290
|
+
pendingOp = null;
|
|
3291
|
+
window.requestAnimationFrame(() => {
|
|
3292
|
+
if (!isWithinViewport(firstChild, this.scrollContainer)) {
|
|
3293
|
+
firstChild.scrollIntoView({ block: "start" });
|
|
3294
|
+
}
|
|
3295
|
+
});
|
|
3296
|
+
});
|
|
3297
|
+
});
|
|
3298
|
+
let onLastChildAtBottom = this.throttle(throttleInterval, (bottomEvent, lastChild) => {
|
|
3299
|
+
pendingOp = () => lastChild.scrollIntoView({ block: "end" });
|
|
3300
|
+
this.liveSocket.execJSHookPush(this.el, bottomEvent, { id: lastChild.id }, () => {
|
|
3301
|
+
pendingOp = null;
|
|
3302
|
+
window.requestAnimationFrame(() => {
|
|
3303
|
+
if (!isWithinViewport(lastChild, this.scrollContainer)) {
|
|
3304
|
+
lastChild.scrollIntoView({ block: "end" });
|
|
3305
|
+
}
|
|
3306
|
+
});
|
|
3307
|
+
});
|
|
3308
|
+
});
|
|
3309
|
+
this.onScroll = (_e) => {
|
|
3310
|
+
let scrollNow = scrollTop(this.scrollContainer);
|
|
3311
|
+
if (pendingOp) {
|
|
3312
|
+
scrollBefore = scrollNow;
|
|
3313
|
+
return pendingOp();
|
|
3314
|
+
}
|
|
3315
|
+
let rect = this.el.getBoundingClientRect();
|
|
3316
|
+
let topEvent = this.el.getAttribute(this.liveSocket.binding("viewport-top"));
|
|
3317
|
+
let bottomEvent = this.el.getAttribute(this.liveSocket.binding("viewport-bottom"));
|
|
3318
|
+
let lastChild = this.el.lastElementChild;
|
|
3319
|
+
let firstChild = this.el.firstElementChild;
|
|
3320
|
+
let isScrollingUp = scrollNow < scrollBefore;
|
|
3321
|
+
let isScrollingDown = scrollNow > scrollBefore;
|
|
3322
|
+
if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) {
|
|
3323
|
+
topOverran = true;
|
|
3324
|
+
onTopOverrun(topEvent, firstChild);
|
|
3325
|
+
} else if (isScrollingDown && topOverran && rect.top <= 0) {
|
|
3326
|
+
topOverran = false;
|
|
3327
|
+
}
|
|
3328
|
+
if (topEvent && isScrollingUp && isAtViewportTop(firstChild, this.scrollContainer)) {
|
|
3329
|
+
onFirstChildAtTop(topEvent, firstChild);
|
|
3330
|
+
} else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild, this.scrollContainer)) {
|
|
3331
|
+
onLastChildAtBottom(bottomEvent, lastChild);
|
|
3332
|
+
}
|
|
3333
|
+
scrollBefore = scrollNow;
|
|
3334
|
+
};
|
|
3335
|
+
if (this.scrollContainer) {
|
|
3336
|
+
this.scrollContainer.addEventListener("scroll", this.onScroll);
|
|
3337
|
+
} else {
|
|
3338
|
+
window.addEventListener("scroll", this.onScroll);
|
|
3339
|
+
}
|
|
3340
|
+
},
|
|
3341
|
+
destroyed() {
|
|
3342
|
+
if (this.scrollContainer) {
|
|
3343
|
+
this.scrollContainer.removeEventListener("scroll", this.onScroll);
|
|
3344
|
+
} else {
|
|
3345
|
+
window.removeEventListener("scroll", this.onScroll);
|
|
3346
|
+
}
|
|
3347
|
+
},
|
|
3348
|
+
throttle(interval, callback) {
|
|
3349
|
+
let lastCallAt = 0;
|
|
3350
|
+
let timer;
|
|
3351
|
+
return (...args) => {
|
|
3352
|
+
let now = Date.now();
|
|
3353
|
+
let remainingTime = interval - (now - lastCallAt);
|
|
3354
|
+
if (remainingTime <= 0 || remainingTime > interval) {
|
|
3355
|
+
if (timer) {
|
|
3356
|
+
clearTimeout(timer);
|
|
3357
|
+
timer = null;
|
|
3358
|
+
}
|
|
3359
|
+
lastCallAt = now;
|
|
3360
|
+
callback(...args);
|
|
3361
|
+
} else if (!timer) {
|
|
3362
|
+
timer = setTimeout(() => {
|
|
3363
|
+
lastCallAt = Date.now();
|
|
3364
|
+
timer = null;
|
|
3365
|
+
callback(...args);
|
|
3366
|
+
}, remainingTime);
|
|
3367
|
+
}
|
|
3368
|
+
};
|
|
3369
|
+
}
|
|
3370
|
+
};
|
|
2340
3371
|
var hooks_default = Hooks;
|
|
2341
3372
|
var DOMPostMorphRestorer = class {
|
|
2342
3373
|
constructor(containerBefore, containerAfter, updateType) {
|
|
@@ -2603,6 +3634,8 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2603
3634
|
} else {
|
|
2604
3635
|
toNode = toElement(toNode);
|
|
2605
3636
|
}
|
|
3637
|
+
} else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
|
|
3638
|
+
toNode = toNode.firstElementChild;
|
|
2606
3639
|
}
|
|
2607
3640
|
var getNodeKey = options.getNodeKey || defaultGetNodeKey;
|
|
2608
3641
|
var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
|
|
@@ -2612,6 +3645,10 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2612
3645
|
var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
|
|
2613
3646
|
var onNodeDiscarded = options.onNodeDiscarded || noop;
|
|
2614
3647
|
var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
|
|
3648
|
+
var skipFromChildren = options.skipFromChildren || noop;
|
|
3649
|
+
var addChild = options.addChild || function(parent, child) {
|
|
3650
|
+
return parent.appendChild(child);
|
|
3651
|
+
};
|
|
2615
3652
|
var childrenOnly = options.childrenOnly === true;
|
|
2616
3653
|
var fromNodesLookup = /* @__PURE__ */ Object.create(null);
|
|
2617
3654
|
var keyedRemovalList = [];
|
|
@@ -2712,6 +3749,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2712
3749
|
}
|
|
2713
3750
|
}
|
|
2714
3751
|
function morphChildren(fromEl, toEl) {
|
|
3752
|
+
var skipFrom = skipFromChildren(fromEl, toEl);
|
|
2715
3753
|
var curToNodeChild = toEl.firstChild;
|
|
2716
3754
|
var curFromNodeChild = fromEl.firstChild;
|
|
2717
3755
|
var curToNodeKey;
|
|
@@ -2723,7 +3761,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2723
3761
|
while (curToNodeChild) {
|
|
2724
3762
|
toNextSibling = curToNodeChild.nextSibling;
|
|
2725
3763
|
curToNodeKey = getNodeKey(curToNodeChild);
|
|
2726
|
-
while (curFromNodeChild) {
|
|
3764
|
+
while (!skipFrom && curFromNodeChild) {
|
|
2727
3765
|
fromNextSibling = curFromNodeChild.nextSibling;
|
|
2728
3766
|
if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
|
|
2729
3767
|
curToNodeChild = toNextSibling;
|
|
@@ -2748,6 +3786,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2748
3786
|
removeNode(curFromNodeChild, fromEl, true);
|
|
2749
3787
|
}
|
|
2750
3788
|
curFromNodeChild = matchingFromEl;
|
|
3789
|
+
curFromNodeKey = getNodeKey(curFromNodeChild);
|
|
2751
3790
|
}
|
|
2752
3791
|
} else {
|
|
2753
3792
|
isCompatible = false;
|
|
@@ -2780,7 +3819,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2780
3819
|
curFromNodeChild = fromNextSibling;
|
|
2781
3820
|
}
|
|
2782
3821
|
if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
|
|
2783
|
-
|
|
3822
|
+
if (!skipFrom) {
|
|
3823
|
+
addChild(fromEl, matchingFromEl);
|
|
3824
|
+
}
|
|
2784
3825
|
morphEl(matchingFromEl, curToNodeChild);
|
|
2785
3826
|
} else {
|
|
2786
3827
|
var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
|
|
@@ -2791,7 +3832,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2791
3832
|
if (curToNodeChild.actualize) {
|
|
2792
3833
|
curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
|
|
2793
3834
|
}
|
|
2794
|
-
fromEl
|
|
3835
|
+
addChild(fromEl, curToNodeChild);
|
|
2795
3836
|
handleNodeAdded(curToNodeChild);
|
|
2796
3837
|
}
|
|
2797
3838
|
}
|
|
@@ -2867,15 +3908,20 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2867
3908
|
}
|
|
2868
3909
|
});
|
|
2869
3910
|
}
|
|
2870
|
-
constructor(view, container, id, html, targetCID) {
|
|
3911
|
+
constructor(view, container, id, html, streams, targetCID) {
|
|
2871
3912
|
this.view = view;
|
|
2872
3913
|
this.liveSocket = view.liveSocket;
|
|
2873
3914
|
this.container = container;
|
|
2874
3915
|
this.id = id;
|
|
2875
3916
|
this.rootID = view.root.id;
|
|
2876
3917
|
this.html = html;
|
|
3918
|
+
this.streams = streams;
|
|
3919
|
+
this.streamInserts = {};
|
|
3920
|
+
this.streamComponentRestore = {};
|
|
2877
3921
|
this.targetCID = targetCID;
|
|
2878
3922
|
this.cidPatch = isCid(this.targetCID);
|
|
3923
|
+
this.pendingRemoves = [];
|
|
3924
|
+
this.phxRemove = this.liveSocket.binding("remove");
|
|
2879
3925
|
this.callbacks = {
|
|
2880
3926
|
beforeadded: [],
|
|
2881
3927
|
beforeupdated: [],
|
|
@@ -2900,11 +3946,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2900
3946
|
this.callbacks[`after${kind}`].forEach((callback) => callback(...args));
|
|
2901
3947
|
}
|
|
2902
3948
|
markPrunableContentForRemoval() {
|
|
2903
|
-
|
|
3949
|
+
let phxUpdate = this.liveSocket.binding(PHX_UPDATE);
|
|
3950
|
+
dom_default.all(this.container, `[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`, (el) => {
|
|
2904
3951
|
el.setAttribute(PHX_PRUNE, "");
|
|
2905
3952
|
});
|
|
2906
3953
|
}
|
|
2907
|
-
perform() {
|
|
3954
|
+
perform(isJoinPatch) {
|
|
2908
3955
|
let { view, liveSocket: liveSocket2, container, html } = this;
|
|
2909
3956
|
let targetContainer = this.isCIDPatch() ? this.targetCIDContainer(html) : container;
|
|
2910
3957
|
if (this.isCIDPatch() && !targetContainer) {
|
|
@@ -2914,30 +3961,63 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2914
3961
|
let { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};
|
|
2915
3962
|
let phxUpdate = liveSocket2.binding(PHX_UPDATE);
|
|
2916
3963
|
let phxFeedbackFor = liveSocket2.binding(PHX_FEEDBACK_FOR);
|
|
3964
|
+
let phxFeedbackGroup = liveSocket2.binding(PHX_FEEDBACK_GROUP);
|
|
2917
3965
|
let disableWith = liveSocket2.binding(PHX_DISABLE_WITH);
|
|
3966
|
+
let phxViewportTop = liveSocket2.binding(PHX_VIEWPORT_TOP);
|
|
3967
|
+
let phxViewportBottom = liveSocket2.binding(PHX_VIEWPORT_BOTTOM);
|
|
2918
3968
|
let phxTriggerExternal = liveSocket2.binding(PHX_TRIGGER_ACTION);
|
|
2919
|
-
let phxRemove = liveSocket2.binding("remove");
|
|
2920
3969
|
let added = [];
|
|
3970
|
+
let feedbackContainers = [];
|
|
2921
3971
|
let updates = [];
|
|
2922
3972
|
let appendPrependUpdates = [];
|
|
2923
|
-
let pendingRemoves = [];
|
|
2924
3973
|
let externalFormTriggered = null;
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
this.trackBefore("added", container);
|
|
2929
|
-
this.trackBefore("updated", container, container);
|
|
2930
|
-
liveSocket2.time("morphdom", () => {
|
|
2931
|
-
morphdom_esm_default(targetContainer, diffHTML, {
|
|
2932
|
-
childrenOnly: targetContainer.getAttribute(PHX_COMPONENT) === null,
|
|
3974
|
+
function morph(targetContainer2, source, withChildren = false) {
|
|
3975
|
+
morphdom_esm_default(targetContainer2, source, {
|
|
3976
|
+
childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,
|
|
2933
3977
|
getNodeKey: (node) => {
|
|
2934
|
-
|
|
3978
|
+
if (dom_default.isPhxDestroyed(node)) {
|
|
3979
|
+
return null;
|
|
3980
|
+
}
|
|
3981
|
+
if (isJoinPatch) {
|
|
3982
|
+
return node.id;
|
|
3983
|
+
}
|
|
3984
|
+
return node.id || node.getAttribute && node.getAttribute(PHX_MAGIC_ID);
|
|
3985
|
+
},
|
|
3986
|
+
skipFromChildren: (from) => {
|
|
3987
|
+
return from.getAttribute(phxUpdate) === PHX_STREAM;
|
|
3988
|
+
},
|
|
3989
|
+
addChild: (parent, child) => {
|
|
3990
|
+
let { ref, streamAt } = this.getStreamInsert(child);
|
|
3991
|
+
if (ref === void 0) {
|
|
3992
|
+
return parent.appendChild(child);
|
|
3993
|
+
}
|
|
3994
|
+
this.setStreamRef(child, ref);
|
|
3995
|
+
if (streamAt === 0) {
|
|
3996
|
+
parent.insertAdjacentElement("afterbegin", child);
|
|
3997
|
+
} else if (streamAt === -1) {
|
|
3998
|
+
parent.appendChild(child);
|
|
3999
|
+
} else if (streamAt > 0) {
|
|
4000
|
+
let sibling = Array.from(parent.children)[streamAt];
|
|
4001
|
+
parent.insertBefore(child, sibling);
|
|
4002
|
+
}
|
|
2935
4003
|
},
|
|
2936
4004
|
onBeforeNodeAdded: (el) => {
|
|
4005
|
+
dom_default.maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom);
|
|
2937
4006
|
this.trackBefore("added", el);
|
|
2938
|
-
|
|
4007
|
+
let morphedEl = el;
|
|
4008
|
+
if (!isJoinPatch && this.streamComponentRestore[el.id]) {
|
|
4009
|
+
morphedEl = this.streamComponentRestore[el.id];
|
|
4010
|
+
delete this.streamComponentRestore[el.id];
|
|
4011
|
+
morph.call(this, morphedEl, el, true);
|
|
4012
|
+
}
|
|
4013
|
+
return morphedEl;
|
|
2939
4014
|
},
|
|
2940
4015
|
onNodeAdded: (el) => {
|
|
4016
|
+
if (el.getAttribute) {
|
|
4017
|
+
this.maybeReOrderStream(el, true);
|
|
4018
|
+
}
|
|
4019
|
+
if (dom_default.isFeedbackContainer(el, phxFeedbackFor))
|
|
4020
|
+
feedbackContainers.push(el);
|
|
2941
4021
|
if (el instanceof HTMLImageElement && el.srcset) {
|
|
2942
4022
|
el.srcset = el.srcset;
|
|
2943
4023
|
} else if (el instanceof HTMLVideoElement && el.autoplay) {
|
|
@@ -2946,27 +4026,20 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2946
4026
|
if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
|
|
2947
4027
|
externalFormTriggered = el;
|
|
2948
4028
|
}
|
|
2949
|
-
dom_default.discardError(targetContainer, el, phxFeedbackFor);
|
|
2950
4029
|
if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {
|
|
2951
4030
|
this.trackAfter("phxChildAdded", el);
|
|
2952
4031
|
}
|
|
2953
4032
|
added.push(el);
|
|
2954
4033
|
},
|
|
2955
|
-
onNodeDiscarded: (el) =>
|
|
2956
|
-
if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {
|
|
2957
|
-
liveSocket2.destroyViewByEl(el);
|
|
2958
|
-
}
|
|
2959
|
-
this.trackAfter("discarded", el);
|
|
2960
|
-
},
|
|
4034
|
+
onNodeDiscarded: (el) => this.onNodeDiscarded(el),
|
|
2961
4035
|
onBeforeNodeDiscarded: (el) => {
|
|
2962
4036
|
if (el.getAttribute && el.getAttribute(PHX_PRUNE) !== null) {
|
|
2963
4037
|
return true;
|
|
2964
4038
|
}
|
|
2965
|
-
if (el.
|
|
4039
|
+
if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [PHX_STREAM, "append", "prepend"])) {
|
|
2966
4040
|
return false;
|
|
2967
4041
|
}
|
|
2968
|
-
if (
|
|
2969
|
-
pendingRemoves.push(el);
|
|
4042
|
+
if (this.maybePendingRemove(el)) {
|
|
2970
4043
|
return false;
|
|
2971
4044
|
}
|
|
2972
4045
|
if (this.skipCIDSibling(el)) {
|
|
@@ -2979,10 +4052,17 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2979
4052
|
externalFormTriggered = el;
|
|
2980
4053
|
}
|
|
2981
4054
|
updates.push(el);
|
|
4055
|
+
this.maybeReOrderStream(el, false);
|
|
2982
4056
|
},
|
|
2983
4057
|
onBeforeElUpdated: (fromEl, toEl) => {
|
|
4058
|
+
dom_default.maybeAddPrivateHooks(toEl, phxViewportTop, phxViewportBottom);
|
|
4059
|
+
if (dom_default.isFeedbackContainer(fromEl, phxFeedbackFor) || dom_default.isFeedbackContainer(toEl, phxFeedbackFor)) {
|
|
4060
|
+
feedbackContainers.push(fromEl);
|
|
4061
|
+
feedbackContainers.push(toEl);
|
|
4062
|
+
}
|
|
2984
4063
|
dom_default.cleanChildNodes(toEl, phxUpdate);
|
|
2985
4064
|
if (this.skipCIDSibling(toEl)) {
|
|
4065
|
+
this.maybeReOrderStream(fromEl);
|
|
2986
4066
|
return false;
|
|
2987
4067
|
}
|
|
2988
4068
|
if (dom_default.isPhxSticky(fromEl)) {
|
|
@@ -2990,7 +4070,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
2990
4070
|
}
|
|
2991
4071
|
if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {
|
|
2992
4072
|
this.trackBefore("updated", fromEl, toEl);
|
|
2993
|
-
dom_default.mergeAttrs(fromEl, toEl, { isIgnored:
|
|
4073
|
+
dom_default.mergeAttrs(fromEl, toEl, { isIgnored: dom_default.isIgnored(fromEl, phxUpdate) });
|
|
2994
4074
|
updates.push(fromEl);
|
|
2995
4075
|
dom_default.applyStickyOperations(fromEl);
|
|
2996
4076
|
return false;
|
|
@@ -3017,9 +4097,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3017
4097
|
return false;
|
|
3018
4098
|
}
|
|
3019
4099
|
dom_default.copyPrivates(toEl, fromEl);
|
|
3020
|
-
dom_default.discardError(targetContainer, toEl, phxFeedbackFor);
|
|
3021
4100
|
let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
|
|
3022
|
-
|
|
4101
|
+
let focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);
|
|
4102
|
+
if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {
|
|
3023
4103
|
this.trackBefore("updated", fromEl, toEl);
|
|
3024
4104
|
dom_default.mergeFocusedInput(fromEl, toEl);
|
|
3025
4105
|
dom_default.syncAttrsToProps(fromEl);
|
|
@@ -3027,6 +4107,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3027
4107
|
dom_default.applyStickyOperations(fromEl);
|
|
3028
4108
|
return false;
|
|
3029
4109
|
} else {
|
|
4110
|
+
if (focusedSelectChanged) {
|
|
4111
|
+
fromEl.blur();
|
|
4112
|
+
}
|
|
3030
4113
|
if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {
|
|
3031
4114
|
appendPrependUpdates.push(new DOMPostMorphRestorer(fromEl, toEl, toEl.getAttribute(phxUpdate)));
|
|
3032
4115
|
}
|
|
@@ -3037,19 +4120,137 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3037
4120
|
}
|
|
3038
4121
|
}
|
|
3039
4122
|
});
|
|
4123
|
+
}
|
|
4124
|
+
this.trackBefore("added", container);
|
|
4125
|
+
this.trackBefore("updated", container, container);
|
|
4126
|
+
liveSocket2.time("morphdom", () => {
|
|
4127
|
+
this.streams.forEach(([ref, inserts, deleteIds, reset]) => {
|
|
4128
|
+
inserts.forEach(([key, streamAt, limit]) => {
|
|
4129
|
+
this.streamInserts[key] = { ref, streamAt, limit, reset };
|
|
4130
|
+
});
|
|
4131
|
+
if (reset !== void 0) {
|
|
4132
|
+
dom_default.all(container, `[${PHX_STREAM_REF}="${ref}"]`, (child) => {
|
|
4133
|
+
this.removeStreamChildElement(child);
|
|
4134
|
+
});
|
|
4135
|
+
}
|
|
4136
|
+
deleteIds.forEach((id) => {
|
|
4137
|
+
let child = container.querySelector(`[id="${id}"]`);
|
|
4138
|
+
if (child) {
|
|
4139
|
+
this.removeStreamChildElement(child);
|
|
4140
|
+
}
|
|
4141
|
+
});
|
|
4142
|
+
});
|
|
4143
|
+
if (isJoinPatch) {
|
|
4144
|
+
dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`, (el) => {
|
|
4145
|
+
this.liveSocket.owner(el, (view2) => {
|
|
4146
|
+
if (view2 === this.view) {
|
|
4147
|
+
Array.from(el.children).forEach((child) => {
|
|
4148
|
+
this.removeStreamChildElement(child);
|
|
4149
|
+
});
|
|
4150
|
+
}
|
|
4151
|
+
});
|
|
4152
|
+
});
|
|
4153
|
+
}
|
|
4154
|
+
morph.call(this, targetContainer, html);
|
|
3040
4155
|
});
|
|
3041
4156
|
if (liveSocket2.isDebugEnabled()) {
|
|
3042
4157
|
detectDuplicateIds();
|
|
4158
|
+
Array.from(document.querySelectorAll("input[name=id]")).forEach((node) => {
|
|
4159
|
+
if (node.form) {
|
|
4160
|
+
console.error('Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\n', node);
|
|
4161
|
+
}
|
|
4162
|
+
});
|
|
3043
4163
|
}
|
|
3044
4164
|
if (appendPrependUpdates.length > 0) {
|
|
3045
4165
|
liveSocket2.time("post-morph append/prepend restoration", () => {
|
|
3046
4166
|
appendPrependUpdates.forEach((update) => update.perform());
|
|
3047
4167
|
});
|
|
3048
4168
|
}
|
|
4169
|
+
dom_default.maybeHideFeedback(targetContainer, feedbackContainers, phxFeedbackFor, phxFeedbackGroup);
|
|
3049
4170
|
liveSocket2.silenceEvents(() => dom_default.restoreFocus(focused, selectionStart, selectionEnd));
|
|
3050
4171
|
dom_default.dispatchEvent(document, "phx:update");
|
|
3051
4172
|
added.forEach((el) => this.trackAfter("added", el));
|
|
3052
4173
|
updates.forEach((el) => this.trackAfter("updated", el));
|
|
4174
|
+
this.transitionPendingRemoves();
|
|
4175
|
+
if (externalFormTriggered) {
|
|
4176
|
+
liveSocket2.unload();
|
|
4177
|
+
Object.getPrototypeOf(externalFormTriggered).submit.call(externalFormTriggered);
|
|
4178
|
+
}
|
|
4179
|
+
return true;
|
|
4180
|
+
}
|
|
4181
|
+
onNodeDiscarded(el) {
|
|
4182
|
+
if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {
|
|
4183
|
+
this.liveSocket.destroyViewByEl(el);
|
|
4184
|
+
}
|
|
4185
|
+
this.trackAfter("discarded", el);
|
|
4186
|
+
}
|
|
4187
|
+
maybePendingRemove(node) {
|
|
4188
|
+
if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {
|
|
4189
|
+
this.pendingRemoves.push(node);
|
|
4190
|
+
return true;
|
|
4191
|
+
} else {
|
|
4192
|
+
return false;
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
removeStreamChildElement(child) {
|
|
4196
|
+
if (this.streamInserts[child.id]) {
|
|
4197
|
+
this.streamComponentRestore[child.id] = child;
|
|
4198
|
+
child.remove();
|
|
4199
|
+
} else {
|
|
4200
|
+
if (!this.maybePendingRemove(child)) {
|
|
4201
|
+
child.remove();
|
|
4202
|
+
this.onNodeDiscarded(child);
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
getStreamInsert(el) {
|
|
4207
|
+
let insert = el.id ? this.streamInserts[el.id] : {};
|
|
4208
|
+
return insert || {};
|
|
4209
|
+
}
|
|
4210
|
+
setStreamRef(el, ref) {
|
|
4211
|
+
dom_default.putSticky(el, PHX_STREAM_REF, (el2) => el2.setAttribute(PHX_STREAM_REF, ref));
|
|
4212
|
+
}
|
|
4213
|
+
maybeReOrderStream(el, isNew) {
|
|
4214
|
+
let { ref, streamAt, reset } = this.getStreamInsert(el);
|
|
4215
|
+
if (streamAt === void 0) {
|
|
4216
|
+
return;
|
|
4217
|
+
}
|
|
4218
|
+
this.setStreamRef(el, ref);
|
|
4219
|
+
if (!reset && !isNew) {
|
|
4220
|
+
return;
|
|
4221
|
+
}
|
|
4222
|
+
if (!el.parentElement) {
|
|
4223
|
+
return;
|
|
4224
|
+
}
|
|
4225
|
+
if (streamAt === 0) {
|
|
4226
|
+
el.parentElement.insertBefore(el, el.parentElement.firstElementChild);
|
|
4227
|
+
} else if (streamAt > 0) {
|
|
4228
|
+
let children = Array.from(el.parentElement.children);
|
|
4229
|
+
let oldIndex = children.indexOf(el);
|
|
4230
|
+
if (streamAt >= children.length - 1) {
|
|
4231
|
+
el.parentElement.appendChild(el);
|
|
4232
|
+
} else {
|
|
4233
|
+
let sibling = children[streamAt];
|
|
4234
|
+
if (oldIndex > streamAt) {
|
|
4235
|
+
el.parentElement.insertBefore(el, sibling);
|
|
4236
|
+
} else {
|
|
4237
|
+
el.parentElement.insertBefore(el, sibling.nextElementSibling);
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
this.maybeLimitStream(el);
|
|
4242
|
+
}
|
|
4243
|
+
maybeLimitStream(el) {
|
|
4244
|
+
let { limit } = this.getStreamInsert(el);
|
|
4245
|
+
let children = limit !== null && Array.from(el.parentElement.children);
|
|
4246
|
+
if (limit && limit < 0 && children.length > limit * -1) {
|
|
4247
|
+
children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));
|
|
4248
|
+
} else if (limit && limit >= 0 && children.length > limit) {
|
|
4249
|
+
children.slice(limit).forEach((child) => this.removeStreamChildElement(child));
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
transitionPendingRemoves() {
|
|
4253
|
+
let { pendingRemoves, liveSocket: liveSocket2 } = this;
|
|
3053
4254
|
if (pendingRemoves.length > 0) {
|
|
3054
4255
|
liveSocket2.transitionRemoves(pendingRemoves);
|
|
3055
4256
|
liveSocket2.requestDOMUpdate(() => {
|
|
@@ -3063,17 +4264,26 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3063
4264
|
this.trackAfter("transitionsDiscarded", pendingRemoves);
|
|
3064
4265
|
});
|
|
3065
4266
|
}
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
4267
|
+
}
|
|
4268
|
+
isChangedSelect(fromEl, toEl) {
|
|
4269
|
+
if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {
|
|
4270
|
+
return false;
|
|
3069
4271
|
}
|
|
3070
|
-
|
|
4272
|
+
if (fromEl.options.length !== toEl.options.length) {
|
|
4273
|
+
return true;
|
|
4274
|
+
}
|
|
4275
|
+
let fromSelected = fromEl.selectedOptions[0];
|
|
4276
|
+
let toSelected = toEl.selectedOptions[0];
|
|
4277
|
+
if (fromSelected && fromSelected.hasAttribute("selected")) {
|
|
4278
|
+
toSelected.setAttribute("selected", fromSelected.getAttribute("selected"));
|
|
4279
|
+
}
|
|
4280
|
+
return !fromEl.isEqualNode(toEl);
|
|
3071
4281
|
}
|
|
3072
4282
|
isCIDPatch() {
|
|
3073
4283
|
return this.cidPatch;
|
|
3074
4284
|
}
|
|
3075
4285
|
skipCIDSibling(el) {
|
|
3076
|
-
return el.nodeType === Node.ELEMENT_NODE && el.
|
|
4286
|
+
return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);
|
|
3077
4287
|
}
|
|
3078
4288
|
targetCIDContainer(html) {
|
|
3079
4289
|
if (!this.isCIDPatch()) {
|
|
@@ -3086,29 +4296,98 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3086
4296
|
return first && first.parentNode;
|
|
3087
4297
|
}
|
|
3088
4298
|
}
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
4299
|
+
indexOf(parent, child) {
|
|
4300
|
+
return Array.from(parent.children).indexOf(child);
|
|
4301
|
+
}
|
|
4302
|
+
};
|
|
4303
|
+
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
4304
|
+
"area",
|
|
4305
|
+
"base",
|
|
4306
|
+
"br",
|
|
4307
|
+
"col",
|
|
4308
|
+
"command",
|
|
4309
|
+
"embed",
|
|
4310
|
+
"hr",
|
|
4311
|
+
"img",
|
|
4312
|
+
"input",
|
|
4313
|
+
"keygen",
|
|
4314
|
+
"link",
|
|
4315
|
+
"meta",
|
|
4316
|
+
"param",
|
|
4317
|
+
"source",
|
|
4318
|
+
"track",
|
|
4319
|
+
"wbr"
|
|
4320
|
+
]);
|
|
4321
|
+
var quoteChars = /* @__PURE__ */ new Set(["'", '"']);
|
|
4322
|
+
var modifyRoot = (html, attrs, clearInnerHTML) => {
|
|
4323
|
+
let i = 0;
|
|
4324
|
+
let insideComment = false;
|
|
4325
|
+
let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;
|
|
4326
|
+
let lookahead = html.match(/^(\s*(?:<!--.*?-->\s*)*)<([^\s\/>]+)/);
|
|
4327
|
+
if (lookahead === null) {
|
|
4328
|
+
throw new Error(`malformed html ${html}`);
|
|
4329
|
+
}
|
|
4330
|
+
i = lookahead[0].length;
|
|
4331
|
+
beforeTag = lookahead[1];
|
|
4332
|
+
tag = lookahead[2];
|
|
4333
|
+
tagNameEndsAt = i;
|
|
4334
|
+
for (i; i < html.length; i++) {
|
|
4335
|
+
if (html.charAt(i) === ">") {
|
|
4336
|
+
break;
|
|
4337
|
+
}
|
|
4338
|
+
if (html.charAt(i) === "=") {
|
|
4339
|
+
let isId = html.slice(i - 3, i) === " id";
|
|
4340
|
+
i++;
|
|
4341
|
+
let char = html.charAt(i);
|
|
4342
|
+
if (quoteChars.has(char)) {
|
|
4343
|
+
let attrStartsAt = i;
|
|
4344
|
+
i++;
|
|
4345
|
+
for (i; i < html.length; i++) {
|
|
4346
|
+
if (html.charAt(i) === char) {
|
|
4347
|
+
break;
|
|
4348
|
+
}
|
|
3105
4349
|
}
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
4350
|
+
if (isId) {
|
|
4351
|
+
id = html.slice(attrStartsAt + 1, i);
|
|
4352
|
+
break;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
3110
4355
|
}
|
|
3111
4356
|
}
|
|
4357
|
+
let closeAt = html.length - 1;
|
|
4358
|
+
insideComment = false;
|
|
4359
|
+
while (closeAt >= beforeTag.length + tag.length) {
|
|
4360
|
+
let char = html.charAt(closeAt);
|
|
4361
|
+
if (insideComment) {
|
|
4362
|
+
if (char === "-" && html.slice(closeAt - 3, closeAt) === "<!-") {
|
|
4363
|
+
insideComment = false;
|
|
4364
|
+
closeAt -= 4;
|
|
4365
|
+
} else {
|
|
4366
|
+
closeAt -= 1;
|
|
4367
|
+
}
|
|
4368
|
+
} else if (char === ">" && html.slice(closeAt - 2, closeAt) === "--") {
|
|
4369
|
+
insideComment = true;
|
|
4370
|
+
closeAt -= 3;
|
|
4371
|
+
} else if (char === ">") {
|
|
4372
|
+
break;
|
|
4373
|
+
} else {
|
|
4374
|
+
closeAt -= 1;
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
afterTag = html.slice(closeAt + 1, html.length);
|
|
4378
|
+
let attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");
|
|
4379
|
+
if (clearInnerHTML) {
|
|
4380
|
+
let idAttrStr = id ? ` id="${id}"` : "";
|
|
4381
|
+
if (VOID_TAGS.has(tag)) {
|
|
4382
|
+
newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;
|
|
4383
|
+
} else {
|
|
4384
|
+
newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}></${tag}>`;
|
|
4385
|
+
}
|
|
4386
|
+
} else {
|
|
4387
|
+
let rest = html.slice(tagNameEndsAt, closeAt + 1);
|
|
4388
|
+
newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;
|
|
4389
|
+
}
|
|
4390
|
+
return [newHTML, beforeTag, afterTag];
|
|
3112
4391
|
};
|
|
3113
4392
|
var Rendered = class {
|
|
3114
4393
|
static extract(diff) {
|
|
@@ -3121,19 +4400,21 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3121
4400
|
constructor(viewId, rendered) {
|
|
3122
4401
|
this.viewId = viewId;
|
|
3123
4402
|
this.rendered = {};
|
|
4403
|
+
this.magicId = 0;
|
|
3124
4404
|
this.mergeDiff(rendered);
|
|
3125
4405
|
}
|
|
3126
4406
|
parentViewId() {
|
|
3127
4407
|
return this.viewId;
|
|
3128
4408
|
}
|
|
3129
4409
|
toString(onlyCids) {
|
|
3130
|
-
|
|
4410
|
+
let [str, streams] = this.recursiveToString(this.rendered, this.rendered[COMPONENTS], onlyCids, true, {});
|
|
4411
|
+
return [str, streams];
|
|
3131
4412
|
}
|
|
3132
|
-
recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids) {
|
|
4413
|
+
recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {
|
|
3133
4414
|
onlyCids = onlyCids ? new Set(onlyCids) : null;
|
|
3134
|
-
let output = { buffer: "", components, onlyCids };
|
|
3135
|
-
this.toOutputBuffer(rendered, null, output);
|
|
3136
|
-
return output.buffer;
|
|
4415
|
+
let output = { buffer: "", components, onlyCids, streams: /* @__PURE__ */ new Set() };
|
|
4416
|
+
this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);
|
|
4417
|
+
return [output.buffer, output.streams];
|
|
3137
4418
|
}
|
|
3138
4419
|
componentCIDs(diff) {
|
|
3139
4420
|
return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));
|
|
@@ -3147,6 +4428,11 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3147
4428
|
getComponent(diff, cid) {
|
|
3148
4429
|
return diff[COMPONENTS][cid];
|
|
3149
4430
|
}
|
|
4431
|
+
resetRender(cid) {
|
|
4432
|
+
if (this.rendered[COMPONENTS][cid]) {
|
|
4433
|
+
this.rendered[COMPONENTS][cid].reset = true;
|
|
4434
|
+
}
|
|
4435
|
+
}
|
|
3150
4436
|
mergeDiff(diff) {
|
|
3151
4437
|
let newc = diff[COMPONENTS];
|
|
3152
4438
|
let cache = {};
|
|
@@ -3177,10 +4463,10 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3177
4463
|
tdiff = oldc[-scid];
|
|
3178
4464
|
}
|
|
3179
4465
|
stat = tdiff[STATIC];
|
|
3180
|
-
ndiff = this.cloneMerge(tdiff, cdiff);
|
|
4466
|
+
ndiff = this.cloneMerge(tdiff, cdiff, true);
|
|
3181
4467
|
ndiff[STATIC] = stat;
|
|
3182
4468
|
} else {
|
|
3183
|
-
ndiff = cdiff[STATIC] !== void 0 ? cdiff : this.cloneMerge(oldc[cid]
|
|
4469
|
+
ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);
|
|
3184
4470
|
}
|
|
3185
4471
|
cache[cid] = ndiff;
|
|
3186
4472
|
return ndiff;
|
|
@@ -3198,26 +4484,40 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3198
4484
|
for (let key in source) {
|
|
3199
4485
|
let val = source[key];
|
|
3200
4486
|
let targetVal = target[key];
|
|
3201
|
-
|
|
4487
|
+
let isObjVal = isObject(val);
|
|
4488
|
+
if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {
|
|
3202
4489
|
this.doMutableMerge(targetVal, val);
|
|
3203
4490
|
} else {
|
|
3204
4491
|
target[key] = val;
|
|
3205
4492
|
}
|
|
3206
4493
|
}
|
|
4494
|
+
if (target[ROOT]) {
|
|
4495
|
+
target.newRender = true;
|
|
4496
|
+
}
|
|
3207
4497
|
}
|
|
3208
|
-
cloneMerge(target, source) {
|
|
4498
|
+
cloneMerge(target, source, pruneMagicId) {
|
|
3209
4499
|
let merged = __spreadValues(__spreadValues({}, target), source);
|
|
3210
4500
|
for (let key in merged) {
|
|
3211
4501
|
let val = source[key];
|
|
3212
4502
|
let targetVal = target[key];
|
|
3213
4503
|
if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {
|
|
3214
|
-
merged[key] = this.cloneMerge(targetVal, val);
|
|
4504
|
+
merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);
|
|
4505
|
+
} else if (val === void 0 && isObject(targetVal)) {
|
|
4506
|
+
merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);
|
|
3215
4507
|
}
|
|
3216
4508
|
}
|
|
4509
|
+
if (pruneMagicId) {
|
|
4510
|
+
delete merged.magicId;
|
|
4511
|
+
delete merged.newRender;
|
|
4512
|
+
} else if (target[ROOT]) {
|
|
4513
|
+
merged.newRender = true;
|
|
4514
|
+
}
|
|
3217
4515
|
return merged;
|
|
3218
4516
|
}
|
|
3219
4517
|
componentToString(cid) {
|
|
3220
|
-
|
|
4518
|
+
let [str, streams] = this.recursiveCIDToString(this.rendered[COMPONENTS], cid, null);
|
|
4519
|
+
let [strippedHTML, _before, _after] = modifyRoot(str, {});
|
|
4520
|
+
return [strippedHTML, streams];
|
|
3221
4521
|
}
|
|
3222
4522
|
pruneCIDs(cids) {
|
|
3223
4523
|
cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);
|
|
@@ -3235,380 +4535,197 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
3235
4535
|
return part;
|
|
3236
4536
|
}
|
|
3237
4537
|
}
|
|
3238
|
-
|
|
4538
|
+
nextMagicID() {
|
|
4539
|
+
this.magicId++;
|
|
4540
|
+
return `m${this.magicId}-${this.parentViewId()}`;
|
|
4541
|
+
}
|
|
4542
|
+
toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {
|
|
3239
4543
|
if (rendered[DYNAMICS]) {
|
|
3240
4544
|
return this.comprehensionToBuffer(rendered, templates, output);
|
|
3241
4545
|
}
|
|
3242
4546
|
let { [STATIC]: statics } = rendered;
|
|
3243
4547
|
statics = this.templateStatic(statics, templates);
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
output.buffer
|
|
3248
|
-
}
|
|
3249
|
-
}
|
|
3250
|
-
comprehensionToBuffer(rendered, templates, output) {
|
|
3251
|
-
let { [DYNAMICS]: dynamics, [STATIC]: statics } = rendered;
|
|
3252
|
-
statics = this.templateStatic(statics, templates);
|
|
3253
|
-
let compTemplates = templates || rendered[TEMPLATES];
|
|
3254
|
-
for (let d = 0; d < dynamics.length; d++) {
|
|
3255
|
-
let dynamic = dynamics[d];
|
|
3256
|
-
output.buffer += statics[0];
|
|
3257
|
-
for (let i = 1; i < statics.length; i++) {
|
|
3258
|
-
this.dynamicToBuffer(dynamic[i - 1], compTemplates, output);
|
|
3259
|
-
output.buffer += statics[i];
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
}
|
|
3263
|
-
dynamicToBuffer(rendered, templates, output) {
|
|
3264
|
-
if (typeof rendered === "number") {
|
|
3265
|
-
output.buffer += this.recursiveCIDToString(output.components, rendered, output.onlyCids);
|
|
3266
|
-
} else if (isObject(rendered)) {
|
|
3267
|
-
this.toOutputBuffer(rendered, templates, output);
|
|
3268
|
-
} else {
|
|
3269
|
-
output.buffer += rendered;
|
|
3270
|
-
}
|
|
3271
|
-
}
|
|
3272
|
-
recursiveCIDToString(components, cid, onlyCids) {
|
|
3273
|
-
let component = components[cid] || logError(`no component for CID ${cid}`, components);
|
|
3274
|
-
let template = document.createElement("template");
|
|
3275
|
-
template.innerHTML = this.recursiveToString(component, components, onlyCids);
|
|
3276
|
-
let container = template.content;
|
|
3277
|
-
let skip = onlyCids && !onlyCids.has(cid);
|
|
3278
|
-
let [hasChildNodes, hasChildComponents] = Array.from(container.childNodes).reduce(([hasNodes, hasComponents], child, i) => {
|
|
3279
|
-
if (child.nodeType === Node.ELEMENT_NODE) {
|
|
3280
|
-
if (child.getAttribute(PHX_COMPONENT)) {
|
|
3281
|
-
return [hasNodes, true];
|
|
3282
|
-
}
|
|
3283
|
-
child.setAttribute(PHX_COMPONENT, cid);
|
|
3284
|
-
if (!child.id) {
|
|
3285
|
-
child.id = `${this.parentViewId()}-${cid}-${i}`;
|
|
3286
|
-
}
|
|
3287
|
-
if (skip) {
|
|
3288
|
-
child.setAttribute(PHX_SKIP, "");
|
|
3289
|
-
child.innerHTML = "";
|
|
3290
|
-
}
|
|
3291
|
-
return [true, hasComponents];
|
|
3292
|
-
} else {
|
|
3293
|
-
if (child.nodeValue.trim() !== "") {
|
|
3294
|
-
logError(`only HTML element tags are allowed at the root of components.
|
|
3295
|
-
|
|
3296
|
-
got: "${child.nodeValue.trim()}"
|
|
3297
|
-
|
|
3298
|
-
within:
|
|
3299
|
-
`, template.innerHTML.trim());
|
|
3300
|
-
child.replaceWith(this.createSpan(child.nodeValue, cid));
|
|
3301
|
-
return [true, hasComponents];
|
|
3302
|
-
} else {
|
|
3303
|
-
child.remove();
|
|
3304
|
-
return [hasNodes, hasComponents];
|
|
3305
|
-
}
|
|
3306
|
-
}
|
|
3307
|
-
}, [false, false]);
|
|
3308
|
-
if (!hasChildNodes && !hasChildComponents) {
|
|
3309
|
-
logError("expected at least one HTML element tag inside a component, but the component is empty:\n", template.innerHTML.trim());
|
|
3310
|
-
return this.createSpan("", cid).outerHTML;
|
|
3311
|
-
} else if (!hasChildNodes && hasChildComponents) {
|
|
3312
|
-
logError("expected at least one HTML element tag directly inside a component, but only subcomponents were found. A component must render at least one HTML tag directly inside itself.", template.innerHTML.trim());
|
|
3313
|
-
return template.innerHTML;
|
|
3314
|
-
} else {
|
|
3315
|
-
return template.innerHTML;
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
createSpan(text, cid) {
|
|
3319
|
-
let span = document.createElement("span");
|
|
3320
|
-
span.innerText = text;
|
|
3321
|
-
span.setAttribute(PHX_COMPONENT, cid);
|
|
3322
|
-
return span;
|
|
3323
|
-
}
|
|
3324
|
-
};
|
|
3325
|
-
var viewHookID = 1;
|
|
3326
|
-
var ViewHook = class {
|
|
3327
|
-
static makeID() {
|
|
3328
|
-
return viewHookID++;
|
|
3329
|
-
}
|
|
3330
|
-
static elementID(el) {
|
|
3331
|
-
return el.phxHookId;
|
|
3332
|
-
}
|
|
3333
|
-
constructor(view, el, callbacks) {
|
|
3334
|
-
this.__view = view;
|
|
3335
|
-
this.liveSocket = view.liveSocket;
|
|
3336
|
-
this.__callbacks = callbacks;
|
|
3337
|
-
this.__listeners = /* @__PURE__ */ new Set();
|
|
3338
|
-
this.__isDisconnected = false;
|
|
3339
|
-
this.el = el;
|
|
3340
|
-
this.el.phxHookId = this.constructor.makeID();
|
|
3341
|
-
for (let key in this.__callbacks) {
|
|
3342
|
-
this[key] = this.__callbacks[key];
|
|
3343
|
-
}
|
|
3344
|
-
}
|
|
3345
|
-
__mounted() {
|
|
3346
|
-
this.mounted && this.mounted();
|
|
3347
|
-
}
|
|
3348
|
-
__updated() {
|
|
3349
|
-
this.updated && this.updated();
|
|
3350
|
-
}
|
|
3351
|
-
__beforeUpdate() {
|
|
3352
|
-
this.beforeUpdate && this.beforeUpdate();
|
|
3353
|
-
}
|
|
3354
|
-
__destroyed() {
|
|
3355
|
-
this.destroyed && this.destroyed();
|
|
3356
|
-
}
|
|
3357
|
-
__reconnected() {
|
|
3358
|
-
if (this.__isDisconnected) {
|
|
3359
|
-
this.__isDisconnected = false;
|
|
3360
|
-
this.reconnected && this.reconnected();
|
|
4548
|
+
let isRoot = rendered[ROOT];
|
|
4549
|
+
let prevBuffer = output.buffer;
|
|
4550
|
+
if (isRoot) {
|
|
4551
|
+
output.buffer = "";
|
|
3361
4552
|
}
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
handleEvent(event, callback) {
|
|
3378
|
-
let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail);
|
|
3379
|
-
window.addEventListener(`phx:${event}`, callbackRef);
|
|
3380
|
-
this.__listeners.add(callbackRef);
|
|
3381
|
-
return callbackRef;
|
|
3382
|
-
}
|
|
3383
|
-
removeHandleEvent(callbackRef) {
|
|
3384
|
-
let event = callbackRef(null, true);
|
|
3385
|
-
window.removeEventListener(`phx:${event}`, callbackRef);
|
|
3386
|
-
this.__listeners.delete(callbackRef);
|
|
3387
|
-
}
|
|
3388
|
-
upload(name, files) {
|
|
3389
|
-
return this.__view.dispatchUploads(name, files);
|
|
3390
|
-
}
|
|
3391
|
-
uploadTo(phxTarget, name, files) {
|
|
3392
|
-
return this.__view.withinTargets(phxTarget, (view) => view.dispatchUploads(name, files));
|
|
3393
|
-
}
|
|
3394
|
-
__cleanup__() {
|
|
3395
|
-
this.__listeners.forEach((callbackRef) => this.removeHandleEvent(callbackRef));
|
|
3396
|
-
}
|
|
3397
|
-
};
|
|
3398
|
-
var focusStack = null;
|
|
3399
|
-
var JS = {
|
|
3400
|
-
exec(eventType, phxEvent, view, sourceEl, defaults) {
|
|
3401
|
-
let [defaultKind, defaultArgs] = defaults || [null, {}];
|
|
3402
|
-
let commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];
|
|
3403
|
-
commands.forEach(([kind, args]) => {
|
|
3404
|
-
if (kind === defaultKind && defaultArgs.data) {
|
|
3405
|
-
args.data = Object.assign(args.data || {}, defaultArgs.data);
|
|
3406
|
-
}
|
|
3407
|
-
this.filterToEls(sourceEl, args).forEach((el) => {
|
|
3408
|
-
this[`exec_${kind}`](eventType, phxEvent, view, sourceEl, el, args);
|
|
3409
|
-
});
|
|
3410
|
-
});
|
|
3411
|
-
},
|
|
3412
|
-
isVisible(el) {
|
|
3413
|
-
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);
|
|
3414
|
-
},
|
|
3415
|
-
exec_dispatch(eventType, phxEvent, view, sourceEl, el, { to, event, detail, bubbles }) {
|
|
3416
|
-
detail = detail || {};
|
|
3417
|
-
detail.dispatcher = sourceEl;
|
|
3418
|
-
dom_default.dispatchEvent(el, event, { detail, bubbles });
|
|
3419
|
-
},
|
|
3420
|
-
exec_push(eventType, phxEvent, view, sourceEl, el, args) {
|
|
3421
|
-
if (!view.isConnected()) {
|
|
3422
|
-
return;
|
|
3423
|
-
}
|
|
3424
|
-
let { event, data, target, page_loading, loading, value, dispatcher } = args;
|
|
3425
|
-
let pushOpts = { loading, value, target, page_loading: !!page_loading };
|
|
3426
|
-
let targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;
|
|
3427
|
-
let phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
|
|
3428
|
-
view.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
3429
|
-
if (eventType === "change") {
|
|
3430
|
-
let { newCid, _target, callback } = args;
|
|
3431
|
-
_target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
|
|
3432
|
-
if (_target) {
|
|
3433
|
-
pushOpts._target = _target;
|
|
3434
|
-
}
|
|
3435
|
-
targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback);
|
|
3436
|
-
} else if (eventType === "submit") {
|
|
3437
|
-
targetView.submitForm(sourceEl, targetCtx, event || phxEvent, pushOpts);
|
|
3438
|
-
} else {
|
|
3439
|
-
targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data, pushOpts);
|
|
3440
|
-
}
|
|
3441
|
-
});
|
|
3442
|
-
},
|
|
3443
|
-
exec_navigate(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
3444
|
-
view.liveSocket.historyRedirect(href, replace ? "replace" : "push");
|
|
3445
|
-
},
|
|
3446
|
-
exec_patch(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
3447
|
-
view.liveSocket.pushHistoryPatch(href, replace ? "replace" : "push", sourceEl);
|
|
3448
|
-
},
|
|
3449
|
-
exec_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
3450
|
-
window.requestAnimationFrame(() => aria_default.attemptFocus(el));
|
|
3451
|
-
},
|
|
3452
|
-
exec_focus_first(eventType, phxEvent, view, sourceEl, el) {
|
|
3453
|
-
window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el));
|
|
3454
|
-
},
|
|
3455
|
-
exec_push_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
3456
|
-
window.requestAnimationFrame(() => focusStack = el || sourceEl);
|
|
3457
|
-
},
|
|
3458
|
-
exec_pop_focus(eventType, phxEvent, view, sourceEl, el) {
|
|
3459
|
-
window.requestAnimationFrame(() => {
|
|
3460
|
-
if (focusStack) {
|
|
3461
|
-
focusStack.focus();
|
|
3462
|
-
}
|
|
3463
|
-
focusStack = null;
|
|
3464
|
-
});
|
|
3465
|
-
},
|
|
3466
|
-
exec_add_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
|
|
3467
|
-
this.addOrRemoveClasses(el, names, [], transition, time, view);
|
|
3468
|
-
},
|
|
3469
|
-
exec_remove_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
|
|
3470
|
-
this.addOrRemoveClasses(el, [], names, transition, time, view);
|
|
3471
|
-
},
|
|
3472
|
-
exec_transition(eventType, phxEvent, view, sourceEl, el, { time, transition }) {
|
|
3473
|
-
let [transition_start, running, transition_end] = transition;
|
|
3474
|
-
let onStart = () => this.addOrRemoveClasses(el, transition_start.concat(running), []);
|
|
3475
|
-
let onDone = () => this.addOrRemoveClasses(el, transition_end, transition_start.concat(running));
|
|
3476
|
-
view.transition(time, onStart, onDone);
|
|
3477
|
-
},
|
|
3478
|
-
exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time }) {
|
|
3479
|
-
this.toggle(eventType, view, el, display, ins, outs, time);
|
|
3480
|
-
},
|
|
3481
|
-
exec_show(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
|
|
3482
|
-
this.show(eventType, view, el, display, transition, time);
|
|
3483
|
-
},
|
|
3484
|
-
exec_hide(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
|
|
3485
|
-
this.hide(eventType, view, el, display, transition, time);
|
|
3486
|
-
},
|
|
3487
|
-
exec_set_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
|
|
3488
|
-
this.setOrRemoveAttrs(el, [[attr, val]], []);
|
|
3489
|
-
},
|
|
3490
|
-
exec_remove_attr(eventType, phxEvent, view, sourceEl, el, { attr }) {
|
|
3491
|
-
this.setOrRemoveAttrs(el, [], [attr]);
|
|
3492
|
-
},
|
|
3493
|
-
show(eventType, view, el, display, transition, time) {
|
|
3494
|
-
if (!this.isVisible(el)) {
|
|
3495
|
-
this.toggle(eventType, view, el, display, transition, null, time);
|
|
3496
|
-
}
|
|
3497
|
-
},
|
|
3498
|
-
hide(eventType, view, el, display, transition, time) {
|
|
3499
|
-
if (this.isVisible(el)) {
|
|
3500
|
-
this.toggle(eventType, view, el, display, null, transition, time);
|
|
3501
|
-
}
|
|
3502
|
-
},
|
|
3503
|
-
toggle(eventType, view, el, display, ins, outs, time) {
|
|
3504
|
-
let [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
|
|
3505
|
-
let [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
|
|
3506
|
-
if (inClasses.length > 0 || outClasses.length > 0) {
|
|
3507
|
-
if (this.isVisible(el)) {
|
|
3508
|
-
let onStart = () => {
|
|
3509
|
-
this.addOrRemoveClasses(el, outStartClasses, inClasses.concat(inStartClasses).concat(inEndClasses));
|
|
3510
|
-
window.requestAnimationFrame(() => {
|
|
3511
|
-
this.addOrRemoveClasses(el, outClasses, []);
|
|
3512
|
-
window.requestAnimationFrame(() => this.addOrRemoveClasses(el, outEndClasses, outStartClasses));
|
|
3513
|
-
});
|
|
3514
|
-
};
|
|
3515
|
-
el.dispatchEvent(new Event("phx:hide-start"));
|
|
3516
|
-
view.transition(time, onStart, () => {
|
|
3517
|
-
this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));
|
|
3518
|
-
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
|
|
3519
|
-
el.dispatchEvent(new Event("phx:hide-end"));
|
|
3520
|
-
});
|
|
3521
|
-
} else {
|
|
3522
|
-
if (eventType === "remove") {
|
|
3523
|
-
return;
|
|
3524
|
-
}
|
|
3525
|
-
let onStart = () => {
|
|
3526
|
-
this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses));
|
|
3527
|
-
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = display || "block");
|
|
3528
|
-
window.requestAnimationFrame(() => {
|
|
3529
|
-
this.addOrRemoveClasses(el, inClasses, []);
|
|
3530
|
-
window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses));
|
|
3531
|
-
});
|
|
3532
|
-
};
|
|
3533
|
-
el.dispatchEvent(new Event("phx:show-start"));
|
|
3534
|
-
view.transition(time, onStart, () => {
|
|
3535
|
-
this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));
|
|
3536
|
-
el.dispatchEvent(new Event("phx:show-end"));
|
|
3537
|
-
});
|
|
3538
|
-
}
|
|
3539
|
-
} else {
|
|
3540
|
-
if (this.isVisible(el)) {
|
|
3541
|
-
window.requestAnimationFrame(() => {
|
|
3542
|
-
el.dispatchEvent(new Event("phx:hide-start"));
|
|
3543
|
-
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
|
|
3544
|
-
el.dispatchEvent(new Event("phx:hide-end"));
|
|
3545
|
-
});
|
|
4553
|
+
if (changeTracking && isRoot && !rendered.magicId) {
|
|
4554
|
+
rendered.newRender = true;
|
|
4555
|
+
rendered.magicId = this.nextMagicID();
|
|
4556
|
+
}
|
|
4557
|
+
output.buffer += statics[0];
|
|
4558
|
+
for (let i = 1; i < statics.length; i++) {
|
|
4559
|
+
this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);
|
|
4560
|
+
output.buffer += statics[i];
|
|
4561
|
+
}
|
|
4562
|
+
if (isRoot) {
|
|
4563
|
+
let skip = false;
|
|
4564
|
+
let attrs;
|
|
4565
|
+
if (changeTracking || rendered.magicId) {
|
|
4566
|
+
skip = changeTracking && !rendered.newRender;
|
|
4567
|
+
attrs = __spreadValues({ [PHX_MAGIC_ID]: rendered.magicId }, rootAttrs);
|
|
3546
4568
|
} else {
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
});
|
|
4569
|
+
attrs = rootAttrs;
|
|
4570
|
+
}
|
|
4571
|
+
if (skip) {
|
|
4572
|
+
attrs[PHX_SKIP] = true;
|
|
3552
4573
|
}
|
|
4574
|
+
let [newRoot, commentBefore, commentAfter] = modifyRoot(output.buffer, attrs, skip);
|
|
4575
|
+
rendered.newRender = false;
|
|
4576
|
+
output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;
|
|
3553
4577
|
}
|
|
3554
|
-
}
|
|
3555
|
-
|
|
3556
|
-
let [
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
4578
|
+
}
|
|
4579
|
+
comprehensionToBuffer(rendered, templates, output) {
|
|
4580
|
+
let { [DYNAMICS]: dynamics, [STATIC]: statics, [STREAM]: stream } = rendered;
|
|
4581
|
+
let [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];
|
|
4582
|
+
statics = this.templateStatic(statics, templates);
|
|
4583
|
+
let compTemplates = templates || rendered[TEMPLATES];
|
|
4584
|
+
for (let d = 0; d < dynamics.length; d++) {
|
|
4585
|
+
let dynamic = dynamics[d];
|
|
4586
|
+
output.buffer += statics[0];
|
|
4587
|
+
for (let i = 1; i < statics.length; i++) {
|
|
4588
|
+
let changeTracking = false;
|
|
4589
|
+
this.dynamicToBuffer(dynamic[i - 1], compTemplates, output, changeTracking);
|
|
4590
|
+
output.buffer += statics[i];
|
|
4591
|
+
}
|
|
3561
4592
|
}
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
4593
|
+
if (stream !== void 0 && (rendered[DYNAMICS].length > 0 || deleteIds.length > 0 || reset)) {
|
|
4594
|
+
delete rendered[STREAM];
|
|
4595
|
+
rendered[DYNAMICS] = [];
|
|
4596
|
+
output.streams.add(stream);
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
dynamicToBuffer(rendered, templates, output, changeTracking) {
|
|
4600
|
+
if (typeof rendered === "number") {
|
|
4601
|
+
let [str, streams] = this.recursiveCIDToString(output.components, rendered, output.onlyCids);
|
|
4602
|
+
output.buffer += str;
|
|
4603
|
+
output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);
|
|
4604
|
+
} else if (isObject(rendered)) {
|
|
4605
|
+
this.toOutputBuffer(rendered, templates, output, changeTracking, {});
|
|
4606
|
+
} else {
|
|
4607
|
+
output.buffer += rendered;
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
recursiveCIDToString(components, cid, onlyCids) {
|
|
4611
|
+
let component = components[cid] || logError(`no component for CID ${cid}`, components);
|
|
4612
|
+
let attrs = { [PHX_COMPONENT]: cid };
|
|
4613
|
+
let skip = onlyCids && !onlyCids.has(cid);
|
|
4614
|
+
component.newRender = !skip;
|
|
4615
|
+
component.magicId = `c${cid}-${this.parentViewId()}`;
|
|
4616
|
+
let changeTracking = !component.reset;
|
|
4617
|
+
let [html, streams] = this.recursiveToString(component, components, onlyCids, changeTracking, attrs);
|
|
4618
|
+
delete component.reset;
|
|
4619
|
+
return [html, streams];
|
|
4620
|
+
}
|
|
4621
|
+
};
|
|
4622
|
+
var viewHookID = 1;
|
|
4623
|
+
var ViewHook = class {
|
|
4624
|
+
static makeID() {
|
|
4625
|
+
return viewHookID++;
|
|
4626
|
+
}
|
|
4627
|
+
static elementID(el) {
|
|
4628
|
+
return el.phxHookId;
|
|
4629
|
+
}
|
|
4630
|
+
constructor(view, el, callbacks) {
|
|
4631
|
+
this.__view = view;
|
|
4632
|
+
this.liveSocket = view.liveSocket;
|
|
4633
|
+
this.__callbacks = callbacks;
|
|
4634
|
+
this.__listeners = /* @__PURE__ */ new Set();
|
|
4635
|
+
this.__isDisconnected = false;
|
|
4636
|
+
this.el = el;
|
|
4637
|
+
this.el.phxHookId = this.constructor.makeID();
|
|
4638
|
+
for (let key in this.__callbacks) {
|
|
4639
|
+
this[key] = this.__callbacks[key];
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
__mounted() {
|
|
4643
|
+
this.mounted && this.mounted();
|
|
4644
|
+
}
|
|
4645
|
+
__updated() {
|
|
4646
|
+
this.updated && this.updated();
|
|
4647
|
+
}
|
|
4648
|
+
__beforeUpdate() {
|
|
4649
|
+
this.beforeUpdate && this.beforeUpdate();
|
|
4650
|
+
}
|
|
4651
|
+
__destroyed() {
|
|
4652
|
+
this.destroyed && this.destroyed();
|
|
4653
|
+
}
|
|
4654
|
+
__reconnected() {
|
|
4655
|
+
if (this.__isDisconnected) {
|
|
4656
|
+
this.__isDisconnected = false;
|
|
4657
|
+
this.reconnected && this.reconnected();
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
__disconnected() {
|
|
4661
|
+
this.__isDisconnected = true;
|
|
4662
|
+
this.disconnected && this.disconnected();
|
|
4663
|
+
}
|
|
4664
|
+
pushEvent(event, payload = {}, onReply = function() {
|
|
4665
|
+
}) {
|
|
4666
|
+
return this.__view.pushHookEvent(this.el, null, event, payload, onReply);
|
|
4667
|
+
}
|
|
4668
|
+
pushEventTo(phxTarget, event, payload = {}, onReply = function() {
|
|
4669
|
+
}) {
|
|
4670
|
+
return this.__view.withinTargets(phxTarget, (view, targetCtx) => {
|
|
4671
|
+
return view.pushHookEvent(this.el, targetCtx, event, payload, onReply);
|
|
3573
4672
|
});
|
|
3574
|
-
}
|
|
3575
|
-
|
|
3576
|
-
let
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
4673
|
+
}
|
|
4674
|
+
handleEvent(event, callback) {
|
|
4675
|
+
let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail);
|
|
4676
|
+
window.addEventListener(`phx:${event}`, callbackRef);
|
|
4677
|
+
this.__listeners.add(callbackRef);
|
|
4678
|
+
return callbackRef;
|
|
4679
|
+
}
|
|
4680
|
+
removeHandleEvent(callbackRef) {
|
|
4681
|
+
let event = callbackRef(null, true);
|
|
4682
|
+
window.removeEventListener(`phx:${event}`, callbackRef);
|
|
4683
|
+
this.__listeners.delete(callbackRef);
|
|
4684
|
+
}
|
|
4685
|
+
upload(name, files) {
|
|
4686
|
+
return this.__view.dispatchUploads(null, name, files);
|
|
4687
|
+
}
|
|
4688
|
+
uploadTo(phxTarget, name, files) {
|
|
4689
|
+
return this.__view.withinTargets(phxTarget, (view, targetCtx) => {
|
|
4690
|
+
view.dispatchUploads(targetCtx, name, files);
|
|
3584
4691
|
});
|
|
3585
|
-
}
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
},
|
|
3589
|
-
isToggledOut(el, outClasses) {
|
|
3590
|
-
return !this.isVisible(el) || this.hasAllClasses(el, outClasses);
|
|
3591
|
-
},
|
|
3592
|
-
filterToEls(sourceEl, { to }) {
|
|
3593
|
-
return to ? dom_default.all(document, to) : [sourceEl];
|
|
4692
|
+
}
|
|
4693
|
+
__cleanup__() {
|
|
4694
|
+
this.__listeners.forEach((callbackRef) => this.removeHandleEvent(callbackRef));
|
|
3594
4695
|
}
|
|
3595
4696
|
};
|
|
3596
|
-
var
|
|
3597
|
-
|
|
3598
|
-
let
|
|
3599
|
-
|
|
4697
|
+
var serializeForm = (form, metadata, onlyNames = []) => {
|
|
4698
|
+
const _a2 = metadata, { submitter } = _a2, meta = __objRest(_a2, ["submitter"]);
|
|
4699
|
+
let injectedElement;
|
|
4700
|
+
if (submitter && submitter.name) {
|
|
4701
|
+
const input = document.createElement("input");
|
|
4702
|
+
input.type = "hidden";
|
|
4703
|
+
const formId = submitter.getAttribute("form");
|
|
4704
|
+
if (formId) {
|
|
4705
|
+
input.setAttribute("form", formId);
|
|
4706
|
+
}
|
|
4707
|
+
input.name = submitter.name;
|
|
4708
|
+
input.value = submitter.value;
|
|
4709
|
+
submitter.parentElement.insertBefore(input, submitter);
|
|
4710
|
+
injectedElement = input;
|
|
4711
|
+
}
|
|
4712
|
+
const formData = new FormData(form);
|
|
4713
|
+
const toRemove = [];
|
|
3600
4714
|
formData.forEach((val, key, _index) => {
|
|
3601
4715
|
if (val instanceof File) {
|
|
3602
4716
|
toRemove.push(key);
|
|
3603
4717
|
}
|
|
3604
4718
|
});
|
|
3605
4719
|
toRemove.forEach((key) => formData.delete(key));
|
|
3606
|
-
|
|
4720
|
+
const params = new URLSearchParams();
|
|
3607
4721
|
for (let [key, val] of formData.entries()) {
|
|
3608
4722
|
if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {
|
|
3609
4723
|
params.append(key, val);
|
|
3610
4724
|
}
|
|
3611
4725
|
}
|
|
4726
|
+
if (submitter && injectedElement) {
|
|
4727
|
+
submitter.parentElement.removeChild(injectedElement);
|
|
4728
|
+
}
|
|
3612
4729
|
for (let metaKey in meta) {
|
|
3613
4730
|
params.append(metaKey, meta[metaKey]);
|
|
3614
4731
|
}
|
|
@@ -3627,7 +4744,7 @@ within:
|
|
|
3627
4744
|
this.childJoins = 0;
|
|
3628
4745
|
this.loaderTimer = null;
|
|
3629
4746
|
this.pendingDiffs = [];
|
|
3630
|
-
this.
|
|
4747
|
+
this.pendingForms = /* @__PURE__ */ new Set();
|
|
3631
4748
|
this.redirect = false;
|
|
3632
4749
|
this.href = null;
|
|
3633
4750
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
|
|
@@ -3640,14 +4757,15 @@ within:
|
|
|
3640
4757
|
};
|
|
3641
4758
|
this.pendingJoinOps = this.parent ? null : [];
|
|
3642
4759
|
this.viewHooks = {};
|
|
3643
|
-
this.uploaders = {};
|
|
3644
4760
|
this.formSubmits = [];
|
|
3645
4761
|
this.children = this.parent ? null : {};
|
|
3646
4762
|
this.root.children[this.id] = {};
|
|
4763
|
+
this.formsForRecovery = {};
|
|
3647
4764
|
this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {
|
|
4765
|
+
let url = this.href && this.expandURL(this.href);
|
|
3648
4766
|
return {
|
|
3649
|
-
redirect: this.redirect ?
|
|
3650
|
-
url: this.redirect ? void 0 :
|
|
4767
|
+
redirect: this.redirect ? url : void 0,
|
|
4768
|
+
url: this.redirect ? void 0 : url || void 0,
|
|
3651
4769
|
params: this.connectParams(liveReferer),
|
|
3652
4770
|
session: this.getSession(),
|
|
3653
4771
|
static: this.getStatic(),
|
|
@@ -3705,7 +4823,7 @@ within:
|
|
|
3705
4823
|
this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished);
|
|
3706
4824
|
}
|
|
3707
4825
|
setContainerClasses(...classes) {
|
|
3708
|
-
this.el.classList.remove(PHX_CONNECTED_CLASS,
|
|
4826
|
+
this.el.classList.remove(PHX_CONNECTED_CLASS, PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS, PHX_SERVER_ERROR_CLASS);
|
|
3709
4827
|
this.el.classList.add(...classes);
|
|
3710
4828
|
}
|
|
3711
4829
|
showLoader(timeout) {
|
|
@@ -3716,7 +4834,7 @@ within:
|
|
|
3716
4834
|
for (let id in this.viewHooks) {
|
|
3717
4835
|
this.viewHooks[id].__disconnected();
|
|
3718
4836
|
}
|
|
3719
|
-
this.setContainerClasses(
|
|
4837
|
+
this.setContainerClasses(PHX_LOADING_CLASS);
|
|
3720
4838
|
}
|
|
3721
4839
|
}
|
|
3722
4840
|
execAll(binding) {
|
|
@@ -3739,19 +4857,19 @@ within:
|
|
|
3739
4857
|
}) {
|
|
3740
4858
|
this.liveSocket.transition(time, onStart, onDone);
|
|
3741
4859
|
}
|
|
3742
|
-
withinTargets(phxTarget, callback) {
|
|
4860
|
+
withinTargets(phxTarget, callback, dom = document, viewEl) {
|
|
3743
4861
|
if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {
|
|
3744
4862
|
return this.liveSocket.owner(phxTarget, (view) => callback(view, phxTarget));
|
|
3745
4863
|
}
|
|
3746
4864
|
if (isCid(phxTarget)) {
|
|
3747
|
-
let targets = dom_default.findComponentNodeList(this.el, phxTarget);
|
|
4865
|
+
let targets = dom_default.findComponentNodeList(viewEl || this.el, phxTarget);
|
|
3748
4866
|
if (targets.length === 0) {
|
|
3749
4867
|
logError(`no component found matching phx-target of ${phxTarget}`);
|
|
3750
4868
|
} else {
|
|
3751
4869
|
callback(this, parseInt(phxTarget));
|
|
3752
4870
|
}
|
|
3753
4871
|
} else {
|
|
3754
|
-
let targets = Array.from(
|
|
4872
|
+
let targets = Array.from(dom.querySelectorAll(phxTarget));
|
|
3755
4873
|
if (targets.length === 0) {
|
|
3756
4874
|
logError(`nothing found matching the phx-target selector "${phxTarget}"`);
|
|
3757
4875
|
}
|
|
@@ -3762,12 +4880,12 @@ within:
|
|
|
3762
4880
|
this.log(type, () => ["", clone(rawDiff)]);
|
|
3763
4881
|
let { diff, reply, events, title } = Rendered.extract(rawDiff);
|
|
3764
4882
|
callback({ diff, reply, events });
|
|
3765
|
-
if (title) {
|
|
4883
|
+
if (typeof title === "string") {
|
|
3766
4884
|
window.requestAnimationFrame(() => dom_default.putTitle(title));
|
|
3767
4885
|
}
|
|
3768
4886
|
}
|
|
3769
4887
|
onJoin(resp) {
|
|
3770
|
-
let { rendered, container } = resp;
|
|
4888
|
+
let { rendered, container, liveview_version } = resp;
|
|
3771
4889
|
if (container) {
|
|
3772
4890
|
let [tag, attrs] = container;
|
|
3773
4891
|
this.el = dom_default.replaceRootContainer(this.el, tag, attrs);
|
|
@@ -3775,24 +4893,21 @@ within:
|
|
|
3775
4893
|
this.childJoins = 0;
|
|
3776
4894
|
this.joinPending = true;
|
|
3777
4895
|
this.flash = null;
|
|
4896
|
+
if (this.root === this) {
|
|
4897
|
+
this.formsForRecovery = this.getFormsForRecovery();
|
|
4898
|
+
}
|
|
4899
|
+
if (liveview_version !== this.liveSocket.version()) {
|
|
4900
|
+
console.error(`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`);
|
|
4901
|
+
}
|
|
3778
4902
|
browser_default.dropLocal(this.liveSocket.localStorage, window.location.pathname, CONSECUTIVE_RELOADS);
|
|
3779
4903
|
this.applyDiff("mount", rendered, ({ diff, events }) => {
|
|
3780
4904
|
this.rendered = new Rendered(this.id, diff);
|
|
3781
|
-
let html = this.renderContainer(null, "join");
|
|
4905
|
+
let [html, streams] = this.renderContainer(null, "join");
|
|
3782
4906
|
this.dropPendingRefs();
|
|
3783
|
-
let forms = this.formsForRecovery(html);
|
|
3784
4907
|
this.joinCount++;
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
if (i === forms.length - 1) {
|
|
3789
|
-
this.onJoinComplete(resp2, html, events);
|
|
3790
|
-
}
|
|
3791
|
-
});
|
|
3792
|
-
});
|
|
3793
|
-
} else {
|
|
3794
|
-
this.onJoinComplete(resp, html, events);
|
|
3795
|
-
}
|
|
4908
|
+
this.maybeRecoverForms(html, () => {
|
|
4909
|
+
this.onJoinComplete(resp, html, streams, events);
|
|
4910
|
+
});
|
|
3796
4911
|
});
|
|
3797
4912
|
}
|
|
3798
4913
|
dropPendingRefs() {
|
|
@@ -3801,9 +4916,9 @@ within:
|
|
|
3801
4916
|
el.removeAttribute(PHX_REF_SRC);
|
|
3802
4917
|
});
|
|
3803
4918
|
}
|
|
3804
|
-
onJoinComplete({ live_patch }, html, events) {
|
|
4919
|
+
onJoinComplete({ live_patch }, html, streams, events) {
|
|
3805
4920
|
if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {
|
|
3806
|
-
return this.applyJoinPatch(live_patch, html, events);
|
|
4921
|
+
return this.applyJoinPatch(live_patch, html, streams, events);
|
|
3807
4922
|
}
|
|
3808
4923
|
let newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter((toEl) => {
|
|
3809
4924
|
let fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);
|
|
@@ -3811,18 +4926,21 @@ within:
|
|
|
3811
4926
|
if (phxStatic) {
|
|
3812
4927
|
toEl.setAttribute(PHX_STATIC, phxStatic);
|
|
3813
4928
|
}
|
|
4929
|
+
if (fromEl) {
|
|
4930
|
+
fromEl.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
4931
|
+
}
|
|
3814
4932
|
return this.joinChild(toEl);
|
|
3815
4933
|
});
|
|
3816
4934
|
if (newChildren.length === 0) {
|
|
3817
4935
|
if (this.parent) {
|
|
3818
|
-
this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, events)]);
|
|
4936
|
+
this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]);
|
|
3819
4937
|
this.parent.ackJoin(this);
|
|
3820
4938
|
} else {
|
|
3821
4939
|
this.onAllChildJoinsComplete();
|
|
3822
|
-
this.applyJoinPatch(live_patch, html, events);
|
|
4940
|
+
this.applyJoinPatch(live_patch, html, streams, events);
|
|
3823
4941
|
}
|
|
3824
4942
|
} else {
|
|
3825
|
-
this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, events)]);
|
|
4943
|
+
this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]);
|
|
3826
4944
|
}
|
|
3827
4945
|
}
|
|
3828
4946
|
attachTrueDocEl() {
|
|
@@ -3830,16 +4948,30 @@ within:
|
|
|
3830
4948
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
3831
4949
|
}
|
|
3832
4950
|
execNewMounted() {
|
|
4951
|
+
let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
|
|
4952
|
+
let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
|
|
4953
|
+
dom_default.all(this.el, `[${phxViewportTop}], [${phxViewportBottom}]`, (hookEl) => {
|
|
4954
|
+
if (this.ownsElement(hookEl)) {
|
|
4955
|
+
dom_default.maybeAddPrivateHooks(hookEl, phxViewportTop, phxViewportBottom);
|
|
4956
|
+
this.maybeAddNewHook(hookEl);
|
|
4957
|
+
}
|
|
4958
|
+
});
|
|
3833
4959
|
dom_default.all(this.el, `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`, (hookEl) => {
|
|
3834
|
-
this.
|
|
4960
|
+
if (this.ownsElement(hookEl)) {
|
|
4961
|
+
this.maybeAddNewHook(hookEl);
|
|
4962
|
+
}
|
|
4963
|
+
});
|
|
4964
|
+
dom_default.all(this.el, `[${this.binding(PHX_MOUNTED)}]`, (el) => {
|
|
4965
|
+
if (this.ownsElement(el)) {
|
|
4966
|
+
this.maybeMounted(el);
|
|
4967
|
+
}
|
|
3835
4968
|
});
|
|
3836
|
-
dom_default.all(this.el, `[${this.binding(PHX_MOUNTED)}]`, (el) => this.maybeMounted(el));
|
|
3837
4969
|
}
|
|
3838
|
-
applyJoinPatch(live_patch, html, events) {
|
|
4970
|
+
applyJoinPatch(live_patch, html, streams, events) {
|
|
3839
4971
|
this.attachTrueDocEl();
|
|
3840
|
-
let patch = new DOMPatch(this, this.el, this.id, html, null);
|
|
4972
|
+
let patch = new DOMPatch(this, this.el, this.id, html, streams, null);
|
|
3841
4973
|
patch.markPrunableContentForRemoval();
|
|
3842
|
-
this.performPatch(patch, false);
|
|
4974
|
+
this.performPatch(patch, false, true);
|
|
3843
4975
|
this.joinNewChildren();
|
|
3844
4976
|
this.execNewMounted();
|
|
3845
4977
|
this.joinPending = false;
|
|
@@ -3878,12 +5010,15 @@ within:
|
|
|
3878
5010
|
newHook.__mounted();
|
|
3879
5011
|
}
|
|
3880
5012
|
}
|
|
3881
|
-
performPatch(patch, pruneCids) {
|
|
5013
|
+
performPatch(patch, pruneCids, isJoinPatch = false) {
|
|
3882
5014
|
let removedEls = [];
|
|
3883
5015
|
let phxChildrenAdded = false;
|
|
3884
5016
|
let updatedHookIds = /* @__PURE__ */ new Set();
|
|
3885
5017
|
patch.after("added", (el) => {
|
|
3886
5018
|
this.liveSocket.triggerDOM("onNodeAdded", [el]);
|
|
5019
|
+
let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
|
|
5020
|
+
let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
|
|
5021
|
+
dom_default.maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom);
|
|
3887
5022
|
this.maybeAddNewHook(el);
|
|
3888
5023
|
if (el.getAttribute) {
|
|
3889
5024
|
this.maybeMounted(el);
|
|
@@ -3913,7 +5048,7 @@ within:
|
|
|
3913
5048
|
}
|
|
3914
5049
|
});
|
|
3915
5050
|
patch.after("transitionsDiscarded", (els) => this.afterElementsRemoved(els, pruneCids));
|
|
3916
|
-
patch.perform();
|
|
5051
|
+
patch.perform(isJoinPatch);
|
|
3917
5052
|
this.afterElementsRemoved(removedEls, pruneCids);
|
|
3918
5053
|
return phxChildrenAdded;
|
|
3919
5054
|
}
|
|
@@ -3940,6 +5075,33 @@ within:
|
|
|
3940
5075
|
joinNewChildren() {
|
|
3941
5076
|
dom_default.findPhxChildren(this.el, this.id).forEach((el) => this.joinChild(el));
|
|
3942
5077
|
}
|
|
5078
|
+
maybeRecoverForms(html, callback) {
|
|
5079
|
+
const phxChange = this.binding("change");
|
|
5080
|
+
const oldForms = this.root.formsForRecovery;
|
|
5081
|
+
let template = document.createElement("template");
|
|
5082
|
+
template.innerHTML = html;
|
|
5083
|
+
const rootEl = template.content.firstElementChild;
|
|
5084
|
+
rootEl.id = this.id;
|
|
5085
|
+
rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
5086
|
+
rootEl.setAttribute(PHX_SESSION, this.getSession());
|
|
5087
|
+
rootEl.setAttribute(PHX_STATIC, this.getStatic());
|
|
5088
|
+
rootEl.setAttribute(PHX_PARENT_ID, this.parent ? this.parent.id : null);
|
|
5089
|
+
const formsToRecover = dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter((newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)).map((newForm) => {
|
|
5090
|
+
return [oldForms[newForm.id], newForm];
|
|
5091
|
+
});
|
|
5092
|
+
if (formsToRecover.length === 0) {
|
|
5093
|
+
return callback();
|
|
5094
|
+
}
|
|
5095
|
+
formsToRecover.forEach(([oldForm, newForm], i) => {
|
|
5096
|
+
this.pendingForms.add(newForm.id);
|
|
5097
|
+
this.pushFormRecovery(oldForm, newForm, template.content, () => {
|
|
5098
|
+
this.pendingForms.delete(newForm.id);
|
|
5099
|
+
if (i === formsToRecover.length - 1) {
|
|
5100
|
+
callback();
|
|
5101
|
+
}
|
|
5102
|
+
});
|
|
5103
|
+
});
|
|
5104
|
+
}
|
|
3943
5105
|
getChildById(id) {
|
|
3944
5106
|
return this.root.children[this.id][id];
|
|
3945
5107
|
}
|
|
@@ -3983,6 +5145,8 @@ within:
|
|
|
3983
5145
|
}
|
|
3984
5146
|
}
|
|
3985
5147
|
onAllChildJoinsComplete() {
|
|
5148
|
+
this.pendingForms.clear();
|
|
5149
|
+
this.formsForRecovery = {};
|
|
3986
5150
|
this.joinCallback(() => {
|
|
3987
5151
|
this.pendingJoinOps.forEach(([view, op]) => {
|
|
3988
5152
|
if (!view.isDestroyed()) {
|
|
@@ -4000,7 +5164,7 @@ within:
|
|
|
4000
5164
|
let phxChildrenAdded = false;
|
|
4001
5165
|
if (this.rendered.isComponentOnlyDiff(diff)) {
|
|
4002
5166
|
this.liveSocket.time("component patch complete", () => {
|
|
4003
|
-
let parentCids = dom_default.
|
|
5167
|
+
let parentCids = dom_default.findExistingParentCIDs(this.el, this.rendered.componentCIDs(diff));
|
|
4004
5168
|
parentCids.forEach((parentCID) => {
|
|
4005
5169
|
if (this.componentPatch(this.rendered.getComponent(diff, parentCID), parentCID)) {
|
|
4006
5170
|
phxChildrenAdded = true;
|
|
@@ -4009,8 +5173,8 @@ within:
|
|
|
4009
5173
|
});
|
|
4010
5174
|
} else if (!isEmpty(diff)) {
|
|
4011
5175
|
this.liveSocket.time("full patch complete", () => {
|
|
4012
|
-
let html = this.renderContainer(diff, "update");
|
|
4013
|
-
let patch = new DOMPatch(this, this.el, this.id, html, null);
|
|
5176
|
+
let [html, streams] = this.renderContainer(diff, "update");
|
|
5177
|
+
let patch = new DOMPatch(this, this.el, this.id, html, streams, null);
|
|
4014
5178
|
phxChildrenAdded = this.performPatch(patch, true);
|
|
4015
5179
|
});
|
|
4016
5180
|
}
|
|
@@ -4022,16 +5186,16 @@ within:
|
|
|
4022
5186
|
renderContainer(diff, kind) {
|
|
4023
5187
|
return this.liveSocket.time(`toString diff (${kind})`, () => {
|
|
4024
5188
|
let tag = this.el.tagName;
|
|
4025
|
-
let cids = diff ? this.rendered.componentCIDs(diff)
|
|
4026
|
-
let html = this.rendered.toString(cids);
|
|
4027
|
-
return `<${tag}>${html}</${tag}
|
|
5189
|
+
let cids = diff ? this.rendered.componentCIDs(diff) : null;
|
|
5190
|
+
let [html, streams] = this.rendered.toString(cids);
|
|
5191
|
+
return [`<${tag}>${html}</${tag}>`, streams];
|
|
4028
5192
|
});
|
|
4029
5193
|
}
|
|
4030
5194
|
componentPatch(diff, cid) {
|
|
4031
5195
|
if (isEmpty(diff))
|
|
4032
5196
|
return false;
|
|
4033
|
-
let html = this.rendered.componentToString(cid);
|
|
4034
|
-
let patch = new DOMPatch(this, this.el, this.id, html, cid);
|
|
5197
|
+
let [html, streams] = this.rendered.componentToString(cid);
|
|
5198
|
+
let patch = new DOMPatch(this, this.el, this.id, html, streams, cid);
|
|
4035
5199
|
let childrenAdded = this.performPatch(patch, true);
|
|
4036
5200
|
return childrenAdded;
|
|
4037
5201
|
}
|
|
@@ -4140,9 +5304,18 @@ within:
|
|
|
4140
5304
|
});
|
|
4141
5305
|
}
|
|
4142
5306
|
onJoinError(resp) {
|
|
4143
|
-
if (resp.reason === "
|
|
5307
|
+
if (resp.reason === "reload") {
|
|
5308
|
+
this.log("error", () => [`failed mount with ${resp.status}. Falling back to page request`, resp]);
|
|
5309
|
+
if (this.isMain()) {
|
|
5310
|
+
this.onRedirect({ to: this.href });
|
|
5311
|
+
}
|
|
5312
|
+
return;
|
|
5313
|
+
} else if (resp.reason === "unauthorized" || resp.reason === "stale") {
|
|
4144
5314
|
this.log("error", () => ["unauthorized live_redirect. Falling back to page request", resp]);
|
|
4145
|
-
|
|
5315
|
+
if (this.isMain()) {
|
|
5316
|
+
this.onRedirect({ to: this.href });
|
|
5317
|
+
}
|
|
5318
|
+
return;
|
|
4146
5319
|
}
|
|
4147
5320
|
if (resp.redirect || resp.live_redirect) {
|
|
4148
5321
|
this.joinPending = false;
|
|
@@ -4154,6 +5327,7 @@ within:
|
|
|
4154
5327
|
if (resp.live_redirect) {
|
|
4155
5328
|
return this.onLiveRedirect(resp.live_redirect);
|
|
4156
5329
|
}
|
|
5330
|
+
this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]);
|
|
4157
5331
|
this.log("error", () => ["unable to join", resp]);
|
|
4158
5332
|
if (this.liveSocket.isConnected()) {
|
|
4159
5333
|
this.liveSocket.reloadWithJitter(this);
|
|
@@ -4181,15 +5355,19 @@ within:
|
|
|
4181
5355
|
this.log("error", () => ["view crashed", reason]);
|
|
4182
5356
|
}
|
|
4183
5357
|
if (!this.liveSocket.isUnloaded()) {
|
|
4184
|
-
this.
|
|
5358
|
+
if (this.liveSocket.isConnected()) {
|
|
5359
|
+
this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]);
|
|
5360
|
+
} else {
|
|
5361
|
+
this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS]);
|
|
5362
|
+
}
|
|
4185
5363
|
}
|
|
4186
5364
|
}
|
|
4187
|
-
displayError() {
|
|
5365
|
+
displayError(classes) {
|
|
4188
5366
|
if (this.isMain()) {
|
|
4189
5367
|
dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: { to: this.href, kind: "error" } });
|
|
4190
5368
|
}
|
|
4191
5369
|
this.showLoader();
|
|
4192
|
-
this.setContainerClasses(
|
|
5370
|
+
this.setContainerClasses(...classes);
|
|
4193
5371
|
this.execAll(this.binding("disconnected"));
|
|
4194
5372
|
}
|
|
4195
5373
|
pushWithReply(refGenerator, event, payload, onReply = function() {
|
|
@@ -4218,35 +5396,44 @@ within:
|
|
|
4218
5396
|
if (resp.live_redirect) {
|
|
4219
5397
|
this.onLiveRedirect(resp.live_redirect);
|
|
4220
5398
|
}
|
|
4221
|
-
if (ref !== null) {
|
|
4222
|
-
this.undoRefs(ref);
|
|
4223
|
-
}
|
|
4224
5399
|
onLoadingDone();
|
|
4225
5400
|
onReply(resp, hookReply);
|
|
4226
5401
|
};
|
|
4227
5402
|
if (resp.diff) {
|
|
4228
5403
|
this.liveSocket.requestDOMUpdate(() => {
|
|
4229
5404
|
this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {
|
|
5405
|
+
if (ref !== null) {
|
|
5406
|
+
this.undoRefs(ref);
|
|
5407
|
+
}
|
|
4230
5408
|
this.update(diff, events);
|
|
4231
5409
|
finish(reply);
|
|
4232
5410
|
});
|
|
4233
5411
|
});
|
|
4234
5412
|
} else {
|
|
5413
|
+
if (ref !== null) {
|
|
5414
|
+
this.undoRefs(ref);
|
|
5415
|
+
}
|
|
4235
5416
|
finish(null);
|
|
4236
5417
|
}
|
|
4237
5418
|
});
|
|
4238
5419
|
});
|
|
4239
5420
|
}
|
|
4240
|
-
undoRefs(ref) {
|
|
5421
|
+
undoRefs(ref, onlyEls) {
|
|
5422
|
+
onlyEls = onlyEls ? new Set(onlyEls) : null;
|
|
4241
5423
|
if (!this.isConnected()) {
|
|
4242
5424
|
return;
|
|
4243
5425
|
}
|
|
4244
5426
|
dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}="${ref}"]`, (el) => {
|
|
5427
|
+
if (onlyEls && !onlyEls.has(el)) {
|
|
5428
|
+
return;
|
|
5429
|
+
}
|
|
5430
|
+
el.dispatchEvent(new CustomEvent("phx:unlock", { bubbles: true, cancelable: false }));
|
|
4245
5431
|
let disabledVal = el.getAttribute(PHX_DISABLED);
|
|
5432
|
+
let readOnlyVal = el.getAttribute(PHX_READONLY);
|
|
4246
5433
|
el.removeAttribute(PHX_REF);
|
|
4247
5434
|
el.removeAttribute(PHX_REF_SRC);
|
|
4248
|
-
if (
|
|
4249
|
-
el.readOnly = false;
|
|
5435
|
+
if (readOnlyVal !== null) {
|
|
5436
|
+
el.readOnly = readOnlyVal === "true" ? true : false;
|
|
4250
5437
|
el.removeAttribute(PHX_READONLY);
|
|
4251
5438
|
}
|
|
4252
5439
|
if (disabledVal !== null) {
|
|
@@ -4276,10 +5463,14 @@ within:
|
|
|
4276
5463
|
if (opts.loading) {
|
|
4277
5464
|
elements = elements.concat(dom_default.all(document, opts.loading));
|
|
4278
5465
|
}
|
|
4279
|
-
|
|
4280
|
-
el.classList.add(`phx-${event}-loading`);
|
|
5466
|
+
for (let el of elements) {
|
|
4281
5467
|
el.setAttribute(PHX_REF, newRef);
|
|
4282
5468
|
el.setAttribute(PHX_REF_SRC, this.el.id);
|
|
5469
|
+
if (opts.submitter && !(el === opts.submitter || el === opts.form)) {
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
el.classList.add(`phx-${event}-loading`);
|
|
5473
|
+
el.dispatchEvent(new CustomEvent(`phx:${event}-loading`, { bubbles: true, cancelable: false }));
|
|
4283
5474
|
let disableText = el.getAttribute(disableWith);
|
|
4284
5475
|
if (disableText !== null) {
|
|
4285
5476
|
if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {
|
|
@@ -4288,9 +5479,10 @@ within:
|
|
|
4288
5479
|
if (disableText !== "") {
|
|
4289
5480
|
el.innerText = disableText;
|
|
4290
5481
|
}
|
|
5482
|
+
el.setAttribute(PHX_DISABLED, el.getAttribute(PHX_DISABLED) || el.disabled);
|
|
4291
5483
|
el.setAttribute("disabled", "");
|
|
4292
5484
|
}
|
|
4293
|
-
}
|
|
5485
|
+
}
|
|
4294
5486
|
return [newRef, elements, opts];
|
|
4295
5487
|
}
|
|
4296
5488
|
componentID(el) {
|
|
@@ -4301,7 +5493,7 @@ within:
|
|
|
4301
5493
|
if (isCid(targetCtx)) {
|
|
4302
5494
|
return targetCtx;
|
|
4303
5495
|
}
|
|
4304
|
-
let cidOrSelector = target.getAttribute(this.binding("target"));
|
|
5496
|
+
let cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
|
|
4305
5497
|
if (isCid(cidOrSelector)) {
|
|
4306
5498
|
return parseInt(cidOrSelector);
|
|
4307
5499
|
} else if (targetCtx && (cidOrSelector !== null || opts.target)) {
|
|
@@ -4319,12 +5511,12 @@ within:
|
|
|
4319
5511
|
return null;
|
|
4320
5512
|
}
|
|
4321
5513
|
}
|
|
4322
|
-
pushHookEvent(targetCtx, event, payload, onReply) {
|
|
5514
|
+
pushHookEvent(el, targetCtx, event, payload, onReply) {
|
|
4323
5515
|
if (!this.isConnected()) {
|
|
4324
5516
|
this.log("hook", () => ["unable to push hook event. LiveView not connected", event, payload]);
|
|
4325
5517
|
return false;
|
|
4326
5518
|
}
|
|
4327
|
-
let [ref, els, opts] = this.putRef([], "hook");
|
|
5519
|
+
let [ref, els, opts] = this.putRef([el], "hook");
|
|
4328
5520
|
this.pushWithReply(() => [ref, els, opts], "event", {
|
|
4329
5521
|
type: "hook",
|
|
4330
5522
|
event,
|
|
@@ -4344,7 +5536,7 @@ within:
|
|
|
4344
5536
|
meta[name.replace(prefix, "")] = el.getAttribute(name);
|
|
4345
5537
|
}
|
|
4346
5538
|
}
|
|
4347
|
-
if (el.value !== void 0) {
|
|
5539
|
+
if (el.value !== void 0 && !(el instanceof HTMLFormElement)) {
|
|
4348
5540
|
if (!meta) {
|
|
4349
5541
|
meta = {};
|
|
4350
5542
|
}
|
|
@@ -4363,13 +5555,13 @@ within:
|
|
|
4363
5555
|
}
|
|
4364
5556
|
return meta;
|
|
4365
5557
|
}
|
|
4366
|
-
pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}) {
|
|
5558
|
+
pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) {
|
|
4367
5559
|
this.pushWithReply(() => this.putRef([el], type, opts), "event", {
|
|
4368
5560
|
type,
|
|
4369
5561
|
event: phxEvent,
|
|
4370
5562
|
value: this.extractMeta(el, meta, opts.value),
|
|
4371
5563
|
cid: this.targetComponentID(el, targetCtx, opts)
|
|
4372
|
-
});
|
|
5564
|
+
}, (resp, reply) => onReply && onReply(reply));
|
|
4373
5565
|
}
|
|
4374
5566
|
pushFileProgress(fileEl, entryRef, progress, onReply = function() {
|
|
4375
5567
|
}) {
|
|
@@ -4385,13 +5577,17 @@ within:
|
|
|
4385
5577
|
}
|
|
4386
5578
|
pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {
|
|
4387
5579
|
let uploads;
|
|
4388
|
-
let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx);
|
|
5580
|
+
let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);
|
|
4389
5581
|
let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts);
|
|
4390
5582
|
let formData;
|
|
5583
|
+
let meta = this.extractMeta(inputEl.form);
|
|
5584
|
+
if (inputEl instanceof HTMLButtonElement) {
|
|
5585
|
+
meta.submitter = inputEl;
|
|
5586
|
+
}
|
|
4391
5587
|
if (inputEl.getAttribute(this.binding("change"))) {
|
|
4392
|
-
formData = serializeForm(inputEl.form, { _target: opts._target }, [inputEl.name]);
|
|
5588
|
+
formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta), [inputEl.name]);
|
|
4393
5589
|
} else {
|
|
4394
|
-
formData = serializeForm(inputEl.form, { _target: opts._target });
|
|
5590
|
+
formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta));
|
|
4395
5591
|
}
|
|
4396
5592
|
if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {
|
|
4397
5593
|
LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));
|
|
@@ -4405,13 +5601,15 @@ within:
|
|
|
4405
5601
|
cid
|
|
4406
5602
|
};
|
|
4407
5603
|
this.pushWithReply(refGenerator, "event", event, (resp) => {
|
|
4408
|
-
dom_default.showError(inputEl, this.liveSocket.binding(PHX_FEEDBACK_FOR));
|
|
4409
|
-
if (dom_default.isUploadInput(inputEl) &&
|
|
5604
|
+
dom_default.showError(inputEl, this.liveSocket.binding(PHX_FEEDBACK_FOR), this.liveSocket.binding(PHX_FEEDBACK_GROUP));
|
|
5605
|
+
if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) {
|
|
4410
5606
|
if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {
|
|
4411
5607
|
let [ref, _els] = refGenerator();
|
|
5608
|
+
this.undoRefs(ref, [inputEl.form]);
|
|
4412
5609
|
this.uploadFiles(inputEl.form, targetCtx, ref, cid, (_uploads) => {
|
|
4413
5610
|
callback && callback(resp);
|
|
4414
5611
|
this.triggerAwaitingSubmit(inputEl.form);
|
|
5612
|
+
this.undoRefs(ref);
|
|
4415
5613
|
});
|
|
4416
5614
|
}
|
|
4417
5615
|
} else {
|
|
@@ -4475,18 +5673,22 @@ within:
|
|
|
4475
5673
|
formEl.setAttribute(this.binding(PHX_PAGE_LOADING), "");
|
|
4476
5674
|
return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts);
|
|
4477
5675
|
}
|
|
4478
|
-
pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply) {
|
|
4479
|
-
let refGenerator = () => this.disableForm(formEl, opts);
|
|
5676
|
+
pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {
|
|
5677
|
+
let refGenerator = () => this.disableForm(formEl, __spreadProps(__spreadValues({}, opts), { form: formEl, submitter }));
|
|
4480
5678
|
let cid = this.targetComponentID(formEl, targetCtx);
|
|
4481
5679
|
if (LiveUploader.hasUploadsInProgress(formEl)) {
|
|
4482
5680
|
let [ref, _els] = refGenerator();
|
|
4483
|
-
let push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply);
|
|
5681
|
+
let push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply);
|
|
4484
5682
|
return this.scheduleSubmit(formEl, ref, opts, push);
|
|
4485
5683
|
} else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
4486
5684
|
let [ref, els] = refGenerator();
|
|
4487
5685
|
let proxyRefGen = () => [ref, els, opts];
|
|
4488
|
-
this.uploadFiles(formEl, targetCtx, ref, cid, (
|
|
4489
|
-
|
|
5686
|
+
this.uploadFiles(formEl, targetCtx, ref, cid, (uploads) => {
|
|
5687
|
+
if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
5688
|
+
return this.undoRefs(ref);
|
|
5689
|
+
}
|
|
5690
|
+
let meta = this.extractMeta(formEl);
|
|
5691
|
+
let formData = serializeForm(formEl, __spreadValues({ submitter }, meta));
|
|
4490
5692
|
this.pushWithReply(proxyRefGen, "event", {
|
|
4491
5693
|
type: "form",
|
|
4492
5694
|
event: phxEvent,
|
|
@@ -4494,8 +5696,9 @@ within:
|
|
|
4494
5696
|
cid
|
|
4495
5697
|
}, onReply);
|
|
4496
5698
|
});
|
|
4497
|
-
} else {
|
|
4498
|
-
let
|
|
5699
|
+
} else if (!(formEl.hasAttribute(PHX_REF) && formEl.classList.contains("phx-submit-loading"))) {
|
|
5700
|
+
let meta = this.extractMeta(formEl);
|
|
5701
|
+
let formData = serializeForm(formEl, __spreadValues({ submitter }, meta));
|
|
4499
5702
|
this.pushWithReply(refGenerator, "event", {
|
|
4500
5703
|
type: "form",
|
|
4501
5704
|
event: phxEvent,
|
|
@@ -4515,8 +5718,11 @@ within:
|
|
|
4515
5718
|
onComplete();
|
|
4516
5719
|
}
|
|
4517
5720
|
});
|
|
4518
|
-
this.uploaders[inputEl] = uploader;
|
|
4519
5721
|
let entries = uploader.entries().map((entry) => entry.toPreflightPayload());
|
|
5722
|
+
if (entries.length === 0) {
|
|
5723
|
+
numFileInputsInProgress--;
|
|
5724
|
+
return;
|
|
5725
|
+
}
|
|
4520
5726
|
let payload = {
|
|
4521
5727
|
ref: inputEl.getAttribute(PHX_UPLOAD_REF),
|
|
4522
5728
|
entries,
|
|
@@ -4525,10 +5731,17 @@ within:
|
|
|
4525
5731
|
this.log("upload", () => ["sending preflight request", payload]);
|
|
4526
5732
|
this.pushWithReply(null, "allow_upload", payload, (resp) => {
|
|
4527
5733
|
this.log("upload", () => ["got preflight response", resp]);
|
|
4528
|
-
|
|
5734
|
+
uploader.entries().forEach((entry) => {
|
|
5735
|
+
if (resp.entries && !resp.entries[entry.ref]) {
|
|
5736
|
+
this.handleFailedEntryPreflight(entry.ref, "failed preflight", uploader);
|
|
5737
|
+
}
|
|
5738
|
+
});
|
|
5739
|
+
if (resp.error || Object.keys(resp.entries).length === 0) {
|
|
4529
5740
|
this.undoRefs(ref);
|
|
4530
|
-
let
|
|
4531
|
-
|
|
5741
|
+
let errors = resp.error || [];
|
|
5742
|
+
errors.map(([entry_ref, reason]) => {
|
|
5743
|
+
this.handleFailedEntryPreflight(entry_ref, reason, uploader);
|
|
5744
|
+
});
|
|
4532
5745
|
} else {
|
|
4533
5746
|
let onError = (callback) => {
|
|
4534
5747
|
this.channel.onError(() => {
|
|
@@ -4542,8 +5755,20 @@ within:
|
|
|
4542
5755
|
});
|
|
4543
5756
|
});
|
|
4544
5757
|
}
|
|
4545
|
-
|
|
4546
|
-
|
|
5758
|
+
handleFailedEntryPreflight(uploadRef, reason, uploader) {
|
|
5759
|
+
if (uploader.isAutoUpload()) {
|
|
5760
|
+
let entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());
|
|
5761
|
+
if (entry) {
|
|
5762
|
+
entry.cancel();
|
|
5763
|
+
}
|
|
5764
|
+
} else {
|
|
5765
|
+
uploader.entries().map((entry) => entry.cancel());
|
|
5766
|
+
}
|
|
5767
|
+
this.log("upload", () => [`error for entry ${uploadRef}`, reason]);
|
|
5768
|
+
}
|
|
5769
|
+
dispatchUploads(targetCtx, name, filesOrBlobs) {
|
|
5770
|
+
let targetElement = this.targetCtxElement(targetCtx) || this.el;
|
|
5771
|
+
let inputs = dom_default.findUploadInputs(targetElement).filter((el) => el.name === name);
|
|
4547
5772
|
if (inputs.length === 0) {
|
|
4548
5773
|
logError(`no live file inputs found matching the name "${name}"`);
|
|
4549
5774
|
} else if (inputs.length > 1) {
|
|
@@ -4552,18 +5777,44 @@ within:
|
|
|
4552
5777
|
dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, { detail: { files: filesOrBlobs } });
|
|
4553
5778
|
}
|
|
4554
5779
|
}
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
let
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
5780
|
+
targetCtxElement(targetCtx) {
|
|
5781
|
+
if (isCid(targetCtx)) {
|
|
5782
|
+
let [target] = dom_default.findComponentNodeList(this.el, targetCtx);
|
|
5783
|
+
return target;
|
|
5784
|
+
} else if (targetCtx) {
|
|
5785
|
+
return targetCtx;
|
|
5786
|
+
} else {
|
|
5787
|
+
return null;
|
|
5788
|
+
}
|
|
5789
|
+
}
|
|
5790
|
+
pushFormRecovery(oldForm, newForm, templateDom, callback) {
|
|
5791
|
+
const phxChange = this.binding("change");
|
|
5792
|
+
const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;
|
|
5793
|
+
const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));
|
|
5794
|
+
const inputs = Array.from(oldForm.elements).filter((el) => dom_default.isFormInput(el) && el.name && !el.hasAttribute(phxChange));
|
|
5795
|
+
if (inputs.length === 0) {
|
|
5796
|
+
return;
|
|
5797
|
+
}
|
|
5798
|
+
inputs.forEach((input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2));
|
|
5799
|
+
let input = inputs.find((el) => el.type !== "hidden") || inputs[0];
|
|
5800
|
+
let pending = 0;
|
|
5801
|
+
this.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
5802
|
+
const cid = this.targetComponentID(newForm, targetCtx);
|
|
5803
|
+
pending++;
|
|
5804
|
+
targetView.pushInput(input, targetCtx, cid, phxEvent, { _target: input.name }, () => {
|
|
5805
|
+
pending--;
|
|
5806
|
+
if (pending === 0) {
|
|
5807
|
+
callback();
|
|
5808
|
+
}
|
|
5809
|
+
});
|
|
5810
|
+
}, templateDom, templateDom);
|
|
4561
5811
|
}
|
|
4562
5812
|
pushLinkPatch(href, targetEl, callback) {
|
|
4563
5813
|
let linkRef = this.liveSocket.setPendingLink(href);
|
|
4564
5814
|
let refGen = targetEl ? () => this.putRef([targetEl], "click") : null;
|
|
4565
5815
|
let fallback = () => this.liveSocket.redirect(window.location.href);
|
|
4566
|
-
let
|
|
5816
|
+
let url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;
|
|
5817
|
+
let push = this.pushWithReply(refGen, "live_patch", { url }, (resp) => {
|
|
4567
5818
|
this.liveSocket.requestDOMUpdate(() => {
|
|
4568
5819
|
if (resp.link_redirect) {
|
|
4569
5820
|
this.liveSocket.replaceMain(href, null, callback, linkRef);
|
|
@@ -4582,38 +5833,33 @@ within:
|
|
|
4582
5833
|
fallback();
|
|
4583
5834
|
}
|
|
4584
5835
|
}
|
|
4585
|
-
|
|
5836
|
+
getFormsForRecovery() {
|
|
4586
5837
|
if (this.joinCount === 0) {
|
|
4587
|
-
return
|
|
5838
|
+
return {};
|
|
4588
5839
|
}
|
|
4589
5840
|
let phxChange = this.binding("change");
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
if (newForm) {
|
|
4595
|
-
return [form, newForm, this.targetComponentID(newForm)];
|
|
4596
|
-
} else {
|
|
4597
|
-
return [form, null, null];
|
|
4598
|
-
}
|
|
4599
|
-
}).filter(([form, newForm, newCid]) => newForm);
|
|
5841
|
+
return dom_default.all(this.el, `form[${phxChange}]`).filter((form) => form.id).filter((form) => form.elements.length > 0).filter((form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore").map((form) => form.cloneNode(true)).reduce((acc, form) => {
|
|
5842
|
+
acc[form.id] = form;
|
|
5843
|
+
return acc;
|
|
5844
|
+
}, {});
|
|
4600
5845
|
}
|
|
4601
5846
|
maybePushComponentsDestroyed(destroyedCIDs) {
|
|
4602
5847
|
let willDestroyCIDs = destroyedCIDs.filter((cid) => {
|
|
4603
5848
|
return dom_default.findComponentNodeList(this.el, cid).length === 0;
|
|
4604
5849
|
});
|
|
4605
5850
|
if (willDestroyCIDs.length > 0) {
|
|
4606
|
-
this.
|
|
5851
|
+
willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));
|
|
4607
5852
|
this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }, () => {
|
|
4608
|
-
this.
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
});
|
|
4612
|
-
if (completelyDestroyCIDs.length > 0) {
|
|
4613
|
-
this.pushWithReply(null, "cids_destroyed", { cids: completelyDestroyCIDs }, (resp) => {
|
|
4614
|
-
this.rendered.pruneCIDs(resp.cids);
|
|
5853
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
5854
|
+
let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {
|
|
5855
|
+
return dom_default.findComponentNodeList(this.el, cid).length === 0;
|
|
4615
5856
|
});
|
|
4616
|
-
|
|
5857
|
+
if (completelyDestroyCIDs.length > 0) {
|
|
5858
|
+
this.pushWithReply(null, "cids_destroyed", { cids: completelyDestroyCIDs }, (resp) => {
|
|
5859
|
+
this.rendered.pruneCIDs(resp.cids);
|
|
5860
|
+
});
|
|
5861
|
+
}
|
|
5862
|
+
});
|
|
4617
5863
|
});
|
|
4618
5864
|
}
|
|
4619
5865
|
}
|
|
@@ -4621,14 +5867,15 @@ within:
|
|
|
4621
5867
|
let parentViewEl = el.closest(PHX_VIEW_SELECTOR);
|
|
4622
5868
|
return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;
|
|
4623
5869
|
}
|
|
4624
|
-
submitForm(form, targetCtx, phxEvent, opts = {}) {
|
|
5870
|
+
submitForm(form, targetCtx, phxEvent, submitter, opts = {}) {
|
|
4625
5871
|
dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
|
|
4626
|
-
|
|
4627
|
-
|
|
5872
|
+
const phxFeedbackFor = this.liveSocket.binding(PHX_FEEDBACK_FOR);
|
|
5873
|
+
const phxFeedbackGroup = this.liveSocket.binding(PHX_FEEDBACK_GROUP);
|
|
5874
|
+
const inputs = Array.from(form.elements);
|
|
4628
5875
|
inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
|
|
4629
5876
|
this.liveSocket.blurActiveElement(this);
|
|
4630
|
-
this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
|
|
4631
|
-
inputs.forEach((input) => dom_default.showError(input,
|
|
5877
|
+
this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {
|
|
5878
|
+
inputs.forEach((input) => dom_default.showError(input, phxFeedbackFor, phxFeedbackGroup));
|
|
4632
5879
|
this.liveSocket.restorePreviouslyActiveFocus();
|
|
4633
5880
|
});
|
|
4634
5881
|
}
|
|
@@ -4677,7 +5924,13 @@ within:
|
|
|
4677
5924
|
this.localStorage = opts.localStorage || window.localStorage;
|
|
4678
5925
|
this.sessionStorage = opts.sessionStorage || window.sessionStorage;
|
|
4679
5926
|
this.boundTopLevelEvents = false;
|
|
4680
|
-
this.
|
|
5927
|
+
this.serverCloseRef = null;
|
|
5928
|
+
this.domCallbacks = Object.assign({
|
|
5929
|
+
onPatchStart: closure2(),
|
|
5930
|
+
onPatchEnd: closure2(),
|
|
5931
|
+
onNodeAdded: closure2(),
|
|
5932
|
+
onBeforeElUpdated: closure2()
|
|
5933
|
+
}, opts.dom || {});
|
|
4681
5934
|
this.transitions = new TransitionSet();
|
|
4682
5935
|
window.addEventListener("pagehide", (_e) => {
|
|
4683
5936
|
this.unloaded = true;
|
|
@@ -4688,6 +5941,9 @@ within:
|
|
|
4688
5941
|
}
|
|
4689
5942
|
});
|
|
4690
5943
|
}
|
|
5944
|
+
version() {
|
|
5945
|
+
return "0.20.17";
|
|
5946
|
+
}
|
|
4691
5947
|
isProfileEnabled() {
|
|
4692
5948
|
return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
|
|
4693
5949
|
}
|
|
@@ -4747,6 +6003,10 @@ within:
|
|
|
4747
6003
|
}
|
|
4748
6004
|
disconnect(callback) {
|
|
4749
6005
|
clearTimeout(this.reloadWithJitterTimer);
|
|
6006
|
+
if (this.serverCloseRef) {
|
|
6007
|
+
this.socket.off(this.serverCloseRef);
|
|
6008
|
+
this.serverCloseRef = null;
|
|
6009
|
+
}
|
|
4750
6010
|
this.socket.disconnect(callback);
|
|
4751
6011
|
}
|
|
4752
6012
|
replaceTransport(transport) {
|
|
@@ -4757,6 +6017,11 @@ within:
|
|
|
4757
6017
|
execJS(el, encodedJS, eventType = null) {
|
|
4758
6018
|
this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
|
|
4759
6019
|
}
|
|
6020
|
+
execJSHookPush(el, phxEvent, data, callback) {
|
|
6021
|
+
this.withinOwners(el, (view) => {
|
|
6022
|
+
js_default.exec("hook", phxEvent, view, el, ["push", { data, callback }]);
|
|
6023
|
+
});
|
|
6024
|
+
}
|
|
4760
6025
|
unload() {
|
|
4761
6026
|
if (this.unloaded) {
|
|
4762
6027
|
return;
|
|
@@ -4908,7 +6173,7 @@ within:
|
|
|
4908
6173
|
return rootsFound;
|
|
4909
6174
|
}
|
|
4910
6175
|
redirect(to, flash) {
|
|
4911
|
-
this.
|
|
6176
|
+
this.unload();
|
|
4912
6177
|
browser_default.redirect(to, flash);
|
|
4913
6178
|
}
|
|
4914
6179
|
replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {
|
|
@@ -4919,26 +6184,28 @@ within:
|
|
|
4919
6184
|
this.main.destroy();
|
|
4920
6185
|
this.main = this.newRootView(newMainEl, flash, liveReferer);
|
|
4921
6186
|
this.main.setRedirect(href);
|
|
4922
|
-
this.transitionRemoves();
|
|
6187
|
+
this.transitionRemoves(null, true);
|
|
4923
6188
|
this.main.join((joinCount, onDone) => {
|
|
4924
6189
|
if (joinCount === 1 && this.commitPendingLink(linkRef)) {
|
|
4925
6190
|
this.requestDOMUpdate(() => {
|
|
4926
6191
|
dom_default.findPhxSticky(document).forEach((el) => newMainEl.appendChild(el));
|
|
4927
6192
|
this.outgoingMainEl.replaceWith(newMainEl);
|
|
4928
6193
|
this.outgoingMainEl = null;
|
|
4929
|
-
callback &&
|
|
6194
|
+
callback && callback(linkRef);
|
|
4930
6195
|
onDone();
|
|
4931
6196
|
});
|
|
4932
6197
|
}
|
|
4933
6198
|
});
|
|
4934
6199
|
}
|
|
4935
|
-
transitionRemoves(elements) {
|
|
6200
|
+
transitionRemoves(elements, skipSticky) {
|
|
4936
6201
|
let removeAttr = this.binding("remove");
|
|
4937
6202
|
elements = elements || dom_default.all(document, `[${removeAttr}]`);
|
|
6203
|
+
if (skipSticky) {
|
|
6204
|
+
const stickies = dom_default.findPhxSticky(document) || [];
|
|
6205
|
+
elements = elements.filter((el) => !dom_default.isChildOfAny(el, stickies));
|
|
6206
|
+
}
|
|
4938
6207
|
elements.forEach((el) => {
|
|
4939
|
-
|
|
4940
|
-
this.execJS(el, el.getAttribute(removeAttr), "remove");
|
|
4941
|
-
}
|
|
6208
|
+
this.execJS(el, el.getAttribute(removeAttr), "remove");
|
|
4942
6209
|
});
|
|
4943
6210
|
}
|
|
4944
6211
|
isPhxView(el) {
|
|
@@ -5024,10 +6291,7 @@ within:
|
|
|
5024
6291
|
return;
|
|
5025
6292
|
}
|
|
5026
6293
|
this.boundTopLevelEvents = true;
|
|
5027
|
-
this.socket.onClose((event) => {
|
|
5028
|
-
if (event && event.code === 1001) {
|
|
5029
|
-
return this.unload();
|
|
5030
|
-
}
|
|
6294
|
+
this.serverCloseRef = this.socket.onClose((event) => {
|
|
5031
6295
|
if (event && event.code === 1e3 && this.main) {
|
|
5032
6296
|
return this.reloadWithJitter(this.main);
|
|
5033
6297
|
}
|
|
@@ -5048,7 +6312,7 @@ within:
|
|
|
5048
6312
|
if (!dead) {
|
|
5049
6313
|
this.bindForms();
|
|
5050
6314
|
}
|
|
5051
|
-
this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent,
|
|
6315
|
+
this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
5052
6316
|
let matchKey = targetEl.getAttribute(this.binding(PHX_KEY));
|
|
5053
6317
|
let pressedKey = e.key && e.key.toLowerCase();
|
|
5054
6318
|
if (matchKey && matchKey.toLowerCase() !== pressedKey) {
|
|
@@ -5057,13 +6321,13 @@ within:
|
|
|
5057
6321
|
let data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
|
|
5058
6322
|
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
5059
6323
|
});
|
|
5060
|
-
this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent,
|
|
5061
|
-
if (!
|
|
6324
|
+
this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
6325
|
+
if (!phxTarget) {
|
|
5062
6326
|
let data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
|
|
5063
6327
|
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
5064
6328
|
}
|
|
5065
6329
|
});
|
|
5066
|
-
this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl,
|
|
6330
|
+
this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
5067
6331
|
if (phxTarget === "window") {
|
|
5068
6332
|
let data = this.eventMeta(type, e, targetEl);
|
|
5069
6333
|
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
@@ -5080,7 +6344,7 @@ within:
|
|
|
5080
6344
|
if (!dropTarget || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) {
|
|
5081
6345
|
return;
|
|
5082
6346
|
}
|
|
5083
|
-
LiveUploader.trackFiles(dropTarget, files);
|
|
6347
|
+
LiveUploader.trackFiles(dropTarget, files, e.dataTransfer);
|
|
5084
6348
|
dropTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5085
6349
|
});
|
|
5086
6350
|
this.on(PHX_TRACK_UPLOADS, (e) => {
|
|
@@ -5144,26 +6408,22 @@ within:
|
|
|
5144
6408
|
}
|
|
5145
6409
|
}
|
|
5146
6410
|
bindClicks() {
|
|
5147
|
-
window.addEventListener("
|
|
5148
|
-
this.bindClick("click", "click"
|
|
5149
|
-
this.bindClick("mousedown", "capture-click", true);
|
|
6411
|
+
window.addEventListener("mousedown", (e) => this.clickStartedAtTarget = e.target);
|
|
6412
|
+
this.bindClick("click", "click");
|
|
5150
6413
|
}
|
|
5151
|
-
bindClick(eventName, bindingName
|
|
6414
|
+
bindClick(eventName, bindingName) {
|
|
5152
6415
|
let click = this.binding(bindingName);
|
|
5153
6416
|
window.addEventListener(eventName, (e) => {
|
|
5154
6417
|
let target = null;
|
|
5155
|
-
if (
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
this.clickStartedAtTarget = null;
|
|
5162
|
-
}
|
|
6418
|
+
if (e.detail === 0)
|
|
6419
|
+
this.clickStartedAtTarget = e.target;
|
|
6420
|
+
let clickStartedAtTarget = this.clickStartedAtTarget || e.target;
|
|
6421
|
+
target = closestPhxBinding(clickStartedAtTarget, click);
|
|
6422
|
+
this.dispatchClickAway(e, clickStartedAtTarget);
|
|
6423
|
+
this.clickStartedAtTarget = null;
|
|
5163
6424
|
let phxEvent = target && target.getAttribute(click);
|
|
5164
6425
|
if (!phxEvent) {
|
|
5165
|
-
|
|
5166
|
-
if (!capture && href !== null && !dom_default.wantsNewTab(e) && dom_default.isNewPageHref(href, window.location)) {
|
|
6426
|
+
if (dom_default.isNewPageClick(e, window.location)) {
|
|
5167
6427
|
this.unload();
|
|
5168
6428
|
}
|
|
5169
6429
|
return;
|
|
@@ -5171,20 +6431,23 @@ within:
|
|
|
5171
6431
|
if (target.getAttribute("href") === "#") {
|
|
5172
6432
|
e.preventDefault();
|
|
5173
6433
|
}
|
|
6434
|
+
if (target.hasAttribute(PHX_REF)) {
|
|
6435
|
+
return;
|
|
6436
|
+
}
|
|
5174
6437
|
this.debounce(target, e, "click", () => {
|
|
5175
6438
|
this.withinOwners(target, (view) => {
|
|
5176
6439
|
js_default.exec("click", phxEvent, view, target, ["push", { data: this.eventMeta("click", e, target) }]);
|
|
5177
6440
|
});
|
|
5178
6441
|
});
|
|
5179
|
-
},
|
|
6442
|
+
}, false);
|
|
5180
6443
|
}
|
|
5181
6444
|
dispatchClickAway(e, clickStartedAt) {
|
|
5182
6445
|
let phxClickAway = this.binding("click-away");
|
|
5183
6446
|
dom_default.all(document, `[${phxClickAway}]`, (el) => {
|
|
5184
6447
|
if (!(el.isSameNode(clickStartedAt) || el.contains(clickStartedAt))) {
|
|
5185
|
-
this.withinOwners(
|
|
6448
|
+
this.withinOwners(el, (view) => {
|
|
5186
6449
|
let phxEvent = el.getAttribute(phxClickAway);
|
|
5187
|
-
if (js_default.isVisible(el)) {
|
|
6450
|
+
if (js_default.isVisible(el) && js_default.isInViewport(el)) {
|
|
5188
6451
|
js_default.exec("click", phxEvent, view, el, ["push", { data: this.eventMeta("click", e, e.target) }]);
|
|
5189
6452
|
}
|
|
5190
6453
|
});
|
|
@@ -5211,6 +6474,7 @@ within:
|
|
|
5211
6474
|
}
|
|
5212
6475
|
let { type, id, root, scroll } = event.state || {};
|
|
5213
6476
|
let href = window.location.href;
|
|
6477
|
+
dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: type === "patch", pop: true } });
|
|
5214
6478
|
this.requestDOMUpdate(() => {
|
|
5215
6479
|
if (this.main.isConnected() && (type === "patch" && id === this.main.id)) {
|
|
5216
6480
|
this.main.pushLinkPatch(href, null, () => {
|
|
@@ -5232,7 +6496,7 @@ within:
|
|
|
5232
6496
|
if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {
|
|
5233
6497
|
return;
|
|
5234
6498
|
}
|
|
5235
|
-
let href = target.href;
|
|
6499
|
+
let href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;
|
|
5236
6500
|
let linkState = target.getAttribute(PHX_LINK_STATE);
|
|
5237
6501
|
e.preventDefault();
|
|
5238
6502
|
e.stopImmediatePropagation();
|
|
@@ -5273,7 +6537,7 @@ within:
|
|
|
5273
6537
|
return callback ? callback(done) : done;
|
|
5274
6538
|
}
|
|
5275
6539
|
pushHistoryPatch(href, linkState, targetEl) {
|
|
5276
|
-
if (!this.isConnected()) {
|
|
6540
|
+
if (!this.isConnected() || !this.main.isMain()) {
|
|
5277
6541
|
return browser_default.redirect(href);
|
|
5278
6542
|
}
|
|
5279
6543
|
this.withPageLoading({ to: href, kind: "patch" }, (done) => {
|
|
@@ -5288,10 +6552,11 @@ within:
|
|
|
5288
6552
|
return;
|
|
5289
6553
|
}
|
|
5290
6554
|
browser_default.pushState(linkState, { type: "patch", id: this.main.id }, href);
|
|
6555
|
+
dom_default.dispatchEvent(window, "phx:navigate", { detail: { patch: true, href, pop: false } });
|
|
5291
6556
|
this.registerNewLocation(window.location);
|
|
5292
6557
|
}
|
|
5293
6558
|
historyRedirect(href, linkState, flash) {
|
|
5294
|
-
if (!this.isConnected()) {
|
|
6559
|
+
if (!this.isConnected() || !this.main.isMain()) {
|
|
5295
6560
|
return browser_default.redirect(href, flash);
|
|
5296
6561
|
}
|
|
5297
6562
|
if (/^\/$|^\/[^\/]+.*$/.test(href)) {
|
|
@@ -5300,9 +6565,12 @@ within:
|
|
|
5300
6565
|
}
|
|
5301
6566
|
let scroll = window.scrollY;
|
|
5302
6567
|
this.withPageLoading({ to: href, kind: "redirect" }, (done) => {
|
|
5303
|
-
this.replaceMain(href, flash, () => {
|
|
5304
|
-
|
|
5305
|
-
|
|
6568
|
+
this.replaceMain(href, flash, (linkRef) => {
|
|
6569
|
+
if (linkRef === this.linkRef) {
|
|
6570
|
+
browser_default.pushState(linkState, { type: "redirect", id: this.main.id, scroll }, href);
|
|
6571
|
+
dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: false, pop: false } });
|
|
6572
|
+
this.registerNewLocation(window.location);
|
|
6573
|
+
}
|
|
5306
6574
|
done();
|
|
5307
6575
|
});
|
|
5308
6576
|
});
|
|
@@ -5350,7 +6618,7 @@ within:
|
|
|
5350
6618
|
e.preventDefault();
|
|
5351
6619
|
e.target.disabled = true;
|
|
5352
6620
|
this.withinOwners(e.target, (view) => {
|
|
5353
|
-
js_default.exec("submit", phxEvent, view, e.target, ["push", {}]);
|
|
6621
|
+
js_default.exec("submit", phxEvent, view, e.target, ["push", { submitter: e.submitter }]);
|
|
5354
6622
|
});
|
|
5355
6623
|
}, false);
|
|
5356
6624
|
for (let type of ["change", "input"]) {
|
|
@@ -5370,7 +6638,7 @@ within:
|
|
|
5370
6638
|
let currentIterations = iterations;
|
|
5371
6639
|
iterations++;
|
|
5372
6640
|
let { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};
|
|
5373
|
-
if (at === currentIterations - 1 && type
|
|
6641
|
+
if (at === currentIterations - 1 && type === "change" && lastType === "input") {
|
|
5374
6642
|
return;
|
|
5375
6643
|
}
|
|
5376
6644
|
dom_default.putPrivate(input, "prev-iteration", { at: currentIterations, type });
|
|
@@ -5385,6 +6653,16 @@ within:
|
|
|
5385
6653
|
});
|
|
5386
6654
|
}, false);
|
|
5387
6655
|
}
|
|
6656
|
+
this.on("reset", (e) => {
|
|
6657
|
+
let form = e.target;
|
|
6658
|
+
dom_default.resetForm(form, this.binding(PHX_FEEDBACK_FOR), this.binding(PHX_FEEDBACK_GROUP));
|
|
6659
|
+
let input = Array.from(form.elements).find((el) => el.type === "reset");
|
|
6660
|
+
if (input) {
|
|
6661
|
+
window.requestAnimationFrame(() => {
|
|
6662
|
+
input.dispatchEvent(new Event("input", { bubbles: true, cancelable: false }));
|
|
6663
|
+
});
|
|
6664
|
+
}
|
|
6665
|
+
});
|
|
5388
6666
|
}
|
|
5389
6667
|
debounce(el, event, eventType, callback) {
|
|
5390
6668
|
if (eventType === "blur" || eventType === "focusout") {
|
|
@@ -5418,7 +6696,6 @@ within:
|
|
|
5418
6696
|
constructor() {
|
|
5419
6697
|
this.transitions = /* @__PURE__ */ new Set();
|
|
5420
6698
|
this.pendingOps = [];
|
|
5421
|
-
this.reset();
|
|
5422
6699
|
}
|
|
5423
6700
|
reset() {
|
|
5424
6701
|
this.transitions.forEach((timer) => {
|
|
@@ -5439,9 +6716,7 @@ within:
|
|
|
5439
6716
|
let timer = setTimeout(() => {
|
|
5440
6717
|
this.transitions.delete(timer);
|
|
5441
6718
|
onDone();
|
|
5442
|
-
|
|
5443
|
-
this.flushPendingOps();
|
|
5444
|
-
}
|
|
6719
|
+
this.flushPendingOps();
|
|
5445
6720
|
}, time);
|
|
5446
6721
|
this.transitions.add(timer);
|
|
5447
6722
|
}
|
|
@@ -5452,20 +6727,26 @@ within:
|
|
|
5452
6727
|
return this.transitions.size;
|
|
5453
6728
|
}
|
|
5454
6729
|
flushPendingOps() {
|
|
5455
|
-
this.
|
|
5456
|
-
|
|
6730
|
+
if (this.size() > 0) {
|
|
6731
|
+
return;
|
|
6732
|
+
}
|
|
6733
|
+
let op = this.pendingOps.shift();
|
|
6734
|
+
if (op) {
|
|
6735
|
+
op();
|
|
6736
|
+
this.flushPendingOps();
|
|
6737
|
+
}
|
|
5457
6738
|
}
|
|
5458
6739
|
};
|
|
5459
6740
|
|
|
5460
|
-
//
|
|
6741
|
+
// js/app.js
|
|
5461
6742
|
var import_nprogress = __toESM(require_nprogress());
|
|
5462
6743
|
var _a;
|
|
5463
6744
|
var Hooks2 = (_a = window.Hooks) != null ? _a : {};
|
|
5464
6745
|
var scrollAt = () => {
|
|
5465
|
-
let
|
|
6746
|
+
let scrollTop2 = document.documentElement.scrollTop || document.body.scrollTop;
|
|
5466
6747
|
let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
5467
6748
|
let clientHeight = document.documentElement.clientHeight;
|
|
5468
|
-
return
|
|
6749
|
+
return scrollTop2 / (scrollHeight - clientHeight) * 100;
|
|
5469
6750
|
};
|
|
5470
6751
|
Hooks2.InfiniteScroll = {
|
|
5471
6752
|
page() {
|
|
@@ -5487,7 +6768,8 @@ within:
|
|
|
5487
6768
|
var csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
|
|
5488
6769
|
var liveSocket = new LiveSocket("/live", Socket, {
|
|
5489
6770
|
hooks: Hooks2,
|
|
5490
|
-
params: { _csrf_token: csrfToken }
|
|
6771
|
+
params: { _csrf_token: csrfToken },
|
|
6772
|
+
uploaders: window.Uploaders || {}
|
|
5491
6773
|
});
|
|
5492
6774
|
window.addEventListener("phx:page-loading-start", (info) => import_nprogress.default.start());
|
|
5493
6775
|
window.addEventListener("phx:page-loading-stop", (info) => import_nprogress.default.done());
|