Skip to content

Commit d956b4a

Browse files
authored
Merge pull request #1 from KevinAst/next1
Next1
2 parents 50208a3 + 2cbdef3 commit d956b4a

File tree

7 files changed

+385
-1
lines changed

7 files changed

+385
-1
lines changed

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# node dependencies (defined via "npm install")
2+
/node_modules/
3+
4+
# logs
5+
logs
6+
*.log
7+
npm-debug.log*
8+
9+
# runtime data
10+
pids
11+
*.pid
12+
*.seed

CHANGELOG.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Change Log
2+
3+
The **gitbook-plugin-folding-menu** project adheres to [Semantic
4+
Versioning](http://semver.org/).
5+
6+
Each release is documented on this page *(in addition to the [Github
7+
Release
8+
Notes](https://github.com/KevinAst/gitbook-plugin-folding-menu/releases))*,
9+
and **contains migration instructions**.
10+
11+
## Summary:
12+
13+
Release | What | *When*
14+
---------|-------------------------------------------------|------------------
15+
[v1.0.0] | Initial Release | *September 7, 2018*
16+
17+
[v1.0.0]: #v100---initial-release-september-7-2018
18+
19+
20+
21+
<!-- UNRELEASED **************************************************************************
22+
23+
TEMPLATE:
24+
## vn.n.n - DESC *(DATE X, 2018)*
25+
26+
[GitHub Content](https://github.com/KevinAst/gitbook-plugin-folding-menu/tree/vn.n.n)
27+
&bull;
28+
[GitHub Release](https://github.com/KevinAst/gitbook-plugin-folding-menu/releases/tag/vn.n.n)
29+
&bull;
30+
[Diff](https://github.com/KevinAst/gitbook-plugin-folding-menu/compare/v1.0.0...v1.0.1)
31+
32+
RUNNING CONTENT (pop out as needed) ...
33+
34+
- adorn bullets with following bolded prefix
35+
**Added**: ... for new features
36+
**Changed**: ... for changes in existing functionality
37+
**Deprecated**: ... for soon-to-be removed features
38+
**Removed**: ... for now removed features
39+
**Fixed**: ... for any bug fixes
40+
**Enhanced**: ... for enhancements
41+
**Security**: ... in case of vulnerabilities
42+
**Docs**: ... changes in documentation
43+
**Review**: ... requires review
44+
**Internal**: ... internal change NOT affecting user/client
45+
46+
47+
UNRELEASED ******************************************************************************** -->
48+
49+
50+
51+
52+
<!-- *** RELEASE *************************************************************** -->
53+
54+
## v1.0.0 - Initial Release *(September 7, 2018)*
55+
[GitHub Content](https://github.com/KevinAst/gitbook-plugin-folding-menu/tree/v1.0.0)
56+
&bull;
57+
[GitHub Release](https://github.com/KevinAst/gitbook-plugin-folding-menu/releases/tag/v1.0.0)
58+
59+
**This is where it all began ...**
60+
61+
1. Holy Guacamole Batman! ... _This commit has no parents!!_
File renamed without changes.

README.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,67 @@
11
# gitbook-plugin-folding-menu
2-
GitBook plugin that "tames" large left-nav menus by visualizing one section at a time.
2+
3+
This gitbook plugin **manages large left-nav menus** by **visualizing only
4+
one section at a time** _(the active section)_.
5+
6+
<!--- Badges for CI Builds --->
7+
8+
[![NPM Version Badge](https://img.shields.io/npm/v/gitbook-plugin-folding-menu.svg)](https://www.npmjs.com/package/gitbook-plugin-folding-menu)
9+
10+
## Overview
11+
12+
The high-level points of interest are:
13+
14+
- On initial display, only the top-level menu items are displayed.
15+
16+
- Navigating to a section with sub-content will dynamically expand it,
17+
collapsing any prior section.
18+
19+
- The active section will expose the entire sub-menu depth _(i.e. all
20+
it's ancestry, not just direct children)_.
21+
22+
- Navigating between sections continues to expand only the active
23+
section _(expanding the active section while collapsing any section
24+
previously expanded)_.
25+
26+
- **Animation is used** to make the user experience more intuitive
27+
_(i.e. they can visually see what is happening)_!
28+
29+
- Sections that are composed of multiple pages are supported.
30+
31+
This plugin has the effect of "taming" a big unruly menu structure, by
32+
exposing only one section at a time, making it more intuitive for
33+
end-user consumption.
34+
35+
You can **see this in action** at: https://feature-u.js.org/ _(one of
36+
my open source projects)_.
37+
38+
This project is a significant improvement on other similar plugins.
39+
40+
## Install
41+
42+
- Add the `"folding-menu"` plugin to your **book.json** file:
43+
44+
```js
45+
{
46+
"plugins": [
47+
... other plugins you may be using
48+
"folding-menu"
49+
]
50+
}
51+
```
52+
53+
- For https://legacy.gitbook.com/ usage, plugins are automatically installed.
54+
55+
- For local gitbook usage run `gitbook install` to install and prepare
56+
all plugins for your books:
57+
58+
```shell
59+
gitbook install
60+
```
61+
62+
- For technical users _(ex: open source documentation)_, install the
63+
plugin to your **devDependencies** as follows:
64+
65+
```shell
66+
npm install --save-dev gitbook-plugin-folding-menu
67+
```

book/plugin.js

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
//***
2+
//*** gitbook-plugin-folding-menu:
3+
//*** GitBook plugin that tames large left-nav menus
4+
//*** by visualizing one section at a time.
5+
//***
6+
require(["gitbook", "jQuery"], function(gitbook, $) {
7+
8+
// listen for gitbook "page.change" events
9+
// ... emitted whenever a file.md changes
10+
gitbook.events.bind("page.change", function(e) {
11+
12+
// handle obsecure case where 'active' class designation is delayed
13+
// - either when different MD files are used within sections/sub-sections
14+
// - or when api.md is referenced in multiple seperate sections
15+
// ... i.e. Core API and Extension API
16+
// > process on next event tick (i.e. timeout) seems to help
17+
setTimeout( function() {
18+
19+
diag('page.change event ... e: ', e);
20+
21+
// locate our top level sections
22+
// ... NOTE: this must be inside our event processor.
23+
// - We cannot perform this once statically,
24+
// - BECAUSE, each page change in gitbook is a FULL page change!
25+
// causing a fresh new DOM to be rendered!
26+
var $topNav = $('ul.summary');
27+
diag('$topNav: ', $topNav);
28+
var $topSections = $topNav.children('li.chapter').children('ul.articles');
29+
diag('$topSections length(' + $topSections.length + ') ... ', $topSections);
30+
31+
// locate activeChapter
32+
// ... there will always be only one (defaults to the first)
33+
// ... this is what is visually highlighted
34+
// ... can be at any depth
35+
// >>> KEY:
36+
// <li class="chapter"> at a file break (can be lower down)
37+
var $activeChapter = $('li.chapter.active'); // various renditions ... all seem to work
38+
// var $activeChapter = $('li.active');
39+
// var $activeChapter = $('.active');
40+
diag('$activeChapter length(' + $activeChapter.length + ') ... ', $activeChapter);
41+
42+
// locate our active top-level section
43+
var $activeTopSection = locateActiveTopSection($activeChapter);
44+
diag('$activeTopSection length(' + $activeTopSection.length + ') ... ', $activeTopSection);
45+
46+
// for our animation to work correctly, we must baseline our
47+
// prior section visibility (INSTANTLY - i.e. no animation)
48+
// ... BECAUSE, each page change in gitbook is a FULL page change,
49+
// the entire page is re-displayed, so a page change ALWAYS
50+
// starts out with leftNav expanded!!!
51+
baselinePriorVisibility($topSections);
52+
53+
// leave the last expanded section in-tact, when a the current section has NO content
54+
// ... by simply no-oping
55+
if ($activeTopSection.length === 0) {
56+
return;
57+
}
58+
59+
// sync our left-nav to display ONLY the active top section
60+
// ... FINALLY: this is what we are here for :-)
61+
// ... we itterate over each, applying show/hide directives
62+
// as opposed to sledge hammer
63+
// a: hide all top,
64+
// b: show active
65+
// ... this has a MUCH better visual
66+
// ... we also use animation - THANK YOU jQuery!!
67+
var activeTopSectionElm = $activeTopSection.get(0); // undefined if out-of-bounds
68+
$topSections.each( function(indx, topSectionElm) {
69+
if (topSectionElm === activeTopSectionElm) {
70+
setVisible(topSectionElm, 'show');
71+
}
72+
else {
73+
setVisible(topSectionElm, 'hide');
74+
}
75+
});
76+
77+
}, 0); // TIMEOUT for next event tick
78+
79+
});
80+
81+
// cache retaining current visibility of sections
82+
// - NOTE: We cannot retain this state in the DOM
83+
// via jQuery.data()
84+
// BECAUSE, each page change in gitbook is a FULL page change!
85+
// In other words, the entire page is re-displayed
86+
// so a page change ALWAYS starts out with leftNav expanded!!!
87+
// THEREFORE: we maintain our own cache, keyed by the data-path
88+
// maintained in the DOM by gitbook.
89+
var visibilityCache = {
90+
/* dynamically maintained ... ex:
91+
elmSectionKey: 'show'/'hide'
92+
============== =============
93+
'usage.html': 'show'
94+
'detail.html': 'hide'
95+
*/
96+
};
97+
98+
// baseline our prior section visibility (INSTANTLY - i.e. no animation)
99+
// ... BECAUSE, each page change in gitbook is a FULL page change,
100+
// the entire page is re-displayed, so a page change ALWAYS
101+
// starts out with leftNav expanded!!!
102+
function baselinePriorVisibility($topSections) {
103+
$topSections.each( function(indx, topSectionElm) {
104+
var sectionKey = getSectionKey(topSectionElm);
105+
var sectionVisibility = getCurSectionVisibility(sectionKey);
106+
if (sectionVisibility === 'show') {
107+
$(topSectionElm).show(); // NO animation on baseline
108+
}
109+
else {
110+
$(topSectionElm).hide(); // NO animation on baseline
111+
}
112+
});
113+
}
114+
115+
// return the persistent section key for the supplied elmSection (ex: "detail.html")
116+
// ... sample elmSection DOM expection (from gitbook generation of leftNav)
117+
// <ul>
118+
// <li data-path="detail.html"> ... we hang our hat on this data-path (maintained by gitbook)
119+
// <li data-path="detail.html#someHash">
120+
// <li data-path="detail.html#etc">
121+
// </ul>
122+
function getSectionKey(elmSection) { // 'show'/'hide'
123+
var domKey = 'data-path'; // maintained by gitbook (something unique to hang our hat on)
124+
var sectionKey = elmSection.childNodes[1].getAttribute(domKey); // HACK: a bit vulnerable ... [0] is a text node, [1] is ... ex: 'detail.html'
125+
return sectionKey;
126+
}
127+
128+
// return the current visibilitys of the supplied sectionKey (from our cache)
129+
function getCurSectionVisibility(sectionKey) { // 'show'/'hide'
130+
var curVisibility = visibilityCache[sectionKey];
131+
return curVisibility || 'hide'; // we force the default/initial state bo be hidden (with our baseline process - an initial display will collapse all sections - but the active)
132+
}
133+
134+
// convenience routine to show/hide supplied elmSection
135+
// ... keeping track of current visibility state
136+
// - resulting in a MUCH better visual
137+
function setVisible(elmSection, directive) {
138+
139+
var animationDelay = 400; // utilize an appropriate animation delay (nice visual)
140+
141+
var sectionKey = getSectionKey(elmSection);
142+
var curSectionVisibility = getCurSectionVisibility(sectionKey);
143+
144+
var diagMsg = 'setVisible(elmSection: ' + sectionKey + ', directive: ' + directive + ') ... curSectionVisibility: ' + curSectionVisibility + ' ... ';
145+
146+
// apply the visibility directive, when needed (based on cached current visibility)
147+
if (directive === 'show') {
148+
if (curSectionVisibility !== 'show') { // when out-of-sync
149+
$(elmSection).show(animationDelay); // ... change visiblity WITH animation
150+
visibilityCache[sectionKey] = 'show'; // ... maintaining our cache
151+
diagMsg += 'SHOWING';
152+
}
153+
else {
154+
diagMsg += 'no-oping';
155+
}
156+
}
157+
else {
158+
if (curSectionVisibility !== 'hide') { // when out-of-sync
159+
$(elmSection).hide(animationDelay); // ... change visiblity WITH animation
160+
visibilityCache[sectionKey] = 'hide'; // ... maintaining our cache
161+
diagMsg += 'HIDING';
162+
}
163+
else {
164+
diagMsg += 'no-oping';
165+
}
166+
}
167+
168+
diag(diagMsg);
169+
}
170+
171+
// locate top level chapter
172+
// ... drill up till parent is <ul class="summary">
173+
function topChapter($elm) {
174+
// normally the initial supplied $elm is what we want
175+
// ... however, when a sub-section is part of a separate file (e.g. api.md under coreApi.md)
176+
// then the initial $elm is lower, and we must drill up (recursively)
177+
if ($elm.parent().attr('class') !== 'summary' &&
178+
$elm.length !== 0) {
179+
diag('topChapter UP');
180+
return topChapter($elm.parent());
181+
}
182+
else {
183+
diag('topChapter USE: ', $elm);
184+
return $elm;
185+
}
186+
}
187+
188+
// locate our active top section
189+
function locateActiveTopSection($activeChapter) {
190+
// drill up till parent is <ul class="summary">
191+
var $topChapter = topChapter($activeChapter);
192+
193+
// resolve chapter into section (if any)
194+
// ... will be an item of 0 length if there is no section
195+
return $topChapter.children('ul.articles');
196+
}
197+
198+
// convenience diagnostic logger
199+
function diag(msg, obj) {
200+
return; // comment out to enable
201+
console.log('Manage LeftNav: ' + msg,
202+
obj ? obj : '');
203+
}
204+
205+
});

index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
book: {
3+
assets: "./book",
4+
js: [
5+
"plugin.js"
6+
]
7+
}
8+
};

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "gitbook-plugin-folding-menu",
3+
"version": "1.0.0",
4+
"description": "GitBook plugin that tames large left-nav menus by visualizing one section at a time",
5+
"main": "index.js",
6+
"engines": {
7+
"gitbook": "*"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/KevinAst/gitbook-plugin-folding-menu.git"
12+
},
13+
"keywords": [
14+
"gitbook",
15+
"plugin",
16+
"menu",
17+
"folding menu",
18+
"collapsible menu",
19+
"utility",
20+
"util",
21+
"utils",
22+
"js",
23+
"javascript",
24+
"geeku",
25+
"astx"
26+
],
27+
"author": "Kevin J. Bridges <kevinast@gmail.com> (https://github.com/KevinAst)",
28+
"license": "MIT",
29+
"bugs": {
30+
"url": "https://github.com/KevinAst/gitbook-plugin-folding-menu/issues"
31+
},
32+
"homepage": "https://github.com/KevinAst/gitbook-plugin-folding-menu"
33+
}

0 commit comments

Comments
 (0)