Add text selection mixin

This mixin leverages HTML callbacks that can be set by WebView editor
to send text selection event to the composer so the composer will
receive text selection event necessary to display buttons related to
text selection.
This commit is contained in:
Théo Poizat
2025-12-04 17:00:08 +01:00
committed by Dat H. Pham
parent 2ccb203610
commit 4013973110
2 changed files with 151 additions and 0 deletions
+74
View File
@@ -48,6 +48,80 @@ class HtmlUtils {
editor.parentNode.replaceChild(newEditor, editor);''',
name: 'unregisterDropListener');
static const registerSelectionChangeListener = (
script: '''
let lastSelectedText = '';
document.addEventListener('selectionchange', function() {
const selection = window.getSelection();
const selectedText = selection ? selection.toString().trim() : '';
if (selectedText === lastSelectedText) {
return;
}
lastSelectedText = selectedText;
if (selectedText.length > 0 && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const rects = range.getClientRects();
if (rects.length > 0) {
const rect = rects[rects.length - 1];
// When iframe
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,
selectedText: selectedText,
coordinates: {
x: rect.right,
y: rect.bottom,
width: rect.width,
height: rect.height
}
});
}
}
} else {
// When iframe
if (window.parent) {
window.parent.postMessage(
JSON.stringify({
name: 'onSelectionChange',
hasSelection: false
}),
"*"
)
}
// When WebView
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('onSelectionChange', {
hasSelection: false
});
}
}
});''',
name: 'onSelectionChange');
static recalculateEditorHeight({double? maxHeight}) => (
script: '''
const editable = document.querySelector('.note-editable');