2012-07-15 16:37:03 +00:00
|
|
|
/*\
|
|
|
|
title: $:/core/modules/utils/dom/modal.js
|
|
|
|
type: application/javascript
|
|
|
|
module-type: utils
|
|
|
|
|
|
|
|
Modal message mechanism
|
|
|
|
|
|
|
|
\*/
|
|
|
|
(function(){
|
|
|
|
|
|
|
|
/*jslint node: true, browser: true */
|
|
|
|
/*global $tw: false */
|
|
|
|
"use strict";
|
|
|
|
|
2013-11-08 08:47:00 +00:00
|
|
|
var widget = require("$:/core/modules/widgets/widget.js");
|
2013-10-21 19:14:01 +00:00
|
|
|
|
2012-07-15 16:37:03 +00:00
|
|
|
var Modal = function(wiki) {
|
|
|
|
this.wiki = wiki;
|
2013-06-04 15:19:47 +00:00
|
|
|
this.modalCount = 0;
|
2012-07-15 16:37:03 +00:00
|
|
|
};
|
|
|
|
|
2012-11-16 19:30:30 +00:00
|
|
|
/*
|
|
|
|
Display a modal dialogue
|
|
|
|
title: Title of tiddler to display
|
|
|
|
options: see below
|
|
|
|
Options include:
|
|
|
|
downloadLink: Text of a big download link to include
|
|
|
|
*/
|
|
|
|
Modal.prototype.display = function(title,options) {
|
|
|
|
options = options || {};
|
2013-08-28 14:15:56 +00:00
|
|
|
var self = this,
|
2013-09-10 14:28:15 +00:00
|
|
|
duration = $tw.utils.getAnimationDuration(),
|
|
|
|
tiddler = this.wiki.getTiddler(title);
|
|
|
|
// Don't do anything if the tiddler doesn't exist
|
|
|
|
if(!tiddler) {
|
|
|
|
return;
|
|
|
|
}
|
2012-07-16 11:57:44 +00:00
|
|
|
// Create the wrapper divs
|
2012-07-15 16:37:03 +00:00
|
|
|
var wrapper = document.createElement("div"),
|
2012-07-16 11:57:44 +00:00
|
|
|
modalBackdrop = document.createElement("div"),
|
|
|
|
modalWrapper = document.createElement("div"),
|
|
|
|
modalHeader = document.createElement("div"),
|
2013-03-01 09:13:10 +00:00
|
|
|
headerTitle = document.createElement("h3"),
|
2012-07-16 11:57:44 +00:00
|
|
|
modalBody = document.createElement("div"),
|
2012-11-16 19:30:30 +00:00
|
|
|
modalLink = document.createElement("a"),
|
2012-07-16 11:57:44 +00:00
|
|
|
modalFooter = document.createElement("div"),
|
2012-07-16 12:47:28 +00:00
|
|
|
modalFooterHelp = document.createElement("span"),
|
2013-09-10 14:28:15 +00:00
|
|
|
modalFooterButtons = document.createElement("span");
|
|
|
|
// Up the modal count and adjust the body class
|
|
|
|
this.modalCount++;
|
|
|
|
this.adjustPageClass();
|
2012-07-16 11:57:44 +00:00
|
|
|
// Add classes
|
2013-06-04 15:19:47 +00:00
|
|
|
$tw.utils.addClass(wrapper,"modal-wrapper");
|
2012-07-16 11:57:44 +00:00
|
|
|
$tw.utils.addClass(modalBackdrop,"modal-backdrop");
|
|
|
|
$tw.utils.addClass(modalWrapper,"modal");
|
|
|
|
$tw.utils.addClass(modalHeader,"modal-header");
|
|
|
|
$tw.utils.addClass(modalBody,"modal-body");
|
2012-11-16 19:30:30 +00:00
|
|
|
$tw.utils.addClass(modalLink,"btn btn-large btn-block btn-success");
|
2012-07-16 11:57:44 +00:00
|
|
|
$tw.utils.addClass(modalFooter,"modal-footer");
|
|
|
|
// Join them together
|
|
|
|
wrapper.appendChild(modalBackdrop);
|
|
|
|
wrapper.appendChild(modalWrapper);
|
|
|
|
modalHeader.appendChild(headerTitle);
|
|
|
|
modalWrapper.appendChild(modalHeader);
|
|
|
|
modalWrapper.appendChild(modalBody);
|
|
|
|
modalFooter.appendChild(modalFooterHelp);
|
|
|
|
modalFooter.appendChild(modalFooterButtons);
|
|
|
|
modalWrapper.appendChild(modalFooter);
|
|
|
|
// Render the title of the message
|
2012-07-16 13:04:29 +00:00
|
|
|
var titleText;
|
|
|
|
if(tiddler && tiddler.fields && tiddler.fields.subtitle) {
|
|
|
|
titleText = tiddler.fields.subtitle;
|
|
|
|
} else {
|
|
|
|
titleText = title;
|
|
|
|
}
|
2013-11-08 08:51:14 +00:00
|
|
|
var headerParser = this.wiki.parseText("text/vnd.tiddlywiki",titleText,{parseAsInline: true}),
|
2013-10-29 14:51:35 +00:00
|
|
|
headerWidgetNode = this.wiki.makeWidget(headerParser,{parentWidget: $tw.rootWidget, document: document});
|
2013-10-29 15:01:36 +00:00
|
|
|
headerWidgetNode.render(headerTitle,null);
|
2013-03-16 10:42:46 +00:00
|
|
|
this.wiki.addEventListener("change",function(changes) {
|
2013-10-21 19:14:01 +00:00
|
|
|
headerWidgetNode.refresh(changes,modalHeader,null);
|
2012-07-15 16:37:03 +00:00
|
|
|
});
|
2012-07-16 11:57:44 +00:00
|
|
|
// Render the body of the message
|
2013-11-08 08:51:14 +00:00
|
|
|
var bodyParser = this.wiki.parseTiddler(title),
|
2013-10-29 14:51:35 +00:00
|
|
|
bodyWidgetNode = this.wiki.makeWidget(bodyParser,{parentWidget: $tw.rootWidget, document: document});
|
2013-10-21 19:14:01 +00:00
|
|
|
bodyWidgetNode.render(modalBody,null);
|
2013-03-16 10:42:46 +00:00
|
|
|
this.wiki.addEventListener("change",function(changes) {
|
2013-10-21 19:14:01 +00:00
|
|
|
bodyWidgetNode.refresh(changes,modalBody,null);
|
2012-07-16 11:57:44 +00:00
|
|
|
});
|
2012-11-16 19:30:30 +00:00
|
|
|
// Setup the link if present
|
|
|
|
if(options.downloadLink) {
|
|
|
|
modalLink.href = options.downloadLink
|
2012-11-16 19:36:50 +00:00
|
|
|
modalLink.appendChild(document.createTextNode("Right-click to save changes"));
|
2012-11-16 19:30:30 +00:00
|
|
|
modalBody.appendChild(modalLink);
|
|
|
|
}
|
2012-07-16 11:57:44 +00:00
|
|
|
// Render the footer of the message
|
2012-07-16 12:47:28 +00:00
|
|
|
if(tiddler && tiddler.fields && tiddler.fields.help) {
|
|
|
|
var link = document.createElement("a");
|
|
|
|
link.setAttribute("href",tiddler.fields.help);
|
|
|
|
link.setAttribute("target","_blank");
|
|
|
|
link.appendChild(document.createTextNode("Help"));
|
|
|
|
modalFooterHelp.appendChild(link);
|
|
|
|
modalFooterHelp.style.float = "left";
|
|
|
|
}
|
2012-07-16 13:04:29 +00:00
|
|
|
var footerText;
|
|
|
|
if(tiddler && tiddler.fields && tiddler.fields.footer) {
|
|
|
|
footerText = tiddler.fields.footer;
|
|
|
|
} else {
|
2013-02-04 15:29:25 +00:00
|
|
|
footerText = '<$button message="tw-close-tiddler" class="btn btn-primary">Close</$button>';
|
2012-07-16 13:04:29 +00:00
|
|
|
}
|
2013-11-08 08:51:14 +00:00
|
|
|
var footerParser = this.wiki.parseText("text/vnd.tiddlywiki",footerText,{parseAsInline: true}),
|
2013-10-29 14:51:35 +00:00
|
|
|
footerWidgetNode = this.wiki.makeWidget(footerParser,{parentWidget: $tw.rootWidget, document: document});
|
2013-10-21 19:14:01 +00:00
|
|
|
footerWidgetNode.render(modalFooterButtons,null);
|
2013-03-16 10:42:46 +00:00
|
|
|
this.wiki.addEventListener("change",function(changes) {
|
2013-10-21 19:14:01 +00:00
|
|
|
footerWidgetNode.refresh(changes,modalFooterButtons,null);
|
2012-07-16 11:57:44 +00:00
|
|
|
});
|
|
|
|
// Add the close event handler
|
2013-10-21 19:14:01 +00:00
|
|
|
var closeHandler = function(event) {
|
2013-06-04 15:19:47 +00:00
|
|
|
// Decrease the modal count and adjust the body class
|
|
|
|
self.modalCount--;
|
|
|
|
self.adjustPageClass();
|
2012-07-18 10:45:17 +00:00
|
|
|
// Force layout and animate the modal message away
|
2012-08-02 21:32:34 +00:00
|
|
|
$tw.utils.forceLayout(modalBackdrop);
|
|
|
|
$tw.utils.forceLayout(modalWrapper);
|
2012-10-26 09:28:32 +00:00
|
|
|
$tw.utils.setStyle(modalBackdrop,[
|
|
|
|
{opacity: "0"}
|
|
|
|
]);
|
|
|
|
$tw.utils.setStyle(modalWrapper,[
|
|
|
|
{transform: "translateY(" + window.innerHeight + "px)"}
|
|
|
|
]);
|
2012-07-18 10:45:17 +00:00
|
|
|
// Set up an event for the transition end
|
2013-08-29 11:43:24 +00:00
|
|
|
window.setTimeout(function() {
|
2012-07-18 10:45:17 +00:00
|
|
|
if(wrapper.parentNode) {
|
|
|
|
// Remove the modal message from the DOM
|
|
|
|
document.body.removeChild(wrapper);
|
|
|
|
}
|
2013-08-29 11:43:24 +00:00
|
|
|
},duration);
|
2013-02-04 15:29:25 +00:00
|
|
|
// Don't let anyone else handle the tw-close-tiddler message
|
2012-07-15 16:37:03 +00:00
|
|
|
return false;
|
2013-10-21 19:14:01 +00:00
|
|
|
};
|
|
|
|
headerWidgetNode.addEventListener("tw-close-tiddler",closeHandler,false);
|
|
|
|
bodyWidgetNode.addEventListener("tw-close-tiddler",closeHandler,false);
|
|
|
|
footerWidgetNode.addEventListener("tw-close-tiddler",closeHandler,false);
|
2012-07-17 17:28:47 +00:00
|
|
|
// Set the initial styles for the message
|
2012-10-26 09:28:32 +00:00
|
|
|
$tw.utils.setStyle(modalBackdrop,[
|
|
|
|
{opacity: "0"}
|
|
|
|
]);
|
|
|
|
$tw.utils.setStyle(modalWrapper,[
|
|
|
|
{transformOrigin: "0% 0%"},
|
|
|
|
{transform: "translateY(" + (-window.innerHeight) + "px)"}
|
|
|
|
]);
|
2012-07-16 11:57:44 +00:00
|
|
|
// Put the message into the document
|
2012-07-15 16:37:03 +00:00
|
|
|
document.body.appendChild(wrapper);
|
2012-07-18 10:45:17 +00:00
|
|
|
// Set up animation for the styles
|
2012-10-26 09:28:32 +00:00
|
|
|
$tw.utils.setStyle(modalBackdrop,[
|
2013-08-29 11:43:24 +00:00
|
|
|
{transition: "opacity " + duration + "ms ease-out"}
|
2012-10-26 09:28:32 +00:00
|
|
|
]);
|
|
|
|
$tw.utils.setStyle(modalWrapper,[
|
2013-08-28 14:15:56 +00:00
|
|
|
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms ease-in-out"}
|
2012-10-26 09:28:32 +00:00
|
|
|
]);
|
2012-07-18 10:45:17 +00:00
|
|
|
// Force layout
|
2012-08-02 21:32:34 +00:00
|
|
|
$tw.utils.forceLayout(modalBackdrop);
|
|
|
|
$tw.utils.forceLayout(modalWrapper);
|
2012-07-18 10:45:17 +00:00
|
|
|
// Set final animated styles
|
2012-10-26 09:28:32 +00:00
|
|
|
$tw.utils.setStyle(modalBackdrop,[
|
2013-02-10 18:44:00 +00:00
|
|
|
{opacity: "0.7"}
|
2012-10-26 09:28:32 +00:00
|
|
|
]);
|
|
|
|
$tw.utils.setStyle(modalWrapper,[
|
|
|
|
{transform: "translateY(0px)"}
|
|
|
|
]);
|
2012-07-15 16:37:03 +00:00
|
|
|
};
|
|
|
|
|
2013-06-04 15:19:47 +00:00
|
|
|
Modal.prototype.adjustPageClass = function() {
|
|
|
|
if($tw.pageContainer) {
|
|
|
|
$tw.utils.toggleClass($tw.pageContainer,"tw-modal-displayed",this.modalCount > 0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-07-15 16:37:03 +00:00
|
|
|
exports.Modal = Modal;
|
|
|
|
|
|
|
|
})();
|