@snippetify/book-reader-component
Version:
Book Reader Component
44 lines (43 loc) • 1.85 kB
JavaScript
import rangy from 'rangy';
import 'rangy/lib/rangy-textrange';
import 'rangy/lib/rangy-classapplier';
import 'rangy/lib/rangy-highlighter';
import { Selection } from '../models/selection';
export class SelectionManager {
constructor() {
this.rangy = rangy;
this.rangy.init();
this.highlighter = this.rangy.createHighlighter(document, 'TextRange');
this.highlighter.addClassApplier(this.rangy.createClassApplier('selection', { useExistingElements: false }));
}
static getInstance() {
return new SelectionManager();
}
create() {
const selection = this.rangy.getSelection();
if (!selection.isCollapsed) {
this.highlighter.highlightSelection('selection');
const focusNode = selection.focusNode.parentElement;
const anchorNode = selection.anchorNode.parentElement;
if (!anchorNode || !focusNode)
return;
const endPage = focusNode.closest('[data-no]') ? parseInt(focusNode.closest('[data-no]').getAttribute('data-no')) : 0;
const endRef = focusNode.closest('[data-pos]') ? parseFloat(focusNode.closest('[data-pos]').getAttribute('data-pos')) : 0;
const startPage = anchorNode.closest('[data-no]') ? parseInt(anchorNode.closest('[data-no]').getAttribute('data-no')) : 0;
const startRef = anchorNode.closest('[data-pos]') ? parseFloat(anchorNode.closest('[data-pos]').getAttribute('data-pos')) : 0;
return new Selection({
pages: [startPage, endPage],
content: selection.toString().replace(/--\{\S{2,12}\s\d{1,4}\.\d{1,3}\}/gmi, ''),
references: [startRef, endRef],
serialized: this.getLast(this.highlighter.serialize())
});
}
}
removePrevious() {
this.highlighter.unhighlightSelection();
}
getLast(value) {
const items = value.split('|');
return `${items[0]}|${items[items.length - 1]}`;
}
}