mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-09-17 23:31:22 +00:00
Refactor draggable stuff for easier reuse
And in the process, make the button widget draggable. Unfortunately, Firefox has a bug that prevents buttons from being dragged (see https://bugzilla.mozilla.org/show_bug.cgi?id=568313 and https://bugzilla.mozilla.org/show_bug.cgi?id=646823). So we have to use the “tag” attribute to make it use a different element.
This commit is contained in:
@@ -1,82 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/dom/datatransfer.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Browser data transfer utilities, used with the clipboard and drag and drop
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {
|
||||
// Try each provided data type in turn
|
||||
for(var t=0; t<importDataTypes.length; t++) {
|
||||
if(!$tw.browser.isIE || importDataTypes[t].IECompatible) {
|
||||
// Get the data
|
||||
var dataType = importDataTypes[t];
|
||||
var data = dataTransfer.getData(dataType.type);
|
||||
// Import the tiddlers in the data
|
||||
if(data !== "" && data !== null) {
|
||||
if($tw.log.IMPORT) {
|
||||
console.log("Importing data type '" + dataType.type + "', data: '" + data + "'")
|
||||
}
|
||||
var tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);
|
||||
callback(tiddlerFields);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var importDataTypes = [
|
||||
{type: "text/vnd.tiddler", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return parseJSONTiddlers(data,fallbackTitle);
|
||||
}},
|
||||
{type: "URL", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
return [{text: data}]; // As URL string
|
||||
}
|
||||
}},
|
||||
{type: "text/x-moz-url", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
return [{text: data}]; // As URL string
|
||||
}
|
||||
}},
|
||||
{type: "text/html", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "text/plain", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "Text", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "text/uri-list", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}}
|
||||
];
|
||||
|
||||
function parseJSONTiddlers(json,fallbackTitle) {
|
||||
var data = JSON.parse(json);
|
||||
if(!$tw.utils.isArray(data)) {
|
||||
data = [data];
|
||||
}
|
||||
data.forEach(function(fields) {
|
||||
fields.title = fields.title || fallbackTitle;
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,172 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/dom/dragndrop.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Browser data transfer utilities, used with the clipboard and drag and drop
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Options:
|
||||
|
||||
domNode: dom node to make draggable
|
||||
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
|
||||
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
|
||||
widget: widget to use as the contect for the filter
|
||||
*/
|
||||
exports.makeDraggable = function(options) {
|
||||
var dragImage,
|
||||
domNode = options.domNode;
|
||||
// Make the dom node draggable
|
||||
domNode.setAttribute("draggable","true");
|
||||
// Add event handlers
|
||||
$tw.utils.addEventListeners(domNode,[
|
||||
{name: "dragstart", handlerFunction: function(event) {
|
||||
// Collect the tiddlers being dragged
|
||||
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
|
||||
dragFilter = options.dragFilterFn && options.dragFilterFn(),
|
||||
titles = dragTiddler ? [dragTiddler] : [];
|
||||
if(dragFilter) {
|
||||
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
|
||||
}
|
||||
var titleString = $tw.utils.stringifyList(titles);
|
||||
// Check that we've something to drag
|
||||
if(titles.length > 0 && event.target === domNode) {
|
||||
// Mark the drag in progress
|
||||
$tw.dragInProgress = domNode;
|
||||
// Set the dragging class on the element being dragged
|
||||
$tw.utils.addClass(event.target,"tc-dragging");
|
||||
// Create the drag image elements
|
||||
dragImage = options.widget.document.createElement("div");
|
||||
dragImage.className = "tc-tiddler-dragger";
|
||||
var inner = options.widget.document.createElement("div");
|
||||
inner.className = "tc-tiddler-dragger-inner";
|
||||
inner.appendChild(options.widget.document.createTextNode(
|
||||
titles.length === 1 ?
|
||||
titles[0] :
|
||||
titles.length + " tiddlers"
|
||||
));
|
||||
dragImage.appendChild(inner);
|
||||
options.widget.document.body.appendChild(dragImage);
|
||||
// Set the data transfer properties
|
||||
var dataTransfer = event.dataTransfer;
|
||||
// Set up the image
|
||||
dataTransfer.effectAllowed = "copy";
|
||||
if(dataTransfer.setDragImage) {
|
||||
dataTransfer.setDragImage(dragImage.firstChild,-16,-16);
|
||||
}
|
||||
// Set up the data transfer
|
||||
dataTransfer.clearData();
|
||||
var jsonData = [];
|
||||
if(titles.length > 1) {
|
||||
titles.forEach(function(title) {
|
||||
jsonData.push(options.widget.wiki.getTiddlerAsJson(title));
|
||||
});
|
||||
jsonData = "[" + jsonData.join(",") + "]";
|
||||
} else {
|
||||
jsonData = options.widget.wiki.getTiddlerAsJson(titles[0]);
|
||||
}
|
||||
// IE doesn't like these content types
|
||||
if(!$tw.browser.isIE) {
|
||||
dataTransfer.setData("text/vnd.tiddler",jsonData);
|
||||
dataTransfer.setData("text/plain",titleString);
|
||||
dataTransfer.setData("text/x-moz-url","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
|
||||
}
|
||||
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
|
||||
dataTransfer.setData("Text",titleString);
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
event.preventDefault();
|
||||
}
|
||||
return false;
|
||||
}},
|
||||
{name: "dragend", handlerFunction: function(event) {
|
||||
if(event.target === domNode) {
|
||||
$tw.dragInProgress = null;
|
||||
// Remove the dragging class on the element being dragged
|
||||
$tw.utils.removeClass(event.target,"tc-dragging");
|
||||
// Delete the drag image element
|
||||
if(dragImage) {
|
||||
dragImage.parentNode.removeChild(dragImage);
|
||||
dragImage = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
]);
|
||||
};
|
||||
|
||||
exports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {
|
||||
// Try each provided data type in turn
|
||||
for(var t=0; t<importDataTypes.length; t++) {
|
||||
if(!$tw.browser.isIE || importDataTypes[t].IECompatible) {
|
||||
// Get the data
|
||||
var dataType = importDataTypes[t];
|
||||
var data = dataTransfer.getData(dataType.type);
|
||||
// Import the tiddlers in the data
|
||||
if(data !== "" && data !== null) {
|
||||
if($tw.log.IMPORT) {
|
||||
console.log("Importing data type '" + dataType.type + "', data: '" + data + "'")
|
||||
}
|
||||
var tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);
|
||||
callback(tiddlerFields);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var importDataTypes = [
|
||||
{type: "text/vnd.tiddler", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return parseJSONTiddlers(data,fallbackTitle);
|
||||
}},
|
||||
{type: "URL", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
return [{text: data}]; // As URL string
|
||||
}
|
||||
}},
|
||||
{type: "text/x-moz-url", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
return [{text: data}]; // As URL string
|
||||
}
|
||||
}},
|
||||
{type: "text/html", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "text/plain", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "Text", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}},
|
||||
{type: "text/uri-list", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
return [{text: data}];
|
||||
}}
|
||||
];
|
||||
|
||||
function parseJSONTiddlers(json,fallbackTitle) {
|
||||
var data = JSON.parse(json);
|
||||
if(!$tw.utils.isArray(data)) {
|
||||
data = [data];
|
||||
}
|
||||
data.forEach(function(fields) {
|
||||
fields.title = fields.title || fallbackTitle;
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user