TF-2903 Handling of 3D links
This commit is contained in:
@@ -31,7 +31,6 @@ export 'presentation/utils/style_utils.dart';
|
|||||||
export 'presentation/utils/app_toast.dart';
|
export 'presentation/utils/app_toast.dart';
|
||||||
export 'presentation/utils/html_transformer/html_transform.dart';
|
export 'presentation/utils/html_transformer/html_transform.dart';
|
||||||
export 'presentation/utils/html_transformer/transform_configuration.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 'data/utils/device_manager.dart';
|
||||||
export 'utils/app_logger.dart';
|
export 'utils/app_logger.dart';
|
||||||
export 'utils/benchmark.dart';
|
export 'utils/benchmark.dart';
|
||||||
|
|||||||
-23
@@ -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<void> process({
|
|
||||||
required Document document,
|
|
||||||
required DioClient dioClient,
|
|
||||||
Map<String, String>? 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';
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<void> process({
|
|
||||||
required Document document,
|
|
||||||
required DioClient dioClient,
|
|
||||||
Map<String, String>? 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 '''
|
|
||||||
<span class="tooltiptext">$url</span>
|
|
||||||
''';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+61
@@ -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<void> process({
|
||||||
|
required Document document,
|
||||||
|
required DioClient dioClient,
|
||||||
|
Map<String, String>? 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 <span class="tooltiptext">$url</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,9 @@
|
|||||||
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
|
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/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_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/hide_draft_signature_transformer.dart';
|
import 'package:core/presentation/utils/html_transformer/dom/hide_draft_signature_transformer.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/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_collapsed_signature_button_transformers.dart';
|
||||||
import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_for_background_image_transformers.dart';
|
import 'package:core/presentation/utils/html_transformer/dom/remove_lazy_loading_for_background_image_transformers.dart';
|
||||||
@@ -14,8 +12,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_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_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/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/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/presentation/utils/html_transformer/text/sanitize_autolink_html_transformers.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
|
|
||||||
@@ -57,9 +56,8 @@ class TransformConfiguration {
|
|||||||
const RemoveScriptTransformer(),
|
const RemoveScriptTransformer(),
|
||||||
const BlockQuotedTransformer(),
|
const BlockQuotedTransformer(),
|
||||||
const BlockCodeTransformer(),
|
const BlockCodeTransformer(),
|
||||||
const AddTargetBlankInTagATransformer(),
|
SanitizeTagAInHtmlTransformer(useTooltip: true),
|
||||||
const ImageTransformer(),
|
const ImageTransformer(),
|
||||||
const AddTooltipLinkTransformer(),
|
|
||||||
const AddLazyLoadingForBackgroundImageTransformer(),
|
const AddLazyLoadingForBackgroundImageTransformer(),
|
||||||
const RemoveCollapsedSignatureButtonTransformer(),
|
const RemoveCollapsedSignatureButtonTransformer(),
|
||||||
]
|
]
|
||||||
@@ -80,7 +78,7 @@ class TransformConfiguration {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
/// Provides easy access to a standard configuration that does not block external images.
|
/// Provides easy access to a standard configuration that does not block external images.
|
||||||
static const TransformConfiguration standardConfiguration = TransformConfiguration(
|
static TransformConfiguration standardConfiguration = TransformConfiguration(
|
||||||
standardDomTransformers,
|
standardDomTransformers,
|
||||||
standardTextTransformers
|
standardTextTransformers
|
||||||
);
|
);
|
||||||
@@ -106,14 +104,14 @@ class TransformConfiguration {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const List<DomTransformer> standardDomTransformers = [
|
static List<DomTransformer> standardDomTransformers = [
|
||||||
RemoveScriptTransformer(),
|
const RemoveScriptTransformer(),
|
||||||
BlockQuotedTransformer(),
|
const BlockQuotedTransformer(),
|
||||||
BlockCodeTransformer(),
|
const BlockCodeTransformer(),
|
||||||
AddTargetBlankInTagATransformer(),
|
SanitizeTagAInHtmlTransformer(),
|
||||||
ImageTransformer(),
|
const ImageTransformer(),
|
||||||
AddLazyLoadingForBackgroundImageTransformer(),
|
const AddLazyLoadingForBackgroundImageTransformer(),
|
||||||
RemoveCollapsedSignatureButtonTransformer(),
|
const RemoveCollapsedSignatureButtonTransformer(),
|
||||||
];
|
];
|
||||||
|
|
||||||
static const List<TextTransformer> standardTextTransformers = [
|
static const List<TextTransformer> standardTextTransformers = [
|
||||||
|
|||||||
@@ -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/block_code_transformers.dart';
|
||||||
import 'package:core/presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart';
|
import 'package:core/presentation/utils/html_transformer/dom/block_quoted_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/image_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/dom/script_transformers.dart';
|
||||||
import 'package:core/presentation/utils/html_transformer/html_transform.dart';
|
import 'package:core/presentation/utils/html_transformer/html_transform.dart';
|
||||||
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
|
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
|
||||||
@@ -67,9 +66,8 @@ class IdentityDataSourceImpl extends IdentityDataSource {
|
|||||||
const RemoveScriptTransformer(),
|
const RemoveScriptTransformer(),
|
||||||
const BlockQuotedTransformer(),
|
const BlockQuotedTransformer(),
|
||||||
const BlockCodeTransformer(),
|
const BlockCodeTransformer(),
|
||||||
const AddTargetBlankInTagATransformer(),
|
SanitizeTagAInHtmlTransformer(useTooltip: PlatformInfo.isWeb),
|
||||||
const ImageTransformer(),
|
const ImageTransformer(),
|
||||||
if (PlatformInfo.isWeb) const AddTooltipLinkTransformer()
|
|
||||||
]));
|
]));
|
||||||
return signatureUnescape;
|
return signatureUnescape;
|
||||||
}).catchError(_exceptionThrower.throwException);
|
}).catchError(_exceptionThrower.throwException);
|
||||||
|
|||||||
Reference in New Issue
Block a user