toc-js.pl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # Copyright (C) 2013 Alex Schroeder <alex@gnu.org>
  2. #
  3. # This program is free software; you can redistribute it and/or modify it under
  4. # the terms of the GNU General Public License as published by the Free Software
  5. # Foundation; either version 3 of the License, or (at your option) any later
  6. # version.
  7. #
  8. # This program is distributed in the hope that it will be useful, but WITHOUT
  9. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License along with
  13. # this program. If not, see <http://www.gnu.org/licenses/>.
  14. use strict;
  15. use v5.10;
  16. use utf8;
  17. AddModuleDescription('toc-js.pl', 'Javascript Table of Contents Extension');
  18. our ($HtmlHeaders, @MyInitVariables);
  19. our ($TocOutlineLibrary);
  20. $TocOutlineLibrary = 'http://h5o.googlecode.com/files/outliner.0.5.0.62.js';
  21. # Add the dojo script to edit pages.
  22. push (@MyInitVariables, \&TocScript);
  23. sub TocScript {
  24. # cookie is not initialized yet so we cannot use GetParam
  25. # Cross browser compatibility: http://www.tek-tips.com/faqs.cfm?fid=4862
  26. # HTML5 Outlines: http://blog.tremily.us/posts/HTML5_outlines/
  27. # Required library: http://code.google.com/p/h5o/
  28. if (GetParam('action', 'browse') eq 'browse') {
  29. $HtmlHeaders .= qq{
  30. <script type="text/javascript" src="$TocOutlineLibrary"></script>
  31. <script type="text/javascript">
  32. function addOnloadEvent(fnc) {
  33. if ( typeof window.addEventListener != "undefined" )
  34. window.addEventListener( "load", fnc, false );
  35. else if ( typeof window.attachEvent != "undefined" ) {
  36. window.attachEvent( "onload", fnc );
  37. }
  38. else {
  39. if ( window.onload != null ) {
  40. var oldOnload = window.onload;
  41. window.onload = function ( e ) {
  42. oldOnload( e );
  43. window[fnc]();
  44. };
  45. }
  46. else
  47. window.onload = fnc;
  48. }
  49. }
  50. // https://stackoverflow.com/questions/280634/endswith-in-javascript
  51. if (typeof String.prototype.endsWith !== 'function') {
  52. String.prototype.endsWith = function(suffix) {
  53. return this.indexOf(suffix, this.length - suffix.length) !== -1;
  54. };
  55. }
  56. var initToc=function() {
  57. var outline = HTML5Outline(document.body);
  58. if (outline.sections.length == 1) {
  59. outline.sections = outline.sections[0].sections;
  60. }
  61. if (outline.sections.length > 1
  62. || outline.sections.length == 1
  63. && outline.sections[0].sections.length > 0) {
  64. var toc = document.getElementById('toc');
  65. if (!toc) {
  66. var divs = document.getElementsByTagName('div');
  67. for (var i = 0; i < divs.length; i++) {
  68. if (divs[i].getAttribute('class') == 'toc') {
  69. toc = divs[i];
  70. break;
  71. }
  72. }
  73. }
  74. if (!toc) {
  75. var h2 = document.getElementsByTagName('h2')[0];
  76. if (h2) {
  77. toc = document.createElement('div');
  78. toc.setAttribute('class', 'toc');
  79. h2.parentNode.insertBefore(toc, h2);
  80. }
  81. }
  82. if (toc) {
  83. var html = outline.asHTML(true);
  84. toc.innerHTML = html;
  85. items = toc.getElementsByTagName('a');
  86. for (var i = 0; i < items.length; i++) {
  87. while (items[i].textContent.endsWith('✎')) {
  88. var text = items[i].childNodes[0].nodeValue;
  89. items[i].childNodes[0].nodeValue = text.substring(0, text.length - 1);
  90. }
  91. }
  92. }
  93. }
  94. }
  95. addOnloadEvent(initToc);
  96. </script>
  97. };
  98. }
  99. }