Skip to content

Commit 4508872

Browse files
author
Manuel Mujica
authored
Merge pull request #11 from bit-docs/ordered-lists
Generate ordered list based on @outline tag value
2 parents 65eda42 + 0d0a749 commit 4508872

File tree

10 files changed

+222
-68
lines changed

10 files changed

+222
-68
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
node_modules/
22
temp/
3-
index.html

.jshintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
"globals": {
2424
"describe": true,
25-
"it": true
25+
"it": true,
26+
"beforeEach": true,
27+
"afterEach": true
2628
}
2729
}

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
language: node_js
22
node_js: node
3+
addons:
4+
firefox: "latest"
35
before_install:
46
- "export DISPLAY=:99.0"
57
- "sh -e /etc/init.d/xvfb start"

package.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "toc.js",
66
"scripts": {
77
"jshint": "jshint *.js --config .jshintrc",
8-
"test": "npm run jshint && mocha --reporter spec",
8+
"test": "npm run jshint && testee test/index.html --browsers firefox --reporter Spec",
99
"postversion": "git push --tags && git push",
1010
"release:pre": "npm version prerelease && npm publish",
1111
"release:patch": "npm version patch && npm publish",
@@ -25,12 +25,19 @@
2525
"url": "https://github.com/bit-docs/bit-docs-html-toc/issues"
2626
},
2727
"homepage": "https://github.com/bit-docs/bit-docs-html-toc#readme",
28-
"system": {},
28+
"system": {
29+
"npmAlgorithm": "flat"
30+
},
2931
"dependencies": {
30-
"can-control": "^3.0.0-pre.5",
31-
"can-stache": "^3.0.0-pre.11"
32+
"can-control": "^3.0.3",
33+
"can-stache": "^3.0.7"
3234
},
3335
"devDependencies": {
34-
"mocha": "^3.1.2"
36+
"chai": "^3.5.0",
37+
"jquery": "^3.1.1",
38+
"jshint": "^2.9.4",
39+
"steal": "^0.16.41",
40+
"steal-mocha": "0.0.3",
41+
"testee": "^0.3.0-pre.2"
3542
}
3643
}

test/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>bit-docs-html-toc</title>
5+
</head>
6+
7+
<body>
8+
<div id="mocha"></div>
9+
<div id="test-area"></div>
10+
11+
<script
12+
data-mocha="bdd"
13+
data-main="test/test"
14+
src="../node_modules/steal/steal.js"
15+
>
16+
</script>
17+
</body>
18+
</html>

test/make-tree-test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
var assert = require("assert");
21
var makeTree = require("../make-tree");
2+
var assert = require("chai/chai").assert;
3+
4+
require("steal-mocha");
35

46
describe("makeTree", function() {
57
it("makes flat trees based on heading tag names", function() {

test/test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require("./make-tree-test");
2+
require("./toc-control-test");

test/toc-control-test.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
var $ = require("jquery");
2+
var assert = require("chai/chai").assert;
3+
var TableOfContents = require("../toc-control");
4+
5+
require("steal-mocha");
6+
7+
describe("TableOfContents", function() {
8+
var $el, $testArea;
9+
10+
beforeEach(function() {
11+
$("body").append("<ul id=\"toc-test\"></ul>");
12+
13+
$el = $("#toc-test");
14+
$testArea = $("#test-area");
15+
});
16+
17+
afterEach(function() {
18+
$el.remove();
19+
$testArea.empty();
20+
});
21+
22+
it("makes a flat list from headings", function() {
23+
var headings = [
24+
"<h2>Usage</h2>",
25+
"<h2>Install</h2>",
26+
"<h2>Configure</h2>",
27+
"<h2>Configure</h2>"
28+
];
29+
30+
$testArea.html(headings.join(""));
31+
32+
new TableOfContents($el.get(0), {
33+
tagName: "ul",
34+
depth: 1,
35+
headingsContainerSelector: "#test-area"
36+
});
37+
38+
assert.equal($el.html(), [
39+
'<li><a href="#usage">Usage</a></li>',
40+
'<li><a href="#install">Install</a></li>',
41+
'<li><a href="#configure">Configure</a></li>',
42+
'<li><a href="#configure-1">Configure</a></li>'
43+
].join(""));
44+
});
45+
46+
it("makes nested lists from headings hierarchy", function() {
47+
var headings = [
48+
"<h2>Bower</h2>",
49+
"<h3>Install</h3>",
50+
"<h2>NPM</h2>",
51+
"<h3>Install</h3>",
52+
"<h4>Configure</h4>",
53+
"<h2>Writing Modules</h2>",
54+
];
55+
56+
$testArea.html(headings.join(""));
57+
58+
new TableOfContents($el.get(0), {
59+
tagName: "ul",
60+
depth: 3,
61+
headingsContainerSelector: "#test-area"
62+
});
63+
64+
assert.equal($el.find(">li:eq(0) ul").length, 1, "bower has a nested list");
65+
assert.equal($el.find(">li:eq(1) ul").length, 2, "npm two nested lists");
66+
assert.equal($el.find(">li:eq(2) ul").length, 0, "writing modules has no nested lists");
67+
});
68+
69+
it("nests lists based on DEPTH value", function() {
70+
var headings = [
71+
"<h2>Bower</h2>",
72+
"<h3>Install</h3>",
73+
"<h2>NPM</h2>",
74+
"<h3>Install</h3>",
75+
"<h4>Configure</h4>",
76+
"<h2>Writing Modules</h2>"
77+
];
78+
79+
$testArea.html(headings.join(""));
80+
81+
new TableOfContents($el.get(0), {
82+
tagName: "ul",
83+
depth: 1,
84+
headingsContainerSelector: "#test-area"
85+
});
86+
87+
assert.equal($el.html(), [
88+
'<li><a href="#bower">Bower</a></li>',
89+
'<li><a href="#npm">NPM</a></li>',
90+
'<li><a href="#writing-modules">Writing Modules</a></li>'
91+
].join(""));
92+
});
93+
});

toc-control.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
var stache = require("can-stache");
2+
var Control = require("can-control");
3+
var makeTree = require("./make-tree");
4+
5+
var template = stache("{{#each nodes}}{{renderNode tagName .}}{{/each}}");
6+
7+
var renderNode = stache(
8+
"<li>" +
9+
"<a href='#{{node.id}}'>{{node.text}}</a>" +
10+
"{{#if node.children.length}}" +
11+
"{{#is tagName 'ul'}}" +
12+
"<ul>{{#each node.children}}{{renderNode tagName .}}{{/each}}</ul>" +
13+
"{{else}}" +
14+
"<ol>{{#each node.children}}{{renderNode tagName .}}{{/each}}</ol>" +
15+
"{{/is}}" +
16+
"{{/if}}" +
17+
"</li>"
18+
);
19+
20+
stache.registerSimpleHelper("renderNode", function(tagName, node) {
21+
return renderNode({ tagName: tagName, node: node });
22+
});
23+
24+
module.exports = Control.extend({
25+
init: function(el, options) {
26+
this.depth = options.depth;
27+
this.tagName = options.tagName;
28+
this.headingsContainerSelector = options.headingsContainerSelector;
29+
30+
var titles = this.collectTitles();
31+
32+
// If there are no titles, bail
33+
if (!titles.length) {
34+
el.parentNode.removeChild(el);
35+
return;
36+
} else {
37+
el.parentNode.style.display = 'block';
38+
}
39+
40+
// Append our template
41+
this.element.appendChild(template({
42+
nodes: titles,
43+
tagName: this.tagName
44+
}));
45+
},
46+
47+
makeSelector: function(tagName) {
48+
var container = this.headingsContainerSelector;
49+
return container + " " + tagName;
50+
},
51+
52+
collectTitles: function() {
53+
var selector = this.getHeadings()
54+
.map(this.makeSelector.bind(this))
55+
.join(",");
56+
57+
var titles = selector ? document.querySelectorAll(selector) : [];
58+
return makeTree(titles);
59+
},
60+
61+
getHeadings: function() {
62+
var headings = [];
63+
64+
for(var i = 0; i < this.depth; i++) {
65+
headings.push("h" + (i + 2));
66+
}
67+
68+
return headings;
69+
}
70+
});
71+

toc.js

Lines changed: 18 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,32 @@
1-
var stache = require("can-stache");
21
var Control = require("can-control");
3-
var makeTree = require("./make-tree");
2+
var TableOfContents = require("./toc-control");
43

5-
var template = stache("{{#each nodes}}{{renderNode .}}{{/each}}");
6-
7-
var renderNode = stache(
8-
"<li>" +
9-
"<a href='#{{id}}'>{{text}}</a>" +
10-
"{{#if children.length}}" +
11-
"<ul>{{#each children}}{{renderNode .}}{{/each}}</ul>" +
12-
"{{/if}}" +
13-
"</li>"
14-
);
4+
var TOCContainer = Control.extend({
5+
init: function(el) {
6+
el.style.display = "none";
157

16-
stache.registerSimpleHelper("renderNode", renderNode);
8+
var depth = this.getOutlineDepth();
9+
var tagName = this.getOutlineTagName();
10+
var toc = document.createElement(tagName);
1711

18-
var TableOfContents = Control.extend({
19-
init: function(el, options) {
20-
var titles = this.collectTitles();
12+
toc.className = "on-this-page";
13+
el.appendChild(toc);
2114

22-
// If there are no titles, bail
23-
if (!titles.length) {
24-
el.parentNode.removeChild(el);
25-
return;
26-
} else {
27-
el.parentNode.style.display = 'block';
28-
}
15+
new TableOfContents(toc, {
16+
depth: depth,
17+
tagName: tagName,
18+
headingsContainerSelector: "article"
19+
});
20+
},
2921

30-
// Append our template
31-
this.element.appendChild(template({
32-
nodes: titles
33-
}));
22+
getOutlineTagName: function() {
23+
var outline = window.docObject.outline || {};
24+
return (outline.tag === "ol") ? "ol" : "ul";
3425
},
3526

3627
getOutlineDepth: function() {
3728
var depth = window.docObject.outline && window.docObject.outline.depth;
3829
return (typeof depth === "number" ? Math.min(depth, 6) : 1);
39-
},
40-
41-
makeSelector: function(tagName) {
42-
return "article " + tagName;
43-
},
44-
45-
collectTitles: function() {
46-
var selector = this.getHeadings().map(this.makeSelector).join(",");
47-
var titles = selector ? document.querySelectorAll(selector) : [];
48-
49-
return makeTree(titles);
50-
},
51-
52-
getHeadings: function() {
53-
var headings = [];
54-
var depth = this.getOutlineDepth();
55-
56-
for(var i = 0; i < depth; i++) {
57-
headings.push("h" + (i + 2));
58-
}
59-
return headings;
60-
}
61-
});
62-
63-
var TOCContainer = Control.extend({
64-
init: function(el) {
65-
el.style.display = "none";
66-
67-
var toc = document.createElement("ul");
68-
toc.className = "on-this-page";
69-
el.appendChild(toc);
70-
71-
new TableOfContents(toc);
7230
}
7331
});
7432

0 commit comments

Comments
 (0)