WebAppRenderer.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. //
  2. // Copyright (c) 2014-2016, THUNDERBEAST GAMES LLC All rights reserved
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include <include/wrapper/cef_message_router.h>
  23. #include "WebAppRenderer.h"
  24. namespace Atomic
  25. {
  26. // Must match the value in client_handler.cc.
  27. static const char kFocusedNodeChangedMessage[] = "ClientRenderer.FocusedNodeChanged";
  28. class WebRenderDelegate : public WebAppRenderer::Delegate
  29. {
  30. public:
  31. WebRenderDelegate()
  32. : last_node_is_editable_(false)
  33. {
  34. }
  35. virtual void OnWebKitInitialized(CefRefPtr<WebAppRenderer> app) OVERRIDE
  36. {
  37. // Create the renderer-side router for query handling.
  38. CefMessageRouterConfig config;
  39. config.js_query_function = "atomicQuery";
  40. config.js_cancel_function = "atomicQueryCancel";
  41. message_router_ = CefMessageRouterRendererSide::Create(config);
  42. }
  43. virtual void OnContextCreated(CefRefPtr<WebAppRenderer> app,
  44. CefRefPtr<CefBrowser> browser,
  45. CefRefPtr<CefFrame> frame,
  46. CefRefPtr<CefV8Context> context) OVERRIDE
  47. {
  48. message_router_->OnContextCreated(browser, frame, context);
  49. }
  50. virtual void OnContextReleased(CefRefPtr<WebAppRenderer> app,
  51. CefRefPtr<CefBrowser> browser,
  52. CefRefPtr<CefFrame> frame,
  53. CefRefPtr<CefV8Context> context) OVERRIDE
  54. {
  55. message_router_->OnContextReleased(browser, frame, context);
  56. }
  57. virtual bool OnProcessMessageReceived (
  58. CefRefPtr<WebAppRenderer> app,
  59. CefRefPtr<CefBrowser> browser,
  60. CefProcessId source_process,
  61. CefRefPtr<CefProcessMessage> message) OVERRIDE
  62. {
  63. const CefString& message_name = message->GetName();
  64. if (message_name == "atomic_eval_javascript")
  65. {
  66. CefRefPtr<CefV8Context> context = browser->GetMainFrame()->GetV8Context();
  67. CefRefPtr<CefV8Value> retval;
  68. CefRefPtr<CefV8Exception> exception;
  69. context->Enter();
  70. CefRefPtr<CefV8Value> json = context->GetGlobal()->GetValue("JSON");
  71. if (!json.get() || !json->IsObject())
  72. {
  73. context->Exit();
  74. return false;
  75. }
  76. CefRefPtr<CefV8Value> stringify = json->GetValue("stringify");
  77. if (!stringify.get() || !stringify->IsFunction())
  78. {
  79. context->Exit();
  80. return false;
  81. }
  82. unsigned evalID = (unsigned) message->GetArgumentList()->GetInt(0);
  83. CefString script = message->GetArgumentList()->GetString(1);
  84. bool result = context->Eval(script, retval, exception);
  85. // Create the result message object.
  86. CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("atomic_eval_javascript_result");
  87. // Retrieve the argument list object.
  88. CefRefPtr<CefListValue> args = msg->GetArgumentList();
  89. // Populate the argument values.
  90. args->SetInt(0, (int) evalID);
  91. args->SetBool(1, result);
  92. if (result)
  93. {
  94. CefV8ValueList stringifyArgs;
  95. stringifyArgs.push_back(retval);
  96. CefRefPtr<CefV8Value> sjson = stringify->ExecuteFunctionWithContext(context, NULL, stringifyArgs);
  97. if (!sjson.get() || !sjson->IsString())
  98. {
  99. args->SetString(2, "WebAppRenderer::OnProcessMessageReceived() - Error Getting Return JSON");
  100. }
  101. else
  102. {
  103. args->SetString(2, sjson->GetStringValue());
  104. }
  105. }
  106. else
  107. args->SetString(2, exception->GetMessage());
  108. browser->SendProcessMessage(PID_BROWSER, msg);
  109. context->Exit();
  110. return true;
  111. }
  112. return message_router_->OnProcessMessageReceived(
  113. browser, source_process, message);
  114. }
  115. private:
  116. bool last_node_is_editable_;
  117. // Handles the renderer side of query routing.
  118. CefRefPtr<CefMessageRouterRendererSide> message_router_;
  119. IMPLEMENT_REFCOUNTING(WebRenderDelegate);
  120. };
  121. WebAppRenderer::WebAppRenderer() {
  122. }
  123. void WebAppRenderer::OnRenderThreadCreated(CefRefPtr<CefListValue> extra_info)
  124. {
  125. delegates_.Push(new WebRenderDelegate());
  126. DelegateSet::Iterator it = delegates_.Begin();
  127. for (; it != delegates_.End(); ++it)
  128. (*it)->OnRenderThreadCreated(this, extra_info);
  129. }
  130. void WebAppRenderer::OnWebKitInitialized()
  131. {
  132. DelegateSet::Iterator it = delegates_.Begin();
  133. for (; it != delegates_.End(); ++it)
  134. (*it)->OnWebKitInitialized(this);
  135. }
  136. void WebAppRenderer::OnBrowserCreated(CefRefPtr<CefBrowser> browser)
  137. {
  138. DelegateSet::Iterator it = delegates_.Begin();
  139. for (; it != delegates_.End(); ++it)
  140. (*it)->OnBrowserCreated(this, browser);
  141. }
  142. void WebAppRenderer::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser)
  143. {
  144. DelegateSet::Iterator it = delegates_.Begin();
  145. for (; it != delegates_.End(); ++it)
  146. (*it)->OnBrowserDestroyed(this, browser);
  147. }
  148. CefRefPtr<CefLoadHandler> WebAppRenderer::GetLoadHandler()
  149. {
  150. CefRefPtr<CefLoadHandler> load_handler;
  151. DelegateSet::Iterator it = delegates_.Begin();
  152. for (; it != delegates_.End() && !load_handler.get(); ++it)
  153. load_handler = (*it)->GetLoadHandler(this);
  154. return load_handler;
  155. }
  156. bool WebAppRenderer::OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
  157. CefRefPtr<CefFrame> frame,
  158. CefRefPtr<CefRequest> request,
  159. NavigationType navigation_type,
  160. bool is_redirect)
  161. {
  162. DelegateSet::Iterator it = delegates_.Begin();
  163. for (; it != delegates_.End(); ++it) {
  164. if ((*it)->OnBeforeNavigation(this, browser, frame, request, navigation_type, is_redirect))
  165. {
  166. return true;
  167. }
  168. }
  169. return false;
  170. }
  171. void WebAppRenderer::OnContextCreated(CefRefPtr<CefBrowser> browser,
  172. CefRefPtr<CefFrame> frame,
  173. CefRefPtr<CefV8Context> context)
  174. {
  175. DelegateSet::Iterator it = delegates_.Begin();
  176. for (; it != delegates_.End(); ++it)
  177. (*it)->OnContextCreated(this, browser, frame, context);
  178. }
  179. void WebAppRenderer::OnContextReleased(CefRefPtr<CefBrowser> browser,
  180. CefRefPtr<CefFrame> frame,
  181. CefRefPtr<CefV8Context> context)
  182. {
  183. DelegateSet::Iterator it = delegates_.Begin();
  184. for (; it != delegates_.End(); ++it)
  185. (*it)->OnContextReleased(this, browser, frame, context);
  186. }
  187. void WebAppRenderer::OnUncaughtException(
  188. CefRefPtr<CefBrowser> browser,
  189. CefRefPtr<CefFrame> frame,
  190. CefRefPtr<CefV8Context> context,
  191. CefRefPtr<CefV8Exception> exception,
  192. CefRefPtr<CefV8StackTrace> stackTrace)
  193. {
  194. DelegateSet::Iterator it = delegates_.Begin();
  195. for (; it != delegates_.End(); ++it)
  196. {
  197. (*it)->OnUncaughtException(this, browser, frame, context, exception, stackTrace);
  198. }
  199. }
  200. void WebAppRenderer::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
  201. CefRefPtr<CefFrame> frame,
  202. CefRefPtr<CefDOMNode> node)
  203. {
  204. DelegateSet::Iterator it = delegates_.Begin();
  205. for (; it != delegates_.End(); ++it)
  206. (*it)->OnFocusedNodeChanged(this, browser, frame, node);
  207. }
  208. bool WebAppRenderer::OnProcessMessageReceived(
  209. CefRefPtr<CefBrowser> browser,
  210. CefProcessId source_process,
  211. CefRefPtr<CefProcessMessage> message)
  212. {
  213. assert(source_process == PID_BROWSER);
  214. bool handled = false;
  215. DelegateSet::Iterator it = delegates_.Begin();
  216. for (; it != delegates_.End() && !handled; ++it) {
  217. handled = (*it)->OnProcessMessageReceived(this, browser, source_process, message);
  218. }
  219. return handled;
  220. }
  221. }