• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MarkUsProject / Markus / 26693782648

30 May 2026 08:11PM UTC coverage: 90.277%. Remained the same
26693782648

Pull #7969

github

web-flow
Merge 149782118 into 5b70aab6e
Pull Request #7969: Refactored SubmissionFilePanel subcomponents into functional style

971 of 2149 branches covered (45.18%)

Branch coverage included in aggregate %.

35 of 45 new or added lines in 5 files covered. (77.78%)

1 existing line in 1 file now uncovered.

46018 of 49901 relevant lines covered (92.22%)

121.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/app/javascript/Components/Result/html_viewer.jsx
1
import React from "react";
2
import {markupTextInRange} from "../Helpers/range_selector";
3
import {renderMathInElement} from "../../common/math_helper";
4

5
export class HTMLViewer extends React.PureComponent {
6
  constructor(props) {
7
    super(props);
×
8
    this.iframe = React.createRef();
×
9
  }
10

11
  componentDidMount() {
12
    if (this.props.resultView) {
×
13
      this.readyAnnotations();
×
14
    }
15
  }
16

17
  readyAnnotations = () => {
×
18
    window.annotation_type = window.ANNOTATION_TYPES.HTML;
×
19
  };
20

21
  renderAnnotations = () => {
×
22
    const doc = this.iframe.current.contentWindow.document;
×
23
    // annotations need to be sorted in the order that they were created so that multiple
24
    // annotations on the same node get rendered in the order they were created. If they are
25
    // not, then the ranges may contain nodes/offsets that don't take the other highlighted
26
    // regions into account.
27
    this.props.annotations
×
28
      .sort((a, b) => (a.number > b.number ? 1 : -1))
×
29
      .forEach(annotation => {
30
        const start_node = doc.evaluate(annotation.start_node, doc).iterateNext();
×
31
        const end_node = doc.evaluate(annotation.end_node, doc).iterateNext();
×
32
        const newRange = doc.createRange();
×
33
        try {
×
34
          if (doc.getElementById(`markus-annotation-${annotation.id}`) === null) {
×
35
            newRange.setStart(start_node, annotation.start_offset);
×
36
            newRange.setEnd(end_node, annotation.end_offset);
×
37
          } else {
38
            // Dummy values for the range
39
            newRange.setStart(start_node, 0);
×
40
            newRange.setEnd(end_node, 0);
×
41
          }
42
          markupTextInRange(newRange, annotation.content, annotation.id);
×
43
        } catch (error) {
44
          console.error(error);
×
45
        }
46
      });
47

48
    renderMathInElement(this.iframe.current.contentDocument.body);
×
49

NEW
50
    this.props.setLoadingCallback(false);
×
51
  };
52

53
  componentDidUpdate(prevProps) {
54
    if (prevProps.annotations !== this.props.annotations) {
×
55
      // If annotations have been deleted, reload the notebook.
56
      // TODO: Remove this after implementing functionality to manually remove
57
      //       an annotation (likely in range_selector.js).
58
      if (prevProps.annotations.length > this.props.annotations.length) {
×
59
        this.iframe.current.contentWindow.location.reload();
×
60
      }
61
      this.renderAnnotations();
×
62
    }
63
  }
64

65
  render() {
66
    return (
×
67
      <div>
68
        <iframe
69
          className={"html-content"}
70
          id={"html-content"}
71
          key={this.props.url}
72
          onLoad={this.renderAnnotations}
73
          src={this.props.url + "&preview=true"}
74
          ref={this.iframe}
75
          sandbox="allow-same-origin"
76
        />
77
      </div>
78
    );
79
  }
80
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc