8f32e5baafe312051b78abf0059fff40be05b134
[yaffs-website] / web / themes / contrib / bootstrap / js / modal.js
1 /**
2  * @file
3  * Bootstrap Modals.
4  */
5 (function ($, Drupal, Bootstrap) {
6   "use strict";
7
8   /**
9    * Extend the Bootstrap Modal plugin constructor class.
10    */
11   Bootstrap.extendPlugin('modal', function (settings) {
12     return {
13       DEFAULTS: {
14         animation: !!settings.modal_animation,
15         backdrop: settings.modal_backdrop === 'static' ? 'static' : !!settings.modal_backdrop,
16         keyboard: !!settings.modal_keyboard,
17         show: !!settings.modal_show,
18         size: settings.modal_size
19       }
20     };
21   });
22
23   /**
24    * Replace the Bootstrap Modal jQuery plugin definition.
25    *
26    * Replacing this is needed so that the "option" method can return values.
27    */
28   Bootstrap.replacePlugin('modal', function () {
29     var Modal = this;
30
31     // Extract the arguments.
32     var args = Array.prototype.slice.call(arguments, 1);
33
34     // Modal jQuery Plugin Definition.
35     return function (option, _relatedTarget) {
36       var ret = void(0);
37       this.each(function () {
38         var $this   = $(this);
39         var data    = $this.data('bs.modal');
40         var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option);
41
42         if (!data) $this.data('bs.modal', (data = new Modal(this, options)));
43         if (typeof option == 'string') ret = data[option].apply(data, args);
44         else if (options.show) data.show(_relatedTarget);
45       });
46
47       // If just one element and there was a result returned for the option passed,
48       // then return the result. Otherwise, just return the jQuery object.
49       return this.length === 1 && ret !== void(0) ? ret : this;
50     }
51   });
52
53   /**
54    * Extend Drupal theming functions.
55    */
56   $.extend(Drupal.theme, /** @lend Drupal.theme */ {
57     /**
58      * Theme function for a Bootstrap Modal.
59      *
60      * @param {object}[variables]
61      *   An object with the following keys:
62      *   - title: The name of the tab.
63      *
64      * @return {string}
65      *   The HTML for the modal.
66      */
67     bootstrapModal: function (variables) {
68       var settings = drupalSettings.bootstrap || {};
69       var defaults = {
70         body: '',
71         closeButton: true,
72         description: {
73           content: null,
74           position: 'before'
75         },
76         footer: '',
77         id: 'drupal-modal',
78         size: settings.modal_size ? settings.modal_size : '',
79         title: Drupal.t('Loading...')
80       };
81       variables = $.extend(true, {}, defaults, variables);
82       var output = '';
83
84       // Build the modal wrapper.
85       var classes = ['modal'];
86       if (settings.modal_animation) {
87         classes.push('fade');
88       }
89       output += '<div id="' + variables.id + '" class="' + classes.join(' ') + '" tabindex="-1" role="dialog">';
90
91       // Build the modal-dialog wrapper.
92       var dialogClasses = ['modal-dialog'];
93       if (variables.size) {
94         // @todo This should really be a clean CSS class method instead.
95         dialogClasses.push(Drupal.checkPlain(variables.size));
96       }
97       output += '<div class="' + dialogClasses.join(' ') + '" role="document">';
98
99       // Build the modal-content wrapper.
100       output += '<div class="modal-content">';
101
102       // Build the header wrapper and title.
103       output += Drupal.theme.bootstrapModalHeader(variables.title, variables.closeButton);
104
105       // Build the body.
106       output += Drupal.theme.bootstrapModalBody(variables.id + '--body', variables.body, variables.description);
107
108       // Build the footer.
109       output += Drupal.theme.bootstrapModalFooter(variables.footer);
110
111       // Close the modal-content wrapper.
112       output += '</div>';
113
114       // Close the modal-dialog wrapper.
115       output += '</div>';
116
117       // Close the modal wrapper.
118       output += '</div>';
119
120       // Return the constructed modal.
121       return output;
122     },
123
124     /**
125      * Theme function for a Bootstrap Modal body markup.
126      *
127      * @param {string} id
128      *   A unique ID for the modal body div.
129      * @param {string} body
130      *   The HTML markup to place in the body.
131      * @param {string|object} description
132      *   A description to show. Can either be a string or an object with the
133      *   following key/value pairs:
134      *   - content: The description value.
135      *   - position: (optional) A display setting that can have these values:
136      *     - before: The description is displayed before the body. This is the
137      *       default value.
138      *     - after: The description is display after the body.
139      *     - invisible: The description is displayed after the element, hidden
140      *       visually but available to screen readers.
141      *
142      * @return {string}
143      *   The HTML for the modal close button.
144      */
145     bootstrapModalBody: function (id, body, description) {
146       var output = '';
147       output += '<div id="' + id + '" class="modal-body">';
148       if (!description || !$.isPlainObject(description)) {
149         description = { content: description};
150       }
151       description = $.extend({ position: 'before' }, description);
152
153       var descriptionClasses = ['help-block'];
154       if (description.content && description.position === 'invisible') {
155         descriptionClasses.push('sr-only');
156       }
157       if (description.content && description.position === 'before') {
158         output += '<p class="' + descriptionClasses.join(' ') + '">' + description.content + '</p>';
159       }
160       output += body;
161       if (description.content && (description.position === 'after' || description.position === 'invisible')) {
162         output += '<p class="' + descriptionClasses.join(' ') + '">' + description.content + '</p>';
163       }
164       output += '</div>';
165       return output;
166     },
167
168     /**
169      * Theme function for a Bootstrap Modal close button.
170      *
171      * @return {string}
172      *   The HTML for the modal close button.
173      */
174     bootstrapModalClose: function () {
175       return '<button type="button" class="close" data-dismiss="modal" aria-label="' + Drupal.t('Close') + '"><span aria-hidden="true">&times;</span></button>';
176     },
177
178     /**
179      * Theme function for a Bootstrap Modal footer.
180      *
181      * @param {string} [footer]
182      *   The HTML markup to place in the footer.
183      * @param {boolean} [force]
184      *   Flag to force the rendering of the footer.
185      *
186      * @return {string}
187      *   The HTML for the modal footer.
188      */
189     bootstrapModalFooter: function (footer, force) {
190       return footer || force ? '<div class="modal-footer">' + (footer || '') + '</div>' : '';
191     },
192
193     /**
194      * Theme function for a Bootstrap Modal header.
195      *
196      * @param {string} [title]
197      *   The title for the header.
198      * @param {boolean} [closeButton]
199      *   Flag indicating whether or not to show the close button in the header.
200      *
201      * @return {string}
202      *   The HTML for the modal header.
203      */
204     bootstrapModalHeader: function (title, closeButton) {
205       var output = '';
206       if (title) {
207         closeButton = closeButton !== void(0) ? closeButton : true;
208         output += '<div class="modal-header">';
209         if (closeButton) {
210           output += Drupal.theme.bootstrapModalClose();
211         }
212         output += '<h4 class="modal-title">' + Drupal.checkPlain(title) + '</h4>';
213         output += '</div>';
214       }
215       return output;
216     }
217   })
218
219 })(window.jQuery, window.Drupal, window.Drupal.bootstrap);