1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-26 07:13:15 +00:00

First pass at a widget for importing tiddlers

This commit is contained in:
Jeremy Ruston 2013-04-01 19:06:39 +01:00
parent a75fd3df34
commit c287d9d6d0
6 changed files with 242 additions and 3 deletions

View File

@ -0,0 +1,196 @@
/*\
title: $:/core/modules/widget/import.js
type: application/javascript
module-type: widget
Implements the import widget.
```
<$import>
Import using the "browse..." button or drag files onto this text
</$import>
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var ImportWidget = function(renderer) {
// Save state
this.renderer = renderer;
// Generate child nodes
this.generate();
};
ImportWidget.prototype.generate = function() {
// Get the parameters from the attributes
this.browse = this.renderer.getAttribute("browse","yes");
this["class"] = this.renderer.getAttribute("class");
// Compute classes
var classes = ["tw-import"];
if(this["class"]) {
$tw.utils.pushTop(classes,this["class"]);
}
// Create the file input and container elements
var fileInput = {
type: "element",
tag: "input",
attributes: {
type: {type: "string", value: "file"},
style: {type: "string", value: this.browse === "no" ? "display: none;" : "display: block;"}
},
events: [{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}]
},
container = {
type: "element",
tag: "div",
children: this.renderer.parseTreeNode.children,
events: [
{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"}]
};
// Set the return element
this.tag = "div";
this.attributes = {
"class": classes.join(" ")
};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[fileInput,container]);
};
ImportWidget.prototype.handleChangeEvent = function(event) {
event.stopPropagation();
this.importFiles(event.target.files);
};
ImportWidget.prototype.handleDragEnterEvent = function(event) {
this.renderer.domNode.classList.add("tw-dragover");
};
ImportWidget.prototype.handleDragOverEvent = function(event) {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
};
ImportWidget.prototype.handleDragLeaveEvent = function(event) {
this.renderer.domNode.classList.remove("tw-dragover");
};
ImportWidget.prototype.handleDropEvent = function(event) {
this.renderer.domNode.classList.remove("tw-dragover");
event.stopPropagation();
event.preventDefault();
this.importFiles(event.dataTransfer.files);
return false;
};
ImportWidget.prototype.handlePasteEvent = function(event) {
var self = this,
items = event.clipboardData.items;
for(var t = 0; t<items.length; t++) {
var item = items[t];
if(item.kind === "file") {
var file = item.getAsFile();
this.importFiles([file]);
} else if(item.kind === "string") {
item.getAsString(function(str) {
var fields = {
title: self.generateTitle("Untitled"),
text: str
}
self.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(fields));
self.openTiddler(fields.title);
});
}
}
event.stopPropagation();
event.preventDefault();
return false;
};
ImportWidget.prototype.openTiddler = function(title) {
$tw.utils.dispatchCustomEvent(this.renderer.domNode,"tw-navigate",{
navigateTo: title,
navigateFromNode: this.renderer.domNode,
navigateFromClientRect: this.renderer.domNode.getBoundingClientRect()
});
};
ImportWidget.prototype.importFiles = function(files) {
var self = this,
importFile = function(file) {
// Get the type, falling back to the filename extension
var type = file.type;
if(type === "" || !type) {
var dotPos = file.name.lastIndexOf(".");
if(dotPos !== -1) {
var fileExtensionInfo = $tw.config.fileExtensionInfo[file.name.substr(dotPos)];
if(fileExtensionInfo) {
type = fileExtensionInfo.type;
}
}
}
// Override HTML files so that they're recognised as TiddlyWiki files
if(type === "text/html") {
type = "application/vnd.tiddlywiki2";
}
// Figure out if we're reading a binary file
var contentTypeInfo = $tw.config.contentTypeInfo[type],
isBinary = contentTypeInfo ? contentTypeInfo.encoding === "base64" : false;
// Create the FileReader
var reader = new FileReader();
reader.onload = function(event) {
// Deserialise the file contents
var fields = {
title: file.name || "Untitled",
type: type};
// Are we binary?
if(isBinary) {
var commaPos = event.target.result.indexOf(",");
if(commaPos !== -1) {
fields.text = event.target.result.substr(commaPos+1);
self.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(fields));
self.openTiddler(fields.title);
}
} else {
var tiddlers = self.renderer.renderTree.wiki.deserializeTiddlers(type,event.target.result,fields);
if(!tiddlers) {
console.log("No tiddlers found in file ",file.name);
} else {
$tw.utils.each(tiddlers,function(tiddlerFields) {
var title = self.generateTitle(tiddlerFields.title);
self.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(tiddlerFields,{title: title}));
self.openTiddler(title);
});
}
}
};
if(isBinary) {
reader.readAsDataURL(file);
} else {
reader.readAsText(file);
}
};
for(var f=0; f<files.length; f++) {
importFile(files[f]);
};
};
ImportWidget.prototype.generateTitle = function(baseTitle) {
var c = 0;
do {
var title = baseTitle + (c ? " " + (c + 1) : "");
c++;
} while(this.renderer.renderTree.wiki.tiddlerExists(title));
return title;
};
exports.import = ImportWidget;
})();

View File

@ -150,11 +150,16 @@ a.tw-tiddlylink-missing {
overflow-y: auto;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding: 4em 0em 2em 2em;
padding: 5em 0em 2em 2em;
margin: 0;
text-shadow: 0 1px 0 rgba(255,255,255, 0.8);
}
.sidebar-header p {
margin-top: 0;
margin-bottom: 0;
}
@media print {
.sidebar-header {
display: none;
@ -366,3 +371,13 @@ embed {
height: 20em;
}
.tw-dragover .tw-drag-target {
display: block;
background: red;
position: absolute;
}
.tw-drag-target {
display: none;
position: absolute;
}

View File

@ -2,6 +2,12 @@ title: $:/templates/ControlPanel
<$button message="tw-new-tiddler" class="btn btn-mini btn-success">New Tiddler</$button>
---
Import: <$import/>
---
<$button message="tw-save-wiki" class="btn btn-mini btn-primary">Save Changes</$button>
---

View File

@ -3,6 +3,13 @@ title: $:/templates/PageTemplate
<!-- The navigator catches navigation events and updates the story and history tiddlers -->
<$navigator story="$:/StoryList" history="$:/HistoryList">
<$import browse="no">
<div class="tw-drag-target">
Drop files here to import them as tiddlers
</div>
<!-- The sidebar header -->
<header class="sidebar-header">
@ -21,5 +28,7 @@ title: $:/templates/PageTemplate
<!-- End of story river -->
</section>
</$import>
</$navigator>

View File

@ -1,6 +1,7 @@
title: Improvements
modifier: JeremyRuston
tags: docs introduction
modifier: JeremyRuston
title: Improvements
modified: 201304011801
TiddlyWiki5 is a complete rewrite of the original TiddlyWiki. It is now based on an elegant [[microkernel architecture|PluginMechanism]], that allows infinite customisation by replacing and augmenting the core modules. The new code is much easier to work with, and will hopefully prove an even more fertile ground for the community of open source developers around TiddlyWiki.
@ -11,5 +12,6 @@ For end users, the important improvements include:
* TiddlyWiki can now be run under [[node.js]] as well as in the browser, allowing it to be used as a personal web server
* Tiddlers containing images are now supported just like WikiText tiddlers, including integrated editing of bitmap and SVG images
* TiddlyWiki5 can directly build both itself and previous (2.x.x) versions of TiddlyWiki from their constituent separate files, without needing external tools
* Easily [[import|ImportTiddlers]] content via drag and drop, copy and paste, or browsing for local files
The internal changes mean that TiddlyWiki5 is not compatible with previous versions, using different plugins, themes and so on. The changes to the WikiText have been carefully developed to try to maximise backwards compatibility but content prepared for previous versions of TiddlyWiki will need massaging to work properly in TiddlyWiki5.

View File

@ -0,0 +1,11 @@
title: ImportTiddlers
tags: docs features
modified: 201304011804
You can import content into a TiddlyWiki file in several ways:
* Use the ''browse'' button to select one or more local files
* Drag and drop files from Windows Explorer or Mac OS X Finder into the TiddlyWiki5 browser window
* Paste content directly from the clipboard using the keyboard shortcut (control-V or command-V)
** Pasting is currently only supported in GoogleChrome