From fc78d52c992b5f5d6d7a154a9b90a9341f558e3c Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 12 Oct 2021 02:22:36 +0300 Subject: [PATCH] modal: don't add margin & padding when sticky is not full width (Backports #30621) --- js/src/modal.js | 45 ++++++++++++++++++++---------------------- js/tests/unit/modal.js | 34 +++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/js/src/modal.js b/js/src/modal.js index a23bfc1ba6d0..d56424b82f65 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -477,40 +477,37 @@ class Modal { _setScrollbar() { if (this._isBodyOverflowing) { - // Note: DOMNode.style.paddingRight returns the actual value or '' if not set - // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set - const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)) - const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)) - // Adjust fixed content padding - $(fixedContent).each((index, element) => { - const actualPadding = element.style.paddingRight - const calculatedPadding = $(element).css('padding-right') - $(element) - .data('padding-right', actualPadding) - .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`) - }) + this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', 'padding-right', true) // Adjust sticky content margin - $(stickyContent).each((index, element) => { - const actualMargin = element.style.marginRight - const calculatedMargin = $(element).css('margin-right') - $(element) - .data('margin-right', actualMargin) - .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`) - }) + this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', 'margin-right', false) // Adjust body padding - const actualPadding = document.body.style.paddingRight - const calculatedPadding = $(document.body).css('padding-right') - $(document.body) - .data('padding-right', actualPadding) - .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`) + this._setElementAttributes('body', 'paddingRight', 'padding-right', true) } $(document.body).addClass(CLASS_NAME_OPEN) } + _setElementAttributes(selector, styleProp, jqCssProperty, add) { + // Note: DOMNode.style.paddingRight returns the actual value or '' if not set + // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set + const elements = [].slice.call(document.querySelectorAll(selector)) + $(elements).each((index, el) => { + if (el !== document.body && window.innerWidth > el.clientWidth + this._scrollbarWidth) { + return + } + + const actualValue = el.style[styleProp] + const calculatedValue = $(el).css(jqCssProperty) + const newValue = parseFloat(calculatedValue) + ((add ? 1 : -1) * this._scrollbarWidth) + $(el) + .data(jqCssProperty, actualValue) + .css(jqCssProperty, `${newValue}px`) + }) + } + _resetScrollbar() { // Restore fixed content padding const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)) diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js index 028ed5490ba1..683f8037ede0 100644 --- a/js/tests/unit/modal.js +++ b/js/tests/unit/modal.js @@ -162,6 +162,32 @@ $(function () { .bootstrapModal('toggle') }) + QUnit.test('should not adjust the inline margin and padding of sticky and fixed elements when element do not have full width', function (assert) { + assert.expect(2) + var done = assert.async() + var content = [ + '
', + '' + ].join('') + $(content).appendTo('#qunit-fixture') + + var stickyTopEl = $('.sticky-top') + var originalMargin = stickyTopEl.css('margin-right') + var originalPadding = stickyTopEl.css('padding-right') + + var modal = $('.modal') + modal.on('shown.bs.modal', function () { + var currentMargin = stickyTopEl.css('margin-right') + var currentPadding = stickyTopEl.css('padding-right') + + assert.strictEqual(currentMargin, originalMargin, 'sticky element\'s margin should not be adjusted while opening') + assert.strictEqual(currentPadding, originalPadding, 'sticky element\'s padding should not be adjusted while opening') + done() + }) + + modal.bootstrapModal('show') + }) + QUnit.test('should remove from dom when click [data-dismiss="modal"]', function (assert) { assert.expect(3) var done = assert.async() @@ -529,7 +555,9 @@ $(function () { done() }) .on('shown.bs.modal', function () { - assert.strictEqual($element.data('padding-right'), originalPadding, 'original fixed element padding should be stored in data-padding-right') + var dataPaddingRight = $element.data('padding-right') + var isCorrect = (dataPaddingRight === originalPadding || typeof dataPaddingRight === 'undefined') + assert.true(isCorrect, 'original fixed element padding should be stored in data-padding-right') $(this).bootstrapModal('hide') }) .bootstrapModal('show') @@ -571,7 +599,9 @@ $(function () { done() }) .on('shown.bs.modal', function () { - assert.strictEqual($element.data('margin-right'), originalPadding, 'original sticky element margin should be stored in data-margin-right') + var dataMarginRight = $element.data('margin-right') + var isCorrect = (dataMarginRight === originalPadding || typeof dataMarginRight === 'undefined') + assert.true(isCorrect, 'original sticky element margin should be stored in data-margin-right') $(this).bootstrapModal('hide') }) .bootstrapModal('show')