Fix selection coordinates in mobile
Because the HTML editor is different, we need a different selector to get the editable element. We also need to add a small offset to the coordinates to avoid positionning the overlay icon above native selection UI in mobile. For example, Android adds a marker at the beginning and the end of the selection and we do not want to display the Scribe overlay icon above this marker.
This commit is contained in:
@@ -73,12 +73,15 @@ class HtmlUtils {
|
|||||||
name: 'unregisterDropListener');
|
name: 'unregisterDropListener');
|
||||||
|
|
||||||
static ({String name, String script}) registerSelectionChangeListener(
|
static ({String name, String script}) registerSelectionChangeListener(
|
||||||
String viewId,
|
String viewId, {
|
||||||
) =>
|
bool isWebPlatform = false,
|
||||||
|
}) =>
|
||||||
(
|
(
|
||||||
script: '''
|
script: '''
|
||||||
let lastSelectedText = '';
|
let lastSelectedText = '';
|
||||||
|
|
||||||
|
const isWebPlatform = $isWebPlatform;
|
||||||
|
|
||||||
const sendSelectionChangeMessage = (data) => {
|
const sendSelectionChangeMessage = (data) => {
|
||||||
// When iframe
|
// When iframe
|
||||||
if (window.parent) {
|
if (window.parent) {
|
||||||
@@ -101,10 +104,17 @@ class HtmlUtils {
|
|||||||
function getEditableFromSelection(selection) {
|
function getEditableFromSelection(selection) {
|
||||||
const node = selection?.focusNode || selection?.anchorNode;
|
const node = selection?.focusNode || selection?.anchorNode;
|
||||||
const el = node?.nodeType === Node.ELEMENT_NODE ? node : node?.parentElement;
|
const el = node?.nodeType === Node.ELEMENT_NODE ? node : node?.parentElement;
|
||||||
return (
|
|
||||||
el?.closest('.note-editor .note-editable') ||
|
if (isWebPlatform) {
|
||||||
document.querySelector('.note-editor .note-editable')
|
return (
|
||||||
);
|
el?.closest('.note-editor .note-editable') ||
|
||||||
|
document.querySelector('.note-editor .note-editable')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
el?.closest('#editor')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp(v, min, max) {
|
function clamp(v, min, max) {
|
||||||
@@ -142,9 +152,13 @@ class HtmlUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const lastRect = rects[rects.length - 1];
|
const lastRect = rects[rects.length - 1];
|
||||||
|
|
||||||
let x = lastRect.right - editableRect.left;
|
// Avoid native selection marks in mobile
|
||||||
let y = lastRect.bottom - editableRect.top;
|
// Offset has been arbitrary determined to avoid selection marks on Android and iOS
|
||||||
|
const buttonOffset = isWebPlatform ? { x: 0, y: 0 } : { x: 22, y: -20 };
|
||||||
|
|
||||||
|
let x = lastRect.right - editableRect.left + buttonOffset.x;
|
||||||
|
let y = lastRect.bottom - editableRect.top + buttonOffset.y;
|
||||||
|
|
||||||
const isInside =
|
const isInside =
|
||||||
lastRect.bottom >= editableRect.top &&
|
lastRect.bottom >= editableRect.top &&
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class _MobileEditorState extends State<MobileEditorWidget> with TextSelectionMix
|
|||||||
_editorController = editorApi.webViewController;
|
_editorController = editorApi.webViewController;
|
||||||
|
|
||||||
registerSelectionChange =
|
registerSelectionChange =
|
||||||
HtmlUtils.registerSelectionChangeListener(_createdViewId);
|
HtmlUtils.registerSelectionChangeListener(_createdViewId, isWebPlatform: PlatformInfo.isWeb);
|
||||||
|
|
||||||
_editorController?.addJavaScriptHandler(
|
_editorController?.addJavaScriptHandler(
|
||||||
handlerName: registerSelectionChange!.name,
|
handlerName: registerSelectionChange!.name,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/html/html_template.dart';
|
import 'package:core/utils/html/html_template.dart';
|
||||||
import 'package:core/utils/html/html_utils.dart';
|
import 'package:core/utils/html/html_utils.dart';
|
||||||
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:html_editor_enhanced/html_editor.dart';
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/mixin/text_selection_mixin.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/mixin/text_selection_mixin.dart';
|
||||||
@@ -104,7 +105,7 @@ class _WebEditorState extends State<WebEditorWidget> with TextSelectionMixin {
|
|||||||
_editorController = widget.editorController;
|
_editorController = widget.editorController;
|
||||||
|
|
||||||
final registerSelectionChange =
|
final registerSelectionChange =
|
||||||
HtmlUtils.registerSelectionChangeListener(_createdViewId);
|
HtmlUtils.registerSelectionChangeListener(_createdViewId, isWebPlatform: PlatformInfo.isWeb);
|
||||||
_selectionChangeScript = WebScript(
|
_selectionChangeScript = WebScript(
|
||||||
name: registerSelectionChange.name,
|
name: registerSelectionChange.name,
|
||||||
script: registerSelectionChange.script,
|
script: registerSelectionChange.script,
|
||||||
@@ -224,7 +225,7 @@ class _WebEditorState extends State<WebEditorWidget> with TextSelectionMixin {
|
|||||||
_editorController.evaluateJavascriptWeb(
|
_editorController.evaluateJavascriptWeb(
|
||||||
HtmlUtils.registerDropListener.name);
|
HtmlUtils.registerDropListener.name);
|
||||||
_editorController.evaluateJavascriptWeb(
|
_editorController.evaluateJavascriptWeb(
|
||||||
HtmlUtils.registerSelectionChangeListener(_createdViewId).name);
|
_selectionChangeScript.name);
|
||||||
_editorListenerRegistered = true;
|
_editorListenerRegistered = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user