markdownr 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/markdown_server/version.rb +1 -1
- data/views/layout.erb +55 -19
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 77751617a0f29c77c283ed5a5861539501bc6e5795af91b83d2f7ca15ff7e19c
|
|
4
|
+
data.tar.gz: fc0003a34b89f185e567954561d5a367a0a671d085f79719d4a292b82d23270f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65dc66819263dd1367b965e3ec480b90dea99581c9e6039e7bf4e171cfd6cfba6d590c19ef9bbfd4e01a440f8e41478a0640734a6552999b9e69aa72672361f6
|
|
7
|
+
data.tar.gz: 825fe2505eb934401acd0881a8826a2de0b2900ba764b0b3f5e4c5da8a54d06efe567becb87f2d38beb5a2f746c46701272d6c30df95ef3902d8d64596d6738c
|
data/views/layout.erb
CHANGED
|
@@ -1419,6 +1419,7 @@
|
|
|
1419
1419
|
var touchMoved = false;
|
|
1420
1420
|
var historyStack = [];
|
|
1421
1421
|
var currentPopupPos = { x: 0, y: 0 };
|
|
1422
|
+
var mouseLeaveTimer = null;
|
|
1422
1423
|
|
|
1423
1424
|
function escHtml(s) {
|
|
1424
1425
|
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
@@ -1446,11 +1447,11 @@
|
|
|
1446
1447
|
|
|
1447
1448
|
var extLinkIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;flex-shrink:0"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>';
|
|
1448
1449
|
|
|
1449
|
-
function showPopup(x, y, title, bodyHtml, href) {
|
|
1450
|
+
function showPopup(x, y, title, bodyHtml, href, linkRect) {
|
|
1450
1451
|
// Remove old popup without clearing historyStack
|
|
1451
1452
|
if (popup && popup.parentNode) popup.parentNode.removeChild(popup);
|
|
1452
1453
|
popup = null;
|
|
1453
|
-
currentPopupPos = { x: x, y: y };
|
|
1454
|
+
currentPopupPos = { x: x, y: y, linkRect: linkRect || null };
|
|
1454
1455
|
|
|
1455
1456
|
popup = document.createElement('div');
|
|
1456
1457
|
popup.className = 'link-ctx-popup';
|
|
@@ -1469,6 +1470,14 @@
|
|
|
1469
1470
|
'<div class="link-ctx-popup-body">' + bodyHtml + '</div>';
|
|
1470
1471
|
document.body.appendChild(popup);
|
|
1471
1472
|
|
|
1473
|
+
clearTimeout(mouseLeaveTimer);
|
|
1474
|
+
popup.addEventListener('mouseleave', function() {
|
|
1475
|
+
mouseLeaveTimer = setTimeout(hidePopup, 150);
|
|
1476
|
+
});
|
|
1477
|
+
popup.addEventListener('mouseenter', function() {
|
|
1478
|
+
clearTimeout(mouseLeaveTimer);
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1472
1481
|
repositionPopup();
|
|
1473
1482
|
|
|
1474
1483
|
var backBtnEl = popup.querySelector('.link-ctx-popup-back');
|
|
@@ -1476,7 +1485,7 @@
|
|
|
1476
1485
|
backBtnEl.addEventListener('click', function(e) {
|
|
1477
1486
|
e.stopPropagation();
|
|
1478
1487
|
var prev = historyStack.pop();
|
|
1479
|
-
if (prev) showPopup(prev.x, prev.y, prev.title, prev.bodyHtml, prev.href);
|
|
1488
|
+
if (prev) showPopup(prev.x, prev.y, prev.title, prev.bodyHtml, prev.href, prev.linkRect);
|
|
1480
1489
|
});
|
|
1481
1490
|
}
|
|
1482
1491
|
popup.querySelector('.link-ctx-popup-close').addEventListener('click', hidePopup);
|
|
@@ -1492,10 +1501,10 @@
|
|
|
1492
1501
|
if (!linkHref || isAnchorOnly(linkHref)) return;
|
|
1493
1502
|
e.stopPropagation();
|
|
1494
1503
|
e.preventDefault();
|
|
1495
|
-
var savedPos = { x: currentPopupPos.x, y: currentPopupPos.y };
|
|
1504
|
+
var savedPos = { x: currentPopupPos.x, y: currentPopupPos.y, linkRect: currentPopupPos.linkRect };
|
|
1496
1505
|
var titleEl = popup.querySelector('.link-ctx-popup-title');
|
|
1497
1506
|
historyStack.push({
|
|
1498
|
-
x: savedPos.x, y: savedPos.y,
|
|
1507
|
+
x: savedPos.x, y: savedPos.y, linkRect: savedPos.linkRect,
|
|
1499
1508
|
title: titleEl ? titleEl.querySelector('span').textContent : '',
|
|
1500
1509
|
bodyHtml: body.innerHTML,
|
|
1501
1510
|
href: titleEl ? (titleEl.getAttribute('href') || '') : ''
|
|
@@ -1510,10 +1519,10 @@
|
|
|
1510
1519
|
if (!linkHref || isAnchorOnly(linkHref)) return;
|
|
1511
1520
|
e.stopPropagation();
|
|
1512
1521
|
e.preventDefault();
|
|
1513
|
-
var savedPos = { x: currentPopupPos.x, y: currentPopupPos.y };
|
|
1522
|
+
var savedPos = { x: currentPopupPos.x, y: currentPopupPos.y, linkRect: currentPopupPos.linkRect };
|
|
1514
1523
|
var titleEl = popup.querySelector('.link-ctx-popup-title');
|
|
1515
1524
|
historyStack.push({
|
|
1516
|
-
x: savedPos.x, y: savedPos.y,
|
|
1525
|
+
x: savedPos.x, y: savedPos.y, linkRect: savedPos.linkRect,
|
|
1517
1526
|
title: titleEl ? titleEl.querySelector('span').textContent : '',
|
|
1518
1527
|
bodyHtml: body.innerHTML,
|
|
1519
1528
|
href: titleEl ? (titleEl.getAttribute('href') || '') : ''
|
|
@@ -1529,13 +1538,35 @@
|
|
|
1529
1538
|
function repositionPopup() {
|
|
1530
1539
|
if (!popup) return;
|
|
1531
1540
|
var x = currentPopupPos.x, y = currentPopupPos.y;
|
|
1541
|
+
var rect = currentPopupPos.linkRect;
|
|
1532
1542
|
var vw = Math.min(window.innerWidth, document.documentElement.clientWidth);
|
|
1533
1543
|
var vh = window.innerHeight;
|
|
1534
|
-
var
|
|
1535
|
-
var
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1544
|
+
var pw = popup.offsetWidth;
|
|
1545
|
+
var ph = popup.offsetHeight;
|
|
1546
|
+
|
|
1547
|
+
// Horizontal: position so mouse is ~16px inside left edge, clamped to viewport
|
|
1548
|
+
var left = Math.min(x - 16, vw - pw - 8);
|
|
1549
|
+
if (left < 8) left = 8;
|
|
1550
|
+
|
|
1551
|
+
// Vertical: tight to link bounds when available
|
|
1552
|
+
var top;
|
|
1553
|
+
if (rect) {
|
|
1554
|
+
var gap = 3;
|
|
1555
|
+
var belowTop = rect.bottom + gap;
|
|
1556
|
+
var aboveTop = rect.top - ph - gap;
|
|
1557
|
+
if (belowTop + ph <= vh - 8) {
|
|
1558
|
+
top = belowTop; // fits below
|
|
1559
|
+
} else if (aboveTop >= 8) {
|
|
1560
|
+
top = aboveTop; // fits above
|
|
1561
|
+
} else {
|
|
1562
|
+
top = Math.max(8, vh - ph - 8); // clamp: covers link
|
|
1563
|
+
}
|
|
1564
|
+
} else {
|
|
1565
|
+
top = y + 12;
|
|
1566
|
+
if (top + ph > vh - 8) top = Math.max(8, y - ph - 12);
|
|
1567
|
+
if (top < 8) top = 8;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1539
1570
|
popup.style.left = left + 'px';
|
|
1540
1571
|
popup.style.top = top + 'px';
|
|
1541
1572
|
}
|
|
@@ -1550,28 +1581,32 @@
|
|
|
1550
1581
|
}
|
|
1551
1582
|
|
|
1552
1583
|
function hidePopup() {
|
|
1584
|
+
clearTimeout(mouseLeaveTimer);
|
|
1553
1585
|
if (popup && popup.parentNode) popup.parentNode.removeChild(popup);
|
|
1554
1586
|
popup = null;
|
|
1555
1587
|
historyStack = [];
|
|
1556
1588
|
}
|
|
1557
1589
|
|
|
1590
|
+
|
|
1558
1591
|
function handleLink(anchor, x, y, chained) {
|
|
1559
1592
|
if (!chained) historyStack = [];
|
|
1560
1593
|
var href = anchor.getAttribute('href');
|
|
1561
1594
|
if (!href || isAnchorOnly(href)) return;
|
|
1562
1595
|
var label = anchor.textContent.trim() || href;
|
|
1596
|
+
// For chained popup navigation keep the current link rect; for new popups measure the anchor
|
|
1597
|
+
var linkRect = chained ? currentPopupPos.linkRect : anchor.getBoundingClientRect();
|
|
1563
1598
|
|
|
1564
1599
|
if (isLocalMd(href)) {
|
|
1565
1600
|
var path = previewPath(href);
|
|
1566
1601
|
var cached = cache[path];
|
|
1567
1602
|
if (cached && typeof cached === 'object') {
|
|
1568
|
-
showPopup(x, y, cached.title || label, cached.html, href);
|
|
1603
|
+
showPopup(x, y, cached.title || label, cached.html, href, linkRect);
|
|
1569
1604
|
} else if (cached === false) {
|
|
1570
1605
|
showPopup(x, y, label,
|
|
1571
1606
|
'<div class="link-ctx-popup-url">' + escHtml(href) + '</div>' +
|
|
1572
|
-
'<p style="margin:0;color:#888;font-family:sans-serif;font-size:0.82rem">Preview not available</p>', href);
|
|
1607
|
+
'<p style="margin:0;color:#888;font-family:sans-serif;font-size:0.82rem">Preview not available</p>', href, linkRect);
|
|
1573
1608
|
} else {
|
|
1574
|
-
showPopup(x, y, label, '<p style="opacity:0.5;margin:0;font-family:sans-serif">Loading\u2026</p>', href);
|
|
1609
|
+
showPopup(x, y, label, '<p style="opacity:0.5;margin:0;font-family:sans-serif">Loading\u2026</p>', href, linkRect);
|
|
1575
1610
|
if (cached === undefined) {
|
|
1576
1611
|
cache[path] = null;
|
|
1577
1612
|
fetch(path)
|
|
@@ -1592,13 +1627,13 @@
|
|
|
1592
1627
|
var extKey = 'ext:' + href;
|
|
1593
1628
|
var extCached = cache[extKey];
|
|
1594
1629
|
if (extCached && typeof extCached === 'object') {
|
|
1595
|
-
showPopup(x, y, extCached.title || label, extCached.html, href);
|
|
1630
|
+
showPopup(x, y, extCached.title || label, extCached.html, href, linkRect);
|
|
1596
1631
|
} else if (extCached === false) {
|
|
1597
1632
|
showPopup(x, y, label,
|
|
1598
1633
|
'<div class="link-ctx-popup-url">' + escHtml(href) + '</div>' +
|
|
1599
|
-
'<p style="margin:0.5rem 0 0;color:#888;font-family:sans-serif;font-size:0.82rem">Could not fetch page content.</p>', href);
|
|
1634
|
+
'<p style="margin:0.5rem 0 0;color:#888;font-family:sans-serif;font-size:0.82rem">Could not fetch page content.</p>', href, linkRect);
|
|
1600
1635
|
} else {
|
|
1601
|
-
showPopup(x, y, label, '<p style="opacity:0.5;margin:0;font-family:sans-serif">Loading\u2026</p>', href);
|
|
1636
|
+
showPopup(x, y, label, '<p style="opacity:0.5;margin:0;font-family:sans-serif">Loading\u2026</p>', href, linkRect);
|
|
1602
1637
|
if (extCached === undefined) {
|
|
1603
1638
|
cache[extKey] = null;
|
|
1604
1639
|
fetch('/fetch?url=' + encodeURIComponent(href))
|
|
@@ -1623,7 +1658,7 @@
|
|
|
1623
1658
|
}
|
|
1624
1659
|
}
|
|
1625
1660
|
} else {
|
|
1626
|
-
showPopup(x, y, label, '<div class="link-ctx-popup-url">' + escHtml(href) + '</div>', href);
|
|
1661
|
+
showPopup(x, y, label, '<div class="link-ctx-popup-url">' + escHtml(href) + '</div>', href, linkRect);
|
|
1627
1662
|
}
|
|
1628
1663
|
}
|
|
1629
1664
|
|
|
@@ -1686,6 +1721,7 @@
|
|
|
1686
1721
|
});
|
|
1687
1722
|
a.addEventListener('mouseleave', function() {
|
|
1688
1723
|
clearTimeout(hoverTimer);
|
|
1724
|
+
if (popup) mouseLeaveTimer = setTimeout(hidePopup, 150);
|
|
1689
1725
|
});
|
|
1690
1726
|
});
|
|
1691
1727
|
})();
|