Skip to content

Commit 8618b95

Browse files
authored
Tooltip content and header behavior is ambiguous (#26)
Fixes: #16 Signed-off-by: Hofi <[email protected]>
2 parents e706ce7 + 9769c1a commit 8618b95

File tree

5 files changed

+148
-128
lines changed

5 files changed

+148
-128
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) {

_layouts/single.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,24 @@
3131
{% unless page.header.overlay_color or page.header.overlay_image %}
3232
<header>
3333
{% if page.title %}
34-
<h1 id="page-title" class="page__title p-name {% if page.subtitle == null and page.description == null %} page__title_decoration{% endif %}" itemprop="headline">
34+
{% comment %}<!-- <h1 id="page-title" class="page__title p-name {% if page.subtitle == null and page.description == null %} page__title_decoration{% endif %}" itemprop="headline"> -->{% endcomment %}
35+
<h1 id="page-title" class="page__title p-name page__title_decoration" itemprop="headline">
3536
<a href="{{ page.url | absolute_url }}" class="u-url nav-link" itemprop="url">{{ page.title | markdownify | remove: "<p>" | remove: "</p>" }}</a>
3637
</h1>
3738
{% endif %}
39+
{% comment %}<!--
40+
DO NOT ADD page.subtitle and page.description !!!
41+
It will be added by aour Jekyll plugin as simple text paragraph right at the beggining of the content, before the first heading instead, that will be used as description in the tooltips.
42+
This eliminates markdown and liquid rendering differences in the description part.
43+
3844
{% if page.subtitle or page.description %}
3945
{% if page.subtitle %}
4046
{% assign subtitle = page.subtitle %}
4147
{% else %}
4248
{% assign subtitle = page.description %}
4349
{% endif %}
4450
<p id="page-subtitle" class="page__subtitle p-name page__title_decoration" itemprop="headline">{{ subtitle | liquify | markdownify | remove: "<p>" | remove: "</p>" }}</p>
45-
{% endif %}
51+
{% endif %} -->{% endcomment %}
4652
{% include page__meta.html %}
4753
</header>
4854
{% endunless %}

0 commit comments

Comments
 (0)