mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-26 10:00:34 +00:00
167 lines
4.8 KiB
JavaScript
167 lines
4.8 KiB
JavaScript
/*\
|
|
title: $:/core/modules/macros/reveal.js
|
|
type: application/javascript
|
|
module-type: macro
|
|
|
|
The reveal macro shows or hides content according to the value of the text in a specified tiddler.
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
exports.info = {
|
|
name: "reveal",
|
|
params: {
|
|
state: {byPos: 0, type: "tiddler"},
|
|
type: {byName: true, type: "text"},
|
|
position: {byName: true, type: "text"},
|
|
qualifyTiddlerTitles: {byName: true, type: "text"},
|
|
"default": {byName: true, type: "text"},
|
|
"class": {byName: true, type: "text"}
|
|
}
|
|
};
|
|
|
|
exports.readState = function() {
|
|
// Start with the default value for being open or closed
|
|
if(this.hasParameter("default")) {
|
|
this.isOpen = this.params["default"] === "open";
|
|
}
|
|
// Read the information from the state tiddler
|
|
if(this.stateTextRef) {
|
|
var state = this.wiki.getTextReference(this.stateTextRef,"",this.tiddlerTitle);
|
|
switch(this.params.type) {
|
|
case "popup":
|
|
this.readPopupState(state);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.readPopupState = function(state) {
|
|
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
|
|
match = popupLocationRegExp.exec(state);
|
|
// Check if the state matches the location regexp
|
|
if(match) {
|
|
// If so, we're open
|
|
this.isOpen = true;
|
|
// Get the location
|
|
this.popup = {
|
|
left: parseFloat(match[1]),
|
|
top: parseFloat(match[2]),
|
|
width: parseFloat(match[3]),
|
|
height: parseFloat(match[4])
|
|
};
|
|
} else {
|
|
// If not, we're closed
|
|
this.isOpen = false;
|
|
}
|
|
};
|
|
|
|
exports.handleEvent = function(event) {
|
|
if(event.type === "click") {
|
|
// Cancel the popup if we get a click on it
|
|
if(this.stateTextRef) {
|
|
this.wiki.deleteTextReference(this.stateTextRef);
|
|
}
|
|
event.preventDefault();
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
exports.executeMacro = function() {
|
|
this.stateTextRef = this.params.state;
|
|
if(this.hasParameter("qualifyTiddlerTitles")) {
|
|
this.stateTextRef = "(" + this.parents.join(",") + "," + this.tiddlerTitle + ")" + this.stateTextRef;
|
|
}
|
|
this.readState();
|
|
var attributes = {
|
|
"class": ["tw-reveal"],
|
|
style: {}
|
|
};
|
|
if(this.hasParameter("class")) {
|
|
attributes["class"].push(this.params["class"]);
|
|
}
|
|
if(this.classes) {
|
|
$tw.utils.pushTop(attributes["class"],this.classes);
|
|
}
|
|
switch(this.params.type) {
|
|
case "popup":
|
|
attributes.style.position = "absolute";
|
|
attributes["class"].push("tw-popup");
|
|
break;
|
|
}
|
|
attributes.style = {display: this.isOpen ? "block" : "none"};
|
|
var child = $tw.Tree.Element("div",attributes,this.isOpen ? this.content : [],{
|
|
events: ["click"],
|
|
eventHandler: this
|
|
});
|
|
child.execute(this.parents,this.tiddlerTitle);
|
|
return child;
|
|
};
|
|
|
|
exports.postRenderInDom = function() {
|
|
switch(this.params.type) {
|
|
case "popup":
|
|
if(this.isOpen) {
|
|
this.child.domNode.style.position = "absolute";
|
|
this.child.domNode.style.zIndex = "1000";
|
|
switch(this.params.position) {
|
|
case "left":
|
|
this.child.domNode.style.left = (this.popup.left - this.child.domNode.offsetWidth) + "px";
|
|
this.child.domNode.style.top = this.popup.top + "px";
|
|
break;
|
|
case "above":
|
|
this.child.domNode.style.left = this.popup.left + "px";
|
|
this.child.domNode.style.top = (this.popup.top - this.child.domNode.offsetHeight) + "px";
|
|
break;
|
|
case "right":
|
|
this.child.domNode.style.left = (this.popup.left + this.popup.width) + "px";
|
|
this.child.domNode.style.top = this.popup.top + "px";
|
|
break;
|
|
case "belowleft":
|
|
this.child.domNode.style.left = (this.popup.left + this.popup.width - this.child.domNode.offsetWidth) + "px";
|
|
this.child.domNode.style.top = (this.popup.top + this.popup.height) + "px";
|
|
break;
|
|
default: // Below
|
|
this.child.domNode.style.left = this.popup.left + "px";
|
|
this.child.domNode.style.top = (this.popup.top + this.popup.height) + "px";
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
exports.refreshInDom = function(changes) {
|
|
var needChildrenRefresh = true, // Avoid refreshing the children nodes if we don't need to
|
|
t;
|
|
// Re-read the open state
|
|
this.readState();
|
|
// Render the children if we're open and we don't have any children yet
|
|
if(this.isOpen && this.child.children.length === 0) {
|
|
// Install the children and execute them
|
|
this.child.children = this.content;
|
|
for(t=0; t<this.child.children.length; t++) {
|
|
this.child.children[t].execute(this.parents,this.tiddlerTitle);
|
|
this.child.children[t].renderInDom(this.child.domNode);
|
|
}
|
|
needChildrenRefresh = false; // Don't refresh the children if we've just created them
|
|
}
|
|
// Refresh the children
|
|
if(needChildrenRefresh) {
|
|
for(t=0; t<this.child.children.length; t++) {
|
|
this.child.children[t].refreshInDom(changes);
|
|
}
|
|
}
|
|
// Set the visibility of the children
|
|
this.child.domNode.style.display = this.isOpen ? "block" : "none";
|
|
// Position the content if required
|
|
this.postRenderInDom();
|
|
};
|
|
|
|
})();
|