mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-11 18:00:26 +00:00
Get rid of the old story macro, and tidy up
This commit is contained in:
parent
ba4e140147
commit
5a58639131
@ -1,305 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/story/story.js
|
||||
type: application/javascript
|
||||
module-type: macro
|
||||
|
||||
Displays a sequence of tiddlers defined in two JSON structures. The story tiddler is the sequence of tiddlers currently present in the DOM:
|
||||
|
||||
{
|
||||
tiddlers: [
|
||||
{title: <string>, draft: <string>}
|
||||
]
|
||||
}
|
||||
|
||||
The optional `draft` member indicates that the tiddler is in edit mode, and the value is the title of the tiddler being used as the draft.
|
||||
|
||||
When the story tiddler changes, the story macro adjusts the DOM to match. An optional storyview module can be used to visualise the changes.
|
||||
|
||||
And the history tiddler is the stack of tiddlers that were navigated to in turn:
|
||||
|
||||
{
|
||||
stack: [
|
||||
{
|
||||
title: <string>,
|
||||
fromTitle: <string>,
|
||||
fromPosition: {bottom: <num>, height: <num>, top: <num>, right: <num>, left: <num>, width: <num>}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
The history stack is updated during navigation, and again the storyview module is given an opportunity to animate the navigation.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "story",
|
||||
params: {
|
||||
story: {byName: "default", type: "tiddler"},
|
||||
history: {byName: "default", type: "tiddler"},
|
||||
viewTemplate: {byName: true, type: "tiddler"},
|
||||
editTemplate: {byName: true, type: "tiddler"},
|
||||
storyviewTiddler: {byName: true, type: "tiddler"},
|
||||
storyview: {byName: true, type: "text"}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Get the data from the JSON story tiddler
|
||||
*/
|
||||
exports.getStory = function() {
|
||||
this.story = this.wiki.getTiddlerData(this.params.story,{tiddlers: []});
|
||||
};
|
||||
|
||||
exports.getHistory = function() {
|
||||
this.history = this.wiki.getTiddlerData(this.params.history,{stack: []});
|
||||
};
|
||||
|
||||
exports.getViewTemplate = function(title) {
|
||||
if(this.hasParameter("viewTemplate")) {
|
||||
return this.params.viewTemplate;
|
||||
} else {
|
||||
return "$:/templates/ViewTemplate";
|
||||
}
|
||||
};
|
||||
|
||||
exports.getEditTemplate = function(title) {
|
||||
if(this.hasParameter("editTemplate")) {
|
||||
return this.params.editTemplate;
|
||||
} else {
|
||||
return "$:/templates/EditTemplate";
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Create a story element representing a given tiddler, optionally being editted
|
||||
*/
|
||||
exports.createStoryElement = function(title,draft) {
|
||||
var node = this.createStoryElementMacro(title,draft),
|
||||
eventHandler = {handleEvent: function(event) {
|
||||
// Add context information to the event
|
||||
event.navigateFromStoryElement = node;
|
||||
event.navigateFromTitle = title;
|
||||
return true;
|
||||
}};
|
||||
node.execute(this.parents,this.tiddlerTitle);
|
||||
var storyElement = $tw.Tree.Element("div",{"class": ["tw-story-element"]},[node],{
|
||||
events: ["tw-NewTiddler","tw-navigate","tw-EditTiddler","tw-SaveTiddler","tw-CloseTiddler"],
|
||||
eventHandler: eventHandler
|
||||
});
|
||||
// Save our data inside the story element node
|
||||
storyElement.storyElementInfo = {title: title};
|
||||
if(draft) {
|
||||
storyElement.storyElementInfo.draft = draft;
|
||||
}
|
||||
return storyElement;
|
||||
};
|
||||
|
||||
/*
|
||||
Create the tiddler macro needed to represent a given tiddler and its draft status
|
||||
*/
|
||||
exports.createStoryElementMacro = function(title,draft) {
|
||||
var srcParams;
|
||||
if(draft) {
|
||||
srcParams = {target: draft, template: this.getEditTemplate(title)};
|
||||
} else {
|
||||
srcParams = {target: title, template: this.getViewTemplate(title)};
|
||||
}
|
||||
return $tw.Tree.Macro("tiddler",{
|
||||
srcParams: srcParams,
|
||||
wiki: this.wiki
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Remove a story element from the story, along with the attendant DOM nodes
|
||||
*/
|
||||
exports.removeStoryElement = function(storyElementIndex) {
|
||||
var storyElement = this.storyNode.children[storyElementIndex];
|
||||
// Invoke the storyview to animate the removal
|
||||
if(this.storyview && this.storyview.remove) {
|
||||
if(!this.storyview.remove(storyElement,storyElementIndex)) {
|
||||
// Only delete the DOM element if the storyview.remove() returned false
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
} else {
|
||||
// Always delete the story element if we didn't invoke the storyview
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
// Then delete the actual renderer node
|
||||
this.storyNode.children.splice(storyElementIndex,1);
|
||||
};
|
||||
|
||||
/*
|
||||
Return the index of the story element that corresponds to a particular title
|
||||
startIndex: index to start search (use zero to search from the top)
|
||||
tiddlerTitle: tiddler title to seach for
|
||||
*/
|
||||
exports.findStoryElementByTitle = function(startIndex,tiddlerTitle) {
|
||||
while(startIndex < this.storyNode.children.length) {
|
||||
if(this.storyNode.children[startIndex].storyElementInfo.title === tiddlerTitle) {
|
||||
return startIndex;
|
||||
}
|
||||
startIndex++;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
exports.executeMacro = function() {
|
||||
// Get the story object
|
||||
this.getStory();
|
||||
// Create the story frame
|
||||
var attributes = {"class": "tw-story-frame"};
|
||||
this.storyNode = $tw.Tree.Element("div",attributes,[]);
|
||||
// Create each story element
|
||||
for(var t=0; t<this.story.tiddlers.length; t++) {
|
||||
this.storyNode.children.push(this.createStoryElement(this.story.tiddlers[t].title,this.story.tiddlers[t].draft));
|
||||
}
|
||||
if(this.classes) {
|
||||
$tw.utils.pushTop(attributes["class"],this.classes);
|
||||
}
|
||||
return this.storyNode;
|
||||
};
|
||||
|
||||
exports.postRenderInDom = function() {
|
||||
// Get the history object and use it to set the previous history
|
||||
this.getHistory();
|
||||
this.prevHistory = this.history;
|
||||
this.history = null;
|
||||
// Instantiate the story view
|
||||
var storyviewName;
|
||||
if(this.hasParameter("storyviewTiddler")) {
|
||||
storyviewName = this.wiki.getTextReference(this.params.storyviewTiddler);
|
||||
}
|
||||
if(!storyviewName && this.hasParameter("storyview")) {
|
||||
storyviewName = this.params.storyview;
|
||||
}
|
||||
var StoryView = this.wiki.macros.story.viewers[storyviewName];
|
||||
if(StoryView) {
|
||||
this.storyview = new StoryView(this);
|
||||
}
|
||||
if(!this.storyview) {
|
||||
StoryView = this.wiki.macros.story.viewers.classic;
|
||||
if(StoryView) {
|
||||
this.storyview = new StoryView(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.refreshInDom = function(changes) {
|
||||
// If the storyview has changed we'll have to completely re-execute the macro
|
||||
if(this.hasParameter("storyviewTiddler") && $tw.utils.hop(changes,this.params.storyviewTiddler)) {
|
||||
this.reexecuteInDom();
|
||||
return;
|
||||
}
|
||||
// If the story tiddler has changed we need to sync the story elements
|
||||
if(this.hasParameter("story") && $tw.utils.hop(changes,this.params.story)) {
|
||||
this.processStoryChange(changes);
|
||||
} else {
|
||||
// If the story didn't change then we must refresh our content
|
||||
this.child.refreshInDom(changes);
|
||||
}
|
||||
// If the history tiddler has changed we may need to visualise something
|
||||
if(this.hasParameter("history") && $tw.utils.hop(changes,this.params.history)) {
|
||||
this.processHistoryChange();
|
||||
}
|
||||
};
|
||||
|
||||
exports.processStoryChange = function(changes) {
|
||||
// Get the tiddlers we're supposed to be displaying
|
||||
var self = this,storyElement,
|
||||
t,n,domNode;
|
||||
// Get the story object
|
||||
this.getStory();
|
||||
// Check through each tiddler in the story
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
// See if the node we want is already there
|
||||
var tiddlerNode = this.findStoryElementByTitle(t,this.story.tiddlers[t].title);
|
||||
if(tiddlerNode === undefined) {
|
||||
// If not, render the tiddler
|
||||
this.storyNode.children.splice(t,0,this.createStoryElement(this.story.tiddlers[t].title,this.story.tiddlers[t].draft));
|
||||
this.storyNode.children[t].renderInDom(this.storyNode.domNode,this.storyNode.domNode.childNodes[t]);
|
||||
// Invoke the storyview to animate the navigation
|
||||
if(this.storyview && this.storyview.insert) {
|
||||
this.storyview.insert(this.storyNode.children[t]);
|
||||
}
|
||||
} else {
|
||||
// Delete any nodes preceding the one we want
|
||||
if(tiddlerNode > t) {
|
||||
for(n=tiddlerNode-1; n>=t; n--) {
|
||||
this.removeStoryElement(n);
|
||||
}
|
||||
}
|
||||
storyElement = this.storyNode.children[t];
|
||||
// Check that the edit status matches
|
||||
if(this.story.tiddlers[t].draft !== storyElement.storyElementInfo.draft) {
|
||||
// If not, we'll have to recreate the story element
|
||||
storyElement.children[0] = this.createStoryElementMacro(this.story.tiddlers[t].title,this.story.tiddlers[t].draft);
|
||||
// Remove the DOM node in the story element
|
||||
storyElement.domNode.removeChild(storyElement.domNode.firstChild);
|
||||
// Reexecute the story element
|
||||
storyElement.children[0].execute(this.parents,this.tiddlerTitle);
|
||||
// Render the story element in the DOM
|
||||
storyElement.children[0].renderInDom(storyElement.domNode);
|
||||
// Reset the information in the story element
|
||||
storyElement.storyElementInfo = {title: this.story.tiddlers[t].title, draft: this.story.tiddlers[t].draft};
|
||||
} else {
|
||||
// If the draft status matches then just refresh the DOM node we're reusing
|
||||
this.storyNode.children[t].refreshInDom(changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove any left over nodes
|
||||
if(this.storyNode.children.length > this.story.tiddlers.length) {
|
||||
for(t=this.storyNode.children.length-1; t>=this.story.tiddlers.length; t--) {
|
||||
this.removeStoryElement(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Respond to a change in the history tiddler. The basic idea is to issue forward/back navigation commands to the story view that correspond to the tiddlers that need to be popped on or off the stack
|
||||
*/
|
||||
exports.processHistoryChange = function() {
|
||||
// Read the history tiddler
|
||||
this.getHistory();
|
||||
if(this.storyview) {
|
||||
var t,indexTo,indexFrom,
|
||||
topCommon = Math.min(this.history.stack.length,this.prevHistory.stack.length);
|
||||
// Find the common heritage of the new history stack and the previous one
|
||||
for(t=0; t<topCommon; t++) {
|
||||
if(this.history.stack[t].title !== this.prevHistory.stack[t].title) {
|
||||
topCommon = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We now navigate backwards through the previous history to get back to the common ancestor
|
||||
for(t=this.prevHistory.stack.length-1; t>=topCommon; t--) {
|
||||
indexTo = this.findStoryElementByTitle(0,this.prevHistory.stack[t].fromTitle);
|
||||
indexFrom = this.findStoryElementByTitle(0,this.prevHistory.stack[t].title);
|
||||
// Call the story view if it defines a navigateBack() method
|
||||
if(indexTo !== undefined && indexFrom !== undefined && this.storyview.navigateBack) {
|
||||
this.storyview.navigateBack(this.storyNode.children[indexTo],this.storyNode.children[indexFrom],this.prevHistory.stack[t]);
|
||||
}
|
||||
}
|
||||
// And now we navigate forwards through the new history to get to the latest tiddler
|
||||
for(t=topCommon; t<this.history.stack.length; t++) {
|
||||
indexTo = this.findStoryElementByTitle(0,this.history.stack[t].title);
|
||||
indexFrom = this.findStoryElementByTitle(0,this.history.stack[t].fromTitle);
|
||||
if(indexTo !== undefined && this.storyview.navigateForward) {
|
||||
this.storyview.navigateForward(this.storyNode.children[indexTo],
|
||||
indexFrom !== undefined ? this.storyNode.children[indexFrom] : undefined,
|
||||
this.history.stack[t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Record the history stack for next time
|
||||
this.prevHistory = this.history;
|
||||
this.history = undefined;
|
||||
};
|
||||
|
||||
})();
|
@ -1,60 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/story/views/classic.js
|
||||
type: application/javascript
|
||||
module-type: storyview
|
||||
|
||||
A storyview that shows a sequence of tiddlers and navigates by smoothly scrolling
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
function ClassicScroller(story) {
|
||||
this.story = story;
|
||||
}
|
||||
|
||||
ClassicScroller.prototype.remove = function(storyElementNode) {
|
||||
var targetElement = storyElementNode.domNode;
|
||||
// Get the current height of the tiddler
|
||||
var currHeight = targetElement.offsetHeight;
|
||||
// Put a wrapper around the dom node we're closing
|
||||
var wrapperElement = document.createElement("div");
|
||||
targetElement.parentNode.insertBefore(wrapperElement,targetElement);
|
||||
wrapperElement.appendChild(targetElement);
|
||||
// Attach an event handler for the end of the transition
|
||||
wrapperElement.addEventListener($tw.browser.transitionEnd,function(event) {
|
||||
if(wrapperElement.parentNode) {
|
||||
wrapperElement.parentNode.removeChild(wrapperElement);
|
||||
}
|
||||
},false);
|
||||
// Animate the closure
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
wrapperElement.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, " +
|
||||
"opacity " + d + " ease-out, " +
|
||||
"height " + d + " ease-in-out";
|
||||
wrapperElement.style[$tw.browser.transformorigin] = "0% 0%";
|
||||
wrapperElement.style[$tw.browser.transform] = "translateX(0px)";
|
||||
wrapperElement.style.opacity = "1.0";
|
||||
wrapperElement.style.height = currHeight + "px";
|
||||
$tw.utils.forceLayout(wrapperElement);
|
||||
wrapperElement.style[$tw.browser.transform] = "translateX(" + window.innerWidth + "px)";
|
||||
wrapperElement.style.opacity = "0.0";
|
||||
wrapperElement.style.height = "0px";
|
||||
// Returning true causes the DOM node not to be deleted
|
||||
return true;
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateBack = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
exports.classic = ClassicScroller;
|
||||
|
||||
})();
|
@ -1,87 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/story/views/sideways.js
|
||||
type: application/javascript
|
||||
module-type: storyview
|
||||
|
||||
A storyview that shows a sequence of tiddlers as horizontally stacked blocks
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
function setStoryElementStyles(e) {
|
||||
e.style.display = "inline-block";
|
||||
e.style.width = "380px";
|
||||
e.style.verticalAlign = "top";
|
||||
e.style.whiteSpace = "normal";
|
||||
}
|
||||
|
||||
function SidewaysView(story) {
|
||||
this.story = story;
|
||||
var wrapper = this.story.child.domNode;
|
||||
// Scroll horizontally
|
||||
wrapper.style.whiteSpace = "nowrap";
|
||||
// Make all the tiddlers position absolute, and hide all but the first one
|
||||
for(var t=0; t<wrapper.children.length; t++) {
|
||||
setStoryElementStyles(wrapper.children[t]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to a new tiddler
|
||||
toStoryElementNode: tree node of the tiddler macro we're navigating to
|
||||
fromStoryElementNode: optionally, tree node of the tiddler we're navigating from
|
||||
historyInfo: record from the history tiddler corresponding to this navigation
|
||||
*/
|
||||
SidewaysView.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Visualise insertion of the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
storyElementNode: tree node of the tiddler macro we're navigating to
|
||||
*/
|
||||
SidewaysView.prototype.insert = function(storyElementNode) {
|
||||
setStoryElementStyles(storyElementNode.domNode);
|
||||
$tw.scroller.scrollIntoView(storyElementNode.domNode);
|
||||
};
|
||||
|
||||
SidewaysView.prototype.remove = function(storyElementNode) {
|
||||
var targetElement = storyElementNode.domNode;
|
||||
// Get the current width of the tiddler
|
||||
var currWidth = targetElement.offsetWidth;
|
||||
// Put a wrapper around the dom node we're closing
|
||||
var wrapperElement = document.createElement("div");
|
||||
targetElement.parentNode.insertBefore(wrapperElement,targetElement);
|
||||
wrapperElement.appendChild(targetElement);
|
||||
// Animate the closure
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
wrapperElement.style.display = "inline-block";
|
||||
wrapperElement.style[$tw.browser.transformorigin] = "0% 0%";
|
||||
wrapperElement.style[$tw.browser.transform] = "translateY(0px)";
|
||||
wrapperElement.style.opacity = "1.0";
|
||||
wrapperElement.style.width = currWidth + "px";
|
||||
wrapperElement.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, " +
|
||||
"opacity " + d + " ease-out, " +
|
||||
"width " + d + " ease-in-out";
|
||||
// Attach an event handler for th eend of the transition
|
||||
wrapperElement.addEventListener($tw.browser.transitionEnd,function(event) {
|
||||
if(wrapperElement.parentNode) {
|
||||
wrapperElement.parentNode.removeChild(wrapperElement);
|
||||
}
|
||||
},true);
|
||||
// Animate
|
||||
$tw.utils.forceLayout(wrapperElement);
|
||||
wrapperElement.style[$tw.browser.transform] = "translateY(" + window.innerHeight + "px)";
|
||||
wrapperElement.style.opacity = "0.0";
|
||||
wrapperElement.style.width = "0px";
|
||||
// Returning true causes the DOM node not to be deleted
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.sideways = SidewaysView;
|
||||
|
||||
})();
|
@ -1,182 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/story/views/zoomin.js
|
||||
type: application/javascript
|
||||
module-type: storyview
|
||||
|
||||
A storyview that shows a single tiddler and navigates by zooming into links.
|
||||
|
||||
To do this, the story wrapper is set to `position:relative` and then each of the story elements to `position:absolute`. This results in all of the tiddlers being stacked on top of one another flush with the top left of the story wrapper.
|
||||
|
||||
Navigating between tiddlers is accomplished by switching the story nodes between `display:block` and `display:none`, but the implementation is considerably more complex due to the animation.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false, Node: false */
|
||||
"use strict";
|
||||
|
||||
function Zoomin(story) {
|
||||
// Save the story
|
||||
this.story = story;
|
||||
this.storyNode = this.story.child.domNode;
|
||||
// Set the current tiddler
|
||||
this.currentTiddler = this.story.child.children[0];
|
||||
// Make all the tiddlers position absolute, and hide all but the first one
|
||||
this.storyNode.style.position = "relative";
|
||||
for(var t=0; t<this.storyNode.children.length; t++) {
|
||||
if(t) {
|
||||
this.storyNode.children[t].style.display = "none";
|
||||
}
|
||||
this.storyNode.children[t].style.position = "absolute";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Find the first descendent node that is a <<view title>> macro
|
||||
*/
|
||||
function findTitleNode(node) {
|
||||
var r;
|
||||
if(node.macroName && node.macroName === "view" && node.params && node.params.field && node.params.field === "title") {
|
||||
return node;
|
||||
}
|
||||
if(node.children) {
|
||||
for(var t=0; t<node.children.length; t++) {
|
||||
r = findTitleNode(node.children[t]);
|
||||
if(r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
} else if(node.child) {
|
||||
r = findTitleNode(node.child);
|
||||
if(r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to a new tiddler
|
||||
toStoryElementNode: tree node of the tiddler macro we're navigating to
|
||||
fromStoryElementNode: optionally, tree node of the tiddler we're navigating from
|
||||
historyInfo: record from the history tiddler corresponding to this navigation
|
||||
*/
|
||||
Zoomin.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
// Make the new tiddler be position absolute and visible so that we can measure it
|
||||
toStoryElement.domNode.style.position = "absolute";
|
||||
toStoryElement.domNode.style.display = "block";
|
||||
toStoryElement.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "none";
|
||||
toStoryElement.domNode.style.opacity = "0.0";
|
||||
// Get the position of the source node, or use the centre of the window as the source position
|
||||
var sourceBounds = historyInfo.fromPosition || {
|
||||
left: window.innerWidth/2 - 2,
|
||||
top: window.innerHeight/2 - 2,
|
||||
width: window.innerWidth/8,
|
||||
height: window.innerHeight/8
|
||||
};
|
||||
// Try to find the title node in the target tiddler
|
||||
var titleNode = findTitleNode(toStoryElement) || toStoryElement,
|
||||
titleBounds = titleNode.getNodeBounds();
|
||||
// Compute the transform for the target tiddler to make the title lie over the source rectange
|
||||
var targetBounds = toStoryElement.getNodeBounds(),
|
||||
scale = sourceBounds.width / titleBounds.width,
|
||||
x = sourceBounds.left - targetBounds.left - (titleBounds.left - targetBounds.left) * scale,
|
||||
y = sourceBounds.top - targetBounds.top - (titleBounds.top - targetBounds.top) * scale;
|
||||
// Transform the target tiddler to its starting position
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
// Get the animation duration
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first
|
||||
var self = this,
|
||||
prevCurrentTiddler = this.currentTiddler;
|
||||
this.currentTiddler = toStoryElement;
|
||||
// Force layout
|
||||
$tw.utils.forceLayout(this.storyNode);
|
||||
// Transform the target tiddler to its natural size
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
toStoryElement.domNode.style.opacity = "1.0";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style.zIndex = "500";
|
||||
// Transform the previous tiddler out of the way and then hide it
|
||||
if(prevCurrentTiddler && prevCurrentTiddler !== toStoryElement) {
|
||||
scale = titleBounds.width / sourceBounds.width;
|
||||
x = titleBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;
|
||||
y = titleBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
prevCurrentTiddler.domNode.style.opacity = "0.0";
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
prevCurrentTiddler.domNode.style.zIndex = "0";
|
||||
var eventHandler = function(event) {
|
||||
// Hide the DOM node when the transition is over
|
||||
if(self.currentTiddler !== prevCurrentTiddler) {
|
||||
prevCurrentTiddler.domNode.style.display = "none";
|
||||
}
|
||||
prevCurrentTiddler.domNode.removeEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
};
|
||||
prevCurrentTiddler.domNode.addEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
}
|
||||
// Scroll the target into view
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Visualise navigating back to the previous tiddler
|
||||
storyElement: story element being closed
|
||||
*/
|
||||
Zoomin.prototype.remove = function(storyElement,storyElementIndex) {
|
||||
// Get the animation duration
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
// Set up the tiddler that is being closed
|
||||
storyElement.domNode.style.position = "absolute";
|
||||
storyElement.domNode.style.display = "block";
|
||||
storyElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElement.domNode.style[$tw.browser.transition] = "none";
|
||||
storyElement.domNode.style.zIndex = "0";
|
||||
// We'll move back to the previous or next element in the story
|
||||
var toStoryElement = this.story.storyNode.children[storyElementIndex - 1];
|
||||
if(!toStoryElement) {
|
||||
toStoryElement = this.story.storyNode.children[storyElementIndex + 1];
|
||||
}
|
||||
// Set up the tiddler we're moving back in
|
||||
if(toStoryElement) {
|
||||
toStoryElement.domNode.style.position = "absolute";
|
||||
toStoryElement.domNode.style.display = "block";
|
||||
toStoryElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(10)";
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
toStoryElement.domNode.style.opacity = "0.0";
|
||||
toStoryElement.domNode.style.zIndex = "500";
|
||||
this.currentTiddler = toStoryElement;
|
||||
}
|
||||
// Animate them both
|
||||
$tw.utils.forceLayout(this.storyNode);
|
||||
// First, the tiddler we're closing
|
||||
storyElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElement.domNode.style.opacity = "0.0";
|
||||
storyElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(0.1)";
|
||||
storyElement.domNode.style.zIndex = "0";
|
||||
var eventHandler = function(event) {
|
||||
// Delete the DOM node when the transition is over
|
||||
if(storyElement.domNode.parentNode) {
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
storyElement.domNode.removeEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
};
|
||||
storyElement.domNode.addEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
// Now the tiddler we're going back to
|
||||
if(toStoryElement) {
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style.opacity = "1.0";
|
||||
}
|
||||
return true; // Indicate that we'll delete the DOM node
|
||||
};
|
||||
|
||||
exports.zoomin = Zoomin;
|
||||
|
||||
})();
|
@ -74,16 +74,16 @@ exports.startup = function() {
|
||||
defaultTiddlers = $tw.wiki.filterTiddlers(defaultTiddlersTiddler.fields.text);
|
||||
}
|
||||
// Initialise the story and history
|
||||
var storyTitle = "$:/StoryTiddlers",
|
||||
historyTitle = "$:/History",
|
||||
story = {tiddlers: []},
|
||||
history = {stack: []};
|
||||
var storyTitle = "$:/StoryList",
|
||||
historyTitle = "$:/HistoryList",
|
||||
story = [],
|
||||
history = [];
|
||||
for(var t=0; t<defaultTiddlers.length; t++) {
|
||||
story.tiddlers[t] = {title: defaultTiddlers[t]};
|
||||
history.stack[defaultTiddlers.length - t - 1] = {title: defaultTiddlers[t], fromTitle: defaultTiddlers[t+1]};
|
||||
story[t] = defaultTiddlers[t];
|
||||
history[defaultTiddlers.length - t - 1] = defaultTiddlers[t];
|
||||
}
|
||||
$tw.wiki.setTiddlerData(storyTitle,story);
|
||||
$tw.wiki.setTiddlerData(historyTitle,history);
|
||||
$tw.wiki.addTiddler({title: storyTitle, text: story.join("\n")});
|
||||
$tw.wiki.addTiddler({title: historyTitle, text: history.join("\n")});
|
||||
// If we're being viewed on a data: URI then give instructions for how to save
|
||||
if(document.location.protocol === "data:") {
|
||||
var event = document.createEvent("Event");
|
||||
|
@ -1,3 +0,0 @@
|
||||
title: $:/History
|
||||
type: application/json
|
||||
|
@ -1,3 +0,0 @@
|
||||
title: $:/StoryTiddlers
|
||||
type: application/json
|
||||
|
@ -3,5 +3,4 @@ title: $:/DefaultTiddlers
|
||||
HelloThere
|
||||
Introduction
|
||||
Improvements
|
||||
Docs
|
||||
Search
|
||||
Docs
|
@ -1,6 +0,0 @@
|
||||
title: $:/StoryList
|
||||
|
||||
HelloThere
|
||||
Introduction
|
||||
Improvements
|
||||
Docs
|
@ -1,7 +1,7 @@
|
||||
title: $:/templates/PageTemplate
|
||||
|
||||
<!-- The navigator catches navigation events and updates the story and history tiddlers -->
|
||||
<<navigator story:"$:/StoryTiddlers" history:"$:/History" ><
|
||||
<<navigator><
|
||||
|
||||
<!-- Zooming chooser -->
|
||||
{{navigation-panel{
|
||||
@ -68,7 +68,7 @@ title: $:/templates/PageTemplate
|
||||
|
||||
<!-- The main story references the same story and history tiddlers as the outer navigator -->
|
||||
<div class="container">
|
||||
<<story story:"$:/StoryTiddlers" history:"$:/History" storyviewTiddler:[[$:/CurrentView]] storyview:classic >>
|
||||
<<list filter:"[list[$:/StoryList]]" template:"$:/templates/ViewTemplate" editTemplate:"$:/templates/EditTemplate" listview:classic >>
|
||||
</div>
|
||||
|
||||
>>
|
||||
|
@ -1,7 +1,7 @@
|
||||
title: $:/templates/PageTemplate
|
||||
|
||||
<!-- The navigator catches navigation events and updates the story and history tiddlers -->
|
||||
<<navigator story:"$:/StoryTiddlers" history:"$:/History" ><
|
||||
<<navigator><
|
||||
|
||||
<!-- The top navigation bar -->
|
||||
<div class="navbar navbar-fixed-top">
|
||||
@ -22,7 +22,7 @@ title: $:/templates/PageTemplate
|
||||
|
||||
<!-- The main story references the same story and history tiddlers as the outer navigator -->
|
||||
<div class="container">
|
||||
<<story story:"$:/StoryTiddlers" history:"$:/History" storyviewTiddler:[[$:/CurrentView]] storyview:classic >>
|
||||
<<list filter:"[list[$:/StoryList]]" template:"$:/templates/ViewTemplate" editTemplate:"$:/templates/EditTemplate" listview:classic >>
|
||||
</div>
|
||||
|
||||
>>
|
||||
|
Loading…
Reference in New Issue
Block a user