asciidoctor-tabs 1.0.0.alpha.6 → 1.0.0.alpha.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd23b52dcb671b18e2fc149ff7c4c0f131acc7b36c5a83df0003c22cc341d8cd
4
- data.tar.gz: 502e57c0df6a007731a21dce2f382f54ea3e940c6548e914e91aab25d233a995
3
+ metadata.gz: 35c07868db0fc9f06cc95b5af64d1228ede7894c8acdb63570c368acf8d179f8
4
+ data.tar.gz: 80e712a56c6e421a922e109ba7cdfcf4807f24aa2b1a8aac9e8d6b334f483986
5
5
  SHA512:
6
- metadata.gz: 41ddf35603690caa50d3685eb398ebbfd65ecc13630827731ec11493667a2bcd4db8616e530ae11cb8f05fa450d258b9e734ad4ee10fbe1bcaaf1c256ee681e7
7
- data.tar.gz: ac3f2b5a3d44a8209436955dd5ebb74eff9e2bfbc0f107e572488859de78cb133817db3c5362c09198aee71b9381dfa56646e036ebd885b5cf05231b23231a7b
6
+ metadata.gz: 3cda7d6fd762ae09f8376b344f3e1a2a28c32605cfc9c5afb51117f31868e5ea9e05f299e587937ad045d4bb2c0e24bc4dc4b3351a02cae840ebe3a7cca56b1b
7
+ data.tar.gz: 68e26c82a72335b2ff799d816f3e8562367b7d14e0de78794ac19b3bcc36a98b4dc51f9d6b9f06d82d5769d87cb132ada8b8a8fd31706434a001428b772367b8
data/CHANGELOG.adoc CHANGED
@@ -4,6 +4,38 @@
4
4
  This document provides a curated view of the changes to Asciidoctor Tabs per release.
5
5
  For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub.
6
6
 
7
+ == 1.0.0-alpha.8 (2022-11-30) - @mojavelinux
8
+
9
+ === Fixed
10
+
11
+ * Sync tab selection on hash change (#32)
12
+ * Lock position of content when synchronizing tab selection (#34)
13
+ * Remove bottom margin from last block in tab pane for the most common cases
14
+
15
+ === Details
16
+
17
+ {url-repo}/releases/tag/v1.0.0-alpha.8[git tag] | {url-repo}/compare/v1.0.0-alpha.7\...v1.0.0-alpha.8[full diff]
18
+
19
+ == 1.0.0-alpha.7 (2022-11-28) - @mojavelinux
20
+
21
+ === Added
22
+
23
+ * In tabs script, add `tab` class to tab element
24
+ * Sync tab selection across tabs blocks if `sync` option is set on tabs block or `tabs-sync-option` attribute is set on document (#28)
25
+ * Delist tabs block from sync if `nosync` option is set on block (#28)
26
+
27
+ === Changed
28
+
29
+ * When inline anchor is used for tab ID, promote value of id attribute to id attribute on tab and remove anchor
30
+
31
+ === Fixed
32
+
33
+ * Apply normal substitutions to principal text (first paragraph) of tab's content (#29)
34
+
35
+ === Details
36
+
37
+ {url-repo}/releases/tag/v1.0.0-alpha.7[git tag] | {url-repo}/compare/v1.0.0-alpha.6\...v1.0.0-alpha.7[full diff]
38
+
7
39
  == 1.0.0-alpha.6 (2022-11-16) - @mojavelinux
8
40
 
9
41
  === Added
@@ -111,7 +143,7 @@ For a detailed view of what has changed, refer to the {url-repo}/commits/main[co
111
143
 
112
144
  == 1.0.0-alpha.1 (2022-10-01) - @mojavelinux
113
145
 
114
- _Initial release._
146
+ _Initial prerelease._
115
147
 
116
148
  === Details
117
149
 
data/README.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor Tabs
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>
3
- v1.0.0-alpha.6, 2022-11-16
3
+ v1.0.0-alpha.8, 2022-11-30
4
4
  :idprefix:
5
5
  :idseparator: -
6
6
  ifndef::env-github[:icons: font]
@@ -84,7 +84,7 @@ The term is used as the tab's label and the description is used as the tab's con
84
84
  The contents can be defined as primary text, attached blocks, or both.
85
85
  If the attached blocks are themselves enclosed in a single open block, the open block enclosure itself is discarded upon conversion.
86
86
 
87
- You may decide to extend the block delimiter length instead of using the typical 4 characters to avoid conflicts with any example blocks inside the tab block (or just as a manner of style).
87
+ You may choose to extend the block delimiter length from the typical 4 characters to 6 in order to avoid conflicts with any example blocks inside the tab block (or just as a matter of style).
88
88
 
89
89
  [,asciidoc]
90
90
  ----
@@ -100,6 +100,33 @@ Tab B:: Just text.
100
100
  ======
101
101
  ----
102
102
 
103
+ == Tabs Sync
104
+
105
+ If you want to synchronize the tab selection across tabsets, set the `tabs-sync-option` on the document.
106
+
107
+ .document-with-tabs-sync.adoc
108
+ [,asciidoc]
109
+ ----
110
+ :tabs-sync-option:
111
+
112
+ [tabs]
113
+ ====
114
+ Tab A:: Contents of tab A in first tabset.
115
+ Tab B:: Contents of tab B in first tabset.
116
+ ====
117
+
118
+ ...
119
+
120
+ [tabs]
121
+ ====
122
+ Tab A:: Contents of tab A in second tabset.
123
+ Tab B:: Contents of tab B in second tabset.
124
+ ====
125
+ ----
126
+
127
+ Alternately, you can set the `sync` option on each tabs block.
128
+ If you want to delist a tabs block from sync, set the `nosync` option on that block.
129
+
103
130
  == Usage
104
131
 
105
132
  === CLI
data/data/css/tabs.css CHANGED
@@ -65,6 +65,8 @@
65
65
  margin-top: 0;
66
66
  }
67
67
 
68
- .tab-pane > :last-child > :last-child {
68
+ #content .tab-pane > :last-child,
69
+ #content .tab-pane > :last-child > :last-child,
70
+ #content .tab-pane > :last-child > :last-child > li:last-child > :last-child {
69
71
  margin-bottom: 0;
70
72
  }
data/data/js/tabs.js CHANGED
@@ -1,70 +1,74 @@
1
- /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
2
- ;(function () {
1
+ ;(function () { /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
3
2
  'use strict'
4
3
 
5
- var tabsets = find('.tabset')
6
- if (!tabsets.length) return
7
- var fragment = decodeFragment(window.location.hash)
4
+ var forEach = Array.prototype.forEach
8
5
 
9
- tabsets.forEach(function (tabset) {
10
- var active
11
- var tabs = tabset.querySelector('.tabs')
12
- if (tabs) {
13
- var first
14
- find('li', tabs).forEach(function (tab, idx) {
15
- var id = (tab.querySelector('a[id]') || tab).id
16
- if (!id) return
6
+ init(document.querySelectorAll('.tabset'))
7
+
8
+ function init (tabsets) {
9
+ if (!tabsets.length) return
10
+ forEach.call(tabsets, function (tabset) {
11
+ var tabs = tabset.querySelectorAll('.tabs li')
12
+ var syncIds = tabset.classList.contains('is-sync') ? {} : undefined
13
+ forEach.call(tabs, function (tab, idx) {
14
+ var id = tab.id
15
+ if (!id) {
16
+ var anchor = tab.querySelector('a[id]')
17
+ if (!anchor) return // invalid state
18
+ tab.id = id = anchor.parentNode.removeChild(anchor).id
19
+ }
20
+ tab.className = idx ? 'tab' : 'tab is-active'
17
21
  var pane = tabset.querySelector('.tab-pane[aria-labelledby~="' + id + '"]')
18
- if (!pane) return
19
- if (!idx) first = { tab: tab, pane: pane }
20
- if (!active && fragment === id && (active = true)) {
21
- tab.classList.add('is-active')
22
- if (pane) pane.classList.add('is-active')
23
- } else if (!idx) {
24
- tab.classList.remove('is-active')
25
- if (pane) pane.classList.remove('is-active')
22
+ if (!pane) return // invalid state
23
+ if (!idx) pane.classList.add('is-active')
24
+ var onClick = activateTab
25
+ var instance = { tabset: tabset, tab: tab, pane: pane }
26
+ var syncId
27
+ if (syncIds && !((syncId = tab.textContent.trim()) in syncIds)) {
28
+ syncIds[(tab.dataset.syncId = syncId)] = true
29
+ onClick = activateTabSync
26
30
  }
27
- tab.addEventListener('click', activateTab.bind({ tabset: tabset, tab: tab, pane: pane }))
31
+ tab.addEventListener('click', onClick.bind(instance))
28
32
  })
29
- if (!active && first) {
30
- first.tab.classList.add('is-active')
31
- if (first.pane) first.pane.classList.add('is-active')
32
- }
33
- }
34
- tabset.classList.remove('is-loading')
35
- })
36
-
37
- tabsets = undefined
38
- window.addEventListener('hashchange', onHashChange)
33
+ })
34
+ onHashChange()
35
+ forEach.call(tabsets, function (tabset) {
36
+ tabset.classList.remove('is-loading')
37
+ })
38
+ window.addEventListener('hashchange', onHashChange)
39
+ }
39
40
 
40
41
  function activateTab (e) {
41
42
  var tab = this.tab
42
- var pane = this.pane
43
- find('.tabs li, .tab-pane', this.tabset).forEach(function (it) {
44
- it === tab || it === pane ? it.classList.add('is-active') : it.classList.remove('is-active')
43
+ var tabset = this.tabset || (this.tabset = tab.closest('.tabset'))
44
+ var pane = this.pane || tabset.querySelector('.tab-pane[aria-labelledby~="' + tab.id + '"]')
45
+ forEach.call(tabset.querySelectorAll('.tabs li, .tab-pane'), function (el) {
46
+ el === tab || el === pane ? el.classList.add('is-active') : el.classList.remove('is-active')
45
47
  })
46
48
  if (!e) return
47
- var hashIdx = window.location.hash ? window.location.href.indexOf('#') : -1
48
- if (~hashIdx) window.history.replaceState(null, '', window.location.href.slice(0, hashIdx))
49
+ var loc = window.location
50
+ var hashIdx = loc.hash ? loc.href.indexOf('#') : -1
51
+ if (~hashIdx) window.history.replaceState(null, '', loc.href.slice(0, hashIdx))
49
52
  e.preventDefault()
50
53
  }
51
54
 
52
- function decodeFragment (hash) {
53
- return hash && (~hash.indexOf('%') ? decodeURIComponent(hash.slice(1)) : hash.slice(1))
55
+ function activateTabSync (e) {
56
+ activateTab.call(this, e)
57
+ var tabset = this.tabset
58
+ var thisTab = this.tab
59
+ var initialY = tabset.getBoundingClientRect().y
60
+ forEach.call(document.querySelectorAll('.tabs li'), function (tab) {
61
+ if (tab !== thisTab && tab.dataset.syncId === thisTab.dataset.syncId) activateTab.call({ tab: tab })
62
+ })
63
+ var shiftedBy = tabset.getBoundingClientRect().y - initialY
64
+ if (shiftedBy && (shiftedBy = Math.round(shiftedBy))) window.scrollBy({ top: shiftedBy, behavior: 'instant' })
54
65
  }
55
66
 
56
67
  function onHashChange () {
57
- var id = decodeFragment(window.location.hash)
68
+ var id = window.location.hash.slice(1)
58
69
  if (!id) return
59
- var tab = document.getElementById(id)
60
- if (!(tab && document.querySelector('.tabset .tabs [id="' + id + '"]'))) return
61
- if (tab.tagName === 'A') tab = tab.parentNode
62
- var tabset = tab.closest('.tabset')
63
- var pane = tabset.querySelector('.tab-pane[aria-labelledby~="' + id + '"]')
64
- activateTab.call({ tabset: tabset, tab: tab, pane: pane })
65
- }
66
-
67
- function find (selector, from) {
68
- return Array.prototype.slice.call((from || document).querySelectorAll(selector))
70
+ var tab = document.getElementById(~id.indexOf('%') ? decodeURIComponent(id) : id)
71
+ if (!(tab && tab.classList.contains('tab'))) return
72
+ tab.dataset.syncId ? activateTabSync.call({ tab: tab }) : activateTab.call({ tab: tab })
69
73
  }
70
74
  })()
@@ -18,7 +18,8 @@ module Asciidoctor
18
18
  end
19
19
  tabset_number = doc.counter 'tabset-number'
20
20
  tabs_id = attrs['id'] || (generate_id %(tabset #{tabset_number}), doc)
21
- parent << (create_html_fragment parent, %(<div id="#{tabs_id}" class="tabset is-loading">))
21
+ sync = !(block.option? 'nosync') && ((block.option? 'sync') || (doc.option? 'tabs-sync')) ? ' is-sync' : nil
22
+ parent << (create_html_fragment parent, %(<div id="#{tabs_id}" class="tabset#{sync || ''} is-loading">))
22
23
  if (title = attrs['title'])
23
24
  parent << (create_html_fragment parent, %(<div class="title">#{parent.apply_subs title}</div>))
24
25
  end
@@ -35,7 +36,9 @@ module Asciidoctor
35
36
  tab_id
36
37
  end
37
38
  if content
38
- tab_blocks = content.text? ? [(create_paragraph parent, (content.instance_variable_get :@text), nil)] : []
39
+ tab_blocks = content.text? ?
40
+ [(create_paragraph parent, (content.instance_variable_get :@text), nil, subs: :normal)]
41
+ : []
39
42
  if content.blocks?
40
43
  if (block0 = (blocks = content.blocks)[0]).context == :open && blocks.size == 1 && block0.blocks?
41
44
  blocks = block0.blocks
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module Tabs
5
- VERSION = '1.0.0.alpha.6'
5
+ VERSION = '1.0.0.alpha.8'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-tabs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.6
4
+ version: 1.0.0.alpha.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-16 00:00:00.000000000 Z
11
+ date: 2022-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  - !ruby/object:Gem::Version
102
102
  version: 1.3.1
103
103
  requirements: []
104
- rubygems_version: 3.3.7
104
+ rubygems_version: 3.3.26
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: An Asciidoctor extension that adds a tabs block to the AsciiDoc syntax.