|
572 | 572 | return targetCell + "-" + line; |
573 | 573 | }) |
574 | 574 | |
575 | | - let top = null; |
576 | | - let height = null; |
577 | | - let parent = null; |
| 575 | + // Each band is positioned against its own containing block, which is |
| 576 | + // not the offsetParent of the lines, so place it from client rects. |
| 577 | + const placeBand = (band, firstEl, lastEl, codeBlock) => { |
| 578 | + const container = band.offsetParent; |
| 579 | + if (container === null) { |
| 580 | + return; |
| 581 | + } |
| 582 | + const containerRect = container.getBoundingClientRect(); |
| 583 | + // Reveal.js scales slides with a transform, so convert client |
| 584 | + // pixels back to the CSS pixels of the container. |
| 585 | + const scale = containerRect.height / container.offsetHeight || 1; |
| 586 | + const firstRect = firstEl.getBoundingClientRect(); |
| 587 | + const lastRect = lastEl.getBoundingClientRect(); |
| 588 | + const top = (firstRect.top - containerRect.top) / scale - container.clientTop + container.scrollTop; |
| 589 | + const height = (lastRect.bottom - firstRect.top) / scale; |
| 590 | + band.style.top = top - 2 + "px"; |
| 591 | + band.style.height = height + 4 + "px"; |
| 592 | + if (codeBlock) { |
| 593 | + // Without the copy button wrapper, the containing block is wider |
| 594 | + // than the code block, so span the code block explicitly. |
| 595 | + const blockRect = codeBlock.getBoundingClientRect(); |
| 596 | + band.style.left = (blockRect.left - containerRect.left) / scale - container.clientLeft + container.scrollLeft + "px"; |
| 597 | + band.style.width = blockRect.width / scale + "px"; |
| 598 | + } |
| 599 | + }; |
| 600 | +
|
578 | 601 | if (lineIds.length > 0) { |
579 | | - //compute the position of the single el (top and bottom and make a div) |
580 | | - const el = window.document.getElementById(lineIds[0]); |
581 | | - top = el.offsetTop; |
582 | | - height = el.offsetHeight; |
583 | | - parent = el.parentElement.parentElement; |
584 | | - |
585 | | - if (lineIds.length > 1) { |
586 | | - const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); |
587 | | - const bottom = lastEl.offsetTop + lastEl.offsetHeight; |
588 | | - height = bottom - top; |
| 602 | + const el = window.document.getElementById(lineIds[0]); |
| 603 | + const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); |
| 604 | + const parent = el.parentElement.parentElement; |
| 605 | +
|
| 606 | + // cook up a div (if necessary) and position it |
| 607 | + let div = window.document.getElementById("code-annotation-line-highlight"); |
| 608 | + if (div === null) { |
| 609 | + div = window.document.createElement("div"); |
| 610 | + div.setAttribute("id", "code-annotation-line-highlight"); |
| 611 | + div.style.position = 'absolute'; |
| 612 | + parent.appendChild(div); |
589 | 613 | } |
590 | | - |
591 | | - if (top !== null && height !== null && parent !== null) { |
592 | | - // cook up a div (if necessary) and position it |
593 | | - let div = window.document.getElementById("code-annotation-line-highlight"); |
594 | | - if (div === null) { |
595 | | - div = window.document.createElement("div"); |
596 | | - div.setAttribute("id", "code-annotation-line-highlight"); |
597 | | - div.style.position = 'absolute'; |
598 | | - parent.appendChild(div); |
599 | | - } |
600 | | - div.style.top = top - 2 + "px"; |
601 | | - div.style.height = height + 4 + "px"; |
602 | | - div.style.left = 0; |
603 | | - |
604 | | - let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); |
605 | | - if (gutterDiv === null) { |
606 | | - gutterDiv = window.document.createElement("div"); |
607 | | - gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); |
608 | | - gutterDiv.style.position = 'absolute'; |
609 | | - const codeCell = window.document.getElementById(targetCell); |
610 | | - const gutter = codeCell.querySelector('.code-annotation-gutter'); |
611 | | - gutter.appendChild(gutterDiv); |
612 | | - } |
613 | | - |
614 | | - gutterDiv.style.top = top - 2 + "px"; |
615 | | - gutterDiv.style.height = height + 4 + "px"; |
| 614 | + placeBand(div, el, lastEl, parent.closest("div.sourceCode") || parent); |
| 615 | +
|
| 616 | + let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); |
| 617 | + if (gutterDiv === null) { |
| 618 | + gutterDiv = window.document.createElement("div"); |
| 619 | + gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); |
| 620 | + gutterDiv.style.position = 'absolute'; |
| 621 | + const codeCell = window.document.getElementById(targetCell); |
| 622 | + const gutter = codeCell.querySelector('.code-annotation-gutter'); |
| 623 | + gutter.appendChild(gutterDiv); |
616 | 624 | } |
| 625 | + placeBand(gutterDiv, el, lastEl); |
| 626 | +
|
617 | 627 | selectedAnnoteEl = annoteEl; |
618 | 628 | } |
619 | 629 | }; |
|
0 commit comments