/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/* eslint-env browser */
/*global niagara*/
/**
* @module bajaux/container/wb/Clipboard
*/
define([
"baja!",
"Promise",
"bajaux/container/wb/StringList" ], function (
baja,
Promise,
StringList) {
"use strict";
/**
* A fake Clipboard that uses BajaScript to support drag and drop in Workbench.
*
* @class
* @alias module:bajaux/container/wb/Clipboard
*/
var Clipboard = function Clipboard() {
var that = this;
that.$data = {};
/**
* The current drop effect being used by the clipboard.
* @type {String}
*/
that.dropEffect = "none";
/**
* The current effect allowed.
* @type {String}
*/
that.effectAllowed = "all";
/**
* A list of the files being dragged (always empty).
* @see http://dev.w3.org/2006/webapi/FileAPI/#dfn-filelist
*/
that.files = {
length: 0,
item: function () {}
};
/**
* The drag data.
* @type {StringList}
*/
that.items = new StringList();
};
/**
* Return data from the clipboard for the specified format.
*
* @param {String} mimeType The format of the data to return.
* @returns the request data (or undefined if nothing can be found).
*/
Clipboard.prototype.getData = function (mimeType) {
return this.$data[mimeType];
};
/**
* Adds the specified data to the clipboard.
*
* @param {String} mimeType The format of the data being added.
* @param data The data to be added to the clipboard.
* @see http://www.w3.org/TR/html5/editing.html#dom-datatransfer-setdata
*/
Clipboard.prototype.setData = function (mimeType, data) {
this.$data[mimeType] = data;
this.items.add(mimeType);
};
/**
* Clear the data from the clipboard for the specified format.
* @param {String} mimeType The format of the data being cleared.
*/
Clipboard.prototype.clearData = function (mimeType) {
if (mimeType && this.$data.hasOwnProperty(mimeType)) {
delete this.$data[mimeType];
this.items.remove(mimeType);
}
};
/**
* Sets a drag image (currently is a no-op).
*/
Clipboard.prototype.setDragImage = function () {};
function makeEvent(eventName, x, y, navNodes) {
// Create event
var event = document.createEvent("HTMLEvents");
event.initEvent(eventName, /*bubbles*/true, /*cancelable*/true);
// Add drag and drop data.
event.clientX = x;
event.clientY = y;
event.screenX = window.screenX + x;
event.screenY = window.screenY + y;
event.dataTransfer = new Clipboard();
// Set the data to transfer
event.dataTransfer.setData("Text", JSON.stringify({
mime: "niagara/navnodes",
data: navNodes
}));
return event;
}
function fireEvent(eventName, x, y, navNodesStr) {
var element = document.elementFromPoint(x, y),
event,
navNodes,
typeSpecs,
dragCallback = typeof niagara !== 'undefined' &&
niagara.wb &&
niagara.wb.util &&
niagara.wb.util.dragCallback;
/**
* @param {boolean} eventWasProcessed true if event processed, false if cancelled
* @returns {Promise.<boolean>}
*/
function ok(eventWasProcessed) {
if (dragCallback) {
dragCallback(eventWasProcessed);
}
return Promise.resolve(eventWasProcessed);
}
// Bail if we can't find an element to drag and drop onto
if (!element) {
return ok(/*eventWasProcessed*/true);
}
// Decode the Nav Node JSON
navNodes = JSON.parse(navNodesStr);
event = makeEvent(eventName, x, y, navNodes);
// Make sure all the Types the NavNodes are referring too are imported.
typeSpecs = navNodes.map(function (navNode) { return navNode.typeSpec; });
// Require the Types and then make the dispatch
return baja.importTypes({ typeSpecs })
.then(() => {
// Dispatch the event to the DOM element and return
// the result of whether it was cancelled or not.
return ok(element.dispatchEvent(event));
})
.catch((err) => {
if (dragCallback) {
dragCallback(true);
}
throw err;
});
}
/**
* The drag over function to be exported for Workbench to use.
*
* @param {Number} x The x co-ordinate of the drag.
* @param {Number} y The y co-ordinate of the drag.
* @param {String} navNodesStr The Nav Node JSON encoded in a String.
* @returns {Promise} A promise that's resolved once the drag operation has completed.
*/
Clipboard.dragover = function dragover(x, y, navNodesStr) {
return fireEvent("dragover", x, y, navNodesStr);
};
/**
* The drop function to be exported for Workbench to use.
*
* @param {Number} x The x co-ordinate of the drop.
* @param {Number} y The y co-ordinate of the drop.
* @param {String} navNodesStr The Nav Node JSON encoded in a String.
* @returns {Promise} A promise that's resolved once the drag operation has completed.
*/
Clipboard.drop = function drop(x, y, navNodesStr) {
return fireEvent("drop", x, y, navNodesStr);
};
return Clipboard;
});