Adds support for onpaste #97 (#98)

* Adds support for onpaste #97

+ file-drop listens for onpaste, if there is data and it matches the
   type it will use that and raise a custom event
+ Adds a new event on file drop 'onfiledrop'
+ App listens for this event and will map to onFileDrop

* Hoisting getFileData

* The linter seems to think Array.from is of type File, when it's not.

* Remove an entire type of event handler.
+ Removes onfilepaste, joins into 'onfiledrop'
+ Adds 'action' to let you distinguish between the paste or drop
+ Updates app so it just uses the one event.

* Fixing PR issues

+ null return types >>> undefiend.
+ FileDropAction type.
+ remove coercsion on the array types.
This commit is contained in:
Paul Kinlan
2018-07-16 14:00:47 +01:00
committed by GitHub
parent acbc31bc35
commit 526520c399
3 changed files with 13741 additions and 12 deletions

13705
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -17,9 +17,9 @@
} }
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^9.4.7", "@types/node": "^9.6.23",
"@types/webassembly-js-api": "0.0.1", "@types/webassembly-js-api": "0.0.1",
"babel-loader": "^7.1.4", "babel-loader": "^7.1.5",
"babel-plugin-jsx-pragmatic": "^1.0.2", "babel-plugin-jsx-pragmatic": "^1.0.2",
"babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
@@ -36,11 +36,11 @@
"exports-loader": "^0.7.0", "exports-loader": "^0.7.0",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"html-webpack-plugin": "^3.0.6", "html-webpack-plugin": "^3.0.6",
"husky": "^1.0.0-rc.9", "husky": "^1.0.0-rc.13",
"if-env": "^1.0.4", "if-env": "^1.0.4",
"loader-utils": "^1.1.0", "loader-utils": "^1.1.0",
"mini-css-extract-plugin": "^0.3.0", "mini-css-extract-plugin": "^0.3.0",
"node-sass": "^4.7.2", "node-sass": "^4.9.2",
"optimize-css-assets-webpack-plugin": "^4.0.0", "optimize-css-assets-webpack-plugin": "^4.0.0",
"progress-bar-webpack-plugin": "^1.11.0", "progress-bar-webpack-plugin": "^1.11.0",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
@@ -55,7 +55,7 @@
"tslint-react": "^3.5.1", "tslint-react": "^3.5.1",
"typescript": "^2.7.2", "typescript": "^2.7.2",
"typings-for-css-modules-loader": "^1.7.0", "typings-for-css-modules-loader": "^1.7.0",
"webpack": "^4.3.0", "webpack": "^4.15.1",
"webpack-bundle-analyzer": "^2.11.1", "webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.13", "webpack-cli": "^2.0.13",
"webpack-dev-server": "^3.1.1", "webpack-dev-server": "^3.1.1",
@@ -70,7 +70,7 @@
"material-components-web": "^0.32.0", "material-components-web": "^0.32.0",
"preact": "^8.2.7", "preact": "^8.2.7",
"preact-i18n": "^1.2.0", "preact-i18n": "^1.2.0",
"preact-material-components": "^1.3.7", "preact-material-components": "^1.4.7",
"preact-router": "^2.6.0" "preact-router": "^2.6.0"
} }
} }

View File

@@ -24,10 +24,20 @@ function firstMatchingItem(list: DataTransferItemList, acceptVal: string): DataT
}); });
} }
function getFileData(data: DataTransfer, accept: string): File | undefined {
const dragDataItem = firstMatchingItem(data.items, accept);
if (!dragDataItem) return;
return dragDataItem.getAsFile() || undefined;
}
interface FileDropEventInit extends EventInit { interface FileDropEventInit extends EventInit {
action: FileDropAccept;
file: File; file: File;
} }
type FileDropAccept = 'drop' | 'paste';
// Safari and Edge don't quite support extending Event, this works around it. // Safari and Edge don't quite support extending Event, this works around it.
function fixExtendedEvent(instance: Event, type: Function) { function fixExtendedEvent(instance: Event, type: Function) {
if (!(instance instanceof type)) { if (!(instance instanceof type)) {
@@ -36,14 +46,20 @@ function fixExtendedEvent(instance: Event, type: Function) {
} }
export class FileDropEvent extends Event { export class FileDropEvent extends Event {
private _action: FileDropAccept;
private _file: File; private _file: File;
constructor(typeArg: string, eventInitDict: FileDropEventInit) { constructor(typeArg: string, eventInitDict: FileDropEventInit) {
super(typeArg, eventInitDict); super(typeArg, eventInitDict);
fixExtendedEvent(this, FileDropEvent); fixExtendedEvent(this, FileDropEvent);
this._file = eventInitDict.file; this._file = eventInitDict.file;
this._action = eventInitDict.action;
} }
get file(): File { get action() {
return this._action;
}
get file() {
return this._file; return this._file;
} }
} }
@@ -70,6 +86,7 @@ export class FileDrop extends HTMLElement {
this.addEventListener('dragenter', this._onDragEnter); this.addEventListener('dragenter', this._onDragEnter);
this.addEventListener('dragend', () => this._reset()); this.addEventListener('dragend', () => this._reset());
this.addEventListener('dragleave', this._onDragLeave); this.addEventListener('dragleave', this._onDragLeave);
this.addEventListener('paste', this._onPaste);
} }
get accept() { get accept() {
@@ -110,13 +127,20 @@ export class FileDrop extends HTMLElement {
private _onDrop(event: DragEvent) { private _onDrop(event: DragEvent) {
event.preventDefault(); event.preventDefault();
this._reset(); this._reset();
const dragDataItem = firstMatchingItem(event.dataTransfer.items, this.accept); const action = 'drop';
if (!dragDataItem) return; const file = getFileData(event.dataTransfer, this.accept);
if (file === undefined) return;
const file = dragDataItem.getAsFile(); this.dispatchEvent(new FileDropEvent('filedrop', { action, file }));
if (file === null) return; }
this.dispatchEvent(new FileDropEvent('filedrop', { file })); @bind
private _onPaste(event: ClipboardEvent) {
const action = 'paste';
const file = getFileData(event.clipboardData, this.accept);
if (file === undefined) return;
this.dispatchEvent(new FileDropEvent('filedrop', { action, file }));
} }
private _reset() { private _reset() {