arrow-admin
Version:
Arrow Admin Website
236 lines (209 loc) • 7.14 kB
JavaScript
define(['jquery'], function ($) {
var container,
headings,
selectedHeading;
var _singlePageMode,
_menu;
$('body').on('contentloaded', function () {
var currentPage = window.location.pathname.split('/').pop().split('.html')[0].toLowerCase();
var $body = $('body');
if (currentPage in { build: 1, logs: 1, registry: 1 }) {
$body.removeClass('has-nav-secondary');
}
else {
$body.addClass('has-nav-secondary');
}
$body
.removeClass('body-' + ($body.data('page') || ''))
.addClass('body-' + currentPage)
.data('page', currentPage);
container = $('#page-container');
headings = container.find('h1,h2');
switch (currentPage) {
case 'index':
buildIndexMenu();
break;
case 'docs':
$.get('docs/menu.json', transformDocsMenu);
break;
case 'cms':
// Note: For CMS, we load the data inside cms.js, and then call in to here to render the menu.
break;
}
});
/*
Page specific logic.
*/
function buildIndexMenu() {
var menu = [],
lastMenu;
var headers = $('#page-container').find('h1,h2');
for (var i = 0; i < headers.length; i++) {
var header = $(headers[i]),
id = header.attr('id'),
text = header.text();
if (header.is('h1')) {
menu.push(lastMenu = { title: text, url: id, pages: [] });
}
else {
lastMenu.pages.push({ title: text, url: id });
}
}
renderMenu(true, menu);
}
function transformDocsMenu(menu) {
// if in "apidoc only" mode, just show first 2 menus (Overview and APIs)
if (typeof APIDocOnly !== 'undefined') {
menu = menu.slice(0, 2);
}
var headers = $('#page-container').find('h2'),
currentPage = window.location.search.slice(6, -5),
activeMenu = menu[1],
activePage = activeMenu.pages.filter(function (page) {
return currentPage === page.url;
})[0];
if (activePage) {
activePage.pages = [];
for (var i = 0; i < headers.length; i++) {
var header = headers[i],
text = header.innerText,
link = $(header).children('a').attr('name');
activePage.pages.push({
url: '#' + link,
title: text.replace('/api/', '')
});
}
}
renderMenu(false, menu);
$('.tocify-subitem').click(function(evt) {
evt.preventDefault();
scrollTo($(this).attr('for').slice(1));
return false;
});
}
function syncScroll() {
var scrollTop = container.scrollTop(),
heading = findClosestHeading(scrollTop);
if (!selectedHeading && !heading.length) {
heading = $(headings[0]);
}
if (selectedHeading !== heading[0]) {
selectedHeading = heading[0];
$('nav .tocify-item.tocify-focus').removeClass('tocify-focus');
var tocifyItem = $('nav .tocify-item[for="#' + heading.attr('id') + '"]');
tocifyItem.addClass('tocify-focus');
$('.tocify-header-collapsee').addClass('off').removeClass('on');
var sectionHeading = heading.is('h2') ? tocifyItem.parent().prev() : tocifyItem.parent(),
sectionItems = sectionHeading.next();
sectionHeading.find('.tocify-item').addClass('tocify-focus');
if (sectionHeading.is('.tocify-header-collapser')) {
sectionItems.addClass('on').removeClass('off');
}
}
}
function findClosestHeading(scrollTop) {
var minIndex = 0,
maxIndex = headings.length - 1;
var currentIndex,
closestElement = $(headings[0]),
currentElement,
elementTop;
while (minIndex <= maxIndex) {
currentIndex = (minIndex + maxIndex) / 2 | 0;
currentElement = $(headings[currentIndex]);
elementTop = currentElement.offset().top - currentElement.parent().offset().top;
if (elementTop < scrollTop) {
closestElement = currentElement;
minIndex = currentIndex + 1;
}
else if (elementTop > scrollTop) {
maxIndex = currentIndex - 1;
}
else {
return currentElement;
}
}
return closestElement;
}
/*
Generic menu rendering logic.
*/
function reRenderMenu() {
if (_singlePageMode !== undefined) {
return renderMenu(_singlePageMode, _menu);
}
}
/**
* Renders a menu based on the provided args.
* @param singlePageMode Whether or not we will be scrolling to the items, as opposed to linking to them.
* @param menu
*/
function renderMenu(singlePageMode, menu) {
_singlePageMode = singlePageMode;
_menu = menu;
var htmlPage = window.location.pathname.split('/').pop().split('.html')[0].toLowerCase(),
currentPage = (singlePageMode ? window.location.hash : window.location.search).substr(1);
menu = menu.filter(function (section) {
return htmlPage !== 'docs' || section.pages.length > 0;
});
$('nav .tocify-wrapper')
.html(menu.map(function mapMenuSection(section, index) {
var sectionURL = section.url || '',
hasChildren = section.pages && section.pages.length,
sectionLink = (hasChildren && sectionURL) ? sectionURL + '/' + section.pages[0].url + '.html' : sectionURL,
sectionActive = singlePageMode ? false : (currentPage === sectionURL || (sectionURL && currentPage.indexOf(sectionURL + '/') >= 0)) || (!sectionURL && currentPage.indexOf('/') === -1),
sectionHREF = singlePageMode ? '#' + section.url : (htmlPage + '.html?' + sectionLink),
classes = 'tocify-header tocify-header-start-' + index + ' tocify-header-end-' + (menu.length - index - 1) + '' + (hasChildren ? ' tocify-header-collapser' : ''),
html = [
'<ul class="' + classes + '">',
'<li class="tocify-item' + (sectionActive ? ' tocify-focus' : '') + '" for="' + sectionHREF + '">',
'<a href="' + sectionHREF + '">' + section.title + '</a>',
'</li>',
'</ul>'
];
if (hasChildren) {
html.push('<ul class="tocify-subheader' + (hasChildren ? ' tocify-header-collapsee' : '') + ' ' + (sectionActive ? 'on' : 'off') + '">');
for (var i = 0; i < section.pages.length; i++) {
var page = section.pages[i],
isIntro = page.url === 'introduction',
prefix = section.url ? section.url + '/' : '',
pageLink = isIntro ? '' : (prefix + page.url + '.html'),
pageActive = currentPage === pageLink,
pageHREF = singlePageMode ? '#' + page.url : (htmlPage + '.html?' + pageLink);
html = html.concat([
'<li class="tocify-item' + (pageActive ? ' tocify-focus' : '') + '" for="' + pageHREF + '">',
'<a href="' + pageHREF + '">' + page.title + '</a>',
'</li>'
]);
if (page.pages) {
html = html.concat(page.pages.map(function(subPage) {
return '<li class="tocify-subitem" for="' + subPage.url + '">' +
'<a href="' + subPage.url + '">' + subPage.title + '</a>' +
'</li>';
}));
}
}
html.push('</ul>');
}
return html.join('');
}).join(''));
if (singlePageMode) {
container.scroll(syncScroll);
setTimeout(syncScroll, 0);
}
if (window.location.hash) {
setTimeout(function() {
scrollTo(window.location.hash.slice(1));
}, 100);
}
}
function scrollTo(name) {
var pageContainer = $('#page-container'),
target = $('a[name="' + name + '"]');
pageContainer.scrollTop(pageContainer.scrollTop() + target.offset().top - 45);
}
return {
renderMenu: renderMenu,
reRenderMenu: reRenderMenu
};
});