wed
Version:
Wed is a schema-aware editor for XML documents.
213 lines • 8.02 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "jquery", "./interactivity", "bootstrap"], function (require, exports, jquery_1, interactivity_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
jquery_1 = __importDefault(jquery_1);
/**
* A modal needs to be created only once per instance of wed. After creation it
* must be installed into the DOM tree of the page on which it is going to be
* used. The method [[Modal.getTopLevel]] must be used to get the top level DOM
* element of the modal which will be inserted into the page. Once inserted, the
* modal is ready to be used once, twice, or more times. It need not be removed,
* re-created, etc. The method [[Modal.modal]] just needs to be called each time
* the modal must be displayed.
*
* A typical usage scenario would be:
*
* <pre>
* // Modal setup.
* mymodal = new Modal();
* mymodal.setTitle("My modal");
* mymodal.setBody(...);
* mymodal.addYesNo();
* // This is a generic example of how to add the modal to a page.
* $("body").append(mymodal.getTopLevel());
*
* ...
*
* // Modal use
* mymodal.modal(function () {...});
* switch(mymodal.getClickedAsText()) {...}
*
* ...
*
* // A second use of the same modal
* mymodal.modal(function () {...});
* switch(mymodal.getClickedAsText()) {...}
* </pre>
*
* If the same modal must be displayed on two different pages, then two Modal
* objects should be created, one per page.
*/
class Modal {
constructor(options) {
options = options != null ? options : {};
// tabindex needed to make keyboard stuff work... grumble...
// https://github.com/twitter/bootstrap/issues/4663
// tslint:disable-next-line:no-jquery-raw-elements
const $dom = this._$dom = jquery_1.default("\
<div class=\"modal\" style=\"position: absolute\" tabindex=\"1\">\
<div class=\"modal-dialog\">\
<div class=\"modal-content\">\
<div class=\"modal-header\">\
<button type=\"button\" class=\"close\" data-dismiss=\"modal\" \
aria-hidden=\"true\">×</button>\
<h3 class=\"modal-title\">Untitled</h3>\
</div>\
<div class=\"modal-body\">\
<p>No body.</p>\
</div>\
<div class=\"modal-footer\">\
</div>\
</div>\
</div>\
</div>");
this._$header = $dom.find(".modal-header");
this._$body = $dom.find(".modal-body");
this._$footer = $dom.find(".modal-footer");
$dom.on("click", ".btn", (ev) => {
this._$clicked = jquery_1.default(ev.currentTarget);
return true;
});
$dom.on("shown.bs.modal.modal", this._handleShown.bind(this));
if (options.resizable) {
this._$body[0].style.overflow = "auto";
interactivity_1.makeResizable($dom);
}
if (options.draggable) {
interactivity_1.makeDraggable($dom);
}
}
/**
* @returns The top level node of the modal, to be inserted
* into a page.
*/
getTopLevel() {
return this._$dom;
}
/**
* Set the title of this modal.
*/
setTitle(title) {
const $h3 = this._$header.find("h3");
$h3.empty();
$h3.append(title);
}
/**
* Set the body of this modal.
*/
setBody(body) {
this._$body.empty();
this._$body.append(body);
}
/**
* Set the footer of this modal.
*/
setFooter(footer) {
this._$footer.empty();
this._$footer.append(footer);
}
/**
* @param name The name of the button.
*
* @param isPrimary True if the button is primary. A modal takes only one
* primary button but no check is made by this method to prevent it. The
* primary button is the one clicked if the user hits enter.
*
* @returns The jQuery object for the button.
*/
addButton(name, isPrimary = false) {
const button = this._$dom[0].ownerDocument.createElement("a");
button.href = "#";
button.className = "btn";
button.setAttribute("data-dismiss", "modal");
button.textContent = name;
button.classList.add(isPrimary ? "btn-primary" : "btn-default");
this._$footer.append(button);
return jquery_1.default(button);
}
/**
* Adds one Ok and one Cancel button.
*
* @returns The two buttons added.
*/
addOkCancel() {
return [this.addButton("Ok", true), this.addButton("Cancel")];
}
/**
* Adds one Yes and one No button.
*
* @returns The two buttons added.
*/
addYesNo() {
return [this.addButton("Yes", true), this.addButton("No")];
}
/**
* Returns the primary button.
*
* @returns The primary button.
*/
getPrimary() {
return this._$footer.find(".btn-primary");
}
/**
* @param callback A callback to call when the modal is dismissed by the
* user. This modal would typically inspect the modal to determine what the
* user did, and potentially clean up after itself. The callback is left out
* if the modal is merely for informational purposes.
*/
modal(callback) {
this._$clicked = undefined;
if (callback !== undefined) {
this._$dom.one("hidden.bs.modal.modal", callback);
}
this._$dom.modal();
}
/**
* @returns The button that was clicked. Could be undefined if the modal
* disappeared without being normally dismissed or if the modal has not been
* used yet.
*/
getClicked() {
return this._$clicked;
}
/**
* @returns The text of the button that was clicked. Could be undefined if the
* modal disappeared without being normally dismissed or if the modal has not
* been used yet.
*/
getClickedAsText() {
if (this._$clicked === undefined) {
return undefined;
}
return this._$clicked.text();
}
/**
* Handles the ``shown`` event.
*
* @param {Event} ev The DOM event.
*/
_handleShown() {
const win = this._$dom[0].ownerDocument.defaultView;
const winHeight = win.innerHeight;
const dialog = this._$dom.find(".modal-dialog")[0];
const rect = dialog.getBoundingClientRect();
const computedStyle = window.getComputedStyle(dialog);
const diff = -rect.top + (winHeight - rect.height) -
parseInt(computedStyle.marginBottom);
const dialogMaxHeight = rect.height + diff;
dialog.style.maxHeight = `${dialogMaxHeight}px`;
const content = this._$dom.find(".modal-content")[0];
content.style.maxHeight = `${dialogMaxHeight}px`;
}
}
exports.Modal = Modal;
});
// LocalWords: dialogMaxHeight clientY clientX resizemove dragmove setTimeout
// LocalWords: ignoreBackdropClick getBoundingClientRect resizeend tabindex
// LocalWords: getTopLevel btn param jQuery bs resizestart href jquery px pre
// LocalWords: mymodal setTitle setBody addYesNo rect getClickedAsText Dubeau
// LocalWords: MPL Mangalam DOM Ok
//# sourceMappingURL=modal.js.map