Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,32 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView {
}

- (void)renderButtons:(UIWebView*)webView {
UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0];
UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:11.0];

UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[callbackButton setTitle:@"Call handler" forState:UIControlStateNormal];
[callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:callbackButton aboveSubview:webView];
callbackButton.frame = CGRectMake(10, 400, 100, 35);
callbackButton.frame = CGRectMake(0, 400, 100, 35);
callbackButton.titleLabel.font = font;

UIButton* reloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[reloadButton setTitle:@"Reload webview" forState:UIControlStateNormal];
[reloadButton addTarget:webView action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:reloadButton aboveSubview:webView];
reloadButton.frame = CGRectMake(110, 400, 100, 35);
reloadButton.frame = CGRectMake(90, 400, 100, 35);
reloadButton.titleLabel.font = font;

UIButton* safetyTimeoutButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[safetyTimeoutButton setTitle:@"Disable safety timeout" forState:UIControlStateNormal];
[safetyTimeoutButton addTarget:self action:@selector(disableSafetyTimeout) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:safetyTimeoutButton aboveSubview:webView];
safetyTimeoutButton.frame = CGRectMake(190, 400, 120, 35);
safetyTimeoutButton.titleLabel.font = font;
}

- (void)disableSafetyTimeout {
[self.bridge disableJavscriptAlertBoxSafetyTimeout];
}

- (void)callHandler:(id)sender {
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ WebViewJavascriptBridge is used by a range of companies and projects. This is a
- [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8)
- [FRIL](https://fril.jp)
- [留白·WHITE](http://liubaiapp.com)
- [BrowZine](http://thirdiron.com/browzine/)

Installation (iOS & OSX)
------------------------
Expand Down Expand Up @@ -198,6 +199,13 @@ Example:

Optionally, set a `UIWebViewDelegate` if you need to respond to the [web view's lifecycle events](http://developer.apple.com/library/ios/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html).

##### `[bridge disableJavscriptAlertBoxSafetyTimeout]`

UNSAFE. Speed up bridge message passing by disabling the setTimeout safety check. It is only safe to disable this safety check if you do not call any of the javascript popup box functions (alert, confirm, and prompt). If you call any of these functions from the bridged javascript code, the app will hang.

Example:

[self.bridge disableJavscriptAlertBoxSafetyTimeout];



Expand Down Expand Up @@ -230,3 +238,14 @@ bridge.callHandler("getScreenHeight", null, function(response) {
alert('Screen height:' + response)
})
```


##### `bridge.disableJavscriptAlertBoxSafetyTimeout()`

Calling `bridge.disableJavscriptAlertBoxSafetyTimeout()` has the same effect as calling `[bridge disableJavscriptAlertBoxSafetyTimeout];` in ObjC.

Example:

```javascript
bridge.disableJavscriptAlertBoxSafetyTimeout()
```
20 changes: 20 additions & 0 deletions Tests/WebViewJavascriptBridgeTests/BridgeTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ - (void)classSpecificTestJavascriptReceiveResponse:(Class)cls webView:(id)webVie
}];
}

- (void)testJavascriptReceiveResponseWithoutSafetyTimeout {
[self classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:[WebViewJavascriptBridge class] webView:_uiWebView];
[self classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:[WKWebViewJavascriptBridge class] webView:_wkWebView];
[self waitForExpectationsWithTimeout:3 handler:NULL];
}
- (void)classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:(Class)cls webView:(id)webView {
WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView];
[bridge disableJavscriptAlertBoxSafetyTimeout];
loadEchoSample(webView);
XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"];
[bridge registerHandler:@"objcEchoToJs" handler:^(id data, WVJBResponseCallback responseCallback) {
responseCallback(data);
}];
[bridge callHandler:@"jsRcvResponseTest" data:nil responseCallback:^(id responseData) {
XCTAssertEqualObjects(responseData, @"Response from JS");
[callbackInvocked fulfill];
}];
}


- (WebViewJavascriptBridge*)bridgeForCls:(Class)cls webView:(id)webView {
if (cls == [WebViewJavascriptBridge class]) {
return [WebViewJavascriptBridge bridgeForWebView:webView];
Expand Down
1 change: 1 addition & 0 deletions WebViewJavascriptBridge/WKWebViewJavascriptBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;
- (void)reset;
- (void)setWebViewDelegate:(id<WKNavigationDelegate>)webViewDelegate;
- (void)disableJavscriptAlertBoxSafetyTimeout;

@end

Expand Down
4 changes: 4 additions & 0 deletions WebViewJavascriptBridge/WKWebViewJavascriptBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ - (void)setWebViewDelegate:(id<WKNavigationDelegate>)webViewDelegate {
_webViewDelegate = webViewDelegate;
}

- (void)disableJavscriptAlertBoxSafetyTimeout {
[_base disableJavscriptAlertBoxSafetyTimeout];
}

/* Internals
***********/

Expand Down
2 changes: 2 additions & 0 deletions WebViewJavascriptBridge/WebViewJavascriptBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@
- (void)callHandler:(NSString*)handlerName data:(id)data;
- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;
- (void)setWebViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate;
- (void)disableJavscriptAlertBoxSafetyTimeout;

@end
5 changes: 5 additions & 0 deletions WebViewJavascriptBridge/WebViewJavascriptBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
_base.messageHandlers[handlerName] = [handler copy];
}

- (void)disableJavscriptAlertBoxSafetyTimeout {
[_base disableJavscriptAlertBoxSafetyTimeout];
}


/* Platform agnostic internals
*****************************/

Expand Down
1 change: 1 addition & 0 deletions WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ typedef NSDictionary WVJBMessage;
- (void)logUnkownMessage:(NSURL*)url;
- (NSString *)webViewJavascriptCheckCommand;
- (NSString *)webViewJavascriptFetchQueyCommand;
- (void)disableJavscriptAlertBoxSafetyTimeout;

@end
4 changes: 4 additions & 0 deletions WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ -(NSString *)webViewJavascriptFetchQueyCommand {
return @"WebViewJavascriptBridge._fetchQueue();";
}

- (void)disableJavscriptAlertBoxSafetyTimeout {
[self sendData:nil responseCallback:nil handlerName:@"_disableJavascriptAlertBoxSafetyTimeout"];
}

// Private
// -------------------------------------------

Expand Down
17 changes: 15 additions & 2 deletions WebViewJavascriptBridge/WebViewJavascriptBridge_JS.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
window.WebViewJavascriptBridge = {
registerHandler: registerHandler,
callHandler: callHandler,
disableJavscriptAlertBoxSafetyTimeout: disableJavscriptAlertBoxSafetyTimeout,
_fetchQueue: _fetchQueue,
_handleMessageFromObjC: _handleMessageFromObjC
};
Expand All @@ -41,6 +42,7 @@

var responseCallbacks = {};
var uniqueId = 1;
var dispatchMessagesWithTimeoutSafety = true;

function registerHandler(handlerName, handler) {
messageHandlers[handlerName] = handler;
Expand All @@ -53,6 +55,9 @@ function callHandler(handlerName, data, responseCallback) {
}
_doSend({ handlerName:handlerName, data:data }, responseCallback);
}
function disableJavscriptAlertBoxSafetyTimeout() {
dispatchMessagesWithTimeoutSafety = false;
}

function _doSend(message, responseCallback) {
if (responseCallback) {
Expand All @@ -71,7 +76,13 @@ function _fetchQueue() {
}

function _dispatchMessageFromObjC(messageJSON) {
setTimeout(function _timeoutDispatchMessageFromObjC() {
if (dispatchMessagesWithTimeoutSafety) {
setTimeout(_doDispatchMessageFromObjC);
} else {
_doDispatchMessageFromObjC();
}

function _doDispatchMessageFromObjC() {
var message = JSON.parse(messageJSON);
var messageHandler;
var responseCallback;
Expand All @@ -98,7 +109,7 @@ function _dispatchMessageFromObjC(messageJSON) {
handler(message.data, responseCallback);
}
}
});
}
}

function _handleMessageFromObjC(messageJSON) {
Expand All @@ -110,6 +121,8 @@ function _handleMessageFromObjC(messageJSON) {
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
document.documentElement.appendChild(messagingIframe);

registerHandler("_disableJavascriptAlertBoxSafetyTimeout", disableJavscriptAlertBoxSafetyTimeout);

setTimeout(_callWVJBCallbacks, 0);
function _callWVJBCallbacks() {
var callbacks = window.WVJBCallbacks;
Expand Down