mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-02-24 06:50:02 +00:00
Split the story macro out into two macros
Now the story macro manages the story element sequence, while the navigator macro listens for the navigation events, and modifies the story tiddler as required. Also introduces a history tiddler that retains the history stack so that we can animate navigation properly (as distinct from animating the addition and removal of story elements). Note that the zoomin storyview isn't quite finished, but this is a stable point to commit these changes.
This commit is contained in:
parent
663fd2fe10
commit
69a0c46447
208
core/modules/macros/navigator.js
Normal file
208
core/modules/macros/navigator.js
Normal file
@ -0,0 +1,208 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/navigator.js
|
||||
type: application/javascript
|
||||
module-type: macro
|
||||
|
||||
Traps navigation events to update a story tiddler and history tiddler. Can also optionally capture navigation target in a specified text reference.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "navigator",
|
||||
params: {
|
||||
story: {byName: "default", type: "text"}, // Actually a tiddler, but we don't want it to be a dependency
|
||||
history: {byName: "default", type: "text"}, // Actually a tiddler, but we don't want it to be a dependency
|
||||
defaultViewTemplate: {byName: true, type: "tiddler"},
|
||||
defaultEditTemplate: {byName: true, type: "tiddler"},
|
||||
set: {byName: true, type: "tiddler"}
|
||||
}
|
||||
};
|
||||
|
||||
exports.getStory = function() {
|
||||
var storyTiddler = this.wiki.getTiddler(this.params.story);
|
||||
this.story = {tiddlers: []};
|
||||
if(storyTiddler && $tw.utils.hop(storyTiddler.fields,"text")) {
|
||||
this.story = JSON.parse(storyTiddler.fields.text);
|
||||
}
|
||||
};
|
||||
|
||||
exports.saveStory = function() {
|
||||
if(this.hasParameter("story")) {
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.story),{title: this.params.story, text: JSON.stringify(this.story)}));
|
||||
}
|
||||
};
|
||||
|
||||
exports.getHistory = function() {
|
||||
var historyTiddler = this.wiki.getTiddler(this.params.history);
|
||||
this.history = {stack: []};
|
||||
if(historyTiddler && $tw.utils.hop(historyTiddler.fields,"text")) {
|
||||
this.history = JSON.parse(historyTiddler.fields.text);
|
||||
}
|
||||
};
|
||||
|
||||
exports.saveHistory = function() {
|
||||
if(this.hasParameter("history")) {
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.history),{title: this.params.history, text: JSON.stringify(this.history)}));
|
||||
}
|
||||
};
|
||||
|
||||
exports.handleEvent = function(event) {
|
||||
if(this.eventMap[event.type]) {
|
||||
this.eventMap[event.type].call(this,event);
|
||||
}
|
||||
};
|
||||
|
||||
exports.eventMap = {};
|
||||
|
||||
// Navigate to a specified tiddler
|
||||
exports.eventMap["tw-navigate"] = function(event) {
|
||||
// Update the story tiddler if specified
|
||||
if(this.hasParameter("story")) {
|
||||
this.getStory();
|
||||
var template = this.params.defaultViewTemplate || "$:/templates/ViewTemplate",
|
||||
t,tiddler,slot;
|
||||
// See if the tiddler is already there
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
if(this.story.tiddlers[t].title === event.navigateTo) {
|
||||
tiddler = t;
|
||||
}
|
||||
}
|
||||
// If not we need to add it
|
||||
if(tiddler === undefined) {
|
||||
// First we try to find the position of the story element we navigated from
|
||||
var navigateFromTitle;
|
||||
if(event.navigateFromStoryElement) {
|
||||
navigateFromTitle = event.navigateFromStoryElement.params.target;
|
||||
}
|
||||
slot = 0;
|
||||
if(navigateFromTitle !== undefined) {
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
if(this.story.tiddlers[t].title === navigateFromTitle) {
|
||||
slot = t + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the tiddler
|
||||
this.story.tiddlers.splice(slot,0,{title: event.navigateTo});
|
||||
// Save the story
|
||||
this.saveStory();
|
||||
}
|
||||
}
|
||||
// Set the tiddler if specified
|
||||
if(this.hasParameter("set")) {
|
||||
this.wiki.setTextReference(this.params.set,event.navigateTo);
|
||||
}
|
||||
// Add the tiddler to the top of the history stack
|
||||
this.getHistory();
|
||||
this.history.stack.push({title: event.navigateTo});
|
||||
this.saveHistory();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Place a tiddler in edit mode
|
||||
exports.eventMap["tw-EditTiddler"] = function(event) {
|
||||
if(this.hasParameter("story")) {
|
||||
var storyTiddler, storyRecord, tiddler, t;
|
||||
// Put the specified tiddler into edit mode
|
||||
this.getStory();
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
storyRecord = this.story.tiddlers[t];
|
||||
if(storyRecord.title === event.tiddlerTitle && !storyRecord.draft) {
|
||||
// Set the story record to the draft of the specified tiddler
|
||||
storyRecord.draft = "Draft " + (new Date()) + " of " + event.tiddlerTitle;
|
||||
// Get the current value of the tiddler we're editing
|
||||
tiddler = this.wiki.getTiddler(event.tiddlerTitle);
|
||||
// Save the initial value of the draft tiddler
|
||||
this.wiki.addTiddler(new $tw.Tiddler(
|
||||
{
|
||||
text: "Type the text for the tiddler '" + event.tiddlerTitle + "'"
|
||||
},
|
||||
tiddler,
|
||||
{
|
||||
title: storyRecord.draft,
|
||||
"draft.title": event.tiddlerTitle,
|
||||
"draft.of": event.tiddlerTitle
|
||||
}));
|
||||
}
|
||||
}
|
||||
this.saveStory();
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Take a tiddler out of edit mode, saving the changes
|
||||
exports.eventMap["tw-SaveTiddler"] = function(event) {
|
||||
if(this.hasParameter("story")) {
|
||||
var storyTiddler, storyRecord, tiddler, storyTiddlerModified, t;
|
||||
this.getStory();
|
||||
storyTiddlerModified = false;
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
storyRecord = this.story.tiddlers[t];
|
||||
if(storyRecord.draft === event.tiddlerTitle) {
|
||||
tiddler = this.wiki.getTiddler(storyRecord.draft);
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.title")) {
|
||||
// Save the draft tiddler as the real tiddler
|
||||
this.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: tiddler.fields["draft.title"],"draft.title": undefined, "draft.of": undefined}));
|
||||
// Remove the draft tiddler
|
||||
this.wiki.deleteTiddler(storyRecord.draft);
|
||||
// Remove the original tiddler if we're renaming it
|
||||
if(tiddler.fields["draft.of"] !== tiddler.fields["draft.title"]) {
|
||||
this.wiki.deleteTiddler(tiddler.fields["draft.of"]);
|
||||
}
|
||||
// Make the story record point to the newly saved tiddler
|
||||
storyRecord.title = tiddler.fields["draft.title"];
|
||||
storyRecord.draft = undefined;
|
||||
// Check if we're modifying the story tiddler itself
|
||||
if(tiddler.fields["draft.title"] === this.params.story) {
|
||||
storyTiddlerModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!storyTiddlerModified) {
|
||||
this.saveStory();
|
||||
}
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Close a specified tiddler
|
||||
exports.eventMap["tw-CloseTiddler"] = function(event) {
|
||||
if(this.hasParameter("story")) {
|
||||
var t,storyElement;
|
||||
this.getStory();
|
||||
// Look for tiddlers with this title to close
|
||||
for(t=this.story.tiddlers.length-1; t>=0; t--) {
|
||||
if(this.story.tiddlers[t].title === event.tiddlerTitle) {
|
||||
this.story.tiddlers.splice(t,1);
|
||||
}
|
||||
}
|
||||
this.saveStory();
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.executeMacro = function() {
|
||||
var attributes = {};
|
||||
if(this.classes) {
|
||||
attributes["class"] = this.classes.slice(0);
|
||||
}
|
||||
for(var t=0; t<this.content.length; t++) {
|
||||
this.content[t].execute(this.parents,this.tiddlerTitle);
|
||||
}
|
||||
return $tw.Tree.Element("div",attributes,this.content,{
|
||||
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler","tw-CloseTiddler"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
@ -3,15 +3,27 @@ title: $:/core/modules/macros/story/story.js
|
||||
type: application/javascript
|
||||
module-type: macro
|
||||
|
||||
Displays a sequence of tiddlers defined in a JSON structure:
|
||||
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>, template: <string>}
|
||||
]
|
||||
{title: <string>, draft: <string>}
|
||||
]
|
||||
}
|
||||
|
||||
The storyview is a plugin that extends the story macro to implement different navigation experiences.
|
||||
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 plugin 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>}
|
||||
]
|
||||
}
|
||||
|
||||
The history stack is updated during navigation, and again the storyview plugin is given an opportunity to animate the navigation.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@ -24,6 +36,7 @@ exports.info = {
|
||||
name: "story",
|
||||
params: {
|
||||
story: {byName: "default", type: "tiddler"},
|
||||
history: {byName: "default", type: "tiddler"},
|
||||
defaultViewTemplate: {byName: true, type: "tiddler"},
|
||||
defaultEditTemplate: {byName: true, type: "tiddler"},
|
||||
storyviewTiddler: {byName: true, type: "tiddler"},
|
||||
@ -31,213 +44,133 @@ exports.info = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Get the data from the JSON story tiddler
|
||||
*/
|
||||
exports.getStory = function() {
|
||||
var storyTiddler = this.wiki.getTiddler(this.params.story),
|
||||
story = {tiddlers: []};
|
||||
var storyTiddler = this.wiki.getTiddler(this.params.story);
|
||||
this.story = {
|
||||
tiddlers: []
|
||||
};
|
||||
if(storyTiddler && $tw.utils.hop(storyTiddler.fields,"text")) {
|
||||
return JSON.parse(storyTiddler.fields.text);
|
||||
} else {
|
||||
return {
|
||||
tiddlers: []
|
||||
};
|
||||
this.story = JSON.parse(storyTiddler.fields.text);
|
||||
}
|
||||
};
|
||||
|
||||
exports.handleEvent = function(event) {
|
||||
if(this.eventMap[event.type]) {
|
||||
this.eventMap[event.type].call(this,event);
|
||||
exports.getHistory = function() {
|
||||
var historyTiddler = this.wiki.getTiddler(this.params.history);
|
||||
this.history = {stack: []};
|
||||
if(historyTiddler && $tw.utils.hop(historyTiddler.fields,"text")) {
|
||||
this.history = JSON.parse(historyTiddler.fields.text);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getViewTemplate = function() {
|
||||
if(this.hasParameter("defaultViewTemplate")) {
|
||||
return this.params.defaultViewTemplate;
|
||||
} else {
|
||||
return "$:/templates/ViewTemplate";
|
||||
}
|
||||
};
|
||||
|
||||
exports.getEditTemplate = function() {
|
||||
if(this.hasParameter("defaultEditTemplate")) {
|
||||
return this.params.defaultEditTemplate;
|
||||
} else {
|
||||
return "$:/templates/EditTemplate";
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Return the index of the story element that contains the specified tree node. Returns -1 if none
|
||||
Create a story element representing a given tiddler, optionally being editted
|
||||
*/
|
||||
exports.findStoryElementContainingNode = function(node) {
|
||||
// Get the DOM node contained by the target node
|
||||
while(node && !node.domNode) {
|
||||
node = node.child;
|
||||
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-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;
|
||||
}
|
||||
// Step through the story elements
|
||||
var slot = -1;
|
||||
for(var t=0; t<this.storyNode.children.length; t++) {
|
||||
if($tw.utils.domContains(this.storyNode.children[t].domNode,node.domNode)) {
|
||||
slot = t;
|
||||
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()};
|
||||
} else {
|
||||
srcParams = {target: title, template: this.getViewTemplate()};
|
||||
}
|
||||
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)) {
|
||||
// Only delete the DOM element if the storyview.remove() returned false
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
// 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
|
||||
templateTitle: optional template title to search for
|
||||
*/
|
||||
exports.findStoryElementByTitle = function(startIndex,tiddlerTitle,templateTitle) {
|
||||
exports.findStoryElementByTitle = function(startIndex,tiddlerTitle) {
|
||||
while(startIndex < this.storyNode.children.length) {
|
||||
var params = this.storyNode.children[startIndex].children[0].params;
|
||||
if(params.target === tiddlerTitle) {
|
||||
if(!templateTitle || params.template === templateTitle) {
|
||||
return startIndex;
|
||||
}
|
||||
if(this.storyNode.children[startIndex].storyElementInfo.title === tiddlerTitle) {
|
||||
return startIndex;
|
||||
}
|
||||
startIndex++;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
exports.eventMap = {};
|
||||
|
||||
// Navigate to a specified tiddler
|
||||
exports.eventMap["tw-navigate"] = function(event) {
|
||||
var template = this.params.defaultViewTemplate || "$:/templates/ViewTemplate",
|
||||
story = this.getStory(),
|
||||
navTiddler,t,tiddler,slot;
|
||||
// See if the tiddler we want is already there
|
||||
for(t=0; t<story.tiddlers.length; t++) {
|
||||
if(story.tiddlers[t].title === event.navigateTo) {
|
||||
navTiddler = t;
|
||||
}
|
||||
}
|
||||
if(typeof(navTiddler) !== "undefined") {
|
||||
// If we found our tiddler, just tell the storyview to navigate to it
|
||||
if(this.storyview && this.storyview.navigate) {
|
||||
this.storyview.navigate(this.storyNode.children[navTiddler],false,event);
|
||||
}
|
||||
} else {
|
||||
// Find the source location in the story
|
||||
if(event.navigateFrom) {
|
||||
slot = this.findStoryElementContainingNode(event.navigateFrom) + 1;
|
||||
} else {
|
||||
slot = 0;
|
||||
}
|
||||
// Add the tiddler to the bottom of the story (subsequently there will be a refreshInDom() call which is when we'll actually do the navigation)
|
||||
story.tiddlers.splice(slot,0,{title: event.navigateTo, template: template});
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.story),{text: JSON.stringify(story)}));
|
||||
// Record the details of the navigation for us to pick up in refreshInDom()
|
||||
this.lastNavigationEvent = event;
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Place a tiddler in edit mode
|
||||
exports.eventMap["tw-EditTiddler"] = function(event) {
|
||||
var template, storyTiddler, story, storyRecord, tiddler, t;
|
||||
// Put the specified tiddler into edit mode
|
||||
template = this.params.defaultEditTemplate || "$:/templates/EditTemplate";
|
||||
story = this.getStory();
|
||||
for(t=0; t<story.tiddlers.length; t++) {
|
||||
storyRecord = story.tiddlers[t];
|
||||
if(storyRecord.title === event.tiddlerTitle && storyRecord.template !== template) {
|
||||
storyRecord.title = "Draft " + (new Date()) + " of " + event.tiddlerTitle;
|
||||
storyRecord.template = template;
|
||||
tiddler = this.wiki.getTiddler(event.tiddlerTitle);
|
||||
this.wiki.addTiddler(new $tw.Tiddler(
|
||||
{
|
||||
text: "Type the text for the tiddler '" + event.tiddlerTitle + "'"
|
||||
},
|
||||
tiddler,
|
||||
{
|
||||
title: storyRecord.title,
|
||||
"draft.title": event.tiddlerTitle,
|
||||
"draft.of": event.tiddlerTitle
|
||||
}));
|
||||
}
|
||||
}
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.story),{text: JSON.stringify(story)}));
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Take a tiddler out of edit mode, saving the changes
|
||||
exports.eventMap["tw-SaveTiddler"] = function(event) {
|
||||
var template, storyTiddler, story, storyRecord, tiddler, storyTiddlerModified, t;
|
||||
template = this.params.defaultEditTemplate || "$:/templates/ViewTemplate";
|
||||
story = this.getStory();
|
||||
storyTiddlerModified = false;
|
||||
for(t=0; t<story.tiddlers.length; t++) {
|
||||
storyRecord = story.tiddlers[t];
|
||||
if(storyRecord.title === event.tiddlerTitle && storyRecord.template !== template) {
|
||||
tiddler = this.wiki.getTiddler(storyRecord.title);
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.title")) {
|
||||
// Save the draft tiddler as the real tiddler
|
||||
this.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: tiddler.fields["draft.title"],"draft.title": undefined, "draft.of": undefined}));
|
||||
// Remove the draft tiddler
|
||||
this.wiki.deleteTiddler(storyRecord.title);
|
||||
// Remove the original tiddler if we're renaming it
|
||||
if(tiddler.fields["draft.of"] !== tiddler.fields["draft.title"]) {
|
||||
this.wiki.deleteTiddler(tiddler.fields["draft.of"]);
|
||||
}
|
||||
// Make the story record point to the newly saved tiddler
|
||||
storyRecord.title = tiddler.fields["draft.title"];
|
||||
storyRecord.template = template;
|
||||
// Check if we're modifying the story tiddler itself
|
||||
if(tiddler.fields["draft.title"] === this.params.story) {
|
||||
storyTiddlerModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!storyTiddlerModified) {
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.story),{text: JSON.stringify(story)}));
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Take a tiddler out of edit mode, saving the changes
|
||||
exports.eventMap["tw-CloseTiddler"] = function(event) {
|
||||
var story,t,storyElement;
|
||||
story = this.getStory();
|
||||
// Look for tiddlers with this title to close
|
||||
for(t=story.tiddlers.length-1; t>=0; t--) {
|
||||
if(story.tiddlers[t].title === event.tiddlerTitle) {
|
||||
storyElement = this.storyNode.children[t];
|
||||
// Invoke the storyview to animate the closure
|
||||
if(this.storyview && this.storyview.close) {
|
||||
if(!this.storyview.close(storyElement,event)) {
|
||||
// Only delete the DOM element if the storyview.close() returned false
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
}
|
||||
// Remove the story element node
|
||||
this.storyNode.children.splice(t,1);
|
||||
// Remove the record in the story
|
||||
story.tiddlers.splice(t,1);
|
||||
}
|
||||
}
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getTiddler(this.params.story),{text: JSON.stringify(story)}));
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.executeMacro = function() {
|
||||
// Get the story object
|
||||
this.getStory();
|
||||
// Create the story frame
|
||||
var story = this.getStory();
|
||||
this.contentNode = $tw.Tree.Element("div",{"class": "tw-story-content"},this.content);
|
||||
this.contentNode.execute(this.parents,this.tiddlerTitle);
|
||||
this.storyNode = $tw.Tree.Element("div",{"class": "tw-story-frame"},[]);
|
||||
var attributes = {"class": "tw-story-frame"};
|
||||
this.storyNode = $tw.Tree.Element("div",attributes,[]);
|
||||
// Create each story element
|
||||
for(var t=0; t<story.tiddlers.length; t++) {
|
||||
var m = $tw.Tree.Macro("tiddler",{
|
||||
srcParams: {target: story.tiddlers[t].title,template: story.tiddlers[t].template},
|
||||
wiki: this.wiki
|
||||
});
|
||||
m.execute(this.parents,this.tiddlerTitle);
|
||||
this.storyNode.children.push($tw.Tree.Element("div",{"class": "tw-story-element"},[m]));
|
||||
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));
|
||||
}
|
||||
var attributes = {};
|
||||
if(this.classes) {
|
||||
attributes["class"] = this.classes.slice(0);
|
||||
$tw.utils.pushTop(attributes["class"],this.classes);
|
||||
}
|
||||
return $tw.Tree.Element("div",attributes,[this.contentNode,this.storyNode],{
|
||||
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler","tw-CloseTiddler"],
|
||||
eventHandler: this
|
||||
});
|
||||
return this.storyNode;
|
||||
};
|
||||
|
||||
exports.postRenderInDom = function() {
|
||||
// Reset the record of the previous history stack
|
||||
this.prevHistory = {stack: []};
|
||||
// Instantiate the story view
|
||||
var storyviewName;
|
||||
if(this.hasParameter("storyviewTiddler")) {
|
||||
@ -259,7 +192,6 @@ exports.postRenderInDom = function() {
|
||||
};
|
||||
|
||||
exports.refreshInDom = function(changes) {
|
||||
var t;
|
||||
// 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 logic should be reused from the base macro class, and not duplicated
|
||||
@ -274,73 +206,105 @@ exports.refreshInDom = function(changes) {
|
||||
this.renderInDom(parentDomNode,insertBefore);
|
||||
return;
|
||||
}
|
||||
/*jslint browser: true */
|
||||
if(this.dependencies.hasChanged(changes,this.tiddlerTitle)) {
|
||||
// Get the tiddlers we're supposed to be displaying
|
||||
var self = this,
|
||||
story = this.getStory(),
|
||||
template = this.params.template,
|
||||
n,domNode,
|
||||
findTiddler = function (childIndex,tiddlerTitle,templateTitle) {
|
||||
while(childIndex < self.storyNode.children.length) {
|
||||
var params = self.storyNode.children[childIndex].children[0].params;
|
||||
if(params.target === tiddlerTitle) {
|
||||
if(!templateTitle || params.template === templateTitle) {
|
||||
return childIndex;
|
||||
}
|
||||
}
|
||||
childIndex++;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
for(t=0; t<story.tiddlers.length; t++) {
|
||||
// See if the node we want is already there
|
||||
var tiddlerNode = findTiddler(t,story.tiddlers[t].title,story.tiddlers[t].template);
|
||||
if(tiddlerNode === null) {
|
||||
// If not, render the tiddler
|
||||
var m = $tw.Tree.Element("div",{"class": "tw-story-element"},[
|
||||
$tw.Tree.Macro("tiddler",{
|
||||
srcParams: {target: story.tiddlers[t].title,template: story.tiddlers[t].template},
|
||||
wiki: this.wiki
|
||||
})
|
||||
]);
|
||||
m.execute(this.parents,this.tiddlerTitle);
|
||||
m.renderInDom(this.storyNode.domNode,this.storyNode.domNode.childNodes[t]);
|
||||
this.storyNode.children.splice(t,0,m);
|
||||
// Invoke the storyview to animate the navigation
|
||||
if(this.storyview && this.storyview.navigate) {
|
||||
this.storyview.navigate(this.storyNode.children[t],true,this.lastNavigationEvent);
|
||||
// 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 {
|
||||
// Delete any nodes preceding the one we want
|
||||
if(tiddlerNode > t) {
|
||||
// First delete the DOM nodes
|
||||
for(n=t; n<tiddlerNode; n++) {
|
||||
domNode = this.storyNode.children[n].domNode;
|
||||
domNode.parentNode.removeChild(domNode);
|
||||
}
|
||||
// Then delete the actual renderer nodes
|
||||
this.storyNode.children.splice(t,tiddlerNode-t);
|
||||
}
|
||||
// Refresh the DOM node we're reusing
|
||||
// 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 > story.tiddlers.length) {
|
||||
for(t=story.tiddlers.length; t<this.storyNode.children.length; t++) {
|
||||
domNode = this.storyNode.children[t].domNode;
|
||||
domNode.parentNode.removeChild(domNode);
|
||||
}
|
||||
this.storyNode.children.splice(story.tiddlers.length,this.storyNode.children.length-story.tiddlers.length);
|
||||
}
|
||||
} else {
|
||||
if(this.child) {
|
||||
this.child.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);
|
||||
}
|
||||
}
|
||||
// Clear the details of the last navigation
|
||||
this.lastNavigationEvent = undefined;
|
||||
};
|
||||
|
||||
/*
|
||||
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,index,
|
||||
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--) {
|
||||
index = this.findStoryElementByTitle(0,this.prevHistory.stack[t].title);
|
||||
if(index !== undefined && this.storyview.navigateBack) {
|
||||
this.storyview.navigateBack(this.storyNode.children[index]);
|
||||
}
|
||||
}
|
||||
// And now we navigate forwards through the new history to get to the latest tiddler
|
||||
for(t=topCommon; t<this.history.stack.length; t++) {
|
||||
index = this.findStoryElementByTitle(0,this.history.stack[t].title);
|
||||
if(index !== undefined && this.storyview.navigateForward) {
|
||||
this.storyview.navigateForward(this.storyNode.children[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Record the history stack for next time
|
||||
this.prevHistory = this.history;
|
||||
this.history = undefined;
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -16,48 +16,46 @@ function ClassicScroller(story) {
|
||||
this.story = story;
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
targetTiddlerNode: tree node of the tiddler macro we're navigating to
|
||||
isNew: true if the node we're navigating to has just been added to the DOM
|
||||
sourceNode: optional tree node that initiated the navigation
|
||||
*/
|
||||
ClassicScroller.prototype.navigate = function(targetTiddlerNode,isNew,sourceEvent) {
|
||||
$tw.utils.scrollIntoView(targetTiddlerNode.domNode);
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.close = function(targetTiddlerNode,sourceEvent) {
|
||||
var targetElement = targetTiddlerNode.domNode;
|
||||
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/1000).toFixed(8) + "s";
|
||||
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";
|
||||
wrapperElement.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, " +
|
||||
"opacity " + d + " ease-out, " +
|
||||
"height " + d + " ease-in-out";
|
||||
$tw.utils.nextTick(function() {
|
||||
wrapperElement.style[$tw.browser.transform] = "translateX(" + window.innerWidth + "px)";
|
||||
wrapperElement.style.opacity = "0.0";
|
||||
wrapperElement.style.height = "0px";
|
||||
});
|
||||
// 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);
|
||||
// Returning true causes the DOM node not to be deleted
|
||||
return true;
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateBack = function(storyElementNode) {
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateForward = function(storyElementNode) {
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
};
|
||||
|
||||
exports.classic = ClassicScroller;
|
||||
|
||||
})();
|
||||
|
@ -21,7 +21,7 @@ function setStoryElementStyles(e) {
|
||||
|
||||
function SidewaysView(story) {
|
||||
this.story = story;
|
||||
var wrapper = this.story.child.children[1].domNode;
|
||||
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
|
||||
@ -31,18 +31,16 @@ function SidewaysView(story) {
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
targetTiddlerNode: tree node of the tiddler macro we're navigating to
|
||||
isNew: true if the node we're navigating to has just been added to the DOM
|
||||
sourceNode: optional tree node that initiated the navigation
|
||||
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.navigate = function(targetTiddlerNode,isNew,sourceEvent) {
|
||||
setStoryElementStyles(targetTiddlerNode.domNode);
|
||||
$tw.utils.scrollIntoView(targetTiddlerNode.domNode);
|
||||
SidewaysView.prototype.insert = function(storyElementNode) {
|
||||
setStoryElementStyles(storyElementNode.domNode);
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
};
|
||||
|
||||
SidewaysView.prototype.close = function(targetTiddlerNode,sourceEvent) {
|
||||
var targetElement = targetTiddlerNode.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
|
||||
|
@ -15,17 +15,17 @@ A storyview that shows a single tiddler and navigates by zooming into links
|
||||
function Zoomin(story) {
|
||||
// Save the story
|
||||
this.story = story;
|
||||
var wrapper = this.story.child.children[1].domNode;
|
||||
this.storyNode = this.story.child.domNode;
|
||||
// Make all the tiddlers position absolute, and hide all but the first one
|
||||
wrapper.style.position = "relative";
|
||||
for(var t=0; t<wrapper.children.length; t++) {
|
||||
this.storyNode.style.position = "relative";
|
||||
for(var t=0; t<this.storyNode.children.length; t++) {
|
||||
if(t) {
|
||||
wrapper.children[t].style.display = "none";
|
||||
this.storyNode.children[t].style.display = "none";
|
||||
}
|
||||
wrapper.children[t].style.position = "absolute";
|
||||
this.storyNode.children[t].style.position = "absolute";
|
||||
}
|
||||
// Record the current tiddler node
|
||||
this.currTiddler = this.story.child.children[1].children[0];
|
||||
this.currTiddler = this.story.child.children[0];
|
||||
// Set up the stack of previously viewed tiddlers
|
||||
this.prevTiddlers = [this.currTiddler.children[0].params.target];
|
||||
}
|
||||
@ -70,44 +70,37 @@ function getNodeBounds(node) {
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
targetTiddlerNode: tree node of the tiddler macro we're navigating to
|
||||
isNew: true if the node we're navigating to has just been added to the DOM
|
||||
sourceNode: optional tree node that initiated the navigation
|
||||
Visualise removal of the the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
storyElementNode: tree node of the tiddler macro we're navigating to
|
||||
*/
|
||||
Zoomin.prototype.navigate = function(targetTiddlerNode,isNew,sourceEvent) {
|
||||
Zoomin.prototype.navigateForward = function(storyElementNode) {
|
||||
// Do nothing if the target tiddler is already the current tiddler
|
||||
if(targetTiddlerNode === this.currTiddler) {
|
||||
if(storyElementNode === this.currTiddler) {
|
||||
return;
|
||||
}
|
||||
// Make the new tiddler be position absolute and visible
|
||||
targetTiddlerNode.domNode.style.position = "absolute";
|
||||
targetTiddlerNode.domNode.style.display = "block";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transition] = "none";
|
||||
storyElementNode.domNode.style.position = "absolute";
|
||||
storyElementNode.domNode.style.display = "block";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "none";
|
||||
// Get the position of the source node, or use the centre of the window as the source position
|
||||
var sourceBounds;
|
||||
if(sourceEvent && sourceEvent.navigateFrom) {
|
||||
sourceBounds = getNodeBounds(sourceEvent.navigateFrom);
|
||||
} else {
|
||||
sourceBounds = {
|
||||
var sourceBounds = {
|
||||
left: window.innerWidth/2 - 2,
|
||||
top: window.innerHeight/2 - 2,
|
||||
width: 4,
|
||||
height: 4
|
||||
};
|
||||
}
|
||||
// Try to find the title node in the target tiddler
|
||||
var titleNode = findTitleNode(targetTiddlerNode) || targetTiddlerNode;
|
||||
var titleNode = findTitleNode(storyElementNode) || storyElementNode;
|
||||
// Compute the transform for the target tiddler to make the title lie over the source rectange
|
||||
var targetBounds = getNodeBounds(targetTiddlerNode),
|
||||
var targetBounds = getNodeBounds(storyElementNode),
|
||||
titleBounds = getNodeBounds(titleNode),
|
||||
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
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
// Get the animation duration
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first
|
||||
@ -118,10 +111,10 @@ Zoomin.prototype.navigate = function(targetTiddlerNode,isNew,sourceEvent) {
|
||||
var currTiddlerBounds = getNodeBounds(currTiddler),
|
||||
x = (currTiddlerBounds.left - targetBounds.left),
|
||||
y = (currTiddlerBounds.top - targetBounds.top);
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
targetTiddlerNode.domNode.style.opacity = "1.0";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(1)";
|
||||
targetTiddlerNode.domNode.style.zIndex = "500";
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElementNode.domNode.style.opacity = "1.0";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(1)";
|
||||
storyElementNode.domNode.style.zIndex = "500";
|
||||
// Transform the current tiddler
|
||||
var scale = titleBounds.width / sourceBounds.width;
|
||||
x = titleBounds.left - targetBounds.left - (sourceBounds.left - currTiddlerBounds.left) * scale;
|
||||
@ -133,15 +126,15 @@ Zoomin.prototype.navigate = function(targetTiddlerNode,isNew,sourceEvent) {
|
||||
currTiddler.domNode.style.zIndex = "0";
|
||||
});
|
||||
// Record the new current tiddler
|
||||
this.currTiddler = targetTiddlerNode;
|
||||
this.currTiddler = storyElementNode;
|
||||
// Save the tiddler in the stack
|
||||
this.prevTiddlers.push(targetTiddlerNode.children[0].params.target);
|
||||
this.prevTiddlers.push(storyElementNode.children[0].params.target);
|
||||
};
|
||||
|
||||
/*
|
||||
Visualise closing a tiddler
|
||||
Visualise removing a tiddler
|
||||
*/
|
||||
Zoomin.prototype.close = function(targetTiddlerNode,sourceEvent) {
|
||||
Zoomin.prototype.remove = function(storyElementNode) {
|
||||
// Remove the last entry from the navigation stack, which will be to navigate to the current tiddler
|
||||
this.prevTiddlers.pop();
|
||||
// Find the top entry in the navigation stack that still exists
|
||||
@ -159,12 +152,12 @@ Zoomin.prototype.close = function(targetTiddlerNode,sourceEvent) {
|
||||
// Get the animation duration
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
// Set up the tiddler that is being closed
|
||||
targetTiddlerNode.domNode.style.position = "absolute";
|
||||
targetTiddlerNode.domNode.style.display = "block";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transition] = "none";
|
||||
targetTiddlerNode.domNode.style.zIndex = "0";
|
||||
storyElementNode.domNode.style.position = "absolute";
|
||||
storyElementNode.domNode.style.display = "block";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "none";
|
||||
storyElementNode.domNode.style.zIndex = "0";
|
||||
// Set up the tiddler we're moving back in
|
||||
if(storyElement !== undefined) {
|
||||
storyElement.domNode.style.position = "absolute";
|
||||
@ -183,15 +176,15 @@ Zoomin.prototype.close = function(targetTiddlerNode,sourceEvent) {
|
||||
// Animate them both
|
||||
$tw.utils.nextTick(function() {
|
||||
// First, the tiddler we're closing
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
targetTiddlerNode.domNode.style.opacity = "0.0";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
targetTiddlerNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(0.1)";
|
||||
targetTiddlerNode.domNode.style.zIndex = "0";
|
||||
targetTiddlerNode.domNode.addEventListener($tw.browser.transitionEnd,function(event) {
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElementNode.domNode.style.opacity = "0.0";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(0.1)";
|
||||
storyElementNode.domNode.style.zIndex = "0";
|
||||
storyElementNode.domNode.addEventListener($tw.browser.transitionEnd,function(event) {
|
||||
// Delete the DOM node when the transition is over
|
||||
if(targetTiddlerNode.domNode.parentNode) {
|
||||
targetTiddlerNode.domNode.parentNode.removeChild(targetTiddlerNode.domNode);
|
||||
if(storyElementNode.domNode.parentNode) {
|
||||
storyElementNode.domNode.parentNode.removeChild(storyElementNode.domNode);
|
||||
}
|
||||
},true);
|
||||
// Now the tiddler we're going back to
|
||||
|
@ -1,7 +1,7 @@
|
||||
title: $:/templates/PageTemplate
|
||||
|
||||
<div class="container">
|
||||
<<story story:"$:/StoryTiddlers" storyviewTiddler:[[$:/CurrentView]] storyview:classic ><
|
||||
<<navigator story:"$:/StoryTiddlers" history:"$:/History" ><
|
||||
|
||||
{{navigation-panel{
|
||||
<<chooser><
|
||||
<<list all>>
|
||||
@ -35,9 +35,13 @@ title: $:/templates/PageTemplate
|
||||
</div>
|
||||
>>
|
||||
>>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<<story story:"$:/StoryTiddlers" history:"$:/History" storyviewTiddler:[[$:/CurrentView]] storyview:classic >>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
>>
|
||||
</div>
|
||||
|
||||
|
@ -3,9 +3,9 @@ type: application/json
|
||||
|
||||
{
|
||||
"tiddlers": [
|
||||
{"title": "HelloThere", "template": "$:/templates/ViewTemplate"},
|
||||
{"title": "Introduction", "template": "$:/templates/ViewTemplate"},
|
||||
{"title": "Improvements", "template": "$:/templates/ViewTemplate"},
|
||||
{"title": "Docs", "template": "$:/templates/ViewTemplate"}
|
||||
{"title": "HelloThere"},
|
||||
{"title": "Introduction"},
|
||||
{"title": "Improvements"},
|
||||
{"title": "Docs"}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user