2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
22 namespace Tizen.WebView
25 /// A view used to render web contents.
27 /// <since_tizen> 4 </since_tizen>
28 public class WebView: EvasObject
30 private static IDictionary<string, JavaScriptMessageHandler> _javaScriptMessageHandlerMap = new Dictionary<string, JavaScriptMessageHandler>();
32 private IntPtr _handle;
33 private IntPtr _realHandle;
34 private Context _context;
35 private Settings _settings;
38 private SmartEvent _focusIn;
39 private SmartEvent _focusOut;
42 private SmartEvent _loadStarted;
43 private SmartEvent _loadFinished;
44 private SmartEvent<SmartCallbackLoadErrorArgs> _loadError;
45 private SmartEvent<SmartCallbackArgs> _titleChanged;
46 private SmartEvent<SmartCallbackArgs> _urlChanged;
51 /// Event that occurs when load started.
53 /// <since_tizen> 4 </since_tizen>
54 public event EventHandler LoadStarted;
57 /// Event that occurs when load finished.
59 /// <since_tizen> 4 </since_tizen>
60 public event EventHandler LoadFinished;
63 /// Event that occurs when load error.
65 /// <since_tizen> 4 </since_tizen>
66 public event EventHandler<SmartCallbackLoadErrorArgs> LoadError;
69 /// Event that occurs when title of main frame was changed.
71 /// <since_tizen> 4 </since_tizen>
72 public event EventHandler<SmartCallbackArgs> TitleChanged;
75 /// Event that occurs when URL of main frame was changed.
77 /// <since_tizen> 4 </since_tizen>
78 public event EventHandler<SmartCallbackArgs> UrlChanged;
81 /// Current URL of the main frame.
83 /// <since_tizen> 4 </since_tizen>
88 return Interop.ChromiumEwk.ewk_view_url_get(_realHandle);
93 /// Current title of the main frame.
95 /// <since_tizen> 4 </since_tizen>
100 return Interop.ChromiumEwk.ewk_view_title_get(_realHandle);
105 /// Current user agent string of this view.
107 /// <since_tizen> 4 </since_tizen>
108 public string UserAgent
112 return Interop.ChromiumEwk.ewk_view_user_agent_get(_realHandle);
117 Interop.ChromiumEwk.ewk_view_user_agent_set(_realHandle, value);
122 /// Whether a view has the focus.
124 /// <since_tizen> 4 </since_tizen>
129 return Interop.ChromiumEwk.ewk_view_focus_get(_realHandle);
134 /// Create a WebView object.
136 /// <param name="parent">Parent object of WebView</param>
137 /// <since_tizen> 4 </since_tizen>
138 public WebView(EvasObject parent) : base(parent)
140 InitializeSmartEvent();
144 /// Gets the Context object of this view.
146 /// <returns>The Context object of this view</returns>
147 /// <since_tizen> 4 </since_tizen>
148 public Context GetContext()
150 if (_context == null)
152 IntPtr contextHandle = Interop.ChromiumEwk.ewk_view_context_get(_realHandle);
153 if (contextHandle == IntPtr.Zero)
157 _context = new Context(contextHandle);
163 /// Gets the Settings object of this view.
165 /// <returns>The Settings object of this view</returns>
166 /// <since_tizen> 4 </since_tizen>
167 public Settings GetSettings()
169 if (_settings == null)
171 IntPtr settingsHandle = Interop.ChromiumEwk.ewk_view_settings_get(_realHandle);
172 if (settingsHandle == IntPtr.Zero)
176 _settings = new Settings(settingsHandle);
182 /// Asks the object to load the given URL.
185 /// You can only be sure that url changed after UrlChanged event.
187 /// <param name="url">The uniform resource identifier to load</param>
188 /// <since_tizen> 4 </since_tizen>
189 public void LoadUrl(string url)
191 Interop.ChromiumEwk.ewk_view_url_set(_realHandle, url);
195 /// Loads the specified html string as the content of the view.
197 /// <param name="html">HTML data to load</param>
198 /// <param name="baseUrl">Base URL used for relative paths to external objects</param>
199 /// <since_tizen> 4 </since_tizen>
200 public void LoadHtml(string html, string baseUrl)
202 Interop.ChromiumEwk.ewk_view_html_string_load(_realHandle, html, baseUrl, null);
206 /// Asks the main frame to stop loading.
208 /// <since_tizen> 4 </since_tizen>
209 public void StopLoading()
211 Interop.ChromiumEwk.ewk_view_stop(_realHandle);
215 /// Asks the main frame to reload the current document.
217 /// <since_tizen> 4 </since_tizen>
220 Interop.ChromiumEwk.ewk_view_reload(_realHandle);
224 /// Asks the main frame to navigate back in history.
226 /// <since_tizen> 4 </since_tizen>
229 Interop.ChromiumEwk.ewk_view_back(_realHandle);
233 /// Asks the main frame to navigate forward in history.
235 /// <since_tizen> 4 </since_tizen>
236 public void GoForward()
238 Interop.ChromiumEwk.ewk_view_forward(_realHandle);
242 /// Checks whether it is possible to navigate backwards one item in history.
244 /// <returns>Whether it is possible to navigate backwards one item in history</returns>
245 /// <since_tizen> 4 </since_tizen>
246 public bool CanGoBack()
248 return Interop.ChromiumEwk.ewk_view_back_possible(_realHandle);
252 /// Checks whether it is possible to navigate forwards one item in history.
254 /// <returns>Whether it is possible to navigate forwards one item in history</returns>
255 /// <since_tizen> 4 </since_tizen>
256 public bool CanGoForward()
258 return Interop.ChromiumEwk.ewk_view_forward_possible(_realHandle);
262 /// Injects the supplied javascript message handler into the view.
264 /// <param name="name"> The message callback</param>
265 /// <param name="handler">The name used to expose the object in JavaScript</param>
266 /// <returns>'true' on success, otherwise 'false'</returns>
267 /// <since_tizen> 4 </since_tizen>
268 public bool AddJavaScriptMessageHandler(string name, JavaScriptMessageHandler handler)
270 lock (_javaScriptMessageHandlerMap)
272 if (_javaScriptMessageHandlerMap.ContainsKey(name))
276 _javaScriptMessageHandlerMap[name] = handler;
278 Interop.ChromiumEwk.ScriptMessageCallback callback = (handle, message) =>
280 JavaScriptMessage convertedMessage = new JavaScriptMessage(message);
281 lock (_javaScriptMessageHandlerMap)
283 if (_javaScriptMessageHandlerMap.ContainsKey(convertedMessage.Name))
285 _javaScriptMessageHandlerMap[convertedMessage.Name](convertedMessage);
289 if (!Interop.ChromiumEwk.ewk_view_javascript_message_handler_add(_realHandle, callback, name))
291 lock (_javaScriptMessageHandlerMap)
293 _javaScriptMessageHandlerMap.Remove(name);
301 /// Requests the execution of given name and result to the JavaScript runtime.
303 /// <param name="name">The name used to expose the object in JavaScript</param>
304 /// <param name="result">The result to the JavaScript runtime</param>
305 /// <since_tizen> 4 </since_tizen>
306 public void EvalWithResult(string name, string result)
308 Interop.ChromiumEwk.ewk_view_evaluate_javascript(_realHandle, name, result);
312 /// Requests the execution of the given script.
314 /// <param name="script">The JavaScript code string to execute</param>
315 /// <since_tizen> 4 </since_tizen>
316 public void Eval(string script)
318 Interop.ChromiumEwk.ewk_view_script_execute(_realHandle, script, null, IntPtr.Zero);
322 /// Requests to set or unset a view as the currently focused one.
324 /// <param name="focused">'true' to set the focus on the view, 'false' to remove the focus from the view</param>
325 /// <since_tizen> 4 </since_tizen>
326 public void SetFocus(bool focused)
328 Interop.ChromiumEwk.ewk_view_focus_set(_realHandle, focused);
332 /// Creates a widget handle.
334 /// <param name="parent">Parent EvasObject</param>
335 /// <returns>IntPtr of the widget handle</returns>
336 /// <since_tizen> 4 </since_tizen>
337 protected override IntPtr CreateHandle(EvasObject parent)
340 _handle = Interop.Elementary.elm_layout_add((IntPtr)parent);
341 Interop.Elementary.elm_layout_theme_set(_handle, "layout", "elm_widget", "default");
342 Interop.Elementary.elm_object_focus_allow_set(_handle, true);
344 IntPtr evas = Interop.Evas.evas_object_evas_get(parent);
345 _realHandle = Interop.ChromiumEwk.ewk_view_add(evas);
346 Interop.Elementary.elm_object_part_content_set(_handle, "elm.swallow.content", _realHandle);
351 private void InitializeSmartEvent()
354 _focusIn = new SmartEvent(this, "focused");
355 _focusOut = new SmartEvent(this, "unfocused");
357 _focusIn.On += (s, e) => { ((WebView)s).SetFocus(true); };
358 _focusOut.On += (s, e) => { ((WebView)s).SetFocus(false); };
360 _loadStarted = new SmartEvent(this, _realHandle, "load,started");
361 _loadFinished = new SmartEvent(this, _realHandle, "load,finished");
362 _loadError = new SmartEvent<SmartCallbackLoadErrorArgs>(this, _realHandle, "load,error", SmartCallbackLoadErrorArgs.CreateFromSmartEvent);
363 _titleChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "title,changed", SmartCallbackArgs.CreateFromSmartEvent);
364 _urlChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "url,changed", SmartCallbackArgs.CreateFromSmartEvent);
366 _loadStarted.On += (s, e) => { LoadStarted?.Invoke(this, EventArgs.Empty); };
367 _loadFinished.On += (s, e) => { LoadFinished?.Invoke(this, EventArgs.Empty); };
368 _loadError.On += (s, e) => { LoadError?.Invoke(this, e); };
369 _titleChanged.On += (s, e) => { TitleChanged?.Invoke(this, e); };
370 _urlChanged.On += (s, e) => { UrlChanged?.Invoke(this, e); };