phoenix_live_view 0.16.3 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +128 -7
- package/assets/js/phoenix_live_view/constants.js +2 -2
- package/assets/js/phoenix_live_view/dom.js +49 -13
- package/assets/js/phoenix_live_view/dom_patch.js +31 -11
- package/assets/js/phoenix_live_view/js.js +169 -0
- package/assets/js/phoenix_live_view/live_socket.js +143 -50
- package/assets/js/phoenix_live_view/view.js +113 -87
- package/assets/js/phoenix_live_view/view_hook.js +2 -2
- package/package.json +5 -3
- package/priv/static/phoenix_live_view.cjs.js +3737 -0
- package/priv/static/phoenix_live_view.cjs.js.map +7 -0
- package/priv/static/phoenix_live_view.esm.js +495 -167
- package/priv/static/phoenix_live_view.esm.js.map +3 -3
- package/priv/static/phoenix_live_view.js +495 -167
- package/priv/static/phoenix_live_view.min.js +6 -6
|
@@ -25,10 +25,10 @@ var PHX_DROP_TARGET = "drop-target";
|
|
|
25
25
|
var PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";
|
|
26
26
|
var PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";
|
|
27
27
|
var PHX_SKIP = "data-phx-skip";
|
|
28
|
-
var
|
|
28
|
+
var PHX_PRUNE = "data-phx-prune";
|
|
29
29
|
var PHX_PAGE_LOADING = "page-loading";
|
|
30
30
|
var PHX_CONNECTED_CLASS = "phx-connected";
|
|
31
|
-
var PHX_DISCONNECTED_CLASS = "phx-
|
|
31
|
+
var PHX_DISCONNECTED_CLASS = "phx-loading";
|
|
32
32
|
var PHX_NO_FEEDBACK_CLASS = "phx-no-feedback";
|
|
33
33
|
var PHX_ERROR_CLASS = "phx-error";
|
|
34
34
|
var PHX_PARENT_ID = "data-phx-parent-id";
|
|
@@ -282,7 +282,9 @@ var DOM = {
|
|
|
282
282
|
return node.id && DOM.private(node, "destroyed") ? true : false;
|
|
283
283
|
},
|
|
284
284
|
markPhxChildDestroyed(el) {
|
|
285
|
-
|
|
285
|
+
if (this.isPhxChild(el)) {
|
|
286
|
+
el.setAttribute(PHX_SESSION, "");
|
|
287
|
+
}
|
|
286
288
|
this.putPrivate(el, "destroyed", true);
|
|
287
289
|
},
|
|
288
290
|
findPhxChildrenInFragment(html, parentId) {
|
|
@@ -336,9 +338,17 @@ var DOM = {
|
|
|
336
338
|
}
|
|
337
339
|
el[PHX_PRIVATE][key] = value;
|
|
338
340
|
},
|
|
341
|
+
updatePrivate(el, key, defaultVal, updateFunc) {
|
|
342
|
+
let existing = this.private(el, key);
|
|
343
|
+
if (existing === void 0) {
|
|
344
|
+
this.putPrivate(el, key, updateFunc(defaultVal));
|
|
345
|
+
} else {
|
|
346
|
+
this.putPrivate(el, key, updateFunc(existing));
|
|
347
|
+
}
|
|
348
|
+
},
|
|
339
349
|
copyPrivates(target, source) {
|
|
340
350
|
if (source[PHX_PRIVATE]) {
|
|
341
|
-
target[PHX_PRIVATE] =
|
|
351
|
+
target[PHX_PRIVATE] = source[PHX_PRIVATE];
|
|
342
352
|
}
|
|
343
353
|
},
|
|
344
354
|
putTitle(str) {
|
|
@@ -520,14 +530,6 @@ var DOM = {
|
|
|
520
530
|
el.checked = el.getAttribute("checked") !== null;
|
|
521
531
|
}
|
|
522
532
|
},
|
|
523
|
-
syncPropsToAttrs(el) {
|
|
524
|
-
if (el instanceof HTMLSelectElement) {
|
|
525
|
-
let selectedItem = el.options.item(el.selectedIndex);
|
|
526
|
-
if (selectedItem && selectedItem.getAttribute("selected") === null) {
|
|
527
|
-
selectedItem.setAttribute("selected", "");
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
533
|
isTextualInput(el) {
|
|
532
534
|
return FOCUSABLE_INPUTS.indexOf(el.type) >= 0;
|
|
533
535
|
},
|
|
@@ -573,7 +575,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
573
575
|
}
|
|
574
576
|
},
|
|
575
577
|
replaceRootContainer(container, tagName, attrs) {
|
|
576
|
-
let retainedAttrs = new Set(["id", PHX_SESSION, PHX_STATIC, PHX_MAIN]);
|
|
578
|
+
let retainedAttrs = new Set(["id", PHX_SESSION, PHX_STATIC, PHX_MAIN, PHX_ROOT_ID]);
|
|
577
579
|
if (container.tagName.toLowerCase() === tagName.toLowerCase()) {
|
|
578
580
|
Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name));
|
|
579
581
|
Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr]));
|
|
@@ -586,6 +588,39 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
586
588
|
container.replaceWith(newContainer);
|
|
587
589
|
return newContainer;
|
|
588
590
|
}
|
|
591
|
+
},
|
|
592
|
+
getSticky(el, name, defaultVal) {
|
|
593
|
+
let op = (DOM.private(el, "sticky") || []).find(([existingName]) => name === existingName);
|
|
594
|
+
if (op) {
|
|
595
|
+
let [_name, _op, stashedResult] = op;
|
|
596
|
+
return stashedResult;
|
|
597
|
+
} else {
|
|
598
|
+
return typeof defaultVal === "function" ? defaultVal() : defaultVal;
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
deleteSticky(el, name) {
|
|
602
|
+
this.updatePrivate(el, "sticky", [], (ops) => {
|
|
603
|
+
return ops.filter(([existingName, _]) => existingName !== name);
|
|
604
|
+
});
|
|
605
|
+
},
|
|
606
|
+
putSticky(el, name, op) {
|
|
607
|
+
let stashedResult = op(el);
|
|
608
|
+
this.updatePrivate(el, "sticky", [], (ops) => {
|
|
609
|
+
let existingIndex = ops.findIndex(([existingName]) => name === existingName);
|
|
610
|
+
if (existingIndex >= 0) {
|
|
611
|
+
ops[existingIndex] = [name, op, stashedResult];
|
|
612
|
+
} else {
|
|
613
|
+
ops.push([name, op, stashedResult]);
|
|
614
|
+
}
|
|
615
|
+
return ops;
|
|
616
|
+
});
|
|
617
|
+
},
|
|
618
|
+
applyStickyOperations(el) {
|
|
619
|
+
let ops = DOM.private(el, "sticky");
|
|
620
|
+
if (!ops) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));
|
|
589
624
|
}
|
|
590
625
|
};
|
|
591
626
|
var dom_default = DOM;
|
|
@@ -1383,7 +1418,8 @@ var DOMPatch = class {
|
|
|
1383
1418
|
afteradded: [],
|
|
1384
1419
|
afterupdated: [],
|
|
1385
1420
|
afterdiscarded: [],
|
|
1386
|
-
afterphxChildAdded: []
|
|
1421
|
+
afterphxChildAdded: [],
|
|
1422
|
+
aftertransitionsDiscarded: []
|
|
1387
1423
|
};
|
|
1388
1424
|
}
|
|
1389
1425
|
before(kind, callback) {
|
|
@@ -1400,7 +1436,7 @@ var DOMPatch = class {
|
|
|
1400
1436
|
}
|
|
1401
1437
|
markPrunableContentForRemoval() {
|
|
1402
1438
|
dom_default.all(this.container, "[phx-update=append] > *, [phx-update=prepend] > *", (el) => {
|
|
1403
|
-
el.setAttribute(
|
|
1439
|
+
el.setAttribute(PHX_PRUNE, "");
|
|
1404
1440
|
});
|
|
1405
1441
|
}
|
|
1406
1442
|
perform() {
|
|
@@ -1415,9 +1451,11 @@ var DOMPatch = class {
|
|
|
1415
1451
|
let phxFeedbackFor = liveSocket.binding(PHX_FEEDBACK_FOR);
|
|
1416
1452
|
let disableWith = liveSocket.binding(PHX_DISABLE_WITH);
|
|
1417
1453
|
let phxTriggerExternal = liveSocket.binding(PHX_TRIGGER_ACTION);
|
|
1454
|
+
let phxRemove = liveSocket.binding("remove");
|
|
1418
1455
|
let added = [];
|
|
1419
1456
|
let updates = [];
|
|
1420
1457
|
let appendPrependUpdates = [];
|
|
1458
|
+
let pendingRemoves = [];
|
|
1421
1459
|
let externalFormTriggered = null;
|
|
1422
1460
|
let diffHTML = liveSocket.time("premorph container prep", () => {
|
|
1423
1461
|
return this.buildDiffHTML(container, html, phxUpdate, targetContainer);
|
|
@@ -1435,6 +1473,11 @@ var DOMPatch = class {
|
|
|
1435
1473
|
return el;
|
|
1436
1474
|
},
|
|
1437
1475
|
onNodeAdded: (el) => {
|
|
1476
|
+
if (el instanceof HTMLImageElement && el.srcset) {
|
|
1477
|
+
el.srcset = el.srcset;
|
|
1478
|
+
} else if (el instanceof HTMLVideoElement && el.autoplay) {
|
|
1479
|
+
el.play();
|
|
1480
|
+
}
|
|
1438
1481
|
if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
|
|
1439
1482
|
externalFormTriggered = el;
|
|
1440
1483
|
}
|
|
@@ -1451,12 +1494,16 @@ var DOMPatch = class {
|
|
|
1451
1494
|
this.trackAfter("discarded", el);
|
|
1452
1495
|
},
|
|
1453
1496
|
onBeforeNodeDiscarded: (el) => {
|
|
1454
|
-
if (el.getAttribute && el.getAttribute(
|
|
1497
|
+
if (el.getAttribute && el.getAttribute(PHX_PRUNE) !== null) {
|
|
1455
1498
|
return true;
|
|
1456
1499
|
}
|
|
1457
1500
|
if (el.parentNode !== null && dom_default.isPhxUpdate(el.parentNode, phxUpdate, ["append", "prepend"]) && el.id) {
|
|
1458
1501
|
return false;
|
|
1459
1502
|
}
|
|
1503
|
+
if (el.getAttribute && el.getAttribute(phxRemove)) {
|
|
1504
|
+
pendingRemoves.push(el);
|
|
1505
|
+
return false;
|
|
1506
|
+
}
|
|
1460
1507
|
if (this.skipCIDSibling(el)) {
|
|
1461
1508
|
return false;
|
|
1462
1509
|
}
|
|
@@ -1477,6 +1524,7 @@ var DOMPatch = class {
|
|
|
1477
1524
|
this.trackBefore("updated", fromEl, toEl);
|
|
1478
1525
|
dom_default.mergeAttrs(fromEl, toEl, { isIgnored: true });
|
|
1479
1526
|
updates.push(fromEl);
|
|
1527
|
+
dom_default.applyStickyOperations(fromEl);
|
|
1480
1528
|
return false;
|
|
1481
1529
|
}
|
|
1482
1530
|
if (fromEl.type === "number" && (fromEl.validity && fromEl.validity.badInput)) {
|
|
@@ -1487,6 +1535,7 @@ var DOMPatch = class {
|
|
|
1487
1535
|
this.trackBefore("updated", fromEl, toEl);
|
|
1488
1536
|
updates.push(fromEl);
|
|
1489
1537
|
}
|
|
1538
|
+
dom_default.applyStickyOperations(fromEl);
|
|
1490
1539
|
return false;
|
|
1491
1540
|
}
|
|
1492
1541
|
if (dom_default.isPhxChild(toEl)) {
|
|
@@ -1496,23 +1545,25 @@ var DOMPatch = class {
|
|
|
1496
1545
|
fromEl.setAttribute(PHX_SESSION, prevSession);
|
|
1497
1546
|
}
|
|
1498
1547
|
fromEl.setAttribute(PHX_ROOT_ID, this.rootID);
|
|
1548
|
+
dom_default.applyStickyOperations(fromEl);
|
|
1499
1549
|
return false;
|
|
1500
1550
|
}
|
|
1501
1551
|
dom_default.copyPrivates(toEl, fromEl);
|
|
1502
1552
|
dom_default.discardError(targetContainer, toEl, phxFeedbackFor);
|
|
1503
|
-
dom_default.syncPropsToAttrs(toEl);
|
|
1504
1553
|
let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
|
|
1505
|
-
if (isFocusedFormEl
|
|
1554
|
+
if (isFocusedFormEl) {
|
|
1506
1555
|
this.trackBefore("updated", fromEl, toEl);
|
|
1507
1556
|
dom_default.mergeFocusedInput(fromEl, toEl);
|
|
1508
1557
|
dom_default.syncAttrsToProps(fromEl);
|
|
1509
1558
|
updates.push(fromEl);
|
|
1559
|
+
dom_default.applyStickyOperations(fromEl);
|
|
1510
1560
|
return false;
|
|
1511
1561
|
} else {
|
|
1512
1562
|
if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {
|
|
1513
1563
|
appendPrependUpdates.push(new DOMPostMorphRestorer(fromEl, toEl, toEl.getAttribute(phxUpdate)));
|
|
1514
1564
|
}
|
|
1515
1565
|
dom_default.syncAttrsToProps(toEl);
|
|
1566
|
+
dom_default.applyStickyOperations(toEl);
|
|
1516
1567
|
this.trackBefore("updated", fromEl, toEl);
|
|
1517
1568
|
return true;
|
|
1518
1569
|
}
|
|
@@ -1531,16 +1582,19 @@ var DOMPatch = class {
|
|
|
1531
1582
|
dom_default.dispatchEvent(document, "phx:update");
|
|
1532
1583
|
added.forEach((el) => this.trackAfter("added", el));
|
|
1533
1584
|
updates.forEach((el) => this.trackAfter("updated", el));
|
|
1585
|
+
if (pendingRemoves.length > 0) {
|
|
1586
|
+
liveSocket.transitionRemoves(pendingRemoves);
|
|
1587
|
+
liveSocket.requestDOMUpdate(() => {
|
|
1588
|
+
pendingRemoves.forEach((el) => el.remove());
|
|
1589
|
+
this.trackAfter("transitionsDiscarded", pendingRemoves);
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1534
1592
|
if (externalFormTriggered) {
|
|
1535
1593
|
liveSocket.disconnect();
|
|
1536
1594
|
externalFormTriggered.submit();
|
|
1537
1595
|
}
|
|
1538
1596
|
return true;
|
|
1539
1597
|
}
|
|
1540
|
-
forceFocusedSelectUpdate(fromEl, toEl) {
|
|
1541
|
-
let isSelect = ["select", "select-one", "select-multiple"].find((t) => t === fromEl.type);
|
|
1542
|
-
return fromEl.multiple === true || isSelect && fromEl.innerHTML != toEl.innerHTML;
|
|
1543
|
-
}
|
|
1544
1598
|
isCIDPatch() {
|
|
1545
1599
|
return this.cidPatch;
|
|
1546
1600
|
}
|
|
@@ -1842,13 +1896,13 @@ var ViewHook = class {
|
|
|
1842
1896
|
}
|
|
1843
1897
|
handleEvent(event, callback) {
|
|
1844
1898
|
let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail);
|
|
1845
|
-
window.addEventListener(`phx
|
|
1899
|
+
window.addEventListener(`phx:${event}`, callbackRef);
|
|
1846
1900
|
this.__listeners.add(callbackRef);
|
|
1847
1901
|
return callbackRef;
|
|
1848
1902
|
}
|
|
1849
1903
|
removeHandleEvent(callbackRef) {
|
|
1850
1904
|
let event = callbackRef(null, true);
|
|
1851
|
-
window.removeEventListener(`phx
|
|
1905
|
+
window.removeEventListener(`phx:${event}`, callbackRef);
|
|
1852
1906
|
this.__listeners.delete(callbackRef);
|
|
1853
1907
|
}
|
|
1854
1908
|
upload(name, files) {
|
|
@@ -1862,6 +1916,156 @@ var ViewHook = class {
|
|
|
1862
1916
|
}
|
|
1863
1917
|
};
|
|
1864
1918
|
|
|
1919
|
+
// js/phoenix_live_view/js.js
|
|
1920
|
+
var JS = {
|
|
1921
|
+
exec(eventType, phxEvent, view, el, defaults) {
|
|
1922
|
+
let [defaultKind, defaultArgs] = defaults || [null, {}];
|
|
1923
|
+
let commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];
|
|
1924
|
+
commands.forEach(([kind, args]) => {
|
|
1925
|
+
if (kind === defaultKind && defaultArgs.data) {
|
|
1926
|
+
args.data = Object.assign(args.data || {}, defaultArgs.data);
|
|
1927
|
+
}
|
|
1928
|
+
this[`exec_${kind}`](eventType, phxEvent, view, el, args);
|
|
1929
|
+
});
|
|
1930
|
+
},
|
|
1931
|
+
exec_dispatch(eventType, phxEvent, view, sourceEl, { to, event, detail }) {
|
|
1932
|
+
if (to) {
|
|
1933
|
+
dom_default.all(document, to, (el) => dom_default.dispatchEvent(el, event, detail));
|
|
1934
|
+
} else {
|
|
1935
|
+
dom_default.dispatchEvent(sourceEl, event, detail);
|
|
1936
|
+
}
|
|
1937
|
+
},
|
|
1938
|
+
exec_push(eventType, phxEvent, view, sourceEl, args) {
|
|
1939
|
+
let { event, data, target, page_loading, loading, value } = args;
|
|
1940
|
+
let pushOpts = { page_loading: !!page_loading, loading, value };
|
|
1941
|
+
let targetSrc = eventType === "change" ? sourceEl.form : sourceEl;
|
|
1942
|
+
let phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
|
|
1943
|
+
view.withinTargets(phxTarget, (targetView, targetCtx) => {
|
|
1944
|
+
if (eventType === "change") {
|
|
1945
|
+
let { newCid, _target, callback } = args;
|
|
1946
|
+
if (_target) {
|
|
1947
|
+
pushOpts._target = _target;
|
|
1948
|
+
}
|
|
1949
|
+
targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback);
|
|
1950
|
+
} else if (eventType === "submit") {
|
|
1951
|
+
targetView.submitForm(sourceEl, targetCtx, event || phxEvent, pushOpts);
|
|
1952
|
+
} else {
|
|
1953
|
+
targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data, pushOpts);
|
|
1954
|
+
}
|
|
1955
|
+
});
|
|
1956
|
+
},
|
|
1957
|
+
exec_add_class(eventType, phxEvent, view, sourceEl, { to, names, transition, time }) {
|
|
1958
|
+
if (to) {
|
|
1959
|
+
dom_default.all(document, to, (el) => this.addOrRemoveClasses(el, names, [], transition, time, view));
|
|
1960
|
+
} else {
|
|
1961
|
+
this.addOrRemoveClasses(sourceEl, names, [], transition, view);
|
|
1962
|
+
}
|
|
1963
|
+
},
|
|
1964
|
+
exec_remove_class(eventType, phxEvent, view, sourceEl, { to, names, transition, time }) {
|
|
1965
|
+
if (to) {
|
|
1966
|
+
dom_default.all(document, to, (el) => this.addOrRemoveClasses(el, [], names, transition, time, view));
|
|
1967
|
+
} else {
|
|
1968
|
+
this.addOrRemoveClasses(sourceEl, [], names, transition, time, view);
|
|
1969
|
+
}
|
|
1970
|
+
},
|
|
1971
|
+
exec_transition(eventType, phxEvent, view, sourceEl, { time, to, names }) {
|
|
1972
|
+
let els = to ? dom_default.all(document, to) : [sourceEl];
|
|
1973
|
+
els.forEach((el) => {
|
|
1974
|
+
this.addOrRemoveClasses(el, names, []);
|
|
1975
|
+
view.transition(time, () => this.addOrRemoveClasses(el, [], names));
|
|
1976
|
+
});
|
|
1977
|
+
},
|
|
1978
|
+
exec_toggle(eventType, phxEvent, view, sourceEl, { to, display, ins, outs, time }) {
|
|
1979
|
+
if (to) {
|
|
1980
|
+
dom_default.all(document, to, (el) => this.toggle(eventType, view, el, display, ins || [], outs || [], time));
|
|
1981
|
+
} else {
|
|
1982
|
+
this.toggle(eventType, view, sourceEl, display, ins || [], outs || [], time);
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
exec_show(eventType, phxEvent, view, sourceEl, { to, display, transition, time }) {
|
|
1986
|
+
if (to) {
|
|
1987
|
+
dom_default.all(document, to, (el) => this.show(eventType, view, el, display, transition, time));
|
|
1988
|
+
} else {
|
|
1989
|
+
this.show(eventType, view, sourceEl, transition, time);
|
|
1990
|
+
}
|
|
1991
|
+
},
|
|
1992
|
+
exec_hide(eventType, phxEvent, view, sourceEl, { to, display, transition, time }) {
|
|
1993
|
+
if (to) {
|
|
1994
|
+
dom_default.all(document, to, (el) => this.hide(eventType, view, el, display, transition, time));
|
|
1995
|
+
} else {
|
|
1996
|
+
this.hide(eventType, view, sourceEl, display, transition, time);
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
show(eventType, view, el, display, transition, time) {
|
|
2000
|
+
let isVisible = this.isVisible(el);
|
|
2001
|
+
if (transition.length > 0 && !isVisible) {
|
|
2002
|
+
this.toggle(eventType, view, el, display, transition, [], time);
|
|
2003
|
+
} else if (!isVisible) {
|
|
2004
|
+
this.toggle(eventType, view, el, display, [], [], null);
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
hide(eventType, view, el, display, transition, time) {
|
|
2008
|
+
let isVisible = this.isVisible(el);
|
|
2009
|
+
if (transition.length > 0 && isVisible) {
|
|
2010
|
+
this.toggle(eventType, view, el, display, [], transition, time);
|
|
2011
|
+
} else if (isVisible) {
|
|
2012
|
+
this.toggle(eventType, view, el, display, [], [], time);
|
|
2013
|
+
}
|
|
2014
|
+
},
|
|
2015
|
+
toggle(eventType, view, el, display, in_classes, out_classes, time) {
|
|
2016
|
+
if (in_classes.length > 0 || out_classes.length > 0) {
|
|
2017
|
+
if (this.isVisible(el)) {
|
|
2018
|
+
this.addOrRemoveClasses(el, out_classes, in_classes);
|
|
2019
|
+
view.transition(time, () => {
|
|
2020
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
|
|
2021
|
+
this.addOrRemoveClasses(el, [], out_classes);
|
|
2022
|
+
});
|
|
2023
|
+
} else {
|
|
2024
|
+
if (eventType === "remove") {
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
2027
|
+
this.addOrRemoveClasses(el, in_classes, out_classes);
|
|
2028
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = display || "block");
|
|
2029
|
+
view.transition(time, () => {
|
|
2030
|
+
this.addOrRemoveClasses(el, [], in_classes);
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
} else {
|
|
2034
|
+
let newDisplay = this.isVisible(el) ? "none" : display || "block";
|
|
2035
|
+
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = newDisplay);
|
|
2036
|
+
}
|
|
2037
|
+
},
|
|
2038
|
+
addOrRemoveClasses(el, adds, removes, transition, time, view) {
|
|
2039
|
+
if (transition && transition.length > 0) {
|
|
2040
|
+
this.addOrRemoveClasses(el, transition, []);
|
|
2041
|
+
return view.transition(time, () => this.addOrRemoveClasses(el, adds, removes.concat(transition)));
|
|
2042
|
+
}
|
|
2043
|
+
window.requestAnimationFrame(() => {
|
|
2044
|
+
let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
|
|
2045
|
+
let keepAdds = adds.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
|
|
2046
|
+
let keepRemoves = removes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
|
|
2047
|
+
let newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);
|
|
2048
|
+
let newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);
|
|
2049
|
+
dom_default.putSticky(el, "classes", (currentEl) => {
|
|
2050
|
+
currentEl.classList.remove(...newRemoves);
|
|
2051
|
+
currentEl.classList.add(...newAdds);
|
|
2052
|
+
return [newAdds, newRemoves];
|
|
2053
|
+
});
|
|
2054
|
+
});
|
|
2055
|
+
},
|
|
2056
|
+
hasAllClasses(el, classes) {
|
|
2057
|
+
return classes.every((name) => el.classList.contains(name));
|
|
2058
|
+
},
|
|
2059
|
+
isVisible(el) {
|
|
2060
|
+
let style = window.getComputedStyle(el);
|
|
2061
|
+
return !(style.opacity === 0 || style.display === "none");
|
|
2062
|
+
},
|
|
2063
|
+
isToggledOut(el, out_classes) {
|
|
2064
|
+
return !this.isVisible(el) || this.hasAllClasses(el, out_classes);
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
var js_default = JS;
|
|
2068
|
+
|
|
1865
2069
|
// js/phoenix_live_view/view.js
|
|
1866
2070
|
var serializeForm = (form, meta = {}) => {
|
|
1867
2071
|
let formData = new FormData(form);
|
|
@@ -1899,7 +2103,8 @@ var View = class {
|
|
|
1899
2103
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
|
|
1900
2104
|
this.joinPending = true;
|
|
1901
2105
|
this.destroyed = false;
|
|
1902
|
-
this.joinCallback = function() {
|
|
2106
|
+
this.joinCallback = function(onDone) {
|
|
2107
|
+
onDone && onDone();
|
|
1903
2108
|
};
|
|
1904
2109
|
this.stopCallback = function() {
|
|
1905
2110
|
};
|
|
@@ -1974,9 +2179,6 @@ var View = class {
|
|
|
1974
2179
|
this.el.classList.remove(PHX_CONNECTED_CLASS, PHX_DISCONNECTED_CLASS, PHX_ERROR_CLASS);
|
|
1975
2180
|
this.el.classList.add(...classes);
|
|
1976
2181
|
}
|
|
1977
|
-
isLoading() {
|
|
1978
|
-
return this.el.classList.contains(PHX_DISCONNECTED_CLASS);
|
|
1979
|
-
}
|
|
1980
2182
|
showLoader(timeout) {
|
|
1981
2183
|
clearTimeout(this.loaderTimer);
|
|
1982
2184
|
if (timeout) {
|
|
@@ -2000,16 +2202,20 @@ var View = class {
|
|
|
2000
2202
|
log(kind, msgCallback) {
|
|
2001
2203
|
this.liveSocket.log(this, kind, msgCallback);
|
|
2002
2204
|
}
|
|
2205
|
+
transition(time, onDone = function() {
|
|
2206
|
+
}) {
|
|
2207
|
+
this.liveSocket.transition(time, onDone);
|
|
2208
|
+
}
|
|
2003
2209
|
withinTargets(phxTarget, callback) {
|
|
2004
|
-
if (phxTarget instanceof HTMLElement) {
|
|
2210
|
+
if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {
|
|
2005
2211
|
return this.liveSocket.owner(phxTarget, (view) => callback(view, phxTarget));
|
|
2006
2212
|
}
|
|
2007
|
-
if (/^(0|[1-9]\d*)$/.test(phxTarget)) {
|
|
2213
|
+
if (typeof phxTarget === "number" || /^(0|[1-9]\d*)$/.test(phxTarget)) {
|
|
2008
2214
|
let targets = dom_default.findComponentNodeList(this.el, phxTarget);
|
|
2009
2215
|
if (targets.length === 0) {
|
|
2010
2216
|
logError(`no component found matching phx-target of ${phxTarget}`);
|
|
2011
2217
|
} else {
|
|
2012
|
-
callback(this,
|
|
2218
|
+
callback(this, parseInt(phxTarget));
|
|
2013
2219
|
}
|
|
2014
2220
|
} else {
|
|
2015
2221
|
let targets = Array.from(document.querySelectorAll(phxTarget));
|
|
@@ -2088,11 +2294,6 @@ var View = class {
|
|
|
2088
2294
|
this.el = dom_default.byId(this.id);
|
|
2089
2295
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
2090
2296
|
}
|
|
2091
|
-
dispatchEvents(events) {
|
|
2092
|
-
events.forEach(([event, payload]) => {
|
|
2093
|
-
window.dispatchEvent(new CustomEvent(`phx:hook:${event}`, { detail: payload }));
|
|
2094
|
-
});
|
|
2095
|
-
}
|
|
2096
2297
|
applyJoinPatch(live_patch, html, events) {
|
|
2097
2298
|
this.attachTrueDocEl();
|
|
2098
2299
|
let patch = new DOMPatch(this, this.el, this.id, html, null);
|
|
@@ -2106,7 +2307,7 @@ var View = class {
|
|
|
2106
2307
|
}
|
|
2107
2308
|
});
|
|
2108
2309
|
this.joinPending = false;
|
|
2109
|
-
this.dispatchEvents(events);
|
|
2310
|
+
this.liveSocket.dispatchEvents(events);
|
|
2110
2311
|
this.applyPendingUpdates();
|
|
2111
2312
|
if (live_patch) {
|
|
2112
2313
|
let { kind, to } = live_patch;
|
|
@@ -2128,7 +2329,7 @@ var View = class {
|
|
|
2128
2329
|
}
|
|
2129
2330
|
}
|
|
2130
2331
|
performPatch(patch, pruneCids) {
|
|
2131
|
-
let
|
|
2332
|
+
let removedEls = [];
|
|
2132
2333
|
let phxChildrenAdded = false;
|
|
2133
2334
|
let updatedHookIds = new Set();
|
|
2134
2335
|
patch.after("added", (el) => {
|
|
@@ -2151,18 +2352,31 @@ var View = class {
|
|
|
2151
2352
|
}
|
|
2152
2353
|
});
|
|
2153
2354
|
patch.after("discarded", (el) => {
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
destroyedCIDs.push(cid);
|
|
2355
|
+
if (el.nodeType === Node.ELEMENT_NODE) {
|
|
2356
|
+
removedEls.push(el);
|
|
2157
2357
|
}
|
|
2158
|
-
let hook = this.getHook(el);
|
|
2159
|
-
hook && this.destroyHook(hook);
|
|
2160
2358
|
});
|
|
2359
|
+
patch.after("transitionsDiscarded", (els) => this.afterElementsRemoved(els, pruneCids));
|
|
2161
2360
|
patch.perform();
|
|
2361
|
+
this.afterElementsRemoved(removedEls, pruneCids);
|
|
2362
|
+
return phxChildrenAdded;
|
|
2363
|
+
}
|
|
2364
|
+
afterElementsRemoved(elements, pruneCids) {
|
|
2365
|
+
let destroyedCIDs = [];
|
|
2366
|
+
elements.forEach((parent) => {
|
|
2367
|
+
let components = dom_default.all(parent, `[${PHX_COMPONENT}]`);
|
|
2368
|
+
components.concat(parent).forEach((el) => {
|
|
2369
|
+
let cid = this.componentID(el);
|
|
2370
|
+
if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1) {
|
|
2371
|
+
destroyedCIDs.push(cid);
|
|
2372
|
+
}
|
|
2373
|
+
let hook = this.getHook(el);
|
|
2374
|
+
hook && this.destroyHook(hook);
|
|
2375
|
+
});
|
|
2376
|
+
});
|
|
2162
2377
|
if (pruneCids) {
|
|
2163
2378
|
this.maybePushComponentsDestroyed(destroyedCIDs);
|
|
2164
2379
|
}
|
|
2165
|
-
return phxChildrenAdded;
|
|
2166
2380
|
}
|
|
2167
2381
|
joinNewChildren() {
|
|
2168
2382
|
dom_default.findPhxChildren(this.el, this.id).forEach((el) => this.joinChild(el));
|
|
@@ -2210,13 +2424,14 @@ var View = class {
|
|
|
2210
2424
|
}
|
|
2211
2425
|
}
|
|
2212
2426
|
onAllChildJoinsComplete() {
|
|
2213
|
-
this.joinCallback()
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2427
|
+
this.joinCallback(() => {
|
|
2428
|
+
this.pendingJoinOps.forEach(([view, op]) => {
|
|
2429
|
+
if (!view.isDestroyed()) {
|
|
2430
|
+
op();
|
|
2431
|
+
}
|
|
2432
|
+
});
|
|
2433
|
+
this.pendingJoinOps = [];
|
|
2218
2434
|
});
|
|
2219
|
-
this.pendingJoinOps = [];
|
|
2220
2435
|
}
|
|
2221
2436
|
update(diff, events) {
|
|
2222
2437
|
if (this.isJoinPending() || this.liveSocket.hasPendingLink()) {
|
|
@@ -2240,7 +2455,7 @@ var View = class {
|
|
|
2240
2455
|
phxChildrenAdded = this.performPatch(patch, true);
|
|
2241
2456
|
});
|
|
2242
2457
|
}
|
|
2243
|
-
this.dispatchEvents(events);
|
|
2458
|
+
this.liveSocket.dispatchEvents(events);
|
|
2244
2459
|
if (phxChildrenAdded) {
|
|
2245
2460
|
this.joinNewChildren();
|
|
2246
2461
|
}
|
|
@@ -2298,13 +2513,15 @@ var View = class {
|
|
|
2298
2513
|
if (this.isJoinPending()) {
|
|
2299
2514
|
this.root.pendingJoinOps.push([this, () => cb(resp)]);
|
|
2300
2515
|
} else {
|
|
2301
|
-
cb(resp);
|
|
2516
|
+
this.liveSocket.requestDOMUpdate(() => cb(resp));
|
|
2302
2517
|
}
|
|
2303
2518
|
});
|
|
2304
2519
|
}
|
|
2305
2520
|
bindChannel() {
|
|
2306
2521
|
this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {
|
|
2307
|
-
this.
|
|
2522
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
2523
|
+
this.applyDiff("update", rawDiff, ({ diff, events }) => this.update(diff, events));
|
|
2524
|
+
});
|
|
2308
2525
|
});
|
|
2309
2526
|
this.onChannel("redirect", ({ to, flash }) => this.onRedirect({ to, flash }));
|
|
2310
2527
|
this.onChannel("live_patch", (redir) => this.onLivePatch(redir));
|
|
@@ -2340,9 +2557,17 @@ var View = class {
|
|
|
2340
2557
|
if (!this.parent) {
|
|
2341
2558
|
this.stopCallback = this.liveSocket.withPageLoading({ to: this.href, kind: "initial" });
|
|
2342
2559
|
}
|
|
2343
|
-
this.joinCallback = () =>
|
|
2560
|
+
this.joinCallback = (onDone) => {
|
|
2561
|
+
onDone = onDone || function() {
|
|
2562
|
+
};
|
|
2563
|
+
callback ? callback(this.joinCount, onDone) : onDone();
|
|
2564
|
+
};
|
|
2344
2565
|
this.liveSocket.wrapPush(this, { timeout: false }, () => {
|
|
2345
|
-
return this.channel.join().receive("ok", (data) =>
|
|
2566
|
+
return this.channel.join().receive("ok", (data) => {
|
|
2567
|
+
if (!this.isDestroyed()) {
|
|
2568
|
+
this.liveSocket.requestDOMUpdate(() => this.onJoin(data));
|
|
2569
|
+
}
|
|
2570
|
+
}).receive("error", (resp) => !this.isDestroyed() && this.onJoinError(resp)).receive("timeout", () => !this.isDestroyed() && this.onJoinError({ reason: "timeout" }));
|
|
2346
2571
|
});
|
|
2347
2572
|
}
|
|
2348
2573
|
onJoinError(resp) {
|
|
@@ -2398,10 +2623,10 @@ var View = class {
|
|
|
2398
2623
|
if (!this.isConnected()) {
|
|
2399
2624
|
return;
|
|
2400
2625
|
}
|
|
2401
|
-
let [ref, [el]] = refGenerator ? refGenerator() : [null, []];
|
|
2626
|
+
let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}];
|
|
2402
2627
|
let onLoadingDone = function() {
|
|
2403
2628
|
};
|
|
2404
|
-
if (el && el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null) {
|
|
2629
|
+
if (opts.page_loading || el && el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null) {
|
|
2405
2630
|
onLoadingDone = this.liveSocket.withPageLoading({ kind: "element", target: el });
|
|
2406
2631
|
}
|
|
2407
2632
|
if (typeof payload.cid !== "number") {
|
|
@@ -2409,26 +2634,28 @@ var View = class {
|
|
|
2409
2634
|
}
|
|
2410
2635
|
return this.liveSocket.wrapPush(this, { timeout: true }, () => {
|
|
2411
2636
|
return this.channel.push(event, payload, PUSH_TIMEOUT).receive("ok", (resp) => {
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
this.update(diff, events)
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2637
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
2638
|
+
let hookReply = null;
|
|
2639
|
+
if (ref !== null) {
|
|
2640
|
+
this.undoRefs(ref);
|
|
2641
|
+
}
|
|
2642
|
+
if (resp.diff) {
|
|
2643
|
+
hookReply = this.applyDiff("update", resp.diff, ({ diff, events }) => {
|
|
2644
|
+
this.update(diff, events);
|
|
2645
|
+
});
|
|
2646
|
+
}
|
|
2647
|
+
if (resp.redirect) {
|
|
2648
|
+
this.onRedirect(resp.redirect);
|
|
2649
|
+
}
|
|
2650
|
+
if (resp.live_patch) {
|
|
2651
|
+
this.onLivePatch(resp.live_patch);
|
|
2652
|
+
}
|
|
2653
|
+
if (resp.live_redirect) {
|
|
2654
|
+
this.onLiveRedirect(resp.live_redirect);
|
|
2655
|
+
}
|
|
2656
|
+
onLoadingDone();
|
|
2657
|
+
onReply(resp, hookReply);
|
|
2658
|
+
});
|
|
2432
2659
|
});
|
|
2433
2660
|
});
|
|
2434
2661
|
}
|
|
@@ -2461,9 +2688,12 @@ var View = class {
|
|
|
2461
2688
|
}
|
|
2462
2689
|
});
|
|
2463
2690
|
}
|
|
2464
|
-
putRef(elements, event) {
|
|
2691
|
+
putRef(elements, event, opts = {}) {
|
|
2465
2692
|
let newRef = this.ref++;
|
|
2466
2693
|
let disableWith = this.binding(PHX_DISABLE_WITH);
|
|
2694
|
+
if (opts.loading) {
|
|
2695
|
+
elements = elements.concat(dom_default.all(document, opts.loading));
|
|
2696
|
+
}
|
|
2467
2697
|
elements.forEach((el) => {
|
|
2468
2698
|
el.classList.add(`phx-${event}-loading`);
|
|
2469
2699
|
el.setAttribute(PHX_REF, newRef);
|
|
@@ -2475,21 +2705,25 @@ var View = class {
|
|
|
2475
2705
|
el.innerText = disableText;
|
|
2476
2706
|
}
|
|
2477
2707
|
});
|
|
2478
|
-
return [newRef, elements];
|
|
2708
|
+
return [newRef, elements, opts];
|
|
2479
2709
|
}
|
|
2480
2710
|
componentID(el) {
|
|
2481
2711
|
let cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);
|
|
2482
2712
|
return cid ? parseInt(cid) : null;
|
|
2483
2713
|
}
|
|
2484
2714
|
targetComponentID(target, targetCtx) {
|
|
2485
|
-
if (
|
|
2715
|
+
if (isCid(targetCtx)) {
|
|
2716
|
+
return targetCtx;
|
|
2717
|
+
} else if (target.getAttribute(this.binding("target"))) {
|
|
2486
2718
|
return this.closestComponentID(targetCtx);
|
|
2487
2719
|
} else {
|
|
2488
2720
|
return null;
|
|
2489
2721
|
}
|
|
2490
2722
|
}
|
|
2491
2723
|
closestComponentID(targetCtx) {
|
|
2492
|
-
if (targetCtx) {
|
|
2724
|
+
if (isCid(targetCtx)) {
|
|
2725
|
+
return targetCtx;
|
|
2726
|
+
} else if (targetCtx) {
|
|
2493
2727
|
return maybe(targetCtx.closest(`[${PHX_COMPONENT}]`), (el) => this.ownsElement(el) && this.componentID(el));
|
|
2494
2728
|
} else {
|
|
2495
2729
|
return null;
|
|
@@ -2500,8 +2734,8 @@ var View = class {
|
|
|
2500
2734
|
this.log("hook", () => ["unable to push hook event. LiveView not connected", event, payload]);
|
|
2501
2735
|
return false;
|
|
2502
2736
|
}
|
|
2503
|
-
let [ref, els] = this.putRef([], "hook");
|
|
2504
|
-
this.pushWithReply(() => [ref, els], "event", {
|
|
2737
|
+
let [ref, els, opts] = this.putRef([], "hook");
|
|
2738
|
+
this.pushWithReply(() => [ref, els, opts], "event", {
|
|
2505
2739
|
type: "hook",
|
|
2506
2740
|
event,
|
|
2507
2741
|
value: payload,
|
|
@@ -2509,38 +2743,44 @@ var View = class {
|
|
|
2509
2743
|
}, (resp, reply) => onReply(reply, ref));
|
|
2510
2744
|
return ref;
|
|
2511
2745
|
}
|
|
2512
|
-
extractMeta(el, meta) {
|
|
2746
|
+
extractMeta(el, meta, value) {
|
|
2513
2747
|
let prefix = this.binding("value-");
|
|
2514
2748
|
for (let i = 0; i < el.attributes.length; i++) {
|
|
2749
|
+
if (!meta) {
|
|
2750
|
+
meta = {};
|
|
2751
|
+
}
|
|
2515
2752
|
let name = el.attributes[i].name;
|
|
2516
2753
|
if (name.startsWith(prefix)) {
|
|
2517
2754
|
meta[name.replace(prefix, "")] = el.getAttribute(name);
|
|
2518
2755
|
}
|
|
2519
2756
|
}
|
|
2520
2757
|
if (el.value !== void 0) {
|
|
2758
|
+
if (!meta) {
|
|
2759
|
+
meta = {};
|
|
2760
|
+
}
|
|
2521
2761
|
meta.value = el.value;
|
|
2522
2762
|
if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) {
|
|
2523
2763
|
delete meta.value;
|
|
2524
2764
|
}
|
|
2525
2765
|
}
|
|
2766
|
+
if (value) {
|
|
2767
|
+
if (!meta) {
|
|
2768
|
+
meta = {};
|
|
2769
|
+
}
|
|
2770
|
+
for (let key in value) {
|
|
2771
|
+
meta[key] = value[key];
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2526
2774
|
return meta;
|
|
2527
2775
|
}
|
|
2528
|
-
pushEvent(type, el, targetCtx, phxEvent, meta) {
|
|
2529
|
-
this.pushWithReply(() => this.putRef([el], type), "event", {
|
|
2776
|
+
pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}) {
|
|
2777
|
+
this.pushWithReply(() => this.putRef([el], type, opts), "event", {
|
|
2530
2778
|
type,
|
|
2531
2779
|
event: phxEvent,
|
|
2532
|
-
value: this.extractMeta(el, meta),
|
|
2780
|
+
value: this.extractMeta(el, meta, opts.value),
|
|
2533
2781
|
cid: this.targetComponentID(el, targetCtx)
|
|
2534
2782
|
});
|
|
2535
2783
|
}
|
|
2536
|
-
pushKey(keyElement, targetCtx, kind, phxEvent, meta) {
|
|
2537
|
-
this.pushWithReply(() => this.putRef([keyElement], kind), "event", {
|
|
2538
|
-
type: kind,
|
|
2539
|
-
event: phxEvent,
|
|
2540
|
-
value: this.extractMeta(keyElement, meta),
|
|
2541
|
-
cid: this.targetComponentID(keyElement, targetCtx)
|
|
2542
|
-
});
|
|
2543
|
-
}
|
|
2544
2784
|
pushFileProgress(fileEl, entryRef, progress, onReply = function() {
|
|
2545
2785
|
}) {
|
|
2546
2786
|
this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {
|
|
@@ -2553,12 +2793,12 @@ var View = class {
|
|
|
2553
2793
|
}, onReply);
|
|
2554
2794
|
});
|
|
2555
2795
|
}
|
|
2556
|
-
pushInput(inputEl, targetCtx, forceCid, phxEvent,
|
|
2796
|
+
pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {
|
|
2557
2797
|
let uploads;
|
|
2558
2798
|
let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx);
|
|
2559
|
-
let refGenerator = () => this.putRef([inputEl, inputEl.form], "change");
|
|
2560
|
-
let formData = serializeForm(inputEl.form, { _target:
|
|
2561
|
-
if (inputEl.files && inputEl.files.length > 0) {
|
|
2799
|
+
let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts);
|
|
2800
|
+
let formData = serializeForm(inputEl.form, { _target: opts._target });
|
|
2801
|
+
if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {
|
|
2562
2802
|
LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));
|
|
2563
2803
|
}
|
|
2564
2804
|
uploads = LiveUploader.serializeUploads(inputEl);
|
|
@@ -2587,19 +2827,19 @@ var View = class {
|
|
|
2587
2827
|
triggerAwaitingSubmit(formEl) {
|
|
2588
2828
|
let awaitingSubmit = this.getScheduledSubmit(formEl);
|
|
2589
2829
|
if (awaitingSubmit) {
|
|
2590
|
-
let [_el, _ref, callback] = awaitingSubmit;
|
|
2830
|
+
let [_el, _ref, _opts, callback] = awaitingSubmit;
|
|
2591
2831
|
this.cancelSubmit(formEl);
|
|
2592
2832
|
callback();
|
|
2593
2833
|
}
|
|
2594
2834
|
}
|
|
2595
2835
|
getScheduledSubmit(formEl) {
|
|
2596
|
-
return this.formSubmits.find(([el, _callback]) => el.isSameNode(formEl));
|
|
2836
|
+
return this.formSubmits.find(([el, _ref, _opts, _callback]) => el.isSameNode(formEl));
|
|
2597
2837
|
}
|
|
2598
|
-
scheduleSubmit(formEl, ref, callback) {
|
|
2838
|
+
scheduleSubmit(formEl, ref, opts, callback) {
|
|
2599
2839
|
if (this.getScheduledSubmit(formEl)) {
|
|
2600
2840
|
return true;
|
|
2601
2841
|
}
|
|
2602
|
-
this.formSubmits.push([formEl, ref, callback]);
|
|
2842
|
+
this.formSubmits.push([formEl, ref, opts, callback]);
|
|
2603
2843
|
}
|
|
2604
2844
|
cancelSubmit(formEl) {
|
|
2605
2845
|
this.formSubmits = this.formSubmits.filter(([el, ref, _callback]) => {
|
|
@@ -2611,7 +2851,7 @@ var View = class {
|
|
|
2611
2851
|
}
|
|
2612
2852
|
});
|
|
2613
2853
|
}
|
|
2614
|
-
pushFormSubmit(formEl, targetCtx, phxEvent, onReply) {
|
|
2854
|
+
pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply) {
|
|
2615
2855
|
let filterIgnored = (el) => {
|
|
2616
2856
|
let userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form);
|
|
2617
2857
|
return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));
|
|
@@ -2639,15 +2879,16 @@ var View = class {
|
|
|
2639
2879
|
}
|
|
2640
2880
|
});
|
|
2641
2881
|
formEl.setAttribute(this.binding(PHX_PAGE_LOADING), "");
|
|
2642
|
-
return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit");
|
|
2882
|
+
return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts);
|
|
2643
2883
|
};
|
|
2644
2884
|
let cid = this.targetComponentID(formEl, targetCtx);
|
|
2645
2885
|
if (LiveUploader.hasUploadsInProgress(formEl)) {
|
|
2646
2886
|
let [ref, _els] = refGenerator();
|
|
2647
|
-
|
|
2887
|
+
let push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, opts, onReply);
|
|
2888
|
+
return this.scheduleSubmit(formEl, ref, opts, push);
|
|
2648
2889
|
} else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
2649
2890
|
let [ref, els] = refGenerator();
|
|
2650
|
-
let proxyRefGen = () => [ref, els];
|
|
2891
|
+
let proxyRefGen = () => [ref, els, opts];
|
|
2651
2892
|
this.uploadFiles(formEl, targetCtx, ref, cid, (_uploads) => {
|
|
2652
2893
|
let formData = serializeForm(formEl, {});
|
|
2653
2894
|
this.pushWithReply(proxyRefGen, "event", {
|
|
@@ -2719,22 +2960,24 @@ var View = class {
|
|
|
2719
2960
|
this.liveSocket.withinOwners(form, (view, targetCtx) => {
|
|
2720
2961
|
let input = form.elements[0];
|
|
2721
2962
|
let phxEvent = form.getAttribute(this.binding(PHX_AUTO_RECOVER)) || form.getAttribute(this.binding("change"));
|
|
2722
|
-
|
|
2963
|
+
js_default.exec("change", phxEvent, view, input, ["push", { _target: input.name, newCid, callback }]);
|
|
2723
2964
|
});
|
|
2724
2965
|
}
|
|
2725
2966
|
pushLinkPatch(href, targetEl, callback) {
|
|
2726
2967
|
let linkRef = this.liveSocket.setPendingLink(href);
|
|
2727
2968
|
let refGen = targetEl ? () => this.putRef([targetEl], "click") : null;
|
|
2728
2969
|
this.pushWithReply(refGen, "live_patch", { url: href }, (resp) => {
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
this.
|
|
2970
|
+
this.liveSocket.requestDOMUpdate(() => {
|
|
2971
|
+
if (resp.link_redirect) {
|
|
2972
|
+
this.liveSocket.replaceMain(href, null, callback, linkRef);
|
|
2973
|
+
} else {
|
|
2974
|
+
if (this.liveSocket.commitPendingLink(linkRef)) {
|
|
2975
|
+
this.href = href;
|
|
2976
|
+
}
|
|
2977
|
+
this.applyPendingUpdates();
|
|
2978
|
+
callback && callback(linkRef);
|
|
2734
2979
|
}
|
|
2735
|
-
|
|
2736
|
-
callback && callback(linkRef);
|
|
2737
|
-
}
|
|
2980
|
+
});
|
|
2738
2981
|
}).receive("timeout", () => this.liveSocket.redirect(window.location.href));
|
|
2739
2982
|
}
|
|
2740
2983
|
formsForRecovery(html) {
|
|
@@ -2775,10 +3018,10 @@ var View = class {
|
|
|
2775
3018
|
ownsElement(el) {
|
|
2776
3019
|
return el.getAttribute(PHX_PARENT_ID) === this.id || maybe(el.closest(PHX_VIEW_SELECTOR), (node) => node.id) === this.id;
|
|
2777
3020
|
}
|
|
2778
|
-
submitForm(form, targetCtx, phxEvent) {
|
|
3021
|
+
submitForm(form, targetCtx, phxEvent, opts = {}) {
|
|
2779
3022
|
dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
|
|
2780
3023
|
this.liveSocket.blurActiveElement(this);
|
|
2781
|
-
this.pushFormSubmit(form, targetCtx, phxEvent, () => {
|
|
3024
|
+
this.pushFormSubmit(form, targetCtx, phxEvent, opts, () => {
|
|
2782
3025
|
this.liveSocket.restorePreviouslyActiveFocus();
|
|
2783
3026
|
});
|
|
2784
3027
|
}
|
|
@@ -2823,6 +3066,7 @@ var LiveSocket = class {
|
|
|
2823
3066
|
this.sessionStorage = opts.sessionStorage || window.sessionStorage;
|
|
2824
3067
|
this.boundTopLevelEvents = false;
|
|
2825
3068
|
this.domCallbacks = Object.assign({ onNodeAdded: closure(), onBeforeElUpdated: closure() }, opts.dom || {});
|
|
3069
|
+
this.transitions = new TransitionSet();
|
|
2826
3070
|
window.addEventListener("pagehide", (_e) => {
|
|
2827
3071
|
this.unloaded = true;
|
|
2828
3072
|
});
|
|
@@ -2881,6 +3125,9 @@ var LiveSocket = class {
|
|
|
2881
3125
|
disconnect(callback) {
|
|
2882
3126
|
this.socket.disconnect(callback);
|
|
2883
3127
|
}
|
|
3128
|
+
execJS(el, encodedJS, eventType = null) {
|
|
3129
|
+
this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
|
|
3130
|
+
}
|
|
2884
3131
|
triggerDOM(kind, args) {
|
|
2885
3132
|
this.domCallbacks[kind](...args);
|
|
2886
3133
|
}
|
|
@@ -2902,6 +3149,13 @@ var LiveSocket = class {
|
|
|
2902
3149
|
debug(view, kind, msg, obj);
|
|
2903
3150
|
}
|
|
2904
3151
|
}
|
|
3152
|
+
requestDOMUpdate(callback) {
|
|
3153
|
+
this.transitions.after(callback);
|
|
3154
|
+
}
|
|
3155
|
+
transition(time, onDone = function() {
|
|
3156
|
+
}) {
|
|
3157
|
+
this.transitions.addTransition(time, onDone);
|
|
3158
|
+
}
|
|
2905
3159
|
onChannel(channel, event, cb) {
|
|
2906
3160
|
channel.on(event, (data) => {
|
|
2907
3161
|
let latency = this.getLatencySim();
|
|
@@ -3007,10 +3261,23 @@ var LiveSocket = class {
|
|
|
3007
3261
|
this.main.destroy();
|
|
3008
3262
|
this.main = this.newRootView(newMainEl, flash);
|
|
3009
3263
|
this.main.setRedirect(href);
|
|
3010
|
-
this.
|
|
3264
|
+
this.transitionRemoves();
|
|
3265
|
+
this.main.join((joinCount, onDone) => {
|
|
3011
3266
|
if (joinCount === 1 && this.commitPendingLink(linkRef)) {
|
|
3012
|
-
|
|
3013
|
-
|
|
3267
|
+
this.requestDOMUpdate(() => {
|
|
3268
|
+
oldMainEl.replaceWith(newMainEl);
|
|
3269
|
+
callback && callback();
|
|
3270
|
+
onDone();
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
3273
|
+
});
|
|
3274
|
+
}
|
|
3275
|
+
transitionRemoves(elements) {
|
|
3276
|
+
let removeAttr = this.binding("remove");
|
|
3277
|
+
elements = elements || dom_default.all(document, `[${removeAttr}]`);
|
|
3278
|
+
elements.forEach((el) => {
|
|
3279
|
+
if (document.body.contains(el)) {
|
|
3280
|
+
this.execJS(el, el.getAttribute(removeAttr), "remove");
|
|
3014
3281
|
}
|
|
3015
3282
|
});
|
|
3016
3283
|
}
|
|
@@ -3029,14 +3296,7 @@ var LiveSocket = class {
|
|
|
3029
3296
|
}
|
|
3030
3297
|
}
|
|
3031
3298
|
withinOwners(childEl, callback) {
|
|
3032
|
-
this.owner(childEl, (view) =>
|
|
3033
|
-
let phxTarget = childEl.getAttribute(this.binding("target"));
|
|
3034
|
-
if (phxTarget === null) {
|
|
3035
|
-
callback(view, childEl);
|
|
3036
|
-
} else {
|
|
3037
|
-
view.withinTargets(phxTarget, callback);
|
|
3038
|
-
}
|
|
3039
|
-
});
|
|
3299
|
+
this.owner(childEl, (view) => callback(view, childEl));
|
|
3040
3300
|
}
|
|
3041
3301
|
getViewByEl(el) {
|
|
3042
3302
|
let rootId = el.getAttribute(PHX_ROOT_ID);
|
|
@@ -3112,22 +3372,25 @@ var LiveSocket = class {
|
|
|
3112
3372
|
this.bindNav();
|
|
3113
3373
|
this.bindClicks();
|
|
3114
3374
|
this.bindForms();
|
|
3115
|
-
this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view,
|
|
3116
|
-
let matchKey =
|
|
3375
|
+
this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent, eventTarget) => {
|
|
3376
|
+
let matchKey = targetEl.getAttribute(this.binding(PHX_KEY));
|
|
3117
3377
|
let pressedKey = e.key && e.key.toLowerCase();
|
|
3118
3378
|
if (matchKey && matchKey.toLowerCase() !== pressedKey) {
|
|
3119
3379
|
return;
|
|
3120
3380
|
}
|
|
3121
|
-
|
|
3381
|
+
let data = { key: e.key, ...this.eventMeta(type, e, targetEl) };
|
|
3382
|
+
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
3122
3383
|
});
|
|
3123
|
-
this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl,
|
|
3124
|
-
if (!
|
|
3125
|
-
|
|
3384
|
+
this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent, eventTarget) => {
|
|
3385
|
+
if (!eventTarget) {
|
|
3386
|
+
let data = { key: e.key, ...this.eventMeta(type, e, targetEl) };
|
|
3387
|
+
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
3126
3388
|
}
|
|
3127
3389
|
});
|
|
3128
3390
|
this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, targetCtx, phxEvent, phxTarget) => {
|
|
3129
|
-
if (phxTarget
|
|
3130
|
-
|
|
3391
|
+
if (phxTarget === "window") {
|
|
3392
|
+
let data = this.eventMeta(type, e, targetEl);
|
|
3393
|
+
js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
|
|
3131
3394
|
}
|
|
3132
3395
|
});
|
|
3133
3396
|
window.addEventListener("dragover", (e) => e.preventDefault());
|
|
@@ -3187,16 +3450,16 @@ var LiveSocket = class {
|
|
|
3187
3450
|
let targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding);
|
|
3188
3451
|
if (targetPhxEvent) {
|
|
3189
3452
|
this.debounce(e.target, e, () => {
|
|
3190
|
-
this.withinOwners(e.target, (view
|
|
3191
|
-
callback(e, event, view, e.target,
|
|
3453
|
+
this.withinOwners(e.target, (view) => {
|
|
3454
|
+
callback(e, event, view, e.target, targetPhxEvent, null);
|
|
3192
3455
|
});
|
|
3193
3456
|
});
|
|
3194
3457
|
} else {
|
|
3195
3458
|
dom_default.all(document, `[${windowBinding}]`, (el) => {
|
|
3196
3459
|
let phxEvent = el.getAttribute(windowBinding);
|
|
3197
3460
|
this.debounce(el, e, () => {
|
|
3198
|
-
this.withinOwners(el, (view
|
|
3199
|
-
callback(e, event, view, el,
|
|
3461
|
+
this.withinOwners(el, (view) => {
|
|
3462
|
+
callback(e, event, view, el, phxEvent, "window");
|
|
3200
3463
|
});
|
|
3201
3464
|
});
|
|
3202
3465
|
});
|
|
@@ -3219,6 +3482,7 @@ var LiveSocket = class {
|
|
|
3219
3482
|
target = e.target.matches(`[${click}]`) ? e.target : e.target.querySelector(`[${click}]`);
|
|
3220
3483
|
} else {
|
|
3221
3484
|
target = closestPhxBinding(e.target, click);
|
|
3485
|
+
this.dispatchClickAway(e);
|
|
3222
3486
|
}
|
|
3223
3487
|
let phxEvent = target && target.getAttribute(click);
|
|
3224
3488
|
if (!phxEvent) {
|
|
@@ -3228,12 +3492,23 @@ var LiveSocket = class {
|
|
|
3228
3492
|
e.preventDefault();
|
|
3229
3493
|
}
|
|
3230
3494
|
this.debounce(target, e, () => {
|
|
3231
|
-
this.withinOwners(target, (view
|
|
3232
|
-
|
|
3495
|
+
this.withinOwners(target, (view) => {
|
|
3496
|
+
js_default.exec("click", phxEvent, view, target, ["push", { data: this.eventMeta("click", e, target) }]);
|
|
3233
3497
|
});
|
|
3234
3498
|
});
|
|
3235
3499
|
}, capture);
|
|
3236
3500
|
}
|
|
3501
|
+
dispatchClickAway(e) {
|
|
3502
|
+
let binding = this.binding("click-away");
|
|
3503
|
+
dom_default.all(document, `[${binding}]`, (el) => {
|
|
3504
|
+
if (!(el.isSameNode(e.target) || el.contains(e.target))) {
|
|
3505
|
+
this.withinOwners(e.target, (view) => {
|
|
3506
|
+
let phxEvent = el.getAttribute(binding);
|
|
3507
|
+
js_default.exec("click", phxEvent, view, e.target, ["push", { data: this.eventMeta("click", e, e.target) }]);
|
|
3508
|
+
});
|
|
3509
|
+
}
|
|
3510
|
+
});
|
|
3511
|
+
}
|
|
3237
3512
|
bindNav() {
|
|
3238
3513
|
if (!browser_default.canPushState()) {
|
|
3239
3514
|
return;
|
|
@@ -3254,20 +3529,22 @@ var LiveSocket = class {
|
|
|
3254
3529
|
}
|
|
3255
3530
|
let { type, id, root, scroll } = event.state || {};
|
|
3256
3531
|
let href = window.location.href;
|
|
3257
|
-
|
|
3258
|
-
this.main.
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3532
|
+
this.requestDOMUpdate(() => {
|
|
3533
|
+
if (this.main.isConnected() && (type === "patch" && id === this.main.id)) {
|
|
3534
|
+
this.main.pushLinkPatch(href, null);
|
|
3535
|
+
} else {
|
|
3536
|
+
this.replaceMain(href, null, () => {
|
|
3537
|
+
if (root) {
|
|
3538
|
+
this.replaceRootHistory();
|
|
3539
|
+
}
|
|
3540
|
+
if (typeof scroll === "number") {
|
|
3541
|
+
setTimeout(() => {
|
|
3542
|
+
window.scrollTo(0, scroll);
|
|
3543
|
+
}, 0);
|
|
3544
|
+
}
|
|
3545
|
+
});
|
|
3546
|
+
}
|
|
3547
|
+
});
|
|
3271
3548
|
}, false);
|
|
3272
3549
|
window.addEventListener("click", (e) => {
|
|
3273
3550
|
let target = closestPhxBinding(e.target, PHX_LIVE_LINK);
|
|
@@ -3282,15 +3559,23 @@ var LiveSocket = class {
|
|
|
3282
3559
|
if (this.pendingLink === href) {
|
|
3283
3560
|
return;
|
|
3284
3561
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3562
|
+
this.requestDOMUpdate(() => {
|
|
3563
|
+
if (type === "patch") {
|
|
3564
|
+
this.pushHistoryPatch(href, linkState, target);
|
|
3565
|
+
} else if (type === "redirect") {
|
|
3566
|
+
this.historyRedirect(href, linkState);
|
|
3567
|
+
} else {
|
|
3568
|
+
throw new Error(`expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`);
|
|
3569
|
+
}
|
|
3570
|
+
});
|
|
3292
3571
|
}, false);
|
|
3293
3572
|
}
|
|
3573
|
+
dispatchEvent(event, payload = {}) {
|
|
3574
|
+
dom_default.dispatchEvent(window, `phx:${event}`, payload);
|
|
3575
|
+
}
|
|
3576
|
+
dispatchEvents(events) {
|
|
3577
|
+
events.forEach(([event, payload]) => this.dispatchEvent(event, payload));
|
|
3578
|
+
}
|
|
3294
3579
|
withPageLoading(info, callback) {
|
|
3295
3580
|
dom_default.dispatchEvent(window, "phx:page-loading-start", info);
|
|
3296
3581
|
let done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", info);
|
|
@@ -3342,7 +3627,9 @@ var LiveSocket = class {
|
|
|
3342
3627
|
}
|
|
3343
3628
|
e.preventDefault();
|
|
3344
3629
|
e.target.disabled = true;
|
|
3345
|
-
this.withinOwners(e.target, (view
|
|
3630
|
+
this.withinOwners(e.target, (view) => {
|
|
3631
|
+
js_default.exec("submit", phxEvent, view, e.target, ["push", {}]);
|
|
3632
|
+
});
|
|
3346
3633
|
}, false);
|
|
3347
3634
|
for (let type of ["change", "input"]) {
|
|
3348
3635
|
this.on(type, (e) => {
|
|
@@ -3362,12 +3649,12 @@ var LiveSocket = class {
|
|
|
3362
3649
|
}
|
|
3363
3650
|
dom_default.putPrivate(input, "prev-iteration", { at: currentIterations, type });
|
|
3364
3651
|
this.debounce(input, e, () => {
|
|
3365
|
-
this.withinOwners(input.form, (view
|
|
3652
|
+
this.withinOwners(input.form, (view) => {
|
|
3366
3653
|
dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);
|
|
3367
3654
|
if (!dom_default.isTextualInput(input)) {
|
|
3368
3655
|
this.setActiveElement(input);
|
|
3369
3656
|
}
|
|
3370
|
-
|
|
3657
|
+
js_default.exec("change", phxEvent, view, input, ["push", { _target: e.target.name }]);
|
|
3371
3658
|
});
|
|
3372
3659
|
});
|
|
3373
3660
|
}, false);
|
|
@@ -3393,6 +3680,47 @@ var LiveSocket = class {
|
|
|
3393
3680
|
});
|
|
3394
3681
|
}
|
|
3395
3682
|
};
|
|
3683
|
+
var TransitionSet = class {
|
|
3684
|
+
constructor() {
|
|
3685
|
+
this.transitions = new Set();
|
|
3686
|
+
this.pendingOps = [];
|
|
3687
|
+
this.reset();
|
|
3688
|
+
}
|
|
3689
|
+
reset() {
|
|
3690
|
+
this.transitions.forEach((timer) => {
|
|
3691
|
+
cancelTimeout(timer);
|
|
3692
|
+
this.transitions.delete(timer);
|
|
3693
|
+
});
|
|
3694
|
+
this.flushPendingOps();
|
|
3695
|
+
}
|
|
3696
|
+
after(callback) {
|
|
3697
|
+
if (this.size() === 0) {
|
|
3698
|
+
callback();
|
|
3699
|
+
} else {
|
|
3700
|
+
this.pushPendingOp(callback);
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
addTransition(time, onDone) {
|
|
3704
|
+
let timer = setTimeout(() => {
|
|
3705
|
+
this.transitions.delete(timer);
|
|
3706
|
+
onDone();
|
|
3707
|
+
if (this.size() === 0) {
|
|
3708
|
+
this.flushPendingOps();
|
|
3709
|
+
}
|
|
3710
|
+
}, time);
|
|
3711
|
+
this.transitions.add(timer);
|
|
3712
|
+
}
|
|
3713
|
+
pushPendingOp(op) {
|
|
3714
|
+
this.pendingOps.push(op);
|
|
3715
|
+
}
|
|
3716
|
+
size() {
|
|
3717
|
+
return this.transitions.size;
|
|
3718
|
+
}
|
|
3719
|
+
flushPendingOps() {
|
|
3720
|
+
this.pendingOps.forEach((op) => op());
|
|
3721
|
+
this.pendingOps = [];
|
|
3722
|
+
}
|
|
3723
|
+
};
|
|
3396
3724
|
export {
|
|
3397
3725
|
LiveSocket
|
|
3398
3726
|
};
|