Skip to content

Commit

Permalink
added toc dropup
Browse files Browse the repository at this point in the history
  • Loading branch information
heropj committed Feb 7, 2025
1 parent 47db0e7 commit 60cb320
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
19 changes: 19 additions & 0 deletions www/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,25 @@ iframe._invert, iframe._mwInvert {
font-weight: bold;
}

.btn-group.btn-block {
padding-left: 5%;
}

.dropdown-menu.flex-container {
overflow-y:auto;
padding: 2px 4px;
position: absolute;
margin: 0 !important;
}

#ToCList{
line-height: 1.7;
}

#ToCList a {
display: block;
}

.container {
margin-bottom: 1.5em;
}
Expand Down
7 changes: 7 additions & 0 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,13 @@ <h3 data-i18n="configure-expert-settings-title">Expert settings</h3>
</div>
</div>
<div id="navigationButtons" class="btn-group btn-block">
<div class="dropup">
<button class="btn btn-lg dropdown-toggle col-xs-4" id="dropup" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true" style="font-size: 14px; padding-top: 12px;">
<i class="fas fa-list-alt fa-lg"></i>
</button>
<ul id="ToCList" class="dropdown-menu flex-container"></ul>
</div>
<a href="#" data-i18n-tip="home" class="btn btn-lg" id="btnHomeBottom" title="Home"><i class="fas fa-home"></i></a>
<a href="#" class="btn btn-lg" data-i18n-tip="home-btn-back" id="btnBack" title="Back"><i class="fas fa-arrow-left"></i></a>
<a href="#" class="btn btn-lg" data-i18n-tip="home-btn-forward" id="btnForward" title="Forward"><i class="fas fa-arrow-right"></i></a>
Expand Down
61 changes: 61 additions & 0 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3228,6 +3228,67 @@ function pushBrowserHistoryState (title, titleSearch) {
window.history.pushState(stateObj, stateLabel, urlParameters);
}

// Setup table of contents and display the list when the dropup button is clicked
var dropup = document.getElementById('dropup');
dropup.setAttribute('tabindex', '0');
var ToCList = document.getElementById('ToCList');

dropup.addEventListener('click', function () {
const isVisible = getComputedStyle(ToCList).display !== 'none';
if (isVisible) {
ToCList.style.display = 'none';
} else {
setupTableOfContents();
ToCList.style.display = 'flex';
ToCList.style.flexDirection = 'column';
}
});

dropup.addEventListener('blur', function () {
if (!ToCList.matches(':hover')) { // If mouse is on TOC, don't hide it..why? so that 'click' event on links can be triggered properly
ToCList.style.display = 'none';
}
});

// Inject table of contents list into dropup element and scroll selection into view
function setupTableOfContents () {
var iframe = document.getElementById('articleContent');
var innerDoc = iframe.contentDocument;
var tableOfContents = new uiUtil.TOC(innerDoc);
var headings = tableOfContents.getHeadingObjects();

var dropupHtml = '';
headings.forEach(function (heading) {
if (/^h1$/i.test(heading.tagName)) {
dropupHtml += '<li style="font-size:' + 18 + 'px;"><a style="color: black;" href="#" data-heading-id="' + heading.id + '">' + heading.textContent + '</a></li>';
} else if (/^h2$/i.test(heading.tagName)) {
dropupHtml += '<li style="margin-top:6px;margin-left:6px;font-size:' + 16 + 'px;"><a style="color: black;" href="#" data-heading-id="' + heading.id + '">' + heading.textContent + '</a></li>';
} else if (/^h3$/i.test(heading.tagName)) {
dropupHtml += '<li style="margin-left:12px;font-weight:350;font-size:' + 14 + 'px;"><a style="color: black;" href="#" data-heading-id="' + heading.id + '">' + heading.textContent + '</a></li>';
} else if (/^h4$/i.test(heading.tagName)) {
dropupHtml += '<li style="margin-left:16px;font-weight:300;font-size:' + 12 + 'px;"><a style="color: black;" href="#" data-heading-id="' + heading.id + '">' + heading.textContent + '</a></li>';
}
// Skip smaller headings (if there are any) to avoid making list too long
});
var ToCList = document.getElementById('ToCList');
ToCList.style.maxHeight = ~~(window.innerHeight * 0.75) + 'px';
ToCList.innerHTML = dropupHtml;
Array.from(ToCList.getElementsByTagName('a'))
.forEach(function (listElement) {
listElement.addEventListener('click', function () {
var sectionEle = innerDoc.getElementById(this.dataset.headingId);
sectionEle.scrollIntoView();
// Scrolling up then down ensures that the toolbars show according to user settings
iframe.contentWindow.scrollBy(0, -5);
setTimeout(function () {
iframe.contentWindow.scrollBy(0, 5);
iframe.contentWindow.focus();
}, 150);
ToCList.style.display = 'none';
});
});
}

/**
* Extracts the content of the given article pathname, or a downloadable file, from the ZIM
*
Expand Down
27 changes: 27 additions & 0 deletions www/js/lib/uiUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,32 @@ function slideAway (e) {
}
}

/*
* Returns a list of headings from an article
* @param {String} the page for which table of cotents needs to be listed
* @returns {List} a list of all headings as objects
*/
function TableOfContents (articleDoc) {
this.doc = articleDoc;
this.headings = this.doc.querySelectorAll('h1, h2, h3, h4, h5, h6');

this.getHeadingObjects = function () {
var headings = [];
for (var i = 0; i < this.headings.length; i++) {
var element = this.headings[i];
var obj = {};
obj.id = element.id;
var objectId = element.innerHTML.match(/\bid\s*=\s*["']\s*([^"']+?)\s*["']/i);
obj.id = obj.id ? obj.id : objectId && objectId.length > 1 ? objectId[1] : '';
obj.index = i;
obj.textContent = element.textContent;
obj.tagName = element.tagName;
headings.push(obj);
}
return headings;
};
}

/**
* Displays a Bootstrap alert or confirm dialog box depending on the options provided
*
Expand Down Expand Up @@ -1083,6 +1109,7 @@ export default {
determineCanvasElementsWorkaround: determineCanvasElementsWorkaround,
replaceCSSLinkWithInlineCSS: replaceCSSLinkWithInlineCSS,
deriveZimUrlFromRelativeUrl: deriveZimUrlFromRelativeUrl,
TOC: TableOfContents,
removeUrlParameters: removeUrlParameters,
displayActiveContentWarning: displayActiveContentWarning,
displayFileDownloadAlert: displayFileDownloadAlert,
Expand Down

0 comments on commit 60cb320

Please # to comment.