|
14 | 14 | #import "objc/runtime.h" |
15 | 15 |
|
16 | 16 | static NSTimer *keyboardTimer; |
| 17 | +static NSString *const HistoryShimName = @"ReactNativeHistoryShim"; |
17 | 18 | static NSString *const MessageHandlerName = @"ReactNativeWebView"; |
18 | 19 | static NSURLCredential* clientAuthenticationCredential; |
19 | 20 | static NSDictionary* customCertificatesForHost; |
@@ -160,6 +161,31 @@ - (void)didMoveToWindow |
160 | 161 | } |
161 | 162 | wkWebViewConfig.userContentController = [WKUserContentController new]; |
162 | 163 |
|
| 164 | + // Shim the HTML5 history API: |
| 165 | + [wkWebViewConfig.userContentController addScriptMessageHandler:self name:HistoryShimName]; |
| 166 | + NSString *source = [NSString stringWithFormat: |
| 167 | + @"(function(history) {\n" |
| 168 | + " function notify(type) {\n" |
| 169 | + " setTimeout(function() {\n" |
| 170 | + " window.webkit.messageHandlers.%@.postMessage(type)\n" |
| 171 | + " }, 0)\n" |
| 172 | + " }\n" |
| 173 | + " function shim(f) {\n" |
| 174 | + " return function pushState() {\n" |
| 175 | + " notify('other')\n" |
| 176 | + " return f.apply(history, arguments)\n" |
| 177 | + " }\n" |
| 178 | + " }\n" |
| 179 | + " history.pushState = shim(history.pushState)\n" |
| 180 | + " history.replaceState = shim(history.replaceState)\n" |
| 181 | + " window.addEventListener('popstate', function() {\n" |
| 182 | + " notify('backforward')\n" |
| 183 | + " })\n" |
| 184 | + "})(window.history)\n", HistoryShimName |
| 185 | + ]; |
| 186 | + WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; |
| 187 | + [wkWebViewConfig.userContentController addUserScript:script]; |
| 188 | + |
163 | 189 | if (_messagingEnabled) { |
164 | 190 | [wkWebViewConfig.userContentController addScriptMessageHandler:self name:MessageHandlerName]; |
165 | 191 |
|
@@ -404,10 +430,18 @@ - (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBeh |
404 | 430 | - (void)userContentController:(WKUserContentController *)userContentController |
405 | 431 | didReceiveScriptMessage:(WKScriptMessage *)message |
406 | 432 | { |
407 | | - if (_onMessage != nil) { |
408 | | - NSMutableDictionary<NSString *, id> *event = [self baseEvent]; |
409 | | - [event addEntriesFromDictionary: @{@"data": message.body}]; |
410 | | - _onMessage(event); |
| 433 | + if ([message.name isEqualToString:HistoryShimName]) { |
| 434 | + if (_onLoadingFinish) { |
| 435 | + NSMutableDictionary<NSString *, id> *event = [self baseEvent]; |
| 436 | + [event addEntriesFromDictionary: @{@"navigationType": message.body}]; |
| 437 | + _onLoadingFinish(event); |
| 438 | + } |
| 439 | + } else if ([message.name isEqualToString:MessageHandlerName]) { |
| 440 | + if (_onMessage) { |
| 441 | + NSMutableDictionary<NSString *, id> *event = [self baseEvent]; |
| 442 | + [event addEntriesFromDictionary: @{@"data": message.body}]; |
| 443 | + _onMessage(event); |
| 444 | + } |
411 | 445 | } |
412 | 446 | } |
413 | 447 |
|
|
0 commit comments