TF-2520 Create some class to handle html
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
+95
-104
@@ -1,101 +1,10 @@
|
||||
library core;
|
||||
|
||||
// Extensions
|
||||
export 'presentation/extensions/color_extension.dart';
|
||||
export 'presentation/extensions/url_extension.dart';
|
||||
export 'presentation/extensions/uri_extension.dart';
|
||||
export 'presentation/extensions/capitalize_extension.dart';
|
||||
export 'presentation/extensions/list_extensions.dart';
|
||||
export 'domain/extensions/datetime_extension.dart';
|
||||
export 'presentation/extensions/html_extension.dart';
|
||||
export 'presentation/extensions/compare_string_extension.dart';
|
||||
export 'presentation/extensions/compare_list_extensions.dart';
|
||||
export 'presentation/extensions/string_extension.dart';
|
||||
export 'presentation/extensions/tap_down_details_extension.dart';
|
||||
export 'domain/extensions/media_type_extension.dart';
|
||||
export 'presentation/extensions/map_extensions.dart';
|
||||
|
||||
// Exceptions
|
||||
export 'domain/exceptions/download_file_exception.dart';
|
||||
export 'data/extensions/options_extensions.dart';
|
||||
export 'domain/exceptions/web_session_exception.dart';
|
||||
|
||||
// Utils
|
||||
export 'presentation/utils/theme_utils.dart';
|
||||
export 'presentation/utils/responsive_utils.dart';
|
||||
export 'presentation/utils/keyboard_utils.dart';
|
||||
export 'presentation/utils/icon_utils.dart';
|
||||
export 'presentation/utils/style_utils.dart';
|
||||
export 'presentation/utils/app_toast.dart';
|
||||
export 'presentation/utils/html_transformer/html_template.dart';
|
||||
export 'presentation/utils/html_transformer/html_transform.dart';
|
||||
export 'presentation/utils/html_transformer/transform_configuration.dart';
|
||||
export 'presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart';
|
||||
export 'data/utils/device_manager.dart';
|
||||
export 'utils/app_logger.dart';
|
||||
export 'utils/benchmark.dart';
|
||||
export 'utils/fps_manager.dart';
|
||||
export 'utils/build_utils.dart';
|
||||
export 'utils/string_convert.dart';
|
||||
export 'utils/config/app_config_loader.dart';
|
||||
export 'utils/config/app_config_parser.dart';
|
||||
export 'utils/config/errors.dart';
|
||||
export 'data/utils/compress_file_utils.dart';
|
||||
export 'utils/platform_info.dart';
|
||||
export 'utils/option_param_mixin.dart';
|
||||
export 'utils/file_utils.dart';
|
||||
export 'utils/print_utils.dart';
|
||||
|
||||
// Views
|
||||
export 'presentation/views/text/slogan_builder.dart';
|
||||
export 'presentation/views/text/text_field_builder.dart';
|
||||
export 'presentation/views/text/text_form_field_builder.dart';
|
||||
export 'presentation/views/text/input_decoration_builder.dart';
|
||||
export 'presentation/views/text/rich_text_builder.dart';
|
||||
export 'presentation/views/text/text_overflow_builder.dart';
|
||||
export 'presentation/views/responsive/responsive_widget.dart';
|
||||
export 'presentation/views/list/tree_view.dart';
|
||||
export 'presentation/views/button/icon_button_web.dart';
|
||||
export 'presentation/views/button/tmail_button_widget.dart';
|
||||
export 'presentation/views/image/avatar_builder.dart';
|
||||
export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart';
|
||||
export 'presentation/views/image/icon_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_action_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_header_builder.dart';
|
||||
export 'presentation/views/context_menu/simple_context_menu_action_builder.dart';
|
||||
export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/confirmation_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/edit_text_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/color_picker_dialog_builder.dart';
|
||||
export 'presentation/views/html_viewer/html_content_viewer_widget.dart';
|
||||
export 'presentation/views/html_viewer/html_content_viewer_on_web_widget.dart';
|
||||
export 'presentation/views/floating_button/scrolling_floating_button_animated.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_action_builder.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_no_icon_builder.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_builder.dart';
|
||||
export 'presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
|
||||
export 'presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart';
|
||||
export 'presentation/views/search/search_bar_view.dart';
|
||||
export 'presentation/views/popup_menu/popup_menu_item_widget.dart';
|
||||
export 'presentation/views/quick_search/quick_search_input_form.dart';
|
||||
export 'presentation/views/toast/toast_position.dart';
|
||||
export 'presentation/views/toast/tmail_toast.dart';
|
||||
export 'presentation/views/bottom_popup/full_screen_action_sheet_builder.dart';
|
||||
export 'presentation/views/checkbox/labeled_checkbox.dart';
|
||||
export 'presentation/views/container/tmail_container_widget.dart';
|
||||
export 'presentation/views/clipper/side_arrow_clipper.dart';
|
||||
export 'presentation/views/avatar/gradient_circle_avatar_icon.dart';
|
||||
export 'presentation/views/loading/cupertino_loading_widget.dart';
|
||||
|
||||
// Resources
|
||||
export 'presentation/resources/assets_paths.dart';
|
||||
export 'presentation/resources/image_paths.dart';
|
||||
|
||||
// Constants
|
||||
export 'presentation/constants/constants_ui.dart';
|
||||
export 'data/constants/constant.dart';
|
||||
|
||||
export 'data/extensions/options_extensions.dart';
|
||||
export 'data/model/query/query_parameter.dart';
|
||||
// Model
|
||||
export 'data/model/source_type/data_source_type.dart';
|
||||
// Network
|
||||
export 'data/network/config/dynamic_url_interceptors.dart';
|
||||
export 'data/network/config/service_path.dart';
|
||||
@@ -103,14 +12,96 @@ export 'data/network/dio_client.dart';
|
||||
export 'data/network/download/download_client.dart';
|
||||
export 'data/network/download/download_manager.dart';
|
||||
export 'data/network/download/downloaded_response.dart';
|
||||
|
||||
export 'data/utils/compress_file_utils.dart';
|
||||
export 'data/utils/device_manager.dart';
|
||||
// Exceptions
|
||||
export 'domain/exceptions/download_file_exception.dart';
|
||||
export 'domain/exceptions/web_session_exception.dart';
|
||||
export 'domain/extensions/datetime_extension.dart';
|
||||
export 'domain/extensions/media_type_extension.dart';
|
||||
// Action
|
||||
export 'presentation/action/action_callback_define.dart';
|
||||
// Constants
|
||||
export 'presentation/constants/constants_ui.dart';
|
||||
export 'presentation/extensions/capitalize_extension.dart';
|
||||
// Extensions
|
||||
export 'presentation/extensions/color_extension.dart';
|
||||
export 'presentation/extensions/compare_list_extensions.dart';
|
||||
export 'presentation/extensions/compare_string_extension.dart';
|
||||
export 'presentation/extensions/html_extension.dart';
|
||||
export 'presentation/extensions/list_extensions.dart';
|
||||
export 'presentation/extensions/map_extensions.dart';
|
||||
export 'presentation/extensions/string_extension.dart';
|
||||
export 'presentation/extensions/tap_down_details_extension.dart';
|
||||
export 'presentation/extensions/uri_extension.dart';
|
||||
export 'presentation/extensions/url_extension.dart';
|
||||
// Resources
|
||||
export 'presentation/resources/assets_paths.dart';
|
||||
export 'presentation/resources/image_paths.dart';
|
||||
export 'presentation/state/failure.dart';
|
||||
// State
|
||||
export 'presentation/state/success.dart';
|
||||
export 'presentation/state/failure.dart';
|
||||
|
||||
// Model
|
||||
export 'data/model/source_type/data_source_type.dart';
|
||||
export 'data/model/query/query_parameter.dart';
|
||||
|
||||
// Action
|
||||
export 'presentation/action/action_callback_define.dart';
|
||||
export 'presentation/utils/app_toast.dart';
|
||||
export 'presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart';
|
||||
export 'presentation/utils/html_transformer/html_transform.dart';
|
||||
export 'presentation/utils/html_transformer/transform_configuration.dart';
|
||||
export 'presentation/utils/icon_utils.dart';
|
||||
export 'presentation/utils/keyboard_utils.dart';
|
||||
export 'presentation/utils/responsive_utils.dart';
|
||||
export 'presentation/utils/style_utils.dart';
|
||||
// Utils
|
||||
export 'presentation/utils/theme_utils.dart';
|
||||
export 'presentation/views/avatar/gradient_circle_avatar_icon.dart';
|
||||
export 'presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_action_builder.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_builder.dart';
|
||||
export 'presentation/views/bottom_popup/cupertino_action_sheet_no_icon_builder.dart';
|
||||
export 'presentation/views/bottom_popup/full_screen_action_sheet_builder.dart';
|
||||
export 'presentation/views/button/icon_button_web.dart';
|
||||
export 'presentation/views/button/tmail_button_widget.dart';
|
||||
export 'presentation/views/checkbox/labeled_checkbox.dart';
|
||||
export 'presentation/views/clipper/side_arrow_clipper.dart';
|
||||
export 'presentation/views/container/tmail_container_widget.dart';
|
||||
export 'presentation/views/context_menu/context_menu_action_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_header_builder.dart';
|
||||
export 'presentation/views/context_menu/simple_context_menu_action_builder.dart';
|
||||
export 'presentation/views/dialog/color_picker_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/confirmation_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/edit_text_dialog_builder.dart';
|
||||
export 'presentation/views/floating_button/scrolling_floating_button_animated.dart';
|
||||
export 'presentation/views/html_viewer/html_content_viewer_on_web_widget.dart';
|
||||
export 'presentation/views/html_viewer/html_content_viewer_widget.dart';
|
||||
export 'presentation/views/image/avatar_builder.dart';
|
||||
export 'presentation/views/image/icon_builder.dart';
|
||||
export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart';
|
||||
export 'presentation/views/list/tree_view.dart';
|
||||
export 'presentation/views/loading/cupertino_loading_widget.dart';
|
||||
export 'presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart';
|
||||
export 'presentation/views/popup_menu/popup_menu_item_widget.dart';
|
||||
export 'presentation/views/quick_search/quick_search_input_form.dart';
|
||||
export 'presentation/views/responsive/responsive_widget.dart';
|
||||
export 'presentation/views/search/search_bar_view.dart';
|
||||
export 'presentation/views/text/input_decoration_builder.dart';
|
||||
export 'presentation/views/text/rich_text_builder.dart';
|
||||
// Views
|
||||
export 'presentation/views/text/slogan_builder.dart';
|
||||
export 'presentation/views/text/text_field_builder.dart';
|
||||
export 'presentation/views/text/text_form_field_builder.dart';
|
||||
export 'presentation/views/text/text_overflow_builder.dart';
|
||||
export 'presentation/views/toast/tmail_toast.dart';
|
||||
export 'presentation/views/toast/toast_position.dart';
|
||||
export 'utils/app_logger.dart';
|
||||
export 'utils/benchmark.dart';
|
||||
export 'utils/build_utils.dart';
|
||||
export 'utils/config/app_config_loader.dart';
|
||||
export 'utils/config/app_config_parser.dart';
|
||||
export 'utils/config/errors.dart';
|
||||
export 'utils/file_utils.dart';
|
||||
export 'utils/fps_manager.dart';
|
||||
export 'utils/html/html_template.dart';
|
||||
export 'utils/option_param_mixin.dart';
|
||||
export 'utils/platform_info.dart';
|
||||
export 'utils/print_utils.dart';
|
||||
export 'utils/string_convert.dart';
|
||||
@@ -4,8 +4,8 @@ import 'dart:io';
|
||||
|
||||
import 'package:core/data/network/dio_client.dart';
|
||||
import 'package:core/data/utils/compress_file_utils.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import 'package:core/data/network/dio_client.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_template.dart';
|
||||
import 'package:core/utils/html/html_template.dart';
|
||||
import 'package:html/dom.dart';
|
||||
|
||||
class AddTooltipLinkTransformer extends DomTransformer {
|
||||
@@ -28,9 +28,9 @@ class AddTooltipLinkTransformer extends DomTransformer {
|
||||
final innerHtml = element.innerHtml;
|
||||
final tagClass = element.attributes['class'];
|
||||
if (tagClass != null) {
|
||||
element.attributes['class'] = '$tagClass $nameClassToolTip';
|
||||
element.attributes['class'] = '$tagClass ${HtmlTemplate.nameClassToolTip}';
|
||||
} else {
|
||||
element.attributes['class'] = nameClassToolTip;
|
||||
element.attributes['class'] = HtmlTemplate.nameClassToolTip;
|
||||
}
|
||||
element.innerHtml = innerHtml + textHasToolTip(url);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
|
||||
import 'package:core/data/network/dio_client.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_template.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_template.dart';
|
||||
import 'package:html/dom.dart';
|
||||
|
||||
class RemoveTooltipLinkTransformer extends DomTransformer {
|
||||
@@ -15,11 +15,11 @@ class RemoveTooltipLinkTransformer extends DomTransformer {
|
||||
required DioClient dioClient,
|
||||
Map<String, String>? mapUrlDownloadCID,
|
||||
}) async {
|
||||
final linkElements = document.querySelectorAll('a.$nameClassToolTip');
|
||||
final linkElements = document.querySelectorAll('a.${HtmlTemplate.nameClassToolTip}');
|
||||
await Future.wait(linkElements.map((linkElement) async {
|
||||
final classAttribute = linkElement.attributes['class'];
|
||||
if (classAttribute != null) {
|
||||
final newClassAttribute = classAttribute.replaceFirst(nameClassToolTip, '');
|
||||
final newClassAttribute = classAttribute.replaceFirst(HtmlTemplate.nameClassToolTip, '');
|
||||
linkElement.attributes['class'] = newClassAttribute;
|
||||
}
|
||||
final listSpanTag = linkElement.querySelectorAll('span.tooltiptext');
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
class HtmlEventAction {
|
||||
static const scrollRightEndAction = 'ScrollRightEndAction';
|
||||
static const scrollLeftEndAction = 'ScrollLeftEndAction';
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const nameClassToolTip = 'tmail-tooltip';
|
||||
|
||||
const tooltipLinkCss = '''
|
||||
.$nameClassToolTip .tooltiptext {
|
||||
visibility: hidden;
|
||||
max-width: 400px;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px 8px 5px 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
.$nameClassToolTip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
''';
|
||||
|
||||
String generateHtml(String content, {
|
||||
double? minHeight,
|
||||
double? minWidth,
|
||||
String? styleCSS,
|
||||
String? javaScripts,
|
||||
bool hideScrollBar = true,
|
||||
TextDirection? direction
|
||||
}) {
|
||||
return '''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style>
|
||||
.tmail-content {
|
||||
min-height: ${minHeight ?? 0}px;
|
||||
min-width: ${minWidth ?? 0}px;
|
||||
overflow: auto;
|
||||
}
|
||||
${hideScrollBar ? '''
|
||||
.tmail-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.tmail-content {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
''' : ''}
|
||||
${styleCSS ?? ''}
|
||||
</style>
|
||||
</head>
|
||||
<body ${direction == TextDirection.rtl ? 'dir="rtl"' : ''} style = "overflow-x: hidden">
|
||||
<div class="tmail-content">$content</div>
|
||||
${javaScripts ?? ''}
|
||||
</body>
|
||||
</html>
|
||||
''';
|
||||
}
|
||||
@@ -3,12 +3,13 @@ import 'dart:convert';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_template.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/presentation/utils/shims/dart_ui.dart' as ui;
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_interaction.dart';
|
||||
import 'package:core/utils/html/html_template.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:core/presentation/utils/shims/dart_ui.dart' as ui;
|
||||
|
||||
class HtmlContentViewerOnWeb extends StatefulWidget {
|
||||
|
||||
@@ -162,11 +163,12 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb> {
|
||||
</script>
|
||||
''';
|
||||
|
||||
final htmlTemplate = generateHtml(content,
|
||||
final htmlTemplate = HtmlUtils.generateHtmlDocument(
|
||||
content: content,
|
||||
minHeight: minHeight,
|
||||
minWidth: _minWidth,
|
||||
styleCSS: tooltipLinkCss,
|
||||
javaScripts: webViewActionScripts + scriptsDisableZoom + HtmlUtils.scriptsHandleLazyLoadingBackgroundImage,
|
||||
styleCSS: HtmlTemplate.tooltipLinkCss,
|
||||
javaScripts: webViewActionScripts + scriptsDisableZoom + HtmlInteraction.scriptsHandleLazyLoadingBackgroundImage,
|
||||
direction: widget.direction);
|
||||
|
||||
return htmlTemplate;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_event_action.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/presentation/views/loading/cupertino_loading_widget.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_interaction.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@@ -72,9 +74,9 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
};
|
||||
}
|
||||
if (PlatformInfo.isAndroid) {
|
||||
_customScripts = HtmlUtils.scriptsHandleLazyLoadingBackgroundImage + HtmlUtils.scriptsHandleContentSizeChanged;
|
||||
_customScripts = HtmlInteraction.scriptsHandleLazyLoadingBackgroundImage + HtmlInteraction.scriptsHandleContentSizeChanged;
|
||||
} else {
|
||||
_customScripts = HtmlUtils.scriptsHandleLazyLoadingBackgroundImage;
|
||||
_customScripts = HtmlInteraction.scriptsHandleLazyLoadingBackgroundImage;
|
||||
}
|
||||
_initialData();
|
||||
}
|
||||
@@ -91,8 +93,8 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
|
||||
void _initialData() {
|
||||
_actualHeight = _minHeight;
|
||||
_htmlData = generateHtml(
|
||||
widget.contentHtml,
|
||||
_htmlData = HtmlUtils.generateHtmlDocument(
|
||||
content: widget.contentHtml,
|
||||
direction: widget.direction,
|
||||
javaScripts: _customScripts
|
||||
);
|
||||
@@ -138,13 +140,13 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
await controller.loadData(data: _htmlData ?? '');
|
||||
|
||||
controller.addJavaScriptHandler(
|
||||
handlerName: HtmlUtils.scrollEventJSChannelName,
|
||||
handlerName: HtmlInteraction.scrollEventJSChannelName,
|
||||
callback: _onHandleScrollEvent
|
||||
);
|
||||
|
||||
if (PlatformInfo.isAndroid) {
|
||||
controller.addJavaScriptHandler(
|
||||
handlerName: HtmlUtils.contentSizeChangedEventJSChannelName,
|
||||
handlerName: HtmlInteraction.contentSizeChangedEventJSChannelName,
|
||||
callback: _onHandleContentSizeChangedEvent
|
||||
);
|
||||
}
|
||||
@@ -174,9 +176,9 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
void _onHandleScrollEvent(List<dynamic> parameters) {
|
||||
log('_HtmlContentViewState::_onHandleScrollEvent():parameters: $parameters');
|
||||
final message = parameters.first;
|
||||
if (message == HtmlEventAction.scrollLeftEndAction) {
|
||||
if (message == HtmlInteraction.scrollLeftEndAction) {
|
||||
widget.onScrollHorizontalEnd?.call(true);
|
||||
} else if (message == HtmlEventAction.scrollRightEndAction) {
|
||||
} else if (message == HtmlInteraction.scrollRightEndAction) {
|
||||
widget.onScrollHorizontalEnd?.call(false);
|
||||
}
|
||||
}
|
||||
@@ -234,7 +236,7 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
}
|
||||
|
||||
if (!isScrollActivated) {
|
||||
await _webViewController.evaluateJavascript(source: HtmlUtils.runScriptsHandleScrollEvent);
|
||||
await _webViewController.evaluateJavascript(source: HtmlInteraction.runScriptsHandleScrollEvent);
|
||||
}
|
||||
widget.onLoadWidthHtmlViewer?.call(isScrollActivated);
|
||||
}
|
||||
|
||||
+11
-65
@@ -1,16 +1,11 @@
|
||||
|
||||
import 'package:core/presentation/extensions/html_extension.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_event_action.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
class HtmlInteraction {
|
||||
static const String scrollRightEndAction = 'ScrollRightEndAction';
|
||||
static const String scrollLeftEndAction = 'ScrollLeftEndAction';
|
||||
static const String scrollEventJSChannelName = 'ScrollEventListener';
|
||||
static const String contentSizeChangedEventJSChannelName = 'ContentSizeChangedEventListener';
|
||||
|
||||
class HtmlUtils {
|
||||
|
||||
static const scrollEventJSChannelName = 'ScrollEventListener';
|
||||
static const contentSizeChangedEventJSChannelName = 'ContentSizeChangedEventListener';
|
||||
|
||||
static const runScriptsHandleScrollEvent = '''
|
||||
static const String runScriptsHandleScrollEvent = '''
|
||||
let contentElement = document.getElementsByClassName('tmail-content')[0];
|
||||
var xDown = null;
|
||||
var yDown = null;
|
||||
@@ -50,11 +45,11 @@ class HtmlUtils {
|
||||
if (maxOffset === scrollLeftRounded ||
|
||||
maxOffset === (scrollLeftRounded + 1) ||
|
||||
maxOffset === (scrollLeftRounded - 1)) {
|
||||
window.flutter_inappwebview.callHandler('$scrollEventJSChannelName', '${HtmlEventAction.scrollRightEndAction}');
|
||||
window.flutter_inappwebview.callHandler('$scrollEventJSChannelName', '$scrollRightEndAction');
|
||||
}
|
||||
} else {
|
||||
if (scrollLeftRounded === 0) {
|
||||
window.flutter_inappwebview.callHandler('$scrollEventJSChannelName', '${HtmlEventAction.scrollLeftEndAction}');
|
||||
window.flutter_inappwebview.callHandler('$scrollEventJSChannelName', '$scrollLeftEndAction');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +59,7 @@ class HtmlUtils {
|
||||
}
|
||||
''';
|
||||
|
||||
static const scriptsHandleContentSizeChanged = '''
|
||||
static const String scriptsHandleContentSizeChanged = '''
|
||||
<script>
|
||||
const bodyResizeObserver = new ResizeObserver(entries => {
|
||||
window.flutter_inappwebview.callHandler('$contentSizeChangedEventJSChannelName', '');
|
||||
@@ -74,7 +69,7 @@ class HtmlUtils {
|
||||
</script>
|
||||
''';
|
||||
|
||||
static const scriptsHandleLazyLoadingBackgroundImage = '''
|
||||
static const String scriptsHandleLazyLoadingBackgroundImage = '''
|
||||
<script>
|
||||
const lazyImages = document.querySelectorAll('[lazy]');
|
||||
const lazyImageObserver = new IntersectionObserver((entries, observer) => {
|
||||
@@ -96,53 +91,4 @@ class HtmlUtils {
|
||||
});
|
||||
</script>
|
||||
''';
|
||||
|
||||
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
|
||||
if (PlatformInfo.isWeb) {
|
||||
return '''
|
||||
<style>
|
||||
.note-editable {
|
||||
direction: ${direction.name};
|
||||
}
|
||||
|
||||
.note-editable .tmail-signature {
|
||||
text-align: ${direction == TextDirection.rtl ? 'right' : 'left'};
|
||||
}
|
||||
</style>
|
||||
''';
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
return '''
|
||||
#editor {
|
||||
direction: ${direction.name};
|
||||
}
|
||||
|
||||
#editor .tmail-signature {
|
||||
text-align: ${direction == TextDirection.rtl ? 'right' : 'left'};
|
||||
}
|
||||
''';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static String validateHtmlImageResourceMimeType(String mimeType) {
|
||||
if (mimeType.endsWith('svg')) {
|
||||
mimeType = 'image/svg+xml';
|
||||
}
|
||||
log('HtmlUtils::validateHtmlImageResourceMimeType:mimeType: $mimeType');
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
static String convertBase64ToImageResourceData({
|
||||
required String base64Data,
|
||||
required String mimeType
|
||||
}) {
|
||||
mimeType = validateHtmlImageResourceMimeType(mimeType);
|
||||
if (!base64Data.endsWith('==')) {
|
||||
base64Data.append('==');
|
||||
}
|
||||
final imageResource = 'data:$mimeType;base64,$base64Data';
|
||||
log('HtmlUtils::convertBase64ToImageResourceData:imageResource: $imageResource');
|
||||
return imageResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
class HtmlTemplate {
|
||||
static const String nameClassToolTip = 'tmail-tooltip';
|
||||
static const String tooltipLinkCss = '''
|
||||
.$nameClassToolTip .tooltiptext {
|
||||
visibility: hidden;
|
||||
max-width: 400px;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px 8px 5px 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
.$nameClassToolTip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
''';
|
||||
|
||||
static const String sampleHtmlDocument = '''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body</body>
|
||||
</html>
|
||||
''';
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
import 'package:core/presentation/extensions/html_extension.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HtmlUtils {
|
||||
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
|
||||
if (PlatformInfo.isWeb) {
|
||||
return '''
|
||||
<style>
|
||||
.note-editable {
|
||||
direction: ${direction.name};
|
||||
}
|
||||
|
||||
.note-editable .tmail-signature {
|
||||
text-align: ${direction == TextDirection.rtl ? 'right' : 'left'};
|
||||
}
|
||||
</style>
|
||||
''';
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
return '''
|
||||
#editor {
|
||||
direction: ${direction.name};
|
||||
}
|
||||
|
||||
#editor .tmail-signature {
|
||||
text-align: ${direction == TextDirection.rtl ? 'right' : 'left'};
|
||||
}
|
||||
''';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static String validateHtmlImageResourceMimeType(String mimeType) {
|
||||
if (mimeType.endsWith('svg')) {
|
||||
mimeType = 'image/svg+xml';
|
||||
}
|
||||
log('HtmlUtils::validateHtmlImageResourceMimeType:mimeType: $mimeType');
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
static String convertBase64ToImageResourceData({
|
||||
required String base64Data,
|
||||
required String mimeType
|
||||
}) {
|
||||
mimeType = validateHtmlImageResourceMimeType(mimeType);
|
||||
if (!base64Data.endsWith('==')) {
|
||||
base64Data.append('==');
|
||||
}
|
||||
final imageResource = 'data:$mimeType;base64,$base64Data';
|
||||
log('HtmlUtils::convertBase64ToImageResourceData:imageResource: $imageResource');
|
||||
return imageResource;
|
||||
}
|
||||
|
||||
static String generateHtmlDocument({
|
||||
required String content,
|
||||
double? minHeight,
|
||||
double? minWidth,
|
||||
String? styleCSS,
|
||||
String? javaScripts,
|
||||
bool hideScrollBar = true,
|
||||
TextDirection? direction
|
||||
}) {
|
||||
return '''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style>
|
||||
.tmail-content {
|
||||
min-height: ${minHeight ?? 0}px;
|
||||
min-width: ${minWidth ?? 0}px;
|
||||
overflow: auto;
|
||||
}
|
||||
${hideScrollBar ? '''
|
||||
.tmail-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.tmail-content {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
''' : ''}
|
||||
${styleCSS ?? ''}
|
||||
</style>
|
||||
</head>
|
||||
<body ${direction == TextDirection.rtl ? 'dir="rtl"' : ''} style = "overflow-x: hidden">
|
||||
<div class="tmail-content">$content</div>
|
||||
${javaScripts ?? ''}
|
||||
</body>
|
||||
</html>
|
||||
''';
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:rich_text_composer/rich_text_composer.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/controller/base_rich_text_controller.dart';
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rich_text_composer/rich_text_composer.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:html_editor_enhanced/html_editor.dart';
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ import 'dart:math' as math;
|
||||
|
||||
import 'package:core/presentation/extensions/capitalize_extension.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/presentation/utils/style_utils.dart';
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:core/presentation/views/responsive/responsive_widget.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/keyboard_utils.dart';
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
Reference in New Issue
Block a user