Skip to content

Commit

Permalink
Tooltips now should look and behave the same for page titles and othe…
Browse files Browse the repository at this point in the history
…r links

Signed-off-by: Hofi <hofione@gmail.com>
  • Loading branch information
HofiOne committed May 10, 2024
1 parent f141f1e commit 9769c1a
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 52 deletions.
105 changes: 73 additions & 32 deletions _js/custom/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ $(function () {
var tocMenuElement = tocElement.querySelector('.toc__menu');
if (null == tocMenuElement || false == tocMenuElement.hasChildNodes)
shouldHide = true;
}
if (shouldHide) {
// TOC is autogenerated via 'include toc.html' so its size is not known prior the call of toc.html
// Signal emptiness, css will hide if needed based on it and config settings
// NOTE: Not hiding directly here to behave the same way like the left sidebar does
tocElement.classList.add('empty');
if (shouldHide) {
// TOC is autogenerated via 'include toc.html' so its size is not known prior the call of toc.html
// Signal emptiness, css will hide if needed based on it and config settings
// NOTE: Not hiding directly here to behave the same way like the left sidebar does
tocElement.classList.add('empty');
}
}
}

Expand Down Expand Up @@ -298,7 +298,7 @@ $(function () {
// Add anchors for headings
// -------------
function addPageAnchors() {
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!)
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!), eliminate it!
$('.page__content').find('h1, h2, h3, h4, h5, h6').each(function () {
var id = $(this).attr('id');
if (id) {
Expand All @@ -312,21 +312,37 @@ $(function () {
});
}

function alterPageForTooltip(content, fullPageContent) {
// To support page links even better if possible in case the page has no description / subtitle, but has some text
// right after the title and before the first heading is presented, it will be treated as the description and will be handled here.
// This part should also handle the case when only the title presented. (a.k.a. not showing the tooltip in that case),
// also responsible to create a uniform look and fell both for page title tooltips and other link tooltips.
//
function alterContentForTooltip(content, url, isFullPageContent) {
let tempContainer = document.createElement('div');
tempContainer.innerHTML = content;

if (fullPageContent)
hideTocIfNotNeeded(tempContainer, true);
hideTocIfNotNeeded(tempContainer, true);

// Remove/Override some default title style formatting to look better in the tooltip
const pageTitle = tempContainer.querySelector('#page-title');
if (pageTitle)
pageTitle.style.marginTop = '1em';

const pageSubtitle = tempContainer.querySelector('#page-subtitle');
if (pageSubtitle)
pageSubtitle.style.borderBottom = '0px';
var pageTitle = tempContainer.querySelector('#page-title');
if (pageTitle == null) {
// If there is no page title, replace the first heading with an item looks and behaves like the page title
// to have similar result both for page title tooltips and other link item tooltips
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!), eliminate it!
var firstHeading = tempContainer.querySelector("h2, h3, h4, h5, h6");
if (firstHeading) {
// Everything bellow must exist, so intentionally there's no error handling, let it rise
pageTitle = document.querySelector('#page-title').cloneNode(true);
pageTitle.id = firstHeading.id;

const anchorElement = pageTitle.querySelector("a");
anchorElement.textContent = firstHeading.textContent;
anchorElement.href = url;

tempContainer.replaceChild(pageTitle, firstHeading);
}
}
pageTitle.style.marginTop = '1em';

var newContent = tempContainer.innerHTML
// remove unnecessary, reqursive inner content tooltips
Expand All @@ -350,22 +366,37 @@ $(function () {
newContent => {
var startHeading = newContent.querySelector('#' + startHeadingId);
if (startHeading) {
var content = startHeading.outerHTML; // Include the starting <h> element itself
var content = '';
var heading = startHeading.outerHTML; // Include the starting <h> element itself
var nextSibling = startHeading.nextElementSibling;

// Collect all siblings until the next heading or the end of the document
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!)
// If handling a page title it will not have next sibling normally at all (we are removed and handling differently the description from the generated page)
// In that case the description is all the normal texts parts in the content, from the top (right bellow the title) to the first heading <h1-6>, try to get, it if there's any.
// If not presented, drop the whole content, return an empty one (a.k.a. do not show title only tooltips)
if (nextSibling == null && false == hasAnchor) {
startHeading = newContent.querySelector('.page__content');
nextSibling = startHeading.firstElementChild;
// First element is the TOC, skip it to be able to produce an empty content
if (nextSibling && nextSibling.classList.contains('sidebar__right'))
nextSibling = nextSibling.nextElementSibling;
}
// Collect all siblings until the next heading or the end of the initial content
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!), eliminate it!
while (nextSibling && nextSibling.tagName !== 'H1' && nextSibling.tagName !== 'H2' && nextSibling.tagName !== 'H3' && nextSibling.tagName !== 'H4' && nextSibling.tagName !== 'H5' && nextSibling.tagName !== 'H6') {
content += nextSibling.outerHTML;
nextSibling = nextSibling.nextElementSibling;
}

if (content.length != 0 || hasAnchor)
content = heading + content;

onSuccess(content);
}
else
console.error('Start heading not found by ID: ' + startHeadingId);
onError('Start heading not found by ID: ' + startHeadingId);
},
error => {
error(error);
onError(error);
}
);
}
Expand Down Expand Up @@ -402,10 +433,10 @@ $(function () {
tooltip.style.setProperty(posName, newPosition);
}

function showTooltip(event, tooltipText, fullPageContent) {
function showTooltip(event, tooltipText, isFullPageContent) {
tooltip.innerHTML = tooltipText.innerHTML;

if (fullPageContent)
if (isFullPageContent)
tooltip.classList.add("full-content-tooltip");
else
tooltip.classList.remove("full-content-tooltip");
Expand Down Expand Up @@ -470,7 +501,7 @@ $(function () {
element.appendChild(tooltipText);

element.addEventListener('mouseover', function (event) {
var fullPageContent = element.classList.contains('full-content-tooltip');
var isFullPageContent = element.classList.contains('full-content-tooltip');

tooltipTarget = element;

Expand All @@ -481,26 +512,36 @@ $(function () {
function onSuccess(newContent) {
if (typeof (newContent) === 'object' && 'innerHTML' in newContent)
newContent = newContent.innerHTML;
newContent = alterPageForTooltip(newContent, fullPageContent);

// cache for reuse
tooltipText.innerHTML = newContent;
showTooltip(event, tooltipText, fullPageContent);
newContent = alterContentForTooltip(newContent, url. isFullPageContent);

if (newContent.length > 0) {
// cache for reuse
tooltipText.innerHTML = newContent;
showTooltip(event, tooltipText, isFullPageContent);
}
else {
// Quick navigation from another link with tooltip to this link would keep alive the previous tooltip
// force close it, as we don't have tooltip for the current and this is the live hovered one.
hideTooltip(false);
}
}

function onError(error) {
// Quick navigation from another link with tooltip to this failing link would keep alive the previous tooltip
// force close it, as we don't have tooltip for the current and this is the live hovered one.
hideTooltip(false);
console.error('Error loading the tooltip content!' + error);
}

if (fullPageContent) {
if (isFullPageContent) {
loadContentFromUrl(url, newContent => onSuccess(newContent), error => onError(error));
}
else {
loadContentPartFrom(url, newContent => onSuccess(newContent), error => onError(error));
}
}
else
showTooltip(event, tooltipText, fullPageContent);
showTooltip(event, tooltipText, isFullPageContent);
});
});

Expand Down
61 changes: 41 additions & 20 deletions _js/main.min.js
Original file line number Diff line number Diff line change
Expand Up @@ -8466,9 +8466,9 @@ $(function() {
if (tocElement) {
var tocMenuElement = tocElement.querySelector(".toc__menu");
if (null == tocMenuElement || false == tocMenuElement.hasChildNodes) shouldHide = true;
}
if (shouldHide) {
tocElement.classList.add("empty");
if (shouldHide) {
tocElement.classList.add("empty");
}
}
}
function adjustSidebars() {
Expand Down Expand Up @@ -8635,14 +8635,23 @@ $(function() {
}
});
}
function alterPageForTooltip(content, fullPageContent) {
function alterContentForTooltip(content, url, isFullPageContent) {
let tempContainer = document.createElement("div");
tempContainer.innerHTML = content;
if (fullPageContent) hideTocIfNotNeeded(tempContainer, true);
const pageTitle = tempContainer.querySelector("#page-title");
if (pageTitle) pageTitle.style.marginTop = "1em";
const pageSubtitle = tempContainer.querySelector("#page-subtitle");
if (pageSubtitle) pageSubtitle.style.borderBottom = "0px";
hideTocIfNotNeeded(tempContainer, true);
var pageTitle = tempContainer.querySelector("#page-title");
if (pageTitle == null) {
var firstHeading = tempContainer.querySelector("h2, h3, h4, h5, h6");
if (firstHeading) {
pageTitle = document.querySelector("#page-title").cloneNode(true);
pageTitle.id = firstHeading.id;
const anchorElement = pageTitle.querySelector("a");
anchorElement.textContent = firstHeading.textContent;
anchorElement.href = url;
tempContainer.replaceChild(pageTitle, firstHeading);
}
}
pageTitle.style.marginTop = "1em";
var newContent = tempContainer.innerHTML;
newContent = newContent.replace(/\bcontent-tooltip\b/g, "");
return newContent;
Expand All @@ -8655,16 +8664,23 @@ $(function() {
loadContentFromUrl(url, newContent => {
var startHeading = newContent.querySelector("#" + startHeadingId);
if (startHeading) {
var content = startHeading.outerHTML;
var content = "";
var heading = startHeading.outerHTML;
var nextSibling = startHeading.nextElementSibling;
if (nextSibling == null && false == hasAnchor) {
startHeading = newContent.querySelector(".page__content");
nextSibling = startHeading.firstElementChild;
if (nextSibling && nextSibling.classList.contains("sidebar__right")) nextSibling = nextSibling.nextElementSibling;
}
while (nextSibling && nextSibling.tagName !== "H1" && nextSibling.tagName !== "H2" && nextSibling.tagName !== "H3" && nextSibling.tagName !== "H4" && nextSibling.tagName !== "H5" && nextSibling.tagName !== "H6") {
content += nextSibling.outerHTML;
nextSibling = nextSibling.nextElementSibling;
}
if (content.length != 0 || hasAnchor) content = heading + content;
onSuccess(content);
} else console.error("Start heading not found by ID: " + startHeadingId);
} else onError("Start heading not found by ID: " + startHeadingId);
}, error => {
error(error);
onError(error);
});
}
const toolTipArrowSize = 10;
Expand All @@ -8689,9 +8705,9 @@ $(function() {
var newPosition = position + "px";
tooltip.style.setProperty(posName, newPosition);
}
function showTooltip(event, tooltipText, fullPageContent) {
function showTooltip(event, tooltipText, isFullPageContent) {
tooltip.innerHTML = tooltipText.innerHTML;
if (fullPageContent) tooltip.classList.add("full-content-tooltip"); else tooltip.classList.remove("full-content-tooltip");
if (isFullPageContent) tooltip.classList.add("full-content-tooltip"); else tooltip.classList.remove("full-content-tooltip");
var tooltipPos = getTooltipPos(event, tooltipTarget);
var tooltipArrowLeftShift = 2 * toolTipArrowSize;
setArrowPosition("--tooltip-arrow-top", -1 * toolTipArrowSize);
Expand Down Expand Up @@ -8733,25 +8749,30 @@ $(function() {
tooltipText.textContent = "";
element.appendChild(tooltipText);
element.addEventListener("mouseover", function(event) {
var fullPageContent = element.classList.contains("full-content-tooltip");
var isFullPageContent = element.classList.contains("full-content-tooltip");
tooltipTarget = element;
if (tooltipText.innerHTML === "") {
var url = element.href;
function onSuccess(newContent) {
if (typeof newContent === "object" && "innerHTML" in newContent) newContent = newContent.innerHTML;
newContent = alterPageForTooltip(newContent, fullPageContent);
tooltipText.innerHTML = newContent;
showTooltip(event, tooltipText, fullPageContent);
newContent = alterContentForTooltip(newContent, url.isFullPageContent);
if (newContent.length > 0) {
tooltipText.innerHTML = newContent;
showTooltip(event, tooltipText, isFullPageContent);
} else {
hideTooltip(false);
}
}
function onError(error) {
hideTooltip(false);
console.error("Error loading the tooltip content!" + error);
}
if (fullPageContent) {
if (isFullPageContent) {
loadContentFromUrl(url, newContent => onSuccess(newContent), error => onError(error));
} else {
loadContentPartFrom(url, newContent => onSuccess(newContent), error => onError(error));
}
} else showTooltip(event, tooltipText, fullPageContent);
} else showTooltip(event, tooltipText, isFullPageContent);
});
});
document.addEventListener("mousemove", function(event) {
Expand Down

0 comments on commit 9769c1a

Please sign in to comment.