From 03e64accf08d7ab8cd84cce94d9cdfc13e6b0ff8 Mon Sep 17 00:00:00 2001 From: BurningTreeC Date: Sat, 6 Apr 2024 07:56:48 +0200 Subject: [PATCH] use view widget from #8135 for testing --- core/modules/widgets/view.js | 520 ++++++++++++++++++++++------------- 1 file changed, 329 insertions(+), 191 deletions(-) diff --git a/core/modules/widgets/view.js b/core/modules/widgets/view.js index 01c1a336b..b84d33552 100755 --- a/core/modules/widgets/view.js +++ b/core/modules/widgets/view.js @@ -18,69 +18,83 @@ var ViewWidget = function(parseTreeNode,options) { this.initialise(parseTreeNode,options); }; -/* -Inherit from the base widget class -*/ -ViewWidget.prototype = new Widget(); - -var ViewHandler = function(options) { - this.document = options.document, - this.title = options.title, - this.field = options.field, - this.index = options.index, - this.mode = options.mode, - this.subTiddler = options.subTiddler, - this.text = options.text || "", - this.viewFormat = options.format, - this.wiki = options.wiki, - this.parentWidget = options.widget, - this.domNodes = []; +var ViewHandler = function(widget) { + this.wiki = widget.wiki; + this.widget = widget; + this.document = widget.document; }; +ViewHandler.prototype = {}; + +/* +Base ViewHandler render method +*/ ViewHandler.prototype.render = function(parent,nextSibling) { - this.parentDomNode = parent; - this.fakeWidget = this.wiki.makeTranscludeWidget(this.title,{ + this.text = this.getValue(); + this.createTextNode(parent,nextSibling); +}; + +/* +Base ViewHandler render method for wikified views +*/ +ViewHandler.prototype.renderWikified = function(parent,nextSibling) { + this.text = this.getValue(this.widget.viewMode); + this.createFakeWidget(); + this.createWikifiedTextNode(parent,nextSibling); +}; + +/* +ViewHandler method to create a simple text node +*/ +ViewHandler.prototype.createTextNode = function(parent,nextSibling) { + if(this.text) { + var textNode = this.document.createTextNode(this.text); + parent.insertBefore(textNode,nextSibling); + this.widget.domNodes.push(textNode); + } else { + this.widget.makeChildWidgets(); + this.widget.renderChildren(parent,nextSibling); + } +}; + +/* +ViewHandler method to always create a text node, even if there's no text +*/ +ViewHandler.prototype.createWikifiedTextNode = function(parent,nextSibling) { + var textNode = this.document.createTextNode(this.text || ""); + parent.insertBefore(textNode,nextSibling); + this.widget.domNodes.push(textNode); +}; + +/* +ViewHandler method to create a fake widget used by wikified views +*/ +ViewHandler.prototype.createFakeWidget = function() { + this.fakeWidget = this.wiki.makeTranscludeWidget(this.widget.viewTitle,{ document: $tw.fakeDocument, - field: this.field, - index: this.index, - parseAsInline: this.mode !== "block", - parentWidget: this.parentWidget, - subTiddler: this.subTiddler + field: this.widget.viewField, + index: this.widget.viewIndex, + parseAsInline: this.widget.viewMode !== "block", + parentWidget: this.widget, + subTiddler: this.widget.viewSubTiddler }); this.fakeNode = $tw.fakeDocument.createElement("div"); this.fakeWidget.makeChildWidgets(); this.fakeWidget.renderChildren(this.fakeNode,null); - var textNode = this.document.createTextNode(this.text); - parent.insertBefore(textNode,nextSibling); - this.domNodes.push(textNode); }; /* -Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +Base ViewHandler refresh method */ ViewHandler.prototype.refresh = function(changedTiddlers) { - var refreshed = this.fakeWidget.refresh(changedTiddlers); - if(refreshed) { - var newText; - switch(this.viewFormat) { - case "htmlwikified": - newText = this.fakeNode.innerHTML; - break; - case "plainwikified": - newText = this.fakeNode.textContent; - break; - case "htmlencodedplainwikified": - newText = $tw.utils.htmlEncode(this.fakeNode.textContent); - break; - } - if(newText !== this.text) { - this.domNodes[0].textContent = newText; - this.text = newText; - } - } - return refreshed; + return false; }; +/* +Inherit from the base widget class +*/ +ViewWidget.prototype = new Widget(); + /* Render this widget into the DOM */ @@ -88,30 +102,8 @@ ViewWidget.prototype.render = function(parent,nextSibling) { this.parentDomNode = parent; this.computeAttributes(); this.execute(); - if(this.viewWikified) { - var options = { - text: this.text, - title: this.viewTitle, - subTiddler: this.viewSubtiddler, - field: this.viewField, - index: this.viewIndex, - format: this.viewFormat, - template: this.viewTemplate, - mode: this.viewMode, - widget: this, - wiki: this.wiki, - document: this.document - } - this.viewHandler = new ViewHandler(options); - this.viewHandler.render(parent,nextSibling); - } else if(this.text) { - var textNode = this.document.createTextNode(this.text); - parent.insertBefore(textNode,nextSibling); - this.domNodes.push(textNode); - } else { - this.makeChildWidgets(); - this.renderChildren(parent,nextSibling); - } + this.view = this.getView(this.viewFormat); + this.view.render(parent,nextSibling); }; /* @@ -126,53 +118,274 @@ ViewWidget.prototype.execute = function() { this.viewFormat = this.getAttribute("format","text"); this.viewTemplate = this.getAttribute("template",""); this.viewMode = this.getAttribute("mode","block"); - this.viewWikified = false; - switch(this.viewFormat) { - case "htmlwikified": - this.text = this.getValueAsHtmlWikified(this.viewMode); - this.viewWikified = true; - break; - case "plainwikified": - this.text = this.getValueAsPlainWikified(this.viewMode); - this.viewWikified = true; - break; - case "htmlencodedplainwikified": - this.text = this.getValueAsHtmlEncodedPlainWikified(this.viewMode); - this.viewWikified = true; - break; - case "htmlencoded": - this.text = this.getValueAsHtmlEncoded(); - break; - case "htmltextencoded": - this.text = this.getValueAsHtmlTextEncoded(); - break; - case "urlencoded": - this.text = this.getValueAsUrlEncoded(); - break; - case "doubleurlencoded": - this.text = this.getValueAsDoubleUrlEncoded(); - break; - case "date": - this.text = this.getValueAsDate(this.viewTemplate); - break; - case "relativedate": - this.text = this.getValueAsRelativeDate(); - break; - case "stripcomments": - this.text = this.getValueAsStrippedComments(); - break; - case "jsencoded": - this.text = this.getValueAsJsEncoded(); - break; - default: // "text" - this.text = this.getValueAsText(); - break; - } }; /* -The various formatter functions are baked into this widget for the moment. Eventually they will be replaced by macro functions +Initialise the view subclasses */ +ViewWidget.prototype.getView = function(format) { + var View = this.initialiseView(); + View.prototype = Object.create(ViewHandler.prototype); + switch(format) { + case "htmlwikified": + View = this.initialiseHTMLWikifiedView(View); + break; + case "plainwikified": + View = this.initialisePlainWikifiedView(View); + break; + case "htmlencodedplainwikified": + View = this.initialiseHTMLEncodedPlainWikifiedView(View); + break; + case "htmlencoded": + View = this.initialiseHTMLEncodedView(View); + break; + case "htmltextencoded": + View = this.initialiseHTMLTextEncodedView(View); + break; + case "urlencoded": + View = this.initialiseURLEncodedView(View); + break; + case "doubleurlencoded": + View = this.initialiseDoubleURLEncodedView(View); + break; + case "date": + View = this.initialiseDateView(View); + break; + case "relativedate": + View = this.initialiseRelativeDateView(View); + break; + case "stripcomments": + View = this.initialiseStripCommentsView(View); + break; + case "jsencoded": + View = this.initialiseJSEncodedView(View); + break; + default: // "text" + View = this.initialiseTextView(View); + break; + }; + return new View(this); +}; + +/* +Return the function to intitialise the view subclass +*/ +ViewWidget.prototype.initialiseView = function() { + return function(widget) { + ViewHandler.call(this,widget); + }; +}; + +/* +Initialise HTML wikified view methods +*/ +ViewWidget.prototype.initialiseHTMLWikifiedView = function(View) { + var self = this; + + View.prototype.render = function(parent,nextSibling) { + this.renderWikified(parent,nextSibling); + }; + + View.prototype.getValue = function(mode) { + return self.wiki.renderText("text/html","text/vnd.tiddlywiki",self.getValueAsText(),{ + parseAsInline: mode !== "block", + parentWidget: self + }); + }; + + View.prototype.refresh = function(changedTiddlers) { + var refreshed = this.fakeWidget.refresh(changedTiddlers); + if(refreshed) { + var newText = this.fakeNode.innerHTML; + if(newText !== this.text) { + self.domNodes[0].textContent = newText; + this.text = newText; + } + } + return refreshed; + }; + return View; +}; + +/* +Initialise plain wikified view methods +*/ +ViewWidget.prototype.initialisePlainWikifiedView = function(View) { + var self = this; + + View.prototype.render = function(parent,nextSibling) { + this.renderWikified(parent,nextSibling); + }; + + View.prototype.getValue = function(mode) { + return self.wiki.renderText("text/plain","text/vnd.tiddlywiki",self.getValueAsText(),{ + parseAsInline: mode !== "block", + parentWidget: self + }); + }; + + View.prototype.refresh = function(changedTiddlers) { + var refreshed = this.fakeWidget.refresh(changedTiddlers); + if(refreshed) { + var newText = this.fakeNode.textContent; + if(newText !== this.text) { + self.domNodes[0].textContent = newText; + this.text = newText; + } + } + return refreshed; + }; + return View; +}; + +/* +Initialise HTML encoded plain wikified methods +*/ +ViewWidget.prototype.initialiseHTMLEncodedPlainWikifiedView = function(View) { + var self = this; + + View.prototype.render = function(parent,nextSibling) { + this.renderWikified(parent,nextSibling); + }; + + View.prototype.getValue = function(mode) { + return $tw.utils.htmlEncode(self.wiki.renderText("text/plain","text/vnd.tiddlywiki",self.getValueAsText(),{ + parseAsInline: mode !== "block", + parentWidget: self + })); + }; + + View.prototype.refresh = function(changedTiddlers) { + var refreshed = this.fakeWidget.refresh(changedTiddlers); + if(refreshed) { + var newText = $tw.utils.htmlEncode(this.fakeNode.textContent); + if(newText !== this.text) { + self.domNodes[0].textContent = newText; + this.text = newText; + } + } + return refreshed; + }; + return View; +}; + +/* +Initialise HTML encoded mehods +*/ +ViewWidget.prototype.initialiseHTMLEncodedView = function(View) { + var self = this; + View.prototype.getValue = function() { + return $tw.utils.htmlEncode(self.getValueAsText()); + }; + return View; +}; + +/* +Initialise HTML text encoded mehods +*/ +ViewWidget.prototype.initialiseHTMLTextEncodedView = function(View) { + var self = this; + View.prototype.getValue = function() { + return $tw.utils.htmlTextEncode(self.getValueAsText()); + }; + return View; +}; + +/* +Initialise URL encoded mehods +*/ +ViewWidget.prototype.initialiseURLEncodedView = function(View) { + var self = this; + View.prototype.getValue = function() { + return $tw.utils.encodeURIComponentExtended(self.getValueAsText()); + }; + return View; +}; + +/* +Initialise double URL encoded mehods +*/ +ViewWidget.prototype.initialiseDoubleURLEncodedView = function(View) { + var self = this; + View.prototype.getValue = function() { + return $tw.utils.encodeURIComponentExtended($tw.utils.encodeURIComponentExtended(self.getValueAsText())); + }; + return View; +}; + +/* +Initialise date mehods +*/ +ViewWidget.prototype.initialiseDateView = function(View) { + var self = this; + View.prototype.getValue = function(format) { + format = format || "YYYY MM DD 0hh:0mm"; + var value = $tw.utils.parseDate(self.getValue()); + if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") { + return $tw.utils.formatDateString(value,format); + } else { + return ""; + } + }; + return View; +}; + +/* +Initialise relative date mehods +*/ +ViewWidget.prototype.initialiseRelativeDateView = function(View) { + var self = this; + View.prototype.getValue = function(format) { + var value = $tw.utils.parseDate(self.getValue()); + if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") { + return $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description; + } else { + return ""; + } + }; + return View; +}; + +/* +Initialise stripcomments mehods +*/ +ViewWidget.prototype.initialiseStripCommentsView = function(View) { + var self = this; + View.prototype.getValue = function() { + var lines = self.getValueAsText().split("\n"), + out = []; + for(var line=0; line