Index: ios/web/web_state/ui/web_view_js_utils.mm |
diff --git a/ios/web/web_state/ui/web_view_js_utils.mm b/ios/web/web_state/ui/web_view_js_utils.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9e914aaccdd4c74db3094c706407f55d86cf9682 |
--- /dev/null |
+++ b/ios/web/web_state/ui/web_view_js_utils.mm |
@@ -0,0 +1,75 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "ios/web/web_state/ui/web_view_js_utils.h" |
+ |
+#import <UIKit/UIKit.h> |
+#import <WebKit/WebKit.h> |
+ |
+#include "base/ios/weak_nsobject.h" |
+#include "base/logging.h" |
+#include "base/mac/scoped_nsobject.h" |
+ |
+namespace { |
+ |
+// Converts result of WKWebView script evaluation to UIWebView format. |
+NSString* UIResultFromWKResult(id result) { |
+ if (!result) |
+ return @""; |
+ |
+ CFTypeID result_type = CFGetTypeID(result); |
+ if (result_type == CFStringGetTypeID()) |
+ return result; |
+ |
+ if (result_type == CFNumberGetTypeID()) |
+ return [result stringValue]; |
+ |
+ if (result_type == CFBooleanGetTypeID()) |
+ return [result boolValue] ? @"true" : @"false"; |
+ |
+ // TODO(stuartmorgan): Stringify other types. |
+ NOTREACHED(); |
+ return nil; |
+} |
+ |
+} // namespace |
+ |
+namespace web { |
+ |
+void EvaluateJavaScript(UIWebView* web_view, |
+ NSString* script, |
+ JavaScriptCompletion completion_handler) { |
+ base::WeakNSObject<UIWebView> weak_web_view(web_view); |
+ dispatch_async(dispatch_get_main_queue(), ^{ |
+ NSString* result = |
+ [weak_web_view stringByEvaluatingJavaScriptFromString:script]; |
+ if (completion_handler) |
+ completion_handler(result, nil); |
+ }); |
+} |
+ |
+void EvaluateJavaScript(WKWebView* web_view, |
+ NSString* script, |
+ JavaScriptCompletion completion_handler) { |
+ DCHECK([script length]); |
+ id web_view_completion_handler = nil; |
droger
2015/02/19 10:51:04
Why id?
sdefresne
2015/02/19 13:39:08
Good catch.
|
+ // Do not create a web_view_completion_handler if no |handler| is passed to |
+ // this function. This results in no creation of an unnecessary block. |
+ if (completion_handler) { |
+ // WKWebView crashes on deallocation when it flushes scripts that did not |
+ // finish the execution but have |completion_handler|. Passing |
+ // |completion_handler| ownership to the block itself and keeping it alive |
+ // until it's executed fixes the crash. No memory leak is expected since |
+ // |completion_handler| is always executed even if WKWebView is deallocated. |
+ // https://bugs.webkit.org/show_bug.cgi?id=140203 |
+ web_view_completion_handler = [^(id result, NSError* error) { |
+ completion_handler(UIResultFromWKResult(result), error); |
+ [web_view_completion_handler autorelease]; |
droger
2015/02/19 10:51:04
This looks like a bug.
I think that the block capt
sdefresne
2015/02/19 13:39:08
I no longer require this file, so the question app
stuartmorgan
2015/02/19 14:23:54
Yep, this does look worrying. I'll investigate.
Eugene But (OOO till 7-30)
2015/02/23 03:20:11
What exactly looks wrong to you? Functionality or
|
+ } copy]; |
+ } |
+ [web_view evaluateJavaScript:script |
+ completionHandler:web_view_completion_handler]; |
+} |
+ |
+} // namespace web |