Skip to content

Commit f89a93b

Browse files
Tal500zwergius
authored andcommitted
safer binding to windows events, and fix issues on SSR.
Additionally, fix a potential issue with timout being invoked after destroying. fixes thecodejack#47
1 parent 7f81b7e commit f89a93b

File tree

2 files changed

+54
-63
lines changed

2 files changed

+54
-63
lines changed

src/components/Dropzone.svelte

Lines changed: 54 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
isEvtWithFiles,
99
isIeOrEdge,
1010
isPropagationStopped,
11-
onDocumentDragOver,
12-
TOO_MANY_FILES_REJECTION,
11+
TOO_MANY_FILES_REJECTION
1312
} from "./../utils/index";
1413
import { onMount, onDestroy, createEventDispatcher } from "svelte";
1514
@@ -47,7 +46,7 @@
4746
isDragReject: false,
4847
draggedFiles: [],
4948
acceptedFiles: [],
50-
fileRejections: [],
49+
fileRejections: []
5150
};
5251
5352
let rootRef;
@@ -113,7 +112,7 @@
113112
dragTargetsRef = [...dragTargetsRef, event.target];
114113
115114
if (isEvtWithFiles(event)) {
116-
Promise.resolve(getFilesFromEvent(event)).then((draggedFiles) => {
115+
Promise.resolve(getFilesFromEvent(event)).then(draggedFiles => {
117116
if (isPropagationStopped(event) && !noDragEventsBubbling) {
118117
return;
119118
}
@@ -122,7 +121,7 @@
122121
state.isDragActive = true;
123122
124123
dispatch("dragenter", {
125-
dragEvent: event,
124+
dragEvent: event
126125
});
127126
});
128127
}
@@ -140,7 +139,7 @@
140139
141140
if (isEvtWithFiles(event)) {
142141
dispatch("dragover", {
143-
dragEvent: event,
142+
dragEvent: event
144143
});
145144
}
146145
@@ -153,7 +152,7 @@
153152
154153
// Only deactivate once the dropzone and all children have been left
155154
const targets = dragTargetsRef.filter(
156-
(target) => rootRef && rootRef.contains(target)
155+
target => rootRef && rootRef.contains(target)
157156
);
158157
// Make sure to remove a target present multiple times only once
159158
// (Firefox may fire dragenter/dragleave multiple times on the same element)
@@ -171,7 +170,7 @@
171170
172171
if (isEvtWithFiles(event)) {
173172
dispatch("dragleave", {
174-
dragEvent: event,
173+
dragEvent: event
175174
});
176175
}
177176
}
@@ -184,30 +183,30 @@
184183
185184
if (isEvtWithFiles(event)) {
186185
dispatch("filedropped", {
187-
event,
188-
});
189-
Promise.resolve(getFilesFromEvent(event)).then((files) => {
186+
event
187+
})
188+
Promise.resolve(getFilesFromEvent(event)).then(files => {
190189
if (isPropagationStopped(event) && !noDragEventsBubbling) {
191190
return;
192191
}
193192
194193
const acceptedFiles = [];
195194
const fileRejections = [];
196195
197-
files.forEach((file) => {
196+
files.forEach(file => {
198197
const [accepted, acceptError] = fileAccepted(file, accept);
199198
const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
200199
if (accepted && sizeMatch) {
201200
acceptedFiles.push(file);
202201
} else {
203-
const errors = [acceptError, sizeError].filter((e) => e);
202+
const errors = [acceptError, sizeError].filter(e => e);
204203
fileRejections.push({ file, errors });
205204
}
206205
});
207206
208207
if (!multiple && acceptedFiles.length > 1) {
209208
// Reject everything and empty accepted files
210-
acceptedFiles.forEach((file) => {
209+
acceptedFiles.forEach(file => {
211210
fileRejections.push({ file, errors: [TOO_MANY_FILES_REJECTION] });
212211
});
213212
acceptedFiles.splice(0);
@@ -224,20 +223,20 @@
224223
dispatch("drop", {
225224
acceptedFiles,
226225
fileRejections,
227-
event,
226+
event
228227
});
229228
230229
if (fileRejections.length > 0) {
231230
dispatch("droprejected", {
232231
fileRejections,
233-
event,
232+
event
234233
});
235234
}
236235
237236
if (acceptedFiles.length > 0) {
238237
dispatch("dropaccepted", {
239238
acceptedFiles,
240-
event,
239+
event
241240
});
242241
}
243242
});
@@ -263,8 +262,18 @@
263262
}
264263
}
265264
265+
// allow the entire document to be a drag target
266+
function onDocumentDragOver(event) {
267+
if (preventDropOnDocument) {
268+
event.preventDefault();
269+
}
270+
}
271+
266272
let dragTargetsRef = [];
267273
function onDocumentDrop(event) {
274+
if (!preventDropOnDocument) {
275+
return;
276+
}
268277
if (rootRef && rootRef.contains(event.target)) {
269278
// If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
270279
return;
@@ -290,27 +299,39 @@
290299
}
291300
}
292301
293-
onMount(() => {
294-
window.addEventListener("focus", onWindowFocus, false);
295-
if (preventDropOnDocument) {
296-
document.addEventListener("dragover", onDocumentDragOver, false);
297-
document.addEventListener("drop", onDocumentDrop, false);
298-
}
299-
});
300-
301302
onDestroy(() => {
302-
window.removeEventListener("focus", onWindowFocus, false);
303-
if (preventDropOnDocument) {
304-
document.removeEventListener("dragover", onDocumentDragOver);
305-
document.removeEventListener("drop", onDocumentDrop);
306-
}
303+
// This is critical for canceling the timeout behaviour on `onWindowFocus()`
304+
inputRef = null;
307305
});
308306
309307
function onInputElementClick(event) {
310308
event.stopPropagation();
311309
}
312310
</script>
313311
312+
<style>
313+
.dropzone {
314+
flex: 1;
315+
display: flex;
316+
flex-direction: column;
317+
align-items: center;
318+
padding: 20px;
319+
border-width: 2px;
320+
border-radius: 2px;
321+
border-color: #eeeeee;
322+
border-style: dashed;
323+
background-color: #fafafa;
324+
color: #bdbdbd;
325+
outline: none;
326+
transition: border 0.24s ease-in-out;
327+
}
328+
.dropzone:focus {
329+
border-color: #2196f3;
330+
}
331+
</style>
332+
333+
<svelte:window on:focus={onWindowFocus} on:dragover={onDocumentDragOver} on:drop={onDocumentDrop} />
334+
314335
<div
315336
bind:this={rootRef}
316337
tabindex="0"
@@ -324,45 +345,20 @@
324345
on:dragenter={composeDragHandler(onDragEnterCb)}
325346
on:dragover={composeDragHandler(onDragOverCb)}
326347
on:dragleave={composeDragHandler(onDragLeaveCb)}
327-
on:drop={composeDragHandler(onDropCb)}
328-
>
348+
on:drop={composeDragHandler(onDropCb)}>
329349
<input
330350
{accept}
331351
{multiple}
332352
{required}
333353
type="file"
334-
{name}
354+
name={name}
335355
autocomplete="off"
336356
tabindex="-1"
337-
on:blur
338357
on:change={onDropCb}
339358
on:click={onInputElementClick}
340-
on:invalid
341359
bind:this={inputRef}
342-
style="display: none;"
343-
/>
360+
style="display: none;" />
344361
<slot>
345362
<p>Drag 'n' drop some files here, or click to select files</p>
346363
</slot>
347364
</div>
348-
349-
<style>
350-
.dropzone {
351-
flex: 1;
352-
display: flex;
353-
flex-direction: column;
354-
align-items: center;
355-
padding: 20px;
356-
border-width: 2px;
357-
border-radius: 2px;
358-
border-color: #eeeeee;
359-
border-style: dashed;
360-
background-color: #fafafa;
361-
color: #bdbdbd;
362-
outline: none;
363-
transition: border 0.24s ease-in-out;
364-
}
365-
.dropzone:focus {
366-
border-color: #2196f3;
367-
}
368-
</style>

src/utils/index.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ export function isKindFile(item) {
111111
return typeof item === "object" && item !== null && item.kind === "file";
112112
}
113113

114-
// allow the entire document to be a drag target
115-
export function onDocumentDragOver(event) {
116-
event.preventDefault();
117-
}
118-
119114
function isIe(userAgent) {
120115
return (
121116
userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1

0 commit comments

Comments
 (0)