diff --git a/core/modules/widgets/list/list.js b/core/modules/widgets/list/list.js index 94d0769a9..06e42fb6c 100644 --- a/core/modules/widgets/list/list.js +++ b/core/modules/widgets/list/list.js @@ -166,8 +166,16 @@ Remove a list element from the list, along with the attendant DOM nodes ListWidget.prototype.removeListElement = function(index) { // Get the list element var listElement = this.children[index]; - // Remove the DOM node - listElement.domNode.parentNode.removeChild(listElement.domNode); + // Invoke the listview to animate the removal + if(this.listview && this.listview.remove) { + if(!this.listview.remove(index)) { + // Only delete the DOM element if the listview.remove() returned false + listElement.domNode.parentNode.removeChild(listElement.domNode); + } + } else { + // Always remove the DOM node if we didn't invoke the listview + listElement.domNode.parentNode.removeChild(listElement.domNode); + } // Then delete the actual renderer node this.children.splice(index,1); }; @@ -266,6 +274,10 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) { // The list element isn't there, so we need to insert it this.children.splice(t,0,this.renderer.renderTree.createRenderer(this.renderer.renderContext,this.createListElement(this.list[t]))); this.renderer.domNode.insertBefore(this.children[t].renderInDom(),this.renderer.domNode.childNodes[t]); + // Ask the listview to animate the insertion + if(this.listview && this.listview.insert) { + this.listview.insert(t); + } } else { // Delete any list elements preceding the one we want for(var n=index-1; n>=t; n--) { diff --git a/core/modules/widgets/list/listviews/classic.js b/core/modules/widgets/list/listviews/classic.js new file mode 100644 index 000000000..b2d0e5ce6 --- /dev/null +++ b/core/modules/widgets/list/listviews/classic.js @@ -0,0 +1,95 @@ +/*\ +title: $:/core/modules/widgets/list/listviews/classic.js +type: application/javascript +module-type: listview + +Views the list as a linear sequence + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var ClassicListView = function(listWidget) { + this.listWidget = listWidget; +} + +ClassicListView.prototype.navigateTo = function(historyInfo) { + var listElementIndex = this.listWidget.findListElementByTitle(0,historyInfo.title), + listElementNode = this.listWidget.children[listElementIndex], + targetElement = listElementNode.domNode; + // Scroll the node into view + var scrollEvent = document.createEvent("Event"); + scrollEvent.initEvent("tw-scroll",true,true); + targetElement.dispatchEvent(scrollEvent); +}; + +ClassicListView.prototype.insert = function(index) { + var listElementNode = this.listWidget.children[index], + targetElement = listElementNode.domNode; + // Get the current height of the tiddler + var currHeight = targetElement.offsetHeight + parseInt(window.getComputedStyle(targetElement).marginTop,10); + // Reset the margin once the transition is over + var transitionEventName = $tw.utils.convertEventName("transitionEnd"); + targetElement.addEventListener(transitionEventName,function handler(event) { + $tw.utils.setStyle(targetElement,[ + {transition: "none"}, + {transform: "none"}, + {marginBottom: ""} + ]); + targetElement.removeEventListener(transitionEventName,handler,false); + },false); + // Set up the initial position of the element + $tw.utils.setStyle(targetElement,[ + {transition: "none"}, + {marginBottom: (-currHeight) + "px"}, + {opacity: "0.0"} + ]); + $tw.utils.forceLayout(targetElement); + // Transition to the final position + $tw.utils.setStyle(targetElement,[ + {transition: "opacity " + $tw.config.preferences.animationDurationMs + " ease-in-out, " + + "margin-bottom " + $tw.config.preferences.animationDurationMs + " ease-in-out"}, + {transform: "rotateX(0deg)"}, + {marginBottom: "0px"}, + {opacity: "1.0"} + ]); +}; + +ClassicListView.prototype.remove = function(index) { + var listElementNode = this.listWidget.children[index], + targetElement = listElementNode.domNode; + // Get the current height of the tiddler + var currWidth = targetElement.offsetWidth, + currHeight = targetElement.offsetHeight + parseInt(window.getComputedStyle(targetElement).marginTop,10); + // Attach an event handler for the end of the transition + targetElement.addEventListener($tw.utils.convertEventName("transitionEnd"),function(event) { + if(targetElement.parentNode) { + targetElement.parentNode.removeChild(targetElement); + } + },false); + // Animate the closure + $tw.utils.setStyle(targetElement,[ + {transition: "none"}, + {transform: "translateX(0px)"}, + {marginBottom: "0px"}, + {opacity: "1.0"} + ]); + $tw.utils.forceLayout(targetElement); + $tw.utils.setStyle(targetElement,[ + {transition: $tw.utils.roundTripPropertyName("transform") + " " + $tw.config.preferences.animationDurationMs + " ease-in-out, " + + "opacity " + $tw.config.preferences.animationDurationMs + " ease-in-out, " + + "margin-bottom " + $tw.config.preferences.animationDurationMs + " ease-in-out"}, + {transform: "translateX(" + currWidth + "px)"}, + {marginBottom: (-currHeight) + "px"}, + {opacity: "0.0"} + ]); + // Returning true causes the DOM node not to be deleted + return true; +}; + +exports.classic = ClassicListView; + +})(); diff --git a/core/templates/PageTemplate.tid b/core/templates/PageTemplate.tid index f5c9b59b2..a412cd697 100644 --- a/core/templates/PageTemplate.tid +++ b/core/templates/PageTemplate.tid @@ -8,7 +8,7 @@ title: $:/templates/PageTemplate {{SiteTitle}}.title
{{SiteSubtitle}} -<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" listview=classic itemClass="tw-menu-list-item"/> +<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" itemClass="tw-menu-list-item"/>
<$button message="tw-new-tiddler" class="btn btn-mini btn-success">New @@ -21,7 +21,7 @@ title: $:/templates/PageTemplate
-<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/templates/ViewTemplate" editTemplate="$:/templates/EditTemplate" listview="scroller" itemClass="tw-tiddler-frame"/> +<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/templates/ViewTemplate" editTemplate="$:/templates/EditTemplate" listview="classic" itemClass="tw-tiddler-frame"/> {{$:/snippets/encryptionstatus}}