TF-3911 Remove window event listeners to prevent memory leaks in Email View

This commit is contained in:
dab246
2025-08-05 23:29:11 +07:00
committed by Dat H. Pham
parent fd7e349929
commit 846c9c6583
2 changed files with 52 additions and 31 deletions
@@ -141,7 +141,7 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb>
_handleHyperLinkEvent(data['url']); _handleHyperLinkEvent(data['url']);
} }
} catch (e) { } catch (e) {
logError('_HtmlContentViewerOnWebState::_handleMessageEvent:Exception = $e'); logError('$runtimeType::_handleMessageEvent:Exception = $e');
} }
} }
@@ -162,28 +162,32 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb>
dynamic data, dynamic data,
ScrollController controller, ScrollController controller,
) { ) {
final deltaY = data['deltaY'] ?? 0.0; try {
final target = controller.offset + deltaY; final deltaY = data['deltaY'] ?? 0.0;
final target = controller.offset + deltaY;
if (PlatformInfo.isWebTouchDevice) { if (PlatformInfo.isWebTouchDevice) {
final newOffset = target.clamp( final newOffset = target.clamp(
controller.position.minScrollExtent, controller.position.minScrollExtent,
controller.position.maxScrollExtent, controller.position.maxScrollExtent,
); );
controller.animateTo( controller.animateTo(
newOffset, newOffset,
duration: const Duration(milliseconds: 50), duration: const Duration(milliseconds: 50),
curve: Curves.linear, curve: Curves.linear,
); );
} else {
if (target < controller.position.minScrollExtent) {
controller.jumpTo(controller.position.minScrollExtent);
} else if (target > controller.position.maxScrollExtent) {
controller.jumpTo(controller.position.maxScrollExtent);
} else { } else {
controller.jumpTo(target); if (target < controller.position.minScrollExtent) {
controller.jumpTo(controller.position.minScrollExtent);
} else if (target > controller.position.maxScrollExtent) {
controller.jumpTo(controller.position.maxScrollExtent);
} else {
controller.jumpTo(target);
}
} }
} catch (e) {
logError('$runtimeType::_handleIframeOnScrollChangedListener:Exception = $e');
} }
} }
@@ -271,19 +275,23 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb>
} }
void _handleOnIFrameKeyboardEvent(dynamic data) { void _handleOnIFrameKeyboardEvent(dynamic data) {
final shortcut = KeyShortcut( try {
key: data['key'] as String, final shortcut = KeyShortcut(
code: data['code'] as String, key: data['key'] as String,
shift: data['shift'] == true, code: data['code'] as String,
); shift: data['shift'] == true,
log('_HtmlContentViewerOnWebState::_handleOnIFrameKeyboardEvent:📥 Shortcut pressed: $shortcut'); );
widget.onIFrameKeyboardShortcutAction?.call(shortcut); log('$runtimeType::_handleOnIFrameKeyboardEvent:📥 Shortcut pressed: $shortcut');
widget.onIFrameKeyboardShortcutAction?.call(shortcut);
} catch (e) {
logError('$runtimeType::_handleOnIFrameKeyboardEvent: Exception = $e');
}
} }
@override @override
void didUpdateWidget(covariant HtmlContentViewerOnWeb oldWidget) { void didUpdateWidget(covariant HtmlContentViewerOnWeb oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
log('_HtmlContentViewerOnWebState::didUpdateWidget():Old-Direction: ${oldWidget.direction} | Current-Direction: ${widget.direction}'); log('$runtimeType::didUpdateWidget():Old-Direction: ${oldWidget.direction} | Current-Direction: ${widget.direction}');
if (widget.contentHtml != oldWidget.contentHtml || if (widget.contentHtml != oldWidget.contentHtml ||
widget.direction != oldWidget.direction) { widget.direction != oldWidget.direction) {
_setUpWeb(); _setUpWeb();
@@ -311,6 +319,7 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb>
window.addEventListener('load', handleOnLoad); window.addEventListener('load', handleOnLoad);
window.addEventListener('pagehide', (event) => { window.addEventListener('pagehide', (event) => {
window.parent.removeEventListener('message', handleMessage, false); window.parent.removeEventListener('message', handleMessage, false);
window.removeEventListener('load', handleOnLoad);
}); });
function handleMessage(e) { function handleMessage(e) {
+16 -4
View File
@@ -286,7 +286,13 @@ class HtmlInteraction {
}, { }, {
passive: false, passive: false,
}); });
window.addEventListener('keydown', function(e) { window.addEventListener('keydown', disableZoomControl);
window.addEventListener('pagehide', (event) => {
window.removeEventListener('keydown', disableZoomControl);
});
function disableZoomControl(event) {
if (event.metaKey || event.ctrlKey) { if (event.metaKey || event.ctrlKey) {
switch (event.key) { switch (event.key) {
case '=': case '=':
@@ -295,7 +301,7 @@ class HtmlInteraction {
break; break;
} }
} }
}); }
</script> </script>
'''; ''';
@@ -381,7 +387,13 @@ class HtmlInteraction {
static String scriptHandleIframeKeyboardListener(String viewId) => ''' static String scriptHandleIframeKeyboardListener(String viewId) => '''
<script type="text/javascript"> <script type="text/javascript">
window.addEventListener('keydown', function (event) { window.addEventListener('keydown', handleIframeKeydown);
window.addEventListener('pagehide', (event) => {
window.removeEventListener('keydown', handleIframeKeydown);
});
function handleIframeKeydown(event) {
const payload = { const payload = {
view: '$viewId', view: '$viewId',
type: 'toDart: iframeKeydown', type: 'toDart: iframeKeydown',
@@ -390,7 +402,7 @@ class HtmlInteraction {
shift: event.shiftKey shift: event.shiftKey
}; };
window.parent.postMessage(JSON.stringify(payload), "*"); window.parent.postMessage(JSON.stringify(payload), "*");
}); }
</script> </script>
'''; ''';
} }