@chegg-ereader/viewer-utils 1.0.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @chegg-ereader/viewer-utils might be problematic. Click here for more details.
- package/LICENSE +0 -0
- package/README.md +30 -0
- package/dist/esm/constants.js +54 -0
- package/dist/esm/modules/bridgeListener.js +18 -0
- package/dist/esm/modules/ePubStyleManager/types.js +8 -0
- package/dist/esm/modules/keyboard_manager.js +67 -0
- package/dist/esm/modules/resizeMonitor.js +73 -0
- package/dist/esm/modules/swipeNavigation/swipeEvents.js +99 -0
- package/dist/esm/modules/touchDetector.js +85 -0
- package/dist/esm/modules/types.js +16 -0
- package/dist/esm/payloads.js +8 -0
- package/package.json +20 -0
package/LICENSE
ADDED
File without changes
|
package/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# @chegg-ereader/viewer-utils
|
2
|
+
|
3
|
+
A base viewer utils for ereader.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- ES6 syntax
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
```sh
|
12
|
+
yarn add @chegg-ereader/viewer-utils
|
13
|
+
// or
|
14
|
+
npm i @chegg-ereader/viewer-utils
|
15
|
+
```
|
16
|
+
|
17
|
+
### Requirements
|
18
|
+
|
19
|
+
- Node.js `v12.x` or later
|
20
|
+
|
21
|
+
|
22
|
+
### Usage
|
23
|
+
|
24
|
+
```js
|
25
|
+
import { registerResizeMonitor } from '@chegg-ereader/viewer-utils';
|
26
|
+
|
27
|
+
registerResizeMonitor.addListener((newSize) => {
|
28
|
+
handleSizeChange(newSize);
|
29
|
+
});
|
30
|
+
```
|
@@ -0,0 +1,54 @@
|
|
1
|
+
export var EVENT_VIEWER_READY = "onViewerReady";
|
2
|
+
export var EVENT_PDF_PAGE_OPEN = "onPdfPageOpen";
|
3
|
+
export var EVENT_PDF_PAGE_LOADED = "onPdfPageLoaded";
|
4
|
+
export var EVENT_EPUB_PAGE_OPEN = "onEpubPageOpen";
|
5
|
+
export var EVENT_EPUB_PAGE_LOADED = "onEpubPageLoaded";
|
6
|
+
export var EVENT_READABLES_READY = "onReadablesReady";
|
7
|
+
export var EVENT_ON_USER_SELECTION = "onUserSelection";
|
8
|
+
export var EVENT_SELECTION_CLICKED = "onSelectionClicked";
|
9
|
+
export var EVENT_CONTEXT_MENU = "onContextMenu";
|
10
|
+
export var EVENT_USER_SELECT_START = "onUserSelectStart";
|
11
|
+
export var EVENT_USER_SELECT_END = "onUserSelectEnd";
|
12
|
+
export var EVENT_CHAPTER_OPEN = "onChapterOpen";
|
13
|
+
export var EVENT_CHAPTER_OPENED = "onChapterOpened";
|
14
|
+
export var EVENT_NAVIGATION = "onNavigation";
|
15
|
+
export var EVENT_ON_TAP = "onTap";
|
16
|
+
export var EVENT_KEYBOARD_PRESS = "onKeyboardPress";
|
17
|
+
export var EVENT_CONTENT_BACKGROUND_SCROLL = "onContentBackgroundScroll";
|
18
|
+
export var EVENT_USER_INTERACTION = "onUserInteraction";
|
19
|
+
export var EVENT_VIEWER_NAVIGATION = "onViewerNavigation";
|
20
|
+
export var EVENT_VIEWER_PAGE_NAVIGATION = "onViewerPageNavigation";
|
21
|
+
export var EVENT_TBS_PROBLEM_CLICKED = "onTbsProblemClicked";
|
22
|
+
export var ACTION_INIT = "init";
|
23
|
+
export var ACTION_CREATE_HIGHLIGHT = "createHighlight";
|
24
|
+
export var ACTION_REMOVE_HIGHLIGHT = "removeHighlight";
|
25
|
+
export var ACTION_OPEN_PAGE = "openPage";
|
26
|
+
export var ACTION_OPEN_LOCATION = "openLocation";
|
27
|
+
export var ACTION_DESELECT = "deselect";
|
28
|
+
export var ACTION_SET_FONT_TYPE = "setFontFamily";
|
29
|
+
export var ACTION_SET_FONT_SIZE = "setFontSize";
|
30
|
+
export var ACTION_LOAD_HIGHLIGHTS = "loadHighlights";
|
31
|
+
export var ACTION_LOAD_SEARCH_HIGHLIGHTS = "loadSearchHighlights";
|
32
|
+
export var ACTION_REMOVE_SEARCH_HIGHLIGHTS = "removeSearchHighlights";
|
33
|
+
export var ACTION_SCROLL_TO_PAGE = "scrollToPage";
|
34
|
+
export var ACTION_SCROLL_TO_ANCHOR = "scrollToAnchor";
|
35
|
+
export var ACTION_OPEN_CHAPTER = "openChapter";
|
36
|
+
export var ACTION_NAVIGATE_NEXT = "navigateNext";
|
37
|
+
export var ACTION_NAVIGATE_PREV = "navigatePrev";
|
38
|
+
export var ACTION_SET_ZOOM_LEVEL = "setZoomLevel";
|
39
|
+
export var ACTION_ADD_KEYBOARD_LISTENER = "addKeyboardListener";
|
40
|
+
export var ACTION_REMOVE_KEYBOARD_LISTENER = "removeKeyboardListener";
|
41
|
+
export var ACTION_CHECK_READY = "checkViewerReader";
|
42
|
+
export var ERROR_CONTENT_LOAD = "onContentLoadError";
|
43
|
+
export var EVENT_NOTE_ICON_CLICK = "onNoteIconClick";
|
44
|
+
export var EVENT_NOTE_GROUP_CLICK = "onNoteGroupClick";
|
45
|
+
export var ACTION_CREATE_SPEECH_HIGHLIGHT = "createSpeechHighlight";
|
46
|
+
export var ACTION_REMOVE_SPEECH_HIGHLIGHT = "removeSpeechHighlight";
|
47
|
+
export var ACTION_LOAD_TBS = "loadTbs";
|
48
|
+
export var MODIFIERS = {
|
49
|
+
CTRL: "ctrlKey",
|
50
|
+
CMD: "metaKey",
|
51
|
+
SHIFT: "shiftKey",
|
52
|
+
ALT: "altKey"
|
53
|
+
};
|
54
|
+
export var IGNORE_PROPERTY = "data-ignore-touch-detection";
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { bridge } from "@chegg-ereader/bridge";
|
2
|
+
export { triggerBridgeEvent, listenBridgeEvent, addBridgeListeners };
|
3
|
+
|
4
|
+
function listenBridgeEvent(type, cb) {
|
5
|
+
bridge.listen(type, function (payload, done) {
|
6
|
+
var type = payload.type,
|
7
|
+
params = payload.params;
|
8
|
+
cb(payload, done);
|
9
|
+
});
|
10
|
+
}
|
11
|
+
|
12
|
+
function addBridgeListeners(map) {
|
13
|
+
bridge.addListeners(map);
|
14
|
+
}
|
15
|
+
|
16
|
+
function triggerBridgeEvent(payload) {
|
17
|
+
bridge.trigger(payload);
|
18
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { MODIFIERS } from "../constants";
|
2
|
+
var $registered = false;
|
3
|
+
var $listeners;
|
4
|
+
var $id = 0;
|
5
|
+
var modifier_names = Object.keys(MODIFIERS).map(function (key) {
|
6
|
+
return MODIFIERS[key];
|
7
|
+
});
|
8
|
+
export { resetKeyboardListener, addKeyboardListener };
|
9
|
+
resetKeyboardListener();
|
10
|
+
|
11
|
+
function addKeyboardListener(_ref) {
|
12
|
+
var key = _ref.key,
|
13
|
+
modifier = _ref.modifier,
|
14
|
+
onShortcut = _ref.onShortcut,
|
15
|
+
prevent = _ref.prevent;
|
16
|
+
var id = "listener-".concat($id++);
|
17
|
+
register();
|
18
|
+
listener.$cb_id = id;
|
19
|
+
$listeners.push(listener);
|
20
|
+
return id;
|
21
|
+
|
22
|
+
function listener(e) {
|
23
|
+
var is_mac = navigator.platform.indexOf("Mac") > -1;
|
24
|
+
|
25
|
+
if (modifier) {
|
26
|
+
if (modifier == MODIFIERS.CMD && !is_mac) {
|
27
|
+
modifier = MODIFIERS.CTRL;
|
28
|
+
}
|
29
|
+
|
30
|
+
if (!e[modifier]) {
|
31
|
+
return;
|
32
|
+
}
|
33
|
+
} else {
|
34
|
+
for (var i = 0, _modifier; _modifier = modifier_names[i]; i++) {
|
35
|
+
// @ts-ignore
|
36
|
+
if (e[_modifier]) {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if (e.key === key) {
|
43
|
+
onShortcut(e);
|
44
|
+
}
|
45
|
+
|
46
|
+
if (prevent) {
|
47
|
+
e.preventDefault();
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
function resetKeyboardListener() {
|
53
|
+
$registered = false;
|
54
|
+
$listeners = [];
|
55
|
+
}
|
56
|
+
|
57
|
+
function register() {
|
58
|
+
if ($registered) return;
|
59
|
+
$registered = true;
|
60
|
+
window.addEventListener("keyup", listener);
|
61
|
+
}
|
62
|
+
|
63
|
+
function listener(e) {
|
64
|
+
$listeners.forEach(function (listener) {
|
65
|
+
listener(e);
|
66
|
+
});
|
67
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
export { __reset, registerResizeMonitor, addOnEnd, addConstant };
|
2
|
+
var $listeners = {
|
3
|
+
constant: [],
|
4
|
+
onEnd: []
|
5
|
+
};
|
6
|
+
var $handle;
|
7
|
+
var $registered = false; //@ts-ignore
|
8
|
+
|
9
|
+
var $last_width = global.innerWidth || 0; //@ts-ignore
|
10
|
+
|
11
|
+
var $last_height = global.innerHeight || 0;
|
12
|
+
|
13
|
+
function __reset() {
|
14
|
+
$registered = false;
|
15
|
+
$listeners.constant = [];
|
16
|
+
$listeners.onEnd = [];
|
17
|
+
}
|
18
|
+
|
19
|
+
function addOnEnd(cb) {
|
20
|
+
$listeners.onEnd.push(cb);
|
21
|
+
return function unregister() {
|
22
|
+
var index = $listeners.onEnd.indexOf(cb);
|
23
|
+
|
24
|
+
if (index > -1) {
|
25
|
+
$listeners.onEnd.splice(index, 1);
|
26
|
+
}
|
27
|
+
};
|
28
|
+
}
|
29
|
+
|
30
|
+
function addConstant(cb) {
|
31
|
+
$listeners.constant.push(cb);
|
32
|
+
return function unregister() {
|
33
|
+
var index = $listeners.constant.indexOf(cb);
|
34
|
+
|
35
|
+
if (index > -1) {
|
36
|
+
$listeners.constant.splice(index, 1);
|
37
|
+
}
|
38
|
+
};
|
39
|
+
}
|
40
|
+
|
41
|
+
function registerResizeMonitor() {
|
42
|
+
if ($registered) return;
|
43
|
+
|
44
|
+
if (!("addEventListener" in global)) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
window.addEventListener("resize", listener);
|
49
|
+
window.addEventListener("orientationchange", listener);
|
50
|
+
$registered = true;
|
51
|
+
}
|
52
|
+
|
53
|
+
function listener() {
|
54
|
+
clearTimeout($handle);
|
55
|
+
$handle = setTimeout(function () {
|
56
|
+
if (window.innerWidth === $last_width && window.innerHeight === $last_height) {
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
|
60
|
+
$last_width = window.innerWidth;
|
61
|
+
$last_height = window.innerHeight;
|
62
|
+
onEnd();
|
63
|
+
$listeners.constant.forEach(function (listener) {
|
64
|
+
window.requestAnimationFrame(listener);
|
65
|
+
});
|
66
|
+
}, 500);
|
67
|
+
}
|
68
|
+
|
69
|
+
function onEnd() {
|
70
|
+
$listeners.onEnd.forEach(function (listener) {
|
71
|
+
window.requestAnimationFrame(listener);
|
72
|
+
});
|
73
|
+
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
export { initSwipeEvents };
|
2
|
+
var START = "touchstart";
|
3
|
+
var END = "touchend";
|
4
|
+
/*
|
5
|
+
these values are derived from the default values
|
6
|
+
of Hammerjs
|
7
|
+
*/
|
8
|
+
|
9
|
+
var MIN_DISTANCE = 10;
|
10
|
+
var MIN_VELOCITY = 0.3;
|
11
|
+
var MAX_DELTA_Y = 60;
|
12
|
+
var $active;
|
13
|
+
var $start_time;
|
14
|
+
var $start_x;
|
15
|
+
var $start_y;
|
16
|
+
resetParams();
|
17
|
+
export var SWIPE_DIRECTIONS;
|
18
|
+
|
19
|
+
(function (SWIPE_DIRECTIONS) {
|
20
|
+
SWIPE_DIRECTIONS[SWIPE_DIRECTIONS["LEFT"] = 0] = "LEFT";
|
21
|
+
SWIPE_DIRECTIONS[SWIPE_DIRECTIONS["RIGHT"] = 1] = "RIGHT";
|
22
|
+
})(SWIPE_DIRECTIONS || (SWIPE_DIRECTIONS = {}));
|
23
|
+
|
24
|
+
function initSwipeEvents() {
|
25
|
+
document.addEventListener(START, start);
|
26
|
+
document.addEventListener(END, end);
|
27
|
+
|
28
|
+
if ('addEventListener' in global) {
|
29
|
+
window.addEventListener("orientationchange", function () {
|
30
|
+
document.removeEventListener(START, start);
|
31
|
+
document.removeEventListener(END, end);
|
32
|
+
document.addEventListener(START, start);
|
33
|
+
document.addEventListener(END, end);
|
34
|
+
});
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
function start(e) {
|
39
|
+
resetParams();
|
40
|
+
|
41
|
+
if (!e.touches || e.touches.length == 0) {
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
|
45
|
+
var touch = e.touches[0];
|
46
|
+
$start_time = Date.now();
|
47
|
+
$start_x = touch.clientX;
|
48
|
+
$start_y = touch.clientY;
|
49
|
+
$active = true;
|
50
|
+
}
|
51
|
+
|
52
|
+
function end(e) {
|
53
|
+
var selection = window.getSelection();
|
54
|
+
|
55
|
+
if (!$active || selection && !selection.isCollapsed) {
|
56
|
+
resetParams();
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
|
60
|
+
if (!e.changedTouches || e.changedTouches.length == 0) {
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
var changed_touch = e.changedTouches[0];
|
65
|
+
var time_delta = Date.now() - $start_time;
|
66
|
+
var delta_y = Math.abs(changed_touch.clientY - $start_y);
|
67
|
+
var distance = changed_touch.clientX - $start_x;
|
68
|
+
var velocity = distance / time_delta;
|
69
|
+
resetParams();
|
70
|
+
|
71
|
+
if (delta_y > MAX_DELTA_Y) {
|
72
|
+
return;
|
73
|
+
}
|
74
|
+
|
75
|
+
if (Math.abs(velocity) < MIN_VELOCITY) {
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
if (Math.abs(distance) < MIN_DISTANCE) {
|
80
|
+
return;
|
81
|
+
}
|
82
|
+
|
83
|
+
var direction = velocity > 0 ? SWIPE_DIRECTIONS.RIGHT : SWIPE_DIRECTIONS.LEFT;
|
84
|
+
var event = new CustomEvent("swipe", {
|
85
|
+
detail: {
|
86
|
+
direction: direction,
|
87
|
+
origEvent: e
|
88
|
+
}
|
89
|
+
});
|
90
|
+
console.log('dispatching');
|
91
|
+
document.dispatchEvent(event);
|
92
|
+
}
|
93
|
+
|
94
|
+
function resetParams() {
|
95
|
+
$active = false;
|
96
|
+
$start_time = 0;
|
97
|
+
$start_x = 0;
|
98
|
+
$start_y = 0;
|
99
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import { triggerBridgeEvent } from "./bridgeListener";
|
2
|
+
import { EVENT_USER_INTERACTION, IGNORE_PROPERTY } from "../constants";
|
3
|
+
export { registerTouchDetector, registerTouchDetectorListener, addTouchDectectorListener, removeTouchDetectorListener, resetTouchDetector, triggerTouchDetectorListeners, useIClick, checkIgnore };
|
4
|
+
var $listeners;
|
5
|
+
var $registered;
|
6
|
+
var $event = "click";
|
7
|
+
resetTouchDetector();
|
8
|
+
|
9
|
+
function useIClick() {
|
10
|
+
$event = "iclick";
|
11
|
+
}
|
12
|
+
|
13
|
+
function registerTouchDetector() {
|
14
|
+
if ($registered) return;
|
15
|
+
registerTouchDetectorListener();
|
16
|
+
addTouchDectectorListener(function () {
|
17
|
+
triggerBridgeEvent({
|
18
|
+
type: EVENT_USER_INTERACTION,
|
19
|
+
params: {}
|
20
|
+
});
|
21
|
+
});
|
22
|
+
}
|
23
|
+
|
24
|
+
function registerTouchDetectorListener() {
|
25
|
+
if ($registered) return; //@ts-ignore
|
26
|
+
|
27
|
+
if (!global.document) {
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
|
31
|
+
document.body.addEventListener($event, triggerTouchDetectorListeners);
|
32
|
+
$registered = true;
|
33
|
+
}
|
34
|
+
|
35
|
+
function triggerTouchDetectorListeners(e) {
|
36
|
+
var el = e && e.target;
|
37
|
+
var has_selection = window.getSelection && window.getSelection();
|
38
|
+
if (has_selection && has_selection.toString().length) return;
|
39
|
+
|
40
|
+
if (checkIgnore(el)) {
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
|
44
|
+
$listeners.forEach(function (cb) {
|
45
|
+
return cb({});
|
46
|
+
});
|
47
|
+
}
|
48
|
+
|
49
|
+
function addTouchDectectorListener(cb) {
|
50
|
+
$listeners.push(cb);
|
51
|
+
}
|
52
|
+
|
53
|
+
function removeTouchDetectorListener(cb) {
|
54
|
+
var index = $listeners.indexOf(cb);
|
55
|
+
|
56
|
+
if (index > -1) {
|
57
|
+
$listeners.splice(index, 1);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
function resetTouchDetector() {
|
62
|
+
$listeners = [];
|
63
|
+
$registered = false; //@ts-ignore
|
64
|
+
|
65
|
+
if (!global.document) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
document.body.removeEventListener($event, triggerTouchDetectorListeners);
|
70
|
+
}
|
71
|
+
|
72
|
+
function checkIgnore(el) {
|
73
|
+
var property = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : IGNORE_PROPERTY;
|
74
|
+
if (!el) return false;
|
75
|
+
|
76
|
+
do {
|
77
|
+
if (el.getAttribute && el.getAttribute(property)) {
|
78
|
+
return true;
|
79
|
+
}
|
80
|
+
|
81
|
+
el = el.parentNode;
|
82
|
+
} while (el && el != document.body);
|
83
|
+
|
84
|
+
return false;
|
85
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
export * from './ePubStyleManager/types';
|
2
|
+
export * from './swipeNavigation/types';
|
3
|
+
import { ACTION_ADD_KEYBOARD_LISTENER, ACTION_CREATE_HIGHLIGHT, ACTION_DESELECT, ACTION_LOAD_HIGHLIGHTS, ACTION_LOAD_SEARCH_HIGHLIGHTS, ACTION_REMOVE_SEARCH_HIGHLIGHTS, ACTION_OPEN_PAGE, ACTION_OPEN_LOCATION, ACTION_REMOVE_HIGHLIGHT, ACTION_SET_FONT_TYPE, ACTION_SET_ZOOM_LEVEL, ACTION_SET_FONT_SIZE, ACTION_INIT, ACTION_NAVIGATE_NEXT, ACTION_NAVIGATE_PREV, ACTION_CHECK_READY, ACTION_CREATE_SPEECH_HIGHLIGHT, ACTION_REMOVE_SPEECH_HIGHLIGHT, ACTION_LOAD_TBS } from "../constants";
|
4
|
+
export var IMAGE_SIZE;
|
5
|
+
|
6
|
+
(function (IMAGE_SIZE) {
|
7
|
+
IMAGE_SIZE["SM"] = "SM";
|
8
|
+
IMAGE_SIZE["MED"] = "MED";
|
9
|
+
IMAGE_SIZE["LRG"] = "LRG";
|
10
|
+
})(IMAGE_SIZE || (IMAGE_SIZE = {}));
|
11
|
+
|
12
|
+
export var ImageSizes = {
|
13
|
+
768: IMAGE_SIZE.SM,
|
14
|
+
992: IMAGE_SIZE.MED,
|
15
|
+
1920: IMAGE_SIZE.LRG
|
16
|
+
};
|
package/package.json
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "@chegg-ereader/viewer-utils",
|
3
|
+
"version": "1.0.0-dev",
|
4
|
+
"private": false,
|
5
|
+
"description": "A base viewer utils for ereader.",
|
6
|
+
"license": "MIT",
|
7
|
+
"author": "hcheg-reader",
|
8
|
+
"main": "tsconfig.json",
|
9
|
+
"repository": "https://www.github.com/hcheg-reader/chegg-ereader/viewer-utils",
|
10
|
+
"scripts": {
|
11
|
+
"test": "exit 0"
|
12
|
+
},
|
13
|
+
"devDependencies": {
|
14
|
+
"@babel/core": "^7.18.10",
|
15
|
+
"@babel/cli": "^7.18.10"
|
16
|
+
},
|
17
|
+
"publishConfig": {
|
18
|
+
"access": "public"
|
19
|
+
}
|
20
|
+
}
|