WebViewDidCreateJavaScriptContext.mm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * Copyright (C) 2013 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #import "config.h"
  26. #import "PlatformUtilities.h"
  27. #import <JavaScriptCore/JSExport.h>
  28. #import <JavaScriptCore/JSContext.h>
  29. #import <WebKit/WebFrameLoadDelegatePrivate.h>
  30. #import <wtf/RetainPtr.h>
  31. #if JSC_OBJC_API_ENABLED
  32. @class MyConsole;
  33. static bool didFinishLoad = false;
  34. static bool didCompleteTestSuccessfully = false;
  35. static bool didCallWindowCallback = false;
  36. static bool didFindMyCustomProperty = false;
  37. static bool didInsertMyCustomProperty = true;
  38. @protocol MyConsole<JSExport>
  39. - (void)log:(NSString *)s;
  40. - (void)printHelloWorld;
  41. - (int)add:(int)a to:(int)b;
  42. @end
  43. @interface MyConsole : NSObject<MyConsole>
  44. @end
  45. @implementation MyConsole
  46. - (void)log:(NSString *)s
  47. {
  48. NSLog(@"%@", s);
  49. }
  50. - (void)printHelloWorld
  51. {
  52. NSLog(@"Hello, World!");
  53. }
  54. - (int)add:(int)a to:(int)b
  55. {
  56. return a + b;
  57. }
  58. @end
  59. @interface DidCreateJavaScriptContextFrameLoadDelegate : NSObject
  60. @end
  61. @implementation DidCreateJavaScriptContextFrameLoadDelegate
  62. - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
  63. {
  64. didFinishLoad = true;
  65. }
  66. - (void)webView:(WebView *)webView didCreateJavaScriptContext:(JSContext *)context forFrame:(WebFrame *)frame
  67. {
  68. MyConsole *myConsole = [[MyConsole alloc] init];
  69. context[@"myConsole"] = myConsole;
  70. context.exceptionHandler = nil;
  71. [myConsole release];
  72. context[@"windowCallback"] = ^(JSValue *thisObject){
  73. didCallWindowCallback = true;
  74. };
  75. context[@"didCompleteTestSuccessfully"] = ^{
  76. didCompleteTestSuccessfully = true;
  77. };
  78. context[@"callMeBack"] = ^(JSValue *functionValue) {
  79. [functionValue callWithArguments:[NSArray array]];
  80. };
  81. context[@"checkForMyCustomProperty"] = ^(JSValue *element) {
  82. if ([element hasProperty:@"myCustomProperty"] && [[element valueForProperty:@"myCustomProperty"] toInt32] == 42)
  83. didFindMyCustomProperty = true;
  84. else
  85. NSLog(@"ERROR: Did not find myCustomProperty.");
  86. };
  87. context[@"insertMyCustomProperty"] = ^(JSValue *element) {
  88. JSValue *fortyTwo = [JSValue valueWithInt32:42 inContext:[JSContext currentContext]];
  89. [element setValue:fortyTwo forProperty:@"myCustomProperty"];
  90. didInsertMyCustomProperty = true;
  91. };
  92. }
  93. @end
  94. namespace TestWebKitAPI {
  95. TEST(WebKit1, DidCreateJavaScriptContextSanity1)
  96. {
  97. didFinishLoad = false;
  98. @autoreleasepool {
  99. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  100. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  101. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  102. WebFrame *mainFrame = webView.get().mainFrame;
  103. NSString *bodyString =
  104. @"<body> \
  105. <script> \
  106. myConsole.printHelloWorld(); \
  107. myConsole.log(\"Loaded custom stuff.\"); \
  108. myConsole.log(myConsole.addTo(40, 2)); \
  109. didCompleteTestSuccessfully(); \
  110. </script> \
  111. </body>";
  112. NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"];
  113. [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
  114. Util::run(&didCompleteTestSuccessfully);
  115. }
  116. }
  117. TEST(WebKit1, DidCreateJavaScriptContextSanity2)
  118. {
  119. didCallWindowCallback = false;
  120. @autoreleasepool {
  121. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  122. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  123. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  124. WebFrame *mainFrame = webView.get().mainFrame;
  125. NSString *bodyString =
  126. @"<body> \
  127. <script> \
  128. setTimeout(windowCallback, 100); \
  129. </script> \
  130. </body>";
  131. NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"];
  132. [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
  133. Util::run(&didCallWindowCallback);
  134. }
  135. }
  136. TEST(WebKit1, DidCreateJavaScriptContextCallJSFunctionFromObjCCallbackTest)
  137. {
  138. @autoreleasepool {
  139. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  140. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  141. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  142. WebFrame *mainFrame = webView.get().mainFrame;
  143. NSString *bodyString =
  144. @"<body> \
  145. <script> \
  146. callMeBack(function() { \
  147. didCompleteTestSuccessfully(); \
  148. }); \
  149. </script> \
  150. </body>";
  151. NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"];
  152. [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
  153. Util::run(&didCompleteTestSuccessfully);
  154. }
  155. }
  156. TEST(WebKit1, DidCreateJavaScriptContextAddCustomPropertiesFromJSTest)
  157. {
  158. didFindMyCustomProperty = false;
  159. @autoreleasepool {
  160. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  161. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  162. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  163. WebFrame *mainFrame = webView.get().mainFrame;
  164. NSString *bodyString =
  165. @"<body> \
  166. <div id=\"test-div\"></div> \
  167. <script> \
  168. var testDiv = document.getElementById(\"test-div\"); \
  169. testDiv.myCustomProperty = 42; \
  170. checkForMyCustomProperty(testDiv); \
  171. </script> \
  172. </body>";
  173. NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"];
  174. [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
  175. Util::run(&didFindMyCustomProperty);
  176. }
  177. }
  178. TEST(WebKit1, DidCreateJavaScriptContextAddCustomPropertiesFromObjCTest)
  179. {
  180. didFindMyCustomProperty = false;
  181. @autoreleasepool {
  182. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  183. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  184. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  185. WebFrame *mainFrame = webView.get().mainFrame;
  186. NSString *bodyString =
  187. @"<body> \
  188. <div id=\"test-div\"></div> \
  189. <script> \
  190. var testDiv = document.getElementById(\"test-div\"); \
  191. insertMyCustomProperty(testDiv); \
  192. if (testDiv.myCustomProperty === 42) { \
  193. checkForMyCustomProperty(testDiv); \
  194. } \
  195. </script> \
  196. </body>";
  197. NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"];
  198. [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
  199. Util::run(&didFindMyCustomProperty);
  200. }
  201. }
  202. TEST(WebKit1, DidCreateJavaScriptContextBackForwardCacheTest)
  203. {
  204. didInsertMyCustomProperty = false;
  205. didFindMyCustomProperty = false;
  206. didCompleteTestSuccessfully = false;
  207. @autoreleasepool {
  208. RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  209. RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
  210. webView.get().frameLoadDelegate = frameLoadDelegate.get();
  211. WebFrame *mainFrame = webView.get().mainFrame;
  212. NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"JSContextBackForwardCache1"
  213. withExtension:@"html"
  214. subdirectory:@"TestWebKitAPI.resources"];
  215. [mainFrame loadRequest:[NSURLRequest requestWithURL:url1]];
  216. Util::run(&didInsertMyCustomProperty);
  217. NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"JSContextBackForwardCache2"
  218. withExtension:@"html"
  219. subdirectory:@"TestWebKitAPI.resources"];
  220. [mainFrame loadRequest:[NSURLRequest requestWithURL:url2]];
  221. Util::run(&didCompleteTestSuccessfully);
  222. didCompleteTestSuccessfully = false;
  223. [[mainFrame javaScriptContext] evaluateScript:
  224. @"var testDiv = document.getElementById(\"test-div\"); \
  225. if (!testDiv.myCustomProperty) { \
  226. didCompleteTestSuccessfully(); \
  227. }"];
  228. EXPECT_TRUE(didCompleteTestSuccessfully);
  229. if ([webView.get() goBack]) {
  230. [[mainFrame javaScriptContext] evaluateScript:
  231. @"var testDiv = document.getElementById(\"test-div\"); \
  232. checkForMyCustomProperty(testDiv);"];
  233. EXPECT_TRUE(didFindMyCustomProperty);
  234. } else
  235. EXPECT_TRUE(false);
  236. }
  237. }
  238. } // namespace TestWebKitAPI
  239. #endif // ENABLE(JSC_OBJC_API)