From 60e6b584bf6b686bf90f30669ad41811e10d14b4 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:16:44 +0100 Subject: [PATCH 1/6] Extend link widget with new attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add “draggable”, “tag” and “tabindex” attributes to link widget. --- core/modules/widgets/link.js | 35 +++++++++++++------ .../tw5.com/tiddlers/widgets/LinkWidget.tid | 5 ++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/modules/widgets/link.js b/core/modules/widgets/link.js index ebb3b413c..17c35dcff 100755 --- a/core/modules/widgets/link.js +++ b/core/modules/widgets/link.js @@ -53,8 +53,13 @@ Render this widget into the DOM */ LinkWidget.prototype.renderLink = function(parent,nextSibling) { var self = this; + // Sanitise the specified tag + var tag = this.linkTag; + if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) { + tag = "a"; + } // Create our element - var domNode = this.document.createElement("a"); + var domNode = this.document.createElement(tag); // Assign classes var classes = []; if(this.linkClasses) { @@ -78,7 +83,10 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) { wikiLinkText = wikiLinkTemplate.replace("$uri_encoded$",encodeURIComponent(this.to)); wikiLinkText = wikiLinkText.replace("$uri_doubleencoded$",encodeURIComponent(encodeURIComponent(this.to))); wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText}); - domNode.setAttribute("href",wikiLinkText); + if(tag === "a") { + domNode.setAttribute("href",wikiLinkText); + } + domNode.setAttribute("tabindex",this.tabIndex); // Set the tooltip // HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to "<$transclude field='tooltip'><$transclude field='title'/>" var tooltipWikiText = this.tooltip || this.getVariable("tv-wikilink-tooltip"); @@ -98,9 +106,13 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) { // Add a click event handler $tw.utils.addEventListeners(domNode,[ {name: "click", handlerObject: this, handlerMethod: "handleClickEvent"}, - {name: "dragstart", handlerObject: this, handlerMethod: "handleDragStartEvent"}, - {name: "dragend", handlerObject: this, handlerMethod: "handleDragEndEvent"} ]); + if(this.draggable === "yes") { + $tw.utils.addEventListeners(domNode,[ + {name: "dragstart", handlerObject: this, handlerMethod: "handleDragStartEvent"}, + {name: "dragend", handlerObject: this, handlerMethod: "handleDragEndEvent"} + ]); + } // Insert the link into the DOM and render any children parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); @@ -119,9 +131,11 @@ LinkWidget.prototype.handleClickEvent = function(event) { }, navigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1) }); - event.preventDefault(); - event.stopPropagation(); - return false; + if(this.domNodes[0].hasAttribute("href")) { + event.preventDefault(); + event.stopPropagation(); + return false; + } }; LinkWidget.prototype.handleDragStartEvent = function(event) { @@ -189,13 +203,14 @@ LinkWidget.prototype.handleDragEndEvent = function(event) { Compute the internal state of the widget */ LinkWidget.prototype.execute = function() { - // Get the target tiddler title + // Pick up our attributes this.to = this.getAttribute("to",this.getVariable("currentTiddler")); - // Get the link title and aria label this.tooltip = this.getAttribute("tooltip"); this["aria-label"] = this.getAttribute("aria-label"); - // Get the link classes this.linkClasses = this.getAttribute("class"); + this.tabIndex = this.getAttribute("tabindex"); + this.draggable = this.getAttribute("draggable","yes"); + this.linkTag = this.getAttribute("tag","a"); // Determine the link characteristics this.isMissing = !this.wiki.tiddlerExists(this.to); this.isShadow = this.wiki.isShadowTiddler(this.to); diff --git a/editions/tw5.com/tiddlers/widgets/LinkWidget.tid b/editions/tw5.com/tiddlers/widgets/LinkWidget.tid index db885e11e..64fd7b93a 100644 --- a/editions/tw5.com/tiddlers/widgets/LinkWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/LinkWidget.tid @@ -1,6 +1,6 @@ title: LinkWidget created: 201310241419 -modified: 201408280837 +modified: 201502231037 tags: Widgets caption: link @@ -12,6 +12,9 @@ The `link` widget generates links to tiddlers. (Use the HTML `` element to ge |to |The title of the target tiddler for the link (defaults to the CurrentTiddler) | |aria-label |Optional [[Accessibility]] label | |tooltip |Optional tooltip WikiText | +|tabindex |Optional numeric [[tabindex|https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/tabIndex]] | +|draggable |"yes" to enable the link to be draggable (defaults to "yes") | +|tag |Optional tag to override the default "a" element | The content of the link widget is rendered within the `` tag. From 0da1f3f554ea46f29f4e35817ffe5e67c6597b4a Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:17:00 +0100 Subject: [PATCH 2/6] Extend list widget to pass refreshes to the story view --- core/modules/widgets/list.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/modules/widgets/list.js b/core/modules/widgets/list.js index ed1998203..7244ee280 100755 --- a/core/modules/widgets/list.js +++ b/core/modules/widgets/list.js @@ -126,20 +126,29 @@ ListWidget.prototype.makeItemTemplate = function(title) { Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ ListWidget.prototype.refresh = function(changedTiddlers) { - var changedAttributes = this.computeAttributes(); + var changedAttributes = this.computeAttributes(), + result; + // Call the storyview + if(this.storyview && this.storyview.refreshStart) { + this.storyview.refreshStart(changedTiddlers,changedAttributes); + } // Completely refresh if any of our attributes have changed if(changedAttributes.filter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) { this.refreshSelf(); - return true; + result = true; } else { // Handle any changes to the list - var hasChanged = this.handleListChanges(changedTiddlers); + result = this.handleListChanges(changedTiddlers); // Handle any changes to the history stack if(this.historyTitle && changedTiddlers[this.historyTitle]) { this.handleHistoryChanges(); } - return hasChanged; } + // Call the storyview + if(this.storyview && this.storyview.refreshEnd) { + this.storyview.refreshEnd(changedTiddlers,changedAttributes); + } + return result; }; /* From 83011ddcffe5b7dbcdbdb1c029adaf790f41862b Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:18:47 +0100 Subject: [PATCH 3/6] Turn tiddler frames into links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By turning the tiddler frame into a link it is now possible to click on a tiddler to navigate to it. This is needed for the new stacked-storyview, but it also useful in other storyviews. Note that there are currently some issues. For example, in classic storyview, clicking on a tiddler will scroll to the top of it, which isn’t helpful if you’ve scrolled halfway down a long tiddler. --- core/ui/ViewTemplate.tid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/ui/ViewTemplate.tid b/core/ui/ViewTemplate.tid index 7d6bc230b..7bbc89281 100644 --- a/core/ui/ViewTemplate.tid +++ b/core/ui/ViewTemplate.tid @@ -3,6 +3,6 @@ title: $:/core/ui/ViewTemplate \define frame-classes() tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ \end -<$set name="storyTiddler" value=<>><$set name="tiddlerInfoState" value=<>><$tiddler tiddler=<>>
>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<>/> -
+<$set name="storyTiddler" value=<>><$set name="tiddlerInfoState" value=<>><$tiddler tiddler=<>><$link tag="div" draggable="no" tabindex="1" class=<>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<>/> + From 122a6f043d3125af38704b89cceb36bfcbd095db Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:20:41 +0100 Subject: [PATCH 4/6] Temporarily remove position sticky from titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Firefox bugs with position:sticky mean that we probably shouldn’t have sticky titles turned on by default. Previously, sticky titles were packaged into a pluggable theme. Now, I think it may make more sense to make the sticky titles status be a theme tweak for the Vanilla theme. --- themes/tiddlywiki/snowwhite/base.tid | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/themes/tiddlywiki/snowwhite/base.tid b/themes/tiddlywiki/snowwhite/base.tid index f4ff84bb3..20a8659ae 100644 --- a/themes/tiddlywiki/snowwhite/base.tid +++ b/themes/tiddlywiki/snowwhite/base.tid @@ -8,14 +8,16 @@ tags: [[$:/tags/Stylesheet]] } .tc-tiddler-title { - position: -webkit-sticky; - position: -moz-sticky; - position: -o-sticky; - position: -ms-sticky; - position: sticky; - top: 0px; - background: <>; - z-index: 500; +/******************************** + position: -webkit-sticky; + position: -moz-sticky; + position: -o-sticky; + position: -ms-sticky; + position: sticky; +********************************/ + top: 0px; + background: <>; + z-index: 500; } .tc-tiddler-info { From 682cfebe73f72fae5a9442129f94594ce27a0e4e Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:21:32 +0100 Subject: [PATCH 5/6] Adjust tiddler shadows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the shadow was to the bottom right. When tiddlers overlap (as with the stacked storyview) it makes them “pop” more if the shadow extends round all sides of the tiddler. --- themes/tiddlywiki/snowwhite/base.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/tiddlywiki/snowwhite/base.tid b/themes/tiddlywiki/snowwhite/base.tid index 20a8659ae..8dc27fd22 100644 --- a/themes/tiddlywiki/snowwhite/base.tid +++ b/themes/tiddlywiki/snowwhite/base.tid @@ -26,7 +26,7 @@ tags: [[$:/tags/Stylesheet]] @media screen { .tc-tiddler-frame { - <> + <> } } From 0bd2ec50e1514ef247182816f9f9e421f52f67bb Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 23 Feb 2015 11:21:57 +0100 Subject: [PATCH 6/6] Add stacked storyview plugin --- editions/prerelease/tiddlers/view.tid | 3 + editions/prerelease/tiddlywiki.info | 3 +- .../stacked-view/StackedControls.tid | 16 ++++ .../StackedStoryViewFanHeight.tid | 3 + plugins/tiddlywiki/stacked-view/plugin.info | 7 ++ plugins/tiddlywiki/stacked-view/readme.tid | 3 + .../stacked-view/stacked-storyview.tid | 4 + plugins/tiddlywiki/stacked-view/stacked.js | 86 +++++++++++++++++++ .../stacked-view/storyview-stacked.tid | 8 ++ 9 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 editions/prerelease/tiddlers/view.tid create mode 100644 plugins/tiddlywiki/stacked-view/StackedControls.tid create mode 100644 plugins/tiddlywiki/stacked-view/StackedStoryViewFanHeight.tid create mode 100644 plugins/tiddlywiki/stacked-view/plugin.info create mode 100644 plugins/tiddlywiki/stacked-view/readme.tid create mode 100644 plugins/tiddlywiki/stacked-view/stacked-storyview.tid create mode 100644 plugins/tiddlywiki/stacked-view/stacked.js create mode 100644 plugins/tiddlywiki/stacked-view/storyview-stacked.tid diff --git a/editions/prerelease/tiddlers/view.tid b/editions/prerelease/tiddlers/view.tid new file mode 100644 index 000000000..0e45ea308 --- /dev/null +++ b/editions/prerelease/tiddlers/view.tid @@ -0,0 +1,3 @@ +title: $:/view + +stacked \ No newline at end of file diff --git a/editions/prerelease/tiddlywiki.info b/editions/prerelease/tiddlywiki.info index 8aef38bf5..aff81f8e9 100644 --- a/editions/prerelease/tiddlywiki.info +++ b/editions/prerelease/tiddlywiki.info @@ -5,7 +5,8 @@ "tiddlywiki/nodewebkitsaver", "tiddlywiki/github-fork-ribbon", "tiddlywiki/browser-sniff", - "tiddlywiki/help" + "tiddlywiki/help", + "tiddlywiki/stacked-view" ], "themes": [ "tiddlywiki/vanilla", diff --git a/plugins/tiddlywiki/stacked-view/StackedControls.tid b/plugins/tiddlywiki/stacked-view/StackedControls.tid new file mode 100644 index 000000000..6fc706fea --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/StackedControls.tid @@ -0,0 +1,16 @@ +title: $:/plugins/tiddlywiki/stacked-view/StackedControls +tags: $:/tags/TopLeftBar + +<$reveal type="match" state="$:/view" text="stacked"> +Stacked view fan height: +<$button set="$:/config/StackedStoryViewFanHeight" setTo="-10">-10 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="0">0 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="10">10 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="30">30 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="50">50 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="100">100 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="300">300 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="500">500 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="700">700 +<$button set="$:/config/StackedStoryViewFanHeight" setTo="1500">1500 + diff --git a/plugins/tiddlywiki/stacked-view/StackedStoryViewFanHeight.tid b/plugins/tiddlywiki/stacked-view/StackedStoryViewFanHeight.tid new file mode 100644 index 000000000..9fc42e0e5 --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/StackedStoryViewFanHeight.tid @@ -0,0 +1,3 @@ +title: $:/config/StackedStoryViewFanHeight + +100 \ No newline at end of file diff --git a/plugins/tiddlywiki/stacked-view/plugin.info b/plugins/tiddlywiki/stacked-view/plugin.info new file mode 100644 index 000000000..2872a79d3 --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/plugin.info @@ -0,0 +1,7 @@ +{ + "title": "$:/plugins/tiddlywiki/stacked-view", + "description": "Stacked card storyview", + "author": "JeremyRuston", + "core-version": ">=5.0.0", + "list": "readme" +} diff --git a/plugins/tiddlywiki/stacked-view/readme.tid b/plugins/tiddlywiki/stacked-view/readme.tid new file mode 100644 index 000000000..6316044d0 --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/readme.tid @@ -0,0 +1,3 @@ +title: $:/plugins/tiddlywiki/stacked-view/readme + +This plugin provides a new story visualisation that displays individual tiddlers as a stack of cards. It is currently incomplete. diff --git a/plugins/tiddlywiki/stacked-view/stacked-storyview.tid b/plugins/tiddlywiki/stacked-view/stacked-storyview.tid new file mode 100644 index 000000000..3065d64d7 --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/stacked-storyview.tid @@ -0,0 +1,4 @@ +title: $:/plugins/tiddlywiki/stacked-view/config-macros/stacked-storyview +tags: $:/tags/Macro + +\define tv-stacked-storyview-fan-height-config-title() $:/config/StackedStoryViewFanHeight diff --git a/plugins/tiddlywiki/stacked-view/stacked.js b/plugins/tiddlywiki/stacked-view/stacked.js new file mode 100644 index 000000000..542a01082 --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/stacked.js @@ -0,0 +1,86 @@ +/*\ +title: $:/plugins/tiddlywiki/stacked-view/stacked.js +type: application/javascript +module-type: storyview + +Keeps tiddlers in a stack + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var easing = "cubic-bezier(0.645, 0.045, 0.355, 1)"; // From http://easings.net/#easeInOutCubic + +var StackedListView = function(listWidget) { + var self = this; + this.listWidget = listWidget; + this.fanHeightConfigTitle = listWidget.getVariable("tv-stacked-storyview-fan-height-config-title"); + this.placeTiddlers(); +}; + +StackedListView.prototype.placeTiddlers = function() { + // Initialise the stack of tiddler titles + this.listStack = []; + var numItems = this.listWidget.children.length, + t, itemWidget, + duration = $tw.utils.getAnimationDuration(); + for(t=numItems-1; t>=0; t--) { + itemWidget = this.listWidget.children[t]; + this.listStack.push(itemWidget.parseTreeNode.itemTitle); + } + // Ensure the tiddler at the top of the history stack is at the top of the array + var history = this.listWidget.wiki.getTiddlerData(this.listWidget.historyTitle,[]); + for(t=0; t=0; t--) { + // Get the DOM node for this tiddler + itemWidget = this.listWidget.children[t]; + var domNode = itemWidget.findFirstDomNode(); + if(domNode instanceof Element) { + // Find the position of the tiddler in the stack + var pos = this.listStack.indexOf(itemWidget.parseTreeNode.itemTitle); + if(pos !== -1) { + // Style the tiddler to position it + var posFactor = pos/(numItems-1); + $tw.utils.setStyle(domNode,[ + {position: "absolute"}, + {transformOrigin: "50% 0"}, + {transition: $tw.utils.roundTripPropertyName("transform") + " " + duration * (0.5 + posFactor) + "ms " + easing}, + {transform: "translateX(0px) translateY(" + (fanHeight * posFactor * posFactor) + "px) scale(" + (0.1 + posFactor * 0.9) + ")"}, + {zIndex: pos + ""} + ]); + } + } + } +}; + +StackedListView.prototype.refreshStart = function(changedTiddlers,changedAttributes) { +}; + +StackedListView.prototype.refreshEnd = function(changedTiddlers,changedAttributes) { + this.placeTiddlers(); +}; + +StackedListView.prototype.navigateTo = function(historyInfo) { +}; + +StackedListView.prototype.insert = function(widget) { +}; + +StackedListView.prototype.remove = function(widget) { + widget.removeChildDomNodes(); +}; + +exports.stacked = StackedListView; + +})(); \ No newline at end of file diff --git a/plugins/tiddlywiki/stacked-view/storyview-stacked.tid b/plugins/tiddlywiki/stacked-view/storyview-stacked.tid new file mode 100644 index 000000000..fdde5185d --- /dev/null +++ b/plugins/tiddlywiki/stacked-view/storyview-stacked.tid @@ -0,0 +1,8 @@ +title: $:/core/images/storyview-stacked +tags: $:/tags/Image + + + + + + \ No newline at end of file