diff --git a/js/src/alert.js b/js/src/alert.js index ab36a8d36383a5e12eca883f469f4f32a2844411..87209a86088e6391938f10bc9005fef2021f522c 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -5,7 +5,9 @@ * -------------------------------------------------------------------------- */ -import $ from 'jquery' +import Data from './dom/data' +import EventHandler from './dom/eventHandler' +import SelectorEngine from './dom/selectorEngine' import Util from './util' /** @@ -64,7 +66,7 @@ class Alert { const customEvent = this._triggerCloseEvent(rootElement) - if (customEvent.isDefaultPrevented()) { + if (customEvent.defaultPrevented) { return } @@ -72,7 +74,7 @@ class Alert { } dispose() { - $.removeData(this._element, DATA_KEY) + Data.removeData(this._element, DATA_KEY) this._element = null } @@ -87,52 +89,45 @@ class Alert { } if (!parent) { - parent = $(element).closest(`.${ClassName.ALERT}`)[0] + parent = SelectorEngine.closest(element, `.${ClassName.ALERT}`) } return parent } _triggerCloseEvent(element) { - const closeEvent = $.Event(Event.CLOSE) - - $(element).trigger(closeEvent) - return closeEvent + return EventHandler.trigger(element, Event.CLOSE) } _removeElement(element) { - $(element).removeClass(ClassName.SHOW) + element.classList.remove(ClassName.SHOW) - if (!$(element).hasClass(ClassName.FADE)) { + if (!element.classList.contains(ClassName.FADE)) { this._destroyElement(element) return } const transitionDuration = Util.getTransitionDurationFromElement(element) - $(element) - .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event)) - - Util.emulateTransitionEnd(transitionDuration) + EventHandler + .one(element, Util.TRANSITION_END, (event) => this._destroyElement(element, event)) + Util.emulateTransitionEnd(element, transitionDuration) } _destroyElement(element) { - $(element) - .detach() - .trigger(Event.CLOSED) - .remove() + EventHandler.trigger(element, Event.CLOSED) + element.parentNode.removeChild(element) } // Static static _jQueryInterface(config) { return this.each(function () { - const $element = $(this) - let data = $element.data(DATA_KEY) + let data = Data.getData(this, DATA_KEY) if (!data) { data = new Alert(this) - $element.data(DATA_KEY, data) + Data.setData(this, DATA_KEY, data) } if (config === 'close') { diff --git a/js/src/dom/data.js b/js/src/dom/data.js new file mode 100644 index 0000000000000000000000000000000000000000..bbe807aac1e10770406531996813cf36d69a8cfc --- /dev/null +++ b/js/src/dom/data.js @@ -0,0 +1,51 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-beta): dom/data.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const mapData = (() => { + const storeData = {} + return { + set(element, key, data) { + let id + if (element.key === undefined) { + element.key = { + key, + id + } + } + + storeData[id] = data + }, + get(element, key) { + if (element.key === undefined || element.key !== key) { + return null + } + const keyProperties = element.key + return storeData[keyProperties.id] + }, + delete(element, key) { + if (element.key === undefined || element.key !== key) { + return + } + const keyProperties = element.key + delete storeData[keyProperties.id] + } + } +})() + +const Data = { + setData(instance, key, data) { + mapData.set(instance, key, data) + }, + getData(instance, key) { + mapData.get(instance, key) + }, + removeData(instance, key) { + mapData.delete(instance, key) + } +} + +export default Data diff --git a/js/src/dom/event.js b/js/src/dom/eventHandler.js similarity index 68% rename from js/src/dom/event.js rename to js/src/dom/eventHandler.js index 5968e62e0ff760564ee26878c16fadc5be995d39..0627ccd26864cc41edf06ec11ca22de59a6e327e 100644 --- a/js/src/dom/event.js +++ b/js/src/dom/eventHandler.js @@ -1,13 +1,13 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-beta): dom/event.js + * Bootstrap (v4.0.0-beta): dom/eventHandler.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -const Event = { +const EventHandler = { on(element, event, handler) { - if (typeof event !== 'string') { + if (typeof event !== 'string' || typeof element === 'undefined') { return } element.addEventListener(event, handler, false) @@ -19,12 +19,12 @@ const Event = { handler() element.removeEventListener(event, complete, false) } - Event.on(element, event, complete) + EventHandler.on(element, event, complete) }, trigger(element, event) { - if (typeof event !== 'string') { - return + if (typeof event !== 'string' || typeof element === 'undefined') { + return null } const eventToDispatch = new CustomEvent(event, { @@ -32,7 +32,9 @@ const Event = { cancelable: true }) element.dispatchEvent(eventToDispatch) + + return eventToDispatch } } -export default Event +export default EventHandler diff --git a/js/src/dom/selectorEngine.js b/js/src/dom/selectorEngine.js new file mode 100644 index 0000000000000000000000000000000000000000..f6bcf6da265bd9aa81397112b602ee6b6ff31805 --- /dev/null +++ b/js/src/dom/selectorEngine.js @@ -0,0 +1,42 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-beta): dom/selectorEngine.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const SelectorEngine = { + matches: Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector, + + find(selector) { + if (typeof selector !== 'string') { + return null + } + + let selectorType = 'querySelectorAll' + if (selector.indexOf('#') === 0) { + selectorType = 'getElementById' + selector = selector.substr(1, selector.length) + } + return document[selectorType](selector) + }, + + closest(element, selector) { + let ancestor = element + if (!document.documentElement.contains(element)) { + return null + } + + do { + if (SelectorEngine.matches.call(ancestor, selector)) { + return ancestor + } + + ancestor = ancestor.parentElement + } while (ancestor !== null) + + return null + } +} + +export default SelectorEngine diff --git a/js/src/util.js b/js/src/util.js index 2ffdec999bd4518d0a0bda5b9c96b4717f83b3af..b5efeca14e0afcc3ee6ea60fb8b4fa6a58e8b31f 100644 --- a/js/src/util.js +++ b/js/src/util.js @@ -5,7 +5,7 @@ * -------------------------------------------------------------------------- */ -import Event from './dom/event' +import EventHandler from './dom/eventHandler' /** * ------------------------------------------------------------------------ @@ -78,7 +78,7 @@ const Util = { }, triggerTransitionEnd(element) { - Event.trigger(element, Util.TRANSITION_END) + EventHandler.trigger(element, Util.TRANSITION_END) }, // TODO: Remove in v5 diff --git a/js/tests/index.html b/js/tests/index.html index a3fd937c2dbbdc0fd37eac8b55a25c527dc3b967..db0743f0ffe069dc572bbb0a7c82830c74125672 100644 --- a/js/tests/index.html +++ b/js/tests/index.html @@ -97,7 +97,9 @@ </script> <!-- Transpiled Plugins --> - <script src="../dist/dom/event.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/util.js"></script> <script src="../dist/alert.js"></script> <script src="../dist/button.js"></script> diff --git a/js/tests/unit/.eslintrc.json b/js/tests/unit/.eslintrc.json index 86d851ad06d0aa8bc7c37f92aef102a01bae95b9..b07efd269d17026d767beb10cc6c6d2777796d7b 100644 --- a/js/tests/unit/.eslintrc.json +++ b/js/tests/unit/.eslintrc.json @@ -12,7 +12,8 @@ "Button": false, "Carousel": false, "Simulator": false, - "Toast": false + "Toast": false, + "EventHandler": false }, "parserOptions": { "ecmaVersion": 5, diff --git a/js/tests/unit/alert.js b/js/tests/unit/alert.js index 65a8f9e76754385d004e1cf781d85ead91fa48ef..32fcc6ceaf7235f9dbba10ba3af59d79e54613d8 100644 --- a/js/tests/unit/alert.js +++ b/js/tests/unit/alert.js @@ -70,16 +70,19 @@ $(function () { QUnit.test('should not fire closed when close is prevented', function (assert) { assert.expect(1) var done = assert.async() - $('<div class="alert"/>') - .on('close.bs.alert', function (e) { - e.preventDefault() - assert.ok(true, 'close event fired') - done() - }) - .on('closed.bs.alert', function () { - assert.ok(false, 'closed event fired') - }) - .bootstrapAlert('close') + var $alert = $('<div class="alert"/>') + $alert.appendTo('#qunit-fixture') + + EventHandler.on($alert[0], 'close.bs.alert', function (e) { + e.preventDefault() + assert.ok(true, 'close event fired') + done() + }) + EventHandler.on($alert[0], 'closed.bs.alert', function () { + assert.ok(false, 'closed event fired') + }) + + $alert.bootstrapAlert('close') }) QUnit.test('close should use internal _element if no element provided', function (assert) { diff --git a/js/tests/visual/alert.html b/js/tests/visual/alert.html index d2befb8b8abe7d3dfb7c1ebf5babdf16d9fbe29c..9111e357275a25675fa54b2df83ed61b8c196724 100644 --- a/js/tests/visual/alert.html +++ b/js/tests/visual/alert.html @@ -52,7 +52,9 @@ </div> <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> - <script src="../../dist/dom/event.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/util.js"></script> <script src="../../dist/alert.js"></script> </body> diff --git a/js/tests/visual/button.html b/js/tests/visual/button.html index ce900e471e80d589245f49fcf937f8d2ef5f7b3d..818160da3b69cb45e943d9a524c5d11b47e50e5d 100644 --- a/js/tests/visual/button.html +++ b/js/tests/visual/button.html @@ -45,7 +45,7 @@ </div> <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/button.js"></script> </body> diff --git a/js/tests/visual/carousel.html b/js/tests/visual/carousel.html index 895a6422c4b7824db803de1f4a58c0811959d342..d1376b39b9f5c996f4733911d3687bf7c1762108 100644 --- a/js/tests/visual/carousel.html +++ b/js/tests/visual/carousel.html @@ -46,7 +46,7 @@ </div> <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/carousel.js"></script> <script> diff --git a/js/tests/visual/collapse.html b/js/tests/visual/collapse.html index 2bc3c086ee5f703d9d63551ceb3d3af580111f8a..e084bd08bc721cf1e53f88c1482b58916a63cb9f 100644 --- a/js/tests/visual/collapse.html +++ b/js/tests/visual/collapse.html @@ -72,7 +72,7 @@ </div> <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/collapse.js"></script> </body> diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html index 9e4a10cfb6eca9623018b4162efe267327d9f71c..d1bb0ed35080c63bb5f375ffb56034cf2e82e67d 100644 --- a/js/tests/visual/dropdown.html +++ b/js/tests/visual/dropdown.html @@ -205,7 +205,7 @@ <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> <script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/dropdown.js"></script> <script src="../../dist/collapse.js"></script> diff --git a/js/tests/visual/modal.html b/js/tests/visual/modal.html index 53ad81a97ac9ecb9bd39cb58b29c34c74aaf1f98..30975b0c7bb539b8efce82fb4d0f42b3facf52f6 100644 --- a/js/tests/visual/modal.html +++ b/js/tests/visual/modal.html @@ -207,13 +207,12 @@ <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> <script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/modal.js"></script> <script src="../../dist/collapse.js"></script> <script src="../../dist/tooltip.js"></script> <script src="../../dist/popover.js"></script> - <script> var firefoxTestDone = false function reportFirefoxTestResult(result) { diff --git a/js/tests/visual/popover.html b/js/tests/visual/popover.html index 38ab65a1256a7294bb29a5128498dead6ec3ac62..e422891dadff81510de26ddda46804bcf343187d 100644 --- a/js/tests/visual/popover.html +++ b/js/tests/visual/popover.html @@ -33,11 +33,10 @@ <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> <script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/tooltip.js"></script> <script src="../../dist/popover.js"></script> - <script> $(function () { $('[data-toggle="popover"]').popover() diff --git a/js/tests/visual/scrollspy.html b/js/tests/visual/scrollspy.html index 2fb4c1ac2bb14e14b771e174b03f87dfac0f2028..f0149198d727dcb60e3631902e87328055d905bc 100644 --- a/js/tests/visual/scrollspy.html +++ b/js/tests/visual/scrollspy.html @@ -88,7 +88,7 @@ <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> <script src="../../../site/docs/4.2/assets/js/vendor/popper.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/scrollspy.js"></script> <script src="../../dist/dropdown.js"></script> diff --git a/js/tests/visual/tab.html b/js/tests/visual/tab.html index 737679a7801876031980dbf5100c1317696fd3c6..3b8ce4026f49b9f983cd905720966657d1ad8be8 100644 --- a/js/tests/visual/tab.html +++ b/js/tests/visual/tab.html @@ -227,7 +227,7 @@ <script src="../../../node_modules/jquery/dist/jquery.slim.min.js"></script> <script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script> - <script src="../../dist/dom/event.js"></script> + <script src="../../dist/dom/eventHandler.js"></script> <script src="../../dist/util.js"></script> <script src="../../dist/tab.js"></script> <script src="../../dist/dropdown.js"></script>