]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
button without jquery
authorXhmikosR <xhmikosr@gmail.com>
Mon, 21 Aug 2017 11:49:41 +0000 (14:49 +0300)
committerXhmikosR <xhmikosr@gmail.com>
Wed, 20 Feb 2019 20:05:45 +0000 (22:05 +0200)
js/src/button.js
js/src/util.js
js/tests/unit/button.js
js/tests/visual/button.html

index fcf805502a33aeafd8179baccbb4f9f734e8312c..410da06cb3996bf7157d4679d76b68fb7b1bafe5 100644 (file)
@@ -5,7 +5,9 @@
  * --------------------------------------------------------------------------
  */
 
-import $ from 'jquery'
+import Data from './dom/data'
+import EventHandler from './dom/eventHandler'
+import SelectorEngine from './dom/selectorEngine'
 
 /**
  * ------------------------------------------------------------------------
@@ -18,7 +20,6 @@ const VERSION             = '4.3.1'
 const DATA_KEY            = 'bs.button'
 const EVENT_KEY           = `.${DATA_KEY}`
 const DATA_API_KEY        = '.data-api'
-const JQUERY_NO_CONFLICT  = $.fn[NAME]
 
 const ClassName = {
   ACTIVE : 'active',
@@ -36,8 +37,8 @@ const Selector = {
 
 const Event = {
   CLICK_DATA_API      : `click${EVENT_KEY}${DATA_API_KEY}`,
-  FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +
-                          `blur${EVENT_KEY}${DATA_API_KEY}`
+  FOCUS_DATA_API      : `focus${EVENT_KEY}${DATA_API_KEY}`,
+  BLUR_DATA_API       : `blur${EVENT_KEY}${DATA_API_KEY}`
 }
 
 /**
@@ -62,12 +63,14 @@ class Button {
   toggle() {
     let triggerChangeEvent = true
     let addAriaPressed = true
-    const rootElement = $(this._element).closest(
+
+    const rootElement = SelectorEngine.closest(
+      this._element,
       Selector.DATA_TOGGLE
-    )[0]
+    )
 
     if (rootElement) {
-      const input = this._element.querySelector(Selector.INPUT)
+      const input = SelectorEngine.findOne(Selector.INPUT, this._element)
 
       if (input) {
         if (input.type === 'radio') {
@@ -75,10 +78,10 @@ class Button {
             this._element.classList.contains(ClassName.ACTIVE)) {
             triggerChangeEvent = false
           } else {
-            const activeElement = rootElement.querySelector(Selector.ACTIVE)
+            const activeElement = SelectorEngine.findOne(Selector.ACTIVE, rootElement)
 
             if (activeElement) {
-              $(activeElement).removeClass(ClassName.ACTIVE)
+              activeElement.classList.remove(ClassName.ACTIVE)
             }
           }
         }
@@ -91,7 +94,7 @@ class Button {
             return
           }
           input.checked = !this._element.classList.contains(ClassName.ACTIVE)
-          $(input).trigger('change')
+          EventHandler.trigger(input, 'change')
         }
 
         input.focus()
@@ -105,12 +108,12 @@ class Button {
     }
 
     if (triggerChangeEvent) {
-      $(this._element).toggleClass(ClassName.ACTIVE)
+      this._element.classList.toggle(ClassName.ACTIVE)
     }
   }
 
   dispose() {
-    $.removeData(this._element, DATA_KEY)
+    Data.removeData(this._element, DATA_KEY)
     this._element = null
   }
 
@@ -118,11 +121,11 @@ class Button {
 
   static _jQueryInterface(config) {
     return this.each(function () {
-      let data = $(this).data(DATA_KEY)
+      let data = Data.getData(this, DATA_KEY)
 
       if (!data) {
         data = new Button(this)
-        $(this).data(DATA_KEY, data)
+        Data.setData(this, DATA_KEY, data)
       }
 
       if (config === 'toggle') {
@@ -138,34 +141,49 @@ class Button {
  * ------------------------------------------------------------------------
  */
 
-$(document)
-  .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
-    event.preventDefault()
+EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
+  event.preventDefault()
 
-    let button = event.target
+  let button = event.target
+  if (!button.classList.contains(ClassName.BUTTON)) {
+    button = SelectorEngine.closest(button, Selector.BUTTON)
+  }
 
-    if (!$(button).hasClass(ClassName.BUTTON)) {
-      button = $(button).closest(Selector.BUTTON)
-    }
+  let data = Data.getData(button, DATA_KEY)
+  if (!data) {
+    data = new Button(button)
+    Data.setData(button, DATA_KEY, data)
+  }
+  data.toggle()
+})
 
-    Button._jQueryInterface.call($(button), 'toggle')
-  })
-  .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
-    const button = $(event.target).closest(Selector.BUTTON)[0]
-    $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
-  })
+EventHandler.on(document, Event.FOCUS_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
+  const button = SelectorEngine.closest(event.target, Selector.BUTTON)
+  button.classList.add(ClassName.FOCUS)
+})
+
+EventHandler.on(document, Event.BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
+  const button = SelectorEngine.closest(event.target, Selector.BUTTON)
+  button.classList.remove(ClassName.FOCUS)
+})
 
 /**
  * ------------------------------------------------------------------------
  * jQuery
  * ------------------------------------------------------------------------
+ * add .button to jQuery only if jQuery is present
  */
 
-$.fn[NAME] = Button._jQueryInterface
-$.fn[NAME].Constructor = Button
-$.fn[NAME].noConflict = () => {
-  $.fn[NAME] = JQUERY_NO_CONFLICT
-  return Button._jQueryInterface
+if (typeof window.$ !== 'undefined' || typeof window.jQuery !== 'undefined') {
+  const $                   = window.$ || window.jQuery
+  const JQUERY_NO_CONFLICT  = $.fn[NAME]
+  $.fn[NAME]                = Button._jQueryInterface
+  $.fn[NAME].Constructor    = Button
+
+  $.fn[NAME].noConflict  = () => {
+    $.fn[NAME] = JQUERY_NO_CONFLICT
+    return Button._jQueryInterface
+  }
 }
 
 export default Button
index b5efeca14e0afcc3ee6ea60fb8b4fa6a58e8b31f..fb777e4f73ffba2b1e9a0042c93918d31f8d154b 100644 (file)
@@ -55,8 +55,8 @@ const Util = {
     }
 
     // Get transition-duration of the element
-    let transitionDuration = $(element).css('transition-duration')
-    let transitionDelay = $(element).css('transition-delay')
+    let transitionDuration = element.style.transitionDuration
+    let transitionDelay = element.style.transitionDelay
 
     const floatTransitionDuration = parseFloat(transitionDuration)
     const floatTransitionDelay = parseFloat(transitionDelay)
index 724545a532e67913f24d4d6755bdf107a7510bb3..68e052e22f4514e981e3bf8ac6fb1d39ba0b9452 100644 (file)
@@ -106,17 +106,19 @@ $(function () {
 
   QUnit.test('should check for closest matching toggle', function (assert) {
     assert.expect(12)
-    var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
-      '<label class="btn btn-primary active">' +
-      '<input type="radio" name="options" id="option1" checked="true"> Option 1' +
-      '</label>' +
-      '<label class="btn btn-primary">' +
-      '<input type="radio" name="options" id="option2"> Option 2' +
-      '</label>' +
-      '<label class="btn btn-primary">' +
-      '<input type="radio" name="options" id="option3"> Option 3' +
-      '</label>' +
-      '</div>'
+    var groupHTML =
+        '<div class="btn-group" data-toggle="buttons">'
+      + '  <label class="btn btn-primary active">'
+      + '    <input type="radio" name="options" id="option1" checked="true"> Option 1'
+      + '  </label>'
+      + '  <label class="btn btn-primary">'
+      + '    <input type="radio" name="options" id="option2"> Option 2'
+      + '  </label>'
+      + '  <label class="btn btn-primary">'
+      + '    <input type="radio" name="options" id="option3"> Option 3'
+      + '  </label>'
+      + '</div>'
+
     var $group = $(groupHTML).appendTo('#qunit-fixture')
 
     var $btn1 = $group.children().eq(0)
@@ -126,13 +128,16 @@ $(function () {
     assert.ok($btn1.find('input').prop('checked'), 'btn1 is checked')
     assert.ok(!$btn2.hasClass('active'), 'btn2 does not have active class')
     assert.ok(!$btn2.find('input').prop('checked'), 'btn2 is not checked')
-    $btn2.find('input').trigger('click')
+
+    EventHandler.trigger($btn2.find('input')[0], 'click')
+
     assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
     assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
     assert.ok($btn2.hasClass('active'), 'btn2 has active class')
     assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked')
 
-    $btn2.find('input').trigger('click') // Clicking an already checked radio should not un-check it
+    EventHandler.trigger($btn2.find('input')[0], 'click') // clicking an already checked radio should not un-check it
+
     assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
     assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
     assert.ok($btn2.hasClass('active'), 'btn2 has active class')
index 818160da3b69cb45e943d9a524c5d11b47e50e5d..774e755eb7299d4b9834d0a2a4449ff512b0a5b4 100644 (file)
@@ -46,6 +46,8 @@
 
     <script src="../../../node_modules/jquery/dist/jquery.slim.min.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/button.js"></script>
   </body>