fixup! Add text selection mixin

This commit is contained in:
Théo Poizat
2025-12-08 09:52:58 +01:00
committed by Dat H. Pham
parent 4013973110
commit 8b17fcdc54
2 changed files with 35 additions and 44 deletions
+32 -43
View File
@@ -52,6 +52,24 @@ class HtmlUtils {
script: ''' script: '''
let lastSelectedText = ''; let lastSelectedText = '';
const sendSelectionChangeMessage = (data) => {
// When iframe
if (window.parent) {
window.parent.postMessage(
JSON.stringify({
...data,
name: 'onSelectionChange',
}),
"*"
)
}
// When WebView
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('onSelectionChange', data);
}
}
document.addEventListener('selectionchange', function() { document.addEventListener('selectionchange', function() {
const selection = window.getSelection(); const selection = window.getSelection();
const selectedText = selection ? selection.toString().trim() : ''; const selectedText = selection ? selection.toString().trim() : '';
@@ -62,33 +80,14 @@ class HtmlUtils {
lastSelectedText = selectedText; lastSelectedText = selectedText;
if (selectedText.length > 0 && selection.rangeCount > 0) { if (selectedText.length > 0 && selection.rangeCount > 0) {
const range = selection.getRangeAt(0); try {
const rects = range.getClientRects(); const range = selection.getRangeAt(0);
const rects = range.getClientRects();
if (rects.length > 0) { if (rects.length > 0) {
const rect = rects[rects.length - 1]; const rect = rects[rects.length - 1];
// When iframe sendSelectionChangeMessage({
if (window.parent) {
window.parent.postMessage(
JSON.stringify({
name: 'onSelectionChange',
hasSelection: true,
selectedText: selectedText,
coordinates: {
x: rect.right,
y: rect.bottom,
width: rect.width,
height: rect.height
}
}),
"*"
)
}
// When WebView
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('onSelectionChange', {
hasSelection: true, hasSelection: true,
selectedText: selectedText, selectedText: selectedText,
coordinates: { coordinates: {
@@ -97,27 +96,17 @@ class HtmlUtils {
width: rect.width, width: rect.width,
height: rect.height height: rect.height
} }
}); })
} }
} catch {
sendSelectionChangeMessage({
hasSelection: false
})
} }
} else { } else {
// When iframe sendSelectionChangeMessage({
if (window.parent) { hasSelection: false
window.parent.postMessage( })
JSON.stringify({
name: 'onSelectionChange',
hasSelection: false
}),
"*"
)
}
// When WebView
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('onSelectionChange', {
hasSelection: false
});
}
} }
});''', });''',
name: 'onSelectionChange'); name: 'onSelectionChange');
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef OnTextSelectionChanged = Function(TextSelectionData?);
class TextSelectionData { class TextSelectionData {
final bool hasSelection; final bool hasSelection;
final String? selectedText; final String? selectedText;
@@ -68,7 +70,7 @@ class TextSelectionCoordinates {
} }
mixin TextSelectionMixin<T extends StatefulWidget> on State<T> { mixin TextSelectionMixin<T extends StatefulWidget> on State<T> {
void Function(TextSelectionData?)? get onSelectionChanged => null; OnTextSelectionChanged? get onSelectionChanged => null;
void handleSelectionChange(Map<dynamic, dynamic> data) { void handleSelectionChange(Map<dynamic, dynamic> data) {
final selectionData = TextSelectionData.fromMap(data); final selectionData = TextSelectionData.fromMap(data);