|  | 
| 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