1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-09-18 02:09:43 +00:00
TiddlyWiki5/core/modules/widgets/edit/editors/texteditor.js
Jeremy Ruston cb34ef20ad Add input type handling to the texteditor
This allows us to customise the input element used for each field type.
The only one implemented at the moment is color, which currently only
works on Chrome
2013-06-13 09:17:36 +01:00

206 lines
6.4 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: {}
};
// Get the edit type associated with this field
var type = "input";
if(this.fieldName === "text") {
type = "textarea";
} else {
var fieldModule = $tw.Tiddler.fieldModules[this.fieldName];
if(fieldModule && fieldModule.editType) {
type = fieldModule.editType;
}
}
var type = this.editWidget.renderer.getAttribute("type",type);
switch(type) {
case "textarea":
node.tag = "textarea";
node.children = [{
type: "text",
text: editInfo.value
}];
break;
case "color":
node.tag = "input";
node.attributes.type = {type: "string", value: "color"};
node.attributes.value = {type: "string", value: 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;
})();