From 5b4466af5229bc946fc34d9c31ea3a0043d8f6cf Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 21 Dec 2023 00:39:09 +0800 Subject: [PATCH] feat: make webView iframe font size follow user custom font size --- .../Feature/Configuration/EZConfiguration.m | 8 +-- .../AppleDictionary/apple-dictionary.html | 51 +++++++++++-------- .../View/WordResultView/EZWebViewManager.h | 2 + .../View/WordResultView/EZWebViewManager.m | 21 ++++++-- .../View/WordResultView/EZWordResultView.m | 26 ++++++++-- .../EZBaseQueryViewController.m | 12 ++--- 6 files changed, 81 insertions(+), 39 deletions(-) diff --git a/Easydict/Feature/Configuration/EZConfiguration.m b/Easydict/Feature/Configuration/EZConfiguration.m index 216e9c118..42a1568f0 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.m +++ b/Easydict/Feature/Configuration/EZConfiguration.m @@ -126,7 +126,7 @@ - (void)setup { self.fontSizes = @[@(1), @(1.1), @(1.2), @(1.3), @(1.4)]; [[NSUserDefaults standardUserDefaults]registerDefaults:@{kTranslationControllerFontKey: self.fontSizes.firstObject}]; - self.fontSizeRatio = [[NSUserDefaults standardUserDefaults]floatForKey:kTranslationControllerFontKey]; + self.fontSizeRatio = [[NSUserDefaults standardUserDefaults] floatForKey:kTranslationControllerFontKey]; } #pragma mark - getter @@ -418,9 +418,9 @@ - (void)setClearInput:(BOOL)clearInput { [self logSettings:@{@"clear_input" : @(clearInput)}]; } -- (void)setFontSizeRatio:(CGFloat)currentFontSizeRatio { - _fontSizeRatio = currentFontSizeRatio; - [NSUserDefaults mm_write:@(currentFontSizeRatio) forKey:kTranslationControllerFontKey]; +- (void)setFontSizeRatio:(CGFloat)fontSizeRatio { + _fontSizeRatio = fontSizeRatio; + [NSUserDefaults mm_write:@(fontSizeRatio) forKey:kTranslationControllerFontKey]; } #pragma mark - Window Frame diff --git a/Easydict/Feature/Service/Apple/AppleDictionary/apple-dictionary.html b/Easydict/Feature/Service/Apple/AppleDictionary/apple-dictionary.html index 11a7ccbf7..3b0f78082 100644 --- a/Easydict/Feature/Service/Apple/AppleDictionary/apple-dictionary.html +++ b/Easydict/Feature/Service/Apple/AppleDictionary/apple-dictionary.html @@ -331,6 +331,17 @@ iframe.style.height = totalHeight + "px"; // console.log(`${i}: frame totalHeight: ${totalHeight}`); + + + var scrollHeight = getScrollHeight(); + + if (window.webkit && window.webkit.messageHandlers) { + // 调用 objc 方法 + window.webkit.messageHandlers.objcHandler.postMessage({ + method: "noteToUpdateScrollHeight", + scrollHeight: scrollHeight, + }); + } } } @@ -372,8 +383,10 @@ bigWordTitleHeight + allIframesHeight + dictionaryTitleHeight * iframesHeight.length; - console.log(`iframesHeight: [${iframesHeight}]`); - console.log(`scrollHeight: ${scrollHeight}`); + + // console.log(`iframesHeight: [${iframesHeight}]`); + // console.log(`scrollHeight: ${scrollHeight}`); + return scrollHeight; } @@ -424,6 +437,19 @@ iframe.style.borderColor = newBorderColor; } } + + // Change all iframes body font size + function changeIframeBodyFontSize(fontSize) { + console.log("fontSize: " + fontSize); + var iframes = document.getElementsByTagName('iframe'); + for (var i = 0; i < iframes.length; i++) { + var iframe = iframes[i]; + var frameDoc = iframe.contentDocument || iframe.contentWindow.document; + + // 修改 iframe 中 body 的字体大小 + frameDoc.body.style.fontSize = fontSize; + } + } window.onload = function () { // 重写 console.log,以便在 Xcode 中输出日志 @@ -442,30 +468,11 @@ }; } - if (isDarkMode()) { - // updateAllIframeColor(true); - // updateBackgroundColor(true); - } - - updateAllIframeStyle(); - - var scrollHeight = getScrollHeight(); - - if (window.webkit && window.webkit.messageHandlers) { - // 调用 Objective-C 方法 - window.webkit.messageHandlers.objcHandler.postMessage({ - method: "getScrollHeight", - scrollHeight: scrollHeight, - }); - } - var colorSchemeListener = window.matchMedia( `(prefers-color-scheme: dark)` ); colorSchemeListener.addEventListener(`change`, function (event) { var isDarkMode = event.matches; - // updateAllIframeColor(isDarkMode); - // updateBackgroundColor(isDarkMode); }); }; @@ -473,4 +480,4 @@ - \ No newline at end of file + diff --git a/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.h b/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.h index afc177241..2a6ef6dc3 100644 --- a/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.h +++ b/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.h @@ -22,6 +22,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)reset; +- (void)updateAllIframe; + @end NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.m b/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.m index f2c4056c8..2219b9c76 100644 --- a/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.m +++ b/Easydict/Feature/ViewController/View/WordResultView/EZWebViewManager.m @@ -7,6 +7,7 @@ // #import "EZWebViewManager.h" +#import "EZConfiguration.h" static NSString *kObjcHandler = @"objcHandler"; static NSString *kMethod = @"method"; @@ -27,30 +28,42 @@ - (WKWebView *)webView { if (!_webView) { WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; [configuration.userContentController addScriptMessageHandler:self name:kObjcHandler]; - _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration]; } return _webView; } #pragma mark - WKScriptMessageHandler + // 处理来自 JavaScript 的消息 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { id body = message.body; - + if([message.name isEqualToString:kObjcHandler]) { if([body[kMethod] isEqualToString:@"consoleLog"]) { NSString *message = body[@"message"]; NSLog(@": %@", message); } - if([body[kMethod] isEqualToString:@"getScrollHeight"]) { + if([body[kMethod] isEqualToString:@"noteToUpdateScrollHeight"]) { CGFloat scrollHeight = [body[@"scrollHeight"] floatValue]; if (self.didFinishUpdatingIframeHeightBlock) { self.didFinishUpdatingIframeHeightBlock(scrollHeight); } } - } + } +} + +#pragma mark - WebView evaluateJavaScript + +- (void)updateAllIframe { + CGFloat fontSize = EZConfiguration.shared.fontSizeRatio * 100; // 140% + NSString *script = [NSString stringWithFormat:@"changeIframeBodyFontSize('%.1f%%'); updateAllIframeStyle();", fontSize]; + [self.webView evaluateJavaScript:script completionHandler:^(id _Nullable result, NSError *_Nullable error) { + if (!error) { + + } + }]; } - (void)reset { diff --git a/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m b/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m index f51b649f8..6f415b959 100644 --- a/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m +++ b/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m @@ -265,6 +265,10 @@ - (void)refreshWithResult:(EZQueryResult *)result { if (result.HTMLString.length) { [self addSubview:self.webView]; + if (result.webViewManager.isLoaded) { + [result.webViewManager updateAllIframe]; + } + [result.webViewManager setDidFinishUpdatingIframeHeightBlock:^(CGFloat scrollHeight) { mm_strongify(self); @@ -1050,18 +1054,16 @@ - (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"webView didFinishNavigation"); + [self.result.webViewManager updateAllIframe]; } - - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"didFailNavigation: %@", error); - } /** 请求服务器发生错误 (如果是goBack时,当前页面也会回调这个方法,原因是NSURLErrorCancelled取消加载) */ - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"didFailProvisionalNavigation: %@", error); - } // 监听 JavaScript 代码是否执行 @@ -1314,6 +1316,24 @@ - (void)getTextWithHref:(NSString *)href completionHandler:(void (^_Nullable)(NS }]; } +- (void)updateWebViewAllIframeFontSize { + CGFloat fontSize = EZConfiguration.shared.fontSizeRatio * 100; + + NSString *jsCode = [NSString stringWithFormat: + @"var iframes = document.querySelectorAll('iframe');" + @"for (var i = 0; i < iframes.length; i++) {" + @" var iframe = iframes[i];" + @" var frameDoc = iframe.contentDocument || iframe.contentWindow.document;" + @" frameDoc.body.style.fontSize = '%f%%';" + @"};", fontSize]; + + [self evaluateJavaScript:jsCode completionHandler:^(id _Nullable result, NSError *_Nullable error) { + if (!error) { + + } + }]; +} + #pragma mark - // Convert text to multiple lines, such as "Hello world" to "Hello\nworld" diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index a4a4f5633..f11946976 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -1257,19 +1257,19 @@ - (EZResultView *)resultCellAtRow:(NSInteger)row { if ([service.serviceType isEqualToString:EZServiceTypeAppleDictionary]) { EZAppleDictionary *appleDictService = (EZAppleDictionary *)service; - webView = result.webViewManager.webView; + EZWebViewManager *webViewManager = result.webViewManager; + webView = webViewManager.webView; resultCell.wordResultView.webView = webView; - BOOL needLoadHTML = result.isShowing && result.HTMLString.length && !result.webViewManager.isLoaded; + BOOL needLoadHTML = result.isShowing && result.HTMLString.length && !webViewManager.isLoaded; if (needLoadHTML) { - result.webViewManager.isLoaded = YES; + webViewManager.isLoaded = YES; NSURL *htmlFileURL = [NSURL fileURLWithPath:appleDictService.htmlFilePath]; webView.navigationDelegate = resultCell.wordResultView; [webView loadFileURL:htmlFileURL allowingReadAccessToURL:TTTDictionary.userDictionaryDirectoryURL]; - } else if (result.webViewManager.needUpdateIframeHeight && result.webViewManager.isLoaded) { - NSString *script = @"updateAllIframeStyle();"; - [webView evaluateJavaScript:script completionHandler:nil]; + } else if (webViewManager.needUpdateIframeHeight && webViewManager.isLoaded) { + [webViewManager updateAllIframe]; } }