From 0e48ab337bc89794af07745c7755bb6f4c468a3d Mon Sep 17 00:00:00 2001 From: Yoni Jah Date: Tue, 9 Apr 2019 11:13:45 +0800 Subject: [PATCH] Feature: safeAppend - Allow using full jQuery nodes in messages, titles and button labels - Everything else is treated as text --- src/bootbox.js | 19 +++++++--- tests/alert.test.js | 87 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/src/bootbox.js b/src/bootbox.js index 098f41cf..55dcc3d1 100644 --- a/src/bootbox.js +++ b/src/bootbox.js @@ -268,7 +268,7 @@ onEscape: options.onEscape }; - body.find('.bootbox-body').html(options.message); + safeAppend(body.find('.bootbox-body'), options.message); // Only attempt to create buttons if at least one has // been defined in the options object @@ -290,7 +290,7 @@ break; } - button.html(b.label); + safeAppend(button, b.label); footer.append(button); callbacks[key] = b.callback; @@ -347,7 +347,7 @@ if (options.title) { body.before(header); - dialog.find('.modal-title').html(options.title); + safeAppend(dialog.find('.modal-title'), options.title); } if (options.closeButton) { @@ -848,7 +848,7 @@ if ($.trim(options.message) !== '') { // Add the form to whatever content the user may have added. - var message = $(templates.promptMessage).html(options.message); + var message = safeAppend($(templates.promptMessage), options.message); form.prepend(message); options.message = form; } @@ -895,7 +895,7 @@ throw new Error('Invalid argument length'); } - if (argn === 2 || typeof args[0] === 'string') { + if (argn === 2 || typeof args[0] === 'string' || args[0] instanceof $) { options[properties[0]] = args[0]; options[properties[1]] = args[1]; } else { @@ -1007,6 +1007,15 @@ return labels ? labels[key] : locales.en[key]; } + // Append child to node + // Make sure child is an jQuery element otherwise add it as text node + function safeAppend (el, child) { + if (child instanceof $) { + el.append(child); + } else { + el.text(child); + } + } // Filter and tidy up any user supplied parameters to this dialog. diff --git a/tests/alert.test.js b/tests/alert.test.js index d722990a..3a00606e 100644 --- a/tests/alert.test.js +++ b/tests/alert.test.js @@ -9,6 +9,10 @@ describe('bootbox.alert', function() { return this.find(selector).text(); }; + this.html = function(selector) { + return this.find(selector).html(); + }; + this.find = function(selector) { return this.dialog.find(selector); }; @@ -69,6 +73,27 @@ describe('bootbox.alert', function() { expect($('body').hasClass('modal-open')).to.be.true; }); }); + + describe('where the argument is string containing html', function () { + beforeEach(function() { + this.dialog = bootbox.alert('Hello world!'); + }); + + it('shows the expected body parsing html to text', function() { + expect(this.text('.bootbox-body')).to.equal('Hello world!'); + }); + }); + + describe('where the argument containes jQuery node', function () { + beforeEach(function() { + this.dialog = bootbox.alert($('Hello world!')); + }); + + it('shows the expected body parsing the html to nodes', function() { + expect(this.text('.bootbox-body')).to.equal('Hello world!'); + expect(this.html('.bootbox-body')).to.equal('Hello world!'); + }); + }); }); describe('with two arguments', function() { @@ -143,6 +168,45 @@ describe('bootbox.alert', function() { }); }); + describe('with a custom ok button containing string html', function() { + beforeEach(function() { + this.options.buttons = { + ok: { + label: 'Custom OK', + className: 'btn-danger' + } + }; + + this.create(); + + this.button = this.dialog.find('.btn:first'); + }); + + it('adds the correct ok button', function() { + expect(this.button.text()).to.equal('Custom OK'); + }); + }); + + describe('with a custom ok button containing jQuery node', function() { + beforeEach(function() { + this.options.buttons = { + ok: { + label: $('Custom OK'), + className: 'btn-danger' + } + }; + + this.create(); + + this.button = this.dialog.find('.btn:first'); + }); + + it('adds the correct ok button', function() { + expect(this.button.text()).to.equal('Custom OK'); + expect(this.button.html()).to.equal('Custom OK'); + }); + }); + describe('with an unrecognised button key', function() { beforeEach(function() { this.options.buttons = { @@ -168,6 +232,29 @@ describe('bootbox.alert', function() { expect(this.text('.modal-title')).to.equal('Hello?'); }); }); + + describe('with a custom string title containing html', function() { + beforeEach(function() { + this.options.title = 'Hello?'; + this.create(); + }); + + it('shows the correct title', function() { + expect(this.text('.modal-title')).to.equal('Hello?'); + }); + }); + + describe('with a custom jQuery node title', function() { + beforeEach(function() { + this.options.title = $('Hello?'); + this.create(); + }); + + it('shows the correct title', function() { + expect(this.text('.modal-title')).to.equal('Hello?'); + expect(this.html('.modal-title')).to.equal('Hello?'); + }); + }); }); });