Skip to content

Commit

Permalink
Add new floating toc
Browse files Browse the repository at this point in the history
  • Loading branch information
bterlson committed Aug 21, 2015
1 parent 6e0ea35 commit 2a32b40
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 24 deletions.
1 change: 1 addition & 0 deletions bin/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = require('nomnom')
css: { metavar: 'FILE', help: 'Write Emu CSS dependencies to FILE' },
js: { metavar: 'FILE', help: 'Write Emu JS dependencies to FILE' },
toc: { flag: true, help: 'Don\'t include the table of contents' },
oldToc: { full: 'old-toc', name: 'old-toc', flag: true, help: 'Use the old table of contents styling' },
verbose: { flag: true, default: false, help: 'Display document build progress' },
version: {
abbr: 'v',
Expand Down
2 changes: 1 addition & 1 deletion bin/ecmarkup.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ ecmarkup.build(args.infile, fetch, args).then(function (spec) {
}

if (args.js) {
fs.writeFileSync(args.js, fs.readFileSync(Path.join(__dirname, '../js/ecmarkup.js')));
fs.writeFileSync(args.js, fs.readFileSync(Path.join(__dirname, '../js/menu.js')));
}
});
153 changes: 150 additions & 3 deletions css/elements.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
html {
padding: 0 7em;
}

body {
Expand All @@ -8,8 +7,13 @@ body {
font-family: Cambria, Palatino Linotype, Palatino, Liberation Serif, serif;
padding: 0;
color: #333;
max-width: 65em;
margin: 0 auto;
max-width: 844px;
margin: 0 0 0 31%;
overflow-x: hidden;
}

body.oldtoc {
margin: 0 auto;
}

a {
Expand Down Expand Up @@ -327,3 +331,146 @@ del {
del.block {
display: block;
}

/* Menu Styles */
#menu-toggle {
font-size: 2em;

position: fixed;
top: 0;
left: 0;
width: 1.5em;
height: 1.5em;
z-index: 3;
visibility: hidden;

background-color: #111;
color: #B6C8E4;

line-height: 1.5em;
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;;

cursor: pointer;
}

#menu {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 24%;
z-index: 2;
overflow-x: hidden;
overflow-y: auto;
box-sizing: border-box;

background-color: #111;

transition: opacity 0.1s linear;
}

#menu.active {
display: block;
opacity: 1;
}

#menu-toc > ol {
padding: 0;
}

#menu-toc > ol , #menu-toc > ol ol {
list-style-type: none;
}

#menu-toc > ol ol {
padding-left: 0.75em;
}

#menu-toc li {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

#menu-toc .item-toggle {
display: inline-block;
transform: rotate(-45deg) translate(-5px, -5px);
transition: transform 0.1s ease;
width: 1em;

color: #555F6E;

-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;;

cursor: pointer;
}

#menu-toc .item-toggle-none {
display: inline-block;
width: 1em;
}

#menu-toc li.active > .item-toggle {
transform: rotate(0);
}

#menu-toc li > ol {
display: none;
}

#menu-toc li.active > ol {
display: block;
}

#menu-toc li > a {
padding-left: 0.25em;
color: #B6C8E4;
}

@media (max-width: 1366px) {
body {
margin: 0 0 0 150px;
}

#menu {
display: none;
padding-top: 2em;
width: 323px;
}

#menu-toggle {
visibility: visible;
}
}

@media only screen and (max-width: 800px) {
body {
margin: 2em 10px 0 10px;
}

#menu {
width: 100%;
}

h1 .secnum {
display: inline;
position: inherit;
left: 0;
right: 0;
}

h1 .secnum:empty {
margin: 0; padding: 0;
}
}
36 changes: 36 additions & 0 deletions js/menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use strict";

function Menu() {
this.$toggle = document.getElementById('menu-toggle');
this.$menu = document.getElementById('menu');

this.$toggle.addEventListener('click', this.toggle.bind(this));

var tocItems = this.$menu.querySelectorAll('#menu-toc li');
for (var i = 0; i < tocItems.length; i++) {
var $item = tocItems[i];
$item.addEventListener('click', function($item, event) {
$item.classList.toggle('active');
event.stopPropagation();
}.bind(null, $item));
}

var tocLinks = this.$menu.querySelectorAll('#menu-toc li > a');
for (var i = 0; i < tocLinks.length; i++) {
var $link = tocLinks[i];
$link.addEventListener('click', function(event) {
this.toggle();
event.stopPropagation();
}.bind(this));
}
}

Menu.prototype.toggle = function () {
this.$menu.classList.toggle("active");
}

function init() {
var menu = new Menu();
}

document.addEventListener('DOMContentLoaded', init);
25 changes: 25 additions & 0 deletions lib/Menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

const Builder = require('./Builder');
const Toc = require('./Toc');

module.exports = class Menu extends Builder {
build() {
const toc = Toc.build(this.spec, true);
const tocContainer = this.spec.doc.createElement('div');
tocContainer.setAttribute('id', 'menu-toc');
tocContainer.innerHTML = toc;

const menuContainer = this.spec.doc.createElement('div');
menuContainer.setAttribute('id', 'menu');
menuContainer.appendChild(tocContainer);

this.spec.doc.body.insertBefore(menuContainer, this.spec.doc.body.firstChild);

const menuToggle = this.spec.doc.createElement('div');
menuToggle.setAttribute('id', 'menu-toggle');
menuToggle.textContent = '☰';

this.spec.doc.body.insertBefore(menuToggle, this.spec.doc.body.firstChild);
}
};
13 changes: 10 additions & 3 deletions lib/Spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Algorithm = require('./Algorithm');
const Dfn = require('./Dfn');
const Note = require('./Note');
const Toc = require('./Toc');
const Menu = require('./Menu');
const Production = require('./Production');
const ProdRef = require('./ProdRef');
const Grammar = require('./Grammar');
Expand Down Expand Up @@ -124,8 +125,15 @@ module.exports = class Spec {
if (this.opts.toc) {
p = p.then(function() {
this._log('Building table of contents...');
const tb = new Toc(this);
return tb.build();

let toc;

if (this.opts.oldToc) {
toc = new Toc(this);
} else {
toc = new Menu(this);
}
return toc.build();
}.bind(this));
}

Expand Down Expand Up @@ -311,4 +319,3 @@ function assign(target, source) {
target[k] = source[k];
});
}

40 changes: 28 additions & 12 deletions lib/Toc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,42 @@ module.exports = class Toc extends Builder {
return;
}

const html = buildToc(this.spec);
const html = Toc.build(this.spec);
const tocContainer = this.spec.doc.createElement('div');
tocContainer.innerHTML = '<h2>Table of Contents</h2>' + html;
const intro = this.spec.doc.querySelector('emu-intro, emu-clause, emu-annex');
intro.parentNode.insertBefore(tocContainer, intro);

const bodyClass = this.spec.doc.body.getAttribute('class') || '';
this.spec.doc.body.setAttribute('class', bodyClass + ' oldtoc');
}
};

function buildToc(spec, level) {
level = level || spec;
static build(level, expandy) {
let html = '<ol class="toc">';

level.subclauses.forEach(function(sub) {
html += '<li>';

let html = '<ol class="toc">';
if (expandy) {
if (sub.subclauses.length > 0) {
html += '<span class="item-toggle">◢</span>';
} else {
html += '<span class="item-toggle-none"></span>';
}
}

level.subclauses.forEach(function (sub) {
html += '<li><a href="#' + sub.id + '"><span class="secnum">' + sub.number + '</span> ' + emd.fragment(sub.title) + '</a>';
if (sub.subclauses.length > 0) html += buildToc(spec, sub);
html += '</li>';
});
html += '<a href="#' + sub.id + '" title="' + sub.title + '"><span class="secnum">' + sub.number + '</span> ' + emd.fragment(shorten(sub.title)) + '</a>';
if (sub.subclauses.length > 0) html += Toc.build(sub, expandy);
html += '</li>';
});

html += '</ol>';
html += '</ol>';

return html;
}
};

return html;
function shorten(title) {
return title.replace('Static Semantics:', 'SS:')
.replace('Runtime Semantics:', 'RS:');
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ecmarkup",
"version": "2.0.0-beta4",
"version": "2.0.0-beta5",
"description": "Custom element definitions and core utilities for markup that specifies ECMAScript and related technologies.",
"main": "lib/ecmarkup.js",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions spec/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!doctype html>
<meta charset="utf8">
<title>Ecmarkup</title>
<script src="ecmarkup.js"></script>
<link rel="stylesheet" href="elements.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/solarized_light.min.css">
<pre class=metadata>
Expand Down
4 changes: 2 additions & 2 deletions test/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const Promise = require('bluebird');

const build = require('../lib/ecmarkup').build;

const doc = '<!doctype html><emu-clause><h1>hi</h1></emu-clause>';
const out = '<!doctype html>\n<head></head><body><div><h2>Table of Contents</h2><ol class="toc"><li><a href="#"><span class="secnum">1</span> hi</a></li></ol></div><emu-clause><h1><span class="secnum">1</span>hi<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1></emu-clause></body>';
const doc = '<!doctype html><pre class=metadata>toc: false</pre><emu-clause><h1>hi</h1></emu-clause>';
const out = '<!doctype html>\n<head></head><body><emu-clause><h1><span class="secnum">1</span>hi<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1></emu-clause></body>';
function fetch(file) {
if (file.match(/\.json$/)) {
return '{}';
Expand Down
1 change: 1 addition & 0 deletions test/clauses.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<pre class=metadata>oldToc: true</pre>
<emu-intro>
<h1>Intro</h1>
<emu-intro>
Expand Down
3 changes: 2 additions & 1 deletion test/clauses.html.baseline
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!doctype html>
<head></head><body><div><h2>Table of Contents</h2><ol class="toc"><li><a href="#"><span class="secnum"></span> Intro</a><ol class="toc"><li><a href="#"><span class="secnum"></span> Sub Intro</a></li></ol></li><li><a href="#"><span class="secnum">1</span> Clause Foo(<var>a</var>, <var>b</var>)</a><ol class="toc"><li><a href="#Foo"><span class="secnum">1.1</span> Sub Clause</a></li></ol></li><li><a href="#"><span class="secnum">A</span> Annex</a><ol class="toc"><li><a href="#"><span class="secnum">A.1</span> Sub-annex</a></li></ol></li></ol></div><emu-intro>
<head></head><body class=" oldtoc">
<div><h2>Table of Contents</h2><ol class="toc"><li><a href="#" title="Intro"><span class="secnum"></span> Intro</a><ol class="toc"><li><a href="#" title="Sub Intro"><span class="secnum"></span> Sub Intro</a></li></ol></li><li><a href="#" title="Clause Foo(_a_, _b_)"><span class="secnum">1</span> Clause Foo(<var>a</var>, <var>b</var>)</a><ol class="toc"><li><a href="#Foo" title="Sub Clause"><span class="secnum">1.1</span> Sub Clause</a></li></ol></li><li><a href="#" title="Annex"><span class="secnum">A</span> Annex</a><ol class="toc"><li><a href="#" title="Sub-annex"><span class="secnum">A.1</span> Sub-annex</a></li></ol></li></ol></div><emu-intro>
<h1><span class="secnum"></span>Intro<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1>
<emu-intro>
<h1><span class="secnum"></span>Sub Intro<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1>
Expand Down
2 changes: 1 addition & 1 deletion test/test.html.baseline
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!doctype html>
<head><meta charset="utf-8">
<link rel="stylesheet" href="https://bterlson.github.com/ecmarkup/elements.css">
</head><body><div><h2>Table of Contents</h2><ol class="toc"><li><a href="#"><span class="secnum"></span> Intro</a><ol class="toc"><li><a href="#"><span class="secnum"></span> Sub Intro</a></li></ol></li><li><a href="#"><span class="secnum">1</span> Clause Foo(<var>a</var>, <var>b</var>)</a><ol class="toc"><li><a href="#Foo"><span class="secnum">1.1</span> Sub Clause</a></li><li><a href="#Bar"><span class="secnum">1.2</span> Sub Clause</a></li><li><a href="#Baz"><span class="secnum">1.3</span> Header</a><ol class="toc"><li><a href="#import3"><span class="secnum">1.3.1</span> Import 3</a></li></ol></li></ol></li><li><a href="#"><span class="secnum">A</span> Annex</a></li></ol></div><emu-intro>
</head><body><div id="menu-toggle">☰</div><div id="menu"><div id="menu-toc"><ol class="toc"><li><span class="item-toggle">◢</span><a href="#" title="Intro"><span class="secnum"></span> Intro</a><ol class="toc"><li><span class="item-toggle-none"></span><a href="#" title="Sub Intro"><span class="secnum"></span> Sub Intro</a></li></ol></li><li><span class="item-toggle">◢</span><a href="#" title="Clause Foo(_a_, _b_)"><span class="secnum">1</span> Clause Foo(<var>a</var>, <var>b</var>)</a><ol class="toc"><li><span class="item-toggle-none"></span><a href="#Foo" title="Sub Clause"><span class="secnum">1.1</span> Sub Clause</a></li><li><span class="item-toggle-none"></span><a href="#Bar" title="Sub Clause"><span class="secnum">1.2</span> Sub Clause</a></li><li><span class="item-toggle">◢</span><a href="#Baz" title="Header"><span class="secnum">1.3</span> Header</a><ol class="toc"><li><span class="item-toggle-none"></span><a href="#import3" title="Import 3"><span class="secnum">1.3.1</span> Import 3</a></li></ol></li></ol></li><li><span class="item-toggle-none"></span><a href="#" title="Annex"><span class="secnum">A</span> Annex</a></li></ol></div></div><emu-intro>
<h1><span class="secnum"></span>Intro<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1>
<emu-intro>
<h1><span class="secnum"></span>Sub Intro<span class="utils"><span class="anchor"><a href="#">#</a></span></span></h1>
Expand Down

0 comments on commit 2a32b40

Please sign in to comment.