rangy
rangy copied to clipboard
allowing for distinct, overlapping highlights (i.e., nested spans)?
Hi @timdown, all,
Using the Highlighter Module or perhaps the Class Applier Module alone, is there a (supported) way to allow for distinct, overlapping highlights (implemented with nested spans having the same class)? For instance, consider a document with a leaf like:
<span>foo bar baz</span>
and a Class Applier like:
var id = 0;
var applier = rangy.createClassApplier('highlight', {
onElementCreate: function(el, applier) {
$(el).attr('unique-id', 'id-' + id);
}
});
$(document.body).on('mouseup', function() {
applier.applyToSelection();
id++;
});
If a user selects foo bar baz, that yields:
<span>
<span class="highlight" unique-id="id-0">foo bar baz</span>
</span>
If a user then selects just bar, the DOM remains unchanged, which seems to be the result of
if (!applier.isIgnorableWhiteSpaceNode(textNode) && !applier.getSelfOrAncestorWithClass(textNode) &&
applier.isModifiable(textNode)) {
applier.applyToTextNode(textNode, positionsToPreserve);
}
in rangy-classapplier.js, specifically the check for whether an ancestor or self already has the class (highlight).
Without that call to getSelfOrAncestorWithClass, the resulting DOM is instead
<span>
<span class="highlight" unique-id="id-0">
foo
<span class="highlight" unique-id="id-1">bar</span>
baz
</span>
</span>
which is desirable if we'd indeed like to keep track of the original selections (e.g., if made by different users and not intended to be merged).
We've been able to achieve that desired outcome with:
...
var applier = rangy.createClassApplier('unused', {
onElementCreate: function(el, applier) {
$(el).removeClass();
$(el).addClass('highlight');
$(el).attr('unique-id', 'id-' + id);
}
});
...
Note the effectively unused class unused. But is there perhaps a cleaner way to achieve this nesting?
(This is perhaps related in spirit to #68 and #302 but thought I'd best elaborate on the use case at hand!)
Many thanks!
I worked around this by adding the id into the class name and then using a wildcard CSS selector.
... .createClassApplier('annotated-text-' + annotation.get('id'));
.annotated-text, [class^="annotated-text-"], [class*=" annotated-text-"] {
background-color: rgba($blue-light, 0.4);
}