Skip to content

Commit 9769c1a

Browse files
committed
Tooltips now should look and behave the same for page titles and other links
Signed-off-by: Hofi <[email protected]>
1 parent f141f1e commit 9769c1a

File tree

2 files changed

+114
-52
lines changed

2 files changed

+114
-52
lines changed

_js/custom/navigation.js

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ $(function () {
2424
var tocMenuElement = tocElement.querySelector('.toc__menu');
2525
if (null == tocMenuElement || false == tocMenuElement.hasChildNodes)
2626
shouldHide = true;
27-
}
28-
if (shouldHide) {
29-
// TOC is autogenerated via 'include toc.html' so its size is not known prior the call of toc.html
30-
// Signal emptiness, css will hide if needed based on it and config settings
31-
// NOTE: Not hiding directly here to behave the same way like the left sidebar does
32-
tocElement.classList.add('empty');
27+
if (shouldHide) {
28+
// TOC is autogenerated via 'include toc.html' so its size is not known prior the call of toc.html
29+
// Signal emptiness, css will hide if needed based on it and config settings
30+
// NOTE: Not hiding directly here to behave the same way like the left sidebar does
31+
tocElement.classList.add('empty');
32+
}
3333
}
3434
}
3535

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

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

319-
if (fullPageContent)
320-
hideTocIfNotNeeded(tempContainer, true);
324+
hideTocIfNotNeeded(tempContainer, true);
321325

322326
// Remove/Override some default title style formatting to look better in the tooltip
323-
const pageTitle = tempContainer.querySelector('#page-title');
324-
if (pageTitle)
325-
pageTitle.style.marginTop = '1em';
326-
327-
const pageSubtitle = tempContainer.querySelector('#page-subtitle');
328-
if (pageSubtitle)
329-
pageSubtitle.style.borderBottom = '0px';
327+
var pageTitle = tempContainer.querySelector('#page-title');
328+
if (pageTitle == null) {
329+
// If there is no page title, replace the first heading with an item looks and behaves like the page title
330+
// to have similar result both for page title tooltips and other link item tooltips
331+
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!), eliminate it!
332+
var firstHeading = tempContainer.querySelector("h2, h3, h4, h5, h6");
333+
if (firstHeading) {
334+
// Everything bellow must exist, so intentionally there's no error handling, let it rise
335+
pageTitle = document.querySelector('#page-title').cloneNode(true);
336+
pageTitle.id = firstHeading.id;
337+
338+
const anchorElement = pageTitle.querySelector("a");
339+
anchorElement.textContent = firstHeading.textContent;
340+
anchorElement.href = url;
341+
342+
tempContainer.replaceChild(pageTitle, firstHeading);
343+
}
344+
}
345+
pageTitle.style.marginTop = '1em';
330346

331347
var newContent = tempContainer.innerHTML
332348
// remove unnecessary, reqursive inner content tooltips
@@ -350,22 +366,37 @@ $(function () {
350366
newContent => {
351367
var startHeading = newContent.querySelector('#' + startHeadingId);
352368
if (startHeading) {
353-
var content = startHeading.outerHTML; // Include the starting <h> element itself
369+
var content = '';
370+
var heading = startHeading.outerHTML; // Include the starting <h> element itself
354371
var nextSibling = startHeading.nextElementSibling;
355372

356-
// Collect all siblings until the next heading or the end of the document
357-
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!)
373+
// 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)
374+
// 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.
375+
// If not presented, drop the whole content, return an empty one (a.k.a. do not show title only tooltips)
376+
if (nextSibling == null && false == hasAnchor) {
377+
startHeading = newContent.querySelector('.page__content');
378+
nextSibling = startHeading.firstElementChild;
379+
// First element is the TOC, skip it to be able to produce an empty content
380+
if (nextSibling && nextSibling.classList.contains('sidebar__right'))
381+
nextSibling = nextSibling.nextElementSibling;
382+
}
383+
// Collect all siblings until the next heading or the end of the initial content
384+
// FIXME: This magic 6 must be maintained together now with generate_links.rb (and other places ?!), eliminate it!
358385
while (nextSibling && nextSibling.tagName !== 'H1' && nextSibling.tagName !== 'H2' && nextSibling.tagName !== 'H3' && nextSibling.tagName !== 'H4' && nextSibling.tagName !== 'H5' && nextSibling.tagName !== 'H6') {
359386
content += nextSibling.outerHTML;
360387
nextSibling = nextSibling.nextElementSibling;
361388
}
389+
390+
if (content.length != 0 || hasAnchor)
391+
content = heading + content;
392+
362393
onSuccess(content);
363394
}
364395
else
365-
console.error('Start heading not found by ID: ' + startHeadingId);
396+
onError('Start heading not found by ID: ' + startHeadingId);
366397
},
367398
error => {
368-
error(error);
399+
onError(error);
369400
}
370401
);
371402
}
@@ -402,10 +433,10 @@ $(function () {
402433
tooltip.style.setProperty(posName, newPosition);
403434
}
404435

405-
function showTooltip(event, tooltipText, fullPageContent) {
436+
function showTooltip(event, tooltipText, isFullPageContent) {
406437
tooltip.innerHTML = tooltipText.innerHTML;
407438

408-
if (fullPageContent)
439+
if (isFullPageContent)
409440
tooltip.classList.add("full-content-tooltip");
410441
else
411442
tooltip.classList.remove("full-content-tooltip");
@@ -470,7 +501,7 @@ $(function () {
470501
element.appendChild(tooltipText);
471502

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

475506
tooltipTarget = element;
476507

@@ -481,26 +512,36 @@ $(function () {
481512
function onSuccess(newContent) {
482513
if (typeof (newContent) === 'object' && 'innerHTML' in newContent)
483514
newContent = newContent.innerHTML;
484-
newContent = alterPageForTooltip(newContent, fullPageContent);
485-
486-
// cache for reuse
487-
tooltipText.innerHTML = newContent;
488-
showTooltip(event, tooltipText, fullPageContent);
515+
newContent = alterContentForTooltip(newContent, url. isFullPageContent);
516+
517+
if (newContent.length > 0) {
518+
// cache for reuse
519+
tooltipText.innerHTML = newContent;
520+
showTooltip(event, tooltipText, isFullPageContent);
521+
}
522+
else {
523+
// Quick navigation from another link with tooltip to this link would keep alive the previous tooltip
524+
// force close it, as we don't have tooltip for the current and this is the live hovered one.
525+
hideTooltip(false);
526+
}
489527
}
490528

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

495-
if (fullPageContent) {
536+
if (isFullPageContent) {
496537
loadContentFromUrl(url, newContent => onSuccess(newContent), error => onError(error));
497538
}
498539
else {
499540
loadContentPartFrom(url, newContent => onSuccess(newContent), error => onError(error));
500541
}
501542
}
502543
else
503-
showTooltip(event, tooltipText, fullPageContent);
544+
showTooltip(event, tooltipText, isFullPageContent);
504545
});
505546
});
506547

_js/main.min.js

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8466,9 +8466,9 @@ $(function() {
84668466
if (tocElement) {
84678467
var tocMenuElement = tocElement.querySelector(".toc__menu");
84688468
if (null == tocMenuElement || false == tocMenuElement.hasChildNodes) shouldHide = true;
8469-
}
8470-
if (shouldHide) {
8471-
tocElement.classList.add("empty");
8469+
if (shouldHide) {
8470+
tocElement.classList.add("empty");
8471+
}
84728472
}
84738473
}
84748474
function adjustSidebars() {
@@ -8635,14 +8635,23 @@ $(function() {
86358635
}
86368636
});
86378637
}
8638-
function alterPageForTooltip(content, fullPageContent) {
8638+
function alterContentForTooltip(content, url, isFullPageContent) {
86398639
let tempContainer = document.createElement("div");
86408640
tempContainer.innerHTML = content;
8641-
if (fullPageContent) hideTocIfNotNeeded(tempContainer, true);
8642-
const pageTitle = tempContainer.querySelector("#page-title");
8643-
if (pageTitle) pageTitle.style.marginTop = "1em";
8644-
const pageSubtitle = tempContainer.querySelector("#page-subtitle");
8645-
if (pageSubtitle) pageSubtitle.style.borderBottom = "0px";
8641+
hideTocIfNotNeeded(tempContainer, true);
8642+
var pageTitle = tempContainer.querySelector("#page-title");
8643+
if (pageTitle == null) {
8644+
var firstHeading = tempContainer.querySelector("h2, h3, h4, h5, h6");
8645+
if (firstHeading) {
8646+
pageTitle = document.querySelector("#page-title").cloneNode(true);
8647+
pageTitle.id = firstHeading.id;
8648+
const anchorElement = pageTitle.querySelector("a");
8649+
anchorElement.textContent = firstHeading.textContent;
8650+
anchorElement.href = url;
8651+
tempContainer.replaceChild(pageTitle, firstHeading);
8652+
}
8653+
}
8654+
pageTitle.style.marginTop = "1em";
86468655
var newContent = tempContainer.innerHTML;
86478656
newContent = newContent.replace(/\bcontent-tooltip\b/g, "");
86488657
return newContent;
@@ -8655,16 +8664,23 @@ $(function() {
86558664
loadContentFromUrl(url, newContent => {
86568665
var startHeading = newContent.querySelector("#" + startHeadingId);
86578666
if (startHeading) {
8658-
var content = startHeading.outerHTML;
8667+
var content = "";
8668+
var heading = startHeading.outerHTML;
86598669
var nextSibling = startHeading.nextElementSibling;
8670+
if (nextSibling == null && false == hasAnchor) {
8671+
startHeading = newContent.querySelector(".page__content");
8672+
nextSibling = startHeading.firstElementChild;
8673+
if (nextSibling && nextSibling.classList.contains("sidebar__right")) nextSibling = nextSibling.nextElementSibling;
8674+
}
86608675
while (nextSibling && nextSibling.tagName !== "H1" && nextSibling.tagName !== "H2" && nextSibling.tagName !== "H3" && nextSibling.tagName !== "H4" && nextSibling.tagName !== "H5" && nextSibling.tagName !== "H6") {
86618676
content += nextSibling.outerHTML;
86628677
nextSibling = nextSibling.nextElementSibling;
86638678
}
8679+
if (content.length != 0 || hasAnchor) content = heading + content;
86648680
onSuccess(content);
8665-
} else console.error("Start heading not found by ID: " + startHeadingId);
8681+
} else onError("Start heading not found by ID: " + startHeadingId);
86668682
}, error => {
8667-
error(error);
8683+
onError(error);
86688684
});
86698685
}
86708686
const toolTipArrowSize = 10;
@@ -8689,9 +8705,9 @@ $(function() {
86898705
var newPosition = position + "px";
86908706
tooltip.style.setProperty(posName, newPosition);
86918707
}
8692-
function showTooltip(event, tooltipText, fullPageContent) {
8708+
function showTooltip(event, tooltipText, isFullPageContent) {
86938709
tooltip.innerHTML = tooltipText.innerHTML;
8694-
if (fullPageContent) tooltip.classList.add("full-content-tooltip"); else tooltip.classList.remove("full-content-tooltip");
8710+
if (isFullPageContent) tooltip.classList.add("full-content-tooltip"); else tooltip.classList.remove("full-content-tooltip");
86958711
var tooltipPos = getTooltipPos(event, tooltipTarget);
86968712
var tooltipArrowLeftShift = 2 * toolTipArrowSize;
86978713
setArrowPosition("--tooltip-arrow-top", -1 * toolTipArrowSize);
@@ -8733,25 +8749,30 @@ $(function() {
87338749
tooltipText.textContent = "";
87348750
element.appendChild(tooltipText);
87358751
element.addEventListener("mouseover", function(event) {
8736-
var fullPageContent = element.classList.contains("full-content-tooltip");
8752+
var isFullPageContent = element.classList.contains("full-content-tooltip");
87378753
tooltipTarget = element;
87388754
if (tooltipText.innerHTML === "") {
87398755
var url = element.href;
87408756
function onSuccess(newContent) {
87418757
if (typeof newContent === "object" && "innerHTML" in newContent) newContent = newContent.innerHTML;
8742-
newContent = alterPageForTooltip(newContent, fullPageContent);
8743-
tooltipText.innerHTML = newContent;
8744-
showTooltip(event, tooltipText, fullPageContent);
8758+
newContent = alterContentForTooltip(newContent, url.isFullPageContent);
8759+
if (newContent.length > 0) {
8760+
tooltipText.innerHTML = newContent;
8761+
showTooltip(event, tooltipText, isFullPageContent);
8762+
} else {
8763+
hideTooltip(false);
8764+
}
87458765
}
87468766
function onError(error) {
8767+
hideTooltip(false);
87478768
console.error("Error loading the tooltip content!" + error);
87488769
}
8749-
if (fullPageContent) {
8770+
if (isFullPageContent) {
87508771
loadContentFromUrl(url, newContent => onSuccess(newContent), error => onError(error));
87518772
} else {
87528773
loadContentPartFrom(url, newContent => onSuccess(newContent), error => onError(error));
87538774
}
8754-
} else showTooltip(event, tooltipText, fullPageContent);
8775+
} else showTooltip(event, tooltipText, isFullPageContent);
87558776
});
87568777
});
87578778
document.addEventListener("mousemove", function(event) {

0 commit comments

Comments
 (0)