Skip to content

Instantly share code, notes, and snippets.

Created August 19, 2015 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/ad07b07e48bb0a029913 to your computer and use it in GitHub Desktop.
Save anonymous/ad07b07e48bb0a029913 to your computer and use it in GitHub Desktop.
// Author: Stefan Bauer
// Web Site: http://www.n8d.at/
// Original Blog Post:
// Version: 1.0
// Description:
// JQuery Plugin to add a navigational table of content to SharePoint
// Usage:
// $("#ms-rtestate-file").tocMenu(options);
// This will try to fine all headline tags in the rich text editor state field
// Options:
// orderedList : true will add <ol> tags to table of contents
// : false will add <ul> tage to table of contents
// customStyle : add an additonal stylesheet class to the table of content
// prepend : defines the element where the table of content should be prepended
// : this can be used with class (.ewiki-slink) and id (#yourselector) selector
// headlineText: allows you to lable the table of contents individually e.g with 'Table of Content' ;)
// CHANGES
// 1.1 - Jānis Veinbergs on 19.08.2015
// Depends: speakingurl.js - https://github.com/pid/speakingurl
// Use header ids instead of adding new link elements
// scrollIntoView added
"use strict";
(function ($) {
$.fn.tocMenu = function (options) {
// Helpder Methodes
String.prototype.repeat = function (num) {
return new Array(num + 1).join(this);
};
// Default settings
var defaults = {
orderedlist: true,
customStyle: "no-bullets",
attachTo: ".ewiki-slink",
prepend: true,
headlineText: "Table of Content",
maxLevel: 6,
};
// check if settings exist
var settings = $.extend({}, defaults, options);
var tocElements = "";
this.filter(
function () {
var listTag = "ol";
if ($("#MSOLayout_InDesignMode") !== null && $("#MSOLayout_InDesignMode").val()) {
return;
}
if (!settings.orderedlist) {
listTag = "ul";
}
// Search for filter
var headers = $(":header", $(this));
// Just in case no headers have been found
if (headers.length === 0) {
return;
}
// define previous tag name used for loop and indention
var prevTagName = null;
// check if header should be set
if (settings.headlineText !== null) {
tocElements += "<b>" + settings.headlineText + "</b>";
}
// initalize element of toc
if (settings.customStyle !== null) {
tocElements += "<" + listTag + " class='tocMain " + settings.customStyle + "'>";
} else {
tocElements += "<" + listTag + " class='tocMain'>";
}
// Defiend level of indention to create perfect unorder list
var lvlCounter = 0;
// Loop through headline
for (var i = 0; i < headers.length; i++) {
var tmpHeader = $(headers[i]);
var headerId = tmpHeader.attr("id");
if (!headerId) {
headerId = escape(getSlug(tmpHeader.text()));
//If such id exists, add 6 random chars to id
if ($("#" + headerId).length > 0) {
//ID will however be different when this will open next time and thus hashtag url may not scroll.
headerId += "-" + Math.random().toString(36).substring(12)
}
console.log("Setting header id to : " + headerId);
tmpHeader.attr("id", headerId);
}
if (prevTagName !== null && tmpHeader.prop('tagName') < prevTagName) {
tocElements += ("</" + listTag + ">").repeat(lvlCounter);
lvlCounter -= 1;
} else if (prevTagName !== null && tmpHeader.prop('tagName') > prevTagName) {
tocElements += "<" + listTag + ">";
lvlCounter += 1;
}
tocElements += "<li><a href='#" + headerId + "'>" + tmpHeader.text() + "</a></li>\n";
prevTagName = tmpHeader.prop('tagName');
}
}
);
if (settings.prepend) {
$(settings.attachTo).prepend(tocElements);
} else {
$(settings.attachTo).append(tocElements);
}
// As id's are added dynamically, we must ues javascript to scroll to the place where hashtag points.
if (location.hash) {
var hashElement = $(location.hash);
if (hashElement.length > 0) {
hashElement[0].scrollIntoView();
}
}
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment