Skip to content

Commit

Permalink
EPUB: Fix page swipes while selecting text (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
mickael-menu authored Aug 16, 2022
1 parent 33e5b92 commit 92fd6e8
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ All notable changes to this project will be documented in this file. Take a look
* [swift-toolkit#61](https://github.com/readium/swift-toolkit/issues/61) Fixed serving EPUB resources when the HREF contains an anchor or query parameters.
* Fixed emitting `currentLocator` with fixed layout EPUBs.
* Prevent refreshing an already loaded EPUB resource when jumping to a `Locator` in it.
* [#86](https://github.com/readium/kotlin-toolkit/issues/86) Fixed page swipes while selecting text in an EPUB resource.
* The `onTap` event is not sent when an EPUB text selection is active anymore, to prevent showing the app bar while dismissing a selection.


## [2.2.0]
Expand Down
24 changes: 23 additions & 1 deletion readium/navigator/src/main/assets/_scripts/src/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// available in the top-level LICENSE file of the project.
//

import { log as logNative, logError } from "./utils";
import { log as logNative, logError, snapCurrentOffset } from "./utils";
import { toNativeRect } from "./rect";
import { TextRange } from "./vendor/hypothesis/anchoring/text-range";

Expand All @@ -14,6 +14,28 @@ matchAll.shim();

const debug = true;

// Notify native code that the selection changes.
window.addEventListener(
"load",
function () {
var isSelecting = false;
document.addEventListener("selectionchange", function () {
const collapsed = window.getSelection().isCollapsed;

if (collapsed && isSelecting) {
isSelecting = false;
Android.onSelectionEnd();
// Snaps the current column in case the user shifted the scroll by dragging the text selection.
snapCurrentOffset();
} else if (!collapsed && !isSelecting) {
isSelecting = true;
Android.onSelectionStart();
}
});
},
false
);

export function getCurrentSelection() {
const text = getCurrentSelectionText();
if (!text) {
Expand Down
3 changes: 1 addition & 2 deletions readium/navigator/src/main/assets/_scripts/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ window.addEventListener(
false
);

// Notify native code that the page has loaded.
window.addEventListener(
"load",
function () {
Expand Down Expand Up @@ -220,7 +219,7 @@ function snapOffset(offset) {
}

// Snaps the current offset to the page width.
function snapCurrentOffset() {
export function snapCurrentOffset() {
// Android.log("snapCurrentOffset");
if (isScrollModeEnabled()) {
return;
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
var resourceUrl: String? = null

internal val scrollModeFlow = MutableStateFlow(false)

/** Indicates that a user text selection is active. */
internal var isSelecting = false

val scrollMode: Boolean get() = scrollModeFlow.value

Expand Down Expand Up @@ -224,6 +227,11 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
*/
@android.webkit.JavascriptInterface
fun onTap(eventJson: String): Boolean {
// If there's an on-going selection, the tap will dismiss it so we don't forward it.
if (isSelecting) {
return false
}

val event = TapEvent.fromJSON(eventJson) ?: return false

// The script prevented the default behavior.
Expand Down Expand Up @@ -393,6 +401,16 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
return runBlocking(uiScope.coroutineContext) { listener.onDragEnd(event) }
}

@android.webkit.JavascriptInterface
fun onSelectionStart() {
isSelecting = true
}

@android.webkit.JavascriptInterface
fun onSelectionEnd() {
isSelecting = false
}

/** Produced by gestures.js */
data class DragEvent(
val defaultPrevented: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,13 +688,12 @@ class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView(context,
mActivePointerId = ev.getPointerId(0)
}
MotionEvent.ACTION_MOVE -> {

if ((mLastMotionX > (width - mGutterSize)) || (mLastMotionX < mGutterSize)) {
requestDisallowInterceptTouchEvent(true)
return false
}

if (!mIsBeingDragged) {
if (!isSelecting && !mIsBeingDragged) {
mInitialVelocity = getCurrentXVelocity()
val pointerIndex = ev.findPointerIndex(mActivePointerId)
val x = ev.getX(pointerIndex)
Expand Down

0 comments on commit 92fd6e8

Please sign in to comment.