1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-08-28 03:52:43 +00:00
TiddlyWiki5/core/modules/widgets/edit/editors/texteditor.js
Jeremy Ruston 2c20e6579d Update edit widget to trigger a popup when focussed
This will allow us to do autocompletion
2013-06-09 19:27:45 +01:00

191 lines
6.0 KiB
JavaScript

/*\
title: $:/core/modules/widgets/edit/editors/texteditor.js
type: application/javascript
module-type: editor
A plain text editor
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var MIN_TEXT_AREA_HEIGHT = 100;
var TextEditor = function(editWidget,tiddlerTitle,fieldName) {
this.editWidget = editWidget;
this.tiddlerTitle = tiddlerTitle;
this.fieldName = fieldName;
};
/*
Get the tiddler being edited and current value
*/
TextEditor.prototype.getEditInfo = function() {
// Get the current tiddler and the field name
var tiddler = this.editWidget.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle),
value;
// If we've got a tiddler, the value to display is the field string value
if(tiddler) {
value = tiddler.getFieldString(this.fieldName);
} else {
// Otherwise, we need to construct a default value for the editor
switch(this.fieldName) {
case "text":
value = "Type the text for the tiddler '" + this.tiddlerTitle + "'";
break;
case "title":
value = this.tiddlerTitle;
break;
default:
value = "";
break;
}
value = this.editWidget.renderer.getAttribute("default",value);
}
return {tiddler: tiddler, value: value};
};
TextEditor.prototype.render = function() {
// Get the initial value of the editor
var editInfo = this.getEditInfo();
// Create the editor nodes
var node = {
type: "element",
attributes: {}
};
var type = this.editWidget.renderer.getAttribute("type",this.fieldName === "text" ? "textarea" : "input");
switch(type) {
case "textarea":
node.tag = "textarea";
node.children = [{
type: "text",
text: editInfo.value
}];
break;
case "search":
node.tag = "input";
node.attributes.type = {type: "string", value: "search"};
node.attributes.value = {type: "string", value: editInfo.value};
break;
default: // "input"
node.tag = "input";
node.attributes.type = {type: "string", value: "text"};
node.attributes.value = {type: "string", value: editInfo.value};
break;
}
node.events = [
{name: "focus", handlerObject: this, handlerMethod: "handleFocusEvent"},
{name: "blur", handlerObject: this, handlerMethod: "handleBlurEvent"},
{name: "input", handlerObject: this, handlerMethod: "handleInputEvent"}
];
// Add a placeholder if specified
if(this.editWidget.renderer.hasAttribute("placeholder")) {
node.attributes.placeholder = {type: "string", value: this.editWidget.renderer.getAttribute("placeholder")};
}
// Set the element details
this.editWidget.tag = this.editWidget.renderer.parseTreeNode.isBlock ? "div" : "span";
this.editWidget.attributes = {
"class": "tw-edit-texteditor"
};
if(this.editWidget.renderer.hasAttribute("class")) {
this.editWidget.attributes["class"] += " " + this.editWidget.renderer.getAttribute("class");
}
if(this.editWidget.renderer.hasAttribute("style")) {
this.editWidget.attributes.style = this.editWidget.attributes.style || "";
this.editWidget.attributes.style += this.editWidget.renderer.getAttribute("style");
}
this.editWidget.children = this.editWidget.renderer.renderTree.createRenderers(this.editWidget.renderer,[node]);
};
TextEditor.prototype.setFocus = function() {
if(this.editWidget.renderer.hasAttribute("focusSet")) {
var title = this.editWidget.renderer.getAttribute("focusSet");
if(this.editWidget.renderer.getAttribute("qualifyTiddlerTitles") === "yes") {
title = title + "-" + this.editWidget.renderer.renderTree.getContextScopeId(this.editWidget.renderer.parentRenderer);
}
$tw.popup.triggerPopup({
domNode: this.editWidget.renderer.domNode,
title: title,
wiki: this.editWidget.renderer.renderTree.wiki,
force: true
});
}
};
TextEditor.prototype.handleFocusEvent = function(event) {
// this.saveChanges();
// this.fixHeight();
this.setFocus();
return true;
};
TextEditor.prototype.handleBlurEvent = function(event) {
// this.saveChanges();
return true;
};
TextEditor.prototype.handleInputEvent = function(event) {
this.saveChanges();
this.fixHeight();
return true;
};
TextEditor.prototype.saveChanges = function() {
var text = this.editWidget.children[0].domNode.value,
tiddler = this.editWidget.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle);
if(!tiddler) {
tiddler = new $tw.Tiddler({title: this.tiddlerTitle});
}
if(text !== tiddler.fields[this.fieldName]) {
var update = {};
update[this.fieldName] = text;
this.editWidget.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(tiddler,update));
}
};
TextEditor.prototype.fixHeight = function() {
var self = this;
if(this.editWidget.children[0].domNode && this.editWidget.children[0].domNode.type === "textarea") {
$tw.utils.nextTick(function() {
// Resize the textarea to fit its content
var textarea = self.editWidget.children[0].domNode,
scrollPosition = $tw.utils.getScrollPosition(),
scrollTop = scrollPosition.y;
// Set its height to auto so that it snaps to the correct height
textarea.style.height = "auto";
// Calculate the revised height
var newHeight = Math.max(textarea.scrollHeight + textarea.offsetHeight - textarea.clientHeight,MIN_TEXT_AREA_HEIGHT);
// Only try to change the height if it has changed
if(newHeight !== textarea.offsetHeight) {
textarea.style.height = newHeight + "px";
// Make sure that the dimensions of the textarea are recalculated
$tw.utils.forceLayout(textarea);
// Check that the scroll position is still visible before trying to scroll back to it
scrollTop = Math.min(scrollTop,self.editWidget.renderer.renderTree.document.body.scrollHeight - window.innerHeight);
window.scrollTo(scrollPosition.x,scrollTop);
}
});
}
};
TextEditor.prototype.postRenderInDom = function() {
this.fixHeight();
};
TextEditor.prototype.refreshInDom = function() {
if(this.editWidget.renderer.renderTree.document.activeElement !== this.editWidget.children[0].domNode) {
var editInfo = this.getEditInfo();
this.editWidget.children[0].domNode.value = editInfo.value;
}
// Fix the height if needed
this.fixHeight();
};
exports["text/vnd.tiddlywiki"] = TextEditor;
exports["text/plain"] = TextEditor;
})();