PageSourceSearch

https://mylibraryworld.web.app/assets/epubjs/lib/annotations.js

js mylibraryworld.web.app collected 2026-10-03 12:32:56 UTC 10,059 bytes, 387 lines download raw bytes

vendor: 6,242 bytes, lines 1-212
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4	value: true
5});
6
7var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
9var _eventEmitter = require("event-emitter");
10
11var _eventEmitter2 = _interopRequireDefault(_eventEmitter);
12
13var _epubcfi = require("./epubcfi");
14
15var _epubcfi2 = _interopRequireDefault(_epubcfi);
16
17var _constants = require("./utils/constants");
18
19function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
21function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22
23/**
24	* Handles managing adding & removing Annotations
25	* @param {Rendition} rendition
26	* @class
27	*/
28var Annotations = function () {
29	function Annotations(rendition) {
30		_classCallCheck(this, Annotations);
31
32		this.rendition = rendition;
33		this.highlights = [];
34		this.underlines = [];
35		this.marks = [];
36		this._annotations = {};
37		this._annotationsBySectionIndex = {};
38
39		this.rendition.hooks.render.register(this.inject.bind(this));
40		this.rendition.hooks.unloaded.register(this.clear.bind(this));
41	}
42
43	/**
44  * Add an annotation to store
45  * @param {string} type Type of annotation to add: "highlight", "underline", "mark"
46  * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
47  * @param {object} data Data to assign to annotation
48  * @param {function} [cb] Callback after annotation is added
49  * @param {string} className CSS class to assign to annotation
50  * @param {object} styles CSS styles to assign to annotation
51  * @returns {Annotation} annotation
52  */
53
54
55	_createClass(Annotations, [{
56		key: "add",
57		value: function add(type, cfiRange, data, cb, className, styles) {
58			var hash = encodeURI(cfiRange + type);
59			var cfi = new _epubcfi2.default(cfiRange);
60			var sectionIndex = cfi.spinePos;
61			var annotation = new Annotation({
62				type: type,
63				cfiRange: cfiRange,
64				data: data,
65				sectionIndex: sectionIndex,
66				cb: cb,
67				className: className,
68				styles: styles
69			});
70
71			this._annotations[hash] = annotation;
72
73			if (sectionIndex in this._annotationsBySectionIndex) {
74				this._annotationsBySectionIndex[sectionIndex].push(hash);
75			} else {
76				this._annotationsBySectionIndex[sectionIndex] = [hash];
77			}
78
79			var views = this.rendition.views();
80
81			views.forEach(function (view) {
82				if (annotation.sectionIndex === view.index) {
83					annotation.attach(view);
84				}
85			});
86
87			return annotation;
88		}
89
90		/**
91   * Remove an annotation from store
92   * @param {EpubCFI} cfiRange EpubCFI range the annotation is attached to
93   * @param {string} type Type of annotation to add: "highlight", "underline", "mark"
94   */
95
96	}, {
97		key: "remove",
98		value: function remove(cfiRange, type) {
99			var _this = this;
100
101			var hash = encodeURI(cfiRange + type);
102
103			if (hash in this._annotations) {
104				var annotation = this._annotations[hash];
105
106				if (type && annotation.type !== type) {
107					return;
108				}
109
110				var views = this.rendition.views();
111				views.forEach(function (view) {
112					_this._removeFromAnnotationBySectionIndex(annotation.sectionIndex, hash);
113					if (annotation.sectionIndex === view.index) {
114						annotation.detach(view);
115					}
116				});
117
118				delete this._annotations[hash];
119			}
120		}
121
122		/**
123   * Remove an annotations by Section Index
124   * @private
125   */
126
127	}, {
128		key: "_removeFromAnnotationBySectionIndex",
129		value: function _removeFromAnnotationBySectionIndex(sectionIndex, hash) {
130			this._annotationsBySectionIndex[sectionIndex] = this._annotationsAt(sectionIndex).filter(function (h) {
131				return h !== hash;
132			});
133		}
134
135		/**
136   * Get annotations by Section Index
137   * @private
138   */
139
140	}, {
141		key: "_annotationsAt",
142		value: function _annotationsAt(index) {
143			return this._annotationsBySectionIndex[index];
144		}
145
146		/**
147   * Add a highlight to the store
148   * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
149   * @param {object} data Data to assign to annotation
150   * @param {function} cb Callback after annotation is clicked
151   * @param {string} className CSS class to assign to annotation
152   * @param {object} styles CSS styles to assign to annotation
153   */
154
155	}, {
156		key: "highlight",
157		value: function highlight(cfiRange, data, cb, className, styles) {
158			return this.add("highlight", cfiRange, data, cb, className, styles);
159		}
160
161		/**
162   * Add a underline to the store
163   * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
164   * @param {object} data Data to assign to annotation
165   * @param {function} cb Callback after annotation is clicked
166   * @param {string} className CSS class to assign to annotation
167   * @param {object} styles CSS styles to assign to annotation
168   */
169
170	}, {
171		key: "underline",
172		value: function underline(cfiRange, data, cb, className, styles) {
173			return this.add("underline", cfiRange, data, cb, className, styles);
174		}
175
176		/**
177   * Add a mark to the store
178   * @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
179   * @param {object} data Data to assign to annotation
180   * @param {function} cb Callback after annotation is clicked
181   */
182
183	}, {
184		key: "mark",
185		value: function mark(cfiRange, data, cb) {
186			return this.add("mark", cfiRange, data, cb);
187		}
188
189		/**
190   * iterate over annotations in the store
191   */
192
193	}, {
194		key: "each",
195		value: function each() {
196			return this._annotations.forEach.apply(this._annotations, arguments);
197		}
198
199		/**
200   * Hook for injecting annotation into a view
201   * @param {View} view
202   * @private
203   */
204
205	}, {
206		key: "inject",
207		value: function inject(view) {
208			var _this2 = this;
209
210			var sectionIndex = view.index;
211			if (sectionIndex in this._annotationsBySectionIndex) {
212				var annotations = this._annotationsBySectionIndex[sectionIndex];
213				annotations.forEach(function (hash) {
214					var annotation = _this2._annotations[hash];
215					annotation.attach(view);
216				});
217			}
218		}
219
220		/**
221   * Hook for removing annotation from a view
222   * @param {View} view
223   * @private
224   */
225
226	}, {
227		key: "clear",
228		value: function clear(view) {
229			var _this3 = this;
230
231			var sectionIndex = view.index;
232			if (sectionIndex in this._annotationsBySectionIndex) {
233				var annotations = this._annotationsBySectionIndex[sectionIndex];
234				annotations.forEach(function (hash) {
235					var annotation = _this3._annotations[hash];
236					annotation.detach(view);
237				});
238			}
239		}
240
241		/**
242   * [Not Implemented] Show annotations
243   * @TODO: needs implementation in View
244   */
245
246	}, {
247		key: "show",
248		value: function show() {}
249
250		/**
251   * [Not Implemented] Hide annotations
252   * @TODO: needs implementation in View
253   */
254
255	}, {
256		key: "hide",
257		value: function hide() {}
258	}]);
259
260	return Annotations;
261}();
262
263/**
264 * Annotation object
265 * @class
266 * @param {object} options
267 * @param {string} options.type Type of annotation to add: "highlight", "underline", "mark"
268 * @param {EpubCFI} options.cfiRange EpubCFI range to attach annotation to
269 * @param {object} options.data Data to assign to annotation
270 * @param {int} options.sectionIndex Index in the Spine of the Section annotation belongs to
271 * @param {function} [options.cb] Callback after annotation is clicked
272 * @param {string} className CSS class to assign to annotation
273 * @param {object} styles CSS styles to assign to annotation
274 * @returns {Annotation} annotation
275 */
276
277
278var Annotation = function () {
279	function Annotation(_ref) {
280		var type = _ref.type,
281		    cfiRange = _ref.cfiRange,
282		    data = _ref.data,
283		    sectionIndex = _ref.sectionIndex,
284		    cb = _ref.cb,
285		    className = _ref.className,
286		    styles = _ref.styles;
287
288		_classCallCheck(this, Annotation);
289
290		this.type = type;
291		this.cfiRange = cfiRange;
292		this.data = data;
293		this.sectionIndex = sectionIndex;
294		this.mark = undefined;
295		this.cb = cb;
296		this.className = className;
297		this.styles = styles;
298	}
299
300	/**
301  * Update stored data
302  * @param {object} data
303  */
304
305
306	_createClass(Annotation, [{
307		key: "update",
308		value: function update(data) {
309			this.data = data;
310		}
311
312		/**
313   * Add to a view
314   * @param {View} view
315   */
316
317	}, {
318		key: "attach",
319		value: function attach(view) {
320			var cfiRange = this.cfiRange,
321			    data = this.data,
322			    type = this.type,
323			    mark = this.mark,
324			    cb = this.cb,
325			    className = this.className,
326			    styles = this.styles;
327
328			var result = void 0;
329
330			if (type === "highlight") {
331				result = view.highlight(cfiRange, data, cb, className, styles);
332			} else if (type === "underline") {
333				result = view.underline(cfiRange, data, cb, className, styles);
334			} else if (type === "mark") {
335				result = view.mark(cfiRange, data, cb);
336			}
337
338			this.mark = result;
339			this.emit(_constants.EVENTS.ANNOTATION.ATTACH, result);
340			return result;
341		}
342
343		/**
344   * Remove from a view
345   * @param {View} view
346   */
347
348	}, {
349		key: "detach",
350		value: function detach(view) {
351			var cfiRange = this.cfiRange,
352			    type = this.type;
353
354			var result = void 0;
355
356			if (view) {
357				if (type === "highlight") {
358					result = view.unhighlight(cfiRange);
359				} else if (type === "underline") {
360					result = view.ununderline(cfiRange);
361				} else if (type === "mark") {
362					result = view.unmark(cfiRange);
363				}
364			}
365
366			this.mark = undefined;
367			this.emit(_constants.EVENTS.ANNOTATION.DETACH, result);
368			return result;
369		}
370
371		/**
372   * [Not Implemented] Get text of an annotation
373   * @TODO: needs implementation in contents
374   */
375
376	}, {
377		key: "text",
378		value: function text() {}
379	}]);
380
381	return Annotation;
382}();
383
384(0, _eventEmitter2.default)(Annotation.prototype);
385
386exports.default = Annotations;
387module.exports = exports["default"];

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.