From 71f6194f01fef4c5653d5b1e910236c0e41af71d Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Thu, 17 Jan 2013 13:52:46 +0000 Subject: [PATCH] Introduce a simple listview that scrolls to newly inserted entries --- core/modules/widgets/list/list.js | 50 ++++++++++++++++++- .../widgets/list/listviews/scroller.js | 31 ++++++++++++ core/templates/PageTemplate.tid | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 core/modules/widgets/list/listviews/scroller.js diff --git a/core/modules/widgets/list/list.js b/core/modules/widgets/list/list.js index 06679126c..afd39fd7e 100644 --- a/core/modules/widgets/list/list.js +++ b/core/modules/widgets/list/list.js @@ -15,6 +15,11 @@ The list widget var ListWidget = function(renderer) { // Save state this.renderer = renderer; + // Initialise the listviews if they've not been done already + if(!this.listViews) { + ListWidget.prototype.listViews = {}; + $tw.modules.applyMethods("listview",this.listViews); + } // Generate widget elements this.generate(); }; @@ -182,9 +187,24 @@ ListWidget.prototype.findListElementByTitle = function(startIndex,title) { return undefined; }; +ListWidget.prototype.postRenderInDom = function() { + this.listview = this.chooseListView(); + this.history = []; +}; + +/* +Select the appropriate list viewer +*/ +ListWidget.prototype.chooseListView = function() { + // Instantiate the list view + var listviewName = this.renderer.getAttribute("listview"); + var ListView = this.listViews[listviewName]; + return ListView ? new ListView(this) : null; +}; + ListWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) { // Reexecute the widget if any of our attributes have changed - if(changedAttributes.itemClass || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.type || changedAttributes.filter || changedAttributes.template) { + if(changedAttributes.itemClass || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.type || changedAttributes.filter || changedAttributes.template || changedAttributes.history || changedAttributes.listview) { // Regenerate and rerender the widget and replace the existing DOM node this.generate(); var oldDomNode = this.renderer.domNode, @@ -193,6 +213,11 @@ ListWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) } else { // Handle any changes to the list, and refresh any nodes we're reusing this.handleListChanges(changedTiddlers); + // Update the history list + var history = this.renderer.getAttribute("history"); + if(history && changedTiddlers[history]) { + this.handleHistoryChanges(); + } } }; @@ -255,6 +280,29 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) { } }; +/* +Handle any changes to the history list +*/ +ListWidget.prototype.handleHistoryChanges = function() { + // Get the history data + var historyAtt = this.renderer.getAttribute("history"), + newHistory = this.renderer.renderTree.wiki.getTiddlerData(historyAtt,[]); + // Ignore any entries of the history that match the previous history + var entry = 0; + while(entry < newHistory.length && entry < this.history.length && newHistory[entry].title === this.history[entry].title) { + entry++; + } + // Navigate forwards to each of the new tiddlers + while(entry < newHistory.length) { + if(this.listview && this.listview.navigateTo) { + this.listview.navigateTo(newHistory[entry]); + } + entry++; + } + // Update the history + this.history = newHistory; +}; + exports.list = ListWidget; })(); diff --git a/core/modules/widgets/list/listviews/scroller.js b/core/modules/widgets/list/listviews/scroller.js new file mode 100644 index 000000000..30a4ef68d --- /dev/null +++ b/core/modules/widgets/list/listviews/scroller.js @@ -0,0 +1,31 @@ +/*\ +title: $:/core/modules/widgets/list/listviews/scroller.js +type: application/javascript +module-type: listview + +A list view that scrolls to newly inserted elements + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var ScrollerListView = function(listWidget) { + this.listWidget = listWidget; +} + +ScrollerListView.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); +}; + +exports.scroller = ScrollerListView; + +})(); diff --git a/core/templates/PageTemplate.tid b/core/templates/PageTemplate.tid index 4550a0b92..f89fd9a3f 100644 --- a/core/templates/PageTemplate.tid +++ b/core/templates/PageTemplate.tid @@ -24,7 +24,7 @@ title: $:/templates/PageTemplate
-<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/templates/ViewTemplate" editTemplate="$:/templates/EditTemplate" listview=classic itemClass="tw-tiddler-frame"/> +<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/templates/ViewTemplate" editTemplate="$:/templates/EditTemplate" listview="scroller" itemClass="tw-tiddler-frame"/>