Comt internal handling of text annotations

Server side:

  • If markdown is used as the source format, it is first turned into html.
  • Then, a span is added as a parent to each TextNode in the DOM. This parent span is set an id sv_nnn (nnn being the index of this text node when performing a depth-first visit through the DOM tree) and a class c-s.
  • Then Again, a span is added as a parent to each TextNode in the DOM. This parent span is given an id sv-nnn and two classes : one named c-c and one c-count-0. (We'll see later how classes c-count-xxx are used to track the number of comments that apply to this section of text, and therefore color commented sections of the text).

Thus wrapping TextNodes in this manner will turn a DOM tree like :

<h1>foo</h1>
bar
<p>foo bar</p>

into :

<h1>
  <span class="c-s" id="sv_0">
    <span class="c-c c-count-0" id="sv-0">foo</span>
  </span>
</h1>
  <span class="c-s" id="sv_1">
    <span class="c-c c-count-0" id="sv-1">bar</span>
  </span>
<p>
  <span class="c-s" id="sv_2">
    <span class="c-c c-count-0" id="sv-2">foo bar</span>
  </span>
</p>

Why did we have to do this double wrapping of text nodes ?

When comments are attached to the text, the way the DOM is changed on the client side to reflect comments scope changes text content of spans with class c-c. This is not the case for spans with c-s classe:the total text content of spans with class c-s won't be change whatever happens on the client side.

Whenever a comment is added to the text their position is sent to the server with respect to nodes with class sv_nnn. A comment scope is described as:

  • the index nnn of its starting sv_nnn span node
  • the index mmm of its starting sv_mmm span node
  • The character offset in sv_nnn from where it starts
  • The character offset in sv_mmm where it ends

Client side:

Both the list of comments and the wrapped html is received on the client. To reflect comment scopes the client changes the DOM. We'll describe this process with 2 comments to illustrate the way it works :

Datas received on the client side :

  1. Server pre-processed html
<h1>
  <span class="c-s" id="sv_0">
    <span class="c-c c-count-0" id="sv-0">foo</span>
  </span>
</h1>
  <span class="c-s" id="sv_1">
    <span class="c-c c-count-0" id="sv-1">bar</span>
  </span>
<p>
  <span class="c-s" id="sv_2">
    <span class="c-c c-count-0" id="sv-2">foo bar</span>
  </span>
</p>
  1. Comment 1 scope:
start_wrapper : 0 means sv_0 is the id of the span (having class c-s) the comment's scope starts in
end_wrapper : 2 means sv_2 is the id of the span (having class c-s) the comment's scope ends in
start_offset : 2 describes the character offset from the start of the starting wrapper node
end_offset : 5 describes the character offset from the start of the ending wrapper node
  1. Comment 2 scope:
start_wrapper : 0
end_wrapper : 1
start_offset : 1
end_offset : 1

DOM result of first comment insertion:

<h1>
  <span class="c-s" id="sv_0">
    <span class="c-c c-count-0" >fo</span>
    <SPAN CLASS="C-C C-ID-5 C-COUNT-1 C-SCOPE" ID="SV-0">O</SPAN>
  </span>
</h1>
<span class="c-s" id="sv_1">
  <SPAN CLASS="C-C C-ID-5 C-COUNT-1 C-SCOPE" ID="SV-1">BAR</SPAN>
</span>
<p>
  <span class="c-s" id="sv_2">
    <SPAN CLASS="C-C C-ID-5 C-COUNT-1 C-SCOPE">FOO B</SPAN>
    <span class="c-c c-count-0" id="sv-2">ar</span>
  </span>
</p>

Uppercase html was used to show that:

  • wrappers with class c-c in nodes where scope starts and ends have been 'cut' at the offset: as a result, the parents sv_0 and sv_2 with class c-s now each have two children nodes having class c-c.
  • wrappers that are anywhere between end scope nodes (in a depth first search of the DOM tree) now have their c-count-nnn incremented: as a result, sv-1 now has a class c-count-1 instead of c-count-0

DOM result of second comment insertion:

<h1 id="foo">
  <span class="c-s" id="sv_0">
    <span class="c-c c-count-0">f</span>
    <span class="c-c c-id-6 c-count-1" >o</span>
    <span class="c-c c-id-5 c-id-6 c-count-2" id="sv-0">o</span>
  </span>
</h1>
<span class="c-s" id="sv_1">
  <span class="c-c c-id-5 c-id-6 c-count-2">b</span>
  <span class="c-c c-id-5 c-count-1" id="sv-1">ar</span>
</span>
<p>
  <span class="c-s" id="sv_2">
    <span class="c-c c-id-5 c-count-1">foo b</span>
    <span class="c-c c-count-0" id="sv-2">ar</span>
  </span>
</p>