|
3 | 3 | * Plugin Name: SimpleTOC - Table of Contents Block |
4 | 4 | * Plugin URI: https://marc.tv/simpletoc-wordpress-inhaltsverzeichnis-plugin-gutenberg/ |
5 | 5 | * Description: SEO-friendly Table of Contents Gutenberg block. No JavaScript and no CSS means faster loading. |
6 | | - * Version: 6.9.7 |
| 6 | + * Version: 7.0.0 |
7 | 7 | * Author: Marc Tönsing |
8 | 8 | * Author URI: https://toensing.com |
9 | 9 | * Text Domain: simpletoc |
@@ -153,13 +153,14 @@ function ( $toc_plugins ) { |
153 | 153 | * Adds IDs to the headings of the provided post content using a recursive block structure. |
154 | 154 | * |
155 | 155 | * @param string $content The content to add IDs to. |
| 156 | + * @param string $skip_regex The regex to skip the content from being processed. |
156 | 157 | * @return string The content with IDs added to its headings |
157 | 158 | */ |
158 | | -function simpletoc_add_ids_to_content( $content ) { |
| 159 | +function simpletoc_add_ids_to_content( $content, $skip_regex = false ) { |
159 | 160 |
|
160 | 161 | // Return early if the content does not contain a simpletoc shortcode. |
161 | 162 | $maybe_shortcode_result = preg_match( '/\[simpletoc ([^\]]*)\]/m', $content, $matches ); |
162 | | - if ( ! $maybe_shortcode_result ) { |
| 163 | + if ( ! $maybe_shortcode_result && ! $skip_regex ) { |
163 | 164 | return $content; |
164 | 165 | } |
165 | 166 |
|
@@ -272,30 +273,45 @@ function add_ids_to_blocks( $content ) { |
272 | 273 | } |
273 | 274 | } |
274 | 275 |
|
| 276 | + // If tag has a parent with 'simpletoc-excluded' class, then skip it. |
| 277 | + // Check if any parent has the 'simpletoc-excluded' class (similar to JS .closest). |
| 278 | + $parent = $tag->parentNode; // phpcs:ignore. |
| 279 | + while ( $parent ) { |
| 280 | + $parent_classes = isset( $parent->className ) ? $parent->className : ''; // phpcs:ignore. |
| 281 | + if ( $parent_classes && strpos( $parent_classes, 'simpletoc-excluded' ) !== false ) { |
| 282 | + continue 2; // Skip this tag, jump out of both while and foreach. |
| 283 | + } |
| 284 | + $parent = $parent->parentNode ?? null; // phpcs:ignore. |
| 285 | + if ( ! $parent ) { |
| 286 | + continue; |
| 287 | + } |
| 288 | + } |
| 289 | + |
275 | 290 | /** |
276 | 291 | * Filter to skip headings inside container blocks. |
277 | 292 | * |
278 | 293 | * @param bool $skip_in_wrapper Whether to skip headings inside container blocks. |
279 | 294 | * @return bool The filtered value. |
| 295 | + * @since 7.0.0 |
280 | 296 | */ |
281 | | - $skip_in_wrapper = apply_filters( 'simpletoc_skip_in_wrapper', true ); |
| 297 | + $skip_in_wrapper = apply_filters( 'simpletoc_skip_in_wrapper', false ); |
282 | 298 | if ( strpos( $tag_classes, 'simpletoc-include' ) !== false ) { |
283 | 299 | // If someone has added the simpletoc-include class, then don't skip it, regardless of wrapper. |
284 | 300 | $skip_in_wrapper = false; |
285 | 301 | } |
286 | 302 | if ( $skip_in_wrapper ) { |
287 | 303 | // Try to get parent tag. |
288 | | - $parent_tag = $tag->parentNode; |
289 | | - if ( $parent_tag && isset( $parent_tag->tagName ) ) { |
290 | | - if ( in_array( strtolower( strtolower( $parent_tag->tagName ) ), array( 'div', 'section', 'article', 'main', 'header', 'footer' ), true ) ) { |
| 304 | + $parent_tag = $tag->parentNode; // phpcs:ignore. |
| 305 | + if ( $parent_tag && isset( $parent_tag->tagName ) ) { // phpcs:ignore. |
| 306 | + if ( in_array( strtolower( strtolower( $parent_tag->tagName ) ), array( 'div', 'section', 'article', 'main', 'header', 'footer' ), true ) ) { // phpcs:ignore. |
291 | 307 | continue; |
292 | 308 | } |
293 | 309 | } |
294 | 310 | } |
295 | 311 |
|
296 | 312 | // Set the ID attribute of the headline anchor if it doesn't exist. |
297 | 313 | $tag_id = $tag->getAttribute( 'id' ); |
298 | | - $headline_anchor = SimpleTOC_Headline_Ids::get_headline_anchor( $tag->ownerDocument->saveHTML( $tag ), true ); |
| 314 | + $headline_anchor = SimpleTOC_Headline_Ids::get_headline_anchor( $tag->ownerDocument->saveHTML( $tag ), true ); // phpcs:ignore. |
299 | 315 | if ( empty( $tag_id ) ) { |
300 | 316 | $tag->setAttribute( 'id', $headline_anchor ); |
301 | 317 | } |
@@ -332,7 +348,7 @@ function render_callback_simpletoc( $attributes ) { |
332 | 348 |
|
333 | 349 | // This processes post content and stores the toc headlines for later rendering. Very simple content processing and fast. The placeholder is skipped. |
334 | 350 | $post_content = do_blocks( $post_content ); |
335 | | - $post_content = simpletoc_add_ids_to_content( $post_content ); |
| 351 | + $post_content = simpletoc_add_ids_to_content( $post_content, true ); |
336 | 352 |
|
337 | 353 | // Now get the toc html only. |
338 | 354 | $return = simpletoc_render_toc( $post_content, true, $attributes, $wrapper_attrs ); |
@@ -434,29 +450,40 @@ function filter_headings( $content ) { |
434 | 450 | continue; |
435 | 451 | } |
436 | 452 | } |
| 453 | + // If tag has a parent with 'simpletoc-excluded' class, then skip it. |
| 454 | + // Check if any parent has the 'simpletoc-excluded' class (similar to JS .closest). |
| 455 | + $parent = $tag->parentNode; // phpcs:ignore. |
| 456 | + while ( $parent && isset( $parent->getAttribute ) ) { // phpcs:ignore. |
| 457 | + $parent_classes = $parent->getAttribute( 'class' ); |
| 458 | + if ( $parent_classes && strpos( $parent_classes, 'simpletoc-excluded' ) !== false ) { |
| 459 | + continue 2; // Skip this tag, jump out of both while and foreach. |
| 460 | + } |
| 461 | + $parent = $parent->parentNode; // phpcs:ignore. |
| 462 | + } |
437 | 463 |
|
438 | 464 | /** |
439 | 465 | * Filter to skip headings inside container blocks. |
440 | 466 | * |
441 | 467 | * @param bool $skip_in_wrapper Whether to skip headings inside container blocks. |
442 | 468 | * @return bool The filtered value. |
| 469 | + * @since 7.0.0 |
443 | 470 | */ |
444 | | - $skip_in_wrapper = apply_filters( 'simpletoc_skip_in_wrapper', true ); |
| 471 | + $skip_in_wrapper = apply_filters( 'simpletoc_skip_in_wrapper', false ); |
445 | 472 | if ( strpos( $tag_classes, 'simpletoc-include' ) !== false ) { |
446 | 473 | // If someone has added the simpletoc-include class, then don't skip it, regardless of wrapper. |
447 | 474 | $skip_in_wrapper = false; |
448 | 475 | } |
449 | 476 | if ( $skip_in_wrapper ) { |
450 | 477 | // Try to get parent tag. |
451 | | - $parent_tag = $tag->parentNode; |
452 | | - if ( $parent_tag && isset( $parent_tag->tagName ) ) { |
453 | | - if ( in_array( strtolower( strtolower( $parent_tag->tagName ) ), array( 'div', 'section', 'article', 'main', 'header', 'footer' ), true ) ) { |
| 478 | + $parent_tag = $tag->parentNode; // phpcs:ignore. |
| 479 | + if ( $parent_tag && isset( $parent_tag->tagName ) ) { // phpcs:ignore. |
| 480 | + if ( in_array( strtolower( strtolower( $parent_tag->tagName ) ), array( 'div', 'section', 'article', 'main', 'header', 'footer' ), true ) ) { // phpcs:ignore. |
454 | 481 | continue; |
455 | 482 | } |
456 | 483 | } |
457 | 484 | } |
458 | 485 |
|
459 | | - $arr[] = $tag->ownerDocument->saveHTML( $tag ); // This gets the full HTML of the heading tag. |
| 486 | + $arr[] = $tag->ownerDocument->saveHTML( $tag ); // phpcs:ignore. |
460 | 487 | } |
461 | 488 |
|
462 | 489 | return $arr; |
|
0 commit comments