phoenix_live_view 0.20.9 → 0.20.11
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/live_uploader.js +14 -6
- package/assets/js/phoenix_live_view/upload_entry.js +14 -7
- package/assets/js/phoenix_live_view/view.js +41 -6
- package/assets/package.json +1 -1
- package/package.json +1 -1
- package/priv/static/phoenix_live_view.cjs.js +60 -14
- package/priv/static/phoenix_live_view.cjs.js.map +2 -2
- package/priv/static/phoenix_live_view.esm.js +60 -14
- package/priv/static/phoenix_live_view.esm.js.map +2 -2
- package/priv/static/phoenix_live_view.js +60 -14
- package/priv/static/phoenix_live_view.min.js +4 -4
|
@@ -70,7 +70,7 @@ export default class LiveUploader {
|
|
|
70
70
|
static trackFiles(inputEl, files, dataTransfer){
|
|
71
71
|
if(inputEl.getAttribute("multiple") !== null){
|
|
72
72
|
let newFiles = files.filter(file => !this.activeFiles(inputEl).find(f => Object.is(f, file)))
|
|
73
|
-
DOM.
|
|
73
|
+
DOM.updatePrivate(inputEl, "files", [], (existing) => existing.concat(newFiles))
|
|
74
74
|
inputEl.value = null
|
|
75
75
|
} else {
|
|
76
76
|
// Reset inputEl files to align output with programmatic changes (i.e. drag and drop)
|
|
@@ -102,28 +102,36 @@ export default class LiveUploader {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
constructor(inputEl, view, onComplete){
|
|
105
|
+
this.autoUpload = DOM.isAutoUpload(inputEl)
|
|
105
106
|
this.view = view
|
|
106
107
|
this.onComplete = onComplete
|
|
107
108
|
this._entries =
|
|
108
109
|
Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || [])
|
|
109
|
-
.map(file => new UploadEntry(inputEl, file, view))
|
|
110
|
+
.map(file => new UploadEntry(inputEl, file, view, this.autoUpload))
|
|
110
111
|
|
|
111
|
-
// prevent sending duplicate preflight requests
|
|
112
|
+
// prevent sending duplicate preflight requests
|
|
112
113
|
LiveUploader.markPreflightInProgress(this._entries)
|
|
113
114
|
|
|
114
115
|
this.numEntriesInProgress = this._entries.length
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
isAutoUpload(){ return this.autoUpload }
|
|
119
|
+
|
|
117
120
|
entries(){ return this._entries }
|
|
118
121
|
|
|
119
122
|
initAdapterUpload(resp, onError, liveSocket){
|
|
120
123
|
this._entries =
|
|
121
124
|
this._entries.map(entry => {
|
|
122
|
-
entry.
|
|
123
|
-
entry.onDone(() => {
|
|
125
|
+
if(entry.isCancelled()){
|
|
124
126
|
this.numEntriesInProgress--
|
|
125
127
|
if(this.numEntriesInProgress === 0){ this.onComplete() }
|
|
126
|
-
}
|
|
128
|
+
} else {
|
|
129
|
+
entry.zipPostFlight(resp)
|
|
130
|
+
entry.onDone(() => {
|
|
131
|
+
this.numEntriesInProgress--
|
|
132
|
+
if(this.numEntriesInProgress === 0){ this.onComplete() }
|
|
133
|
+
})
|
|
134
|
+
}
|
|
127
135
|
return entry
|
|
128
136
|
})
|
|
129
137
|
|
|
@@ -10,15 +10,13 @@ import {
|
|
|
10
10
|
} from "./utils"
|
|
11
11
|
|
|
12
12
|
import LiveUploader from "./live_uploader"
|
|
13
|
-
import DOM from "./dom"
|
|
14
13
|
|
|
15
14
|
export default class UploadEntry {
|
|
16
15
|
static isActive(fileEl, file){
|
|
17
16
|
let isNew = file._phxRef === undefined
|
|
18
|
-
let isPreflightInProgress = UploadEntry.isPreflightInProgress(file)
|
|
19
17
|
let activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",")
|
|
20
18
|
let isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0
|
|
21
|
-
return file.size > 0 && (isNew || isActive
|
|
19
|
+
return file.size > 0 && (isNew || isActive)
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
static isPreflighted(fileEl, file){
|
|
@@ -35,7 +33,7 @@ export default class UploadEntry {
|
|
|
35
33
|
file._preflightInProgress = true
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
constructor(fileEl, file, view){
|
|
36
|
+
constructor(fileEl, file, view, autoUpload){
|
|
39
37
|
this.ref = LiveUploader.genFileRef(file)
|
|
40
38
|
this.fileEl = fileEl
|
|
41
39
|
this.file = file
|
|
@@ -45,9 +43,10 @@ export default class UploadEntry {
|
|
|
45
43
|
this._isDone = false
|
|
46
44
|
this._progress = 0
|
|
47
45
|
this._lastProgressSent = -1
|
|
48
|
-
this._onDone = function
|
|
46
|
+
this._onDone = function(){ }
|
|
49
47
|
this._onElUpdated = this.onElUpdated.bind(this)
|
|
50
48
|
this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated)
|
|
49
|
+
this.autoUpload = autoUpload
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
metadata(){ return this.meta }
|
|
@@ -70,7 +69,10 @@ export default class UploadEntry {
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
|
|
72
|
+
isCancelled(){ return this._isCancelled }
|
|
73
|
+
|
|
73
74
|
cancel(){
|
|
75
|
+
this.file._preflightInProgress = false
|
|
74
76
|
this._isCancelled = true
|
|
75
77
|
this._isDone = true
|
|
76
78
|
this._onDone()
|
|
@@ -81,9 +83,11 @@ export default class UploadEntry {
|
|
|
81
83
|
error(reason = "failed"){
|
|
82
84
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated)
|
|
83
85
|
this.view.pushFileProgress(this.fileEl, this.ref, {error: reason})
|
|
84
|
-
if(!
|
|
86
|
+
if(!this.isAutoUpload()){ LiveUploader.clearFiles(this.fileEl) }
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
isAutoUpload(){ return this.autoUpload }
|
|
90
|
+
|
|
87
91
|
//private
|
|
88
92
|
|
|
89
93
|
onDone(callback){
|
|
@@ -95,7 +99,10 @@ export default class UploadEntry {
|
|
|
95
99
|
|
|
96
100
|
onElUpdated(){
|
|
97
101
|
let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",")
|
|
98
|
-
if(activeRefs.indexOf(this.ref) === -1){
|
|
102
|
+
if(activeRefs.indexOf(this.ref) === -1){
|
|
103
|
+
LiveUploader.untrackFile(this.fileEl, this.file)
|
|
104
|
+
this.cancel()
|
|
105
|
+
}
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
toPreflightPayload(){
|
|
@@ -120,6 +120,7 @@ export default class View {
|
|
|
120
120
|
this.childJoins = 0
|
|
121
121
|
this.loaderTimer = null
|
|
122
122
|
this.pendingDiffs = []
|
|
123
|
+
this.pendingForms = new Set()
|
|
123
124
|
this.redirect = false
|
|
124
125
|
this.href = null
|
|
125
126
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0
|
|
@@ -282,12 +283,16 @@ export default class View {
|
|
|
282
283
|
this.rendered = new Rendered(this.id, diff)
|
|
283
284
|
let [html, streams] = this.renderContainer(null, "join")
|
|
284
285
|
this.dropPendingRefs()
|
|
285
|
-
let forms = this.formsForRecovery(html)
|
|
286
|
+
let forms = this.formsForRecovery(html).filter(([form, newForm, newCid]) => {
|
|
287
|
+
return !this.pendingForms.has(form.id)
|
|
288
|
+
})
|
|
286
289
|
this.joinCount++
|
|
287
290
|
|
|
288
291
|
if(forms.length > 0){
|
|
289
292
|
forms.forEach(([form, newForm, newCid], i) => {
|
|
293
|
+
this.pendingForms.add(form.id)
|
|
290
294
|
this.pushFormRecovery(form, newCid, resp => {
|
|
295
|
+
this.pendingForms.delete(form.id)
|
|
291
296
|
if(i === forms.length - 1){
|
|
292
297
|
this.onJoinComplete(resp, html, streams, events)
|
|
293
298
|
}
|
|
@@ -307,6 +312,9 @@ export default class View {
|
|
|
307
312
|
}
|
|
308
313
|
|
|
309
314
|
onJoinComplete({live_patch}, html, streams, events){
|
|
315
|
+
// we can clear pending form recoveries now that we've joined.
|
|
316
|
+
// They either all resolved or were abandoned
|
|
317
|
+
this.pendingForms.clear()
|
|
310
318
|
// In order to provide a better experience, we want to join
|
|
311
319
|
// all LiveViews first and only then apply their patches.
|
|
312
320
|
if(this.joinCount > 1 || (this.parent && !this.parent.isJoinPending())){
|
|
@@ -1029,7 +1037,12 @@ export default class View {
|
|
|
1029
1037
|
} else if(LiveUploader.inputsAwaitingPreflight(formEl).length > 0){
|
|
1030
1038
|
let [ref, els] = refGenerator()
|
|
1031
1039
|
let proxyRefGen = () => [ref, els, opts]
|
|
1032
|
-
this.uploadFiles(formEl, targetCtx, ref, cid, (
|
|
1040
|
+
this.uploadFiles(formEl, targetCtx, ref, cid, (uploads) => {
|
|
1041
|
+
// if we still having pending preflights it means we have invalid entries
|
|
1042
|
+
// and the phx-submit cannot be completed
|
|
1043
|
+
if(LiveUploader.inputsAwaitingPreflight(formEl).length > 0){
|
|
1044
|
+
return this.undoRefs(ref)
|
|
1045
|
+
}
|
|
1033
1046
|
let meta = this.extractMeta(formEl)
|
|
1034
1047
|
let formData = serializeForm(formEl, {submitter, ...meta})
|
|
1035
1048
|
this.pushWithReply(proxyRefGen, "event", {
|
|
@@ -1065,7 +1078,7 @@ export default class View {
|
|
|
1065
1078
|
|
|
1066
1079
|
let entries = uploader.entries().map(entry => entry.toPreflightPayload())
|
|
1067
1080
|
|
|
1068
|
-
if
|
|
1081
|
+
if(entries.length === 0) {
|
|
1069
1082
|
numFileInputsInProgress--
|
|
1070
1083
|
return
|
|
1071
1084
|
}
|
|
@@ -1080,10 +1093,21 @@ export default class View {
|
|
|
1080
1093
|
|
|
1081
1094
|
this.pushWithReply(null, "allow_upload", payload, resp => {
|
|
1082
1095
|
this.log("upload", () => ["got preflight response", resp])
|
|
1083
|
-
|
|
1096
|
+
// the preflight will reject entries beyond the max entries
|
|
1097
|
+
// so we error and cancel entries on the client that are missing from the response
|
|
1098
|
+
uploader.entries().forEach(entry => {
|
|
1099
|
+
if(resp.entries && !resp.entries[entry.ref]){
|
|
1100
|
+
this.handleFailedEntryPreflight(entry.ref, "failed preflight", uploader)
|
|
1101
|
+
}
|
|
1102
|
+
})
|
|
1103
|
+
// for auto uploas, we may have an empty entries response from the server
|
|
1104
|
+
// for form submits that contain invalid entries
|
|
1105
|
+
if(resp.error || Object.keys(resp.entries).length === 0){
|
|
1084
1106
|
this.undoRefs(ref)
|
|
1085
|
-
let
|
|
1086
|
-
|
|
1107
|
+
let errors = resp.error || []
|
|
1108
|
+
errors.map(([entry_ref, reason]) => {
|
|
1109
|
+
this.handleFailedEntryPreflight(entry_ref, reason, uploader)
|
|
1110
|
+
})
|
|
1087
1111
|
} else {
|
|
1088
1112
|
let onError = (callback) => {
|
|
1089
1113
|
this.channel.onError(() => {
|
|
@@ -1096,6 +1120,17 @@ export default class View {
|
|
|
1096
1120
|
})
|
|
1097
1121
|
}
|
|
1098
1122
|
|
|
1123
|
+
handleFailedEntryPreflight(uploadRef, reason, uploader){
|
|
1124
|
+
if(uploader.isAutoUpload()){
|
|
1125
|
+
// uploadRef may be top level upload config ref or entry ref
|
|
1126
|
+
let entry = uploader.entries().find(entry => entry.ref === uploadRef.toString())
|
|
1127
|
+
if(entry){ entry.cancel() }
|
|
1128
|
+
} else {
|
|
1129
|
+
uploader.entries().map(entry => entry.cancel())
|
|
1130
|
+
}
|
|
1131
|
+
this.log("upload", () => [`error for entry ${uploadRef}`, reason])
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1099
1134
|
dispatchUploads(targetCtx, name, filesOrBlobs){
|
|
1100
1135
|
let targetElement = this.targetCtxElement(targetCtx) || this.el
|
|
1101
1136
|
let inputs = DOM.findUploadInputs(targetElement).filter(el => el.name === name)
|
package/assets/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1124,10 +1124,9 @@ var dom_default = DOM;
|
|
|
1124
1124
|
var UploadEntry = class {
|
|
1125
1125
|
static isActive(fileEl, file) {
|
|
1126
1126
|
let isNew = file._phxRef === void 0;
|
|
1127
|
-
let isPreflightInProgress = UploadEntry.isPreflightInProgress(file);
|
|
1128
1127
|
let activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
|
|
1129
1128
|
let isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
|
|
1130
|
-
return file.size > 0 && (isNew || isActive
|
|
1129
|
+
return file.size > 0 && (isNew || isActive);
|
|
1131
1130
|
}
|
|
1132
1131
|
static isPreflighted(fileEl, file) {
|
|
1133
1132
|
let preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");
|
|
@@ -1140,7 +1139,7 @@ var UploadEntry = class {
|
|
|
1140
1139
|
static markPreflightInProgress(file) {
|
|
1141
1140
|
file._preflightInProgress = true;
|
|
1142
1141
|
}
|
|
1143
|
-
constructor(fileEl, file, view) {
|
|
1142
|
+
constructor(fileEl, file, view, autoUpload) {
|
|
1144
1143
|
this.ref = LiveUploader.genFileRef(file);
|
|
1145
1144
|
this.fileEl = fileEl;
|
|
1146
1145
|
this.file = file;
|
|
@@ -1154,6 +1153,7 @@ var UploadEntry = class {
|
|
|
1154
1153
|
};
|
|
1155
1154
|
this._onElUpdated = this.onElUpdated.bind(this);
|
|
1156
1155
|
this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
1156
|
+
this.autoUpload = autoUpload;
|
|
1157
1157
|
}
|
|
1158
1158
|
metadata() {
|
|
1159
1159
|
return this.meta;
|
|
@@ -1175,7 +1175,11 @@ var UploadEntry = class {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
}
|
|
1177
1177
|
}
|
|
1178
|
+
isCancelled() {
|
|
1179
|
+
return this._isCancelled;
|
|
1180
|
+
}
|
|
1178
1181
|
cancel() {
|
|
1182
|
+
this.file._preflightInProgress = false;
|
|
1179
1183
|
this._isCancelled = true;
|
|
1180
1184
|
this._isDone = true;
|
|
1181
1185
|
this._onDone();
|
|
@@ -1186,10 +1190,13 @@ var UploadEntry = class {
|
|
|
1186
1190
|
error(reason = "failed") {
|
|
1187
1191
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
1188
1192
|
this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });
|
|
1189
|
-
if (!
|
|
1193
|
+
if (!this.isAutoUpload()) {
|
|
1190
1194
|
LiveUploader.clearFiles(this.fileEl);
|
|
1191
1195
|
}
|
|
1192
1196
|
}
|
|
1197
|
+
isAutoUpload() {
|
|
1198
|
+
return this.autoUpload;
|
|
1199
|
+
}
|
|
1193
1200
|
onDone(callback) {
|
|
1194
1201
|
this._onDone = () => {
|
|
1195
1202
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
@@ -1199,6 +1206,7 @@ var UploadEntry = class {
|
|
|
1199
1206
|
onElUpdated() {
|
|
1200
1207
|
let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
|
|
1201
1208
|
if (activeRefs.indexOf(this.ref) === -1) {
|
|
1209
|
+
LiveUploader.untrackFile(this.fileEl, this.file);
|
|
1202
1210
|
this.cancel();
|
|
1203
1211
|
}
|
|
1204
1212
|
}
|
|
@@ -1285,7 +1293,7 @@ var LiveUploader = class {
|
|
|
1285
1293
|
static trackFiles(inputEl, files, dataTransfer) {
|
|
1286
1294
|
if (inputEl.getAttribute("multiple") !== null) {
|
|
1287
1295
|
let newFiles = files.filter((file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file)));
|
|
1288
|
-
dom_default.
|
|
1296
|
+
dom_default.updatePrivate(inputEl, "files", [], (existing) => existing.concat(newFiles));
|
|
1289
1297
|
inputEl.value = null;
|
|
1290
1298
|
} else {
|
|
1291
1299
|
if (dataTransfer && dataTransfer.files.length > 0) {
|
|
@@ -1312,24 +1320,35 @@ var LiveUploader = class {
|
|
|
1312
1320
|
entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));
|
|
1313
1321
|
}
|
|
1314
1322
|
constructor(inputEl, view, onComplete) {
|
|
1323
|
+
this.autoUpload = dom_default.isAutoUpload(inputEl);
|
|
1315
1324
|
this.view = view;
|
|
1316
1325
|
this.onComplete = onComplete;
|
|
1317
|
-
this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view));
|
|
1326
|
+
this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));
|
|
1318
1327
|
LiveUploader.markPreflightInProgress(this._entries);
|
|
1319
1328
|
this.numEntriesInProgress = this._entries.length;
|
|
1320
1329
|
}
|
|
1330
|
+
isAutoUpload() {
|
|
1331
|
+
return this.autoUpload;
|
|
1332
|
+
}
|
|
1321
1333
|
entries() {
|
|
1322
1334
|
return this._entries;
|
|
1323
1335
|
}
|
|
1324
1336
|
initAdapterUpload(resp, onError, liveSocket) {
|
|
1325
1337
|
this._entries = this._entries.map((entry) => {
|
|
1326
|
-
entry.
|
|
1327
|
-
entry.onDone(() => {
|
|
1338
|
+
if (entry.isCancelled()) {
|
|
1328
1339
|
this.numEntriesInProgress--;
|
|
1329
1340
|
if (this.numEntriesInProgress === 0) {
|
|
1330
1341
|
this.onComplete();
|
|
1331
1342
|
}
|
|
1332
|
-
}
|
|
1343
|
+
} else {
|
|
1344
|
+
entry.zipPostFlight(resp);
|
|
1345
|
+
entry.onDone(() => {
|
|
1346
|
+
this.numEntriesInProgress--;
|
|
1347
|
+
if (this.numEntriesInProgress === 0) {
|
|
1348
|
+
this.onComplete();
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1333
1352
|
return entry;
|
|
1334
1353
|
});
|
|
1335
1354
|
let groupedEntries = this._entries.reduce((acc, entry) => {
|
|
@@ -2920,6 +2939,7 @@ var View = class {
|
|
|
2920
2939
|
this.childJoins = 0;
|
|
2921
2940
|
this.loaderTimer = null;
|
|
2922
2941
|
this.pendingDiffs = [];
|
|
2942
|
+
this.pendingForms = new Set();
|
|
2923
2943
|
this.redirect = false;
|
|
2924
2944
|
this.href = null;
|
|
2925
2945
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
|
|
@@ -3072,11 +3092,15 @@ var View = class {
|
|
|
3072
3092
|
this.rendered = new Rendered(this.id, diff);
|
|
3073
3093
|
let [html, streams] = this.renderContainer(null, "join");
|
|
3074
3094
|
this.dropPendingRefs();
|
|
3075
|
-
let forms = this.formsForRecovery(html)
|
|
3095
|
+
let forms = this.formsForRecovery(html).filter(([form, newForm, newCid]) => {
|
|
3096
|
+
return !this.pendingForms.has(form.id);
|
|
3097
|
+
});
|
|
3076
3098
|
this.joinCount++;
|
|
3077
3099
|
if (forms.length > 0) {
|
|
3078
3100
|
forms.forEach(([form, newForm, newCid], i) => {
|
|
3101
|
+
this.pendingForms.add(form.id);
|
|
3079
3102
|
this.pushFormRecovery(form, newCid, (resp2) => {
|
|
3103
|
+
this.pendingForms.delete(form.id);
|
|
3080
3104
|
if (i === forms.length - 1) {
|
|
3081
3105
|
this.onJoinComplete(resp2, html, streams, events);
|
|
3082
3106
|
}
|
|
@@ -3094,6 +3118,7 @@ var View = class {
|
|
|
3094
3118
|
});
|
|
3095
3119
|
}
|
|
3096
3120
|
onJoinComplete({ live_patch }, html, streams, events) {
|
|
3121
|
+
this.pendingForms.clear();
|
|
3097
3122
|
if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {
|
|
3098
3123
|
return this.applyJoinPatch(live_patch, html, streams, events);
|
|
3099
3124
|
}
|
|
@@ -3813,7 +3838,10 @@ var View = class {
|
|
|
3813
3838
|
} else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
3814
3839
|
let [ref, els] = refGenerator();
|
|
3815
3840
|
let proxyRefGen = () => [ref, els, opts];
|
|
3816
|
-
this.uploadFiles(formEl, targetCtx, ref, cid, (
|
|
3841
|
+
this.uploadFiles(formEl, targetCtx, ref, cid, (uploads) => {
|
|
3842
|
+
if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
3843
|
+
return this.undoRefs(ref);
|
|
3844
|
+
}
|
|
3817
3845
|
let meta = this.extractMeta(formEl);
|
|
3818
3846
|
let formData = serializeForm(formEl, { submitter, ...meta });
|
|
3819
3847
|
this.pushWithReply(proxyRefGen, "event", {
|
|
@@ -3858,10 +3886,17 @@ var View = class {
|
|
|
3858
3886
|
this.log("upload", () => ["sending preflight request", payload]);
|
|
3859
3887
|
this.pushWithReply(null, "allow_upload", payload, (resp) => {
|
|
3860
3888
|
this.log("upload", () => ["got preflight response", resp]);
|
|
3861
|
-
|
|
3889
|
+
uploader.entries().forEach((entry) => {
|
|
3890
|
+
if (resp.entries && !resp.entries[entry.ref]) {
|
|
3891
|
+
this.handleFailedEntryPreflight(entry.ref, "failed preflight", uploader);
|
|
3892
|
+
}
|
|
3893
|
+
});
|
|
3894
|
+
if (resp.error || Object.keys(resp.entries).length === 0) {
|
|
3862
3895
|
this.undoRefs(ref);
|
|
3863
|
-
let
|
|
3864
|
-
|
|
3896
|
+
let errors = resp.error || [];
|
|
3897
|
+
errors.map(([entry_ref, reason]) => {
|
|
3898
|
+
this.handleFailedEntryPreflight(entry_ref, reason, uploader);
|
|
3899
|
+
});
|
|
3865
3900
|
} else {
|
|
3866
3901
|
let onError = (callback) => {
|
|
3867
3902
|
this.channel.onError(() => {
|
|
@@ -3875,6 +3910,17 @@ var View = class {
|
|
|
3875
3910
|
});
|
|
3876
3911
|
});
|
|
3877
3912
|
}
|
|
3913
|
+
handleFailedEntryPreflight(uploadRef, reason, uploader) {
|
|
3914
|
+
if (uploader.isAutoUpload()) {
|
|
3915
|
+
let entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());
|
|
3916
|
+
if (entry) {
|
|
3917
|
+
entry.cancel();
|
|
3918
|
+
}
|
|
3919
|
+
} else {
|
|
3920
|
+
uploader.entries().map((entry) => entry.cancel());
|
|
3921
|
+
}
|
|
3922
|
+
this.log("upload", () => [`error for entry ${uploadRef}`, reason]);
|
|
3923
|
+
}
|
|
3878
3924
|
dispatchUploads(targetCtx, name, filesOrBlobs) {
|
|
3879
3925
|
let targetElement = this.targetCtxElement(targetCtx) || this.el;
|
|
3880
3926
|
let inputs = dom_default.findUploadInputs(targetElement).filter((el) => el.name === name);
|