Easy Table of Contents - Version 1.7

Version Description

Requires WordPress >

Download this release

Release Info

Developer shazahm1@hotmail.com
Plugin Icon 128x128 Easy Table of Contents
Version 1.7
Comparing to
See all releases

Code changes from version 1.6.1 to 1.7

README.txt CHANGED
@@ -2,10 +2,10 @@
2
  Contributors: shazahm1@hotmail.com
3
  Donate link: http://connections-pro.com/
4
  Tags: table of contents, toc
5
- Requires at least: 4.3
6
  Tested up to: 4.9
7
  Requires PHP: 5.3
8
- Stable tag: 1.6.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -90,6 +90,28 @@ Easy Table Contents is a fork of the excellent [Table of Contents Plus](https://
90
 
91
  == Changelog ==
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  = 1.6.1 03/16/2018 =
94
  * TWEAK: Revert change made to allow HTML added via the `ez_toc_title` filter as it caused undesirable side effects.
95
  * BUG: Ensure Smooth Scroll Offset is parsed as an integer.
@@ -244,3 +266,6 @@ Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
244
 
245
  = 1.6.1 =
246
  Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
 
 
 
2
  Contributors: shazahm1@hotmail.com
3
  Donate link: http://connections-pro.com/
4
  Tags: table of contents, toc
5
+ Requires at least: 4.4
6
  Tested up to: 4.9
7
  Requires PHP: 5.3
8
+ Stable tag: 1.7
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
90
 
91
  == Changelog ==
92
 
93
+ = 1.7 05/09/2018 =
94
+ * NEW: Introduce the `ez_toc_shortcode` filter.
95
+ * TWEAK: Fix notices due to late eligibility check. props unixtam
96
+ * TWEAK: Tweak eligibility check to support the TOC widget.
97
+ * TWEAK: Prefix a few CSS classes in order to prevent collisions with theme's and other plugins.
98
+ * TWEAK: Avoid potential PHP notice in admin when saving the post by checking for nonce before validating it.
99
+ * TWEAK: Using the shortcode now overrides global options.
100
+ * TWEAK: `the_content()` now caches result of `is_eligible()`.
101
+ * TWEAK: Refactor to pass the WP_Post object internally vs. accessing it via the `$wp_query->post` which may not in all cases exist.
102
+ * TWEAK: Use `pre_replace()` to replace one or more spaces with an underscore.
103
+ * TWEAK: Return original title in the `ez_toc_url_anchor_target` filter.
104
+ * TWEAK: Strip ` `, replacing it with a space character.
105
+ * TWEAK: Minor tweaks to the in page URL creating.
106
+ * TWEAK: Wrap TOC list in a nav element.
107
+ * TWEAK: Init plugin on the `plugins_loaded` hook.
108
+ * TWEAK: Tweak the minimum number of headers to 1.
109
+ * BUG: The header options from the post meta should be used when building the TOC hierarchy, not the header options from the global settings.
110
+ * BUG: Do not double escape field values.
111
+ * BUG: Ensure Apostrophe / Single quote use in Exclude Headings work.
112
+ * OTHER: Update CSS to include the newly prefixed classes.
113
+ * DEV: Remove some commented out unused code.
114
+
115
  = 1.6.1 03/16/2018 =
116
  * TWEAK: Revert change made to allow HTML added via the `ez_toc_title` filter as it caused undesirable side effects.
117
  * BUG: Ensure Smooth Scroll Offset is parsed as an integer.
266
 
267
  = 1.6.1 =
268
  Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
269
+
270
+ = 1.7 =
271
+ Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
assets/css/screen.css CHANGED
@@ -181,7 +181,7 @@
181
  font-weight: 900;
182
  }
183
 
184
- .btn {
185
  display: inline-block;
186
  padding: 6px 12px;
187
  margin-bottom: 0;
@@ -202,37 +202,37 @@
202
  user-select: none
203
  }
204
 
205
- .btn:focus {
206
  outline: thin dotted #333;
207
  outline: 5px auto -webkit-focus-ring-color;
208
  outline-offset: -2px
209
  }
210
 
211
- .btn:hover,.btn:focus {
212
  color: #333;
213
  text-decoration: none
214
  }
215
 
216
- .btn:active,.btn.active {
217
  background-image: none;
218
  outline: 0;
219
  -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
220
  box-shadow: inset 0 3px 5px rgba(0,0,0,0.125)
221
  }
222
 
223
- .btn-default {
224
  color: #333;
225
  background-color: #fff;
226
  border-color: #ccc
227
  }
228
 
229
- .btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active {
230
  color: #333;
231
  background-color: #ebebeb;
232
  border-color: #adadad
233
  }
234
 
235
- .btn-default:active,.btn-default.active {
236
  background-image: none
237
  }
238
 
@@ -243,33 +243,33 @@
243
  /*border-radius: 6px*/
244
  /*}*/
245
 
246
- .btn-sm,.btn-xs {
247
  padding: 5px 10px;
248
  font-size: 12px;
249
  line-height: 1.5;
250
  border-radius: 3px
251
  }
252
 
253
- .btn-xs {
254
  padding: 1px 5px
255
  }
256
 
257
- .btn-default {
258
  text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
259
  -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);
260
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)
261
  }
262
 
263
- .btn-default:active {
264
  -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
265
  box-shadow: inset 0 3px 5px rgba(0,0,0,0.125)
266
  }
267
 
268
- .btn:active,.btn.active {
269
  background-image: none
270
  }
271
 
272
- .btn-default {
273
  text-shadow: 0 1px 0 #fff;
274
  background-image: -webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));
275
  background-image: -webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);
@@ -282,22 +282,22 @@
282
  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false)
283
  }
284
 
285
- .btn-default:hover,.btn-default:focus {
286
  background-color: #e0e0e0;
287
  background-position: 0 -15px
288
  }
289
 
290
- .btn-default:active,.btn-default.active {
291
  background-color: #e0e0e0;
292
  border-color: #dbdbdb
293
  }
294
 
295
- .pull-right {
296
  float: right !important;
297
  margin-left: 10px;
298
  }
299
 
300
- .glyphicon {
301
  position: relative;
302
  top: 1px;
303
  display: inline-block;
@@ -309,11 +309,11 @@
309
  -moz-osx-font-smoothing: grayscale
310
  }
311
 
312
- .glyphicon:empty {
313
  width: 1em
314
  }
315
 
316
- .ez-toc-toggle i.glyphicon {
317
  font-size: 16px;
318
  margin-left: 2px;
319
  }
181
  font-weight: 900;
182
  }
183
 
184
+ .ez-toc-btn {
185
  display: inline-block;
186
  padding: 6px 12px;
187
  margin-bottom: 0;
202
  user-select: none
203
  }
204
 
205
+ .ez-toc-btn:focus {
206
  outline: thin dotted #333;
207
  outline: 5px auto -webkit-focus-ring-color;
208
  outline-offset: -2px
209
  }
210
 
211
+ .ez-toc-btn:hover,.ez-toc-btn:focus {
212
  color: #333;
213
  text-decoration: none
214
  }
215
 
216
+ .ez-toc-btn:active,.ez-toc-btn.active {
217
  background-image: none;
218
  outline: 0;
219
  -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
220
  box-shadow: inset 0 3px 5px rgba(0,0,0,0.125)
221
  }
222
 
223
+ .ez-toc-btn-default {
224
  color: #333;
225
  background-color: #fff;
226
  border-color: #ccc
227
  }
228
 
229
+ .ez-toc-btn-default:hover,.ez-toc-btn-default:focus,.ez-toc-btn-default:active,.ez-toc-btn-default.active {
230
  color: #333;
231
  background-color: #ebebeb;
232
  border-color: #adadad
233
  }
234
 
235
+ .ez-toc-btn-default:active,.ez-toc-btn-default.active {
236
  background-image: none
237
  }
238
 
243
  /*border-radius: 6px*/
244
  /*}*/
245
 
246
+ .ez-toc-btn-sm,.ez-toc-btn-xs {
247
  padding: 5px 10px;
248
  font-size: 12px;
249
  line-height: 1.5;
250
  border-radius: 3px
251
  }
252
 
253
+ .ez-toc-btn-xs {
254
  padding: 1px 5px
255
  }
256
 
257
+ .ez-toc-btn-default {
258
  text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
259
  -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);
260
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)
261
  }
262
 
263
+ .ez-toc-btn-default:active {
264
  -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125);
265
  box-shadow: inset 0 3px 5px rgba(0,0,0,0.125)
266
  }
267
 
268
+ .ez-toc-btn:active,.btn.active {
269
  background-image: none
270
  }
271
 
272
+ .ez-toc-btn-default {
273
  text-shadow: 0 1px 0 #fff;
274
  background-image: -webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));
275
  background-image: -webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);
282
  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false)
283
  }
284
 
285
+ .ez-toc-btn-default:hover,.ez-toc-btn-default:focus {
286
  background-color: #e0e0e0;
287
  background-position: 0 -15px
288
  }
289
 
290
+ .ez-toc-btn-default:active,.ez-toc-btn-default.active {
291
  background-color: #e0e0e0;
292
  border-color: #dbdbdb
293
  }
294
 
295
+ .ez-toc-pull-right {
296
  float: right !important;
297
  margin-left: 10px;
298
  }
299
 
300
+ .ez-toc-glyphicon {
301
  position: relative;
302
  top: 1px;
303
  display: inline-block;
309
  -moz-osx-font-smoothing: grayscale
310
  }
311
 
312
+ .ez-toc-glyphicon:empty {
313
  width: 1em
314
  }
315
 
316
+ .ez-toc-toggle i.ez-toc-glyphicon {
317
  font-size: 16px;
318
  margin-left: 2px;
319
  }
assets/css/screen.min.css CHANGED
@@ -1 +1 @@
1
- #ez-toc-container{background:#F9F9F9;border:1px solid #AAA;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);display:table;margin-bottom:1em;padding:10px;position:relative;width:auto}.ez-toc-widget-container{position:relative;white-space:nowrap}#ez-toc-container.ez-toc-light-blue{background:#EDF6FF}#ez-toc-container.ez-toc-white{background:#FFF}#ez-toc-container.ez-toc-black{background:#000}#ez-toc-container.ez-toc-transparent{background:none}.ez-toc-widget-container ul.ez-toc-list{padding:0 10px}#ez-toc-container ul ul,.ez-toc div.ez-toc-widget-container ul ul{margin-left:1.5em}#ez-toc-container li,#ez-toc-container ul{padding:0}#ez-toc-container li,#ez-toc-container ul,#ez-toc-container ul li,.ez-toc-widget-container,.ez-toc-widget-container li{background:0 0;list-style:none;line-height:1.6;margin:0;overflow:hidden;z-index:1}.btn,.btn-default.active,.btn-default:active{background-image:none}#ez-toc-container p.ez-toc-title{text-align:left;line-height:1.45;margin:0;padding:0}.ez-toc-title-container{display:table;width:100%}.ez-toc-title,.ez-toc-title-toggle{display:table-cell;text-align:left;vertical-align:middle}.btn,.glyphicon{display:inline-block}#ez-toc-container.ez-toc-black p.ez-toc-title{color:#FFF}#ez-toc-container div.ez-toc-title-container+ul.ez-toc-list{margin-top:1em}.ez-toc-wrap-left{float:left;margin-right:10px}.ez-toc-wrap-right{float:right;margin-left:10px}#ez-toc-container a{color:#444;text-decoration:none;text-shadow:none}#ez-toc-container a:visited{color:#9f9f9f}#ez-toc-container a:hover{text-decoration:underline}#ez-toc-container.ez-toc-black a,#ez-toc-container.ez-toc-black a:visited{color:#FFF}#ez-toc-container a.ez-toc-toggle{color:#444}#ez-toc-container.counter-flat ul,#ez-toc-container.counter-hierarchy ul,.ez-toc-widget-container.counter-flat ul,.ez-toc-widget-container.counter-hierarchy ul{counter-reset:item}#ez-toc-container.counter-numeric li,.ez-toc-widget-container.counter-numeric li{list-style-type:decimal;list-style-position:inside}#ez-toc-container.counter-decimal ul.ez-toc-list li a::before,.ez-toc-widget-container.counter-decimal ul.ez-toc-list li a::before{content:counters(item,".") ". ";counter-increment:item}#ez-toc-container.counter-roman li a::before,.ez-toc-widget-container.counter-roman ul.ez-toc-list li a::before{content:counters(item,".",upper-roman) ". ";counter-increment:item}.ez-toc-widget-container ul.ez-toc-list li::before{content:' ';position:absolute;left:0;right:0;height:30px;line-height:30px;z-index:-1}.ez-toc-widget-container ul.ez-toc-list li.active::before{background-color:#EDEDED}.ez-toc-widget-container li.active>a{font-weight:900}.btn{padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-image:none}.btn-default{color:#333;background-color:#fff}.btn-default.active,.btn-default:active,.btn-default:focus,.btn-default:hover{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.glyphicon,[class*=ez-toc-icon-]{font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.btn-xs{padding:1px 5px}.btn-default{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-moz-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-default:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.pull-right{float:right!important;margin-left:10px}.glyphicon{position:relative;top:1px;font-family:'Glyphicons Halflings'}.glyphicon:empty{width:1em}.ez-toc-toggle i.glyphicon{font-size:16px;margin-left:2px}[class*=ez-toc-icon-]{font-family:ez-toc-icomoon!important;speak:none;font-variant:normal;text-transform:none}.ez-toc-icon-toggle:before{content:"\e87a"}
1
+ #ez-toc-container{background:#F9F9F9;border:1px solid #AAA;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);display:table;margin-bottom:1em;padding:10px;position:relative;width:auto}.ez-toc-widget-container{position:relative;white-space:nowrap}#ez-toc-container.ez-toc-light-blue{background:#EDF6FF}#ez-toc-container.ez-toc-white{background:#FFF}#ez-toc-container.ez-toc-black{background:#000}#ez-toc-container.ez-toc-transparent{background:none}.ez-toc-widget-container ul.ez-toc-list{padding:0 10px}#ez-toc-container ul ul,.ez-toc div.ez-toc-widget-container ul ul{margin-left:1.5em}#ez-toc-container li,#ez-toc-container ul{padding:0}#ez-toc-container li,#ez-toc-container ul,#ez-toc-container ul li,.ez-toc-widget-container,.ez-toc-widget-container li{background:0 0;list-style:none;line-height:1.6;margin:0;overflow:hidden;z-index:1}.btn.active,.ez-toc-btn,.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn:active{background-image:none}#ez-toc-container p.ez-toc-title{text-align:left;line-height:1.45;margin:0;padding:0}.ez-toc-title-container{display:table;width:100%}.ez-toc-title,.ez-toc-title-toggle{display:table-cell;text-align:left;vertical-align:middle}#ez-toc-container.ez-toc-black p.ez-toc-title{color:#FFF}#ez-toc-container div.ez-toc-title-container+ul.ez-toc-list{margin-top:1em}.ez-toc-wrap-left{float:left;margin-right:10px}.ez-toc-wrap-right{float:right;margin-left:10px}#ez-toc-container a{color:#444;text-decoration:none;text-shadow:none}#ez-toc-container a:visited{color:#9f9f9f}#ez-toc-container a:hover{text-decoration:underline}#ez-toc-container.ez-toc-black a,#ez-toc-container.ez-toc-black a:visited{color:#FFF}#ez-toc-container a.ez-toc-toggle{color:#444}#ez-toc-container.counter-flat ul,#ez-toc-container.counter-hierarchy ul,.ez-toc-widget-container.counter-flat ul,.ez-toc-widget-container.counter-hierarchy ul{counter-reset:item}#ez-toc-container.counter-numeric li,.ez-toc-widget-container.counter-numeric li{list-style-type:decimal;list-style-position:inside}#ez-toc-container.counter-decimal ul.ez-toc-list li a::before,.ez-toc-widget-container.counter-decimal ul.ez-toc-list li a::before{content:counters(item,".") ". ";counter-increment:item}#ez-toc-container.counter-roman li a::before,.ez-toc-widget-container.counter-roman ul.ez-toc-list li a::before{content:counters(item,".",upper-roman) ". ";counter-increment:item}.ez-toc-widget-container ul.ez-toc-list li::before{content:' ';position:absolute;left:0;right:0;height:30px;line-height:30px;z-index:-1}.ez-toc-widget-container ul.ez-toc-list li.active::before{background-color:#EDEDED}.ez-toc-widget-container li.active>a{font-weight:900}.ez-toc-btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.ez-toc-btn:focus{outline:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.ez-toc-btn:focus,.ez-toc-btn:hover{color:#333;text-decoration:none}.ez-toc-btn.active,.ez-toc-btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{color:#333;background-color:#fff;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{color:#333;background-color:#ebebeb;border-color:#adadad}.ez-toc-btn-sm,.ez-toc-btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.ez-toc-glyphicon,[class*=ez-toc-icon-]{font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ez-toc-btn-xs{padding:1px 5px}.ez-toc-btn-default:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-moz-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.ez-toc-btn-default.active,.ez-toc-btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.ez-toc-pull-right{float:right!important;margin-left:10px}.ez-toc-glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings'}.ez-toc-glyphicon:empty{width:1em}.ez-toc-toggle i.ez-toc-glyphicon{font-size:16px;margin-left:2px}[class*=ez-toc-icon-]{font-family:ez-toc-icomoon!important;speak:none;font-variant:normal;text-transform:none}.ez-toc-icon-toggle:before{content:"\e87a"}
easy-table-of-contents.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Easy Table of Contents
4
  * Plugin URI: http://connections-pro.com/
5
  * Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
6
- * Version: 1.6.1
7
  * Author: Steven A. Zahm
8
  * Author URI: http://connections-pro.com/
9
  * Text Domain: easy-table-of-contents
@@ -26,7 +26,7 @@
26
  * @package Easy Table of Contents
27
  * @category Plugin
28
  * @author Steven A. Zahm
29
- * @version 1.6.1
30
  */
31
 
32
  // Exit if accessed directly
@@ -45,7 +45,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
45
  * @since 1.0
46
  * @var string
47
  */
48
- const VERSION = '1.6.1';
49
 
50
  /**
51
  * Stores the instance of this class.
@@ -93,6 +93,8 @@ if ( ! class_exists( 'ezTOC' ) ) {
93
  self::defineConstants();
94
  self::includes();
95
  self::hooks();
 
 
96
  }
97
 
98
  return self::$instance;
@@ -142,13 +144,13 @@ if ( ! class_exists( 'ezTOC' ) ) {
142
  */
143
  private static function hooks() {
144
 
145
- add_action( 'plugins_loaded', array( __CLASS__, 'loadTextdomain' ) );
146
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
147
 
148
  // Run after shortcodes are interpreted (priority 10).
149
  add_filter( 'the_content', array( __CLASS__, 'the_content' ), 100 );
150
  add_shortcode( 'ez-toc', array( __CLASS__, 'shortcode' ) );
151
- add_shortcode( 'toc', array( __CLASS__, 'shortcode' ) );
152
  }
153
 
154
  /**
@@ -338,7 +340,10 @@ if ( ! class_exists( 'ezTOC' ) ) {
338
 
339
  if ( $title ) {
340
 
341
- $return = trim( strip_tags( $title ) );
 
 
 
342
 
343
  // Convert accented characters to ASCII.
344
  $return = remove_accents( $return );
@@ -346,18 +351,18 @@ if ( ! class_exists( 'ezTOC' ) ) {
346
  // replace newlines with spaces (eg when headings are split over multiple lines)
347
  $return = str_replace( array( "\r", "\n", "\n\r", "\r\n" ), ' ', $return );
348
 
349
- // remove &
350
- $return = str_replace( '&', '', $return );
 
 
 
 
351
 
352
  // remove non alphanumeric chars
353
  $return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
354
 
355
  // convert spaces to _
356
- $return = str_replace(
357
- array( ' ', ' ' ),
358
- '_',
359
- $return
360
- );
361
 
362
  // remove trailing - and _
363
  $return = rtrim( $return, '-_' );
@@ -385,7 +390,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
385
 
386
  if ( array_key_exists( $return, self::$collision_collector ) ) {
387
 
388
- self::$collision_collector[ $return ] ++;
389
  $return .= '-' . self::$collision_collector[ $return ];
390
 
391
  } else {
@@ -393,7 +398,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
393
  self::$collision_collector[ $return ] = 1;
394
  }
395
 
396
- return apply_filters( 'ez_toc_url_anchor_target', $return );
397
  }
398
 
399
  /**
@@ -404,10 +409,11 @@ if ( ! class_exists( 'ezTOC' ) ) {
404
  * @static
405
  *
406
  * @param array $matches
 
407
  *
408
  * @return string
409
  */
410
- private static function build_hierarchy( &$matches ) {
411
 
412
  $current_depth = 100; // headings can't be larger than h6 but 100 as a default to be sure
413
  $html = '';
@@ -445,7 +451,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
445
  }
446
 
447
  // list item
448
- if ( in_array( $matches[ $i ][2], ezTOC_Option::get( 'heading_levels' ) ) ) {
449
 
450
  //$title = apply_filters( 'ez_toc_title', strip_tags( wp_kses_post( $matches[ $i ][0] ) ) );
451
  $title = strip_tags( apply_filters( 'ez_toc_title', $matches[ $i ][0] ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
@@ -579,17 +585,13 @@ if ( ! class_exists( 'ezTOC' ) ) {
579
  * @since 1.0
580
  * @static
581
  *
582
- * @param array $find
583
- * @param array $replace
584
- * @param string $content
585
  *
586
  * @return bool|string
587
  */
588
- public static function extract_headings( &$find, &$replace, $content = '' ) {
589
-
590
- global $wp_query;
591
-
592
- $post = $wp_query->post;
593
 
594
  $matches = array();
595
  $anchor = '';
@@ -619,7 +621,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
619
  // the head html tag, or to provide descriptions to twitter/facebook
620
  self::$collision_collector = array();
621
 
622
- $content = apply_filters( 'ez_toc_extract_headings_content', $content );
623
 
624
  if ( is_array( $find ) && is_array( $replace ) && $content ) {
625
 
@@ -671,7 +673,21 @@ if ( ! class_exists( 'ezTOC' ) ) {
671
 
672
  for ( $j = 0; $j < $excluded_count; $j++ ) {
673
 
674
- if ( @preg_match( '/^' . $excluded_headings[ $j ] . '$/imU', strip_tags( $matches[ $i ][0] ) ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
675
 
676
  $found = TRUE;
677
  break;
@@ -796,7 +812,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
796
  // we could have tested for $items but that var can be quite large in some cases
797
  if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
798
 
799
- $items = self::build_hierarchy( $toc );
800
  }
801
 
802
  }
@@ -845,19 +861,25 @@ if ( ! class_exists( 'ezTOC' ) ) {
845
  global $wp_query;
846
 
847
  $post = $wp_query->post;
848
- $type = get_post_type( $post->ID );
849
 
850
- // do not trigger the TOC when displaying an XML/RSS feed
851
- if ( is_feed() ) {
 
852
 
 
 
 
 
 
853
  return FALSE;
854
  }
855
 
 
 
856
  $enabled = in_array( $type, ezTOC_Option::get( 'enabled_post_types', array() ) );
857
  $insert = in_array( $type, ezTOC_Option::get( 'auto_insert_post_types', array() ) );
858
 
859
- if ( ( ( $insert || $enabled ) && ! is_search() && ! is_archive() && ! is_front_page() ) ||
860
- ( ezTOC_Option::get( 'include_homepage' ) && is_front_page() ) ) {
861
 
862
  if ( ezTOC_Option::get( 'restrict_path' ) ) {
863
 
@@ -914,151 +936,148 @@ if ( ! class_exists( 'ezTOC' ) ) {
914
  * @since 1.3
915
  * @static
916
  *
917
- * @param string $content The page/post content.
918
  *
919
  * @return array
920
  */
921
- public static function build( $content ) {
922
 
923
  $css_classes = '';
924
 
925
  $html = '';
926
  $find = array();
927
  $replace = array();
928
- $items = self::extract_headings( $find, $replace, $content );
929
 
930
  if ( $items ) {
931
 
932
- if ( self::is_eligible() ) {
 
933
 
934
- // wrapping css classes
935
- switch ( ezTOC_Option::get( 'wrapping' ) ) {
936
-
937
- case 'left':
938
- $css_classes .= ' ez-toc-wrap-left';
939
- break;
940
 
941
- case 'right':
942
- $css_classes .= ' ez-toc-wrap-right';
943
- break;
944
 
945
- case 'none':
946
- default:
947
- // do nothing
948
- }
949
 
950
- if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
951
 
952
- $css_classes .= ' counter-hierarchy';
953
 
954
- } else {
955
 
956
- $css_classes .= ' counter-flat';
957
- }
958
 
959
- switch ( ezTOC_Option::get( 'counter' ) ) {
960
 
961
- case 'numeric':
962
- $css_classes .= ' counter-numeric';
963
- break;
964
 
965
- case 'roman':
966
- $css_classes .= ' counter-roman';
967
- break;
968
 
969
- case 'decimal':
970
- $css_classes .= ' counter-decimal';
971
- break;
972
- }
973
 
974
- // colour themes
975
- switch ( ezTOC_Option::get( 'theme' ) ) {
976
 
977
- case 'light-blue':
978
- $css_classes .= ' ez-toc-light-blue';
979
- break;
980
 
981
- case 'white':
982
- $css_classes .= ' ez-toc-white';
983
- break;
984
 
985
- case 'black':
986
- $css_classes .= ' ez-toc-black';
987
- break;
988
 
989
- case 'transparent':
990
- $css_classes .= ' ez-toc-transparent';
991
- break;
992
 
993
- case 'grey':
994
- $css_classes .= ' ez-toc-grey';
995
- break;
996
 
997
- default:
998
- // do nothing
999
- }
1000
 
1001
- if ( ezTOC_Option::get( 'css_container_class' ) ) {
1002
 
1003
- $css_classes .= ' ' . ezTOC_Option::get( 'css_container_class' );
1004
- }
1005
 
1006
- $css_classes = trim( $css_classes );
1007
 
1008
- // an empty class="" is invalid markup!
1009
- if ( ! $css_classes ) {
1010
 
1011
- $css_classes = ' ';
1012
- }
1013
 
1014
- // add container, toc title and list items
1015
- $html .= '<div id="ez-toc-container" class="' . $css_classes . '">' . PHP_EOL;
1016
 
1017
- if ( ezTOC_Option::get( 'show_heading_text' ) ) {
1018
 
1019
- $toc_title = ezTOC_Option::get( 'heading_text' );
1020
 
1021
- if ( strpos( $toc_title, '%PAGE_TITLE%' ) !== FALSE ) {
1022
 
1023
- $toc_title = str_replace( '%PAGE_TITLE%', get_the_title(), $toc_title );
1024
- }
1025
 
1026
- if ( strpos( $toc_title, '%PAGE_NAME%' ) !== FALSE ) {
1027
 
1028
- $toc_title = str_replace( '%PAGE_NAME%', get_the_title(), $toc_title );
1029
- }
1030
 
1031
- $html .= '<div class="ez-toc-title-container">' . PHP_EOL;
1032
 
1033
- $html .= '<p class="ez-toc-title">' . esc_html( htmlentities( $toc_title, ENT_COMPAT, 'UTF-8' ) ). '</p>' . PHP_EOL;
1034
 
1035
- $html .= '<span class="ez-toc-title-toggle">';
1036
 
1037
- if ( ezTOC_Option::get( 'visibility' ) ) {
1038
 
1039
- $html .= '<a class="pull-right btn btn-xs btn-default ez-toc-toggle"><i class="glyphicon ez-toc-icon-toggle"></i></a>';
1040
- }
1041
 
1042
- $html .= '</span>';
1043
 
1044
- $html .= '</div>' . PHP_EOL;
1045
- }
1046
 
1047
- ob_start();
1048
- do_action( 'ez_toc_before' );
1049
- $html .= ob_get_clean();
1050
 
1051
- $html .= '<ul class="ez-toc-list">' . $items . '</ul>';
1052
 
1053
- ob_start();
1054
- do_action( 'ez_toc_after' );
1055
- $html .= ob_get_clean();
1056
 
1057
- $html .= '</div>' . PHP_EOL;
1058
 
1059
- // Enqueue the script.
1060
- wp_enqueue_script( 'ez-toc-js' );
1061
- }
1062
  }
1063
 
1064
  return array( 'find' => $find, 'replace' => $replace, 'content' => $html );
@@ -1086,8 +1105,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
1086
 
1087
  if ( $run ) {
1088
 
1089
- $id = get_the_ID();
1090
- $args = self::build( get_the_content( $id ) );
1091
  $out = $args['content'];
1092
  $run = FALSE;
1093
  }
@@ -1111,45 +1129,69 @@ if ( ! class_exists( 'ezTOC' ) ) {
1111
  */
1112
  public static function the_content( $content ) {
1113
 
1114
- $args = self::build( $content );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  $find = $args['find'];
1116
  $replace = $args['replace'];
1117
  $html = $args['content'];
1118
 
1119
- if ( count( $find ) > 0 ) {
1120
-
1121
- // If the TOC was embedded in the content using the `[ez-toc]` shortcode, skip. TOC should only exist once.
1122
- if ( strpos( $content, 'ez-toc-container' ) ) {
1123
 
1124
- return self::mb_find_replace( $find, $replace, $content );
1125
- }
1126
 
1127
- switch ( ezTOC_Option::get( 'position' ) ) {
 
1128
 
1129
- //case 'placeholder':
1130
- // $content = self::mb_find_replace( $find, $replace, $content );
1131
- // $content = preg_replace( '/\[toc.*\]/i', $html, $content );
1132
- // break;
1133
 
1134
- case 'top':
1135
- $content = $html . self::mb_find_replace( $find, $replace, $content );
1136
- break;
1137
 
1138
- case 'bottom':
1139
- $content = self::mb_find_replace( $find, $replace, $content ) . $html;
1140
- break;
1141
 
1142
- case 'after':
1143
- $replace[0] = $replace[0] . $html;
1144
- $content = self::mb_find_replace( $find, $replace, $content );
1145
- break;
1146
 
1147
- case 'before':
1148
- default:
1149
- $replace[0] = $html . $replace[0];
1150
- $content = self::mb_find_replace( $find, $replace, $content );
1151
- }
1152
 
 
 
 
 
1153
  }
1154
 
1155
  return $content;
@@ -1175,7 +1217,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
1175
  }
1176
 
1177
  // Start Easy Table of Contents.
1178
- ezTOC();
1179
  }
1180
 
1181
 
3
  * Plugin Name: Easy Table of Contents
4
  * Plugin URI: http://connections-pro.com/
5
  * Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
6
+ * Version: 1.7
7
  * Author: Steven A. Zahm
8
  * Author URI: http://connections-pro.com/
9
  * Text Domain: easy-table-of-contents
26
  * @package Easy Table of Contents
27
  * @category Plugin
28
  * @author Steven A. Zahm
29
+ * @version 1.7
30
  */
31
 
32
  // Exit if accessed directly
45
  * @since 1.0
46
  * @var string
47
  */
48
+ const VERSION = '1.7';
49
 
50
  /**
51
  * Stores the instance of this class.
93
  self::defineConstants();
94
  self::includes();
95
  self::hooks();
96
+
97
+ self::loadTextdomain();
98
  }
99
 
100
  return self::$instance;
144
  */
145
  private static function hooks() {
146
 
147
+ //add_action( 'plugins_loaded', array( __CLASS__, 'loadTextdomain' ) );
148
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
149
 
150
  // Run after shortcodes are interpreted (priority 10).
151
  add_filter( 'the_content', array( __CLASS__, 'the_content' ), 100 );
152
  add_shortcode( 'ez-toc', array( __CLASS__, 'shortcode' ) );
153
+ add_shortcode( apply_filters( 'ez_toc_shortcode', 'toc' ), array( __CLASS__, 'shortcode' ) );
154
  }
155
 
156
  /**
340
 
341
  if ( $title ) {
342
 
343
+ // WP entity encodes the post content.
344
+ $return = html_entity_decode( $title, ENT_QUOTES, get_option( 'blog_charset' ) );
345
+
346
+ $return = trim( strip_tags( $return ) );
347
 
348
  // Convert accented characters to ASCII.
349
  $return = remove_accents( $return );
351
  // replace newlines with spaces (eg when headings are split over multiple lines)
352
  $return = str_replace( array( "\r", "\n", "\n\r", "\r\n" ), ' ', $return );
353
 
354
+ // Remove `&amp;` and `&nbsp;` NOTE: in order to strip "hidden" `&nbsp;`,
355
+ // title needs to be converted to HTML entities.
356
+ // @link https://stackoverflow.com/a/21801444/5351316
357
+ $return = htmlentities2( $return );
358
+ $return = str_replace( array( '&amp;', '&nbsp;' ), ' ', $return );
359
+ $return = html_entity_decode( $return, ENT_QUOTES, get_option( 'blog_charset' ) );
360
 
361
  // remove non alphanumeric chars
362
  $return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
363
 
364
  // convert spaces to _
365
+ $return = preg_replace( '/\s+/', '_', $return );
 
 
 
 
366
 
367
  // remove trailing - and _
368
  $return = rtrim( $return, '-_' );
390
 
391
  if ( array_key_exists( $return, self::$collision_collector ) ) {
392
 
393
+ self::$collision_collector[ $return ]++;
394
  $return .= '-' . self::$collision_collector[ $return ];
395
 
396
  } else {
398
  self::$collision_collector[ $return ] = 1;
399
  }
400
 
401
+ return apply_filters( 'ez_toc_url_anchor_target', $return, $title );
402
  }
403
 
404
  /**
409
  * @static
410
  *
411
  * @param array $matches
412
+ * @param array $headings Array of headers to be considered for a TOC item.
413
  *
414
  * @return string
415
  */
416
+ private static function build_hierarchy( &$matches, $headings ) {
417
 
418
  $current_depth = 100; // headings can't be larger than h6 but 100 as a default to be sure
419
  $html = '';
451
  }
452
 
453
  // list item
454
+ if ( in_array( $matches[ $i ][2], $headings ) ) {
455
 
456
  //$title = apply_filters( 'ez_toc_title', strip_tags( wp_kses_post( $matches[ $i ][0] ) ) );
457
  $title = strip_tags( apply_filters( 'ez_toc_title', $matches[ $i ][0] ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
585
  * @since 1.0
586
  * @static
587
  *
588
+ * @param array $find
589
+ * @param array $replace
590
+ * @param WP_Post $post
591
  *
592
  * @return bool|string
593
  */
594
+ public static function extract_headings( &$find, &$replace, $post ) {
 
 
 
 
595
 
596
  $matches = array();
597
  $anchor = '';
621
  // the head html tag, or to provide descriptions to twitter/facebook
622
  self::$collision_collector = array();
623
 
624
+ $content = apply_filters( 'ez_toc_extract_headings_content', $post->post_content );
625
 
626
  if ( is_array( $find ) && is_array( $replace ) && $content ) {
627
 
673
 
674
  for ( $j = 0; $j < $excluded_count; $j++ ) {
675
 
676
+ // Since WP manipulates the post content it is required that the excluded header and
677
+ // the actual header be manipulated similarly so a match can be made.
678
+ $pattern = html_entity_decode(
679
+ wptexturize( $excluded_headings[ $j ] ),
680
+ ENT_NOQUOTES,
681
+ get_option( 'blog_charset' )
682
+ );
683
+
684
+ $against = html_entity_decode(
685
+ wptexturize( strip_tags( $matches[ $i ][0] ) ),
686
+ ENT_NOQUOTES,
687
+ get_option( 'blog_charset' )
688
+ );
689
+
690
+ if ( @preg_match( '/^' . $pattern . '$/imU', $against ) ) {
691
 
692
  $found = TRUE;
693
  break;
812
  // we could have tested for $items but that var can be quite large in some cases
813
  if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
814
 
815
+ $items = self::build_hierarchy( $toc, $headings );
816
  }
817
 
818
  }
861
  global $wp_query;
862
 
863
  $post = $wp_query->post;
 
864
 
865
+ if ( empty( $post ) ) {
866
+ return FALSE;
867
+ }
868
 
869
+ if ( has_shortcode( $post->post_content, 'toc' ) || has_shortcode( $post->post_content, 'ez-toc' ) ) {
870
+ return TRUE;
871
+ }
872
+
873
+ if ( is_front_page() && ! ezTOC_Option::get( 'include_homepage' ) ) {
874
  return FALSE;
875
  }
876
 
877
+ $type = get_post_type( $post->ID );
878
+
879
  $enabled = in_array( $type, ezTOC_Option::get( 'enabled_post_types', array() ) );
880
  $insert = in_array( $type, ezTOC_Option::get( 'auto_insert_post_types', array() ) );
881
 
882
+ if ( $insert || $enabled ) {
 
883
 
884
  if ( ezTOC_Option::get( 'restrict_path' ) ) {
885
 
936
  * @since 1.3
937
  * @static
938
  *
939
+ * @param WP_Post $post The page/post content.
940
  *
941
  * @return array
942
  */
943
+ public static function build( $post ) {
944
 
945
  $css_classes = '';
946
 
947
  $html = '';
948
  $find = array();
949
  $replace = array();
950
+ $items = self::extract_headings( $find, $replace, $post );
951
 
952
  if ( $items ) {
953
 
954
+ // wrapping css classes
955
+ switch ( ezTOC_Option::get( 'wrapping' ) ) {
956
 
957
+ case 'left':
958
+ $css_classes .= ' ez-toc-wrap-left';
959
+ break;
 
 
 
960
 
961
+ case 'right':
962
+ $css_classes .= ' ez-toc-wrap-right';
963
+ break;
964
 
965
+ case 'none':
966
+ default:
967
+ // do nothing
968
+ }
969
 
970
+ if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
971
 
972
+ $css_classes .= ' counter-hierarchy';
973
 
974
+ } else {
975
 
976
+ $css_classes .= ' counter-flat';
977
+ }
978
 
979
+ switch ( ezTOC_Option::get( 'counter' ) ) {
980
 
981
+ case 'numeric':
982
+ $css_classes .= ' counter-numeric';
983
+ break;
984
 
985
+ case 'roman':
986
+ $css_classes .= ' counter-roman';
987
+ break;
988
 
989
+ case 'decimal':
990
+ $css_classes .= ' counter-decimal';
991
+ break;
992
+ }
993
 
994
+ // colour themes
995
+ switch ( ezTOC_Option::get( 'theme' ) ) {
996
 
997
+ case 'light-blue':
998
+ $css_classes .= ' ez-toc-light-blue';
999
+ break;
1000
 
1001
+ case 'white':
1002
+ $css_classes .= ' ez-toc-white';
1003
+ break;
1004
 
1005
+ case 'black':
1006
+ $css_classes .= ' ez-toc-black';
1007
+ break;
1008
 
1009
+ case 'transparent':
1010
+ $css_classes .= ' ez-toc-transparent';
1011
+ break;
1012
 
1013
+ case 'grey':
1014
+ $css_classes .= ' ez-toc-grey';
1015
+ break;
1016
 
1017
+ default:
1018
+ // do nothing
1019
+ }
1020
 
1021
+ if ( ezTOC_Option::get( 'css_container_class' ) ) {
1022
 
1023
+ $css_classes .= ' ' . ezTOC_Option::get( 'css_container_class' );
1024
+ }
1025
 
1026
+ $css_classes = trim( $css_classes );
1027
 
1028
+ // an empty class="" is invalid markup!
1029
+ if ( ! $css_classes ) {
1030
 
1031
+ $css_classes = ' ';
1032
+ }
1033
 
1034
+ // add container, toc title and list items
1035
+ $html .= '<div id="ez-toc-container" class="' . $css_classes . '">' . PHP_EOL;
1036
 
1037
+ if ( ezTOC_Option::get( 'show_heading_text' ) ) {
1038
 
1039
+ $toc_title = ezTOC_Option::get( 'heading_text' );
1040
 
1041
+ if ( strpos( $toc_title, '%PAGE_TITLE%' ) !== FALSE ) {
1042
 
1043
+ $toc_title = str_replace( '%PAGE_TITLE%', get_the_title(), $toc_title );
1044
+ }
1045
 
1046
+ if ( strpos( $toc_title, '%PAGE_NAME%' ) !== FALSE ) {
1047
 
1048
+ $toc_title = str_replace( '%PAGE_NAME%', get_the_title(), $toc_title );
1049
+ }
1050
 
1051
+ $html .= '<div class="ez-toc-title-container">' . PHP_EOL;
1052
 
1053
+ $html .= '<p class="ez-toc-title">' . esc_html( htmlentities( $toc_title, ENT_COMPAT, 'UTF-8' ) ). '</p>' . PHP_EOL;
1054
 
1055
+ $html .= '<span class="ez-toc-title-toggle">';
1056
 
1057
+ if ( ezTOC_Option::get( 'visibility' ) ) {
1058
 
1059
+ $html .= '<a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle"><i class="ez-toc-glyphicon ez-toc-icon-toggle"></i></a>';
1060
+ }
1061
 
1062
+ $html .= '</span>';
1063
 
1064
+ $html .= '</div>' . PHP_EOL;
1065
+ }
1066
 
1067
+ ob_start();
1068
+ do_action( 'ez_toc_before' );
1069
+ $html .= ob_get_clean();
1070
 
1071
+ $html .= '<nav><ul class="ez-toc-list">' . $items . '</ul></nav>';
1072
 
1073
+ ob_start();
1074
+ do_action( 'ez_toc_after' );
1075
+ $html .= ob_get_clean();
1076
 
1077
+ $html .= '</div>' . PHP_EOL;
1078
 
1079
+ // Enqueue the script.
1080
+ wp_enqueue_script( 'ez-toc-js' );
 
1081
  }
1082
 
1083
  return array( 'find' => $find, 'replace' => $replace, 'content' => $html );
1105
 
1106
  if ( $run ) {
1107
 
1108
+ $args = self::build( get_post( get_the_ID() ) );
 
1109
  $out = $args['content'];
1110
  $run = FALSE;
1111
  }
1129
  */
1130
  public static function the_content( $content ) {
1131
 
1132
+ // bail if feed, search or archive
1133
+ if ( is_feed() || is_search() || is_archive() ) {
1134
+ return $content;
1135
+ }
1136
+
1137
+ // bail if post not eligible and widget is not active
1138
+ $is_eligible = self::is_eligible();
1139
+
1140
+ if ( ! $is_eligible && ! is_active_widget( false, false, 'ezw_tco' ) ) {
1141
+
1142
+ return $content;
1143
+ }
1144
+
1145
+ /*
1146
+ * get_post() does not return post_content filtered via `the_content` filter, which is good otherwise this
1147
+ * might cause an infinite loop.
1148
+ *
1149
+ * Since the ezTOC `the_content` filter is added at priority 100, it should run last in most situations
1150
+ * and already be filtered by other plugins/themes which ezTOC should take into account when building the
1151
+ * TOC. So, take the post content past via `the_content` filter callback and replace the post_content with
1152
+ * it before building the TOC.
1153
+ */
1154
+ $post = get_post( get_the_ID() );
1155
+ $post->post_content = $content;
1156
+
1157
+ // build toc
1158
+ $args = self::build( $post );
1159
  $find = $args['find'];
1160
  $replace = $args['replace'];
1161
  $html = $args['content'];
1162
 
1163
+ // bail if no headings found
1164
+ if ( empty( $find ) ) {
 
 
1165
 
1166
+ return $content;
1167
+ }
1168
 
1169
+ // if shortcode used or post not eligible, return content with anchored headings
1170
+ if ( strpos( $content, 'ez-toc-container' ) || ! $is_eligible ) {
1171
 
1172
+ return self::mb_find_replace( $find, $replace, $content );
1173
+ }
 
 
1174
 
1175
+ // else also add toc to content
1176
+ switch ( ezTOC_Option::get( 'position' ) ) {
 
1177
 
1178
+ case 'top':
1179
+ $content = $html . self::mb_find_replace( $find, $replace, $content );
1180
+ break;
1181
 
1182
+ case 'bottom':
1183
+ $content = self::mb_find_replace( $find, $replace, $content ) . $html;
1184
+ break;
 
1185
 
1186
+ case 'after':
1187
+ $replace[0] = $replace[0] . $html;
1188
+ $content = self::mb_find_replace( $find, $replace, $content );
1189
+ break;
 
1190
 
1191
+ case 'before':
1192
+ default:
1193
+ $replace[0] = $html . $replace[0];
1194
+ $content = self::mb_find_replace( $find, $replace, $content );
1195
  }
1196
 
1197
  return $content;
1217
  }
1218
 
1219
  // Start Easy Table of Contents.
1220
+ add_action( 'plugins_loaded', 'ezTOC' );
1221
  }
1222
 
1223
 
includes/class.admin.php CHANGED
@@ -259,7 +259,7 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
259
  'size' => 'large',
260
  'default' => '',
261
  ),
262
- esc_textarea( $altText )
263
  );
264
  ?>
265
  </td>
@@ -293,7 +293,7 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
293
  'size' => 'large',
294
  'default' => '',
295
  ),
296
- esc_textarea( $exclude )
297
  );
298
  ?>
299
  </td>
@@ -337,7 +337,10 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
337
  */
338
  public function save( $post_id, $post, $update ) {
339
 
340
- if ( current_user_can( 'edit_post', $post_id ) && wp_verify_nonce( $_REQUEST['_ez_toc_nonce'], 'ez_toc_save' ) ) {
 
 
 
341
 
342
  // Checkboxes are present if checked, absent if not.
343
  if ( isset( $_REQUEST['ez-toc-settings']['disabled-toc'] ) ) {
259
  'size' => 'large',
260
  'default' => '',
261
  ),
262
+ $altText
263
  );
264
  ?>
265
  </td>
293
  'size' => 'large',
294
  'default' => '',
295
  ),
296
+ $exclude
297
  );
298
  ?>
299
  </td>
337
  */
338
  public function save( $post_id, $post, $update ) {
339
 
340
+ if ( current_user_can( 'edit_post', $post_id ) &&
341
+ isset( $_REQUEST['_ez_toc_nonce'] ) &&
342
+ wp_verify_nonce( $_REQUEST['_ez_toc_nonce'], 'ez_toc_save' )
343
+ ) {
344
 
345
  // Checkboxes are present if checked, absent if not.
346
  if ( isset( $_REQUEST['ez-toc-settings']['disabled-toc'] ) ) {
includes/class.options.php CHANGED
@@ -194,7 +194,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
194
  'name' => __( 'Show when', 'easy-table-of-contents' ),
195
  'desc' => __( 'or more headings are present', 'easy-table-of-contents' ),
196
  'type' => 'select',
197
- 'options' => array_combine( range( 2, 10 ), range( 2, 10 ) ),
198
  'default' => 4,
199
  ),
200
  'show_heading_text' => array(
194
  'name' => __( 'Show when', 'easy-table-of-contents' ),
195
  'desc' => __( 'or more headings are present', 'easy-table-of-contents' ),
196
  'type' => 'select',
197
+ 'options' => array_combine( range( 1, 10 ), range( 1, 10 ) ),
198
  'default' => 4,
199
  ),
200
  'show_heading_text' => array(
includes/class.widget-toc.php CHANGED
@@ -149,7 +149,7 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
149
  * Ensure the ezTOC content filter is not applied when running `the_content` filter.
150
  */
151
  remove_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
152
- $content = apply_filters( 'the_content', $post->post_content );
153
  add_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
154
 
155
  /**
@@ -161,7 +161,7 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
161
  extract( $args );
162
 
163
  $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
164
- $items = ezTOC::extract_headings( $find, $replace, $content );
165
 
166
  if ( FALSE !== strpos( $title, '%PAGE_TITLE%' ) || FALSE !== strpos( $title, '%PAGE_NAME%' ) ) {
167
 
@@ -242,7 +242,7 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
242
  <?php
243
  if ( ezTOC_Option::get( 'visibility' ) ) {
244
 
245
- echo '<a class="pull-right btn btn-xs btn-default ez-toc-toggle"><i class="glyphicon ez-toc-icon-toggle"></i></a>';
246
  }
247
  ?>
248
 
@@ -255,7 +255,7 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
255
  <?php
256
  }
257
 
258
- echo '<ul class="ez-toc-list">'. PHP_EOL . $items . '</ul>' . PHP_EOL;
259
 
260
  do_action( 'ez_toc_after_widget' );
261
 
149
  * Ensure the ezTOC content filter is not applied when running `the_content` filter.
150
  */
151
  remove_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
152
+ $post->post_content = apply_filters( 'the_content', $post->post_content );
153
  add_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
154
 
155
  /**
161
  extract( $args );
162
 
163
  $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
164
+ $items = ezTOC::extract_headings( $find, $replace, $post );
165
 
166
  if ( FALSE !== strpos( $title, '%PAGE_TITLE%' ) || FALSE !== strpos( $title, '%PAGE_NAME%' ) ) {
167
 
242
  <?php
243
  if ( ezTOC_Option::get( 'visibility' ) ) {
244
 
245
+ echo '<a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle"><i class="ez-toc-glyphicon ez-toc-icon-toggle"></i></a>';
246
  }
247
  ?>
248
 
255
  <?php
256
  }
257
 
258
+ echo '<nav><ul class="ez-toc-list">'. PHP_EOL . $items . '</ul></nav>' . PHP_EOL;
259
 
260
  do_action( 'ez_toc_after_widget' );
261