Add lazy loading for html tag use background-image

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit 7f1a3b22ee8973c6756534a2c7da3cc1964ea9de)
This commit is contained in:
dab246
2023-10-16 18:45:27 +07:00
committed by Dat H. Pham
parent 72ba6d4145
commit 967015d0df
6 changed files with 130 additions and 16 deletions
@@ -1,5 +1,7 @@
import 'package:core/data/network/dio_client.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
import 'package:html/dom.dart';
/// Transforms the HTML DOM.
@@ -22,4 +24,26 @@ abstract class DomTransformer {
document.children.insert(0, Element.html('<head></head>'));
}
}
Tuple2<String, String>? findImageUrlFromStyleTag(String style) {
try {
final regExp = RegExp(r'background-image:\s*url\(([^)]+)\).*?');
final match = regExp.firstMatch(style);
if (match == null) {
return null;
}
final backgroundImageUrl = match.group(0) ?? '';
final imageUrl = match.group(1)?.replaceAll('\'', '').replaceAll('"', '') ?? '';
log('DomTransformer::findImageUrlFromStyleTag:backgroundImageUrl: $backgroundImageUrl | imageUrl: $imageUrl');
if (backgroundImageUrl.isNotEmpty && imageUrl.isNotEmpty) {
return Tuple2(backgroundImageUrl, imageUrl);
} else {
return null;
}
} catch (e) {
logError('DomTransformer::findImageUrlFromStyleTag:Exception: $e');
return null;
}
}
}
@@ -0,0 +1,29 @@
import 'package:core/data/network/dio_client.dart';
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
import 'package:core/utils/app_logger.dart';
import 'package:html/dom.dart';
class AddLazyLoadingForBackgroundImageTransformer extends DomTransformer {
const AddLazyLoadingForBackgroundImageTransformer();
@override
Future<void> process({
required Document document,
required DioClient dioClient,
Map<String, String>? mapUrlDownloadCID,
}) async {
final elements = document.querySelectorAll('[style*="background-image"]');
log('AddLazyLoadingForBackgroundImageTagTransformer::process:elements: ${elements.length}');
await Future.wait(elements.map((element) async {
var exStyle = element.attributes['style'];
final imageUrls = findImageUrlFromStyleTag(exStyle!);
if (imageUrls != null) {
exStyle = exStyle.replaceFirst(imageUrls.value1, '');
element.attributes['style'] = exStyle;
element.attributes['data-src'] = imageUrls.value2;
element.attributes.addAll({'lazy': ''});
log('AddLazyLoadingForBackgroundImageTagTransformer::process:NEW_ELEMENT: ${element.outerHtml}');
}
}));
}
}
@@ -72,6 +72,29 @@ class HtmlUtils {
</script>
''';
static const scriptsHandleLazyLoadingBackgroundImage = '''
<script>
const lazyImages = document.querySelectorAll('[lazy]');
const lazyImageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target;
const src = lazyImage.dataset.src;
lazyImage.tagName.toLowerCase() === 'img'
? lazyImage.src = src
: lazyImage.style.backgroundImage = "url(\'" + src + "\')";
lazyImage.removeAttribute('lazy');
observer.unobserve(lazyImage);
}
});
});
lazyImages.forEach((lazyImage) => {
lazyImageObserver.observe(lazyImage);
});
</script>
''';
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
if (PlatformInfo.isWeb) {
return '''
@@ -2,6 +2,7 @@
import 'package:core/core.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/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/blockcode_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/blockquoted_transformers.dart';
@@ -48,6 +49,7 @@ class TransformConfiguration {
const AddTargetBlankInTagATransformer(),
const ImageTransformer(),
const AddTooltipLinkTransformer(),
const AddLazyLoadingForBackgroundImageTransformer(),
]
);
@@ -86,6 +88,7 @@ class TransformConfiguration {
BlockCodeTransformer(),
AddTargetBlankInTagATransformer(),
ImageTransformer(),
AddLazyLoadingForBackgroundImageTransformer(),
];
static const List<TextTransformer> standardTextTransformers = [