blob: 392f48ae74b6b7bb00da35791a03692e1d5ffff5 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright (c) 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Paul Lewis9950e182019-12-16 16:06:074
Paul Lewis9950e182019-12-16 16:06:075import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
6
Blink Reformat4c46d092018-04-07 15:32:377/**
8 * @unrestricted
9 */
Paul Lewis9950e182019-12-16 16:06:0710export class DropTarget {
Blink Reformat4c46d092018-04-07 15:32:3711 /**
12 * @param {!Element} element
13 * @param {!Array<{kind: string, type: !RegExp}>} transferTypes
14 * @param {string} messageText
Tim van der Lippe403a88d2020-05-13 11:51:3215 * @param {function(!DataTransfer):*} handleDrop
Blink Reformat4c46d092018-04-07 15:32:3716 */
17 constructor(element, transferTypes, messageText, handleDrop) {
18 element.addEventListener('dragenter', this._onDragEnter.bind(this), true);
19 element.addEventListener('dragover', this._onDragOver.bind(this), true);
20 this._element = element;
21 this._transferTypes = transferTypes;
22 this._messageText = messageText;
23 this._handleDrop = handleDrop;
24 this._enabled = true;
Simon Zündf6760092020-08-13 06:19:2825 /** @type {?Element} */
26 this._dragMaskElement = null;
Blink Reformat4c46d092018-04-07 15:32:3727 }
28
29 /**
30 * @param {boolean} enabled
31 */
32 setEnabled(enabled) {
33 this._enabled = enabled;
34 }
35
36 /**
37 * @param {!Event} event
38 */
39 _onDragEnter(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3440 if (this._enabled && this._hasMatchingType(event)) {
Blink Reformat4c46d092018-04-07 15:32:3741 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:3442 }
Blink Reformat4c46d092018-04-07 15:32:3743 }
44
45 /**
Simon Zündf6760092020-08-13 06:19:2846 * @param {!Event} ev
Blink Reformat4c46d092018-04-07 15:32:3747 * @return {boolean}
48 */
Simon Zündf6760092020-08-13 06:19:2849 _hasMatchingType(ev) {
50 const event = /** @type {!DragEvent} */ (ev);
51 if (!event.dataTransfer) {
52 return false;
53 }
Blink Reformat4c46d092018-04-07 15:32:3754 for (const transferType of this._transferTypes) {
55 const found = Array.from(event.dataTransfer.items).find(item => {
56 return transferType.kind === item.kind && !!transferType.type.exec(item.type);
57 });
Tim van der Lippe1d6e57a2019-09-30 11:55:3458 if (found) {
Blink Reformat4c46d092018-04-07 15:32:3759 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:3460 }
Blink Reformat4c46d092018-04-07 15:32:3761 }
62 return false;
63 }
64
65 /**
Simon Zündf6760092020-08-13 06:19:2866 * @param {!Event} ev
Blink Reformat4c46d092018-04-07 15:32:3767 */
Simon Zündf6760092020-08-13 06:19:2868 _onDragOver(ev) {
69 const event = /** @type {!DragEvent} */ (ev);
Tim van der Lippe1d6e57a2019-09-30 11:55:3470 if (!this._enabled || !this._hasMatchingType(event)) {
Blink Reformat4c46d092018-04-07 15:32:3771 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3472 }
Simon Zündf6760092020-08-13 06:19:2873 if (event.dataTransfer) {
74 event.dataTransfer.dropEffect = 'copy';
75 }
Blink Reformat4c46d092018-04-07 15:32:3776 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:3477 if (this._dragMaskElement) {
Blink Reformat4c46d092018-04-07 15:32:3778 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3479 }
Blink Reformat4c46d092018-04-07 15:32:3780 this._dragMaskElement = this._element.createChild('div', '');
Paul Lewis9950e182019-12-16 16:06:0781 const shadowRoot = createShadowRootWithCoreStyles(this._dragMaskElement, 'ui/dropTarget.css');
Blink Reformat4c46d092018-04-07 15:32:3782 shadowRoot.createChild('div', 'drop-target-message').textContent = this._messageText;
83 this._dragMaskElement.addEventListener('drop', this._onDrop.bind(this), true);
84 this._dragMaskElement.addEventListener('dragleave', this._onDragLeave.bind(this), true);
85 }
86
87 /**
Simon Zündf6760092020-08-13 06:19:2888 * @param {!Event} ev
Blink Reformat4c46d092018-04-07 15:32:3789 */
Simon Zündf6760092020-08-13 06:19:2890 _onDrop(ev) {
91 const event = /** @type {!DragEvent} */ (ev);
Blink Reformat4c46d092018-04-07 15:32:3792 event.consume(true);
93 this._removeMask();
Simon Zündf6760092020-08-13 06:19:2894 if (this._enabled && event.dataTransfer) {
Blink Reformat4c46d092018-04-07 15:32:3795 this._handleDrop(event.dataTransfer);
Tim van der Lippe1d6e57a2019-09-30 11:55:3496 }
Blink Reformat4c46d092018-04-07 15:32:3797 }
98
99 /**
100 * @param {!Event} event
101 */
102 _onDragLeave(event) {
103 event.consume(true);
104 this._removeMask();
105 }
106
107 _removeMask() {
Simon Zündf6760092020-08-13 06:19:28108 if (this._dragMaskElement) {
109 this._dragMaskElement.remove();
110 this._dragMaskElement = null;
111 }
Blink Reformat4c46d092018-04-07 15:32:37112 }
Tim van der Lippe0830b3d2019-10-03 13:20:07113}
Blink Reformat4c46d092018-04-07 15:32:37114
Tim van der Lippe0830b3d2019-10-03 13:20:07115export const Type = {
Blink Reformat4c46d092018-04-07 15:32:37116 URI: {kind: 'string', type: /text\/uri-list/},
117 Folder: {kind: 'file', type: /$^/},
118 File: {kind: 'file', type: /.*/},
119 WebFile: {kind: 'file', type: /[\w]+/},
120 ImageFile: {kind: 'file', type: /image\/.*/},
121};