From 2e5f037b9be834c77e2832ef11122e089b42b0df Mon Sep 17 00:00:00 2001
From: Phil Hughes <theephil@gmail.com>
Date: Fri, 10 Oct 2014 15:50:00 +0100
Subject: [PATCH 1/4] Hide and hidden events on tabs

---
 docs/_includes/js/tabs.html |  8 ++++++
 js/tab.js                   | 17 +++++++-----
 js/tests/unit/tab.js        | 54 +++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/docs/_includes/js/tabs.html b/docs/_includes/js/tabs.html
index 39c244e8e4..39af74dd65 100644
--- a/docs/_includes/js/tabs.html
+++ b/docs/_includes/js/tabs.html
@@ -132,6 +132,14 @@ $('#myTab li:eq(2) a').tab('show') // Select third tab (0-indexed)
          <td>shown.bs.tab</td>
          <td>This event fires on tab show after a tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
        </tr>
+       <tr>
+         <td>hide.bs.tab</td>
+         <td>This event fires immediately when a new tab is to be shown.</td>
+       </tr>
+       <tr>
+         <td>hidden.bs.tab</td>
+         <td>This event fires after a new tab is shown.</td>
+       </tr>
       </tbody>
     </table>
   </div><!-- /.table-responsive -->
diff --git a/js/tab.js b/js/tab.js
index d7023c8170..3c3283df2e 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -33,22 +33,27 @@
 
     if ($this.parent('li').hasClass('active')) return
 
-    var previous = $ul.find('.active:last a')[0]
-    var e        = $.Event('show.bs.tab', {
-      relatedTarget: previous
+    var $previous   = $ul.find('.active:last a')
+    var hideEvent  = $.Event('hide.bs.tab')
+    var showEvent  = $.Event('show.bs.tab', {
+      relatedTarget: $previous[0]
     })
 
-    $this.trigger(e)
+    $previous.trigger(hideEvent)
+    $this.trigger(showEvent)
 
-    if (e.isDefaultPrevented()) return
+    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
 
     var $target = $(selector)
 
     this.activate($this.closest('li'), $ul)
     this.activate($target, $target.parent(), function () {
+      $previous.trigger({
+        type: 'hidden.bs.tab'
+      })
       $this.trigger({
         type: 'shown.bs.tab',
-        relatedTarget: previous
+        relatedTarget: $previous[0]
       })
     })
   }
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index 8e50614ecc..5394ee0e81 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -101,4 +101,58 @@ $(function () {
         .bootstrapTab('show')
   })
 
+  test('should fire hide and hidden events', function () {
+    stop()
+
+    var tabsHTML = '<ul class="tabs">'
+        + '<li><a href="#home">Home</a></li>'
+        + '<li><a href="#profile">Profile</a></li>'
+        + '</ul>'
+
+    $(tabsHTML)
+      .find('li:first a')
+        .on('hide.bs.tab', function (e) {
+          ok(true, 'hide event fired')
+        })
+        .bootstrapTab('show')
+      .end()
+      .find('li:last a')
+        .bootstrapTab('show')
+
+    $(tabsHTML)
+      .find('li:first a')
+        .on('hidden.bs.tab', function (e) {
+          ok(true, 'hidden event fired')
+          start()
+        })
+        .bootstrapTab('show')
+      .end()
+      .find('li:last a')
+        .bootstrapTab('show')
+  })
+
+  test('should not fire hidden when hide is prevented', function () {
+    stop()
+
+    var tabsHTML = '<ul class="tabs">'
+        + '<li><a href="#home">Home</a></li>'
+        + '<li><a href="#profile">Profile</a></li>'
+        + '</ul>'
+
+    $(tabsHTML)
+      .find('li:first a')
+        .on('hide.bs.tab', function (e) {
+          e.preventDefault()
+          ok(true, 'hide event fired')
+          start()
+        })
+        .on('hidden.bs.tab', function (e) {
+          ok(false, 'hidden event fired')
+        })
+        .bootstrapTab('show')
+      .end()
+      .find('li:last a')
+        .bootstrapTab('show')
+  })
+
 })
-- 
GitLab


From 9d992c80e9bc659063df636482267f13f6069930 Mon Sep 17 00:00:00 2001
From: Phil Hughes <theephil@gmail.com>
Date: Fri, 10 Oct 2014 16:02:57 +0100
Subject: [PATCH 2/4] Added related target to tab hide/hidden events

Related target contains the new tab to be shown
---
 docs/_includes/js/tabs.html |  4 ++--
 js/tab.js                   |  9 ++++++---
 js/tests/unit/tab.js        | 29 ++++++++++++++++++++++++++---
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/docs/_includes/js/tabs.html b/docs/_includes/js/tabs.html
index 39af74dd65..98a7e9f993 100644
--- a/docs/_includes/js/tabs.html
+++ b/docs/_includes/js/tabs.html
@@ -134,11 +134,11 @@ $('#myTab li:eq(2) a').tab('show') // Select third tab (0-indexed)
        </tr>
        <tr>
          <td>hide.bs.tab</td>
-         <td>This event fires immediately when a new tab is to be shown.</td>
+         <td>This event fires immediately when a new tab is to be shown. Use <code>event.relatedTarget</code> to target the new tab.</td>
        </tr>
        <tr>
          <td>hidden.bs.tab</td>
-         <td>This event fires after a new tab is shown.</td>
+         <td>This event fires after a new tab is shown.. Use <code>event.relatedTarget</code> to target the new tab.</td>
        </tr>
       </tbody>
     </table>
diff --git a/js/tab.js b/js/tab.js
index 3c3283df2e..9c38530111 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -34,8 +34,10 @@
     if ($this.parent('li').hasClass('active')) return
 
     var $previous   = $ul.find('.active:last a')
-    var hideEvent  = $.Event('hide.bs.tab')
-    var showEvent  = $.Event('show.bs.tab', {
+    var hideEvent   = $.Event('hide.bs.tab', {
+      relatedTarget: $this[0]
+    })
+    var showEvent   = $.Event('show.bs.tab', {
       relatedTarget: $previous[0]
     })
 
@@ -49,7 +51,8 @@
     this.activate($this.closest('li'), $ul)
     this.activate($target, $target.parent(), function () {
       $previous.trigger({
-        type: 'hidden.bs.tab'
+        type: 'hidden.bs.tab',
+        relatedTarget: $this[0]
       })
       $this.trigger({
         type: 'shown.bs.tab',
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index 5394ee0e81..6fbf36c50b 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -111,7 +111,7 @@ $(function () {
 
     $(tabsHTML)
       .find('li:first a')
-        .on('hide.bs.tab', function (e) {
+        .on('hide.bs.tab', function () {
           ok(true, 'hide event fired')
         })
         .bootstrapTab('show')
@@ -121,7 +121,7 @@ $(function () {
 
     $(tabsHTML)
       .find('li:first a')
-        .on('hidden.bs.tab', function (e) {
+        .on('hidden.bs.tab', function () {
           ok(true, 'hidden event fired')
           start()
         })
@@ -146,7 +146,7 @@ $(function () {
           ok(true, 'hide event fired')
           start()
         })
-        .on('hidden.bs.tab', function (e) {
+        .on('hidden.bs.tab', function () {
           ok(false, 'hidden event fired')
         })
         .bootstrapTab('show')
@@ -155,4 +155,27 @@ $(function () {
         .bootstrapTab('show')
   })
 
+  test('hide and hidden events contain correct relatedTarget', function () {
+    stop()
+
+    var tabsHTML = '<ul class="tabs">'
+        + '<li><a href="#home">Home</a></li>'
+        + '<li><a href="#profile">Profile</a></li>'
+        + '</ul>'
+
+    $(tabsHTML)
+      .find('li:first a')
+        .on('hide.bs.tab', function (e) {
+          equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
+        })
+        .on('hidden.bs.tab', function (e) {
+          equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
+          start()
+        })
+        .bootstrapTab('show')
+      .end()
+      .find('li:last a')
+        .bootstrapTab('show')
+  })
+
 })
-- 
GitLab


From ce809d58c7041894322adb38eeb31c2fd593f8b9 Mon Sep 17 00:00:00 2001
From: Phil Hughes <theephil@gmail.com>
Date: Fri, 10 Oct 2014 16:21:44 +0100
Subject: [PATCH 3/4] Code alignment fix

---
 js/tab.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/js/tab.js b/js/tab.js
index 9c38530111..c597d7ab6b 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -33,11 +33,11 @@
 
     if ($this.parent('li').hasClass('active')) return
 
-    var $previous   = $ul.find('.active:last a')
-    var hideEvent   = $.Event('hide.bs.tab', {
+    var $previous = $ul.find('.active:last a')
+    var hideEvent = $.Event('hide.bs.tab', {
       relatedTarget: $this[0]
     })
-    var showEvent   = $.Event('show.bs.tab', {
+    var showEvent = $.Event('show.bs.tab', {
       relatedTarget: $previous[0]
     })
 
-- 
GitLab


From 29337c7eb48497d89d5f72c95a8f8f5e8ed1d737 Mon Sep 17 00:00:00 2001
From: Phil Hughes <theephil@gmail.com>
Date: Sun, 12 Oct 2014 09:58:27 +0100
Subject: [PATCH 4/4] Updated tabs docs

---
 docs/_includes/js/tabs.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/_includes/js/tabs.html b/docs/_includes/js/tabs.html
index 98a7e9f993..570e21e201 100644
--- a/docs/_includes/js/tabs.html
+++ b/docs/_includes/js/tabs.html
@@ -134,11 +134,11 @@ $('#myTab li:eq(2) a').tab('show') // Select third tab (0-indexed)
        </tr>
        <tr>
          <td>hide.bs.tab</td>
-         <td>This event fires immediately when a new tab is to be shown. Use <code>event.relatedTarget</code> to target the new tab.</td>
+         <td>This event fires immediately when a new tab is to be shown and before the <code>show.bs.tab</code> event. Use <code>event.relatedTarget</code> to target the new tab.</td>
        </tr>
        <tr>
          <td>hidden.bs.tab</td>
-         <td>This event fires after a new tab is shown.. Use <code>event.relatedTarget</code> to target the new tab.</td>
+         <td>This event fires after a new tab is shown and before the <code>shown.bs.tab</code> event. Use <code>event.relatedTarget</code> to target the new tab.</td>
        </tr>
       </tbody>
     </table>
-- 
GitLab