Load api navigation dynamically to reduce needed disk space

This commit is contained in:
Maximilian Krög
2020-09-18 21:20:53 +02:00
parent 1f761d943f
commit 14c5e9a7e8
6 changed files with 116 additions and 64 deletions

View File

@@ -500,6 +500,7 @@ exports.publish = function (taffyData, opts, tutorials) {
// once for all // once for all
view.nav = buildNav(members); view.nav = buildNav(members);
attachModuleSymbols( attachModuleSymbols(
find({kind: ['class', 'function'], longname: {left: 'module:'}}), find({kind: ['class', 'function'], longname: {left: 'module:'}}),
members.modules members.modules
@@ -518,7 +519,16 @@ exports.publish = function (taffyData, opts, tutorials) {
// index page displays information from package.json and lists files // index page displays information from package.json and lists files
const files = find({kind: 'file'}); const files = find({kind: 'file'});
view.navigationHtml = helper.resolveLinks(view.partial('navigation.tmpl')); view.navigationItems = view.nav.reduce(function (dict, item) {
dict[item.longname] = item;
return dict;
}, {});
const navigationHtml = helper.resolveLinks(
view.nav.map((item) => view.partial('navigation.tmpl', {item})).join('')
);
const navHtmlPath = path.join(outdir, 'navigation.tmpl.html');
fs.writeFileSync(navHtmlPath, navigationHtml, 'utf8');
generate( generate(
'Index', 'Index',
[ [

View File

@@ -62,21 +62,47 @@ $(function () {
$navList.addClass('search-empty'); $navList.addClass('search-empty');
return 'search-empty'; return 'search-empty';
})(); })();
let initialCurrent = navListNode.querySelector('li.item');
const longname = initialCurrent && initialCurrent.dataset.longname;
let manualToggles = {}; let manualToggles = {};
if (initialCurrent) {
// Show an item related a current documentation automatically manualToggles[longname] = $(initialCurrent);
const longname = $('.page-title').data('filename')
.replace(/\.[a-z]+$/, '')
.replace('module-', 'module:')
.replace(/_/g, '/')
.replace(/-/g, '~');
const currentItem = navListNode.querySelector('.item[data-longname="' + longname + '"]');
if (currentItem) {
$navList.prepend(currentItem);
} }
fetch('./navigation.tmpl.html').then(function (response) {
return response.text();
}).then(function (text) {
navListNode.innerHTML = text;
// Show an item related a current documentation automatically
const currentItem = navListNode.querySelector('.item[data-longname="' + longname + '"]');
if (currentItem) {
$navList.prepend(currentItem);
search.$currentItem = $(currentItem);
}
$classItems = undefined;
$members = undefined;
// Search again with full navigation, if user already searched
manualToggles = {};
const lastTerm = search.lastSearchTerm;
search.lastSearchTerm = undefined;
const fa = currentItem.querySelector('.title > .fa');
fa.classList.add('no-transition');
doSearch(lastTerm || '');
// Transfer manual toggle state to newly loaded current node
if (initialCurrent && initialCurrent.classList.contains('toggle-manual')) {
search.manualToggle(search.$currentItem, initialCurrent.classList.contains('toggle-manual-show'));
}
setTimeout(function () {
fa.classList.remove('no-transition');
}, 0);
});
return { return {
$navList: $navList, $navList: $navList,
$currentItem: currentItem ? $(currentItem) : undefined, $currentItem: initialCurrent ? $(initialCurrent) : undefined,
lastSearchTerm: undefined, lastSearchTerm: undefined,
lastState: {}, lastState: {},
lastClasses: undefined, lastClasses: undefined,
@@ -240,7 +266,7 @@ $(function () {
// Toggle when click an item element // Toggle when click an item element
search.$navList.on('click', '.toggle', function (e) { search.$navList.on('click', '.toggle', function (e) {
if (event.target.tagName.toLowerCase() === 'a') { if (e.target.tagName === 'A') {
return; return;
} }
const clsItem = $(this).closest('.item'); const clsItem = $(this).closest('.item');

View File

@@ -5,6 +5,7 @@
.navbar-brand img { .navbar-brand img {
height: 35px; height: 35px;
width: 35px;
vertical-align: middle; vertical-align: middle;
margin-right: 5px; margin-right: 5px;
display: inline-block; display: inline-block;
@@ -71,6 +72,11 @@ li {
.navigation-list { .navigation-list {
padding: 0 15px 0 15px; padding: 0 15px 0 15px;
} }
.no-transition,
.no-transition:after,
.no-transition:before {
transition: none!important;
}
@supports (position: sticky) { @supports (position: sticky) {
.navigation { .navigation {
position: sticky; position: sticky;
@@ -78,7 +84,7 @@ li {
height: calc(100vh - 54px); height: calc(100vh - 54px);
} }
.navigation-list { .navigation-list {
overflow: auto; overflow-y: auto;
/* 54px navbar height */ /* 54px navbar height */
/* 4.25rem + 2px searchbox height */ /* 4.25rem + 2px searchbox height */
/* 25px navigation padding */ /* 25px navigation padding */
@@ -94,7 +100,7 @@ li {
position: inherit; position: inherit;
} }
.navigation-list { .navigation-list {
overflow: auto; overflow-y: auto;
max-height: 33vh; max-height: 33vh;
height: inherit; height: inherit;
} }
@@ -206,6 +212,10 @@ li {
padding-left: 8px; padding-left: 8px;
} }
.navigation-list li.loading {
display: block;
height: 101vh;
}
/* search state */ /* search state */
/* show all classes when search is empty */ /* show all classes when search is empty */
.navigation-list.search-empty .item { .navigation-list.search-empty .item {

View File

@@ -29,7 +29,7 @@ var version = obj.packageInfo.version;
gtag('js', new Date()); gtag('js', new Date());
gtag('config', 'UA-2577926-1', { 'anonymize_ip': true }); gtag('config', 'UA-2577926-1', { 'anonymize_ip': true });
</script> </script>
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css" /> <link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js"></script>
<script> <script>
window.addEventListener("load", function() { window.addEventListener("load", function() {
@@ -64,14 +64,14 @@ var version = obj.packageInfo.version;
</script> </script>
<title>OpenLayers v<?js= version ?> API - <?js= title ?></title> <title>OpenLayers v<?js= version ?> API - <?js= title ?></title>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script>
<script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"> </script> <script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"> </script> <script src="scripts/jquery.min.js"></script>
<script src="scripts/bootstrap.bundle.min.js"> </script> <script src="scripts/bootstrap.bundle.min.js"></script>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]--> <![endif]-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css"> <link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css"> <link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/jaguar.css"> <link type="text/css" rel="stylesheet" href="styles/jaguar.css">
@@ -115,15 +115,35 @@ var version = obj.packageInfo.version;
</nav> </nav>
</header> </header>
<div id="wrap" class="row"> <div id="wrap" class="row">
<?js= this.navigationHtml ?> <div class="navigation col-md-4 col-lg-3">
<div class="main col-md-8 col-lg-9"> <div class="search-wrapper">
<h1 class="page-title" data-filename="<?js= filename ?>"><?js= title ?></h1> <div class="search">
<div id="latest-check" class="alert alert-warning alert-dismissible" role="alert" style="display:none"> <input id="search" type="text" autocomplete="off" class="form-control input-sm" placeholder="Search Documentation">
<button id="latest-dismiss" type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button> </div>
This documentation is for OpenLayers v<span id="package-version"><?js= version ?></span>. The <a id="latest-link" href="#" class="alert-link">latest</a> is v<span id="latest-version"></span>.
</div>
<?js= content ?>
</div> </div>
<div class="navigation-list-wrapper">
<ul class="navigation-list search-empty"><?js
const item = this.navigationItems[docs[0].longname];
const listItem = item
? this.partial('navigation.tmpl', {
item: item,
classes: ' toggle-manual toggle-manual-show',
})
: '';
?><?js= listItem ?>
<li class="loading">Loading …
</ul>
</div>
</div>
<div class="main col-md-8 col-lg-9">
<h1 class="page-title" data-filename="<?js= filename ?>"><?js= title ?></h1>
<div id="latest-check" class="alert alert-warning alert-dismissible" role="alert" style="display:none">
<button id="latest-dismiss" type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
This documentation is for OpenLayers v<span id="package-version"><?js= version ?></span>. The <a id="latest-link" href="#" class="alert-link">latest</a> is v<span id="latest-version"></span>.
</div>
<?js= content ?>
</div>
</div> </div>
<script>prettyPrint();</script> <script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script> <script src="scripts/linenumber.js"></script>

View File

@@ -16,12 +16,12 @@ function getItemCssClass(type) {
const printListItem = (member) => { const printListItem = (member) => {
const shortName = toShortName(member.name); ?> const shortName = toShortName(member.name); ?>
<li data-name="<?js= shortName.toLowerCase() ?>"><?js= self.linkto(member.longname, shortName) ?><?js <li data-name="<?js= shortName.toLowerCase() ?>"><?js= self.linkto(member.longname, shortName) ?><?js
}; };
const printListItemWithStability = (member) => { const printListItemWithStability = (member) => {
const shortName = toShortName(member.name); const shortName = toShortName(member.name);
const cls = member.stability && member.stability !== 'stable' ? ' class="unstable"' : ''; ?> const cls = member.stability && member.stability !== 'stable' ? ' class="unstable"' : ''; ?>
<li data-name="<?js= shortName.toLowerCase() ?>"<?js= cls ?>><?js= self.linkto(member.longname, shortName) ?><?js <li data-name="<?js= shortName.toLowerCase() ?>"<?js= cls ?>><?js= self.linkto(member.longname, shortName) ?><?js
}; };
const printFiresListItem = (eventName) => { const printFiresListItem = (eventName) => {
const ancestor = self.find({longname: eventName})[0] || const ancestor = self.find({longname: eventName})[0] ||
@@ -32,43 +32,28 @@ const printFiresListItem = (eventName) => {
} else { } else {
const cls = ancestor.stability && ancestor.stability !== 'stable' ? ' class="unstable"' : ''; const cls = ancestor.stability && ancestor.stability !== 'stable' ? ' class="unstable"' : '';
const shortName = toShortName(ancestor.name); ?> const shortName = toShortName(ancestor.name); ?>
<li data-name="<?js= shortName.toLowerCase() ?>"<?js= cls ?>><?js= shortName ?><?js <li data-name="<?js= shortName.toLowerCase() ?>"<?js= cls ?>><?js= shortName ?><?js
} }
}; };
function listContent(item, title, listItemPrinter) { function listContent(item, title, listItemPrinter) {
const type = title.toLowerCase(); const type = title.toLowerCase();
if (item[type] && item[type].length) { ?> if (item[type] && item[type].length) { ?>
<div class="member-list" data-type="<?js= type ?>"> <div class="member-list" data-type="<?js= type ?>">
<span class="subtitle"><?js= title ?></span> <span class="subtitle"><?js= title ?></span>
<ul><?js <ul><?js
item[type].forEach(function (v) { item[type].forEach((v) => listItemPrinter(v)); ?>
listItemPrinter(v);
}); ?>
</ul>
</div><?js
}
}
?>
<div class="navigation col-md-4 col-lg-3">
<div class="search-wrapper">
<div class="search">
<input id="search" type="text" autocomplete="off" class="form-control input-sm" placeholder="Search Documentation">
</div>
</div>
<div class="navigation-list-wrapper">
<ul class="navigation-list search-empty"><?js
this.nav.forEach(function (item) { ?>
<li class="item item-<?js= item.type ?>" data-longname="<?js= item.longname ?>" data-name="<?js= item.prettyname.toLowerCase() ?>">
<span class="title toggle">
<span class="fa <?js= getItemCssClass(item.type) ?> mr-2 mt-1"></span>
<span><?js= self.linkto(item.longname, item.prettyname.replace(/[.~\/]/g, '\u200b$&')) ?></span>
</span><?js
listContent(item, 'Members', printListItem);
listContent(item, 'Typedefs', printListItemWithStability);
listContent(item, 'Methods', printListItemWithStability);
listContent(item, 'Fires', printFiresListItem);
}); ?>
</ul> </ul>
</div> </div><?js
</div> }
} ?>
<li class="item item-<?js= item.type ?><?js= obj.classes || '' ?>" data-longname="<?js= item.longname ?>" data-name="<?js= item.prettyname.toLowerCase() ?>">
<span class="title toggle">
<span class="fa <?js= getItemCssClass(item.type) ?> mr-2 mt-1"></span>
<span><?js= self.linkto(item.longname, item.prettyname.replace(/[.~\/]/g, '\u200b$&')) ?></span>
</span><?js
listContent(item, 'Members', printListItem);
listContent(item, 'Typedefs', printListItemWithStability);
listContent(item, 'Methods', printListItemWithStability);
listContent(item, 'Fires', printFiresListItem);
?>

View File

@@ -22,6 +22,7 @@ body {
} }
.navbar-brand img { .navbar-brand img {
height: 35px; height: 35px;
width: 35px;;
vertical-align: middle; vertical-align: middle;
margin-right: 5px; margin-right: 5px;
display: inline-block; display: inline-block;