Skip to content

Commit

Permalink
Fix client js (dotnet#2665)
Browse files Browse the repository at this point in the history
* Fix tabbed content issue and siblings issue

* fix affix issue

* fix affix bug

* check null hierarchy

* clean up code
  • Loading branch information
vicancy authored Apr 23, 2018
1 parent 31de7cb commit ba8b920
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 117 deletions.
2 changes: 1 addition & 1 deletion src/docfx.website.themes/default/layout/_master.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<!--[if IE]><![endif]-->
<html>
{{>partials/head}}
<body data-spy="scroll" data-target="#affix">
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
{{^_disableNavbar}}
Expand Down
181 changes: 65 additions & 116 deletions src/docfx.website.themes/default/styles/docfx.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ $(function () {
renderAffix();
renderTabs();
}

// Add this event listener when needed
// window.addEventListener('content-update', contentUpdate);


function breakText() {
$(".xref").addClass("text-break");
var texts = $(".text-break");
Expand Down Expand Up @@ -537,36 +534,29 @@ $(function () {
//Setup Affix
function renderAffix() {
var hierarchy = getHierarchy();
if (hierarchy.length > 0) {
if (hierarchy && hierarchy.length > 0) {
var html = '<h5 class="title">In This Article</h5>'
html += util.formList(hierarchy, ['nav', 'bs-docs-sidenav']);
$("#affix").empty().append(html);
if ($('footer').is(':visible')) {
$(".sideaffix").css("bottom", "70px");
}
$('#affix').on('activate.bs.scrollspy', function (e) {
if (e.target) {
if ($(e.target).find('li.active').length > 0) {
return;
}
var top = $(e.target).position().top;
$(e.target).parents('li').each(function (i, e) {
top += $(e).position().top;
});
var container = $('#affix > ul');
var height = container.height();
container.scrollTop(container.scrollTop() + top - height / 2);
$('#affix a').click((e) => {
var scrollspy = $('[data-spy="scroll"]').data()['bs.scrollspy'];
var target = e.target.hash;
if (scrollspy && target){
scrollspy.activate(target);
}
})
});
}

function getHierarchy() {
// supported headers are h1, h2, h3, and h4
var $headers = $($.map(['h1', 'h2', 'h3', 'h4'], function(h) { return ".article article " + h; }).join(", "));
var $headers = $($.map(['h1', 'h2', 'h3', 'h4'], function (h) { return ".article article " + h; }).join(", "));

// a stack of hierarchy items that are currently being built
var stack = [];
$headers.each(function(i, e){
$headers.each(function (i, e) {
if (!e.id) {
return;
}
Expand Down Expand Up @@ -606,21 +596,23 @@ $(function () {
while (stack.length > 1) {
buildParent();
}

function buildParent() {
var childrenToAttach = stack.pop();
var parentFrame = stack[stack.length - 1];
var parent = parentFrame.siblings[parentFrame.siblings.length - 1];
$.each(childrenToAttach.siblings, function(i, child) {
$.each(childrenToAttach.siblings, function (i, child) {
parent.items.push(child);
});
}

var topLevel = stack.pop().siblings;
if (topLevel.length === 1) { // if there's only one topmost header, dump it
return topLevel[0].items;
if (stack.length > 0) {
var topLevel = stack.pop().siblings;
if (topLevel.length === 1) { // if there's only one topmost header, dump it
return topLevel[0].items;
}
return topLevel;
}
return topLevel;
return undefined;
}

function htmlEncode(str) {
Expand Down Expand Up @@ -739,8 +731,8 @@ $(function () {
this.a = a;
this.section = section;
}
Object.defineProperty(Tab.prototype, "tabIds", {
get: function () { return this.a.getAttribute('data-tab').split(' '); },
Object.defineProperty(Tab.prototype, "tabId", {
get: function () { return this.a.getAttribute('data-tab'); },
enumerable: true,
configurable: true
});
Expand Down Expand Up @@ -789,48 +781,39 @@ $(function () {
return Tab;
}());

initTabs(document.body);
initTabs();

function initTabs(container) {
function initTabs() {
var queryStringTabs = readTabsQueryStringParam();
var elements = container.querySelectorAll('.tabGroup');
var elements = document.querySelectorAll('.tabGroup');
var state = { groups: [], selectedTabs: [] };
for (var i = 0; i < elements.length; i++) {
var group = initTabGroup(elements.item(i));
if (!group.independent) {
updateVisibilityAndSelection(group, state);
state.groups.push(group);
}
initTabGroup(elements.item(i), state);
}
container.addEventListener('click', function (event) { return handleClick(event, state); });
if (state.groups.length === 0) {
return state;
}
selectTabs(queryStringTabs, container);
document.body.addEventListener('click', function (event) { return handleClick(event, state); });
selectTabs(queryStringTabs);
updateTabsQueryStringParam(state);
notifyContentUpdated();
return state;
}

function initTabGroup(element) {
var group = {
independent: element.hasAttribute('data-tab-group-independent'),
tabs: []
};
function initTabGroup(element, state) {
var group = { tabs: [] };
var li = element.firstElementChild.firstElementChild;
while (li) {
var a = li.firstElementChild;
a.setAttribute(contentAttrs.name, 'tab');
var dataTab = a.getAttribute('data-tab').replace(/\+/g, ' ');
a.setAttribute('data-tab', dataTab);
var section = element.querySelector("[id=\"" + a.getAttribute('aria-controls') + "\"]");
var section = document.getElementById(a.getAttribute('aria-controls'));
var tab = new Tab(li, a, section);
group.tabs.push(tab);
li = li.nextElementSibling;
}
updateVisibilityAndSelection(group, state);
element.setAttribute(contentAttrs.name, 'tab-group');
element.tabGroup = group;
return group;
state.groups.push(group);
}

function updateVisibilityAndSelection(group, state) {
Expand All @@ -844,40 +827,34 @@ $(function () {
firstVisibleTab = tab;
}
}
tab.selected = tab.visible && arraysIntersect(state.selectedTabs, tab.tabIds);
tab.selected = tab.visible && state.selectedTabs.indexOf(tab.tabId) !== -1;
anySelected = anySelected || tab.selected;
}
if (!anySelected) {
for (var _b = 0, _c = group.tabs; _b < _c.length; _b++) {
var tabIds = _c[_b].tabIds;
for (var _d = 0, tabIds_1 = tabIds; _d < tabIds_1.length; _d++) {
var tabId = tabIds_1[_d];
var index = state.selectedTabs.indexOf(tabId);
if (index === -1) {
continue;
}
state.selectedTabs.splice(index, 1);
var tab_1 = _c[_b];
var index = state.selectedTabs.indexOf(tab_1.tabId);
if (index === -1) {
continue;
}
state.selectedTabs.splice(index, 1);
}
firstVisibleTab.selected = true;
state.selectedTabs.push(tab.tabIds[0]);
var tab = firstVisibleTab;
tab.selected = true;
state.selectedTabs.push(tab.tabId);
}
}

function getTabInfoFromEvent(event) {
if (!(event.target instanceof HTMLElement)) {
if (!(event.target instanceof HTMLAnchorElement)) {
return null;
}
var anchor = event.target.closest('a[data-tab]');
if (anchor === null) {
var tabId = event.target.getAttribute('data-tab');
if (tabId === null) {
return null;
}
var tabIds = anchor.getAttribute('data-tab').split(' ');
var group = anchor.parentElement.parentElement.parentElement.tabGroup;
if (group === undefined) {
return null;
}
return { tabIds: tabIds, group: group, anchor: anchor };
var group = event.target.parentElement.parentElement.parentElement.tabGroup;
return { tabId: tabId, group: group, anchor: event.target };
}

function handleClick(event, state) {
Expand All @@ -886,29 +863,18 @@ $(function () {
return;
}
event.preventDefault();
info.anchor.href = 'javascript:';
setTimeout(function () { return info.anchor.href = '#' + info.anchor.getAttribute('aria-controls'); });
var tabIds = info.tabIds, group = info.group;
var originalTop = info.anchor.getBoundingClientRect().top;
if (group.independent) {
for (var _i = 0, _a = group.tabs; _i < _a.length; _i++) {
var tab = _a[_i];
tab.selected = arraysIntersect(tab.tabIds, tabIds);
}
var tabId = info.tabId, group = info.group;
if (state.selectedTabs.indexOf(tabId) !== -1) {
return;
}
else {
if (arraysIntersect(state.selectedTabs, tabIds)) {
return;
}
var previousTabId = group.tabs.filter(function (t) { return t.selected; })[0].tabIds[0];
state.selectedTabs.splice(state.selectedTabs.indexOf(previousTabId), 1, tabIds[0]);
for (var _b = 0, _c = state.groups; _b < _c.length; _b++) {
var group_1 = _c[_b];
updateVisibilityAndSelection(group_1, state);
}
updateTabsQueryStringParam(state);
var originalTop = info.anchor.getBoundingClientRect().top;
var previousTabId = group.tabs.filter(function (t) { return t.selected; })[0].tabId;
state.selectedTabs.splice(state.selectedTabs.indexOf(previousTabId), 1, tabId);
updateTabsQueryStringParam(state);
for (var _i = 0, _a = state.groups; _i < _a.length; _i++) {
var group_1 = _a[_i];
updateVisibilityAndSelection(group_1, state);
}
notifyContentUpdated();
var top = info.anchor.getBoundingClientRect().top;
if (top !== originalTop && event instanceof MouseEvent) {
window.scrollTo(0, window.pageYOffset + top - originalTop);
Expand All @@ -918,7 +884,7 @@ $(function () {
function selectTabs(tabIds) {
for (var _i = 0, tabIds_1 = tabIds; _i < tabIds_1.length; _i++) {
var tabId = tabIds_1[_i];
var a = document$1.querySelector(".tabGroup > ul > li > a[data-tab=\"" + tabId + "\"]:not([hidden])");
var a = document.querySelector(".tabGroup > ul > li > a[data-tab=\"" + tabId + "\"]:not([hidden])");
if (a === null) {
return;
}
Expand Down Expand Up @@ -970,24 +936,6 @@ $(function () {
}
return urlParams;
}

function arraysIntersect(a, b) {
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
var itemA = a_1[_i];
for (var _a = 0, b_1 = b; _a < b_1.length; _a++) {
var itemB = b_1[_a];
if (itemA === itemB) {
return true;
}
}
}
return false;
}

function notifyContentUpdated() {
// Dispatch this event when needed
// window.dispatchEvent(new CustomEvent('content-update'));
}
}

function utility() {
Expand Down Expand Up @@ -1083,7 +1031,7 @@ $(function () {
function getFixedOffset() {
return $('header').first().height();
}

/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
Expand All @@ -1093,26 +1041,26 @@ $(function () {
function scrollIfAnchor(href, pushToHistory) {
var match, rect, anchorOffset;

if(!ANCHOR_REGEX.test(href)) {
if (!ANCHOR_REGEX.test(href)) {
return false;
}

match = document.getElementById(href.slice(1));

if(match) {
if (match) {
rect = match.getBoundingClientRect();
anchorOffset = window.pageYOffset + rect.top - getFixedOffset();
window.scrollTo(window.pageXOffset, anchorOffset);

// Add the state to history as-per normal anchor links
if(HISTORY_SUPPORT && pushToHistory) {
if (HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href);
}
}

return !!match;
}

/**
* Attempt to scroll to the current location's hash.
*/
Expand All @@ -1126,13 +1074,14 @@ $(function () {
function delegateAnchors(e) {
var elem = e.target;

if(scrollIfAnchor(elem.getAttribute('href'), true)) {
if (scrollIfAnchor(elem.getAttribute('href'), true)) {
e.preventDefault();
}
}

$(window).on('hashchange', scrollToCurrent);
$(document.body).click('a', delegateAnchors);
// Exclude tabbed content case
$('a:not([data-tab])').click(delegateAnchors);
scrollToCurrent();
}
});

0 comments on commit ba8b920

Please sign in to comment.