assets/javascripts/bootstrap.js in bootstrap-4.3.0 vs assets/javascripts/bootstrap.js in bootstrap-4.3.1

- old
+ new

@@ -1,7 +1,7 @@ /*! - * Bootstrap v4.3.0 (https://getbootstrap.com/) + * Bootstrap v4.3.1 (https://getbootstrap.com/) * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) : @@ -68,11 +68,11 @@ subClass.__proto__ = superClass; } /** * -------------------------------------------------------------------------- - * Bootstrap (v4.3.0): util.js + * Bootstrap (v4.3.1): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ @@ -228,11 +228,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME = 'alert'; - var VERSION = '4.3.0'; + var VERSION = '4.3.1'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; var JQUERY_NO_CONFLICT = $.fn[NAME]; var Selector = { @@ -393,11 +393,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$1 = 'button'; - var VERSION$1 = '4.3.0'; + var VERSION$1 = '4.3.1'; var DATA_KEY$1 = 'bs.button'; var EVENT_KEY$1 = "." + DATA_KEY$1; var DATA_API_KEY$1 = '.data-api'; var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1]; var ClassName$1 = { @@ -547,11 +547,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$2 = 'carousel'; - var VERSION$2 = '4.3.0'; + var VERSION$2 = '4.3.1'; var DATA_KEY$2 = 'bs.carousel'; var EVENT_KEY$2 = "." + DATA_KEY$2; var DATA_API_KEY$2 = '.data-api'; var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2]; var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key @@ -1147,11 +1147,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$3 = 'collapse'; - var VERSION$3 = '4.3.0'; + var VERSION$3 = '4.3.1'; var DATA_KEY$3 = 'bs.collapse'; var EVENT_KEY$3 = "." + DATA_KEY$3; var DATA_API_KEY$3 = '.data-api'; var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3]; var Default$1 = { @@ -1507,11 +1507,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$4 = 'dropdown'; - var VERSION$4 = '4.3.0'; + var VERSION$4 = '4.3.1'; var DATA_KEY$4 = 'bs.dropdown'; var EVENT_KEY$4 = "." + DATA_KEY$4; var DATA_API_KEY$4 = '.data-api'; var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4]; var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key @@ -2033,11 +2033,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$5 = 'modal'; - var VERSION$5 = '4.3.0'; + var VERSION$5 = '4.3.1'; var DATA_KEY$5 = 'bs.modal'; var EVENT_KEY$5 = "." + DATA_KEY$5; var DATA_API_KEY$5 = '.data-api'; var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5]; var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key @@ -2609,22 +2609,144 @@ $.fn[NAME$5] = JQUERY_NO_CONFLICT$5; return Modal._jQueryInterface; }; /** + * -------------------------------------------------------------------------- + * Bootstrap (v4.3.1): tools/sanitizer.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + }; + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; + + function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase(); + + if (allowedAttributeList.indexOf(attrName) !== -1) { + if (uriAttrs.indexOf(attrName) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); + } + + return true; + } + + var regExp = allowedAttributeList.filter(function (attrRegex) { + return attrRegex instanceof RegExp; + }); // Check if a regular expression validates the attribute. + + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true; + } + } + + return false; + } + + function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { + if (unsafeHtml.length === 0) { + return unsafeHtml; + } + + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeHtml); + } + + var domParser = new window.DOMParser(); + var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); + var whitelistKeys = Object.keys(whiteList); + var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); + + var _loop = function _loop(i, len) { + var el = elements[i]; + var elName = el.nodeName.toLowerCase(); + + if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { + el.parentNode.removeChild(el); + return "continue"; + } + + var attributeList = [].slice.call(el.attributes); + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + attributeList.forEach(function (attr) { + if (!allowedAttribute(attr, whitelistedAttributes)) { + el.removeAttribute(attr.nodeName); + } + }); + }; + + for (var i = 0, len = elements.length; i < len; i++) { + var _ret = _loop(i, len); + + if (_ret === "continue") continue; + } + + return createdDocument.body.innerHTML; + } + + /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ var NAME$6 = 'tooltip'; - var VERSION$6 = '4.3.0'; + var VERSION$6 = '4.3.1'; var DATA_KEY$6 = 'bs.tooltip'; var EVENT_KEY$6 = "." + DATA_KEY$6; var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6]; var CLASS_PREFIX = 'bs-tooltip'; var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; var DefaultType$4 = { animation: 'boolean', template: 'string', title: '(string|element|function)', trigger: 'string', @@ -2633,11 +2755,14 @@ selector: '(string|boolean)', placement: '(string|function)', offset: '(number|string|function)', container: '(string|element|boolean)', fallbackPlacement: '(string|array)', - boundary: '(string|element)' + boundary: '(string|element)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + whiteList: 'object' }; var AttachmentMap$1 = { AUTO: 'auto', TOP: 'top', RIGHT: 'right', @@ -2654,11 +2779,14 @@ selector: false, placement: 'top', offset: 0, container: false, fallbackPlacement: 'flip', - boundary: 'scrollParent' + boundary: 'scrollParent', + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist }; var HoverState = { SHOW: 'show', OUT: 'out' }; @@ -2971,23 +3099,31 @@ this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle()); $(tip).removeClass(ClassName$6.FADE + " " + ClassName$6.SHOW); }; _proto.setElementContent = function setElementContent($element, content) { - var html = this.config.html; - if (typeof content === 'object' && (content.nodeType || content.jquery)) { // Content is a DOM node or a jQuery - if (html) { + if (this.config.html) { if (!$(content).parent().is($element)) { $element.empty().append(content); } } else { $element.text($(content).text()); } + + return; + } + + if (this.config.html) { + if (this.config.sanitize) { + content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); + } + + $element.html(content); } else { - $element[html ? 'html' : 'text'](content); + $element.text(content); } }; _proto.getTitle = function getTitle() { var title = this.element.getAttribute('data-original-title'); @@ -3151,11 +3287,17 @@ return false; }; _proto._getConfig = function _getConfig(config) { - config = _objectSpread({}, this.constructor.Default, $(this.element).data(), typeof config === 'object' && config ? config : {}); + var dataAttributes = $(this.element).data(); + Object.keys(dataAttributes).forEach(function (dataAttr) { + if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { + delete dataAttributes[dataAttr]; + } + }); + config = _objectSpread({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {}); if (typeof config.delay === 'number') { config.delay = { show: config.delay, hide: config.delay @@ -3169,10 +3311,15 @@ if (typeof config.content === 'number') { config.content = config.content.toString(); } Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType); + + if (config.sanitize) { + config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); + } + return config; }; _proto._getDelegateConfig = function _getDelegateConfig() { var config = {}; @@ -3306,11 +3453,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$7 = 'popover'; - var VERSION$7 = '4.3.0'; + var VERSION$7 = '4.3.1'; var DATA_KEY$7 = 'bs.popover'; var EVENT_KEY$7 = "." + DATA_KEY$7; var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7]; var CLASS_PREFIX$1 = 'bs-popover'; var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g'); @@ -3493,11 +3640,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$8 = 'scrollspy'; - var VERSION$8 = '4.3.0'; + var VERSION$8 = '4.3.1'; var DATA_KEY$8 = 'bs.scrollspy'; var EVENT_KEY$8 = "." + DATA_KEY$8; var DATA_API_KEY$6 = '.data-api'; var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8]; var Default$6 = { @@ -3800,11 +3947,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$9 = 'tab'; - var VERSION$9 = '4.3.0'; + var VERSION$9 = '4.3.1'; var DATA_KEY$9 = 'bs.tab'; var EVENT_KEY$9 = "." + DATA_KEY$9; var DATA_API_KEY$7 = '.data-api'; var JQUERY_NO_CONFLICT$9 = $.fn[NAME$9]; var Event$9 = { @@ -4035,11 +4182,11 @@ * Constants * ------------------------------------------------------------------------ */ var NAME$a = 'toast'; - var VERSION$a = '4.3.0'; + var VERSION$a = '4.3.1'; var DATA_KEY$a = 'bs.toast'; var EVENT_KEY$a = "." + DATA_KEY$a; var JQUERY_NO_CONFLICT$a = $.fn[NAME$a]; var Event$a = { CLICK_DISMISS: "click.dismiss" + EVENT_KEY$a, @@ -4245,10 +4392,10 @@ return Toast._jQueryInterface; }; /** * -------------------------------------------------------------------------- - * Bootstrap (v4.3.0): index.js + * Bootstrap (v4.3.1): index.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ (function () {