1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-02-07 22:50:02 +00:00

Modals: Display in source-window (#3539)

* Make modals display in source Window

this makes modals display within the window where they got opened, with the parameter `rootwindow` that, if `yes` or `true`, shows the modal always in the root TW window (`<$action-sendmessage $message="tm-modal" $param="mymodal" rootwindow="yes|true"/>`)

* pass the full event to $tw.modal.display

we need the event there to find `srcDocument` and `srcWindow`

* pass event in options object

* update modal.js to use options.event

* add docs for rootwindow tm-modal attribute
This commit is contained in:
BurningTreeC 2018-11-18 21:57:04 +01:00 committed by Jeremy Ruston
parent 3aae643e14
commit 33ba69e852
3 changed files with 32 additions and 26 deletions

View File

@ -23,7 +23,7 @@ exports.startup = function() {
// Install the modal message mechanism // Install the modal message mechanism
$tw.modal = new $tw.utils.Modal($tw.wiki); $tw.modal = new $tw.utils.Modal($tw.wiki);
$tw.rootWidget.addEventListener("tm-modal",function(event) { $tw.rootWidget.addEventListener("tm-modal",function(event) {
$tw.modal.display(event.param,{variables: event.paramObject}); $tw.modal.display(event.param,{variables: event.paramObject, event: event});
}); });
// Install the notification mechanism // Install the notification mechanism
$tw.notifier = new $tw.utils.Notifier($tw.wiki); $tw.notifier = new $tw.utils.Notifier($tw.wiki);

View File

@ -28,6 +28,10 @@ Options include:
*/ */
Modal.prototype.display = function(title,options) { Modal.prototype.display = function(title,options) {
options = options || {}; options = options || {};
this.srcDocument = options.variables && (options.variables.rootwindow === "true" ||
options.variables.rootwindow === "yes") ? document :
(options.event.event ? options.event.event.target.ownerDocument : document);
this.srcWindow = this.srcDocument.defaultView;
var self = this, var self = this,
refreshHandler, refreshHandler,
duration = $tw.utils.getAnimationDuration(), duration = $tw.utils.getAnimationDuration(),
@ -39,16 +43,16 @@ Modal.prototype.display = function(title,options) {
// Create the variables // Create the variables
var variables = $tw.utils.extend({currentTiddler: title},options.variables); var variables = $tw.utils.extend({currentTiddler: title},options.variables);
// Create the wrapper divs // Create the wrapper divs
var wrapper = document.createElement("div"), var wrapper = this.srcDocument.createElement("div"),
modalBackdrop = document.createElement("div"), modalBackdrop = this.srcDocument.createElement("div"),
modalWrapper = document.createElement("div"), modalWrapper = this.srcDocument.createElement("div"),
modalHeader = document.createElement("div"), modalHeader = this.srcDocument.createElement("div"),
headerTitle = document.createElement("h3"), headerTitle = this.srcDocument.createElement("h3"),
modalBody = document.createElement("div"), modalBody = this.srcDocument.createElement("div"),
modalLink = document.createElement("a"), modalLink = this.srcDocument.createElement("a"),
modalFooter = document.createElement("div"), modalFooter = this.srcDocument.createElement("div"),
modalFooterHelp = document.createElement("span"), modalFooterHelp = this.srcDocument.createElement("span"),
modalFooterButtons = document.createElement("span"); modalFooterButtons = this.srcDocument.createElement("span");
// Up the modal count and adjust the body class // Up the modal count and adjust the body class
this.modalCount++; this.modalCount++;
this.adjustPageClass(); this.adjustPageClass();
@ -80,7 +84,7 @@ Modal.prototype.display = function(title,options) {
value: title value: title
}}}], }}}],
parentWidget: $tw.rootWidget, parentWidget: $tw.rootWidget,
document: document, document: this.srcDocument,
variables: variables, variables: variables,
importPageMacros: true importPageMacros: true
}); });
@ -88,7 +92,7 @@ Modal.prototype.display = function(title,options) {
// Render the body of the message // Render the body of the message
var bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{ var bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{
parentWidget: $tw.rootWidget, parentWidget: $tw.rootWidget,
document: document, document: this.srcDocument,
variables: variables, variables: variables,
importPageMacros: true importPageMacros: true
}); });
@ -96,16 +100,16 @@ Modal.prototype.display = function(title,options) {
// Setup the link if present // Setup the link if present
if(options.downloadLink) { if(options.downloadLink) {
modalLink.href = options.downloadLink; modalLink.href = options.downloadLink;
modalLink.appendChild(document.createTextNode("Right-click to save changes")); modalLink.appendChild(this.srcDocument.createTextNode("Right-click to save changes"));
modalBody.appendChild(modalLink); modalBody.appendChild(modalLink);
} }
// Render the footer of the message // Render the footer of the message
if(tiddler && tiddler.fields && tiddler.fields.help) { if(tiddler && tiddler.fields && tiddler.fields.help) {
var link = document.createElement("a"); var link = this.srcDocument.createElement("a");
link.setAttribute("href",tiddler.fields.help); link.setAttribute("href",tiddler.fields.help);
link.setAttribute("target","_blank"); link.setAttribute("target","_blank");
link.setAttribute("rel","noopener noreferrer"); link.setAttribute("rel","noopener noreferrer");
link.appendChild(document.createTextNode("Help")); link.appendChild(this.srcDocument.createTextNode("Help"));
modalFooterHelp.appendChild(link); modalFooterHelp.appendChild(link);
modalFooterHelp.style.float = "left"; modalFooterHelp.style.float = "left";
} }
@ -129,7 +133,7 @@ Modal.prototype.display = function(title,options) {
}}} }}}
]}], ]}],
parentWidget: $tw.rootWidget, parentWidget: $tw.rootWidget,
document: document, document: this.srcDocument,
variables: variables, variables: variables,
importPageMacros: true importPageMacros: true
}); });
@ -155,13 +159,13 @@ Modal.prototype.display = function(title,options) {
{opacity: "0"} {opacity: "0"}
]); ]);
$tw.utils.setStyle(modalWrapper,[ $tw.utils.setStyle(modalWrapper,[
{transform: "translateY(" + window.innerHeight + "px)"} {transform: "translateY(" + self.srcWindow.innerHeight + "px)"}
]); ]);
// Set up an event for the transition end // Set up an event for the transition end
window.setTimeout(function() { self.srcWindow.setTimeout(function() {
if(wrapper.parentNode) { if(wrapper.parentNode) {
// Remove the modal message from the DOM // Remove the modal message from the DOM
document.body.removeChild(wrapper); self.srcDocument.body.removeChild(wrapper);
} }
},duration); },duration);
// Don't let anyone else handle the tm-close-tiddler message // Don't let anyone else handle the tm-close-tiddler message
@ -176,10 +180,10 @@ Modal.prototype.display = function(title,options) {
]); ]);
$tw.utils.setStyle(modalWrapper,[ $tw.utils.setStyle(modalWrapper,[
{transformOrigin: "0% 0%"}, {transformOrigin: "0% 0%"},
{transform: "translateY(" + (-window.innerHeight) + "px)"} {transform: "translateY(" + (-this.srcWindow.innerHeight) + "px)"}
]); ]);
// Put the message into the document // Put the message into the document
document.body.appendChild(wrapper); this.srcDocument.body.appendChild(wrapper);
// Set up animation for the styles // Set up animation for the styles
$tw.utils.setStyle(modalBackdrop,[ $tw.utils.setStyle(modalBackdrop,[
{transition: "opacity " + duration + "ms ease-out"} {transition: "opacity " + duration + "ms ease-out"}
@ -200,8 +204,9 @@ Modal.prototype.display = function(title,options) {
}; };
Modal.prototype.adjustPageClass = function() { Modal.prototype.adjustPageClass = function() {
if($tw.pageContainer) { var windowContainer = $tw.pageContainer ? ($tw.pageContainer === this.srcDocument.body.firstChild ? $tw.pageContainer : this.srcDocument.body.firstChild) : null;
$tw.utils.toggleClass($tw.pageContainer,"tc-modal-displayed",this.modalCount > 0); if(windowContainer) {
$tw.utils.toggleClass(windowContainer,"tc-modal-displayed",this.modalCount > 0);
} }
}; };

View File

@ -5,11 +5,10 @@ title: WidgetMessage: tm-modal
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
caption: tm-modal caption: tm-modal
The modal message displays a specified tiddler in a modal overlay that dims the main page. It requires the following properties on the `event` object:
|!Name |!Description | |!Name |!Description |
|param |Title of the tiddler to be displayed | |param |Title of the tiddler to be displayed |
|paramObject |Hashmap of variables to be provided to the modal | |paramObject |Hashmap of variables to be provided to the modal |
|rootwindow |<<.from-version 5.1.18>> ''yes'' or ''true'' will always display a modal in the wiki-root-window |
The "currentTiddler" variable is set to the title of the modal tiddler, but can be overridden by specifying a different value in `paramObject`. The "currentTiddler" variable is set to the title of the modal tiddler, but can be overridden by specifying a different value in `paramObject`.
@ -30,3 +29,5 @@ Your message:
Click me! Click me!
</$button>'/> </$button>'/>
<<.tip """<$macrocall $name=".from-version" version="5.1.18"/> if triggered from within a ''new window'', the above examples will be displayed within that window. The <$macrocall $name=".attr" _="rootwindow"/> attribute can be set to ''yes'' or ''true'' to inherit this behavior and to display the Modal within the ''root'' window""">>