markdownr 0.6.3 → 0.6.4
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 +38 -14
- data/views/popup_assets.erb +61 -11
- 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: 845f5eba9de7543ef7e3c386e54f127d8ecfaf48e368d5fb11de54ca5d96cc6c
|
|
4
|
+
data.tar.gz: 9b00fb58e4c3a4e9e3b5c8236f30b96577f7e8bd4d18a17d8576b6382d568380
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 619d4b659c762122321ee3215e06b996c111d88f36bcc83a57b7613f2c9d241a9dea383bb2fbd86c9afa3a579085c7ae7b42519f597e795cb327f23426a5de7d
|
|
7
|
+
data.tar.gz: cf8bc3acf215f5fae8fbbafa137a231e8b37a1db8e73691f95cdc4f1f4acdd9631b19200cf4483b3dcad8df4c95d1a5ee6487cc34e7fb9de16c5c7d0d516b7d7
|
data/views/layout.erb
CHANGED
|
@@ -883,6 +883,12 @@
|
|
|
883
883
|
margin-bottom: 0.5rem;
|
|
884
884
|
}
|
|
885
885
|
|
|
886
|
+
/* Verse range highlighting */
|
|
887
|
+
.verse-selected {
|
|
888
|
+
background: #e5eefb;
|
|
889
|
+
border-radius: 2px;
|
|
890
|
+
}
|
|
891
|
+
|
|
886
892
|
/* Mermaid diagrams */
|
|
887
893
|
.mermaid { text-align: center; margin: 1.2rem 0; overflow-x: auto; }
|
|
888
894
|
.mermaid svg { max-width: 100%; height: auto; }
|
|
@@ -2017,30 +2023,48 @@
|
|
|
2017
2023
|
historyStack = [];
|
|
2018
2024
|
}
|
|
2019
2025
|
|
|
2026
|
+
function findVerseSpans(root, verseNum) {
|
|
2027
|
+
var span = root.querySelector('[data-verse="' + verseNum + '"]');
|
|
2028
|
+
if (span) return [span];
|
|
2029
|
+
var spans = root.querySelectorAll('[data-verse$=":' + verseNum + '"]');
|
|
2030
|
+
return spans.length ? Array.prototype.slice.call(spans) : [];
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2020
2033
|
function applyPopupAnchor(hash) {
|
|
2021
2034
|
if (!hash || !popup) return;
|
|
2022
2035
|
var id = hash.replace(/^#/, '');
|
|
2023
2036
|
try {
|
|
2024
|
-
var
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2037
|
+
var body = popup.querySelector('.link-ctx-popup-body');
|
|
2038
|
+
if (!body) return;
|
|
2039
|
+
|
|
2040
|
+
// Verse range: #vN or #vN-M
|
|
2041
|
+
var vm = id.match(/^v(\d+)(?:-(\d+))?$/);
|
|
2042
|
+
if (vm) {
|
|
2043
|
+
var start = parseInt(vm[1], 10);
|
|
2044
|
+
var end = vm[2] ? parseInt(vm[2], 10) : start;
|
|
2045
|
+
var first = null;
|
|
2046
|
+
for (var v = start; v <= end; v++) {
|
|
2047
|
+
var spans = findVerseSpans(body, v);
|
|
2048
|
+
for (var i = 0; i < spans.length; i++) {
|
|
2049
|
+
spans[i].classList.add('verse-selected');
|
|
2050
|
+
if (!first) first = spans[i];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
if (first) {
|
|
2054
|
+
var bodyTop = body.getBoundingClientRect().top;
|
|
2055
|
+
var targetTop = first.getBoundingClientRect().top;
|
|
2056
|
+
body.scrollTop += targetTop - bodyTop - 8;
|
|
2033
2057
|
}
|
|
2058
|
+
return;
|
|
2034
2059
|
}
|
|
2060
|
+
|
|
2061
|
+
// Standard anchor by ID
|
|
2062
|
+
var eid = id.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
2063
|
+
var target = popup.querySelector('[id="' + eid + '"]');
|
|
2035
2064
|
if (!target) return;
|
|
2036
|
-
// Scroll the body container (which has overflow-y:auto) to the target,
|
|
2037
|
-
// accounting for the sticky header so the heading lands just below it
|
|
2038
|
-
var body = popup.querySelector('.link-ctx-popup-body');
|
|
2039
|
-
if (!body) return;
|
|
2040
2065
|
var bodyTop = body.getBoundingClientRect().top;
|
|
2041
2066
|
var targetTop = target.getBoundingClientRect().top;
|
|
2042
2067
|
body.scrollTop += targetTop - bodyTop - 8;
|
|
2043
|
-
// Append section heading text to the popup title
|
|
2044
2068
|
if (/^H[1-6]$/.test(target.tagName)) {
|
|
2045
2069
|
var titleEl = popup.querySelector('.link-ctx-popup-title span');
|
|
2046
2070
|
if (titleEl) titleEl.textContent = titleEl.textContent + ' \u203a ' + target.textContent;
|
data/views/popup_assets.erb
CHANGED
|
@@ -142,6 +142,12 @@
|
|
|
142
142
|
margin-bottom: 0.5rem;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/* Verse range highlighting */
|
|
146
|
+
.verse-selected {
|
|
147
|
+
background: #e5eefb;
|
|
148
|
+
border-radius: 2px;
|
|
149
|
+
}
|
|
150
|
+
|
|
145
151
|
/* Shared popup content styles */
|
|
146
152
|
.link-ctx-popup-body {
|
|
147
153
|
font-family: Georgia, "Times New Roman", serif;
|
|
@@ -589,24 +595,45 @@
|
|
|
589
595
|
historyStack = [];
|
|
590
596
|
}
|
|
591
597
|
|
|
598
|
+
function findVerseSpans(root, verseNum) {
|
|
599
|
+
var span = root.querySelector('[data-verse="' + verseNum + '"]');
|
|
600
|
+
if (span) return [span];
|
|
601
|
+
var spans = root.querySelectorAll('[data-verse$=":' + verseNum + '"]');
|
|
602
|
+
return spans.length ? Array.prototype.slice.call(spans) : [];
|
|
603
|
+
}
|
|
604
|
+
|
|
592
605
|
function applyPopupAnchor(hash) {
|
|
593
606
|
if (!hash || !popup) return;
|
|
594
607
|
var id = hash.replace(/^#/, '');
|
|
595
608
|
try {
|
|
596
|
-
var
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
609
|
+
var body = popup.querySelector('.link-ctx-popup-body');
|
|
610
|
+
if (!body) return;
|
|
611
|
+
|
|
612
|
+
// Verse range: #vN or #vN-M
|
|
613
|
+
var vm = id.match(/^v(\d+)(?:-(\d+))?$/);
|
|
614
|
+
if (vm) {
|
|
615
|
+
var start = parseInt(vm[1], 10);
|
|
616
|
+
var end = vm[2] ? parseInt(vm[2], 10) : start;
|
|
617
|
+
var first = null;
|
|
618
|
+
for (var v = start; v <= end; v++) {
|
|
619
|
+
var spans = findVerseSpans(body, v);
|
|
620
|
+
for (var i = 0; i < spans.length; i++) {
|
|
621
|
+
spans[i].classList.add('verse-selected');
|
|
622
|
+
if (!first) first = spans[i];
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
if (first) {
|
|
626
|
+
var bodyTop = body.getBoundingClientRect().top;
|
|
627
|
+
var targetTop = first.getBoundingClientRect().top;
|
|
628
|
+
body.scrollTop += targetTop - bodyTop - 8;
|
|
605
629
|
}
|
|
630
|
+
return;
|
|
606
631
|
}
|
|
632
|
+
|
|
633
|
+
// Standard anchor by ID
|
|
634
|
+
var eid = id.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
635
|
+
var target = popup.querySelector('[id="' + eid + '"]');
|
|
607
636
|
if (!target) return;
|
|
608
|
-
var body = popup.querySelector('.link-ctx-popup-body');
|
|
609
|
-
if (!body) return;
|
|
610
637
|
var bodyTop = body.getBoundingClientRect().top;
|
|
611
638
|
var targetTop = target.getBoundingClientRect().top;
|
|
612
639
|
body.scrollTop += targetTop - bodyTop - 8;
|
|
@@ -847,4 +874,27 @@
|
|
|
847
874
|
})();
|
|
848
875
|
|
|
849
876
|
})();
|
|
877
|
+
|
|
878
|
+
// Full-page verse highlighting from URL hash (#vN or #vN-M)
|
|
879
|
+
(function() {
|
|
880
|
+
var m = window.location.hash.match(/^#v(\d+)(?:-(\d+))?$/);
|
|
881
|
+
if (!m) return;
|
|
882
|
+
var start = parseInt(m[1], 10);
|
|
883
|
+
var end = m[2] ? parseInt(m[2], 10) : start;
|
|
884
|
+
var first = null;
|
|
885
|
+
for (var v = start; v <= end; v++) {
|
|
886
|
+
var sel = '[data-verse$=":' + v + '"]';
|
|
887
|
+
var spans = document.querySelectorAll(sel);
|
|
888
|
+
if (!spans.length) spans = document.querySelectorAll('[data-verse="' + v + '"]');
|
|
889
|
+
for (var i = 0; i < spans.length; i++) {
|
|
890
|
+
spans[i].classList.add('verse-selected');
|
|
891
|
+
if (!first) first = spans[i];
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
if (!first) return;
|
|
895
|
+
var top = first.getBoundingClientRect().top + window.pageYOffset;
|
|
896
|
+
var toolbar = document.querySelector('.toolbar');
|
|
897
|
+
if (toolbar) top -= toolbar.offsetHeight + 4;
|
|
898
|
+
window.scrollTo({ top: top, behavior: 'instant' });
|
|
899
|
+
})();
|
|
850
900
|
</script>
|