+
+ // Return the constructed modal.
+ return output;
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal dialog markup.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ *
+ * @return {string}
+ * The HTML for the modal close button.
+ */
+ bootstrapModalDialog: function (variables) {
+ var output = '';
+
+ var defaults = {
+ attributes: {
+ class: ['modal-dialog'],
+ role: 'document'
+ },
+ id: 'drupal-modal'
+ };
+ variables = $.extend(true, {}, defaults, variables);
+
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ attributes.set('id', attributes.get('id', variables.id + '--dialog'));
+
+ if (variables.size) {
+ attributes.addClass(variables.size);
+ }
+ output += '<div' + attributes + '>';
+
+ // Build the modal-content wrapper.
+ output += Drupal.theme('bootstrapModalContent', _.omit(variables, 'attributes'));
+
+ // Close the modal-dialog wrapper.
+ output += '</div>';
+ return output;
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal content markup.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ *
+ * @return {string}
+ * The HTML for the modal close button.
+ */
+ bootstrapModalContent: function (variables) {
+ var output = '';
+
+ var defaults = {
+ attributes: {
+ class: ['modal-content']
+ },
+ id: 'drupal-modal'
+ };
+ variables = $.extend(true, {}, defaults, variables);
+
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ attributes.set('id', attributes.get('id', variables.id + '--content'));
+
+ // Build the modal-content wrapper.
+ output += '<div' + attributes + '>';
+ variables = _.omit(variables, 'attributes');
+
+ // Build the header wrapper and title.
+ output += Drupal.theme('bootstrapModalHeader', variables);
+
+ // Build the body.
+ output += Drupal.theme('bootstrapModalBody', variables);
+
+ // Build the footer.
+ output += Drupal.theme('bootstrapModalFooter', variables);
+
+ // Close the modal-content wrapper.
+ output += '</div>';
+
+ return output;
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal body markup.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ *
+ * @return {string}
+ * The HTML for the modal close button.
+ */
+ bootstrapModalBody: function (variables) {
+ var output = '';
+
+ var defaults = {
+ attributes: {
+ class: ['modal-body']
+ },
+ body: '',
+ description: {
+ attributes: {
+ class: ['help-block']
+ },
+ content: null,
+ position: 'before'
+ },
+ id: 'drupal-modal'
+ };
+ variables = $.extend(true, {}, defaults, variables);
+
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ attributes.set('id', attributes.get('id', variables.id + '--body'));
+
+ output += '<div' + attributes + '>';
+
+ if (typeof variables.description === 'string') {
+ variables.description = $.extend({}, defaults.description, { content: variables.description });
+ }
+
+ var description = variables.description;
+ description.attributes = Attributes.create(defaults.description.attributes).merge(description.attributes);
+
+ if (description.content && description.position === 'invisible') {
+ description.attributes.addClass('sr-only');
+ }
+
+ if (description.content && description.position === 'before') {
+ output += '<p' + description.attributes + '>' + description.content + '</p>';
+ }
+
+ output += variables.body;
+
+ if (description.content && (description.position === 'after' || description.position === 'invisible')) {
+ output += '<p' + description.attributes + '>' + description.content + '</p>';
+ }
+
+ output += '</div>';
+
+ return output;
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal close button.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ *
+ * @return {string}
+ * The HTML for the modal close button.
+ */
+ bootstrapModalClose: function (variables) {
+ var defaults = {
+ attributes: {
+ 'aria-label': Drupal.t('Close'),
+ class: ['close'],
+ 'data-dismiss': 'modal',
+ type: 'button'
+ }
+ };
+ variables = $.extend(true, {}, defaults, variables);
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ return '<button' + attributes + '><span aria-hidden="true">×</span></button>';
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal footer.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ * @param {boolean} [force]
+ * Flag to force rendering the footer, regardless if there's content.
+ *
+ * @return {string}
+ * The HTML for the modal footer.
+ */
+ bootstrapModalFooter: function (variables, force) {
+ var output = '';
+ var defaults = {
+ attributes: {
+ class: ['modal-footer']
+ },
+ footer: '',
+ id: 'drupal-modal'
+ };
+
+ variables = $.extend(true, {}, defaults, variables);
+
+ if (force || variables.footer) {
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ attributes.set('id', attributes.get('id', variables.id + '--footer'));
+ output += '<div' + attributes + '>';
+ output += variables.footer;
+ output += '</div>';
+ }
+
+ return output;
+ },
+
+ /**
+ * Theme function for a Bootstrap Modal header.
+ *
+ * @param {Object} [variables]
+ * An object containing key/value pairs of variables.
+ *
+ * @return {string}
+ * The HTML for the modal header.
+ */
+ bootstrapModalHeader: function (variables) {
+ var output = '';
+
+ var defaults = {
+ attributes: {
+ class: ['modal-header']
+ },
+ closeButton: true,
+ id: 'drupal-modal',
+ title: {
+ attributes: {
+ class: ['modal-title']
+ },
+ content: Drupal.t('Loading...'),
+ html: false,
+ tag: 'h4'
+ }
+ };
+ variables = $.extend(true, {}, defaults, variables);
+
+ var title = variables.title;
+ if (title) {
+ var attributes = Attributes.create(defaults.attributes).merge(variables.attributes);
+ attributes.set('id', attributes.get('id', variables.id + '--header'));
+
+ if (typeof title === 'string') {
+ title = $.extend({}, defaults.title, { content: title });
+ }
+
+ output += '<div' + attributes + '>';
+
+ if (variables.closeButton) {
+ output += Drupal.theme('bootstrapModalClose', _.omit(variables, 'attributes'));
+ }
+
+ output += '<' + Drupal.checkPlain(title.tag) + Attributes.create(defaults.title.attributes).merge(title.attributes) + '>' + (title.html ? title.content : Drupal.checkPlain(title.content)) + '</' + Drupal.checkPlain(title.tag) + '>';
+
+ output += '</div>';
+ }
+
+ return output;