AutoTOC

Automatically creates a table of contents for all HTML-headers on a web page.

目前為 2016-01-01 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         AutoTOC
// @namespace    http://runeskaug.com/greasemonkey
// @description  Automatically creates a table of contents for all HTML-headers on a web page.
// @author       Rune Skaug ([email protected])
// @include      http://*
// @include      https://*
// @version      1.7.65
// @released     2005-07-06
// @updated      2006-12-25
// @compatible   Greasemonkey, Opera 8/9
//
// Change history (main changes):
//
// 1.0 - Basic version
// 1.1 - Adds Hide TOC button
// 1.2 - Only show visible headings (Firefox)
//     - Work around Firefox rendering bugs
//     - Adds Menu item: AutoTOC: Toggle display (Firefox)
// 1.3 - Sets a session cookie for TOC hiding (per domain)
// 1.4 - Disables adding of menu item.
//     - Choose your own string pattern to match (RXmatch)
// 1.5 - Minor adjustments for GM 0.6/FF1.5
//     - Moved closebutton to the left
//     - Flash on select
// 1.6 - Xpath search replaces treewalker, FF1,1.5,Opera9
// 1.7 - Minor fixes, screen-only stylesheet
// 
// @ujs:category browser: enhancements
// @ujs:published 2005-07-06 13:03
// @ujs:modified 2005-07-06 17:31
// @ujs:documentation http://userjs.org/scripts/browser/enhancements/auto-toc 
// @ujs:download http://userjs.org/scripts/download/browser/enhancements/auto-toc.user.js 
// @ujs:download.gm http://userjs.org/scripts/download/browser/enhancements/auto-toc.user.js
// ==/UserScript==


/* 
 * Creative Commons Attribution License
 * http://creativecommons.org/licenses/by/2.5/
 */

(function() {
  // text constants
  var fullTOCText = "Table of Contents";
  var hideBtnText = "\u00a0X\u00a0";
  var RXmatch = /^h[1-4]$/i; // regexp
  var XPmatch = "//h1|//h2|//h3|//h4"; // xpath
  //set the optional behaviour of the TOC box
  // if true, resets it to its initial state after you have selected a header - false does not reset it
  var resetSelect = true;
  // if true, shows a "Hide TOC"/close button on the left side of the bar
  var showHide = true;
  // if true, hides the TOC for all pages on current site
  var useCookie = true;
  // if true, adds menu item (Toggle TOC)
  var addMenuItem = true;

  function f() {
    //only on (X)HTML pages containing at least one heading - excludes XML files, text files, plugins and images (displayed using minimal HTML)
    if (document.getElementsByTagName("html").length && ( document.getElementsByTagName('h1').length || 
                                                          document.getElementsByTagName('h2').length || 
                                                          document.getElementsByTagName('h3').length || 
                                                          document.getElementsByTagName('h4').length ) 
                                                     && (!useCookie || (useCookie && getCookie('autotoc_hide')!='true'))) {
      var aHs = getHTMLHeadings();
      if (aHs.length>1) { // HTML document, more than one heading.
        var body = document.getElementsByTagName('body')[0];
        body.style.marginBottom = "24px !important";
        addCSS(
          '@media print { #js-toc {display: none; visibility: hidden; }}\n'+
          '@media screen { #js-toc {position: fixed; left: 0; right: 0; top: auto; bottom: 0; width: 100%; display: block; border-top: 1px solid #777; background: #ddd; margin: 0; padding: 3px; z-index: 9999; }\n'+
          '#js-toc select { font: 8pt verdana, sans-serif; margin: 0; margin-left:5px; background: #fff; color: #000; float: left; padding: 0; vertical-align: bottom;}\n'+
          '#js-toc option { font: 8pt verdana, sans-serif; color: #000; }\n'+
          '#js-toc .hideBtn { font: bold 8pt verdana, sans-serif !important; float: left; margin-left: 2px; margin-right: 2px; padding: 1px; border: 1px solid #999; background: #e7e7e7; }\n'+
          '#js-toc .hideBtn a { color: #333; text-decoration: none; background: transparent;} #js-toc .hideBtn a:hover { color: #333; text-decoration: none; background: transparent;} }'
        );
        // Browser sniff++ - due to rendering bug(s) in FF1.0
        var toc = document.createElement(window.opera||showHide?'tocdiv':'div');
        toc.id = 'js-toc';
        if (showHide) {
          var hideDiv = document.createElement('div');
          hideDiv.setAttribute('class','hideBtn');
          var hideLink = document.createElement('a');
          hideLink.setAttribute("href","#");
          hideLink.setAttribute("onclick",useCookie?"document.getElementById('js-toc').style.display = 'none'; document.cookie = 'autotoc_hide=true; path=/'; return false;":"document.getElementById('js-toc').style.display = 'none';");
          hideLink.appendChild(document.createTextNode(hideBtnText));
          hideDiv.appendChild(hideLink);
          toc.appendChild(hideDiv);
        }
        tocSelect = document.createElement('select');
        tocSelect.setAttribute("onchange", "if(this.value){function flash(rep,delay) { for (var i=rep;i>0;i--) {window.setTimeout('el.style.background=\"#ff7\";',delay*i*2);window.setTimeout('el.style.background=elbg',delay*((i*2)+1));};}; elid = this.value; el=document.getElementById(elid); elbg=el.style.background; location.href='#'+elid; flash(5,100);"+(resetSelect?"this.selectedIndex=0;}":"}"));
        tocSelect.id = 'toc-select';
        tocEmptyOption = document.createElement('option');
        tocEmptyOption.setAttribute('value','');
        tocEmptyOption.appendChild(document.createTextNode(fullTOCText));
        tocSelect.appendChild(tocEmptyOption);
        toc.appendChild(tocSelect);
        document.body.appendChild(toc);  
        for (var i=0,aH;aH=aHs[i];i++) {
          if (aH.offsetWidth) {
            op  = document.createElement("option");
            op.appendChild(document.createTextNode(gs(aH.tagName)+getInnerText(aH).substring(0,100)));
            var refID = aH.id ? aH.id : aH.tagName+'-'+(i*1+1);
            op.setAttribute("value", refID);
            document.getElementById("toc-select").appendChild(op);
            aH.id = refID;
          }
        }
      }
    }
  };
  
  function autoTOC_toggleDisplay() {
    if (document.getElementById('js-toc')) {
      // toc-bar exists
      if (document.getElementById('js-toc').style.display == 'none') {
        document.getElementById('js-toc').style.display = 'block'; 
        if (useCookie) {document.cookie = 'autotoc_hide=; path=/';}
      }
      else {
        document.getElementById('js-toc').style.display = 'none'; 
        if (useCookie) {document.cookie = 'autotoc_hide=true; path=/';}
      };
    } else {
      // toc-bar not created yet, clear hide-cookie and run main script
      if (useCookie) {document.cookie = 'autotoc_hide=; path=/';}
      f();
    }
  }
  
  function getHTMLHeadings() {
    function acceptNode(node) {
      if (node.tagName.match(RXmatch)) { if (node.value+''!='') { return NodeFilter.FILTER_ACCEPT; } }
      return NodeFilter.FILTER_SKIP;
    }
    outArray = new Array();
    // XPath
    if (document.evaluate) {
      var nodes = document.evaluate(XPmatch, document, null, XPathResult.ANY_TYPE, null);
      var thisHeading = nodes.iterateNext();
      var j = 0;
      while (thisHeading) {
        if (thisHeading.textContent+''!='') {
          outArray[j++] = thisHeading;
        }
        thisHeading = nodes.iterateNext();
      }
    }
    // document.getElementsByTagName - slow! :)
    else {
      var els = document.getElementsByTagName("*");
      var j = 0;
      for (var i=0,el;el=els[i];i++) {
        if (el.tagName.match(RXmatch)) outArray[j++] = el;
      }
    }
    return outArray;
  }
  function addCSS(css) {
      var head, styleLink;
      head = document.getElementsByTagName('head')[0];
      if (!head) { return; }
      styleLink = document.createElement('link');
      styleLink.setAttribute('rel','stylesheet');
      styleLink.setAttribute('type','text/css');
      styleLink.setAttribute('href','data:text/css,'+escape(css));
      head.appendChild(styleLink);
  }
  function gs(s){
    s = s.toLowerCase();
    var ret = "";
    for (var i=1; i<(s.substring(1)*1);i++) {
      ret = ret + "\u00a0 \u00a0 ";
    }
    return ret;
  }
  function getInnerText(el) {
    var s='';
    for (var i=0,node; node=el.childNodes[i]; i++) {
      if (node.nodeType == 1) s += getInnerText(node); 
      else if (node.nodeType == 3) s += node.nodeValue;
    }
    return s;
  }
  function getCookie(cname)
  {
  	var namesep = cname + "=";
  	var ca = document.cookie.split(';');
  	for(var i=0, c; c=ca[i]; i++)
  	{
  		c = c.replace(/^\s*|\s*$/g,"");
  		if (c.indexOf(namesep) == 0) {
    		return c.substring(namesep.length,c.length);
  		}
  	}
  	return null;
  }
  // main()
  if (!window.opera && addMenuItem) { 
    GM_registerMenuCommand('AutoTOC: Toggle display', autoTOC_toggleDisplay); 
  }
  f();
})();