@snippetify/book-reader
Version:
Book reader utilities
147 lines (121 loc) • 3.73 kB
JavaScript
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