From 0d5417646a93d7376f5721f10a949f92c670f4cb Mon Sep 17 00:00:00 2001 From: Mikkel Vester Petersen Date: Thu, 5 Jul 2018 10:57:21 +0200 Subject: [PATCH] Custom CSS for annotations Annotations can be created with a CSS class and CSS attributes. Adds the possibility to have multiple annotations with difference styles/colors. --- src/annotations.js | 34 ++++++++++++++++++++++++---------- src/managers/views/iframe.js | 16 +++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/annotations.js b/src/annotations.js index a0349c0..ecbec8a 100644 --- a/src/annotations.js +++ b/src/annotations.js @@ -26,9 +26,11 @@ class Annotations { * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to * @param {object} data Data to assign to annotation * @param {function} [cb] Callback after annotation is added + * @param {string} className CSS class to assign to annotation + * @param {object} styles CSS styles to assign to annotation * @returns {Annotation} annotation */ - add (type, cfiRange, data, cb) { + add (type, cfiRange, data, cb, className, styles) { let hash = encodeURI(cfiRange); let cfi = new EpubCFI(cfiRange); let sectionIndex = cfi.spinePos; @@ -37,7 +39,9 @@ class Annotations { cfiRange, data, sectionIndex, - cb + cb, + className, + styles }); this._annotations[hash] = annotation; @@ -108,9 +112,11 @@ class Annotations { * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to * @param {object} data Data to assign to annotation * @param {function} cb Callback after annotation is added + * @param {string} className CSS class to assign to annotation + * @param {object} styles CSS styles to assign to annotation */ - highlight (cfiRange, data, cb) { - this.add("highlight", cfiRange, data, cb); + highlight (cfiRange, data, cb, className, styles) { + this.add("highlight", cfiRange, data, cb, className, styles); } /** @@ -118,9 +124,11 @@ class Annotations { * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to * @param {object} data Data to assign to annotation * @param {function} cb Callback after annotation is added + * @param {string} className CSS class to assign to annotation + * @param {object} styles CSS styles to assign to annotation */ - underline (cfiRange, data, cb) { - this.add("underline", cfiRange, data, cb); + underline (cfiRange, data, cb, className, styles) { + this.add("underline", cfiRange, data, cb, className, styles); } /** @@ -199,6 +207,8 @@ class Annotations { * @param {object} options.data Data to assign to annotation * @param {int} options.sectionIndex Index in the Spine of the Section annotation belongs to * @param {function} [options.cb] Callback after annotation is added + * @param {string} className CSS class to assign to annotation + * @param {object} styles CSS styles to assign to annotation * @returns {Annotation} annotation */ class Annotation { @@ -208,7 +218,9 @@ class Annotation { cfiRange, data, sectionIndex, - cb + cb, + className, + styles }) { this.type = type; this.cfiRange = cfiRange; @@ -216,6 +228,8 @@ class Annotation { this.sectionIndex = sectionIndex; this.mark = undefined; this.cb = cb; + this.className = className; + this.styles = styles; } /** @@ -231,13 +245,13 @@ class Annotation { * @param {View} view */ attach (view) { - let {cfiRange, data, type, mark, cb} = this; + let {cfiRange, data, type, mark, cb, className, styles} = this; let result; if (type === "highlight") { - result = view.highlight(cfiRange, data, cb); + result = view.highlight(cfiRange, data, cb, className, styles); } else if (type === "underline") { - result = view.underline(cfiRange, data, cb); + result = view.underline(cfiRange, data, cb, className, styles); } else if (type === "mark") { result = view.mark(cfiRange, data, cb); } diff --git a/src/managers/views/iframe.js b/src/managers/views/iframe.js index 6596f8f..0affa48 100644 --- a/src/managers/views/iframe.js +++ b/src/managers/views/iframe.js @@ -543,10 +543,11 @@ class IframeView { return this.elementBounds; } - highlight(cfiRange, data={}, cb) { + highlight(cfiRange, data={}, cb, className = "epubjs-hl", styles = {}) { if (!this.contents) { return; } + const attributes = Object.assign({"fill": "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply"}, styles); let range = this.contents.range(cfiRange); let emitter = () => { @@ -559,12 +560,12 @@ class IframeView { this.pane = new Pane(this.iframe, this.element); } - let m = new Highlight(range, "epubjs-hl", data, {'fill': 'yellow', 'fill-opacity': '0.3', 'mix-blend-mode': 'multiply'}); + let m = new Highlight(range, className, data, attributes); let h = this.pane.addMark(m); this.highlights[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] }; - h.element.setAttribute("ref", "epubjs-hl"); + h.element.setAttribute("ref", className); h.element.addEventListener("click", emitter); h.element.addEventListener("touchstart", emitter); @@ -575,10 +576,11 @@ class IframeView { return h; } - underline(cfiRange, data={}, cb) { + underline(cfiRange, data={}, cb, className = "epubjs-ul", styles = {}) { if (!this.contents) { return; } + const attributes = Object.assign({"stroke": "black", "stroke-opacity": "0.3", "mix-blend-mode": "multiply"}, styles); let range = this.contents.range(cfiRange); let emitter = () => { this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data); @@ -590,12 +592,12 @@ class IframeView { this.pane = new Pane(this.iframe, this.element); } - let m = new Underline(range, "epubjs-ul", data, {'stroke': 'black', 'stroke-opacity': '0.3', 'mix-blend-mode': 'multiply'}); + let m = new Underline(range, className, data, attributes); let h = this.pane.addMark(m); this.underlines[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] }; - h.element.setAttribute("ref", "epubjs-ul"); + h.element.setAttribute("ref", className); h.element.addEventListener("click", emitter); h.element.addEventListener("touchstart", emitter); @@ -658,7 +660,7 @@ class IframeView { } - let mark = this.document.createElement('a'); + let mark = this.document.createElement("a"); mark.setAttribute("ref", "epubjs-mk"); mark.style.position = "absolute"; mark.style.top = `${top}px`;