Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPUB: Fix page swipes while selecting text #143

Merged
merged 2 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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