vendor: 4,023 bytes, lines 1-93
1/* 2 * Table of Contents jQuery Plugin - jquery.toc 3 * 4 * Copyright 2013 Nikhil Dabas 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 * in compliance with the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17(function ($) { 18 "use strict"; 19 20 // Builds a list with the table of contents in the current selector. 21 // options: 22 // content: where to look for headings 23 // headings: string with a comma-separated list of selectors to be used as headings, ordered 24 // by their relative hierarchy level 25 var toc = function (options) { 26 return this.each(function () { 27 var root = $(this), 28 data = root.data(), 29 thisOptions, 30 stack = [root], // The upside-down stack keeps track of list elements 31 listTag = this.tagName, 32 currentLevel = 0, 33 headingSelectors; 34 35 // Defaults: plugin parameters override data attributes, which override our defaults 36 thisOptions = $.extend( 37 {content: "body", headings: "h1,h2,h3"}, 38 {content: data.toc || undefined, headings: data.tocHeadings || undefined}, 39 options 40 ); 41 headingSelectors = thisOptions.headings.split(","); 42 43 // Set up some automatic IDs if we do not already have them 44 $(thisOptions.content).find(thisOptions.headings).attr("id", function (index, attr) { 45 // Generate a valid ID: must start with a letter, and contain only letters and 46 // numbers. All other characters are replaced with underscores. 47 return attr || 48 $(this).text().replace(/^[^A-Za-z]*/, "").replace(/[^A-Za-z0-9]+/g, "_"); 49 }).each(function () { 50 // What level is the current heading? 51 var elem = $(this), level = $.map(headingSelectors, function (selector, index) { 52 return elem.is(selector) ? index : undefined; 53 })[0]; 54 55 if (level > currentLevel) { 56 // If the heading is at a deeper level than where we are, start a new nested 57 // list, but only if we already have some list items in the parent. If we do 58 // not, that means that we're skipping levels, so we can just add new list items 59 // at the current level. 60 // In the upside-down stack, unshift = push, and stack[0] = the top. 61 var parentItem = stack[0].children("li:last")[0]; 62 if (parentItem) { 63 stack.unshift($("<" + listTag + "/>").appendTo(parentItem)); 64 } 65 } else { 66 // Truncate the stack to the current level by chopping off the 'top' of the 67 // stack. We also need to preserve at least one element in the stack - that is 68 // the containing element. 69 stack.splice(0, Math.min(currentLevel - level, Math.max(stack.length - 1, 0))); 70 } 71 72 // Add the list item 73 $("<li/>").appendTo(stack[0]).append( 74 $("<a/>").text(elem.text()).attr("href", "#" + elem.attr("id")) 75 ); 76 77 currentLevel = level; 78 }); 79 }); 80 }, old = $.fn.toc; 81 82 $.fn.toc = toc; 83 84 $.fn.toc.noConflict = function () { 85 $.fn.toc = old; 86 return this; 87 }; 88 89 // Data API 90 $(function () { 91 toc.call($("[data-toc]")); 92 }); 93}(window.jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.