@chegg-ereader/viewer-utils 1.0.0-dev
Sign up to get free protection for your applications and to get access to all the features.
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
|
+
}
|