Skip to content

Commit f95aed6

Browse files
author
Nitai Sasson
committed
draft: fix Ferris hiding code
1 parent 8695fc2 commit f95aed6

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

ferris.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,7 @@ pre:hover > .buttons button {
6565
visibility: visible;
6666
opacity: 1;
6767
}
68+
69+
.ferris-buffer {
70+
margin-right: 5em;
71+
}

ferris.js

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ function attachFerrises(type) {
5252
continue;
5353
}
5454

55-
container.appendChild(createFerris(type, size));
55+
let ferris = createFerris(type, size)
56+
container.appendChild(ferris);
57+
addPadding(codeBlock, ferris);
5658
}
5759
}
5860

@@ -100,3 +102,77 @@ function createFerris(type, size) {
100102

101103
return a;
102104
}
105+
106+
/**
107+
*
108+
* @param {HTMLElement} codeBlock
109+
* @param {HTMLAnchorElement} ferris
110+
*/
111+
function addPadding(codeBlock, ferris) {
112+
// console.log("offsetHeight:", ferris.offsetHeight, "offsetWidth:", ferris.offsetWidth, "offsetLeft", ferris.offsetLeft, "offsetTop:", ferris.offsetTop, "offsetParent:", ferris.offsetParent);
113+
// console.log(ferris.getBoundingClientRect());
114+
115+
const suspects = []; // array of spans which *might* be hidden by Ferris
116+
117+
const walker = document.createTreeWalker(codeBlock, NodeFilter.SHOW_TEXT);
118+
const re = /^(.*?)\n(.*)$/s
119+
120+
let linebreaksToFix = 10;
121+
while (linebreaksToFix > 0 && walker.nextNode()) {
122+
const current = walker.currentNode;
123+
const parent = current.parentNode;
124+
125+
// sanity checking + lint fixes
126+
if (!(current instanceof Text)) {
127+
console.log("!(current instanceof Text) shouldn't happen");
128+
continue;
129+
}
130+
if (!parent) {
131+
console.log("!parent shouldn't happen");
132+
continue;
133+
}
134+
135+
let re_results;
136+
// I know nodeValue is not null because current is Text
137+
current.splitText
138+
while (re_results = current.nodeValue.match(re)) {
139+
linebreaksToFix--;
140+
if (!linebreaksToFix) { break; }
141+
142+
let [_, before, after] = re_results;
143+
144+
let elemBefore = document.createElement("span");
145+
elemBefore.innerText = before;
146+
suspects.push(elemBefore);
147+
148+
parent.insertBefore(elemBefore, current);
149+
parent.insertBefore(document.createTextNode("\n"), current);
150+
current.nodeValue = after;
151+
}
152+
}
153+
154+
codeBlock.normalize(); // not strictly necessary, but good practice to leave the DOM normalized
155+
156+
const actual_ferris = ferris.firstChild;
157+
158+
setTimeout(detectOverlap, 0, suspects, actual_ferris);
159+
}
160+
161+
/**
162+
*
163+
* @param {[HTMLSpanElement]} suspects
164+
* @param {HTMLAnchorElement} ferris
165+
*/
166+
function detectOverlap(suspects, ferris) {
167+
const f = ferris.getBoundingClientRect();
168+
suspects.forEach((s) => {
169+
const {bottom, top} = s.getBoundingClientRect();
170+
if ( // vertical overlap between ferris and span
171+
(bottom >= f.top && bottom <= f.bottom)
172+
|| (top >= f.top && top <= f.bottom)
173+
|| (f.top >= top && f.top <= bottom)
174+
) {
175+
s.classList.add("ferris-buffer");
176+
}
177+
});
178+
}

0 commit comments

Comments
 (0)