45a41eef8acc10b163eae84092285b5fce39d259
[platform/framework/web/crosswalk-tizen.git] / atom / renderer / atom_render_view_observer.cc
1 // Copyright (c) 2013 GitHub, Inc.
2 // Use of this source code is governed by the MIT license that can be
3 // found in the LICENSE file.
4
5 #include "atom/renderer/atom_render_view_observer.h"
6
7 #include <string>
8 #include <vector>
9
10 // Put this before event_emitter_caller.h to have string16 support.
11 #include "atom/common/native_mate_converters/string16_converter.h"
12
13 #include "atom/common/api/api_messages.h"
14 #include "atom/common/api/event_emitter_caller.h"
15 #include "atom/common/native_mate_converters/value_converter.h"
16 #include "atom/common/node_includes.h"
17 #include "atom/common/options_switches.h"
18 #include "atom/renderer/atom_renderer_client.h"
19 #include "base/command_line.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "content/public/renderer/render_view.h"
22 #include "ipc/ipc_message_macros.h"
23 #include "net/base/net_module.h"
24 #include "net/grit/net_resources.h"
25 #include "third_party/WebKit/public/web/WebDraggableRegion.h"
26 #include "third_party/WebKit/public/web/WebDocument.h"
27 #include "third_party/WebKit/public/web/WebFrame.h"
28 #include "third_party/WebKit/public/web/WebLocalFrame.h"
29 #include "third_party/WebKit/public/web/WebKit.h"
30 #include "third_party/WebKit/public/web/WebView.h"
31 #include "ui/base/resource/resource_bundle.h"
32 #include "native_mate/dictionary.h"
33
34 namespace atom {
35
36 namespace {
37
38 bool GetIPCObject(v8::Isolate* isolate,
39                   v8::Local<v8::Context> context,
40                   v8::Local<v8::Object>* ipc) {
41   v8::Local<v8::String> key = mate::StringToV8(isolate, "ipc");
42   v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
43   v8::Local<v8::Object> global_object = context->Global();
44   v8::Local<v8::Value> value;
45   if (!global_object->GetPrivate(context, privateKey).ToLocal(&value))
46     return false;
47   if (value.IsEmpty() || !value->IsObject())
48     return false;
49   *ipc = value->ToObject();
50   return true;
51 }
52
53 std::vector<v8::Local<v8::Value>> ListValueToVector(
54     v8::Isolate* isolate,
55     const base::ListValue& list) {
56   v8::Local<v8::Value> array = mate::ConvertToV8(isolate, list);
57   std::vector<v8::Local<v8::Value>> result;
58   mate::ConvertFromV8(isolate, array, &result);
59   return result;
60 }
61
62 void EmitIPCEvent(blink::WebFrame* frame,
63                   const base::string16& channel,
64                   const base::ListValue& args) {
65   if (!frame || frame->isWebRemoteFrame())
66     return;
67
68   v8::Isolate* isolate = blink::mainThreadIsolate();
69   v8::HandleScope handle_scope(isolate);
70
71   v8::Local<v8::Context> context = frame->mainWorldScriptContext();
72   v8::Context::Scope context_scope(context);
73
74   // Only emit IPC event for context with node integration.
75   node::Environment* env = node::Environment::GetCurrent(context);
76   if (!env)
77     return;
78
79   v8::Local<v8::Object> ipc;
80   if (GetIPCObject(isolate, context, &ipc)) {
81     auto args_vector = ListValueToVector(isolate, args);
82     // Insert the Event object, event.sender is ipc.
83     mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
84     event.Set("sender", ipc);
85     args_vector.insert(args_vector.begin(), event.GetHandle());
86     mate::EmitEvent(isolate, ipc, channel, args_vector);
87   }
88 }
89
90 base::StringPiece NetResourceProvider(int key) {
91   if (key == IDR_DIR_HEADER_HTML) {
92     base::StringPiece html_data =
93         ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
94             IDR_DIR_HEADER_HTML);
95     return html_data;
96   }
97   return base::StringPiece();
98 }
99
100 }  // namespace
101
102 AtomRenderViewObserver::AtomRenderViewObserver(
103     content::RenderView* render_view,
104     AtomRendererClient* renderer_client)
105     : content::RenderViewObserver(render_view),
106       renderer_client_(renderer_client),
107       document_created_(false) {
108   // Initialise resource for directory listing.
109   net::NetModule::SetResourceProvider(NetResourceProvider);
110 }
111
112 AtomRenderViewObserver::~AtomRenderViewObserver() {
113 }
114
115 void AtomRenderViewObserver::DidCreateDocumentElement(
116     blink::WebLocalFrame* frame) {
117   document_created_ = true;
118
119   // Read --zoom-factor from command line.
120   std::string zoom_factor_str = base::CommandLine::ForCurrentProcess()->
121       GetSwitchValueASCII(switches::kZoomFactor);
122   if (zoom_factor_str.empty())
123     return;
124   double zoom_factor;
125   if (!base::StringToDouble(zoom_factor_str, &zoom_factor))
126     return;
127   double zoom_level = blink::WebView::zoomFactorToZoomLevel(zoom_factor);
128   frame->view()->setZoomLevel(zoom_level);
129 }
130
131 void AtomRenderViewObserver::DraggableRegionsChanged(blink::WebFrame* frame) {
132   blink::WebVector<blink::WebDraggableRegion> webregions =
133       frame->document().draggableRegions();
134   std::vector<DraggableRegion> regions;
135   for (const auto& webregion : webregions) {
136     DraggableRegion region;
137     region.bounds = webregion.bounds;
138     region.draggable = webregion.draggable;
139     regions.push_back(region);
140   }
141   Send(new AtomViewHostMsg_UpdateDraggableRegions(routing_id(), regions));
142 }
143
144 bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
145   bool handled = true;
146   IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message)
147     IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage)
148     IPC_MESSAGE_UNHANDLED(handled = false)
149   IPC_END_MESSAGE_MAP()
150
151   return handled;
152 }
153
154 void AtomRenderViewObserver::OnBrowserMessage(bool send_to_all,
155                                               const base::string16& channel,
156                                               const base::ListValue& args) {
157   if (!document_created_)
158     return;
159
160   if (!render_view()->GetWebView())
161     return;
162
163   blink::WebFrame* frame = render_view()->GetWebView()->mainFrame();
164   if (!frame || frame->isWebRemoteFrame())
165     return;
166
167   EmitIPCEvent(frame, channel, args);
168
169   // Also send the message to all sub-frames.
170   if (send_to_all) {
171     for (blink::WebFrame* child = frame->firstChild(); child;
172          child = child->nextSibling())
173       EmitIPCEvent(child, channel, args);
174   }
175 }
176
177 }  // namespace atom