Skip to content

Commit

Permalink
fix(window): added window.print function (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
mustafauyysl authored Feb 20, 2024
1 parent cdecd91 commit ff4f749
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintJob;
import android.print.PrintManager;
import android.text.TextUtils;
import android.util.AttributeSet;

Expand Down Expand Up @@ -85,6 +90,13 @@ public class RNCWebView extends WebView implements LifecycleEventListener {
public RNCWebView(ThemedReactContext reactContext) {
super(reactContext);
this.createCatalystInstance();

// The bridge is necessary to support the window.print() functionality.
// Not sure, is there any significant drawback just to always create it,
// vs. any noticeable benefit to make the print() support and opt-in feature,
// that will ensure the brige creation if a flag is set on WebView in JS layer.
this.createRNCWebViewBridge(this);

progressChangedFilter = new ProgressChangedFilter();
}

Expand Down Expand Up @@ -284,10 +296,16 @@ public void callInjectedJavaScript() {
}

public void callInjectedJavaScriptBeforeContentLoaded() {
if (getSettings().getJavaScriptEnabled() &&
injectedJSBeforeContentLoaded != null &&
!TextUtils.isEmpty(injectedJSBeforeContentLoaded)) {
if (getSettings().getJavaScriptEnabled()) {
// This is necessary to support window.print() in the loaded web pages.
evaluateJavascriptWithFallback(
"(function(){window.print=function(){window.ReactNativeWebView.print();};})();"
);

if (injectedJSBeforeContentLoaded != null &&
!TextUtils.isEmpty(injectedJSBeforeContentLoaded)) {
evaluateJavascriptWithFallback("(function() {\n" + injectedJSBeforeContentLoaded + ";\n})();");
}
}
}

Expand Down Expand Up @@ -393,6 +411,27 @@ protected class RNCWebViewBridge {
mWebView = c;
}

@JavascriptInterface
public void print() {
// This code is adopted from https://developer.android.com/training/printing/html-docs
// but all WebView methods must be called from the same thread, and this bridge method
// is called on a different thread, thus the need to post a runnable to the handler.
WebView view = this.mWebView;
Handler handler = view.getHandler();
handler.post(new Runnable() {
@Override
public void run() {
PrintManager manager = (PrintManager) view.getContext().getSystemService(Context.PRINT_SERVICE);
String jobName = view.getTitle();
PrintDocumentAdapter adapter = view.createPrintDocumentAdapter(jobName);
PrintJob job = manager.print(jobName, adapter, new PrintAttributes.Builder().build());
// NOTE: Here `job` can be kept around and used to further check on the print job status,
// but it is not required, according to the docs, so no need to do it for now.
}
});
}


/**
* This method is called whenever JavaScript running within the web view calls:
* - window[JAVASCRIPT_INTERFACE].postMessage
Expand Down
22 changes: 22 additions & 0 deletions apple/RNCWebViewImpl.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
static NSTimer *keyboardTimer;
static NSString *const HistoryShimName = @"ReactNativeHistoryShim";
static NSString *const MessageHandlerName = @"ReactNativeWebView";
static NSString *const PrintingHandlerName = @"ReactNativeWebViewPrinting";
static NSURLCredential* clientAuthenticationCredential;
static NSDictionary* customCertificatesForHost;

Expand Down Expand Up @@ -412,6 +413,9 @@ - (WKWebViewConfiguration *)setUpWkWebViewConfig
}
#endif

// Sets up the window.print() support
[wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
name:PrintingHandlerName];
// Shim the HTML5 history API:
[wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
name:HistoryShimName];
Expand Down Expand Up @@ -536,6 +540,7 @@ - (void)removeFromSuperview
if (_webView) {
[_webView.configuration.userContentController removeScriptMessageHandlerForName:HistoryShimName];
[_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHandlerName];
[_webView.configuration.userContentController removeScriptMessageHandlerForName:PrintingHandlerName];
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
[_webView removeFromSuperview];
#if !TARGET_OS_OSX
Expand Down Expand Up @@ -702,6 +707,10 @@ - (void)userContentController:(WKUserContentController *)userContentController
[event addEntriesFromDictionary: @{@"data": message.body}];
_onMessage(event);
}
} else if ([message.name isEqualToString:PrintingHandlerName]) {
UIPrintInteractionController *ctrl = UIPrintInteractionController.sharedPrintController;
ctrl.printFormatter = _webView.viewPrintFormatter;
[ctrl presentAnimated:YES completionHandler:nil];
}
}

Expand Down Expand Up @@ -1667,6 +1676,19 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig {
WKUserScript *script = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
[wkWebViewConfig.userContentController addUserScript:script];

// This is for the window.print() support.
NSString *windowPrintSource = [NSString stringWithFormat:
@"(function() {"
" window.print = function() {"
" window.webkit.messageHandlers.%@.postMessage('');"
" };"
"})();", PrintingHandlerName];
WKUserScript *windowPrintScript = [[WKUserScript alloc]
initWithSource:windowPrintSource
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:YES];
[wkWebViewConfig.userContentController addUserScript:windowPrintScript];

if(_sharedCookiesEnabled) {
// More info to sending cookies with WKWebView
// https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
Expand Down

0 comments on commit ff4f749

Please sign in to comment.