-
Notifications
You must be signed in to change notification settings - Fork 68
Added options "headings" and "class" #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,26 @@ | ||
| /*! | ||
| * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) | ||
| * Copyright 2015 Aidan Feldman | ||
| * Bootstrap Table of Contents v0.4.2 (http://afeld.github.io/bootstrap-toc/) | ||
| * Copyright 2015 Aidan Feldman, modified by Ircama, 2016 | ||
| * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ | ||
| !function(){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var r=e.find(t);return e.filter(t).add(r).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){var t=$(e).text(),r=t.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g,"-");return r||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),r=0;;r++){var n=t;if(r>0&&(n+="-"+r),!document.getElementById(n))return n}},generateAnchor:function(e){if(e.id)return e.id;var t=this.generateUniqueId(e);return e.id=t,t},createNavList:function(){return $('<ul class="nav"></ul>')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var r=$("<a></a>");r.attr("href","#"+e),r.text(t);var n=$("<li></li>");return n.append(r),n},generateNavItem:function(e){var t=this.generateAnchor(e),r=$(e),n=r.data("toc-text")||r.text();return this.generateNavEl(t,n)},getTopLevel:function(e){for(var t=1;t<=6;t++){var r=this.findOrFilter(e,"h"+t);if(r.length>1)return t}return 1},getHeadings:function(e,t){var r="h"+t,n=t+1,a="h"+n;return this.findOrFilter(e,r+","+a)},getNavLevel:function(e){return parseInt(e.tagName.charAt(1),10)},populateNav:function(e,t,r){var n,a=e,i=this;r.each(function(r,o){var s=i.generateNavItem(o),u=i.getNavLevel(o);u===t?a=e:n&&a===e&&(a=i.createChildNavList(n)),a.append(s),n=s})},parseOps:function(e){var t;return t=e.jquery?{$nav:e}:e,t.$scope=t.$scope||$(document.body),t}},init:function(e){e=this.helpers.parseOps(e),e.$nav.attr("data-toggle","toc");var t=this.helpers.createChildNavList(e.$nav),r=this.helpers.getTopLevel(e.$scope),n=this.helpers.getHeadings(e.$scope,r);this.helpers.populateNav(t,r,n)}},$(function(){$('nav[data-toggle="toc"]').each(function(e,t){var r=$(t);Toc.init(r)})})}(); | ||
| !function(){"use strict" | ||
| window.Toc={helpers:{findOrFilter:function(e,t){var r=e.find(t) | ||
| return e.filter(t).add(r).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){var t=$(e).text(),r=t.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g,"-") | ||
| return r||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),r=0;;r++){var a=t | ||
| if(r>0&&(a+="-"+r),!document.getElementById(a))return a}},generateAnchor:function(e){if(e.id)return e.id | ||
| var t=this.generateUniqueId(e) | ||
| return e.id=t,t},createNavList:function(){return $('<ul class="nav"></ul>')},createChildNavList:function(e){var t=this.createNavList() | ||
| return e.append(t),t},generateNavEl:function(e,t,r,a){var n=$("<a class="+a+r+"></a>") | ||
| n.attr("href","#"+e),n.text(t) | ||
| var i=$("<li></li>") | ||
| return i.append(n),i},generateNavItem:function(e,t,r){var a=this.generateAnchor(e),n=$(e),i=n.data("toc-text")||n.text() | ||
| return this.generateNavEl(a,i,t,r)},getTopLevel:function(e){for(var t=1;6>=t;t++){var r=this.findOrFilter(e,"h"+t) | ||
| if(r.length>1)return t}return 1},getHeadings:function(e,t,r){if(void 0===r){var a="h"+t,n=t+1,i="h"+n | ||
| return this.findOrFilter(e,a+","+i)}return this.findOrFilter(e,r)},getNavLevel:function(e){return parseInt(e.tagName.charAt(1),10)},populateNav:function(e,t,r,a){var n,i=e,s=this | ||
| r.each(function(r,o){var c=s.getNavLevel(o),v=s.generateNavItem(o,c,a) | ||
| t>=c?i=e:n&&i===e&&(i=s.createChildNavList(n)),i.append(v),n=v})},parseOps:function(e){var t | ||
| return t=e.jquery?{$nav:e}:e,t.$scope=t.$scope||$(document.body),t}},init:function(e,t){e=this.helpers.parseOps(e) | ||
| var r=void 0===t?void 0:t.headings,a=void 0===t||void 0===t["class"]||""==t["class"]?"toc-nav-h":t["class"] | ||
| e.$nav.attr("data-toggle","toc") | ||
| var n=this.helpers.createChildNavList(e.$nav),i=this.helpers.getTopLevel(e.$scope),s=this.helpers.getHeadings(e.$scope,i,r) | ||
| this.helpers.populateNav(n,i,s,a)}},$(function(){$('nav[data-toggle="toc"]').each(function(e,t){var r=$(t) | ||
| Toc.init(r)})})}() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -154,6 +154,72 @@ nav[data-toggle='toc'] { | |
| } | ||
| ``` | ||
|
|
||
| ## Additional options | ||
|
|
||
| By default, the plugin finds the first heading level (`<h1>`, then `<h2>`, etc.) that has more than one element and defaults to 1 (for `<h1>`). The identified level becomes the top heading and the plugin supports a single nesting level associated to it, including the subsequent heading only. E.g., if the identified top level is `<h1>`, the nested level will be `<h2>`, which is the next below it; if the top level is `<h2>`, the nested one will be `<h3>`. No additional level to the nested one and no previous level to the top one will be shown. | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is great, thanks for adding!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added it as it took me sometimes to understand that, if my top level was h2, only this level and h3 could be represented, while h1 within the middle of the document and also h4 did not show up. |
||
|
|
||
| The plugin allows options to customize this behavior: | ||
|
|
||
| * `headings` (which can be a string): if set to a list of headers (in the form *hN,hM,...* where N, M, ... are levels, e.g., `h1,h2,h3`), all of them are searched instead of the first declared one and of its subsequent heading. Example: `headings: 'h1,h2,h3,h4,h5,h6'` (in this case, all of them are searched and not only `<h2>` and `<h3>` in case `<h2>` is the top level). | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the use case here? Do you have an example page where you would want to use this? What would the desired outcome be? Also, does this differ from $scope: $('h1,h2,h3,h4,h5,h6')?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi, I generally agree about your comments and you can add new commits to this branch. This PR was more than discuss than considering an immediate merge.
Check this page as an example: https://ircama.github.io/osm-carto-tutorials/tile-server-ubuntu/ Your plugin is running there. In fact, at the end of the HTML: $(function() {
var navSelector = '#toc';
var $myNav = $(navSelector);
Toc.init($myNav, { headings: 'h1,h2,h3,h4,h5,h6' } );
$('body').scrollspy({
target: navSelector,
offset: 220
});
});In the page, you can see that my top level is 2 and that I generally use one sublevel, but there are some paragraphs with an additional sublevel 4: https://ircama.github.io/osm-carto-tutorials/tile-server-ubuntu/#install-mapnik-library-from-package
You see that h4 items are present (this is thanks to
Could you please make an example of this?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's deal with the "depth" feature request separately: #37 |
||
| * `class`: (which can be a string): if set to a string, its value is used to customize the CSS class that the plugin sets for each description, concatenating it with the related header level. If not set, the default class heading will be `toc-nav-h`. Example: by default, a top level description (`<h1>`) has class`toc-nav-h1`, a second level description (`<h2>`) has class `toc-nav-h2`, etc. If the option `class` is set to e.g. `my-class`, a top level description (`<h1>`) will have class `my-class-h1`, a second level description (`<h2>`) will have class `my-class-h2`, etc. This feature allows adding CSS attributes to customize the descriptions according its header level. | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I like the adding of classes to different levels to make styling easier, the customization of said class seems overkill...
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, what's the behavior when the top-level heading in the sidebar corresponds to an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Maybe it is indead an overkill if no one is going to use the same root in other places. You can suggest a code rework or do it yourself if wanted.
If you have top level h2, h1 in the middle of the document will be always shown when setting
To make sure I got your point, would you change
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still not sure I understand the use case here. Feel free to open an issue if you are still interested. |
||
|
|
||
| Example of usage: | ||
|
|
||
| ```javascript | ||
| Toc.init($myNav, { | ||
| headings: 'h1,h2,h3,h4,h5,h6', | ||
| class: 'my-class' | ||
| }); | ||
| ``` | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the existing options object—no need to make a second one.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Would you please suggest a code rework? Thanks
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Toc.init({
$nav: $myNav,
headings: 'h1,h2,h3,h4,h5,h6',
class: 'my-class'
}); |
||
|
|
||
| Example of CSS to customize the behavior of the plugin where the target documentation is supposed to mostly exploit `<h2>` as top level and `<h3>` as neighboring one (supposing to set `headings: 'h1,h2,h3,h4,h5,h6'` and not to change the default `class` option): | ||
|
|
||
| ```css | ||
| /* | ||
| * Customizations of Bootstrap Table of Contents v0.4.2 | ||
| */ | ||
| nav[data-toggle='toc'] .nav .nav > li > a { | ||
| padding-bottom: 3px !important; | ||
| } | ||
| .toc-nav-h1 { | ||
| text-decoration: navy dotted underline; | ||
| font-size: 15px !important; | ||
| padding-left: 15px !important; | ||
| } | ||
| .toc-nav-h4 { | ||
| font-size: 11px !important; | ||
| padding-left: 40px !important; | ||
| } | ||
| .toc-nav-h5 { | ||
| font-size: 11px !important; | ||
| padding-left: 46px !important; | ||
| } | ||
| .toc-nav-h6 { | ||
| font-size: 11px !important; | ||
| padding-left: 52px !important; | ||
| } | ||
| ``` | ||
|
|
||
| The following example includes an additional setting for scrollspy (both `target` and `offset` options are used: | ||
|
|
||
| ```html | ||
| <script> | ||
| try { | ||
| $(function() { | ||
| var navSelector = '#toc'; | ||
| var $myNav = $(navSelector); | ||
| Toc.init($myNav, { headings: 'h1,h2,h3,h4,h5,h6' } ); | ||
| $('body').scrollspy({ | ||
| target: navSelector, | ||
| offset: 220 | ||
| }); | ||
| }); | ||
| } | ||
| catch(e) { | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mind removing the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, right! |
||
| </script> | ||
| ``` | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking it would make more sense to throw an example like this in a sandbox so that it can be interactive, and tweakable by the user.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that would be great, I did not have time to setup it. |
||
|
|
||
| ## See also | ||
|
|
||
| This plugin was heavily inspired by: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind removing this? If all contributions were added to the top of the file, it would get very large very fast 😏 Easier to point people to
https://github.com/afeld/bootstrap-toc/search?q=-author%3Aafeld&type=Issues&utf8=%E2%9C%93
since that list keeps itself up-to-date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, sure!