diff --git a/core/lib/core.dart b/core/lib/core.dart index 9bc6ca3923..7a44cd0ee1 100644 --- a/core/lib/core.dart +++ b/core/lib/core.dart @@ -29,7 +29,6 @@ export 'presentation/utils/style_utils.dart'; export 'presentation/utils/app_toast.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'; diff --git a/core/lib/presentation/utils/html_transformer/dom/add_target_blank_in_tag_a_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/add_target_blank_in_tag_a_transformers.dart deleted file mode 100644 index a66a387d92..0000000000 --- a/core/lib/presentation/utils/html_transformer/dom/add_target_blank_in_tag_a_transformers.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:core/data/network/dio_client.dart'; -import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart'; -import 'package:html/dom.dart'; - -class AddTargetBlankInTagATransformer extends DomTransformer { - const AddTargetBlankInTagATransformer(); - - @override - Future process({ - required Document document, - required DioClient dioClient, - Map? mapUrlDownloadCID, - }) async { - final elements = document.querySelectorAll('a'); - await Future.wait(elements.map((element) async { - element.attributes['target'] = '_blank'; - final rel = element.attributes['rel']; - if (rel == null || (!rel.contains('noopener') && !rel.contains('noreferrer'))) { - element.attributes['rel'] = 'noreferrer'; - } - })); - } -} diff --git a/core/lib/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart deleted file mode 100644 index 48466aac27..0000000000 --- a/core/lib/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart +++ /dev/null @@ -1,44 +0,0 @@ - -import 'package:core/data/network/dio_client.dart'; -import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart'; -import 'package:core/utils/html/html_template.dart'; -import 'package:html/dom.dart'; - -class AddTooltipLinkTransformer extends DomTransformer { - - const AddTooltipLinkTransformer(); - - @override - Future process({ - required Document document, - required DioClient dioClient, - Map? mapUrlDownloadCID, - }) async { - final linkElements = document.querySelectorAll('a[href^="http"]'); - await Future.wait(linkElements.map((linkElement) async { - _addToolTipWhenHoverLink(linkElement); - })); - } - - void _addToolTipWhenHoverLink(Element element) { - final url = element.attributes['href']; - final text = element.text; - final children = element.children; - if (children.isEmpty && text.isNotEmpty && url != null) { - final innerHtml = element.innerHtml; - final tagClass = element.attributes['class']; - if (tagClass != null) { - element.attributes['class'] = '$tagClass ${HtmlTemplate.nameClassToolTip}'; - } else { - element.attributes['class'] = HtmlTemplate.nameClassToolTip; - } - element.innerHtml = innerHtml + textHasToolTip(url); - } - } - - String textHasToolTip(String url) { - return ''' - $url - '''; - } -} \ No newline at end of file diff --git a/core/lib/presentation/utils/html_transformer/dom/blockcode_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/block_code_transformers.dart similarity index 100% rename from core/lib/presentation/utils/html_transformer/dom/blockcode_transformers.dart rename to core/lib/presentation/utils/html_transformer/dom/block_code_transformers.dart diff --git a/core/lib/presentation/utils/html_transformer/dom/blockquoted_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/block_quoted_transformers.dart similarity index 100% rename from core/lib/presentation/utils/html_transformer/dom/blockquoted_transformers.dart rename to core/lib/presentation/utils/html_transformer/dom/block_quoted_transformers.dart diff --git a/core/lib/presentation/utils/html_transformer/dom/sanitize_tag_a_in_html_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/sanitize_tag_a_in_html_transformers.dart new file mode 100644 index 0000000000..4e2e67555f --- /dev/null +++ b/core/lib/presentation/utils/html_transformer/dom/sanitize_tag_a_in_html_transformers.dart @@ -0,0 +1,61 @@ +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/sanitize_url.dart'; +import 'package:core/utils/html/html_template.dart'; +import 'package:html/dom.dart'; + +class SanitizeTagAInHtmlTransformer extends DomTransformer { + final _sanitizeUrl = SanitizeUrl(); + final bool useTooltip; + + SanitizeTagAInHtmlTransformer({this.useTooltip = false}); + + @override + Future process({ + required Document document, + required DioClient dioClient, + Map? mapUrlDownloadCID, + }) async { + final elements = document.querySelectorAll('a'); + await Future.wait(elements.map((element) async { + _addToolTipWhenHoverLink(element); + _addBlankForTargetProperty(element); + _addNoReferrerForRelProperty(element); + })); + } + + void _addToolTipWhenHoverLink(Element element) { + final url = element.attributes['href'] ?? ''; + + final urlSanitized = _sanitizeUrl.process(url); + if (urlSanitized.isEmpty) { + return; + } + + element.attributes['href'] = urlSanitized; + + final text = element.text; + final children = element.children; + if (children.isEmpty && text.isNotEmpty) { + final innerHtml = element.innerHtml; + final tagClass = element.attributes['class']; + if (tagClass != null) { + element.attributes['class'] = '$tagClass ${HtmlTemplate.nameClassToolTip}'; + } else { + element.attributes['class'] = HtmlTemplate.nameClassToolTip; + } + element.innerHtml = '$innerHtml $url'; + } + } + + void _addBlankForTargetProperty(Element element) { + element.attributes['target'] = '_blank'; + } + + void _addNoReferrerForRelProperty(Element element) { + final rel = element.attributes['rel']; + if (rel == null || (!rel.contains('noopener') && !rel.contains('noreferrer'))) { + element.attributes['rel'] = 'noreferrer'; + } + } +} diff --git a/core/lib/presentation/utils/html_transformer/dom/sigature_transformers.dart b/core/lib/presentation/utils/html_transformer/dom/signature_transformers.dart similarity index 100% rename from core/lib/presentation/utils/html_transformer/dom/sigature_transformers.dart rename to core/lib/presentation/utils/html_transformer/dom/signature_transformers.dart diff --git a/core/lib/presentation/utils/html_transformer/transform_configuration.dart b/core/lib/presentation/utils/html_transformer/transform_configuration.dart index 6c8ad45207..0f6719c517 100644 --- a/core/lib/presentation/utils/html_transformer/transform_configuration.dart +++ b/core/lib/presentation/utils/html_transformer/transform_configuration.dart @@ -2,10 +2,8 @@ import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart'; import 'package:core/presentation/utils/html_transformer/base/text_transformer.dart'; import 'package:core/presentation/utils/html_transformer/dom/add_lazy_loading_for_background_image_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/add_target_blank_in_tag_a_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/blockcode_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/blockquoted_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/block_code_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/block_quoted_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/image_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_collapsed_signature_button_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_for_background_image_transformers.dart'; @@ -13,8 +11,9 @@ import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading import 'package:core/presentation/utils/html_transformer/dom/remove_max_width_in_image_style_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_style_tag_outside_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/sanitize_tag_a_in_html_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/script_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/sigature_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/signature_transformers.dart'; import 'package:core/presentation/utils/html_transformer/text/sanitize_autolink_html_transformers.dart'; import 'package:core/utils/platform_info.dart'; @@ -53,9 +52,8 @@ class TransformConfiguration { const RemoveScriptTransformer(), const BlockQuotedTransformer(), const BlockCodeTransformer(), - const AddTargetBlankInTagATransformer(), + SanitizeTagAInHtmlTransformer(useTooltip: true), const ImageTransformer(), - const AddTooltipLinkTransformer(), const AddLazyLoadingForBackgroundImageTransformer(), const RemoveCollapsedSignatureButtonTransformer(), ] @@ -74,7 +72,7 @@ class TransformConfiguration { ]); /// Provides easy access to a standard configuration that does not block external images. - static const TransformConfiguration standardConfiguration = TransformConfiguration( + static TransformConfiguration standardConfiguration = TransformConfiguration( standardDomTransformers, standardTextTransformers ); @@ -100,14 +98,14 @@ class TransformConfiguration { ); } - static const List standardDomTransformers = [ - RemoveScriptTransformer(), - BlockQuotedTransformer(), - BlockCodeTransformer(), - AddTargetBlankInTagATransformer(), - ImageTransformer(), - AddLazyLoadingForBackgroundImageTransformer(), - RemoveCollapsedSignatureButtonTransformer(), + static List standardDomTransformers = [ + const RemoveScriptTransformer(), + const BlockQuotedTransformer(), + const BlockCodeTransformer(), + SanitizeTagAInHtmlTransformer(), + const ImageTransformer(), + const AddLazyLoadingForBackgroundImageTransformer(), + const RemoveCollapsedSignatureButtonTransformer(), ]; static const List standardTextTransformers = [ diff --git a/lib/features/manage_account/data/datasource_impl/identity_data_source_impl.dart b/lib/features/manage_account/data/datasource_impl/identity_data_source_impl.dart index 7cbf828728..046b23b369 100644 --- a/lib/features/manage_account/data/datasource_impl/identity_data_source_impl.dart +++ b/lib/features/manage_account/data/datasource_impl/identity_data_source_impl.dart @@ -1,8 +1,7 @@ -import 'package:core/presentation/utils/html_transformer/dom/add_target_blank_in_tag_a_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/blockcode_transformers.dart'; -import 'package:core/presentation/utils/html_transformer/dom/blockquoted_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/block_code_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/block_quoted_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/image_transformers.dart'; +import 'package:core/presentation/utils/html_transformer/dom/sanitize_tag_a_in_html_transformers.dart'; import 'package:core/presentation/utils/html_transformer/dom/script_transformers.dart'; import 'package:core/presentation/utils/html_transformer/html_transform.dart'; import 'package:core/presentation/utils/html_transformer/transform_configuration.dart'; @@ -67,9 +66,8 @@ class IdentityDataSourceImpl extends IdentityDataSource { const RemoveScriptTransformer(), const BlockQuotedTransformer(), const BlockCodeTransformer(), - const AddTargetBlankInTagATransformer(), + SanitizeTagAInHtmlTransformer(useTooltip: PlatformInfo.isWeb), const ImageTransformer(), - if (PlatformInfo.isWeb) const AddTooltipLinkTransformer() ])); return signatureUnescape; }).catchError(_exceptionThrower.throwException);