<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[10938] sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/table-of-contents.php: Handbooks, ToC: Prevent potential auto-generated ToC heading IDs from conflicting with those in theme markup.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/10938">10938</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/10938","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>coffee2code</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-04-29 22:28:42 +0000 (Thu, 29 Apr 2021)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Handbooks, ToC: Prevent potential auto-generated ToC heading IDs from conflicting with those in theme markup.

Ensures ToC heading links are unique so that in such cases the links actually lead to the section heading and not some other part of the page.

This is very theme-specific and would need adjustments if the theme employs new potentially-conflicting markup IDs.

Props fahimmurshed, SergeyBiryukov, coffee2code.
Fixes <a href="http://meta.trac.wordpress.org/ticket/5064">#5064</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginshandbookinctableofcontentsphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/table-of-contents.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginshandbookinctableofcontentsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/table-of-contents.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/table-of-contents.php       2021-04-29 22:07:27 UTC (rev 10937)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/table-of-contents.php 2021-04-29 22:28:42 UTC (rev 10938)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -45,6 +45,44 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Returns reserved markup IDs likely to conflict with ToC-generated heading IDs.
+        *
+        * This list isn't meant to be exhaustive, just IDs that are likely to conflict
+        * with ToC-generated section heading IDs.
+        *
+        * If a reserved ID is encountered when a ToC section heading ID is being
+        * generated, the generated ID is incremented to avoid a conflict.
+        *
+        * @return array
+        */
+       public function get_reserved_ids() {
+               /**
+                * Filters the array of reserved IDs considered when auto-generating IDs for
+                * ToC sections.
+                *
+                * This is mostly for specifying markup IDs that may appear on the same page
+                * as the ToC for which any ToC-generated IDs would conflict. In such
+                * cases, the first instance of the ID on the page would be the target of
+                * the ToC section permalink which is likely not the ToC section itself.
+                *
+                * By specifying these reserved IDs, any potential use of the IDs by the theme
+                * can be accounted for by incrementing the auto-generated ID to avoid conflict.
+                *
+                * E.g. if the theme has `<div id="main">`, a ToC with a section titled "Main"
+                * would have a permalink that links to the div and not the ToC section.
+                *
+                * @param array $ids Array of IDs.
+                */
+               return (array) apply_filters(
+                       'handbooks_reserved_ids',
+                       [
+                               'main', 'masthead', 'menu-header', 'page', 'primary', 'secondary', 'secondary-content', 'site-navigation',
+                               'wordpress-org', 'wp-toolbar', 'wpadminbar', 'wporg-footer', 'wporg-header'
+                       ]
+               );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Converts given content to dynamically add the ToC.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -78,7 +116,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $toc .= '<div class="table-of-contents">';
</span><span class="cx" style="display: block; padding: 0 10px">                        $toc .= "<$contents_header>" . esc_html( $this->args->header_text ) . "</$contents_header><ul class=\"items\">";
</span><span class="cx" style="display: block; padding: 0 10px">                        $last_item = false;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $used_ids = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $used_ids = $this->get_reserved_ids();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach ( $items as $item ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                if ( $last_item ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -115,7 +153,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $first = true;
</span><span class="cx" style="display: block; padding: 0 10px">                $matches = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $replacements = array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $used_ids = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $used_ids = $this->get_reserved_ids();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $items as $item ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $replacement = '';
</span></span></pre>
</div>
</div>

</body>
</html>