Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Modals.setScrollbar() and Modals.resetScrollbar() to properly handle padding-right of body and fixed elements #18441

Merged
merged 2 commits into from
Apr 2, 2017

Conversation

deilv
Copy link
Contributor

@deilv deilv commented Dec 5, 2015

Fixes #18373, Fixes #20824, Fixes #21700, Fixes #21840 (duplicates)

The problem:

_setScrollbar() and _resetScrollbar() in file js/src/modal.js failed to properly adjust padding-right when opening and closing modals, while using fixed elements (ie fixed-top navbar). Both functions had to be rewritten.

Changes:

_setScrollbar() -- called when opening a modal

  • Store the original body padding-right in data-padding-right
  • Adjust the body padding-right according to the calculated _scrollbarWidth
  • Store the fixed element's original padding-right in data-padding-right
  • Adjust the element's padding-right according to the calculated _scrollbarWidth
  • Store the navbar-toggler's original margin-right in data-margin-right
  • Adjust the navbar-toggler's margin-right according to the calculated _scrollbarWidth

_resetScrollbar() -- called when closing a modal

  • Restore original body padding-right and remove the data attribute
  • Restore original fixed element's padding-right and remove the data attribute
  • Restore original navbar-toggler's margin-right and remove the data attribute

Unit Tests

  • Fixed missing modal-scrollbar-measure in modal unit tests
  • Fixed test for body padding adjustment
  • Added tests for fixed element padding adjustment
  • Added tests for navbar-toggler margin adjustment
  • Removed some unused tests from previous, incomplete patches

You can see the changes live in codepen.

@cvrebert
Copy link
Collaborator

cvrebert commented Dec 6, 2015

Travis is failing because some of your indentation is incorrect. See the output.

js/src/modal.js Outdated
// Adjust Fixed Content Padding
$(Selector.FIXED_CONTENT).map((index, element) => {
let fixedPadding = $(element).css('padding-right')
this._originalPadding[index] = fixedPadding
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Store the original padding in a data-* attribute on each element instead of in _originalPadding

@cvrebert
Copy link
Collaborator

cvrebert commented Dec 6, 2015

Comments should use sentence casing, not title casing.
E.g. // Adjust fixed content padding instead of // Adjust Fixed Content Padding

@cvrebert
Copy link
Collaborator

cvrebert commented Dec 6, 2015

Unit tests should be added to prevent future regressions. See https://github.com/twbs/bootstrap/blob/v4-dev/js/tests/README.md for info.

@deilv
Copy link
Contributor Author

deilv commented Dec 6, 2015

I still need to write some extra unit tests for the newly inserted data-* attributes. The pre-existing unit tests checked whether the body padding was properly changed and restored and they still work fine.

Also, if a script changes the dom while a modal is open, it can optionally remove the data-* attribute to prevent it from resetting after the modal is closed. Should we reference that somewhere?

@cvrebert
Copy link
Collaborator

cvrebert commented Dec 6, 2015

The pre-existing unit tests checked whether the body padding was properly changed and restored and they still work fine.

Yes, but it was getting changed to the wrong value. The unit tests ought to have detected that, so they're deficient in some respect.

Also, if a script changes the dom while a modal is open, it can optionally remove the data-* attribute to prevent it from resetting after the modal is closed. Should we reference that somewhere?

IMHO, no. I wouldn't call it a feature, and libraries which remove random data-* attributes do so at their own peril.

@deilv
Copy link
Contributor Author

deilv commented Dec 6, 2015

The unit tests only check whether the dom changes as expected; they don't care how it's done internally, which is why they don't fail after my modifications.

I will add tests for the data-* values, which will in practice also monitor the internal operations. Beyond that I think anything else would be overkill.

@deilv
Copy link
Contributor Author

deilv commented Dec 6, 2015

Added unit tests for body padding.

@mdo
Copy link
Member

mdo commented Nov 26, 2016

Would love a review of this if it's still valid, and possibly a rebase if it's good to go so we can merge.

/cc @cvrebert @Johann-S @bardiharborow

@bardiharborow
Copy link
Member

bardiharborow commented Nov 27, 2016

@mdo, rebase and squash, plus minor changes are at 9ea8274, however the following unit tests are failing. I'll need to review this further.

should have a paddingRight when the modal is taller than the viewport
should remove padding-right on modal after closing

@deilv, for future reference, parseFloat does not take a radix argument like parseInt does.

@deilv
Copy link
Contributor Author

deilv commented Nov 28, 2016

@bardiharborow thanks, I totally missed that. 9ea8274 looks good.

@mdo mdo added this to the v4.0.0-alpha.6 milestone Dec 29, 2016
@mdo mdo requested a review from bardiharborow January 4, 2017 03:49
@mdo
Copy link
Member

mdo commented Jan 4, 2017

@bardiharborow I took a look at this PR again and I'm unsure how to proceed. I see your 9ea8274 commit, but I don't know how to fetch that. You also mentioned reviewing this further. Any chance you can revisit this? Happy to help however I can to see it merged.

@mdo mdo modified the milestones: v4.0.0-alpha.6, v4.0.0-beta Jan 4, 2017
@deilv
Copy link
Contributor Author

deilv commented Jan 7, 2017

@mdo I can rebase and cleanup the PR, but I'm not sure how I can cleanly include @bardiharborow's commit for proper credit. Please advise.

@bardiharborow
Copy link
Member

@deilv oh don't worry about credit, it's not an issue. The main issue here is that the unit tests fail when I rebase this. If you could look into that and fix the issues, then we'll get this merged.

@deilv
Copy link
Contributor Author

deilv commented Jan 9, 2017

I will get this fixed asap

@deilv
Copy link
Contributor Author

deilv commented Jan 10, 2017

@cvrebert @bardiharborow Hm, this is weird. It's been over a year and now I can no longer replicate this issue. Either another commit or the upgrade to jquery3 seem to have fixed the issue. Can anyone verify?
http://codepen.io/deilv/pen/MJKbMv

@deilv
Copy link
Contributor Author

deilv commented Jan 12, 2017

Closing this PR as no longer relevant. Issue #18373 should probably be closed as well.

@deilv deilv closed this Jan 12, 2017
@pvdlg
Copy link
Contributor

pvdlg commented Jan 13, 2017

IT seems the issue is reproduced here #21700. Maybe this PR is still relevant?

@deilv deilv reopened this Jan 14, 2017
@deilv
Copy link
Contributor Author

deilv commented Jan 14, 2017

Indeed, when the body is large enough the issue still occurs. I will get this sorted.

@pvdlg
Copy link
Contributor

pvdlg commented Feb 6, 2017

I encountered the same issue with the unit test. Those tests do not work because .modal-scrollbar-measure is not present in the unit tests. That prevent the detection of the scrollbar to works.
See #21800 for my version of the fix.

@deilv
Copy link
Contributor Author

deilv commented Feb 6, 2017

@vanduynslagerp have you figured out why those two tests were needed in the first place?

@pvdlg
Copy link
Contributor

pvdlg commented Feb 6, 2017

The test are used to:

  • make sure a padding is added to the body when the modal is higher than the viewport
  • and to make sure it's removed when the modal is closed

It was added in PR #17536 even though, due to the absence of .modal-scrollbar-measure the tests were ineffective.

I kept those test in #21800 and I added the bootstrap css to the Qunit page so they now work properly. In addition I made the necessary change in the other unit test due to the presence of the bootstrap styles (ie. it fixed a test in tooltip as well).

You created the PR first, and I created one because there was no response on this thread for a while and it didn't pass the test at that time. Now that you're back, feel free to reuse the code from mine regarding the unit tests if you're interested and I'll close it to avoid the dupe.
Also the code in the modal plugin is a bit more efficient on #21800 (ie. using each instead of map, avoid calling JQuery on element twice in a row and a few other simplifications/optimizations).

@deilv
Copy link
Contributor Author

deilv commented Feb 6, 2017

IMHO each test should be individual of everything else and should only be linked to a specific part of code. That said adding a css file and modifying another test to keep things working is only looking for trouble next time someone makes a seemingly unrelated change. Thus I'd rather have those two tests removed and reviewed, so they can be written properly if needed. I'll wait to see what mdo thinks about this.

Note: the changes in the tests appear messy in the online editor, but they're actually quite straight. Two tests are added and two are removed.

@deilv
Copy link
Contributor Author

deilv commented Feb 7, 2017

Restored the removed tests and will spend some more time to rewrite them so they work properly. I also found that we need to include a fix for the collapse button which is also affected by the padding issue.

@deilv
Copy link
Contributor Author

deilv commented Feb 9, 2017

Ok, here is what happened so far. Commit 3af4560 was meant to fix #17399, and then commit c01fa6b added tests for those changes. As it turns out, the issue still exists and the tests don't even come close to what they intended to do (I'm amazed they didn't fail in the first place).

This PR completely rewrites the problematic modal functions, solving all padding issues and making both previous commits obsolete.

@pvdlg
Copy link
Contributor

pvdlg commented Feb 9, 2017

You still don't have any test that check the modified code works because the class .modal-scrollbar-measure is not present.
So the method _getScrollbarWidth will always returns 0 during the unit, and the scrollbar will never be detected.

@deilv
Copy link
Contributor Author

deilv commented Feb 9, 2017

@vanduynslagerp this PR is about fixing a padding issue, not adding a test for a private function. If you want to work on that on a separate PR, you're welcome. Please keep in mind that unit tests are meant to test the logic in javascript, so adding css in the mix may not be desired.

@mdo @bardiharborow Please review this and send me your feedback.

There still one issue to solve, but it's not an easy one. When using a fixed navbar, the absolutely positioned navbar-toggler button does not respect the parent's padding, so when the modal opens it moves to the right. I think a css solution is the most clean one, but I haven't found it yet. The alternative would be to have modal.js manipulate margin-right instead of padding-right, which solves all problems but the user may notice an empty strip under the scrollbar. Any ideas?

@pvdlg
Copy link
Contributor

pvdlg commented Feb 9, 2017

@vanduynslagerp this PR is about fixing a padding issue, not adding a test for a private function.

The fix of the padding issue is tested by the 2 unit tests that you removed.

Please keep in mind that unit tests are meant to test the logic in javascript, so adding css in the mix may not be desired.

The logic in javascript (in _getScrollbarWidth) depends on the css class .modal-scrollbar-measure. The Javascript create a div with this class to determine if there is a sidebar and if the padding has to be adjusted by measuring the width of the sidebar. You can't test if it works without the css class.

If you want to work on that on a separate PR, you're welcome.

I did: #21800

@deilv
Copy link
Contributor Author

deilv commented Feb 10, 2017

@vanduynslagerp this PR is about fixing a padding issue, not adding a test for a private function.

The fix of the padding issue is tested by the 2 unit tests that you removed.

Actually no, those 2 unit tests were related to a code change that I reversed and are no longer relevant. There are other tests in place already. Remember these are unit tests, they have a very specific scope.

Please keep in mind that unit tests are meant to test the logic in javascript, so adding css in the mix may not be desired.

The logic in javascript (in _getScrollbarWidth) depends on the css class .modal-scrollbar-measure. The Javascript create a div with this class to determine if there is a sidebar and if the padding has to be adjusted by measuring the width of the sidebar. You can't test if it works without the css class.

If you read the title, this PR has nothing to do with _getScrollbarWidth(). Each commit should focus on a very specific change, so it's easier to track issues in the future.

If you want to work on that on a separate PR, you're welcome.

I did: #21800

No you did not actually. You copied the code contributed by me and bardiharborow, and then rigged the tests to make them always succeed; since the code failed to add padding, you added it yourself and then checked if it was there. Really?

Please stop spamming this thread. Really, please.

@bardiharborow
Copy link
Member

Breathe.

@deilv, your prior comment seems to indicate that you take attribution fairly seriously. This is not in any way a problem.

@vanduynslagerp, understandably, the PR system is a little clunky and sometimes it is easier to just re-create a PR than to work with the existing PR owner. It isn't as much of a problem for me, as often the PR creator will have allowed edits from maintainers, but I do understand. Additionally, your PRs often cross several issues, which while quite common given the casual atmosphere of Bootstrap, is probably technically incorrect.

The combination of these things seems to have caused a bit of a dispute, and it is specifically why I'm quite paranoid about maintaining commit's author value when I do have to recreate PRs.

Now I'm not in a position to comment on the technical content of either PR, as I still haven't had the time to understand the actual issue it's fixing. I'm sorry about this, I've just been in the middle of some family issues.

Rest assured that the PR I end up merging will include correct attribution for whoever's code I end up using. Thank you for contributing to Bootstrap, and I hope that things will work smoothly from here. I'm reachable on Slack anytime, if you'd like to discuss any of this, or just Bootstrap in general.

Peace out. ❤️

@deilv
Copy link
Contributor Author

deilv commented Feb 16, 2017

Hi @bardiharborow and thank you for your comment. I hope your family issues are resolved soon.

Honestly, this isn't about credit. The comment was about your rights, for the work you did in commit 9ea8274. I couldn't care less who's name shows up in the merge. However, I really enjoy using bootstrap and I'm trying to do my part to keep code quality high.

Anyway, I still need some feedback on how to best solve the navbar-toggler padding issue. I already have a working solution in my codepen, but this will require existing users to add a navbar-wrapper around the button (which may not be a big issue while in alpha stage). The alternative is to adjust the button's position through javascript, like all other fixed elements. The first way is more elegant, the second is more hacky.

Please reply so I can push another commit with the complete solution.

PS. Edits from maintainers have been enabled for quite some time, feel free to play along.

@Johann-S can you please elaborate on whether the tests you added in c01fa6b are still relevant? The affected code has be completely replaced in this PR.

@deilv
Copy link
Contributor Author

deilv commented Feb 16, 2017

Updated the initial post of this PR. You can see all changes live in my codepen including the fixed navbar-toggler.

@Johann-S
Copy link
Member

@deilv my tests aren't relevant anymore 👍 you did great job

@deilv
Copy link
Contributor Author

deilv commented Feb 17, 2017

Updated commit to include the latest changes promised earlier. All tests pass. Everything looks good in all browsers I tested. I would like to do one more optimization pass and add some reference to navbar-wrapper in the docs. Some feedback would be great at this point.

@deilv
Copy link
Contributor Author

deilv commented Mar 11, 2017

Yet another update to this PR. When opening/closing a modal with the navbar-toggler present, its right margin is adjusted (instead of padding) which means it does not break compatibility (ie users won't have to change their code to add a parent div). More tests were added, too.

@bardiharborow Any chance you can have a look at this? It'd be shame to let it stall for another year.

@Johann-S
Copy link
Member

Hi @deilv, is it possible to you to update your branch ? And I'll review your PR asap thank you

@deilv
Copy link
Contributor Author

deilv commented Mar 31, 2017

@Johann-S The branch is now up-to-date, no conflicts. All tests pass locally.

@Johann-S Johann-S requested review from Johann-S and removed request for bardiharborow April 2, 2017 11:25
Copy link
Member

@Johann-S Johann-S left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @deilv everything is fine 👍

@Softmaker
Copy link

When opening a modal popup on a page with navbar fixed top, the page below the navbar still get wrong horizontal adjustment (padding) compared to the navbar above (Bootstrap v4.0.0-beta, IE 11, Windows 10).

Please see #22792

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants