@@ -19,6 +19,7 @@ typedef OnLoadWidthHtmlViewerAction = Function(bool isScrollPageViewActivated);
1919typedef OnMailtoDelegateAction = Future <void > Function (Uri ? uri);
2020typedef OnPreviewEMLDelegateAction = Future <void > Function (Uri ? uri);
2121typedef OnDownloadAttachmentDelegateAction = Future <void > Function (Uri ? uri);
22+ typedef OnHtmlContentClippedAction = Function (bool isClipped);
2223
2324class HtmlContentViewer extends StatefulWidget {
2425
@@ -34,6 +35,7 @@ class HtmlContentViewer extends StatefulWidget {
3435 final OnScrollHorizontalEndAction ? onScrollHorizontalEnd;
3536 final OnPreviewEMLDelegateAction ? onPreviewEMLDelegateAction;
3637 final OnDownloadAttachmentDelegateAction ? onDownloadAttachmentDelegateAction;
38+ final OnHtmlContentClippedAction ? onHtmlContentClippedAction;
3739
3840 const HtmlContentViewer ({
3941 Key ? key,
@@ -48,6 +50,7 @@ class HtmlContentViewer extends StatefulWidget {
4850 this .onScrollHorizontalEnd,
4951 this .onPreviewEMLDelegateAction,
5052 this .onDownloadAttachmentDelegateAction,
53+ this .onHtmlContentClippedAction,
5154 }) : super (key: key);
5255
5356 @override
@@ -57,6 +60,7 @@ class HtmlContentViewer extends StatefulWidget {
5760class _HtmlContentViewState extends State <HtmlContentViewer > {
5861
5962 static const double _minHeight = 100.0 ;
63+ static const double _iOSHtmlContentMaxHeight = 22000.0 ;
6064 static const double _offsetHeight = 30.0 ;
6165
6266 late InAppWebViewController _webViewController;
@@ -184,12 +188,25 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
184188 Size oldContentSize,
185189 Size newContentSize
186190 ) async {
191+ if (! mounted || _loadingBarNotifier.value) return ;
192+
187193 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 ' );
191208 setState (() {
192- _actualHeight = maxContentHeight + _offsetHeight ;
209+ _actualHeight = currentHeight ;
193210 });
194211 }
195212 }
@@ -205,55 +222,84 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
205222 }
206223
207224 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 ' );
212245 setState (() {
213- _actualHeight = maxContentHeight + _offsetHeight ;
246+ _actualHeight = currentHeight ;
214247 });
215248 }
216249 }
217250
218251 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' ),
223258 ]);
224- log ('_HtmlContentViewState::_getActualSizeHtmlViewer():listSize: $listSize ' );
225- Set <Factory <OneSequenceGestureRecognizer >>? newGestureRecognizers;
259+
260+ log ('_HtmlContentViewState::_getActualSizeHtmlViewer(): listSize: $listSize ' );
261+
226262 bool isScrollActivated = false ;
263+ Set <Factory <OneSequenceGestureRecognizer >>? newGestureRecognizers;
227264
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 ;
232268
269+ if (scrollWidth != null && offsetWidth != null ) {
270+ isScrollActivated = scrollWidth.round () == offsetWidth.round ();
233271 if (! isScrollActivated && PlatformInfo .isIOS) {
234272 newGestureRecognizers = {
235273 Factory <LongPressGestureRecognizer >(() => LongPressGestureRecognizer (duration: _longPressGestureDurationIOS)),
236- Factory <HorizontalDragGestureRecognizer >(() => HorizontalDragGestureRecognizer ())
274+ Factory <HorizontalDragGestureRecognizer >(() => HorizontalDragGestureRecognizer ()),
237275 };
238276 }
239277 }
240278
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 ' );
244292 setState (() {
245- _actualHeight = scrollHeight + _offsetHeight ;
293+ _actualHeight = currentHeight ;
246294 if (newGestureRecognizers != null ) {
247295 _gestureRecognizers = newGestureRecognizers;
248296 }
249297 });
250298 }
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+ });
257303 }
258304
259305 if (! isScrollActivated) {
0 commit comments