/*\ title: $:/core/modules/widgets/dropzone.js type: application/javascript module-type: widget Dropzone widget \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; var Widget = require("$:/core/modules/widgets/widget.js").widget; var DropZoneWidget = function(parseTreeNode,options) { this.initialise(parseTreeNode,options); }; /* Inherit from the base widget class */ DropZoneWidget.prototype = new Widget(); /* Render this widget into the DOM */ DropZoneWidget.prototype.render = function(parent,nextSibling) { var self = this; // Remember parent this.parentDomNode = parent; // Compute attributes and execute state this.computeAttributes(); this.execute(); // Create element var domNode = this.document.createElement("div"); domNode.className = "tc-dropzone"; // Add event handlers $tw.utils.addEventListeners(domNode,[ {name: "dragenter", handlerObject: this, handlerMethod: "handleDragEnterEvent"}, {name: "dragover", handlerObject: this, handlerMethod: "handleDragOverEvent"}, {name: "dragleave", handlerObject: this, handlerMethod: "handleDragLeaveEvent"}, {name: "drop", handlerObject: this, handlerMethod: "handleDropEvent"}, {name: "paste", handlerObject: this, handlerMethod: "handlePasteEvent"} ]); domNode.addEventListener("click",function (event) { },false); // Insert element parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); this.domNodes.push(domNode); }; DropZoneWidget.prototype.enterDrag = function() { // Check for this window being the source of the drag if($tw.dragInProgress) { return false; } // We count enter/leave events this.dragEnterCount = (this.dragEnterCount || 0) + 1; // If we're entering for the first time we need to apply highlighting if(this.dragEnterCount === 1) { $tw.utils.addClass(this.domNodes[0],"tc-dragover"); } }; DropZoneWidget.prototype.leaveDrag = function() { // Reduce the enter count this.dragEnterCount = (this.dragEnterCount || 0) - 1; // Remove highlighting if we're leaving externally if(this.dragEnterCount <= 0) { $tw.utils.removeClass(this.domNodes[0],"tc-dragover"); } }; DropZoneWidget.prototype.handleDragEnterEvent = function(event) { this.enterDrag(); // Tell the browser that we're ready to handle the drop event.preventDefault(); // Tell the browser not to ripple the drag up to any parent drop handlers event.stopPropagation(); }; DropZoneWidget.prototype.handleDragOverEvent = function(event) { // Check for being over a TEXTAREA or INPUT if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) !== -1) { return false; } // Check for this window being the source of the drag if($tw.dragInProgress) { return false; } // Tell the browser that we're still interested in the drop event.preventDefault(); event.dataTransfer.dropEffect = "copy"; // Explicitly show this is a copy }; DropZoneWidget.prototype.handleDragLeaveEvent = function(event) { this.leaveDrag(); }; DropZoneWidget.prototype.handleDropEvent = function(event) { this.leaveDrag(); // Check for being over a TEXTAREA or INPUT if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) !== -1) { return false; } // Check for this window being the source of the drag if($tw.dragInProgress) { return false; } var self = this, dataTransfer = event.dataTransfer; // Reset the enter count this.dragEnterCount = 0; // Remove highlighting $tw.utils.removeClass(this.domNodes[0],"tc-dragover"); // Import any files in the drop var numFiles = this.wiki.readFiles(dataTransfer.files,function(tiddlerFieldsArray) { self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)}); }); // Try to import the various data types we understand if(numFiles === 0) { this.importData(dataTransfer); } // Tell the browser that we handled the drop event.preventDefault(); // Stop the drop ripple up to any parent handlers event.stopPropagation(); }; DropZoneWidget.prototype.importData = function(dataTransfer) { // Try each provided data type in turn for(var t=0; t