jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/349375 )

Change subject: Flatten links inside section titles anchors
......................................................................


Flatten links inside section titles anchors

Anchor names of section titles don't have any HTML in MediaWiki.

Now using anchor ids straight from Parsoid HTML. The ids are
temporarily stored as data-anchor attributes since ids are already
used for the section id numbers.

This also helped to make anchor ids more similar to MW output.
No need for our own anchorencode implementation. We almost got rid of
the locutus/php/url/urlencode dependency if it wasn't still used by
the most read functionality.

Change-Id: Ib774f286e47e6b0a05272fd9cb56dbb8ab00efce
---
D lib/anchorencode.js
M lib/parseSection.js
M lib/parsoid-access.js
M 
test/diff/results/page_formatted-enwiki-User%3ABSitzmann_(WMF)_MCS_Test_Frankenstein.json
M 
test/diff/results/page_formatted-enwiki-User%3ABSitzmann_(WMF)_MCS_Test_TitleLinkEncoding.json
M 
test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_(WMF)_MCS_Test_Frankenstein.json
M 
test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_(WMF)_MCS_Test_TitleLinkEncoding.json
D test/lib/anchorencode/anchorencode-test.js
M test/lib/parsoid/parsoid-access-test.js
9 files changed, 26 insertions(+), 91 deletions(-)

Approvals:
  jenkins-bot: Verified
  Mholloway: Looks good to me, approved



diff --git a/lib/anchorencode.js b/lib/anchorencode.js
deleted file mode 100644
index 906f883..0000000
--- a/lib/anchorencode.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-const urlencode = require('locutus/php/url/urlencode');
-
-/**
- * Encodes an input string so that it can be used as an HTML anchor id
- * (e.g. for a section in a page: <h2 id="anchor">).
- * See 
https://www.mediawiki.org/wiki/Manual:PAGENAMEE_encoding#Encodings_compared
- * https://www.mediawiki.org/wiki/Special:Code/MediaWiki/16279
- * core/include/parser/CoreParserFunctions.php
- * https://phabricator.wikimedia.org/T9059
- * https://gerrit.wikimedia.org/r/#/c/226032/
- * @param {!string} input the input string (usually the heading text of a 
section heading)
- * @return {!string} the sanitized version of the input string so it can be 
used as an anchor.
- */
-function anchorencode(input) {
-    const id = input.replace(/\s+/g, '_');
-    return urlencode(id)
-        .replace(/%3A/g, ':')
-        .replace(/%/g, '.');
-}
-
-module.exports = {
-    anchorencode
-};
diff --git a/lib/parseSection.js b/lib/parseSection.js
index c064fbe..16934de 100644
--- a/lib/parseSection.js
+++ b/lib/parseSection.js
@@ -1,7 +1,5 @@
 'use strict';
 
-const a = require('./anchorencode');
-
 function parse(sectionDiv, startingNode) {
     let nextNode;
     const nextSection = {};
@@ -16,7 +14,7 @@
         } else {
             nextSection.toclevel = parseInt(node.tagName.charAt(1), 10) - 1;
             nextSection.line = node.innerHTML.trim();
-            nextSection.anchor = a.anchorencode(nextSection.line);
+            nextSection.anchor = node.id;
             node = node.nextSibling;
             break;
         }
diff --git a/lib/parsoid-access.js b/lib/parsoid-access.js
index 9ef3f61..f659048 100644
--- a/lib/parsoid-access.js
+++ b/lib/parsoid-access.js
@@ -5,7 +5,6 @@
 'use strict';
 
 const domino = require('domino');
-const a = require('./anchorencode');
 const sUtil = require('./util');
 const api = require('./api-util');
 const parseSection = require('./parseSection');
@@ -69,6 +68,7 @@
         sectionDiv.id = `section_${i}`;
         sectionDiv.className = `toclevel_${section.toclevel}`;
         sectionDiv.title = section.line;
+        sectionDiv.setAttribute('data-anchor', section.anchor);
         output = parseSection(sectionDiv, output.nextNode);
         if (output.nextNode) {
             doc.body.insertBefore(output.sectionDiv, output.nextNode);
@@ -98,7 +98,7 @@
             const className = currentSectionDiv.className;
             currentSection.toclevel = 
parseInt(className.substring('toclevel_'.length), 10);
             currentSection.line = currentSectionDiv.title;
-            currentSection.anchor = a.anchorencode(currentSection.line);
+            currentSection.anchor = 
currentSectionDiv.getAttribute('data-anchor');
         }
 
         sections.push(currentSection);
diff --git 
"a/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
 
"b/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
index 1883aa9..7761bae 100644
--- 
"a/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
+++ 
"b/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
@@ -11,12 +11,12 @@
     "protection": {},
     "editable": true,
     "hatnotes": [],
-    "intro": "<p><b>Frankenstein Castle</b> is a medieval fortification on a 
<a href=\"/wiki/Spur_castle\" title=\"Spur castle\">spur</a> above the village 
of <a href=\"/wiki/Frankenstein,_Rhineland-Palatinate\" title=\"Frankenstein, 
Rhineland-Palatinate\">Frankenstein, Rhineland-Palatinate</a> in the <a 
href=\"/wiki/Palatinate_Forest\" title=\"Palatinate Forest\">Palatinate 
Forest</a> in <a href=\"/wiki/Germany\" title=\"Germany\">Germany</a>. Its name 
derives from the local House of Frankenstein.</p><figure 
class=\"mw-default-size\"><a href=\"/wiki/File:Frankensteingrundriss.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/220px-Frankensteingrundriss.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/440px-Frankensteingrundriss.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/330px-Frankensteingrundriss.jpg
 1.5x\" height=\"177\" width=\"220\"></a><figcaption>Layout of Frankenstein 
Castle</figcaption></figure>",
+    "intro": "<p><b>Frankenstein Castle</b> is a medieval fortification on a 
<a href=\"/wiki/Spur_castle\" title=\"Spur castle\">spur</a> above the village 
of <a href=\"/wiki/Frankenstein,_Rhineland-Palatinate\" title=\"Frankenstein, 
Rhineland-Palatinate\">Frankenstein, Rhineland-Palatinate</a> in the <a 
href=\"/wiki/Palatinate_Forest\" title=\"Palatinate Forest\">Palatinate 
Forest</a> in <a href=\"/wiki/Germany\" title=\"Germany\">Germany</a>. Its name 
derives from the local House of Frankenstein.</p><figure 
class=\"mw-default-size\"><a href=\"/wiki/File:Frankensteingrundriss.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/220px-Frankensteingrundriss.jpg\"
 data-file-type=\"bitmap\" height=\"177\" width=\"220\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/440px-Frankensteingrundriss.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/330px-Frankensteingrundriss.jpg
 1.5x\"></a><figcaption>Layout of Frankenstein Castle</figcaption></figure>",
     "geo": {
       "latitude": 49.4388,
       "longitude": 7.975
     },
-    "text": "<table class=\"plainlinks ombox ombox-notice\"><tbody><tr><td 
class=\"mbox-image\"><span><span><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/30px-Walnut.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/60px-Walnut.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/45px-Walnut.png 
1.5x\" height=\"30\" width=\"30\"></span></span></td><td 
class=\"mbox-text\"><b>This page in a nutshell:</b> A Collection of various 
elements of WP pages to be used for 
testing.</td></tr></tbody></table>\n\n<figure class=\"mw-default-size 
mw-halign-right\"><a href=\"/wiki/File:Frankensteinarp.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/220px-Frankensteinarp.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/440px-Frankensteinarp.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/330px-Frankensteinarp.jpg
 1.5x\" height=\"160\" width=\"220\"></a><figcaption>Frankenstein 
Castle</figcaption></figure>\n<p><span style=\"font-size: 
small;\"></span></p>\n\n<p><a href=\"/wiki/Red_link_in_da_house\" title=\"Red 
link in da house\">Red link in da house</a>!</p>\n\n"
+    "text": "<table class=\"plainlinks ombox ombox-notice\"><tbody><tr><td 
class=\"mbox-image\"><span><span><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/30px-Walnut.png\"
 data-file-type=\"bitmap\" height=\"30\" width=\"30\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/60px-Walnut.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/45px-Walnut.png 
1.5x\"></span></span></td><td class=\"mbox-text\"><b>This page in a 
nutshell:</b> A Collection of various elements of WP pages to be used for 
testing.</td></tr></tbody></table>\n\n<figure class=\"mw-default-size 
mw-halign-right\"><a href=\"/wiki/File:Frankensteinarp.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/220px-Frankensteinarp.jpg\"
 data-file-type=\"bitmap\" height=\"160\" width=\"220\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/440px-Frankensteinarp.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/330px-Frankensteinarp.jpg
 1.5x\"></a><figcaption>Frankenstein Castle</figcaption></figure>\n<p><span 
style=\"font-size: small;\"></span></p>\n\n<p><a 
href=\"/wiki/Red_link_in_da_house\" title=\"Red link in da house\">Red link in 
da house</a>!</p>\n\n"
   },
   "remaining": {
     "sections": [
@@ -71,7 +71,7 @@
       },
       {
         "id": 8,
-        "text": "\n\n<p><span><a href=\"/wiki/File:Example.png\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/7/70/Example.png/150px-Example.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 2x, 
//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 1.5x\" height=\"155\" 
width=\"150\"></a></span></p>\n\n<p>Multiple images:</p>\n<div class=\"thumb 
tmulti tright\"><div class=\"thumbinner\" 
style=\"width:208px;max-width:208px\"><div class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Yellow_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/100px-Yellow_card.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/200px-Yellow_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/150px-Yellow_card.svg.png
 1.5x\" height=\"130\" width=\"100\"></a></span></div><div 
class=\"thumbcaption\" style=\"clear:left\">Caution</div></div><div 
class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Red_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/100px-Red_card.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/200px-Red_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/150px-Red_card.svg.png
 1.5x\" height=\"130\" width=\"100\"></a></span></div><div 
class=\"thumbcaption\" style=\"clear:left\">Ejection</div></div><div 
style=\"clear:left\"></div><div class=\"thumbcaption\" 
style=\"clear:left;text-align:left;background-color:transparent\">Two cards 
used by football referees</div></div></div>\n\n<p>Imagemap:</p>\n<div 
class=\"floatright\">\n<div class=\"noresize\" style=\"height: 152px; width: 
300px; \"><a href=\"http://projects.vassar.edu/1896/democrats.html\"; 
class=\"plainlinks\" rel=\"nofollow\" title=\"1896 Democrats\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/300px-Bryan-Sewall.jpg\"
 width=\"300\" height=\"152\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/450px-Bryan-Sewall.jpg
 1.5x, 
//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/600px-Bryan-Sewall.jpg
 2x\" usemap=\"#ImageMap_\"></a><map name=\"ImageMap_\" 
id=\"ImageMap_\">\n<area href=\"/wiki/William_Jennings_Bryan\" shape=\"circle\" 
coords=\"73,65,54\" alt=\"William J. Bryan\" title=\"William J. Bryan\">\n<area 
href=\"/wiki/Arthur_Sewall\" shape=\"circle\" coords=\"226,65,54\" alt=\"Arthur 
Sewall\" title=\"Arthur Sewall\"></map>\n<div style=\"margin-left: 280px; 
margin-top: -20px; text-align: left;\"><a href=\"/wiki/File:Bryan-Sewall.jpg\" 
title=\"About this image\"><img 
src=\"/w/extensions/ImageMap/desc-20.png?15600\" style=\"border: 
none;\"></a></div>\n</div>\n</div>\n\n<p>Panoramas:</p>\n<div class=\"thumb 
tnone\" style=\"margin-left: auto; margin-right:auto; overflow:hidden; 
width:auto; max-width:1808px;\">\n<div class=\"thumbinner\" style=\"\"><div 
class=\"overflowbugx\" style=\"overflow:auto;\"><span><a 
href=\"/wiki/File:Helsinki_z00.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/07/Helsinki_z00.jpg/1800px-Helsinki_z00.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 2x, 
//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 1.5x\" 
height=\"216\" width=\"1800\"></a></span></div><div class=\"thumbcaption\"><a 
href=\"/wiki/Helsinki\" title=\"Helsinki\">Helsinki</a> has many 
buildings.</div>\n</div></div>\n\n",
+        "text": "\n\n<p><span><a href=\"/wiki/File:Example.png\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/7/70/Example.png/150px-Example.png\"
 data-file-type=\"bitmap\" height=\"155\" width=\"150\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 2x, 
//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 
1.5x\"></a></span></p>\n\n<p>Multiple images:</p>\n<div class=\"thumb tmulti 
tright\"><div class=\"thumbinner\" style=\"width:208px;max-width:208px\"><div 
class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Yellow_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/100px-Yellow_card.svg.png\"
 data-file-type=\"drawing\" height=\"130\" width=\"100\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/200px-Yellow_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/150px-Yellow_card.svg.png
 1.5x\"></a></span></div><div class=\"thumbcaption\" 
style=\"clear:left\">Caution</div></div><div class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Red_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/100px-Red_card.svg.png\"
 data-file-type=\"drawing\" height=\"130\" width=\"100\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/200px-Red_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/150px-Red_card.svg.png
 1.5x\"></a></span></div><div class=\"thumbcaption\" 
style=\"clear:left\">Ejection</div></div><div style=\"clear:left\"></div><div 
class=\"thumbcaption\" 
style=\"clear:left;text-align:left;background-color:transparent\">Two cards 
used by football referees</div></div></div>\n\n<p>Imagemap:</p>\n<div 
class=\"floatright\">\n<div class=\"noresize\" style=\"height: 152px; width: 
300px; \"><a href=\"http://projects.vassar.edu/1896/democrats.html\"; 
class=\"plainlinks\" rel=\"nofollow\" title=\"1896 Democrats\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/300px-Bryan-Sewall.jpg\"
 width=\"300\" height=\"152\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/450px-Bryan-Sewall.jpg
 1.5x, 
//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/600px-Bryan-Sewall.jpg
 2x\" usemap=\"#ImageMap_\"></a><map name=\"ImageMap_\" 
id=\"ImageMap_\">\n<area href=\"/wiki/William_Jennings_Bryan\" shape=\"circle\" 
coords=\"73,65,54\" alt=\"William J. Bryan\" title=\"William J. Bryan\">\n<area 
href=\"/wiki/Arthur_Sewall\" shape=\"circle\" coords=\"226,65,54\" alt=\"Arthur 
Sewall\" title=\"Arthur Sewall\"></map>\n<div style=\"margin-left: 280px; 
margin-top: -20px; text-align: left;\"><a href=\"/wiki/File:Bryan-Sewall.jpg\" 
title=\"About this image\"><img 
src=\"/w/extensions/ImageMap/desc-20.png?15600\" style=\"border: 
none;\"></a></div>\n</div>\n</div>\n\n<p>Panoramas:</p>\n<div class=\"thumb 
tnone\" style=\"margin-left: auto; margin-right:auto; overflow:hidden; 
width:auto; max-width:1808px;\">\n<div class=\"thumbinner\" style=\"\"><div 
class=\"overflowbugx\" style=\"overflow:auto;\"><span><a 
href=\"/wiki/File:Helsinki_z00.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/07/Helsinki_z00.jpg/1800px-Helsinki_z00.jpg\"
 data-file-type=\"bitmap\" height=\"216\" width=\"1800\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 2x, 
//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 
1.5x\"></a></span></div><div class=\"thumbcaption\"><a href=\"/wiki/Helsinki\" 
title=\"Helsinki\">Helsinki</a> has many buildings.</div>\n</div></div>\n\n",
         "toclevel": 1,
         "line": "Images",
         "anchor": "Images"
@@ -88,14 +88,14 @@
         "text": "\n<div class=\"hatnote\">\"WP:TPA\" redirects here. For talk 
page archiving, see <a href=\"/wiki/Help:Archiving_a_talk_page\" 
title=\"Help:Archiving a talk page\">Help:Archiving a talk 
page</a>.</div>\n<p><big id=\"mwWg\"><b>A perfect Wikipedia 
article...</b></big></p>\n<ul><li id=\"mwXQ\"><b>Is on a <a 
href=\"/wiki/Wikipedia:Note\" title=\"Wikipedia:Note\">notable</a> 
topic.</b>\n<ul><li id=\"mwYQ\"><b>Fills a gap</b> not provided by existing or 
related articles.</li></ul></li>\n<li id=\"mwYw\"><b>Has an appropriate 
structure.</b></li></ul>\n\n",
         "toclevel": 1,
         "line": "From <a href=\"/wiki/Wikipedia:The_perfect_article\" 
title=\"Wikipedia:The perfect article\">Wikipedia:The perfect article</a>",
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:The_perfect_article.22_title.3D.22Wikipedia:The_perfect_article.22.3EWikipedia:The_perfect_article.3C.2Fa.3E"
+        "anchor": "From_Wikipedia:The_perfect_article"
       },
       {
         "id": 11,
         "text": "\n\n",
         "toclevel": 1,
         "line": "From <a href=\"/wiki/Wikipedia:Manual_of_Style/Layout\" 
title=\"Wikipedia:Manual of 
Style/Layout\">Wikipedia:Manual_of_Style/Layout</a>",
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:Manual_of_Style.2FLayout.22_title.3D.22Wikipedia:Manual_of_Style.2FLayout.22.3EWikipedia:Manual_of_Style.2FLayout.3C.2Fa.3E"
+        "anchor": "From_Wikipedia:Manual_of_Style.2FLayout"
       },
       {
         "id": 12,
@@ -106,7 +106,7 @@
       },
       {
         "id": 13,
-        "text": "\n<div 
style=\"position:relative;top:-3em\"></div><span>\n</span><div 
class=\"shortcutbox plainlist noprint\" style=\"float:right;border:1px solid 
#aaa;background:#fff;margin:.3em .3em .3em 1em;padding:.4em 
.6em;text-align:center;font-size:smaller;line-height:2em;font-weight:bold\"><a 
href=\"/wiki/Wikipedia:Shortcut\" 
title=\"Wikipedia:Shortcut\">Shortcut</a>:\n<ul><li><span 
class=\"plainlinks\"><a rel=\"mw:ExtLink\" 
href=\"//en.wikipedia.org/w/index.php?title=MOS:BODY&amp;redirect=no\" 
class=\"external\">MOS:BODY</a></span></li></ul></div>\n<div 
class=\"hatnote\">Further information: <a href=\"/wiki/Help:Section\" 
title=\"Help:Section\">Help:Section</a> and <a 
href=\"/wiki/Wikipedia:Manual_of_Style#Article_titles.2C_headings.2C_and_sections\"
 title=\"Wikipedia:Manual of Style\">Wikipedia:Manual of Style 
§<span>&nbsp;</span>Article titles, headings, and sections</a></div>\n\n<figure 
class=\"mw-default-size\"><a 
href=\"/wiki/File:Wikipedia_layout_sample_bodies.png\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/180px-Wikipedia_layout_sample_bodies.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/360px-Wikipedia_layout_sample_bodies.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/270px-Wikipedia_layout_sample_bodies.png
 1.5x\" height=\"225\" width=\"180\"></a><figcaption>Body sections appear after 
the lead and table of contents (click on image for larger 
view).</figcaption></figure>\n\n<p>Articles longer than a stub are generally 
divided into sections...</p>\n\n",
+        "text": "\n<div 
style=\"position:relative;top:-3em\"></div><span>\n</span><div 
class=\"shortcutbox plainlist noprint\" style=\"float:right;border:1px solid 
#aaa;background:#fff;margin:.3em .3em .3em 1em;padding:.4em 
.6em;text-align:center;font-size:smaller;line-height:2em;font-weight:bold\"><a 
href=\"/wiki/Wikipedia:Shortcut\" 
title=\"Wikipedia:Shortcut\">Shortcut</a>:\n<ul><li><span 
class=\"plainlinks\"><a rel=\"mw:ExtLink\" 
href=\"//en.wikipedia.org/w/index.php?title=MOS:BODY&amp;redirect=no\" 
class=\"external\">MOS:BODY</a></span></li></ul></div>\n<div 
class=\"hatnote\">Further information: <a href=\"/wiki/Help:Section\" 
title=\"Help:Section\">Help:Section</a> and <a 
href=\"/wiki/Wikipedia:Manual_of_Style#Article_titles.2C_headings.2C_and_sections\"
 title=\"Wikipedia:Manual of Style\">Wikipedia:Manual of Style 
§<span>&nbsp;</span>Article titles, headings, and sections</a></div>\n\n<figure 
class=\"mw-default-size\"><a 
href=\"/wiki/File:Wikipedia_layout_sample_bodies.png\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/180px-Wikipedia_layout_sample_bodies.png\"
 data-file-type=\"bitmap\" height=\"225\" width=\"180\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/360px-Wikipedia_layout_sample_bodies.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/270px-Wikipedia_layout_sample_bodies.png
 1.5x\"></a><figcaption>Body sections appear after the lead and table of 
contents (click on image for larger view).</figcaption></figure>\n\n<p>Articles 
longer than a stub are generally divided into sections...</p>\n\n",
         "toclevel": 2,
         "line": "Body sections",
         "anchor": "Body_sections"
@@ -162,7 +162,7 @@
       },
       {
         "id": 21,
-        "text": "\n\n<table class=\"mbox-small plainlinks sistersitebox\" 
style=\"background-color:#f9f9f9;border:1px solid 
#aaa;color:#000\">\n<tbody><tr>\n<td class=\"mbox-image\"><span 
class=\"noviewer\"><a href=\"/wiki/File:Commons-logo.svg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png
 1.5x\" height=\"40\" width=\"30\"></a></span></td>\n<td class=\"mbox-text 
plainlist\">Wikimedia Commons has media related to <i><b><a rel=\"mw:ExtLink\" 
href=\"https://commons.wikimedia.org/wiki/Category:Wikipedia%20logos\"; 
title=\"commons:Category:Wikipedia logos\" class=\"external\">Wikipedia 
logos</a></b></i>.</td></tr></tbody></table><span>\n</span>\n<p>More precisely, 
box-type templates such as <code>{{<a href=\"/wiki/Template:Commons_category\" 
title=\"Template:Commons category\">Commons category</a>}}</code> shown at 
right have to be put at the beginning of the <i>last section</i></p> \n\n",
+        "text": "\n\n<table class=\"mbox-small plainlinks sistersitebox\" 
style=\"background-color:#f9f9f9;border:1px solid 
#aaa;color:#000\">\n<tbody><tr>\n<td class=\"mbox-image\"><span 
class=\"noviewer\"><a href=\"/wiki/File:Commons-logo.svg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\"
 data-file-type=\"drawing\" height=\"40\" width=\"30\" 
srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png
 1.5x\"></a></span></td>\n<td class=\"mbox-text plainlist\">Wikimedia Commons 
has media related to <i><b><a rel=\"mw:ExtLink\" 
href=\"https://commons.wikimedia.org/wiki/Category:Wikipedia%20logos\"; 
title=\"commons:Category:Wikipedia logos\" class=\"external\">Wikipedia 
logos</a></b></i>.</td></tr></tbody></table><span>\n</span>\n<p>More precisely, 
box-type templates such as <code>{{<a href=\"/wiki/Template:Commons_category\" 
title=\"Template:Commons category\">Commons category</a>}}</code> shown at 
right have to be put at the beginning of the <i>last section</i></p> \n\n",
         "toclevel": 2,
         "line": "Links to sister projects",
         "anchor": "Links_to_sister_projects"
diff --git 
"a/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
 
"b/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
index f5e51f2..988b586 100644
--- 
"a/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
+++ 
"b/test/diff/results/page_formatted-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
@@ -21,7 +21,7 @@
         "text": "\n<p>Special chars in section heading.</p>\n\n",
         "toclevel": 1,
         "line": "Special chars $%&amp;",
-        "anchor": "Special_chars_.24.25.26amp.3B"
+        "anchor": "Special_chars_.24.25.26"
       },
       {
         "id": 2,
diff --git 
"a/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
 
"b/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
index ad0f691..ddc25c7 100644
--- 
"a/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
+++ 
"b/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_Frankenstein.json"
@@ -18,7 +18,7 @@
     "sections": [
       {
         "id": 0,
-        "text": "<span><p><b>Frankenstein Castle</b> is a medieval 
fortification on a <a href=\"/wiki/Spur_castle\" title=\"Spur castle\">spur</a> 
above the village of <a href=\"/wiki/Frankenstein,_Rhineland-Palatinate\" 
title=\"Frankenstein, Rhineland-Palatinate\">Frankenstein, 
Rhineland-Palatinate</a> in the <a href=\"/wiki/Palatinate_Forest\" 
title=\"Palatinate Forest\">Palatinate Forest</a> in <a href=\"/wiki/Germany\" 
title=\"Germany\">Germany</a>. Its name derives from the local House of 
Frankenstein.</p><figure class=\"mw-default-size\"><a 
href=\"/wiki/File:Frankensteingrundriss.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/220px-Frankensteingrundriss.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/440px-Frankensteingrundriss.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/330px-Frankensteingrundriss.jpg
 1.5x\" height=\"177\" width=\"220\"></a><figcaption>Layout of Frankenstein 
Castle</figcaption></figure></span><table class=\"plainlinks ombox 
ombox-notice\"><tbody><tr><td class=\"mbox-image\"><span><span><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/30px-Walnut.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/60px-Walnut.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/45px-Walnut.png 
1.5x\" height=\"30\" width=\"30\"></span></span></td><td 
class=\"mbox-text\"><b>This page in a nutshell:</b> A Collection of various 
elements of WP pages to be used for 
testing.</td></tr></tbody></table>\n\n<figure class=\"mw-default-size 
mw-halign-right\"><a href=\"/wiki/File:Frankensteinarp.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/220px-Frankensteinarp.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/440px-Frankensteinarp.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/330px-Frankensteinarp.jpg
 1.5x\" height=\"160\" width=\"220\"></a><figcaption>Frankenstein 
Castle</figcaption></figure>\n\n\n\n<p><span style=\"font-size: 
small;\"></span></p>\n\n<p><a href=\"/wiki/Red_link_in_da_house\" title=\"Red 
link in da house\">Red link in da house</a>!</p>\n\n"
+        "text": "<span><p><b>Frankenstein Castle</b> is a medieval 
fortification on a <a href=\"/wiki/Spur_castle\" title=\"Spur castle\">spur</a> 
above the village of <a href=\"/wiki/Frankenstein,_Rhineland-Palatinate\" 
title=\"Frankenstein, Rhineland-Palatinate\">Frankenstein, 
Rhineland-Palatinate</a> in the <a href=\"/wiki/Palatinate_Forest\" 
title=\"Palatinate Forest\">Palatinate Forest</a> in <a href=\"/wiki/Germany\" 
title=\"Germany\">Germany</a>. Its name derives from the local House of 
Frankenstein.</p><figure class=\"mw-default-size\"><a 
href=\"/wiki/File:Frankensteingrundriss.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/220px-Frankensteingrundriss.jpg\"
 data-file-type=\"bitmap\" height=\"177\" width=\"220\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/440px-Frankensteingrundriss.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Frankensteingrundriss.jpg/330px-Frankensteingrundriss.jpg
 1.5x\"></a><figcaption>Layout of Frankenstein 
Castle</figcaption></figure></span><table class=\"plainlinks ombox 
ombox-notice\"><tbody><tr><td class=\"mbox-image\"><span><span><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/30px-Walnut.png\"
 data-file-type=\"bitmap\" height=\"30\" width=\"30\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/60px-Walnut.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Walnut.png/45px-Walnut.png 
1.5x\"></span></span></td><td class=\"mbox-text\"><b>This page in a 
nutshell:</b> A Collection of various elements of WP pages to be used for 
testing.</td></tr></tbody></table>\n\n<figure class=\"mw-default-size 
mw-halign-right\"><a href=\"/wiki/File:Frankensteinarp.jpg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/220px-Frankensteinarp.jpg\"
 data-file-type=\"bitmap\" height=\"160\" width=\"220\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/440px-Frankensteinarp.jpg
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Frankensteinarp.jpg/330px-Frankensteinarp.jpg
 1.5x\"></a><figcaption>Frankenstein 
Castle</figcaption></figure>\n\n\n\n<p><span style=\"font-size: 
small;\"></span></p>\n\n<p><a href=\"/wiki/Red_link_in_da_house\" title=\"Red 
link in da house\">Red link in da house</a>!</p>\n\n"
       },
       {
         "id": 1,
@@ -77,13 +77,13 @@
       {
         "id": 10,
         "toclevel": 1,
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:The_perfect_article.22_title.3D.22Wikipedia:The_perfect_article.22.3EWikipedia:The_perfect_article.3C.2Fa.3E",
+        "anchor": "From_Wikipedia:The_perfect_article",
         "line": "From <a href=\"/wiki/Wikipedia:The_perfect_article\" 
title=\"Wikipedia:The perfect article\">Wikipedia:The perfect article</a>"
       },
       {
         "id": 11,
         "toclevel": 1,
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:Manual_of_Style.2FLayout.22_title.3D.22Wikipedia:Manual_of_Style.2FLayout.22.3EWikipedia:Manual_of_Style.2FLayout.3C.2Fa.3E",
+        "anchor": "From_Wikipedia:Manual_of_Style.2FLayout",
         "line": "From <a href=\"/wiki/Wikipedia:Manual_of_Style/Layout\" 
title=\"Wikipedia:Manual of Style/Layout\">Wikipedia:Manual_of_Style/Layout</a>"
       },
       {
@@ -213,7 +213,7 @@
       },
       {
         "id": 8,
-        "text": "\n\n<p><span><a href=\"/wiki/File:Example.png\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/7/70/Example.png/150px-Example.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 2x, 
//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 1.5x\" height=\"155\" 
width=\"150\"></a></span></p>\n\n<p>Multiple images:</p>\n<div class=\"thumb 
tmulti tright\"><div class=\"thumbinner\" 
style=\"width:208px;max-width:208px\"><div class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Yellow_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/100px-Yellow_card.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/200px-Yellow_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/150px-Yellow_card.svg.png
 1.5x\" height=\"130\" width=\"100\"></a></span></div><div 
class=\"thumbcaption\" style=\"clear:left\">Caution</div></div><div 
class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Red_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/100px-Red_card.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/200px-Red_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/150px-Red_card.svg.png
 1.5x\" height=\"130\" width=\"100\"></a></span></div><div 
class=\"thumbcaption\" style=\"clear:left\">Ejection</div></div><div 
style=\"clear:left\"></div><div class=\"thumbcaption\" 
style=\"clear:left;text-align:left;background-color:transparent\">Two cards 
used by football referees</div></div></div>\n\n<p>Imagemap:</p>\n<div 
class=\"floatright\">\n<div class=\"noresize\" style=\"height: 152px; width: 
300px; \"><a href=\"http://projects.vassar.edu/1896/democrats.html\"; 
class=\"plainlinks\" rel=\"nofollow\" title=\"1896 Democrats\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/300px-Bryan-Sewall.jpg\"
 width=\"300\" height=\"152\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/450px-Bryan-Sewall.jpg
 1.5x, 
//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/600px-Bryan-Sewall.jpg
 2x\" usemap=\"#ImageMap_\"></a><map name=\"ImageMap_\" 
id=\"ImageMap_\">\n<area href=\"/wiki/William_Jennings_Bryan\" shape=\"circle\" 
coords=\"73,65,54\" alt=\"William J. Bryan\" title=\"William J. Bryan\">\n<area 
href=\"/wiki/Arthur_Sewall\" shape=\"circle\" coords=\"226,65,54\" alt=\"Arthur 
Sewall\" title=\"Arthur Sewall\"></map>\n<div style=\"margin-left: 280px; 
margin-top: -20px; text-align: left;\"><a href=\"/wiki/File:Bryan-Sewall.jpg\" 
title=\"About this image\"><img 
src=\"/w/extensions/ImageMap/desc-20.png?15600\" style=\"border: 
none;\"></a></div>\n</div>\n</div>\n\n<p>Panoramas:</p>\n<div class=\"thumb 
tnone\" style=\"margin-left: auto; margin-right:auto; overflow:hidden; 
width:auto; max-width:1808px;\">\n<div class=\"thumbinner\" style=\"\"><div 
class=\"overflowbugx\" style=\"overflow:auto;\"><span><a 
href=\"/wiki/File:Helsinki_z00.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/07/Helsinki_z00.jpg/1800px-Helsinki_z00.jpg\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 2x, 
//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 1.5x\" 
height=\"216\" width=\"1800\"></a></span></div><div class=\"thumbcaption\"><a 
href=\"/wiki/Helsinki\" title=\"Helsinki\">Helsinki</a> has many 
buildings.</div>\n</div></div>\n\n",
+        "text": "\n\n<p><span><a href=\"/wiki/File:Example.png\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/7/70/Example.png/150px-Example.png\"
 data-file-type=\"bitmap\" height=\"155\" width=\"150\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 2x, 
//upload.wikimedia.org/wikipedia/commons/7/70/Example.png 
1.5x\"></a></span></p>\n\n<p>Multiple images:</p>\n<div class=\"thumb tmulti 
tright\"><div class=\"thumbinner\" style=\"width:208px;max-width:208px\"><div 
class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Yellow_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/100px-Yellow_card.svg.png\"
 data-file-type=\"drawing\" height=\"130\" width=\"100\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/200px-Yellow_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Yellow_card.svg/150px-Yellow_card.svg.png
 1.5x\"></a></span></div><div class=\"thumbcaption\" 
style=\"clear:left\">Caution</div></div><div class=\"tsingle\" 
style=\"float:left;margin:1px;width:102px;max-width:102px\"><div 
class=\"thumbimage\"><span><a href=\"/wiki/File:Red_card.svg\" 
class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/100px-Red_card.svg.png\"
 data-file-type=\"drawing\" height=\"130\" width=\"100\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/200px-Red_card.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Red_card.svg/150px-Red_card.svg.png
 1.5x\"></a></span></div><div class=\"thumbcaption\" 
style=\"clear:left\">Ejection</div></div><div style=\"clear:left\"></div><div 
class=\"thumbcaption\" 
style=\"clear:left;text-align:left;background-color:transparent\">Two cards 
used by football referees</div></div></div>\n\n<p>Imagemap:</p>\n<div 
class=\"floatright\">\n<div class=\"noresize\" style=\"height: 152px; width: 
300px; \"><a href=\"http://projects.vassar.edu/1896/democrats.html\"; 
class=\"plainlinks\" rel=\"nofollow\" title=\"1896 Democrats\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/300px-Bryan-Sewall.jpg\"
 width=\"300\" height=\"152\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/450px-Bryan-Sewall.jpg
 1.5x, 
//upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bryan-Sewall.jpg/600px-Bryan-Sewall.jpg
 2x\" usemap=\"#ImageMap_\"></a><map name=\"ImageMap_\" 
id=\"ImageMap_\">\n<area href=\"/wiki/William_Jennings_Bryan\" shape=\"circle\" 
coords=\"73,65,54\" alt=\"William J. Bryan\" title=\"William J. Bryan\">\n<area 
href=\"/wiki/Arthur_Sewall\" shape=\"circle\" coords=\"226,65,54\" alt=\"Arthur 
Sewall\" title=\"Arthur Sewall\"></map>\n<div style=\"margin-left: 280px; 
margin-top: -20px; text-align: left;\"><a href=\"/wiki/File:Bryan-Sewall.jpg\" 
title=\"About this image\"><img 
src=\"/w/extensions/ImageMap/desc-20.png?15600\" style=\"border: 
none;\"></a></div>\n</div>\n</div>\n\n<p>Panoramas:</p>\n<div class=\"thumb 
tnone\" style=\"margin-left: auto; margin-right:auto; overflow:hidden; 
width:auto; max-width:1808px;\">\n<div class=\"thumbinner\" style=\"\"><div 
class=\"overflowbugx\" style=\"overflow:auto;\"><span><a 
href=\"/wiki/File:Helsinki_z00.jpg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/0/07/Helsinki_z00.jpg/1800px-Helsinki_z00.jpg\"
 data-file-type=\"bitmap\" height=\"216\" width=\"1800\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 2x, 
//upload.wikimedia.org/wikipedia/commons/0/07/Helsinki_z00.jpg 
1.5x\"></a></span></div><div class=\"thumbcaption\"><a href=\"/wiki/Helsinki\" 
title=\"Helsinki\">Helsinki</a> has many buildings.</div>\n</div></div>\n\n",
         "toclevel": 1,
         "line": "Images",
         "anchor": "Images"
@@ -230,14 +230,14 @@
         "text": "\n<div class=\"hatnote\">\"WP:TPA\" redirects here. For talk 
page archiving, see <a href=\"/wiki/Help:Archiving_a_talk_page\" 
title=\"Help:Archiving a talk page\">Help:Archiving a talk 
page</a>.</div>\n<p><big id=\"mwWg\"><b>A perfect Wikipedia 
article...</b></big></p>\n<ul><li id=\"mwXQ\"><b>Is on a <a 
href=\"/wiki/Wikipedia:Note\" title=\"Wikipedia:Note\">notable</a> 
topic.</b>\n<ul><li id=\"mwYQ\"><b>Fills a gap</b> not provided by existing or 
related articles.</li></ul></li>\n<li id=\"mwYw\"><b>Has an appropriate 
structure.</b></li></ul>\n\n",
         "toclevel": 1,
         "line": "From <a href=\"/wiki/Wikipedia:The_perfect_article\" 
title=\"Wikipedia:The perfect article\">Wikipedia:The perfect article</a>",
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:The_perfect_article.22_title.3D.22Wikipedia:The_perfect_article.22.3EWikipedia:The_perfect_article.3C.2Fa.3E"
+        "anchor": "From_Wikipedia:The_perfect_article"
       },
       {
         "id": 11,
         "text": "\n\n",
         "toclevel": 1,
         "line": "From <a href=\"/wiki/Wikipedia:Manual_of_Style/Layout\" 
title=\"Wikipedia:Manual of 
Style/Layout\">Wikipedia:Manual_of_Style/Layout</a>",
-        "anchor": 
"From_.3Ca_href.3D.22.2Fwiki.2FWikipedia:Manual_of_Style.2FLayout.22_title.3D.22Wikipedia:Manual_of_Style.2FLayout.22.3EWikipedia:Manual_of_Style.2FLayout.3C.2Fa.3E"
+        "anchor": "From_Wikipedia:Manual_of_Style.2FLayout"
       },
       {
         "id": 12,
@@ -248,7 +248,7 @@
       },
       {
         "id": 13,
-        "text": "\n<div 
style=\"position:relative;top:-3em\"></div><span>\n</span><div 
class=\"shortcutbox plainlist noprint\" style=\"float:right;border:1px solid 
#aaa;background:#fff;margin:.3em .3em .3em 1em;padding:.4em 
.6em;text-align:center;font-size:smaller;line-height:2em;font-weight:bold\"><a 
href=\"/wiki/Wikipedia:Shortcut\" 
title=\"Wikipedia:Shortcut\">Shortcut</a>:\n<ul><li><span 
class=\"plainlinks\"><a rel=\"mw:ExtLink\" 
href=\"//en.wikipedia.org/w/index.php?title=MOS:BODY&amp;redirect=no\" 
class=\"external\">MOS:BODY</a></span></li></ul></div>\n<div 
class=\"hatnote\">Further information: <a href=\"/wiki/Help:Section\" 
title=\"Help:Section\">Help:Section</a> and <a 
href=\"/wiki/Wikipedia:Manual_of_Style#Article_titles.2C_headings.2C_and_sections\"
 title=\"Wikipedia:Manual of Style\">Wikipedia:Manual of Style 
§<span>&nbsp;</span>Article titles, headings, and sections</a></div>\n\n<figure 
class=\"mw-default-size\"><a 
href=\"/wiki/File:Wikipedia_layout_sample_bodies.png\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/180px-Wikipedia_layout_sample_bodies.png\"
 data-file-type=\"bitmap\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/360px-Wikipedia_layout_sample_bodies.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/270px-Wikipedia_layout_sample_bodies.png
 1.5x\" height=\"225\" width=\"180\"></a><figcaption>Body sections appear after 
the lead and table of contents (click on image for larger 
view).</figcaption></figure>\n\n<p>Articles longer than a stub are generally 
divided into sections...</p>\n\n",
+        "text": "\n<div 
style=\"position:relative;top:-3em\"></div><span>\n</span><div 
class=\"shortcutbox plainlist noprint\" style=\"float:right;border:1px solid 
#aaa;background:#fff;margin:.3em .3em .3em 1em;padding:.4em 
.6em;text-align:center;font-size:smaller;line-height:2em;font-weight:bold\"><a 
href=\"/wiki/Wikipedia:Shortcut\" 
title=\"Wikipedia:Shortcut\">Shortcut</a>:\n<ul><li><span 
class=\"plainlinks\"><a rel=\"mw:ExtLink\" 
href=\"//en.wikipedia.org/w/index.php?title=MOS:BODY&amp;redirect=no\" 
class=\"external\">MOS:BODY</a></span></li></ul></div>\n<div 
class=\"hatnote\">Further information: <a href=\"/wiki/Help:Section\" 
title=\"Help:Section\">Help:Section</a> and <a 
href=\"/wiki/Wikipedia:Manual_of_Style#Article_titles.2C_headings.2C_and_sections\"
 title=\"Wikipedia:Manual of Style\">Wikipedia:Manual of Style 
§<span>&nbsp;</span>Article titles, headings, and sections</a></div>\n\n<figure 
class=\"mw-default-size\"><a 
href=\"/wiki/File:Wikipedia_layout_sample_bodies.png\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/180px-Wikipedia_layout_sample_bodies.png\"
 data-file-type=\"bitmap\" height=\"225\" width=\"180\" 
srcset=\"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/360px-Wikipedia_layout_sample_bodies.png
 2x, 
//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Wikipedia_layout_sample_bodies.png/270px-Wikipedia_layout_sample_bodies.png
 1.5x\"></a><figcaption>Body sections appear after the lead and table of 
contents (click on image for larger view).</figcaption></figure>\n\n<p>Articles 
longer than a stub are generally divided into sections...</p>\n\n",
         "toclevel": 2,
         "line": "Body sections",
         "anchor": "Body_sections"
@@ -304,7 +304,7 @@
       },
       {
         "id": 21,
-        "text": "\n\n<table class=\"mbox-small plainlinks sistersitebox\" 
style=\"background-color:#f9f9f9;border:1px solid 
#aaa;color:#000\">\n<tbody><tr>\n<td class=\"mbox-image\"><span 
class=\"noviewer\"><a href=\"/wiki/File:Commons-logo.svg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\"
 data-file-type=\"drawing\" 
srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png
 1.5x\" height=\"40\" width=\"30\"></a></span></td>\n<td class=\"mbox-text 
plainlist\">Wikimedia Commons has media related to <i><b><a rel=\"mw:ExtLink\" 
href=\"https://commons.wikimedia.org/wiki/Category:Wikipedia%20logos\"; 
title=\"commons:Category:Wikipedia logos\" class=\"external\">Wikipedia 
logos</a></b></i>.</td></tr></tbody></table><span>\n</span>\n<p>More precisely, 
box-type templates such as <code>{{<a href=\"/wiki/Template:Commons_category\" 
title=\"Template:Commons category\">Commons category</a>}}</code> shown at 
right have to be put at the beginning of the <i>last section</i></p> \n\n",
+        "text": "\n\n<table class=\"mbox-small plainlinks sistersitebox\" 
style=\"background-color:#f9f9f9;border:1px solid 
#aaa;color:#000\">\n<tbody><tr>\n<td class=\"mbox-image\"><span 
class=\"noviewer\"><a href=\"/wiki/File:Commons-logo.svg\" class=\"image\"><img 
src=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\"
 data-file-type=\"drawing\" height=\"40\" width=\"30\" 
srcset=\"//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png
 2x, 
//upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png
 1.5x\"></a></span></td>\n<td class=\"mbox-text plainlist\">Wikimedia Commons 
has media related to <i><b><a rel=\"mw:ExtLink\" 
href=\"https://commons.wikimedia.org/wiki/Category:Wikipedia%20logos\"; 
title=\"commons:Category:Wikipedia logos\" class=\"external\">Wikipedia 
logos</a></b></i>.</td></tr></tbody></table><span>\n</span>\n<p>More precisely, 
box-type templates such as <code>{{<a href=\"/wiki/Template:Commons_category\" 
title=\"Template:Commons category\">Commons category</a>}}</code> shown at 
right have to be put at the beginning of the <i>last section</i></p> \n\n",
         "toclevel": 2,
         "line": "Links to sister projects",
         "anchor": "Links_to_sister_projects"
diff --git 
"a/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
 
"b/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
index 83ec9bc..7796f70 100644
--- 
"a/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
+++ 
"b/test/diff/results/page_mobile-sections-enwiki-User%3ABSitzmann_\050WMF\051_MCS_Test_TitleLinkEncoding.json"
@@ -19,7 +19,7 @@
       {
         "id": 1,
         "toclevel": 1,
-        "anchor": "Special_chars_.24.25.26amp.3B",
+        "anchor": "Special_chars_.24.25.26",
         "line": "Special chars $%&amp;"
       },
       {
@@ -43,7 +43,7 @@
         "text": "\n<p>Special chars in section heading.</p>\n\n",
         "toclevel": 1,
         "line": "Special chars $%&amp;",
-        "anchor": "Special_chars_.24.25.26amp.3B"
+        "anchor": "Special_chars_.24.25.26"
       },
       {
         "id": 2,
diff --git a/test/lib/anchorencode/anchorencode-test.js 
b/test/lib/anchorencode/anchorencode-test.js
deleted file mode 100644
index b2eedd5..0000000
--- a/test/lib/anchorencode/anchorencode-test.js
+++ /dev/null
@@ -1,41 +0,0 @@
-'use strict';
-
-const assert = require('../../utils/assert.js');
-const a = require('../../../lib/anchorencode');
-
-describe('lib:anchorencode', function() {
-
-    this.timeout(20000); // eslint-disable-line no-invalid-this
-
-    it('anchorencode(empty) should return an empty string', () => {
-        assert.deepEqual(a.anchorencode(''), '');
-    });
-
-    it('anchorencode("a") should return a', () => {
-        assert.deepEqual(a.anchorencode('a'), 'a');
-    });
-
-    it('anchorencode("Z") should return Z', () => {
-        assert.deepEqual(a.anchorencode('Z'), 'Z');
-    });
-
-    it('anchorencode("  Z  ") should return Z', () => {
-        assert.deepEqual(a.anchorencode('  Z  '), 'Z');
-    });
-
-    it('anchorencode("a b c") should return a_b_c', () => {
-        assert.deepEqual(a.anchorencode('a b c'), 'a_b_c');
-    });
-
-    it('anchorencode("a  b  c") should return a_b_c', () => {
-        assert.deepEqual(a.anchorencode('a  b  c'), 'a_b_c');
-    });
-
-    it('anchorencode("!@#$%^&*()") should return 
21.40.23.24.25.5E.26.2A.28.29', () => {
-        assert.deepEqual(a.anchorencode('!@#$%^&*()'), 
'21.40.23.24.25.5E.26.2A.28.29');
-    });
-
-    it('anchorencode(":") should not be converted', () => {
-        assert.deepEqual(a.anchorencode(':'), ':');
-    });
-});
diff --git a/test/lib/parsoid/parsoid-access-test.js 
b/test/lib/parsoid/parsoid-access-test.js
index d20a833..b37e22f 100644
--- a/test/lib/parsoid/parsoid-access-test.js
+++ b/test/lib/parsoid/parsoid-access-test.js
@@ -4,7 +4,10 @@
 const domino = require('domino');
 const parsoid = require('../../../lib/parsoid-access');
 
-const html = '<body>text0<h2>foo</h2>text1<h3 id="mwBa">Funny section 
!@#$%^&*()</h3>text2</body>';
+const html = '<body>text0' +
+    '<h2 id="foo">foo</h2>text1' +
+    '<h3 id="Funny_section_.21.40.23.24">Funny section !@#$%^&*()</h3>text2' +
+    '</body>';
 const headHtml1
     = `<html><head>
         <base href="//en.wikipedia.org/wiki/"/>
@@ -67,7 +70,7 @@
     });
 
     it('getSectionsText() with one h2 should produce two sections', () => {
-        const doc = 
domino.createDocument('<body>text0<h2>foo</h2>text1</body>');
+        const doc = domino.createDocument('<body>text0<h2 
id="foo">foo</h2>text1</body>');
         parsoid._addSectionDivs(doc);
         const sections = parsoid._getSectionsText(doc);
         assert.deepEqual(sections.length, 2);

-- 
To view, visit https://gerrit.wikimedia.org/r/349375
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib774f286e47e6b0a05272fd9cb56dbb8ab00efce
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/services/mobileapps
Gerrit-Branch: master
Gerrit-Owner: BearND <[email protected]>
Gerrit-Reviewer: BearND <[email protected]>
Gerrit-Reviewer: Gergő Tisza <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Mholloway <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to