phoenix_live_view 0.20.7 → 0.20.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/js/phoenix_live_view/dom_patch.js +14 -7
- package/assets/js/phoenix_live_view/rendered.js +8 -10
- package/assets/js/phoenix_live_view/view.js +7 -8
- package/assets/package.json +1 -1
- package/package.json +1 -1
- package/priv/static/phoenix_live_view.cjs.js +18 -22
- package/priv/static/phoenix_live_view.cjs.js.map +2 -2
- package/priv/static/phoenix_live_view.esm.js +18 -22
- package/priv/static/phoenix_live_view.esm.js.map +2 -2
- package/priv/static/phoenix_live_view.js +18 -22
- package/priv/static/phoenix_live_view.min.js +5 -5
|
@@ -331,14 +331,15 @@ export default class DOMPatch {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
removeStreamChildElement(child){
|
|
334
|
-
if
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
334
|
+
// we need to store the node if it is actually re-added in the same patch
|
|
335
|
+
// we do NOT want to execute phx-remove, we do NOT want to call onNodeDiscarded
|
|
336
|
+
if(this.streamInserts[child.id]){
|
|
337
|
+
this.streamComponentRestore[child.id] = child
|
|
338
|
+
child.remove()
|
|
339
|
+
} else {
|
|
340
|
+
// only remove the element now if it has no phx-remove binding
|
|
341
|
+
if(!this.maybePendingRemove(child)){
|
|
340
342
|
child.remove()
|
|
341
|
-
// TODO: check if we really don't want to call discarded for re-added stream items
|
|
342
343
|
this.onNodeDiscarded(child)
|
|
343
344
|
}
|
|
344
345
|
}
|
|
@@ -365,6 +366,12 @@ export default class DOMPatch {
|
|
|
365
366
|
return
|
|
366
367
|
}
|
|
367
368
|
|
|
369
|
+
// check if the element has a parent element;
|
|
370
|
+
// it doesn't if we are currently recursively morphing (restoring a saved stream child)
|
|
371
|
+
// because the element is not yet added to the real dom;
|
|
372
|
+
// reordering does not make sense in that case anyway
|
|
373
|
+
if(!el.parentElement){ return }
|
|
374
|
+
|
|
368
375
|
if(streamAt === 0){
|
|
369
376
|
el.parentElement.insertBefore(el, el.parentElement.firstElementChild)
|
|
370
377
|
} else if(streamAt > 0){
|
|
@@ -167,13 +167,6 @@ export default class Rendered {
|
|
|
167
167
|
let newc = diff[COMPONENTS]
|
|
168
168
|
let cache = {}
|
|
169
169
|
delete diff[COMPONENTS]
|
|
170
|
-
// we must consider all newly added components as reset for proper change tracking
|
|
171
|
-
if(newc){
|
|
172
|
-
let prevComponents = this.rendered[COMPONENTS] || {}
|
|
173
|
-
for(let cid in newc){
|
|
174
|
-
if(prevComponents[cid] === undefined){ newc[cid].reset = true }
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
170
|
this.rendered = this.mutableMerge(this.rendered, diff)
|
|
178
171
|
this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {}
|
|
179
172
|
|
|
@@ -257,6 +250,8 @@ export default class Rendered {
|
|
|
257
250
|
let targetVal = target[key]
|
|
258
251
|
if(isObject(val) && val[STATIC] === undefined && isObject(targetVal)){
|
|
259
252
|
merged[key] = this.cloneMerge(targetVal, val, pruneMagicId)
|
|
253
|
+
} else if(val === undefined && isObject(targetVal)){
|
|
254
|
+
merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId)
|
|
260
255
|
}
|
|
261
256
|
}
|
|
262
257
|
if(pruneMagicId){
|
|
@@ -294,7 +289,7 @@ export default class Rendered {
|
|
|
294
289
|
|
|
295
290
|
nextMagicID(){
|
|
296
291
|
this.magicId++
|
|
297
|
-
return
|
|
292
|
+
return `m${this.magicId}-${this.parentViewId()}`
|
|
298
293
|
}
|
|
299
294
|
|
|
300
295
|
// Converts rendered tree to output buffer.
|
|
@@ -330,7 +325,7 @@ export default class Rendered {
|
|
|
330
325
|
if(isRoot){
|
|
331
326
|
let skip = false
|
|
332
327
|
let attrs
|
|
333
|
-
//
|
|
328
|
+
// When a LC is re-added to the page, we need to re-render the entire LC tree,
|
|
334
329
|
// therefore changeTracking is false; however, we need to keep all the magicIds
|
|
335
330
|
// from any function component so the next time the LC is updated, we can apply
|
|
336
331
|
// the skip optimization
|
|
@@ -403,12 +398,15 @@ export default class Rendered {
|
|
|
403
398
|
// Both optimization flows apply here. newRender is set based on the onlyCids optimization, and
|
|
404
399
|
// we track a deterministic magicId based on the cid.
|
|
405
400
|
//
|
|
401
|
+
// changeTracking is about the entire tree
|
|
402
|
+
// newRender is about the current root in the tree
|
|
403
|
+
//
|
|
406
404
|
// By default changeTracking is enabled, but we special case the flow where the client is pruning
|
|
407
405
|
// cids and the server adds the component back. In such cases, we explicitly disable changeTracking
|
|
408
406
|
// with resetRender for this cid, then re-enable it after the recursive call to skip the optimization
|
|
409
407
|
// for the entire component tree.
|
|
410
408
|
component.newRender = !skip
|
|
411
|
-
component.magicId =
|
|
409
|
+
component.magicId = `c${cid}-${this.parentViewId()}`
|
|
412
410
|
// enable change tracking as long as the component hasn't been reset
|
|
413
411
|
let changeTracking = !component.reset
|
|
414
412
|
let [html, streams] = this.recursiveToString(component, components, onlyCids, changeTracking, attrs)
|
|
@@ -120,7 +120,6 @@ export default class View {
|
|
|
120
120
|
this.childJoins = 0
|
|
121
121
|
this.loaderTimer = null
|
|
122
122
|
this.pendingDiffs = []
|
|
123
|
-
this.pruningCIDs = []
|
|
124
123
|
this.redirect = false
|
|
125
124
|
this.href = null
|
|
126
125
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0
|
|
@@ -130,7 +129,6 @@ export default class View {
|
|
|
130
129
|
this.stopCallback = function(){ }
|
|
131
130
|
this.pendingJoinOps = this.parent ? null : []
|
|
132
131
|
this.viewHooks = {}
|
|
133
|
-
this.uploaders = {}
|
|
134
132
|
this.formSubmits = []
|
|
135
133
|
this.children = this.parent ? null : {}
|
|
136
134
|
this.root.children[this.id] = {}
|
|
@@ -560,7 +558,7 @@ export default class View {
|
|
|
560
558
|
let tag = this.el.tagName
|
|
561
559
|
// Don't skip any component in the diff nor any marked as pruned
|
|
562
560
|
// (as they may have been added back)
|
|
563
|
-
let cids = diff ? this.rendered.componentCIDs(diff)
|
|
561
|
+
let cids = diff ? this.rendered.componentCIDs(diff) : null
|
|
564
562
|
let [html, streams] = this.rendered.toString(cids)
|
|
565
563
|
return [`<${tag}>${html}</${tag}>`, streams]
|
|
566
564
|
})
|
|
@@ -1065,9 +1063,13 @@ export default class View {
|
|
|
1065
1063
|
if(numFileInputsInProgress === 0){ onComplete() }
|
|
1066
1064
|
});
|
|
1067
1065
|
|
|
1068
|
-
this.uploaders[inputEl] = uploader
|
|
1069
1066
|
let entries = uploader.entries().map(entry => entry.toPreflightPayload())
|
|
1070
1067
|
|
|
1068
|
+
if (entries.length === 0) {
|
|
1069
|
+
numFileInputsInProgress--
|
|
1070
|
+
return
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1071
1073
|
let payload = {
|
|
1072
1074
|
ref: inputEl.getAttribute(PHX_UPLOAD_REF),
|
|
1073
1075
|
entries: entries,
|
|
@@ -1183,11 +1185,9 @@ export default class View {
|
|
|
1183
1185
|
}
|
|
1184
1186
|
|
|
1185
1187
|
maybePushComponentsDestroyed(destroyedCIDs){
|
|
1186
|
-
let willDestroyCIDs = destroyedCIDs.
|
|
1188
|
+
let willDestroyCIDs = destroyedCIDs.filter(cid => {
|
|
1187
1189
|
return DOM.findComponentNodeList(this.el, cid).length === 0
|
|
1188
1190
|
})
|
|
1189
|
-
// make sure this is a copy and not a reference
|
|
1190
|
-
this.pruningCIDs = willDestroyCIDs.concat([])
|
|
1191
1191
|
|
|
1192
1192
|
if(willDestroyCIDs.length > 0){
|
|
1193
1193
|
// we must reset the render change tracking for cids that
|
|
@@ -1203,7 +1203,6 @@ export default class View {
|
|
|
1203
1203
|
|
|
1204
1204
|
if(completelyDestroyCIDs.length > 0){
|
|
1205
1205
|
this.pushWithReply(null, "cids_destroyed", {cids: completelyDestroyCIDs}, (resp) => {
|
|
1206
|
-
this.pruningCIDs = this.pruningCIDs.filter(cid => resp.cids.indexOf(cid) === -1)
|
|
1207
1206
|
this.rendered.pruneCIDs(resp.cids)
|
|
1208
1207
|
})
|
|
1209
1208
|
}
|
package/assets/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2363,11 +2363,11 @@ var DOMPatch = class {
|
|
|
2363
2363
|
}
|
|
2364
2364
|
}
|
|
2365
2365
|
removeStreamChildElement(child) {
|
|
2366
|
-
if (
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2366
|
+
if (this.streamInserts[child.id]) {
|
|
2367
|
+
this.streamComponentRestore[child.id] = child;
|
|
2368
|
+
child.remove();
|
|
2369
|
+
} else {
|
|
2370
|
+
if (!this.maybePendingRemove(child)) {
|
|
2371
2371
|
child.remove();
|
|
2372
2372
|
this.onNodeDiscarded(child);
|
|
2373
2373
|
}
|
|
@@ -2389,6 +2389,9 @@ var DOMPatch = class {
|
|
|
2389
2389
|
if (!reset && !isNew) {
|
|
2390
2390
|
return;
|
|
2391
2391
|
}
|
|
2392
|
+
if (!el.parentElement) {
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2392
2395
|
if (streamAt === 0) {
|
|
2393
2396
|
el.parentElement.insertBefore(el, el.parentElement.firstElementChild);
|
|
2394
2397
|
} else if (streamAt > 0) {
|
|
@@ -2606,14 +2609,6 @@ var Rendered = class {
|
|
|
2606
2609
|
let newc = diff[COMPONENTS];
|
|
2607
2610
|
let cache = {};
|
|
2608
2611
|
delete diff[COMPONENTS];
|
|
2609
|
-
if (newc) {
|
|
2610
|
-
let prevComponents = this.rendered[COMPONENTS] || {};
|
|
2611
|
-
for (let cid in newc) {
|
|
2612
|
-
if (prevComponents[cid] === void 0) {
|
|
2613
|
-
newc[cid].reset = true;
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
2612
|
this.rendered = this.mutableMerge(this.rendered, diff);
|
|
2618
2613
|
this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {};
|
|
2619
2614
|
if (newc) {
|
|
@@ -2679,6 +2674,8 @@ var Rendered = class {
|
|
|
2679
2674
|
let targetVal = target[key];
|
|
2680
2675
|
if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {
|
|
2681
2676
|
merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);
|
|
2677
|
+
} else if (val === void 0 && isObject(targetVal)) {
|
|
2678
|
+
merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);
|
|
2682
2679
|
}
|
|
2683
2680
|
}
|
|
2684
2681
|
if (pruneMagicId) {
|
|
@@ -2712,7 +2709,7 @@ var Rendered = class {
|
|
|
2712
2709
|
}
|
|
2713
2710
|
nextMagicID() {
|
|
2714
2711
|
this.magicId++;
|
|
2715
|
-
return
|
|
2712
|
+
return `m${this.magicId}-${this.parentViewId()}`;
|
|
2716
2713
|
}
|
|
2717
2714
|
toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {
|
|
2718
2715
|
if (rendered[DYNAMICS]) {
|
|
@@ -2787,7 +2784,7 @@ var Rendered = class {
|
|
|
2787
2784
|
let attrs = { [PHX_COMPONENT]: cid };
|
|
2788
2785
|
let skip = onlyCids && !onlyCids.has(cid);
|
|
2789
2786
|
component.newRender = !skip;
|
|
2790
|
-
component.magicId =
|
|
2787
|
+
component.magicId = `c${cid}-${this.parentViewId()}`;
|
|
2791
2788
|
let changeTracking = !component.reset;
|
|
2792
2789
|
let [html, streams] = this.recursiveToString(component, components, onlyCids, changeTracking, attrs);
|
|
2793
2790
|
delete component.reset;
|
|
@@ -2923,7 +2920,6 @@ var View = class {
|
|
|
2923
2920
|
this.childJoins = 0;
|
|
2924
2921
|
this.loaderTimer = null;
|
|
2925
2922
|
this.pendingDiffs = [];
|
|
2926
|
-
this.pruningCIDs = [];
|
|
2927
2923
|
this.redirect = false;
|
|
2928
2924
|
this.href = null;
|
|
2929
2925
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
|
|
@@ -2936,7 +2932,6 @@ var View = class {
|
|
|
2936
2932
|
};
|
|
2937
2933
|
this.pendingJoinOps = this.parent ? null : [];
|
|
2938
2934
|
this.viewHooks = {};
|
|
2939
|
-
this.uploaders = {};
|
|
2940
2935
|
this.formSubmits = [];
|
|
2941
2936
|
this.children = this.parent ? null : {};
|
|
2942
2937
|
this.root.children[this.id] = {};
|
|
@@ -3331,7 +3326,7 @@ var View = class {
|
|
|
3331
3326
|
renderContainer(diff, kind) {
|
|
3332
3327
|
return this.liveSocket.time(`toString diff (${kind})`, () => {
|
|
3333
3328
|
let tag = this.el.tagName;
|
|
3334
|
-
let cids = diff ? this.rendered.componentCIDs(diff)
|
|
3329
|
+
let cids = diff ? this.rendered.componentCIDs(diff) : null;
|
|
3335
3330
|
let [html, streams] = this.rendered.toString(cids);
|
|
3336
3331
|
return [`<${tag}>${html}</${tag}>`, streams];
|
|
3337
3332
|
});
|
|
@@ -3850,8 +3845,11 @@ var View = class {
|
|
|
3850
3845
|
onComplete();
|
|
3851
3846
|
}
|
|
3852
3847
|
});
|
|
3853
|
-
this.uploaders[inputEl] = uploader;
|
|
3854
3848
|
let entries = uploader.entries().map((entry) => entry.toPreflightPayload());
|
|
3849
|
+
if (entries.length === 0) {
|
|
3850
|
+
numFileInputsInProgress--;
|
|
3851
|
+
return;
|
|
3852
|
+
}
|
|
3855
3853
|
let payload = {
|
|
3856
3854
|
ref: inputEl.getAttribute(PHX_UPLOAD_REF),
|
|
3857
3855
|
entries,
|
|
@@ -3953,10 +3951,9 @@ var View = class {
|
|
|
3953
3951
|
}).filter(([form, newForm, newCid]) => newForm);
|
|
3954
3952
|
}
|
|
3955
3953
|
maybePushComponentsDestroyed(destroyedCIDs) {
|
|
3956
|
-
let willDestroyCIDs = destroyedCIDs.
|
|
3954
|
+
let willDestroyCIDs = destroyedCIDs.filter((cid) => {
|
|
3957
3955
|
return dom_default.findComponentNodeList(this.el, cid).length === 0;
|
|
3958
3956
|
});
|
|
3959
|
-
this.pruningCIDs = willDestroyCIDs.concat([]);
|
|
3960
3957
|
if (willDestroyCIDs.length > 0) {
|
|
3961
3958
|
willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));
|
|
3962
3959
|
this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }, () => {
|
|
@@ -3965,7 +3962,6 @@ var View = class {
|
|
|
3965
3962
|
});
|
|
3966
3963
|
if (completelyDestroyCIDs.length > 0) {
|
|
3967
3964
|
this.pushWithReply(null, "cids_destroyed", { cids: completelyDestroyCIDs }, (resp) => {
|
|
3968
|
-
this.pruningCIDs = this.pruningCIDs.filter((cid) => resp.cids.indexOf(cid) === -1);
|
|
3969
3965
|
this.rendered.pruneCIDs(resp.cids);
|
|
3970
3966
|
});
|
|
3971
3967
|
}
|