Dom annotation (question)
by David Guan
HTML
<h2>
Story:
</h2>
Mr. Sima Suyuan is a big fan of A Song of Ice and Fire as well as an exceptional frontend engineer. To help himself understand the content of the books more visually, he decides to annotate different part of the text with different styles. For example, he wants to annotate each major character names with the main color of his/her sigil and underline importance sentence.
<p>
For example, he wants to annotate the following text (under a div with id="root" ) with a bunch of queries embeded in the unfinished Javascript file
</p>
<div id='root'>During the War of the Five Kings, Robb Stark, also known as the Young Wolf, fought Lord Tywin Lannister in various battles in the Riverlands. In the mean time, Mace Tyrell declared for King Renly Baratheon even though his elder brother Stannis Baratheon had a better claim to the throne. Across the narrow sea, Daenerys Targaryen hatched three dragons and crowned herself Queen of Meereen.
</div>
<p>
The queries are pairs of source range in original text and a CSS class that Mr Sima wants to annotate. e.g. following quries means Mr Sima wants to annotate "Robb Stark" with "start" class which uses his family color, and also wants to annotate "Robb" wiht class "first" so first name of characters could be emphasized.
</p>
<code>
[{start: 34, end: 44}, 'stark'],
[{start: 34, end: 38}, 'first'],
</code>
<p>
All other style are defined in the CSS and all other queries are in the unifished Javascript file which Mr Sima just started.
</p>
<p>
Since Mr Sima is very busy recently, he wants you to help him finish the code that actually doing the annotation, if the code works correctly, the original text would looks exactly as follow:
</p>
<div id="root">During the War of the Five Kings, <span class="stark"><span class="first">Robb</span> Stark</span>, also known as the Young Wolf, fought Lord <span class="lannister"><span class="first">Tywin</span> Lannister</span> in various battles in the Riverlands. In the...
CSS
.lannister {color: red;}
.baratheon {color: orange;}
.stark {color: silver;}
.tyrell {color: green;}
.targaryen {color: white; background-color: black;}
.first {font-weight: bold;}
.important {text-decoration: underline;}
JavaScript
var queries = [
[{start: 34, end: 44}, 'stark'],
[{start: 88, end: 103}, 'lannister'],
[{start: 160, end: 171}, 'tyrell'],
[{start: 190, end: 205}, 'baratheon'],
[{start: 236, end: 253}, 'baratheon'],
[{start: 311, end: 329}, 'targaryen'],
[{start: 34, end: 38}, 'first'],
[{start: 88, end: 93}, 'first'],
[{start: 160, end: 164}, 'first'],
[{start: 190, end: 195}, 'first'],
[{start: 236, end: 243}, 'first'],
[{start: 311, end: 319}, 'first'],
[{start: 160, end: 286}, 'important'],
];
var root = document.getElementById("root");
// Hi dear friend I'm super busy, could you help me finish the rest of the code?
// restruct data, for clearer logic
queries = queries.map(d => ({
start: d[0].start,
end: d[0].end,
className: d[1],
children: []
}))
// sort queries
for (let i = 1; i < queries.length; i++) {
for (let j = 0; j < queries.length - i; j++) {
if (queries[j].start > queries[j + 1].start) {
const tmp = queries[j]
queries[j] = queries[j + 1]
queries[j + 1] = tmp
}
}
}
// find container relationship
queries.forEach((d, i) => {
let parents = []
for (let j = 0; j < queries.length; j++) {
const { start, end } = queries[j]
if (d.end < start) break
if (j !== i && start <= d.start && end >= d.end) {
parents.push({width: end - start, index: j})
}
}
if (parents.length) {
let parent = parents[0]
for (let j = 1; j < parents.length; j++) {
if (parent.width > parents[j].width) {
parent = parents[j]
}
}
queries[i].parentIndex = parent.index
queries[parent.index].children.push(i)
}
})
let endPoint = 0
let output = ''
const segments = []
const text = root.innerHTML
root.innerHTML = ''
//queries = queries.slice(0, 2)
console.log(queries)
function traversalText(dom, containerID, start, end) {
for (let i = 0; i < queries.length; i++) {
const d = queries[i]
if (d.parentIndex !== undefined) {
if (containerID === undefined ||...