Accordion Shortcodes - Version 2.4.0

Version Description

  • NEW: Added option to add a button tag wrapper around the accordion title
  • FIXED: better accessibility support
  • Now compatible up to WordPress 5.1
Download this release

Release Info

Developer philbuchanan
Plugin Icon 128x128 Accordion Shortcodes
Version 2.4.0
Comparing to
See all releases

Code changes from version 2.3.3 to 2.4.0

Files changed (5) hide show
  1. accordion-shortcodes.php +44 -23
  2. accordion.js +126 -102
  3. accordion.min.js +1 -1
  4. readme.txt +31 -2
  5. tinymce/tinymce-plugin.js +15 -1
accordion-shortcodes.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Accordion Shortcodes
4
  * Description: Shortcodes for creating responsive accordion drop-downs.
5
- * Version: 2.3.3
6
  * Author: Phil Buchanan
7
  * Author URI: http://philbuchanan.com
8
  */
@@ -17,7 +17,7 @@ class Accordion_Shortcodes {
17
  /**
18
  * Current plugin version number
19
  */
20
- private $plugin_version = '2.3.3';
21
 
22
 
23
 
@@ -71,6 +71,13 @@ class Accordion_Shortcodes {
71
 
72
 
73
 
 
 
 
 
 
 
 
74
  /**
75
  * Class constructor
76
  * Sets up the plugin, including: textdomain, adding shortcodes, registering
@@ -168,10 +175,14 @@ class Accordion_Shortcodes {
168
  */
169
  private function check_html_tag($tag) {
170
  $tag = preg_replace('/\s/', '', $tag);
171
- $tags = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div');
172
 
173
- if (in_array($tag, $tags)) return $tag;
174
- else return $this->title_tag;
 
 
 
 
175
  }
176
 
177
 
@@ -232,8 +243,9 @@ class Accordion_Shortcodes {
232
  'openall' => false,
233
  'clicktoclose' => false,
234
  'scroll' => false,
 
235
  'semantics' => '',
236
- 'class' => ''
237
  ), $atts, 'accordion'));
238
 
239
  // Set global HTML tag names
@@ -252,6 +264,10 @@ class Accordion_Shortcodes {
252
  $this->content_tag = 'div';
253
  }
254
 
 
 
 
 
255
  // Set settings object (for use in JavaScript)
256
  $script_data = array(
257
  'id' => "accordion-$this->group_count",
@@ -259,13 +275,14 @@ class Accordion_Shortcodes {
259
  'openFirst' => $this->is_boolean($openfirst),
260
  'openAll' => $this->is_boolean($openall),
261
  'clickToClose' => $this->is_boolean($clicktoclose),
262
- 'scroll' => $this->check_scroll_value($scroll)
 
263
  );
264
 
265
  // Add this shortcodes settings instance to the global script data array
266
  $this->script_data[] = $script_data;
267
 
268
- return sprintf('<%2$s id="%3$s" class="accordion no-js%4$s" role="tablist" aria-multiselectable="true">%1$s</%2$s>',
269
  do_shortcode($content),
270
  $this->wrapper_tag,
271
  "accordion-$this->group_count",
@@ -292,23 +309,27 @@ class Accordion_Shortcodes {
292
 
293
  $ids = $this->get_accordion_id($id);
294
 
295
- $accordion_title = sprintf('<%1$s id="%3$s" class="accordion-title%5$s" role="tab" aria-controls="%4$s" aria-selected="false" aria-expanded="false" tabindex="0" %6$s>%2$s</%1$s>',
296
- $tag ? $this->check_html_tag($tag) : $this->title_tag,
297
- $title ? $title : '<span style="color:red;">' . __('Please enter a title attribute', 'accordion_shortcodes') . '</span>',
298
- $ids['title'],
299
- $ids['content'],
300
- $class ? " $class" : '',
301
- $state ? ' data-initialstate="' . $state . '"' : ''
302
- );
303
 
304
- $accordion_content = sprintf('<%1$s id="%3$s" class="accordion-content" role="tabpanel" aria-labelledby="%4$s" aria-hidden="true">%2$s</%1$s>',
305
- $this->content_tag,
306
- do_shortcode($content),
307
- $ids['content'],
308
- $ids['title']
309
- );
 
 
 
 
 
 
 
 
 
 
 
310
 
311
- return $accordion_title . $accordion_content;
312
  }
313
 
314
 
2
  /**
3
  * Plugin Name: Accordion Shortcodes
4
  * Description: Shortcodes for creating responsive accordion drop-downs.
5
+ * Version: 2.4.0
6
  * Author: Phil Buchanan
7
  * Author URI: http://philbuchanan.com
8
  */
17
  /**
18
  * Current plugin version number
19
  */
20
+ private $plugin_version = '2.4.0';
21
 
22
 
23
 
71
 
72
 
73
 
74
+ /**
75
+ * Whether to include a `<button>` tag wrapper on each title
76
+ */
77
+ private $use_buttons = false;
78
+
79
+
80
+
81
  /**
82
  * Class constructor
83
  * Sets up the plugin, including: textdomain, adding shortcodes, registering
175
  */
176
  private function check_html_tag($tag) {
177
  $tag = preg_replace('/\s/', '', $tag);
178
+ $tags = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'button');
179
 
180
+ if (in_array($tag, $tags)) {
181
+ return $tag;
182
+ }
183
+ else {
184
+ return $this->title_tag;
185
+ }
186
  }
187
 
188
 
243
  'openall' => false,
244
  'clicktoclose' => false,
245
  'scroll' => false,
246
+ 'usebuttons' => false,
247
  'semantics' => '',
248
+ 'class' => '',
249
  ), $atts, 'accordion'));
250
 
251
  // Set global HTML tag names
264
  $this->content_tag = 'div';
265
  }
266
 
267
+ if ($usebuttons && $this->is_boolean($usebuttons)) {
268
+ $this->use_buttons = true;
269
+ }
270
+
271
  // Set settings object (for use in JavaScript)
272
  $script_data = array(
273
  'id' => "accordion-$this->group_count",
275
  'openFirst' => $this->is_boolean($openfirst),
276
  'openAll' => $this->is_boolean($openall),
277
  'clickToClose' => $this->is_boolean($clicktoclose),
278
+ 'scroll' => $this->check_scroll_value($scroll),
279
+ 'usebuttons' => $this->is_boolean($usebuttons),
280
  );
281
 
282
  // Add this shortcodes settings instance to the global script data array
283
  $this->script_data[] = $script_data;
284
 
285
+ return sprintf('<%2$s id="%3$s" class="accordion no-js%4$s">%1$s</%2$s>',
286
  do_shortcode($content),
287
  $this->wrapper_tag,
288
  "accordion-$this->group_count",
309
 
310
  $ids = $this->get_accordion_id($id);
311
 
312
+ $html_tag = $tag ? $this->check_html_tag($tag) : $this->title_tag;
 
 
 
 
 
 
 
313
 
314
+ ob_start(); ?>
315
+
316
+ <?php if ($this->use_buttons) { ?>
317
+ <<?php echo $html_tag; ?> class="accordion-title<?php echo $class ? " $class" : ''; ?>">
318
+ <button id="<?php echo $ids['title']; ?>" class="js-accordion-controller" aria-controls="<?php echo $ids['content']; ?>" aria-expanded="false" <?php echo $state ? ' data-initialstate="' . esc_attr($state) . '"' : ''; ?>>
319
+ <?php echo $title ? $title : '<span style="color:red;">' . __('Please enter a title attribute', 'accordion_shortcodes') . '</span>'; ?>
320
+ </button>
321
+ </<?php echo $html_tag; ?>>
322
+ <?php } else { ?>
323
+ <<?php echo $html_tag; ?> role="button" id="<?php echo $ids['title']; ?>" class="accordion-title<?php echo !$this->use_buttons ? ' js-accordion-controller' : ''; echo $class ? " $class" : ''; ?>" aria-controls="<?php echo $ids['content']; ?>" aria-expanded="false" tabindex="0"<?php echo $state ? ' data-initialstate="' . esc_attr($state) . '"' : ''; ?>>
324
+ <?php echo $title ? $title : '<span style="color:red;">' . __('Please enter a title attribute', 'accordion_shortcodes') . '</span>'; ?>
325
+ </<?php echo $html_tag; ?>>
326
+ <?php } ?>
327
+
328
+ <<?php echo $this->content_tag; ?> id="<?php echo $ids['content']; ?>" class="accordion-content" aria-hidden="true">
329
+ <?php echo do_shortcode($content); ?>
330
+ </<?php echo $this->content_tag; ?>>
331
 
332
+ <?php return ob_get_clean();
333
  }
334
 
335
 
accordion.js CHANGED
@@ -12,20 +12,19 @@
12
  */
13
  $.fn.accordionShortcodes = function(options) {
14
 
15
- var allTitles = this.children('.accordion-title'),
16
- allPanels = this.children('.accordion-content').hide(),
17
- firstTitle = allTitles.first(),
18
- firstPanel = allPanels.first(),
19
- selectedId = $(window.location.hash),
20
- duration = 250,
21
- settings = $.extend({
22
- // Set default settings
23
- autoClose: true,
24
- openFirst: false,
25
- openAll: false,
26
- clickToClose: false,
27
- scroll: false
28
- }, options);
29
 
30
 
31
 
@@ -38,28 +37,113 @@
38
 
39
  settings.scrollOffset = Math.floor(parseInt(settings.scroll)) | 0;
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
 
43
  /**
44
  * Defualt click function
45
- * Called when an accordion title is clicked.
46
  */
47
- function clickHandler() {
48
  // Only open the item if item isn't already open
49
- if (!$(this).hasClass('open')) {
50
  // Close all accordion items
51
  if (settings.autoClose) {
52
- allTitles.each(function() {
53
- closeItem($(this));
54
  });
55
  }
56
 
57
  // Open clicked item
58
- openItem($(this), true);
59
  }
60
  // If item is open, and click to close is set, close it
61
  else if (settings.clickToClose) {
62
- closeItem($(this));
63
  }
64
 
65
  return false;
@@ -71,29 +155,26 @@
71
  * Opens an accordion item
72
  * Also handles accessibility attribute settings.
73
  *
74
- * @param object ele The accordion item title to open
75
  * @param bool scroll Whether to scroll the page
76
  */
77
- function openItem(ele, scroll) {
78
- // Clear/stop any previous animations before revealing content
79
- ele.next().clearQueue().stop().slideDown(duration, function() {
80
  // Scroll page to the title
81
  if (scroll && settings.scroll) {
82
  $('html, body').animate({
83
- scrollTop: $(this).prev().offset().top - settings.scrollOffset
84
  }, duration);
85
  }
86
  });
87
 
88
- // Mark accordion item as open and read and set aria attributes
89
- ele.addClass('open read')
90
- .attr({
91
- 'aria-selected': 'true',
92
- 'aria-expanded': 'true'
93
- })
94
- .next().attr({
95
- 'aria-hidden': 'false'
96
- });
97
  }
98
 
99
 
@@ -102,85 +183,28 @@
102
  * Closes an accordion item
103
  * Also handles accessibility attribute settings.
104
  *
105
- * @param object ele The accordion item title to open
106
  */
107
- function closeItem(ele) {
108
- ele.next().slideUp(duration);
109
- ele.removeClass('open');
110
 
111
  // Set accessibility attributes
112
- ele.attr({
113
- 'aria-selected': 'false',
114
- 'aria-expanded': 'false'
115
- })
116
- .next().attr({
117
- 'aria-hidden': 'true'
118
- });
119
- }
120
-
121
 
122
-
123
- /**
124
- * Should any accordions be opened or closed on load?
125
- * Open first, open all, open based on URL hash or open/closed based on
126
- * initial state setting.
127
- */
128
- if (selectedId.length && selectedId.hasClass('accordion-title')) {
129
- openItem(selectedId, true);
130
- }
131
- else if (settings.openAll) {
132
- allTitles.each(function() {
133
- openItem($(this), false);
134
- });
135
- }
136
- else if (settings.openFirst) {
137
- openItem(firstTitle, false);
138
  }
139
 
140
- // Open or close items if initial state set to open or close
141
- $('[data-initialstate!=""]').each(function() {
142
- switch ($(this).data('initialstate')) {
143
- case 'open':
144
- openItem($(this), false);
145
- break;
146
- case 'closed':
147
- // Only close it if the hash isn't for this item
148
- if ($(this).attr('id') !== selectedId.attr('id')) {
149
- closeItem($(this));
150
- }
151
- break;
152
- }
153
- });
154
 
155
 
156
-
157
- /**
158
- * Add event listeners
159
- */
160
- allTitles.click(clickHandler);
161
-
162
- allTitles.keydown(function(e) {
163
- var code = e.which;
164
-
165
- // 13 = Return, 32 = Space
166
- if ((code === 13) || (code === 32)) {
167
- // Simulate click on title
168
- $(this).click();
169
- }
170
- });
171
-
172
  // Listen for hash changes (in page jump links for accordions)
173
  $(window).on('hashchange', function() {
174
  selectedId = $(window.location.hash);
175
 
176
- if (selectedId.length && selectedId.hasClass('accordion-title')) {
177
- if (settings.autoClose) {
178
- allTitles.each(function() {
179
- closeItem($(this));
180
- });
181
- }
182
-
183
- openItem(selectedId, true);
184
  }
185
  });
186
 
12
  */
13
  $.fn.accordionShortcodes = function(options) {
14
 
15
+ var items = [];
16
+ var allControllers = $('.js-accordion-controller');
17
+ var selectedId = window.location.hash;
18
+ var duration = 250;
19
+ var settings = $.extend({
20
+ // Set default settings
21
+ autoClose: true,
22
+ openFirst: false,
23
+ openAll: false,
24
+ clickToClose: false,
25
+ scroll: false,
26
+ usebuttons: false,
27
+ }, options);
 
28
 
29
 
30
 
37
 
38
  settings.scrollOffset = Math.floor(parseInt(settings.scroll)) | 0;
39
 
40
+ allControllers.each(function(index) {
41
+ var initiallyOpen = false;
42
+
43
+ // Should any accordions be opened or closed on load?
44
+ if (index == 0 && settings.openFirst) {
45
+ initiallyOpen = true;
46
+ }
47
+
48
+ // Open all overwrites open first setting
49
+ if (settings.openAll) {
50
+ initiallyOpen = true;
51
+ }
52
+
53
+ // Initial state settings on individual items override global initial state settings
54
+ switch ($(this).data('initialstate')) {
55
+ case 'open':
56
+ var initiallyOpen = true;
57
+ break;
58
+ case 'closed':
59
+ var initiallyOpen = false;
60
+ break;
61
+ }
62
+
63
+ // ID hashs override all initial state settings
64
+ if (selectedId.length && selectedId == '#' + $(this).attr('id')) {
65
+ initiallyOpen = true;
66
+ }
67
+
68
+ var item = getAccordionItemObject($(this), initiallyOpen);
69
+
70
+ items.push(item);
71
+
72
+ // Add event listeners to controller
73
+ $(this).click(function(event) {
74
+ clickControllerHandler(item);
75
+ });
76
+
77
+ $(this).keydown(function(event) {
78
+ var code = event.which;
79
+
80
+ // We only need to add manual keyboard events if _not_ using `<button>` elements
81
+ // `<button>` tags will natively fire the click event.
82
+ if (!settings.usebuttons) {
83
+ // 13 = Return, 32 = Space
84
+ if ((code === 13) || (code === 32)) {
85
+ $(this).click();
86
+ }
87
+ }
88
+
89
+ // 27 = Esc
90
+ if (code === 27) {
91
+ if (settings.clickToClose) {
92
+ closeAccordionItem(item);
93
+ }
94
+ }
95
+ });
96
+
97
+ // Should this item be opened or closed by default?
98
+ if (item.isOpen) {
99
+ openAccordionItem(item);
100
+ }
101
+ else {
102
+ closeAccordionItem(item);
103
+ }
104
+ });
105
+
106
+
107
+
108
+ /**
109
+ * Get an accordion item object
110
+ *
111
+ * @param array ele a jQuery object
112
+ * @param bool initiallyOpen Should this item be open by default?
113
+ * @return object An object with an accordion items components
114
+ */
115
+ function getAccordionItemObject(ele, initiallyOpen) {
116
+ return {
117
+ id: ele.attr('id'),
118
+ controller: ele,
119
+ controls: ele.attr('aria-controls'),
120
+ content: $('#' + ele.attr('aria-controls')),
121
+ isOpen: initiallyOpen ? initiallyOpen : false,
122
+ }
123
+ }
124
+
125
 
126
 
127
  /**
128
  * Defualt click function
129
+ * Called when an accordion controller is clicked.
130
  */
131
+ function clickControllerHandler(item) {
132
  // Only open the item if item isn't already open
133
+ if (!item.isOpen) {
134
  // Close all accordion items
135
  if (settings.autoClose) {
136
+ $.each(items, function(index, item) {
137
+ closeAccordionItem(item);
138
  });
139
  }
140
 
141
  // Open clicked item
142
+ openAccordionItem(item, true);
143
  }
144
  // If item is open, and click to close is set, close it
145
  else if (settings.clickToClose) {
146
+ closeAccordionItem(item);
147
  }
148
 
149
  return false;
155
  * Opens an accordion item
156
  * Also handles accessibility attribute settings.
157
  *
158
+ * @param object item The accordion item to open
159
  * @param bool scroll Whether to scroll the page
160
  */
161
+ function openAccordionItem(item, scroll) {
162
+ item.content.clearQueue().stop().slideDown(duration, function() {
 
163
  // Scroll page to the title
164
  if (scroll && settings.scroll) {
165
  $('html, body').animate({
166
+ scrollTop: item.controller.offset().top - settings.scrollOffset
167
  }, duration);
168
  }
169
  });
170
 
171
+ item.controller.addClass('open read');
172
+
173
+ // Set accessibility attributes
174
+ item.controller.attr('aria-expanded', 'true');
175
+ item.content.attr('aria-hidden', 'false');
176
+
177
+ item.isOpen = true;
 
 
178
  }
179
 
180
 
183
  * Closes an accordion item
184
  * Also handles accessibility attribute settings.
185
  *
186
+ * @param object item The accordion item to close
187
  */
188
+ function closeAccordionItem(item) {
189
+ item.content.slideUp(duration);
190
+ item.controller.removeClass('open');
191
 
192
  // Set accessibility attributes
193
+ item.controller.attr('aria-expanded', 'false');
194
+ item.content.attr('aria-hidden', 'true');
 
 
 
 
 
 
 
195
 
196
+ item.isOpen = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  }
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  // Listen for hash changes (in page jump links for accordions)
202
  $(window).on('hashchange', function() {
203
  selectedId = $(window.location.hash);
204
 
205
+ if (selectedId.length && selectedId.hasClass('js-accordion-controller')) {
206
+ // Simulate click on controller
207
+ selectedId.click();
 
 
 
 
 
208
  }
209
  });
210
 
accordion.min.js CHANGED
@@ -1 +1 @@
1
- !function(t){"use strict";var o;t.fn.accordionShortcodes=function(o){function e(){return t(this).hasClass("open")?h.clickToClose&&n(t(this)):(h.autoClose&&a.each(function(){n(t(this))}),i(t(this),!0)),!1}function i(o,e){o.next().clearQueue().stop().slideDown(l,function(){e&&h.scroll&&t("html, body").animate({scrollTop:t(this).prev().offset().top-h.scrollOffset},l)}),o.addClass("open read").attr({"aria-selected":"true","aria-expanded":"true"}).next().attr({"aria-hidden":"false"})}function n(t){t.next().slideUp(l),t.removeClass("open"),t.attr({"aria-selected":"false","aria-expanded":"false"}).next().attr({"aria-hidden":"true"})}var a=this.children(".accordion-title"),s=this.children(".accordion-content").hide(),c=a.first(),r=(s.first(),t(window.location.hash)),l=250,h=t.extend({autoClose:!0,openFirst:!1,openAll:!1,clickToClose:!1,scroll:!1},o);return t(".accordion").removeClass("no-js"),h.scrollOffset=0|Math.floor(parseInt(h.scroll)),r.length&&r.hasClass("accordion-title")?i(r,!0):h.openAll?a.each(function(){i(t(this),!1)}):h.openFirst&&i(c,!1),t('[data-initialstate!=""]').each(function(){switch(t(this).data("initialstate")){case"open":i(t(this),!1);break;case"closed":t(this).attr("id")!==r.attr("id")&&n(t(this))}}),a.click(e),a.keydown(function(o){var e=o.which;(13===e||32===e)&&t(this).click()}),t(window).on("hashchange",function(){r=t(window.location.hash),r.length&&r.hasClass("accordion-title")&&(h.autoClose&&a.each(function(){n(t(this))}),i(r,!0))}),this},t(window).on("load",function(){for(var e=0;e<accordionShortcodesSettings.length;e+=1)o=accordionShortcodesSettings[e],t("#"+o.id).accordionShortcodes(o)})}(jQuery);
1
+ !function(d){"use strict";var t;d.fn.accordionShortcodes=function(o){var r=[],t=d(".js-accordion-controller"),s=window.location.hash,n=250,a=d.extend({autoClose:!0,openFirst:!1,openAll:!1,clickToClose:!1,scroll:!1,usebuttons:!1},o);function i(o,t){o.content.clearQueue().stop().slideDown(n,function(){t&&a.scroll&&d("html, body").animate({scrollTop:o.controller.offset().top-a.scrollOffset},n)}),o.controller.addClass("open read"),o.controller.attr("aria-expanded","true"),o.content.attr("aria-hidden","false"),o.isOpen=!0}function l(o){o.content.slideUp(n),o.controller.removeClass("open"),o.controller.attr("aria-expanded","false"),o.content.attr("aria-hidden","true"),o.isOpen=!1}return d(".accordion").removeClass("no-js"),a.scrollOffset=0|Math.floor(parseInt(a.scroll)),t.each(function(o){var t=!1;switch(0==o&&a.openFirst&&(t=!0),a.openAll&&(t=!0),d(this).data("initialstate")){case"open":t=!0;break;case"closed":t=!1}s.length&&s=="#"+d(this).attr("id")&&(t=!0);var n,e,c=(n=d(this),e=t,{id:n.attr("id"),controller:n,controls:n.attr("aria-controls"),content:d("#"+n.attr("aria-controls")),isOpen:e||!1});r.push(c),d(this).click(function(o){var t;(t=c).isOpen?a.clickToClose&&l(t):(a.autoClose&&d.each(r,function(o,t){l(t)}),i(t,!0))}),d(this).keydown(function(o){var t=o.which;a.usebuttons||13!==t&&32!==t||d(this).click(),27===t&&a.clickToClose&&l(c)}),c.isOpen?i(c):l(c)}),d(window).on("hashchange",function(){(s=d(window.location.hash)).length&&s.hasClass("js-accordion-controller")&&s.click()}),this},d(window).on("load",function(){for(var o=0;o<accordionShortcodesSettings.length;o+=1)t=accordionShortcodesSettings[o],d("#"+t.id).accordionShortcodes(t)})}(jQuery);
readme.txt CHANGED
@@ -4,8 +4,8 @@ Author URI: http://philbuchanan.com/
4
  Donate Link: http://philbuchanan.com/
5
  Tags: accordion, accordions, shortcodes, responsive accordions, accordions plugin, jquery accordions, accordions short-code, accordions plugin wordpress, accordions plugin jquery
6
  Requires at least: 3.3
7
- Tested up to: 4.8
8
- Stable tag: 2.3.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -208,6 +208,27 @@ There are a few advanced settings you can add to the opening accordion shortcode
208
 
209
  **tag**: You can also set the HTML tag for the titles of each accordion item individually by adding `tag="tagname"` to each `[accordion-item]` shortcode. Make sure to **not** include the angle brackets around the tag name. Example: to use `<h2>` instead of the default `<h3>` tag: `[accordion-item title="Item title" tag="h2"]Item content[/accordion-item]`. Using a tag attribute on an individual accordion item will override the global setting. The list of valid tags is: h1, h2, h3, h4, h5, h6, p, div.
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  = Filtering Shortcodes =
212
 
213
  You can filter the settings and content of the shortcodes by adding some simply code to the functions.php file of your theme.
@@ -244,6 +265,11 @@ For bug reports or feature requests or if you'd like to contribute to the plugin
244
  3. The Accordion Item shortcode insertion dialog box
245
 
246
  == Changelog ==
 
 
 
 
 
247
  = 2.3.3 =
248
  * Now compatible up to WordPress 4.8
249
  * FIXED: aria-mutliselectable is now on the accordion group instead of each accordion item title
@@ -305,6 +331,9 @@ FIXED: A bug where setting both scroll and openfirst would scroll the window wit
305
  * FIXED: A few incredibly small bugs/annoyances
306
 
307
  == Upgrade Notice ==
 
 
 
308
  = 2.3.2 =
309
  You may notice a focus state around your accordion items when clicking them. This is necessary to support accessibility within the plugin. If you really must remove the focus state (though not recommended) you can do so by adding this CSS to your theme's stylesheet: `.accordion-title {outline: none;}`.
310
 
4
  Donate Link: http://philbuchanan.com/
5
  Tags: accordion, accordions, shortcodes, responsive accordions, accordions plugin, jquery accordions, accordions short-code, accordions plugin wordpress, accordions plugin jquery
6
  Requires at least: 3.3
7
+ Tested up to: 5.1
8
+ Stable tag: 2.4.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
208
 
209
  **tag**: You can also set the HTML tag for the titles of each accordion item individually by adding `tag="tagname"` to each `[accordion-item]` shortcode. Make sure to **not** include the angle brackets around the tag name. Example: to use `<h2>` instead of the default `<h3>` tag: `[accordion-item title="Item title" tag="h2"]Item content[/accordion-item]`. Using a tag attribute on an individual accordion item will override the global setting. The list of valid tags is: h1, h2, h3, h4, h5, h6, p, div.
210
 
211
+ **usebutons**: You can now optionally wrap each accordion item title in a `<button>` tag by adding `usebuttons="true"` to the main `[accordion]` shortcode. Please note that your theme may apply undesirable styles to `<button>` tags by default. You may need to add more custom styles to override your themes default styles. Using this setting will produce this HTML output:
212
+
213
+ <div class="accordion">
214
+ <h3 class="accordion-title">
215
+ <button>
216
+ Title of accordion item
217
+ </button>
218
+ </h3>
219
+ <div class="accordion-content">
220
+ Drop-down content goes here.
221
+ </div>
222
+ <h3 class="accordion-title">
223
+ <button>
224
+ Second accordion item
225
+ </button>
226
+ </h3>
227
+ <div class="accordion-content">
228
+ Drop-down content goes here.
229
+ </div>
230
+ </div>
231
+
232
  = Filtering Shortcodes =
233
 
234
  You can filter the settings and content of the shortcodes by adding some simply code to the functions.php file of your theme.
265
  3. The Accordion Item shortcode insertion dialog box
266
 
267
  == Changelog ==
268
+ = 2.4.0 =
269
+ * NEW: Added option to add a button tag wrapper around the accordion title
270
+ * FIXED: better accessibility support
271
+ * Now compatible up to WordPress 5.1
272
+
273
  = 2.3.3 =
274
  * Now compatible up to WordPress 4.8
275
  * FIXED: aria-mutliselectable is now on the accordion group instead of each accordion item title
331
  * FIXED: A few incredibly small bugs/annoyances
332
 
333
  == Upgrade Notice ==
334
+ = 2.4.0 =
335
+ Updated accessibility. Added an option to a button wrapper around each accordion item title.
336
+
337
  = 2.3.2 =
338
  You may notice a focus state around your accordion items when clicking them. This is necessary to support accessibility within the plugin. If you really must remove the focus state (though not recommended) you can do so by adding this CSS to your theme's stylesheet: `.accordion-title {outline: none;}`.
339
 
tinymce/tinymce-plugin.js CHANGED
@@ -57,7 +57,18 @@
57
  {text: 'p', value: 'p'},
58
  {text: 'div', value: 'div'}
59
  ]
60
- }
 
 
 
 
 
 
 
 
 
 
 
61
  ],
62
  onsubmit: function(e) {
63
  var shortcode = '[' + accordionShortcodesPrefix + 'accordion';
@@ -80,6 +91,9 @@
80
  if (e.data.tag) {
81
  shortcode += ' tag=' + e.data.tag;
82
  }
 
 
 
83
 
84
  shortcode += ']' + editor.selection.getContent() + '[/' + accordionShortcodesPrefix + 'accordion]';
85
 
57
  {text: 'p', value: 'p'},
58
  {text: 'div', value: 'div'}
59
  ]
60
+ },
61
+ {
62
+ type: 'checkbox',
63
+ name: 'usebuttons',
64
+ label: 'Wrap title in <button> tag'
65
+ },
66
+ {
67
+ type: 'container',
68
+ name: 'container',
69
+ label: '',
70
+ html: '<div style="font-size: 0.75em;">Button tags are better for accessibility, but may require<br/>additional CSS styling to match your site design.</div>'
71
+ },
72
  ],
73
  onsubmit: function(e) {
74
  var shortcode = '[' + accordionShortcodesPrefix + 'accordion';
91
  if (e.data.tag) {
92
  shortcode += ' tag=' + e.data.tag;
93
  }
94
+ if (e.data.usebuttons) {
95
+ shortcode += ' usebuttons=' + e.data.usebuttons;
96
+ }
97
 
98
  shortcode += ']' + editor.selection.getContent() + '[/' + accordionShortcodesPrefix + 'accordion]';
99