include lineHeight property in sidebar elements (#4831)
This also makes the full line number element clickable to ensure a positive UX for the ``?lineNumber`` URL endpoint. It also makes it more obvious that a click action can happen based on the hover. Make line numbers stick to baseline of first line of wrapped content and editor lines with increased line hieght. Make it compatible with ep_author_neatpull/4833/head
parent
08d2024caf
commit
4ca2d7ea3a
|
@ -3786,7 +3786,24 @@ function Ace2Inner() {
|
||||||
|
|
||||||
// Refs #4228, to avoid layout trashing, we need to first calculate all the heights,
|
// Refs #4228, to avoid layout trashing, we need to first calculate all the heights,
|
||||||
// and then apply at once all new height to div elements
|
// and then apply at once all new height to div elements
|
||||||
|
const lineOffsets = [];
|
||||||
|
|
||||||
|
// To place the line number on the same Z point as the first character of the first line
|
||||||
|
// we need to know the line height including the margins of the firstChild within the line
|
||||||
|
// This is somewhat computationally expensive as it looks at the first element within
|
||||||
|
// the line. Alternative, cheaper approaches are welcome.
|
||||||
|
// Original Issue: https://github.com/ether/etherpad-lite/issues/4527
|
||||||
const lineHeights = [];
|
const lineHeights = [];
|
||||||
|
|
||||||
|
// 24 is the default line height within Etherpad - There may be quirks here such as
|
||||||
|
// none text elements (images/embeds etc) where the line height will be greater
|
||||||
|
// but as it's non-text type the line-height/margins might not be present and it
|
||||||
|
// could be that this breaks a theme that has a different default line height..
|
||||||
|
// So instead of using an integer here we get the value from the Editor CSS.
|
||||||
|
const innerdocbody = document.querySelector('#innerdocbody');
|
||||||
|
const innerdocbodyStyles = getComputedStyle(innerdocbody);
|
||||||
|
const defaultLineHeight = parseInt(innerdocbodyStyles['line-height']);
|
||||||
|
|
||||||
let docLine = doc.body.firstChild;
|
let docLine = doc.body.firstChild;
|
||||||
let currentLine = 0;
|
let currentLine = 0;
|
||||||
let h = null;
|
let h = null;
|
||||||
|
@ -3811,7 +3828,21 @@ function Ace2Inner() {
|
||||||
// last line
|
// last line
|
||||||
h = (docLine.clientHeight || docLine.offsetHeight);
|
h = (docLine.clientHeight || docLine.offsetHeight);
|
||||||
}
|
}
|
||||||
lineHeights.push(h);
|
lineOffsets.push(h);
|
||||||
|
|
||||||
|
if (docLine.clientHeight !== defaultLineHeight) {
|
||||||
|
// line is wrapped OR has a larger line height within so we will do additional
|
||||||
|
// computation to figure out the line-height of the first element and
|
||||||
|
// use that for displaying the side div line number inline with the first line
|
||||||
|
// of content -- This is used in ep_headings, ep_font_size etc. where the line
|
||||||
|
// height is increased.
|
||||||
|
const elementStyle = window.getComputedStyle(docLine.firstChild);
|
||||||
|
const lineHeight = parseInt(elementStyle.getPropertyValue('line-height'));
|
||||||
|
const marginBottom = parseInt(elementStyle.getPropertyValue('margin-bottom'));
|
||||||
|
lineHeights.push(lineHeight + marginBottom);
|
||||||
|
} else {
|
||||||
|
lineHeights.push(defaultLineHeight);
|
||||||
|
}
|
||||||
docLine = docLine.nextSibling;
|
docLine = docLine.nextSibling;
|
||||||
currentLine++;
|
currentLine++;
|
||||||
}
|
}
|
||||||
|
@ -3823,8 +3854,9 @@ function Ace2Inner() {
|
||||||
// Apply height to existing sidediv lines
|
// Apply height to existing sidediv lines
|
||||||
currentLine = 0;
|
currentLine = 0;
|
||||||
while (sidebarLine && currentLine <= lineNumbersShown) {
|
while (sidebarLine && currentLine <= lineNumbersShown) {
|
||||||
if (lineHeights[currentLine] != null) {
|
if (lineOffsets[currentLine] != null) {
|
||||||
sidebarLine.style.height = `${lineHeights[currentLine]}px`;
|
sidebarLine.style.height = `${lineOffsets[currentLine]}px`;
|
||||||
|
sidebarLine.style.lineHeight = `${lineHeights[currentLine]}px`;
|
||||||
}
|
}
|
||||||
sidebarLine = sidebarLine.nextSibling;
|
sidebarLine = sidebarLine.nextSibling;
|
||||||
currentLine++;
|
currentLine++;
|
||||||
|
@ -3839,8 +3871,9 @@ function Ace2Inner() {
|
||||||
while (lineNumbersShown < newNumLines) {
|
while (lineNumbersShown < newNumLines) {
|
||||||
lineNumbersShown++;
|
lineNumbersShown++;
|
||||||
const div = odoc.createElement('DIV');
|
const div = odoc.createElement('DIV');
|
||||||
if (lineHeights[currentLine]) {
|
if (lineOffsets[currentLine]) {
|
||||||
div.style.height = `${lineHeights[currentLine]}px`;
|
div.style.height = `${lineOffsets[currentLine]}px`;
|
||||||
|
div.style.lineHeight = `${lineHeights[currentLine]}px`;
|
||||||
}
|
}
|
||||||
$(div).append($(`<span class='line-number'>${String(lineNumbersShown)}</span>`));
|
$(div).append($(`<span class='line-number'>${String(lineNumbersShown)}</span>`));
|
||||||
fragment.appendChild(div);
|
fragment.appendChild(div);
|
||||||
|
|
|
@ -12,8 +12,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidedivinner>div .line-number {
|
#sidedivinner>div .line-number {
|
||||||
line-height: 24px;
|
line-height: inherit;
|
||||||
font-family: RobotoMono;
|
font-family: RobotoMono;
|
||||||
|
display: inline-block;
|
||||||
color: #576273;
|
color: #576273;
|
||||||
color: var(--text-soft-color);
|
color: var(--text-soft-color);
|
||||||
}
|
height:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidedivinner>div .line-number:hover {
|
||||||
|
background-color: var(--bg-soft-color);
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
.plugin-ep_author_neat #sidedivinner>div .line-number:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue