From cdb884ac55e65bab5b49934e2585cfafbf34f5ea Mon Sep 17 00:00:00 2001 From: smulvihill <smulvihill@795442.no-reply.drupal.org> Date: Thu, 12 May 2022 13:02:38 +1000 Subject: [PATCH] Issue #3118516 by bgilhome, smulvih2, VladimirAus: Add an 'exclude' xpath option --- config/install/toc_api.toc_type.default.yml | 1 + config/install/toc_api.toc_type.full.yml | 1 + .../toc_api.toc_type.full_numbered.yml | 1 + config/install/toc_api.toc_type.simple.yml | 1 + .../toc_api.toc_type.simple_numbered.yml | 1 + config/schema/toc_api.toc_type.schema.yml | 3 +++ src/Toc.php | 15 +++++++++++- src/TocTypeForm.php | 6 +++++ toc_api.install | 23 +++++++++++++++++++ 9 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 toc_api.install diff --git a/config/install/toc_api.toc_type.default.yml b/config/install/toc_api.toc_type.default.yml index 7affc29..705ec78 100644 --- a/config/install/toc_api.toc_type.default.yml +++ b/config/install/toc_api.toc_type.default.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full.yml b/config/install/toc_api.toc_type.full.yml index 3b43c55..dd671e8 100644 --- a/config/install/toc_api.toc_type.full.yml +++ b/config/install/toc_api.toc_type.full.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full_numbered.yml b/config/install/toc_api.toc_type.full_numbered.yml index 0bb82d8..61961c7 100644 --- a/config/install/toc_api.toc_type.full_numbered.yml +++ b/config/install/toc_api.toc_type.full_numbered.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple.yml b/config/install/toc_api.toc_type.simple.yml index 55f2403..20bfad3 100644 --- a/config/install/toc_api.toc_type.simple.yml +++ b/config/install/toc_api.toc_type.simple.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple_numbered.yml b/config/install/toc_api.toc_type.simple_numbered.yml index bff2503..bcccb13 100644 --- a/config/install/toc_api.toc_type.simple_numbered.yml +++ b/config/install/toc_api.toc_type.simple_numbered.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/schema/toc_api.toc_type.schema.yml b/config/schema/toc_api.toc_type.schema.yml index 0966dfa..19bdb58 100644 --- a/config/schema/toc_api.toc_type.schema.yml +++ b/config/schema/toc_api.toc_type.schema.yml @@ -42,6 +42,9 @@ toc_api.toc_type.*: header_id_prefix: type: string label: 'Header ID prefix' + header_exclude_xpath: + type: string + label: 'Header exclude XPath' top_label: type: string label: 'Back to top' diff --git a/src/Toc.php b/src/Toc.php index 545ce8b..fa5eed4 100644 --- a/src/Toc.php +++ b/src/Toc.php @@ -40,6 +40,7 @@ class Toc implements TocInterface { 'header_allowed_tags' => '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>', 'header_id' => 'title', 'header_id_prefix' => 'section', + 'header_exclude_xpath' => '', 'top_label' => 'Back to top', 'top_min' => 2, 'top_max' => 2, @@ -135,6 +136,8 @@ class Toc implements TocInterface { * - 'header_id_prefix': Prefix to be prepended to header id when * 'path' or 'key' is selected. * Default value is 'section' + * - 'header_exclude_xpath': Optional XPath for any headers to exclude from + * the table of contents. * * - 'top_min': The minimum level of header to include a back to top link. * Default value is 2 @@ -203,12 +206,22 @@ class Toc implements TocInterface { $index_keys = $default_keys; $dom = Html::load($this->source); + + // If the exclude XPath option is set, retrieve those elements. + $exclude_nodes = []; + if ($this->options['header_exclude_xpath']) { + $xpath = new \DOMXPath($dom); + foreach ($xpath->query($this->options['header_exclude_xpath']) as $exclude_node) { + $exclude_nodes[] = $exclude_node; + } + } + // Loop through all the tags to ensure headers are found in the correct // order. $dom_nodes = $dom->getElementsByTagName('*'); /** @var \DOMElement $dom_node */ foreach ($dom_nodes as $dom_node) { - if (empty($this->options['headers'][$dom_node->tagName])) { + if (empty($this->options['headers'][$dom_node->tagName]) || in_array($dom_node, $exclude_nodes, TRUE)) { continue; } diff --git a/src/TocTypeForm.php b/src/TocTypeForm.php index 9f6f547..9c1012e 100644 --- a/src/TocTypeForm.php +++ b/src/TocTypeForm.php @@ -197,6 +197,12 @@ class TocTypeForm extends EntityForm { '#type' => 'textfield', '#default_value' => $options['header_id_prefix'], ]; + $form['options']['header']['header_exclude_xpath'] = [ + '#title' => $this->t('Header exclude XPath'), + '#description' => $this->t('Optional XPath for header elements to exclude from the table of contents. Example - //*[contains(@class,"toc-ignore")]'), + '#type' => 'textfield', + '#default_value' => $options['header_exclude_xpath'] ?? '', + ]; $form['options']['top'] = [ '#type' => 'details', diff --git a/toc_api.install b/toc_api.install new file mode 100644 index 0000000..e41b719 --- /dev/null +++ b/toc_api.install @@ -0,0 +1,23 @@ +<?php + +/** + * @file + * Update functions for the toc_api module. + */ + +/** + * Add header_exclude_xpath to existing TOCs + */ +function toc_api_update_8001() { + $toc_types = \Drupal::entityQuery('toc_type')->execute(); + + foreach ($toc_types as $type) { + $entity = \Drupal::entityTypeManager()->getStorage('toc_type')->load($type); + $options = $entity->getOptions(); + + if (empty($options['header_exclude_xpath'])) { + $config_factory = \Drupal::configFactory(); + $config_factory->getEditable('toc_api.toc_type.' . $type)->set('options.header_exclude_xpath', '')->save(); + } + } +} -- GitLab