1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-13 00:54:04 +02:00

move util in a util folder with the sanitizer

This commit is contained in:
Johann-S
2019-02-23 00:37:55 +02:00
committed by XhmikosR
parent 8affe84c72
commit 8a37045b79
34 changed files with 559 additions and 589 deletions

View File

@@ -1,142 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Bootstrap Plugin Test Suite</title>
<!-- jQuery -->
<script src="../../node_modules/jquery/dist/jquery.slim.min.js"></script>
<script src="../../node_modules/popper.js/dist/umd/popper.min.js"></script>
<!-- QUnit -->
<link rel="stylesheet" href="../../node_modules/qunit/qunit/qunit.css" media="screen">
<script src="../../node_modules/qunit/qunit/qunit.js"></script>
<!-- Sinon -->
<script src="../../node_modules/sinon/pkg/sinon-no-sourcemaps.js"></script>
<!-- Hammer simulator -->
<script src="../../node_modules/hammer-simulator/index.js"></script>
<script>
// Disable jQuery event aliases to ensure we don't accidentally use any of them
[
'blur',
'focus',
'focusin',
'focusout',
'resize',
'scroll',
'click',
'dblclick',
'mousedown',
'mouseup',
'mousemove',
'mouseover',
'mouseout',
'mouseenter',
'mouseleave',
'change',
'select',
'submit',
'keydown',
'keypress',
'keyup',
'contextmenu'
].forEach(function(eventAlias) {
$.fn[eventAlias] = function() {
throw new Error('Using the ".' + eventAlias + '()" method is not allowed, so that Bootstrap can be compatible with custom jQuery builds which exclude the "event aliases" module that defines said method. See https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#js')
}
})
// Require assert.expect in each test
QUnit.config.requireExpects = true
// See https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit
var log = []
var testName
QUnit.done(function(testResults) {
var tests = []
for (var i = 0; i < log.length; i++) {
var details = log[i]
tests.push({
name: details.name,
result: details.result,
expected: details.expected,
actual: details.actual,
source: details.source
})
}
testResults.tests = tests
window.global_test_results = testResults
})
QUnit.testStart(function(testDetails) {
QUnit.log(function(details) {
if (!details.result) {
details.name = testDetails.name
log.push(details)
}
})
})
// Display fixture on-screen on iOS to avoid false positives
// See https://github.com/twbs/bootstrap/pull/15955
if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
QUnit.begin(function() {
$('#qunit-fixture').css({ top: 0, left: 0 })
})
QUnit.done(function() {
$('#qunit-fixture').css({ top: '', left: '' })
})
}
</script>
<!-- Transpiled Plugins -->
<script src="../dist/util.js"></script>
<script src="../dist/dom/polyfill.js"></script>
<script src="../dist/dom/manipulator.js"></script>
<script src="../dist/dom/eventHandler.js"></script>
<script src="../dist/dom/selectorEngine.js"></script>
<script src="../dist/dom/data.js"></script>
<script src="../dist/alert.js"></script>
<script src="../dist/button.js"></script>
<script src="../dist/carousel.js"></script>
<script src="../dist/collapse.js"></script>
<script src="../dist/dropdown.js"></script>
<script src="../dist/modal.js"></script>
<script src="../dist/scrollspy.js"></script>
<script src="../dist/tab.js"></script>
<script src="../dist/tooltip.js"></script>
<script src="../dist/popover.js"></script>
<script src="../dist/toast.js"></script>
<!-- Unit Tests -->
<script src="unit/dom/eventHandler.js"></script>
<script src="unit/dom/manipulator.js"></script>
<script src="unit/dom/data.js"></script>
<script src="unit/dom/selectorEngine.js"></script>
<script src="unit/alert.js"></script>
<script src="unit/button.js"></script>
<script src="unit/carousel.js"></script>
<script src="unit/collapse.js"></script>
<script src="unit/dropdown.js"></script>
<script src="unit/modal.js"></script>
<script src="unit/scrollspy.js"></script>
<script src="unit/tab.js"></script>
<script src="unit/tooltip.js"></script>
<script src="unit/popover.js"></script>
<script src="unit/util.js"></script>
<script src="unit/toast.js"></script>
</head>
<body>
<div id="qunit-container">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</div>
</body>
</html>

View File

@@ -2,8 +2,6 @@ import 'popper.js'
import bootstrap from '../../../dist/js/bootstrap'
window.addEventListener('load', () => {
document.getElementById('resultUID').innerHTML = bootstrap.Util.getUID('bs')
bootstrap.Util.makeArray(document.querySelectorAll('[data-toggle="tooltip"]'))
Array.from(document.querySelectorAll('[data-toggle="tooltip"]'))
.map((tooltipNode) => new bootstrap.Tooltip(tooltipNode))
})

View File

@@ -13,11 +13,7 @@
<body>
<div class="container">
<h1>Hello, world!</h1>
<div class="col-12">
<div class="mt-5 mb-3">
<span>Util.getUID: </span>
<span id="resultUID"></span>
</div>
<div class="col-12 mt-5">
<button type="button" class="btn btn-secondary" data-toggle="tooltip" data-placement="top" title="Tooltip on top">
Tooltip on top
</button>

View File

@@ -11,6 +11,7 @@ const {
const jqueryFile = process.env.USE_OLD_JQUERY ? 'https://code.jquery.com/jquery-1.9.1.min.js' : 'node_modules/jquery/dist/jquery.slim.min.js'
const bundle = process.env.BUNDLE === 'true'
const browserStack = process.env.BROWSER === 'true'
const debug = process.env.DEBUG === 'true'
const frameworks = [
'qunit',
@@ -28,11 +29,11 @@ const detectBrowsers = {
usePhantomJS: false,
postDetection(availableBrowser) {
if (typeof process.env.TRAVIS_JOB_ID !== 'undefined' || availableBrowser.includes('Chrome')) {
return ['ChromeHeadless']
return debug ? ['Chrome'] : ['ChromeHeadless']
}
if (availableBrowser.includes('Firefox')) {
return ['FirefoxHeadless']
return debug ? ['Firefox'] : ['FirefoxHeadless']
}
throw new Error('Please install Firefox or Chrome')
@@ -76,7 +77,8 @@ if (bundle) {
conf.detectBrowsers = detectBrowsers
files = files.concat([
jqueryFile,
'dist/js/bootstrap.js'
'dist/js/bootstrap.js',
'js/tests/unit/*.js'
])
} else if (browserStack) {
conf.hostname = ip.address()
@@ -93,7 +95,8 @@ if (bundle) {
reporters.push('BrowserStack')
files = files.concat([
'node_modules/jquery/dist/jquery.slim.min.js',
'js/coverage/dist/util.js',
'js/coverage/dist/util/util.js',
'js/coverage/dist/util/sanitizer.js',
'js/coverage/dist/dom/polyfill.js',
'js/coverage/dist/dom/eventHandler.js',
'js/coverage/dist/dom/selectorEngine.js',
@@ -103,7 +106,8 @@ if (bundle) {
'js/coverage/dist/tooltip.js',
'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js
'js/tests/unit/*.js',
'js/tests/unit/dom/*.js'
'js/tests/unit/dom/*.js',
'js/tests/unit/util/*.js'
])
} else {
frameworks.push('detectBrowsers')
@@ -115,7 +119,8 @@ if (bundle) {
)
files = files.concat([
jqueryFile,
'js/coverage/dist/util.js',
'js/coverage/dist/util/util.js',
'js/coverage/dist/util/sanitizer.js',
'js/coverage/dist/dom/polyfill.js',
'js/coverage/dist/dom/eventHandler.js',
'js/coverage/dist/dom/selectorEngine.js',
@@ -125,7 +130,8 @@ if (bundle) {
'js/coverage/dist/tooltip.js',
'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js
'js/tests/unit/*.js',
'js/tests/unit/dom/*.js'
'js/tests/unit/dom/*.js',
'js/tests/unit/util/*.js'
])
reporters.push('coverage-istanbul')
conf.customLaunchers = customLaunchers
@@ -153,9 +159,12 @@ if (bundle) {
}
}
}
}
files.push('js/tests/unit/*.js')
if (debug) {
conf.singleRun = false
conf.autoWatch = true
}
}
conf.frameworks = frameworks
conf.plugins = plugins

View File

@@ -8,6 +8,7 @@
"bootstrap": false,
"sinon": false,
"Util": false,
"Sanitizer": false,
"Data": false,
"Alert": false,
"Button": false,

View File

@@ -695,13 +695,10 @@ $(function () {
].join('')
var $modal = $(modalHTML).appendTo('#qunit-fixture')
var expectedTransitionDuration = 300
var spy = sinon.spy(Util, 'getTransitionDurationFromElement')
$modal.on('shown.bs.modal', function () {
assert.ok(spy.returned(expectedTransitionDuration))
$style.remove()
spy.restore()
assert.ok(true)
done()
})
.bootstrapModal('show')

View File

@@ -722,8 +722,10 @@ $(function () {
QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
assert.expect(1)
var fakeId = 1
var titleHtml = function () {
var uid = Util.getUID('tooltip')
var uid = fakeId
fakeId++
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
}
@@ -753,8 +755,10 @@ $(function () {
QUnit.test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function (assert) {
assert.expect(4)
var fakeId = 1
var titleHtml = function () {
var uid = Util.getUID('tooltip')
var uid = 'tooltip' + fakeId
fakeId++
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
}
@@ -1152,24 +1156,6 @@ $(function () {
assert.strictEqual(tooltip.config.template.indexOf('onError'), -1)
})
QUnit.test('should sanitize template by removing tags with XSS', function (assert) {
assert.expect(1)
var $trigger = $('<a href="#" rel="tooltip" data-trigger="click" title="Another tooltip"/>')
.appendTo('#qunit-fixture')
.bootstrapTooltip({
template: [
'<div>',
' <a href="javascript:alert(7)">Click me</a>',
' <span>Some content</span>',
'</div>'
].join('')
})
var tooltip = Tooltip._getInstance($trigger[0])
assert.strictEqual(tooltip.config.template.indexOf('script'), -1)
})
QUnit.test('should allow custom sanitization rules', function (assert) {
assert.expect(2)

View File

@@ -1,8 +1,6 @@
$(function () {
'use strict'
window.Util = typeof bootstrap !== 'undefined' ? bootstrap.Util : Util
QUnit.module('util', {
afterEach: function () {
$('#qunit-fixture').html('')

View File

@@ -0,0 +1,51 @@
$(function () {
'use strict'
QUnit.module('sanitizer', {
afterEach: function () {
$('#qunit-fixture').html('')
}
})
QUnit.test('should export a default white list', function (assert) {
assert.expect(1)
assert.ok(Sanitizer.DefaultWhitelist)
})
QUnit.test('should sanitize template by removing tags with XSS', function (assert) {
assert.expect(1)
var template = [
'<div>',
' <a href="javascript:alert(7)">Click me</a>',
' <span>Some content</span>',
'</div>'
].join('')
var result = Sanitizer.sanitizeHtml(template, Sanitizer.DefaultWhitelist, null)
assert.strictEqual(result.indexOf('script'), -1)
})
QUnit.test('should not use native api to sanitize if a custom function passed', function (assert) {
assert.expect(2)
var template = [
'<div>',
' <span>Some content</span>',
'</div>'
].join('')
function mySanitize(htmlUnsafe) {
return htmlUnsafe
}
var spy = sinon.spy(DOMParser.prototype, 'parseFromString')
var result = Sanitizer.sanitizeHtml(template, Sanitizer.DefaultWhitelist, mySanitize)
assert.strictEqual(result, template)
assert.strictEqual(spy.called, false)
spy.restore()
})
})

View File

@@ -60,13 +60,13 @@
<script src="../../dist/toast.js"></script>
<script>
window.addEventListener('load', function () {
Util.makeArray(document.querySelectorAll('.toast'))
Array.from(document.querySelectorAll('.toast'))
.forEach(function (toastNode) {
new Toast(toastNode)
})
document.getElementById('btnShowToast').addEventListener('click', function () {
Util.makeArray(document.querySelectorAll('.toast'))
Array.from(document.querySelectorAll('.toast'))
.forEach(function (toastNode) {
var toast = Toast._getInstance(toastNode)
toast.show()
@@ -74,7 +74,7 @@
})
document.getElementById('btnHideToast').addEventListener('click', function () {
Util.makeArray(document.querySelectorAll('.toast'))
Array.from(document.querySelectorAll('.toast'))
.forEach(function (toastNode) {
var toast = Toast._getInstance(toastNode)
toast.hide()