Skip to content

Commit

Permalink
Merge branch 'v4-dev' into v4-dev-xmr-docs-toggle-spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
XhmikosR committed Dec 28, 2018
2 parents 9c365fe + ee09d96 commit a7e8479
Show file tree
Hide file tree
Showing 35 changed files with 236 additions and 117 deletions.
9 changes: 8 additions & 1 deletion .stylelintrc
Expand Up @@ -261,7 +261,14 @@
"fill",
"stroke"
],
"property-blacklist": ["transition"],
"property-blacklist": [
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"transition"
],
"property-no-vendor-prefix": true,
"rule-empty-line-before": null,
"scss/at-function-named-arguments": "never",
Expand Down
1 change: 1 addition & 0 deletions _config.yml
Expand Up @@ -38,6 +38,7 @@ current_ruby_version: 4.2.1
docs_version: 4.2
repo: "https://github.com/twbs/bootstrap"
slack: "https://bootstrap-slack.herokuapp.com"
opencollective: "https://opencollective.com/bootstrap"
blog: "https://blog.getbootstrap.com"
expo: "https://expo.getbootstrap.com"
themes: "https://themes.getbootstrap.com"
Expand Down
6 changes: 5 additions & 1 deletion js/src/util.js
Expand Up @@ -82,7 +82,11 @@ const Util = {
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''
}

return selector && document.querySelector(selector) ? selector : null
try {
return document.querySelector(selector) ? selector : null
} catch (err) {
return null
}
},

getTransitionDurationFromElement(element) {
Expand Down
45 changes: 21 additions & 24 deletions js/tests/unit/modal.js
Expand Up @@ -619,40 +619,37 @@ $(function () {
assert.expect(1)
var done = assert.async()

try {
var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div id=&quot;modal-test&quot;&gt;&lt;div class=&quot;contents&quot;&lt;div&lt;div id=&quot;close&quot; data-dismiss=&quot;modal&quot;/&gt;&lt;/div&gt;&lt;/div&gt;"/>')
.appendTo('#qunit-fixture')
var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div id=&quot;modal-test&quot;&gt;&lt;div class=&quot;contents&quot;&lt;div&lt;div id=&quot;close&quot; data-dismiss=&quot;modal&quot;/&gt;&lt;/div&gt;&lt;/div&gt;"/>')
.appendTo('#qunit-fixture')

$toggleBtn.trigger('click')
} catch (e) {
$toggleBtn.trigger('click')
setTimeout(function () {
assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
done()
}
}, 0)
})

QUnit.test('should not execute js from target', function (assert) {
assert.expect(0)
var done = assert.async()

try {
// This toggle button contains XSS payload in its data-target
// Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
// a script element works in manual tests though, so here it is likely blocked by the qunit framework
var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div&gt;&lt;image src=&quot;missing.png&quot; onerror=&quot;$(&apos;#qunit-fixture button.control&apos;).trigger(&apos;click&apos;)&quot;&gt;&lt;/div&gt;"/>')
.appendTo('#qunit-fixture')
// The XSS payload above does not have a closure over this function and cannot access the assert object directly
// However, it can send a click event to the following control button, which will then fail the assert
$('<button>')
.addClass('control')
.on('click', function () {
assert.notOk(true, 'XSS payload is not executed as js')
})
.appendTo('#qunit-fixture')
// This toggle button contains XSS payload in its data-target
// Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
// a script element works in manual tests though, so here it is likely blocked by the qunit framework
var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div&gt;&lt;image src=&quot;missing.png&quot; onerror=&quot;$(&apos;#qunit-fixture button.control&apos;).trigger(&apos;click&apos;)&quot;&gt;&lt;/div&gt;"/>')
.appendTo('#qunit-fixture')
// The XSS payload above does not have a closure over this function and cannot access the assert object directly
// However, it can send a click event to the following control button, which will then fail the assert
$('<button>')
.addClass('control')
.on('click', function () {
assert.notOk(true, 'XSS payload is not executed as js')
})
.appendTo('#qunit-fixture')

$toggleBtn.trigger('click')
} catch (e) {
done()
}
$toggleBtn.trigger('click')

setTimeout(done, 500)
})

QUnit.test('should not try to open a modal which is already visible', function (assert) {
Expand Down
13 changes: 6 additions & 7 deletions js/tests/unit/util.js
Expand Up @@ -20,17 +20,16 @@ $(function () {
assert.strictEqual(Util.getSelectorFromElement($el2[0]), null)
})

QUnit.test('Util.getSelectorFromElement should throw error when there is a bad selector', function (assert) {
QUnit.test('Util.getSelectorFromElement should return null when there is a bad selector', function (assert) {
assert.expect(2)

var $el = $('<div data-target="#1"></div>').appendTo($('#qunit-fixture'))

try {
assert.ok(true, 'trying to use a bad selector')
Util.getSelectorFromElement($el[0])
} catch (e) {
assert.ok(e instanceof DOMException)
}
assert.strictEqual(Util.getSelectorFromElement($el[0]), null)

var $el2 = $('<a href="/posts"></a>').appendTo($('#qunit-fixture'))

assert.strictEqual(Util.getSelectorFromElement($el2[0]), null)
})

QUnit.test('Util.typeCheckConfig should thrown an error when a bad config is passed', function (assert) {
Expand Down
9 changes: 5 additions & 4 deletions nuget/MyGet.ps1
@@ -1,16 +1,17 @@
# set env vars usually set by MyGet (enable for local testing)
#$env:SourcesPath = '..'
#$env:NuGet = "./nuget.exe" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
#$env:NuGet = "./nuget.exe" # https://dist.nuget.org/win-x86-commandline/latest/nuget.exe

$nuget = $env:NuGet

Copy-Item $env:SourcesPath\LICENSE $env:SourcesPath\LICENSE.txt # has to be .txt extension, don't check in

# parse the version number out of package.json
$bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-'
$bsversion = $bsversionParts[0]

if ($bsversionParts.Length -gt 1)
{
$bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part
if ($bsversionParts.Length -gt 1) {
$bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part
}

# create packages
Expand Down
4 changes: 3 additions & 1 deletion nuget/bootstrap.nuspec
Expand Up @@ -12,7 +12,7 @@
<language>en-us</language>
<projectUrl>https://getbootstrap.com/</projectUrl>
<iconUrl>https://getbootstrap.com/docs/4.2/assets/img/favicons/apple-touch-icon.png</iconUrl>
<licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl>
<license type="file">LICENSE.txt</license>
<copyright>Copyright 2017-2018</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
Expand All @@ -22,6 +22,8 @@
<tags>css mobile-first responsive front-end framework web</tags>
</metadata>
<files>
<file src="LICENSE.txt" target="" />

<file src="dist\css\*.*" target="content\Content" />
<file src="dist\js\bootstrap*.js" target="content\Scripts" />
<file src="dist\js\bootstrap*.js.map" target="content\Scripts" />
Expand Down
4 changes: 3 additions & 1 deletion nuget/bootstrap.sass.nuspec
Expand Up @@ -12,7 +12,7 @@
<language>en-us</language>
<projectUrl>https://getbootstrap.com/</projectUrl>
<iconUrl>https://getbootstrap.com/docs/4.2/assets/img/favicons/apple-touch-icon.png</iconUrl>
<licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl>
<license type="file">LICENSE.txt</license>
<copyright>Copyright 2017-2018</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
Expand All @@ -22,6 +22,8 @@
<tags>css sass mobile-first responsive front-end framework web</tags>
</metadata>
<files>
<file src="LICENSE.txt" target="" />

<file src="scss\**\*.scss" target="content\Content\bootstrap" />
<file src="dist\js\bootstrap*.js" target="content\Scripts" />
<file src="dist\js\bootstrap*.js.map" target="content\Scripts" />
Expand Down
42 changes: 10 additions & 32 deletions scss/_card.scss
Expand Up @@ -195,55 +195,35 @@

// Handle rounded corners
@if $enable-rounded {
&:first-child {
&:not(:last-child) {
@include border-right-radius(0);

.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-right-radius: 0;
}
}

&:last-child {
&:not(:first-child) {
@include border-left-radius(0);

.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-left-radius: 0;
}
}

&:only-child {
@include border-radius($card-border-radius);

.card-img-top,
.card-header {
@include border-top-radius($card-border-radius);
}
.card-img-bottom,
.card-footer {
@include border-bottom-radius($card-border-radius);
}
}

&:not(:first-child):not(:last-child):not(:only-child) {
@include border-radius(0);

.card-img-top,
.card-img-bottom,
.card-header,
.card-footer {
@include border-radius(0);
}
}
}
}
}
Expand Down Expand Up @@ -283,24 +263,22 @@

&:not(:first-of-type) {
.card-header:first-child {
border-radius: 0;
@include border-radius(0);
}

&:not(:last-of-type) {
border-bottom: 0;
border-radius: 0;
@include border-radius(0);
}
}

&:first-of-type {
border-bottom: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
@include border-bottom-radius(0);
}

&:last-of-type {
border-top-left-radius: 0;
border-top-right-radius: 0;
@include border-top-radius(0);
}

.card-header {
Expand Down
9 changes: 4 additions & 5 deletions scss/_custom-forms.scss
Expand Up @@ -144,6 +144,7 @@

.custom-radio {
.custom-control-label::before {
// stylelint-disable-next-line property-blacklist
border-radius: $custom-radio-indicator-border-radius;
}

Expand Down Expand Up @@ -173,6 +174,7 @@
left: -($custom-switch-width + $custom-control-gutter);
width: $custom-switch-width;
pointer-events: all;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
}

Expand All @@ -182,6 +184,7 @@
width: $custom-switch-indicator-size;
height: $custom-switch-indicator-size;
background-color: $custom-control-indicator-border-color;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
@include transition(transform .15s ease-in-out, $custom-forms-transition);
}
Expand Down Expand Up @@ -220,11 +223,7 @@
background: $custom-select-background;
background-color: $custom-select-bg;
border: $custom-select-border-width solid $custom-select-border-color;
@if $enable-rounded {
border-radius: $custom-select-border-radius;
} @else {
border-radius: 0;
}
@include border-radius($custom-select-border-radius, 0);
@include box-shadow($custom-select-box-shadow);
appearance: none;

Expand Down
8 changes: 1 addition & 7 deletions scss/_forms.scss
Expand Up @@ -18,13 +18,7 @@
border: $input-border-width solid $input-border-color;

// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@if $enable-rounded {
// Manually use the if/else instead of the mixin to account for iOS override
border-radius: $input-border-radius;
} @else {
// Otherwise undo the iOS default
border-radius: 0;
}
@include border-radius($input-border-radius, 0);

@include box-shadow($input-box-shadow);
@include transition($input-transition);
Expand Down
3 changes: 2 additions & 1 deletion scss/_reboot.scss
Expand Up @@ -297,6 +297,7 @@ label {
//
// Details at https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-blacklist
border-radius: 0;
}

Expand Down Expand Up @@ -421,7 +422,7 @@ progress {
}

//
// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
// Remove the inner padding in Chrome and Safari on macOS.
//

[type="search"]::-webkit-search-decoration {
Expand Down
2 changes: 2 additions & 0 deletions scss/_spinners.scss
Expand Up @@ -13,6 +13,7 @@
vertical-align: text-bottom;
border: $spinner-border-width solid currentColor;
border-right-color: transparent;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
animation: spinner-border .75s linear infinite;
}
Expand Down Expand Up @@ -42,6 +43,7 @@
height: $spinner-height;
vertical-align: text-bottom;
background-color: currentColor;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
opacity: 0;
animation: spinner-grow .75s linear infinite;
Expand Down
1 change: 1 addition & 0 deletions scss/_utilities.scss
Expand Up @@ -11,6 +11,7 @@
@import "utilities/screenreaders";
@import "utilities/shadows";
@import "utilities/sizing";
@import "utilities/stretched-link";
@import "utilities/spacing";
@import "utilities/text";
@import "utilities/visibility";
4 changes: 2 additions & 2 deletions scss/_variables.scss
Expand Up @@ -264,7 +264,7 @@ $embed-responsive-aspect-ratios: join(
(
(21 9),
(16 9),
(3 4),
(4 3),
(1 1),
),
$embed-responsive-aspect-ratios
Expand Down Expand Up @@ -652,7 +652,7 @@ $form-feedback-invalid-color: theme-color("danger") !default;
$form-feedback-icon-valid-color: $form-feedback-valid-color !default;
$form-feedback-icon-valid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;
$form-feedback-icon-invalid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E"), "#", "%23") !default;
$form-feedback-icon-invalid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3e%3cpath stroke='#{$form-feedback-icon-invalid-color}' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E"), "#", "%23") !default;


// Z-index master list
Expand Down
6 changes: 5 additions & 1 deletion scss/mixins/_border-radius.scss
@@ -1,9 +1,13 @@
// stylelint-disable property-blacklist
// Single side border-radius

@mixin border-radius($radius: $border-radius) {
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
@if $enable-rounded {
border-radius: $radius;
}
@else if $fallback-border-radius != false {
border-radius: $fallback-border-radius;
}
}

@mixin border-top-radius($radius) {
Expand Down

0 comments on commit a7e8479

Please sign in to comment.