@@ -19,6 +19,7 @@ typedef OnLoadWidthHtmlViewerAction = Function(bool isScrollPageViewActivated);
19
19
typedef OnMailtoDelegateAction = Future <void > Function (Uri ? uri);
20
20
typedef OnPreviewEMLDelegateAction = Future <void > Function (Uri ? uri);
21
21
typedef OnDownloadAttachmentDelegateAction = Future <void > Function (Uri ? uri);
22
+ typedef OnHtmlContentClippedAction = Function (bool isClipped);
22
23
23
24
class HtmlContentViewer extends StatefulWidget {
24
25
@@ -34,6 +35,7 @@ class HtmlContentViewer extends StatefulWidget {
34
35
final OnScrollHorizontalEndAction ? onScrollHorizontalEnd;
35
36
final OnPreviewEMLDelegateAction ? onPreviewEMLDelegateAction;
36
37
final OnDownloadAttachmentDelegateAction ? onDownloadAttachmentDelegateAction;
38
+ final OnHtmlContentClippedAction ? onHtmlContentClippedAction;
37
39
38
40
const HtmlContentViewer ({
39
41
Key ? key,
@@ -48,6 +50,7 @@ class HtmlContentViewer extends StatefulWidget {
48
50
this .onScrollHorizontalEnd,
49
51
this .onPreviewEMLDelegateAction,
50
52
this .onDownloadAttachmentDelegateAction,
53
+ this .onHtmlContentClippedAction,
51
54
}) : super (key: key);
52
55
53
56
@override
@@ -57,6 +60,7 @@ class HtmlContentViewer extends StatefulWidget {
57
60
class _HtmlContentViewState extends State <HtmlContentViewer > {
58
61
59
62
static const double _minHeight = 100.0 ;
63
+ static const double _iOSHtmlContentMaxHeight = 22000.0 ;
60
64
static const double _offsetHeight = 30.0 ;
61
65
62
66
late InAppWebViewController _webViewController;
@@ -184,12 +188,25 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
184
188
Size oldContentSize,
185
189
Size newContentSize
186
190
) async {
191
+ if (! mounted || _loadingBarNotifier.value) return ;
192
+
187
193
final maxContentHeight = math.max (oldContentSize.height, newContentSize.height);
188
- log ('_HtmlContentViewState::_onContentSizeChanged:maxContentHeight: $maxContentHeight ' );
189
- if (maxContentHeight > _actualHeight && ! _loadingBarNotifier.value && mounted) {
190
- log ('_HtmlContentViewState::_onContentSizeChanged:HEIGHT_UPDATED: $maxContentHeight ' );
194
+ if (maxContentHeight <= _actualHeight) return ;
195
+
196
+ double currentHeight = maxContentHeight + _offsetHeight;
197
+
198
+ if (PlatformInfo .isIOS) {
199
+ final isClipped = currentHeight > _iOSHtmlContentMaxHeight;
200
+ if (isClipped) {
201
+ widget.onHtmlContentClippedAction? .call (true );
202
+ }
203
+ currentHeight = currentHeight.clamp (_minHeight, _iOSHtmlContentMaxHeight);
204
+ }
205
+
206
+ if (_actualHeight != currentHeight) {
207
+ log ('_HtmlContentViewState::_onContentSizeChanged: currentHeight = $currentHeight ' );
191
208
setState (() {
192
- _actualHeight = maxContentHeight + _offsetHeight ;
209
+ _actualHeight = currentHeight ;
193
210
});
194
211
}
195
212
}
@@ -205,55 +222,84 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
205
222
}
206
223
207
224
void _onHandleContentSizeChangedEvent (List <dynamic > parameters) async {
208
- final maxContentHeight = await _webViewController.evaluateJavascript (source: 'document.body.scrollHeight' );
209
- log ('_HtmlContentViewState::_onHandleContentSizeChangedEvent:maxContentHeight: $maxContentHeight ' );
210
- if (maxContentHeight is num && maxContentHeight > _actualHeight && ! _loadingBarNotifier.value && mounted) {
211
- log ('_HtmlContentViewState::_onHandleContentSizeChangedEvent:HEIGHT_UPDATED: $maxContentHeight ' );
225
+ if (! mounted || _loadingBarNotifier.value) return ;
226
+
227
+ final dynamic result = await _webViewController.evaluateJavascript (source: 'document.body.scrollHeight' );
228
+ if (result is ! num ) return ;
229
+
230
+ final double maxContentHeight = result.toDouble ();
231
+ if (maxContentHeight <= _actualHeight) return ;
232
+
233
+ double currentHeight = maxContentHeight + _offsetHeight;
234
+
235
+ if (PlatformInfo .isIOS) {
236
+ final bool isClipped = currentHeight > _iOSHtmlContentMaxHeight;
237
+ if (isClipped) {
238
+ widget.onHtmlContentClippedAction? .call (true );
239
+ }
240
+ currentHeight = currentHeight.clamp (_minHeight, _iOSHtmlContentMaxHeight);
241
+ }
242
+
243
+ if (_actualHeight != currentHeight) {
244
+ log ('_HtmlContentViewState::_onHandleContentSizeChangedEvent: currentHeight = $currentHeight ' );
212
245
setState (() {
213
- _actualHeight = maxContentHeight + _offsetHeight ;
246
+ _actualHeight = currentHeight ;
214
247
});
215
248
}
216
249
}
217
250
218
251
Future <void > _getActualSizeHtmlViewer () async {
219
- final listSize = await Future .wait ([
220
- _webViewController.evaluateJavascript (source: 'document.getElementsByClassName("tmail-content")[0].scrollWidth' ),
221
- _webViewController.evaluateJavascript (source: 'document.getElementsByClassName("tmail-content")[0].offsetWidth' ),
222
- _webViewController.evaluateJavascript (source: 'document.body.scrollHeight' ),
252
+ if (! mounted) return ;
253
+
254
+ final List <dynamic > listSize = await Future .wait ([
255
+ _webViewController.evaluateJavascript (source: 'document.getElementsByClassName("tmail-content")[0]?.scrollWidth' ),
256
+ _webViewController.evaluateJavascript (source: 'document.getElementsByClassName("tmail-content")[0]?.offsetWidth' ),
257
+ _webViewController.evaluateJavascript (source: 'document.body?.scrollHeight' ),
223
258
]);
224
- log ('_HtmlContentViewState::_getActualSizeHtmlViewer():listSize: $listSize ' );
225
- Set <Factory <OneSequenceGestureRecognizer >>? newGestureRecognizers;
259
+
260
+ log ('_HtmlContentViewState::_getActualSizeHtmlViewer(): listSize: $listSize ' );
261
+
226
262
bool isScrollActivated = false ;
263
+ Set <Factory <OneSequenceGestureRecognizer >>? newGestureRecognizers;
227
264
228
- if (listSize[0 ] is num && listSize[1 ] is num ) {
229
- final scrollWidth = listSize[0 ] as num ;
230
- final offsetWidth = listSize[1 ] as num ;
231
- isScrollActivated = scrollWidth.round () == offsetWidth.round ();
265
+ final double ? scrollWidth = listSize[0 ] is num ? (listSize[0 ] as num ).toDouble () : null ;
266
+ final double ? offsetWidth = listSize[1 ] is num ? (listSize[1 ] as num ).toDouble () : null ;
267
+ final double ? scrollHeight = listSize[2 ] is num ? (listSize[2 ] as num ).toDouble () : null ;
232
268
269
+ if (scrollWidth != null && offsetWidth != null ) {
270
+ isScrollActivated = scrollWidth.round () == offsetWidth.round ();
233
271
if (! isScrollActivated && PlatformInfo .isIOS) {
234
272
newGestureRecognizers = {
235
273
Factory <LongPressGestureRecognizer >(() => LongPressGestureRecognizer (duration: _longPressGestureDurationIOS)),
236
- Factory <HorizontalDragGestureRecognizer >(() => HorizontalDragGestureRecognizer ())
274
+ Factory <HorizontalDragGestureRecognizer >(() => HorizontalDragGestureRecognizer ()),
237
275
};
238
276
}
239
277
}
240
278
241
- if (listSize[2 ] is num ) {
242
- final scrollHeight = listSize[2 ] as num ;
243
- if (mounted && scrollHeight > 0 ) {
279
+ if (scrollHeight != null && scrollHeight > 0 ) {
280
+ double currentHeight = scrollHeight + _offsetHeight;
281
+
282
+ if (PlatformInfo .isIOS) {
283
+ final bool isClipped = currentHeight > _iOSHtmlContentMaxHeight;
284
+ if (isClipped) {
285
+ widget.onHtmlContentClippedAction? .call (true );
286
+ }
287
+ currentHeight = currentHeight.clamp (_minHeight, _iOSHtmlContentMaxHeight);
288
+ }
289
+
290
+ if (_actualHeight != currentHeight || newGestureRecognizers != null ) {
291
+ log ('_HtmlContentViewState::_getActualSizeHtmlViewer: currentHeight = $currentHeight ' );
244
292
setState (() {
245
- _actualHeight = scrollHeight + _offsetHeight ;
293
+ _actualHeight = currentHeight ;
246
294
if (newGestureRecognizers != null ) {
247
295
_gestureRecognizers = newGestureRecognizers;
248
296
}
249
297
});
250
298
}
251
- } else {
252
- if (mounted && newGestureRecognizers != null ) {
253
- setState (() {
254
- _gestureRecognizers = newGestureRecognizers! ;
255
- });
256
- }
299
+ } else if (newGestureRecognizers != null ) {
300
+ setState (() {
301
+ _gestureRecognizers = newGestureRecognizers! ;
302
+ });
257
303
}
258
304
259
305
if (! isScrollActivated) {
0 commit comments