UNPKG

@snippetify/book-reader

Version:
147 lines (121 loc) 3.73 kB
const Events = require('./events') const Decorator = require('./models/Decorator') const rangy = require('rangy/lib/rangy-highlighter') const classApplier = require('rangy/lib/rangy-classapplier') class DecoratorManager { constructor () { this.config = {} this.events = {} this.rangy = rangy this.decorators = [] this.rootElement = document } static getInstance () { return new DecoratorManager() } setConfig (config) { this.config = config return this } setRootElement (element) { this.rootElement = element return this } setEvents (events) { this.events = events return this } find (uuid) { return this.decorators.find(v => v.uuid === uuid) } setMany (items, print) { this.decorators = items || [] if (print) { this.print() } return this } add (item, print) { this.decorators.push(item) if (print) { this.printOne(item) } return this } update (item, print) { this.remove(item).add(item) if (print) { this.updatePrinting(item) } return this } updateMany (items, print) { items.forEach(v => this.update(v, print)) return this } remove (item, print) { this.decorators = this.decorators.filter(v => v.uuid !== item.uuid) if (print) { this.unprintOne(item) } return this } removeMany (items, print) { items.forEach(v => this.remove(v, print)) return this } removeAll (print) { this.decorators = [] if (print) { this.unprintAll() } return this } print () { this.decorators.forEach(decorator => this.printOne(decorator)) return this } printOne (decorator) { this.initHighlighter() const selection = $(this.rootElement).find('.selection') decorator = new Decorator(decorator) if (selection.length > 0) { selection .removeClass('selection') .addClass(decorator.type) .css({ ...decorator.style }) .attr({ 'data-uuid': decorator.uuid, 'data-type': decorator.type }) } else { this.highlighter.classAppliers[decorator.type].elementProperties.style = decorator.style this.highlighter.classAppliers[decorator.type].elementAttributes['data-uuid'] = decorator.uuid this.highlighter.classAppliers[decorator.type].elementAttributes['data-type'] = decorator.type this.highlighter.deserialize(decorator.getSelerialized()) } this.rangy.getSelection().removeAllRanges() return this } updatePrinting (decorator) { $(this.rootElement).find(`[data-uuid="${decorator.uuid}"]`).css(decorator.style) return this } unprintOne (decorator) { const tag = $(this.rootElement).find(`[data-uuid="${decorator.uuid}"]`) tag.replaceWith(tag.html()) return this } unprintAll () { $(this.rootElement).find('[data-uuid]').each((_, elem) => { const tag = $(elem) tag.replaceWith(tag.html()) }) return this } initDispatcher () { $(this.rootElement).on('click', '[data-uuid]', (e) => { const event = this.find($(e.target).data('uuid')) if (event) { this.events.notify(Events.decoratorClick, event) } }) return this } initHighlighter () { if (!this.highlighter) { this.highlighter = this.rangy.createHighlighter(document, 'TextRange') this.highlighter.addClassApplier(classApplier.createClassApplier('note')) this.highlighter.addClassApplier(classApplier.createClassApplier('bookmark')) this.highlighter.addClassApplier(classApplier.createClassApplier('highlight')) this.highlighter.addClassApplier(classApplier.createClassApplier('search-result')) } } } module.exports = DecoratorManager module.exports.default = DecoratorManager