mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-18 18:29:42 +00:00
cb34ef20ad
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
206 lines
6.4 KiB
JavaScript
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;
|
|
|
|
})();
|