Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/destroy-instances.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"dropzone": patch
---

Stop `destroy()` removing a different instance. `Dropzone.instances.splice(indexOf(this), 1)` dropped the last entry whenever `indexOf` returned -1 — calling `destroy()` twice was enough — evicting an unrelated live Dropzone from the registry.
5 changes: 5 additions & 0 deletions .changeset/form-enctype.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"dropzone": patch
---

Set `enctype="multipart/form-data"` on a form again. `init()` compared `tagName` against lower-case `"form"`, which never matches, so the attribute was never set. Only affects forms that are also submitted natively; the XHR upload is unchanged.
11 changes: 8 additions & 3 deletions packages/dropzone/src/dropzone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,9 @@ export default class Dropzone extends Emitter {
// The function that gets called when Dropzone is initialized. You
// can (and should) setup event listeners inside this function.
init() {
// In case it isn't set already
if (this.element.tagName === "form") {
// In case it isn't set already. `tagName` is upper case on HTML elements,
// so this never matched and the attribute was never set.
if (this.element.tagName === "FORM") {
this.element.setAttribute("enctype", "multipart/form-data");
}

Expand Down Expand Up @@ -547,7 +548,11 @@ export default class Dropzone extends Emitter {
this.hiddenFileInput = null;
}
delete this.element.dropzone;
return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
// `indexOf` returns -1 for an instance that is no longer registered --
// destroying twice is enough -- and `splice(-1, 1)` would then quietly
// drop the last entry, which is a different, live Dropzone.
let index = Dropzone.instances.indexOf(this);
return index === -1 ? [] : Dropzone.instances.splice(index, 1);
}

updateTotalUploadProgress() {
Expand Down
30 changes: 30 additions & 0 deletions packages/dropzone/test/unit-tests/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,24 @@ describe("Dropzone", function () {
}, 10);
})));

describe("init()", function () {
it("should set the enctype on a form element", function () {
let form = Dropzone.createElement("<form></form>");
let formDropzone = new Dropzone(form, { url: "url" });

expect(form.getAttribute("enctype")).toBe("multipart/form-data");
formDropzone.destroy();
});

it("should leave an existing enctype alone on a non-form element", function () {
let div = Dropzone.createElement("<div></div>");
let divDropzone = new Dropzone(div, { url: "url" });

expect(div.getAttribute("enctype")).toBe(null);
divDropzone.destroy();
});
});

describe(".destroy()", function () {
it("should properly cancel all pending uploads and remove all file references", () =>
new Promise((done) => {
Expand Down Expand Up @@ -807,6 +825,18 @@ describe("Dropzone", function () {
dropzone.destroy();
return expect(Dropzone.instances.indexOf(dropzone) === -1).toBeTruthy();
});

it("should leave other instances alone when destroyed twice", function () {
let other = new Dropzone(Dropzone.createElement("<div></div>"), { url: "url" });

dropzone.destroy();
// The second call finds nothing to remove. `splice(-1, 1)` used to
// take the last entry regardless, evicting an unrelated live instance.
dropzone.destroy();

expect(Dropzone.instances.indexOf(other) !== -1).toBeTruthy();
other.destroy();
});
});

describe(".filesize()", function () {
Expand Down
Loading