From 0b16c8c6d9a9690d537bd08eac8a8292ebf938cd Mon Sep 17 00:00:00 2001 From: Johann-S Date: Mon, 21 Aug 2017 09:11:37 +0200 Subject: alert without jquery --- js/src/alert.js | 37 ++++++++++++++------------------ js/src/dom/data.js | 51 ++++++++++++++++++++++++++++++++++++++++++++ js/src/dom/event.js | 38 --------------------------------- js/src/dom/eventHandler.js | 40 ++++++++++++++++++++++++++++++++++ js/src/dom/selectorEngine.js | 42 ++++++++++++++++++++++++++++++++++++ js/src/util.js | 4 ++-- 6 files changed, 151 insertions(+), 61 deletions(-) create mode 100644 js/src/dom/data.js delete mode 100644 js/src/dom/event.js create mode 100644 js/src/dom/eventHandler.js create mode 100644 js/src/dom/selectorEngine.js (limited to 'js/src') diff --git a/js/src/alert.js b/js/src/alert.js index ab36a8d36..87209a860 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 000000000..bbe807aac --- /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/event.js deleted file mode 100644 index 5968e62e0..000000000 --- a/js/src/dom/event.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-beta): dom/event.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -const Event = { - on(element, event, handler) { - if (typeof event !== 'string') { - return - } - element.addEventListener(event, handler, false) - }, - - one(element, event, handler) { - const complete = () => { - /* eslint func-style: off */ - handler() - element.removeEventListener(event, complete, false) - } - Event.on(element, event, complete) - }, - - trigger(element, event) { - if (typeof event !== 'string') { - return - } - - const eventToDispatch = new CustomEvent(event, { - bubbles: true, - cancelable: true - }) - element.dispatchEvent(eventToDispatch) - } -} - -export default Event diff --git a/js/src/dom/eventHandler.js b/js/src/dom/eventHandler.js new file mode 100644 index 000000000..0627ccd26 --- /dev/null +++ b/js/src/dom/eventHandler.js @@ -0,0 +1,40 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-beta): dom/eventHandler.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const EventHandler = { + on(element, event, handler) { + if (typeof event !== 'string' || typeof element === 'undefined') { + return + } + element.addEventListener(event, handler, false) + }, + + one(element, event, handler) { + const complete = () => { + /* eslint func-style: off */ + handler() + element.removeEventListener(event, complete, false) + } + EventHandler.on(element, event, complete) + }, + + trigger(element, event) { + if (typeof event !== 'string' || typeof element === 'undefined') { + return null + } + + const eventToDispatch = new CustomEvent(event, { + bubbles: true, + cancelable: true + }) + element.dispatchEvent(eventToDispatch) + + return eventToDispatch + } +} + +export default EventHandler diff --git a/js/src/dom/selectorEngine.js b/js/src/dom/selectorEngine.js new file mode 100644 index 000000000..f6bcf6da2 --- /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 2ffdec999..b5efeca14 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 -- cgit v1.2.3