2012-01-23 18:31:17 +00:00
|
|
|
/*\
|
|
|
|
title: js/macros/slider.js
|
|
|
|
|
2012-03-04 13:20:38 +00:00
|
|
|
!Introduction
|
|
|
|
The slider macro is used to selectively reveal a chunk of text. By default, it renders as a button that may be clicked or touched to reveal the enclosed text.
|
|
|
|
|
|
|
|
The enclosed text can be a string of WikiText or be taken from a target tiddler.
|
2012-03-04 21:58:33 +00:00
|
|
|
|
|
|
|
The current state of the slider can be stored as the string "open" or "closed" in a specified tiddler. If the value of that tiddler changes then the slider is automatically updated.
|
2012-03-04 13:20:38 +00:00
|
|
|
!!Parameters
|
|
|
|
|`state` //(defaults to 1st parameter)// |The title of the tiddler to contain the current state of the slider |
|
|
|
|
|`default` |The initial state of the slider, either `open` or `closed` |
|
|
|
|
|`content` |The WikiText to be enclosed in the slider. Overrides the `target` parameter, if present |
|
|
|
|
|`target` //(defaults to 2nd parameter)// |The title of the tiddler that contains the enclosed text. Ignored if the `content` parameter is specified |
|
|
|
|
|`label` //(defaults to 3rd parameter)// |The plain text to be displayed as the label for the slider button |
|
|
|
|
|`tooltip` //(defaults to 4th parameter)// |The plain text tooltip to be displayed when the mouse hovers over the slider button |
|
|
|
|
!!Examples
|
|
|
|
A minimal slider:
|
|
|
|
{{{
|
|
|
|
<<slider target:MyTiddler>>
|
|
|
|
}}}
|
|
|
|
!!Notes
|
|
|
|
The slider is a good study example of a simple interactive macro.
|
2012-01-23 18:31:17 +00:00
|
|
|
\*/
|
|
|
|
(function(){
|
|
|
|
|
|
|
|
/*jslint node: true */
|
|
|
|
"use strict";
|
|
|
|
|
2012-02-16 20:38:10 +00:00
|
|
|
var Renderer = require("../Renderer.js").Renderer,
|
2012-02-17 14:11:25 +00:00
|
|
|
Dependencies = require("../Dependencies.js").Dependencies,
|
2012-02-17 12:36:39 +00:00
|
|
|
Tiddler = require("../Tiddler.js").Tiddler,
|
2012-02-06 11:31:23 +00:00
|
|
|
utils = require("../Utils.js");
|
2012-01-23 18:31:17 +00:00
|
|
|
|
2012-03-04 21:58:33 +00:00
|
|
|
|
|
|
|
function getOpenState() {
|
|
|
|
if(this.params.hasOwnProperty("state")) {
|
|
|
|
var stateTiddler = this.store.getTiddler(this.params.state);
|
|
|
|
if(stateTiddler) {
|
|
|
|
return stateTiddler.text.trim() === "open";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(this.params.hasOwnProperty("default")) {
|
|
|
|
return this.params["default"] === "open";
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
function saveOpenState() {
|
|
|
|
if(this.params.hasOwnProperty("state")) {
|
|
|
|
var stateTiddler = this.store.getTiddler(this.params.state) ||
|
|
|
|
new Tiddler({title: this.params.state, text: ""});
|
|
|
|
this.store.addTiddler(new Tiddler(stateTiddler,{text: this.isOpen ? "open" : "closed"}));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSliderContent() {
|
|
|
|
if(this.params.hasOwnProperty("content")) {
|
|
|
|
return this.store.parseText("text/x-tiddlywiki",this.params.content).nodes;
|
|
|
|
} else if(this.params.hasOwnProperty("target")) {
|
|
|
|
return [Renderer.MacroNode(
|
|
|
|
"tiddler",
|
|
|
|
{target: this.params.target},
|
|
|
|
null,
|
|
|
|
this.store)];
|
|
|
|
} else {
|
|
|
|
return [Renderer.ErrorNode("No content specified for slider")];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-01-23 18:31:17 +00:00
|
|
|
exports.macro = {
|
|
|
|
name: "slider",
|
|
|
|
types: ["text/html","text/plain"],
|
|
|
|
params: {
|
2012-02-19 17:24:01 +00:00
|
|
|
state: {byPos: 0, type: "tiddler"},
|
2012-03-04 13:20:38 +00:00
|
|
|
"default": {byName: true, type: "text"},
|
|
|
|
target: {byPos: 1, type: "tiddler"},
|
2012-02-17 17:32:32 +00:00
|
|
|
label: {byPos: 2, type: "text"},
|
2012-02-22 21:39:59 +00:00
|
|
|
tooltip: {byPos: 3, type: "text"},
|
|
|
|
content: {byName: true, type: "text"}
|
2012-01-23 18:31:17 +00:00
|
|
|
},
|
2012-02-02 17:48:09 +00:00
|
|
|
events: {
|
2012-02-21 21:57:30 +00:00
|
|
|
click: function(event) {
|
2012-03-04 21:58:33 +00:00
|
|
|
if(event.target === this.domNode.firstChild.firstChild) {
|
|
|
|
this.isOpen = !this.isOpen;
|
|
|
|
if(!saveOpenState.call(this)) {
|
|
|
|
exports.macro.refreshInDom.call(this,{});
|
|
|
|
}
|
2012-02-19 17:24:01 +00:00
|
|
|
event.preventDefault();
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
2012-02-02 17:48:09 +00:00
|
|
|
}
|
|
|
|
},
|
2012-02-21 21:57:30 +00:00
|
|
|
execute: function() {
|
2012-03-04 21:58:33 +00:00
|
|
|
this.isOpen = getOpenState.call(this);
|
|
|
|
var sliderContent = [];
|
|
|
|
if(this.isOpen) {
|
|
|
|
sliderContent = getSliderContent.call(this);
|
2012-02-22 21:39:59 +00:00
|
|
|
}
|
2012-02-21 21:57:30 +00:00
|
|
|
var content = Renderer.SliderNode(this.params.state,
|
2012-03-04 21:58:33 +00:00
|
|
|
this.params.label ? this.params.label : this.params.target,
|
2012-02-21 21:57:30 +00:00
|
|
|
this.params.tooltip,
|
2012-03-04 21:58:33 +00:00
|
|
|
this.isOpen,
|
2012-02-22 21:39:59 +00:00
|
|
|
sliderContent);
|
2012-03-04 21:58:33 +00:00
|
|
|
content.execute(this.parents,this.store.getTiddler(this.tiddlerTitle));
|
2012-02-16 20:38:10 +00:00
|
|
|
return [content];
|
2012-02-19 17:24:01 +00:00
|
|
|
},
|
2012-02-22 23:27:21 +00:00
|
|
|
refreshInDom: function(changes) {
|
2012-03-04 21:58:33 +00:00
|
|
|
var needContentRefresh = true; // Avoid refreshing the content nodes if we don't need to
|
|
|
|
// If the state tiddler has changed then reset the open state
|
|
|
|
if(this.params.hasOwnProperty("state") && changes.hasOwnProperty(this.params.state)) {
|
|
|
|
this.isOpen = getOpenState.call(this);
|
|
|
|
}
|
|
|
|
// Render the content if the slider is open and we don't have any content yet
|
|
|
|
if(this.isOpen && this.content[0].children[1].children.length === 0) {
|
|
|
|
// Get the slider content and execute it
|
|
|
|
this.content[0].children[1].children = getSliderContent.call(this);
|
|
|
|
this.content[0].children[1].execute(this.parents,this.store.getTiddler(this.tiddlerTitle));
|
|
|
|
// Replace the existing slider body DOM node
|
|
|
|
this.domNode.firstChild.removeChild(this.domNode.firstChild.firstChild.nextSibling);
|
|
|
|
this.content[0].children[1].renderInDom(this.domNode.firstChild,this.domNode.firstChild.firstChild.nextSibling);
|
|
|
|
needContentRefresh = false; // Don't refresh the children if we've just created them
|
|
|
|
}
|
|
|
|
// Set the visibility of the slider content
|
|
|
|
var el = this.domNode.firstChild.firstChild.nextSibling;
|
|
|
|
el.style.display = this.isOpen ? "block" : "none";
|
|
|
|
// Refresh any children
|
|
|
|
if(needContentRefresh) {
|
2012-02-22 22:47:42 +00:00
|
|
|
for(var t=0; t<this.content.length; t++) {
|
|
|
|
this.content[t].refreshInDom(changes);
|
|
|
|
}
|
2012-02-19 17:24:01 +00:00
|
|
|
}
|
2012-01-23 18:31:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
})();
|
|
|
|
|