[NUI] TCSACR-226 code change (#1032)
[platform/core/csapi/tizenfx.git] / src / Tizen.WebView / Tizen.WebView / WebView.cs
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 using ElmSharp;
18 using System;
19 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using System.ComponentModel;
22
23 namespace Tizen.WebView
24 {
25     /// <summary>
26     /// Enumeration values used to specify search options.
27     /// </summary>
28     /// <since_tizen> 6 </since_tizen>
29     [Flags]
30     public enum FindOption
31     {
32         /// <summary>
33         /// No search flags, this means a case sensitive, no wrap, forward only search.
34         /// </summary>
35         None = 0,
36         /// <summary>
37         /// Case insensitive search.
38         /// </summary>
39         CaseInsensitive = 1 << 0,
40         /// <summary>
41         /// Search text only at the beginning of the words.
42         /// </summary>
43         AtWordStart = 1 << 1,
44         /// <summary>
45         /// Treat capital letters in the middle of words as word start.
46         /// </summary>
47         TreatMedialCapitalAsWordStart = 1 << 2,
48         /// <summary>
49         /// Search backwards.
50         /// </summary>
51         Backwards = 1 << 3,
52         /// <summary>
53         /// If not present the search stops at the end of the document.
54         /// </summary>
55         WrapAround = 1 << 4,
56         /// <summary>
57         /// Show overlay.
58         /// </summary>
59         ShowOverlay = 1 << 5,
60         /// <summary>
61         /// Show Indicator.
62         /// </summary>
63         ShowIndicator = 1 << 6,
64         /// <summary>
65         /// Show Highlight.
66         /// </summary>
67         ShowHighlight = 1 << 7,
68     }
69
70     /// <summary>
71     /// Enumeration for Http Method.
72     /// </summary>
73     /// <since_tizen> 6 </since_tizen>
74     public enum HttpMethod
75     {
76         /// <summary>
77         /// Get.
78         /// </summary>
79         Get,
80         /// <summary>
81         /// Head.
82         /// </summary>
83         Head,
84         /// <summary>
85         /// Post.
86         /// </summary>
87         Post,
88         /// <summary>
89         /// Put.
90         /// </summary>
91         Put,
92         /// <summary>
93         /// Delete.
94         /// </summary>
95         Delete,
96     }
97
98     /// <summary>
99     /// Enumeration for Orientation of the device.
100     /// </summary>
101     /// <since_tizen> 6 </since_tizen>
102     public enum Orientation
103     {
104         /// <summary>
105         /// 0 degrees when the device is oriented to natural position.
106         /// </summary>
107         Natural = 0,
108         /// <summary>
109         /// -90 degrees when it's left side is at the top.
110         /// </summary>
111         LeftAtTop = -90,
112         /// <summary>
113         /// 90 degrees when it's right side is at the top.
114         /// </summary>
115         RightAtTop = 90,
116         /// <summary>
117         /// 180 degrees when it is upside down.
118         /// </summary>
119         UpsideDown = 180,
120     }
121
122     /// <summary>
123     /// A view used to render the web contents.
124     /// </summary>
125     /// <since_tizen> 4 </since_tizen>
126     public class WebView : EvasObject
127     {
128         private static IDictionary<string, JavaScriptMessageHandler> _javaScriptMessageHandlerMap = new Dictionary<string, JavaScriptMessageHandler>();
129
130         private IntPtr _handle;
131         private IntPtr _realHandle;
132         private Context _context;
133         private Settings _settings;
134
135         // focus dummy
136         private SmartEvent _focusIn;
137         private SmartEvent _focusOut;
138
139         // Smart events
140         private SmartEvent _loadStarted;
141         private SmartEvent _loadFinished;
142         private SmartEvent<SmartCallbackLoadErrorArgs> _loadError;
143         private SmartEvent<SmartCallbackArgs> _titleChanged;
144         private SmartEvent<SmartCallbackArgs> _urlChanged;
145         private SmartEvent<NavigationPolicyEventArgs> _policyNavigationDecide;
146         private SmartEvent<NewWindowPolicyEventArgs> _policyNewWindowDecide;
147         private SmartEvent<ResponsePolicyEventArgs> _policyResponseDecide;
148
149         private SmartEvent<ContextMenuItemEventArgs> _contextMenuItemSelected;
150         private SmartEvent<ContextMenuCustomizeEventArgs> _contextMenuCustomize;
151
152         private ContextMenuCustomize _contextMenuCustomizeDelegate;
153
154         /// <summary>
155         /// Event that occurs when the load is started.
156         /// </summary>
157         /// <since_tizen> 4 </since_tizen>
158         public event EventHandler LoadStarted;
159
160         /// <summary>
161         /// Event that occurs when the load is finished.
162         /// </summary>
163         /// <since_tizen> 4 </since_tizen>
164         public event EventHandler LoadFinished;
165
166         /// <summary>
167         /// Event that occurs when the load throws an error.
168         /// </summary>
169         /// <since_tizen> 4 </since_tizen>
170         public event EventHandler<SmartCallbackLoadErrorArgs> LoadError;
171
172         /// <summary>
173         /// Event that occurs when the title of the main frame is changed.
174         /// </summary>
175         /// <since_tizen> 4 </since_tizen>
176         public event EventHandler<SmartCallbackArgs> TitleChanged;
177
178         /// <summary>
179         /// Event that occurs when the URL of the main frame is changed.
180         /// </summary>
181         /// <since_tizen> 4 </since_tizen>
182         public event EventHandler<SmartCallbackArgs> UrlChanged;
183
184         /// <summary>
185         /// Event that occurs when the policy navigation is decided.
186         /// </summary>
187         /// <since_tizen> 6 </since_tizen>
188         public event EventHandler<NavigationPolicyEventArgs> NavigationPolicyDecideRequested;
189
190         /// <summary>
191         /// Event that occurs when the policy new window is decided.
192         /// </summary>
193         /// <since_tizen> 6 </since_tizen>
194         public event EventHandler<NewWindowPolicyEventArgs> NewWindowPolicyDecideRequested;
195
196         /// <summary>
197         /// Event that occurs when the policy response is decided.
198         /// </summary>
199         /// <since_tizen> 6 </since_tizen>
200         public event EventHandler<ResponsePolicyEventArgs> ResponsePolicyDecideRequested;
201
202         /// <summary>
203         /// Event that occurs when the context menu item selected.
204         /// </summary>
205         /// <since_tizen> 6 </since_tizen>
206         public event EventHandler<ContextMenuItemEventArgs> ContextMenuItemSelected;
207
208         /// <summary>
209         /// The delegate is invoked when context menu customization is needed.
210         /// </summary>
211         /// <param name="menu">The instance of ContextMenu.</param>
212         /// <since_tizen> 6 </since_tizen>
213         public delegate void ContextMenuCustomize(ContextMenu menu);
214
215
216         /// <summary>
217         /// Current URL of the main frame.
218         /// </summary>
219         /// <since_tizen> 4 </since_tizen>
220         public string Url
221         {
222             get
223             {
224                 return Interop.ChromiumEwk.ewk_view_url_get(_realHandle);
225             }
226         }
227
228         /// <summary>
229         /// Current title of the main frame.
230         /// </summary>
231         /// <since_tizen> 4 </since_tizen>
232         public string Title
233         {
234             get
235             {
236                 return Interop.ChromiumEwk.ewk_view_title_get(_realHandle);
237             }
238         }
239
240         /// <summary>
241         /// Current user agent string of this view.
242         /// </summary>
243         /// <since_tizen> 4 </since_tizen>
244         public string UserAgent
245         {
246             get
247             {
248                 return Interop.ChromiumEwk.ewk_view_user_agent_get(_realHandle);
249             }
250
251             set
252             {
253                 Interop.ChromiumEwk.ewk_view_user_agent_set(_realHandle, value);
254             }
255         }
256
257         /// <summary>
258         /// Whether a view has the focus.
259         /// </summary>
260         /// <since_tizen> 4 </since_tizen>
261         public bool HasFocus
262         {
263             get
264             {
265                 return Interop.ChromiumEwk.ewk_view_focus_get(_realHandle);
266             }
267         }
268
269         /// <summary>
270         /// Creates a WebView object.
271         /// </summary>
272         /// <param name="parent">Parent object of the WebView.</param>
273         /// <since_tizen> 4 </since_tizen>
274         public WebView(EvasObject parent) : base(parent)
275         {
276             InitializeSmartEvent();
277         }
278
279         /// <summary>
280         /// Gets the context object of this view.
281         /// </summary>
282         /// <returns>The context object of this view.</returns>
283         /// <since_tizen> 4 </since_tizen>
284         public Context GetContext()
285         {
286             if (_context == null)
287             {
288                 IntPtr contextHandle = Interop.ChromiumEwk.ewk_view_context_get(_realHandle);
289                 if (contextHandle == IntPtr.Zero)
290                 {
291                     return null;
292                 }
293                 _context = new Context(contextHandle);
294             }
295             return _context;
296         }
297
298         /// <summary>
299         /// Gets the settings object of this view.
300         /// </summary>
301         /// <returns>The settings object of this view.</returns>
302         /// <since_tizen> 4 </since_tizen>
303         public Settings GetSettings()
304         {
305             if (_settings == null)
306             {
307                 IntPtr settingsHandle = Interop.ChromiumEwk.ewk_view_settings_get(_realHandle);
308                 if (settingsHandle == IntPtr.Zero)
309                 {
310                     return null;
311                 }
312                 _settings = new Settings(settingsHandle);
313             }
314             return _settings;
315         }
316
317         /// <summary>
318         /// Gets the back/forward list object of this view.
319         /// </summary>
320         /// <returns>The BackForward List object of this view.</returns>
321         /// <since_tizen> 6 </since_tizen>
322         public BackForwardList GetBackForwardList()
323         {
324             IntPtr backforwardlistHandle = Interop.ChromiumEwk.ewk_view_back_forward_list_get(_realHandle);
325             if (backforwardlistHandle == IntPtr.Zero)
326             {
327                 return null;
328             }
329             return new BackForwardList(backforwardlistHandle);
330         }
331
332         /// <summary>
333         /// Clear the back/forward list object of this view.
334         /// </summary>
335         /// <since_tizen> 6 </since_tizen>
336         public void ClearBackForwardList()
337         {
338             Interop.ChromiumEwk.ewk_view_back_forward_list_clear(_realHandle);
339         }
340
341         /// <summary>
342         /// Asks the object to load the given URL.
343         /// </summary>
344         /// <remarks>
345         /// You can only be sure that the URL changes after UrlChanged event.
346         /// </remarks>
347         /// <param name="url">The uniform resource identifier to load.</param>
348         /// <since_tizen> 4 </since_tizen>
349         public void LoadUrl(string url)
350         {
351             Interop.ChromiumEwk.ewk_view_url_set(_realHandle, url);
352         }
353
354         /// <summary>
355         /// Loads the specified HTML string as the content of the view.
356         /// </summary>
357         /// <param name="html">HTML data to load.</param>
358         /// <param name="baseUrl">Base URL used for relative paths to external objects.</param>
359         /// <since_tizen> 4 </since_tizen>
360         public void LoadHtml(string html, string baseUrl)
361         {
362             Interop.ChromiumEwk.ewk_view_html_string_load(_realHandle, html, baseUrl, null);
363         }
364
365         /// <summary>
366         /// Asks the main frame to stop loading.
367         /// </summary>
368         /// <since_tizen> 4 </since_tizen>
369         public void StopLoading()
370         {
371             Interop.ChromiumEwk.ewk_view_stop(_realHandle);
372         }
373
374         /// <summary>
375         /// Asks the main frame to reload the current document.
376         /// </summary>
377         /// <since_tizen> 4 </since_tizen>
378         public void Reload()
379         {
380             Interop.ChromiumEwk.ewk_view_reload(_realHandle);
381         }
382
383         /// <summary>
384         /// Asks the main frame to navigate back in history.
385         /// </summary>
386         /// <since_tizen> 4 </since_tizen>
387         public void GoBack()
388         {
389             Interop.ChromiumEwk.ewk_view_back(_realHandle);
390         }
391
392         /// <summary>
393         /// Asks the main frame to navigate forward in history.
394         /// </summary>
395         /// <since_tizen> 4 </since_tizen>
396         public void GoForward()
397         {
398             Interop.ChromiumEwk.ewk_view_forward(_realHandle);
399         }
400
401         /// <summary>
402         /// Checks whether it is possible to navigate backward one item in history.
403         /// </summary>
404         /// <returns>Whether it is possible to navigate backward one item in history.</returns>
405         /// <since_tizen> 4 </since_tizen>
406         public bool CanGoBack()
407         {
408             return Interop.ChromiumEwk.ewk_view_back_possible(_realHandle);
409         }
410
411         /// <summary>
412         /// Checks whether it is possible to navigate forward one item in history.
413         /// </summary>
414         /// <returns>Whether it is possible to navigate forward one item in history.</returns>
415         /// <since_tizen> 4 </since_tizen>
416         public bool CanGoForward()
417         {
418             return Interop.ChromiumEwk.ewk_view_forward_possible(_realHandle);
419         }
420
421         /// <summary>
422         /// Injects the supplied javascript message handler into the view.
423         /// </summary>
424         /// <param name="name"> The message callback.</param>
425         /// <param name="handler">The name used to expose the object in JavaScript.</param>
426         /// <returns>'true' on success, otherwise 'false'.</returns>
427         /// <since_tizen> 4 </since_tizen>
428         public bool AddJavaScriptMessageHandler(string name, JavaScriptMessageHandler handler)
429         {
430             lock (_javaScriptMessageHandlerMap)
431             {
432                 if (_javaScriptMessageHandlerMap.ContainsKey(name))
433                 {
434                     return false;
435                 }
436                 _javaScriptMessageHandlerMap[name] = handler;
437             }
438             Interop.ChromiumEwk.ScriptMessageCallback callback = (handle, message) =>
439             {
440                 JavaScriptMessage convertedMessage = new JavaScriptMessage(message);
441                 lock (_javaScriptMessageHandlerMap)
442                 {
443                     if (_javaScriptMessageHandlerMap.ContainsKey(convertedMessage.Name))
444                     {
445                         _javaScriptMessageHandlerMap[convertedMessage.Name](convertedMessage);
446                     }
447                 }
448             };
449             if (!Interop.ChromiumEwk.ewk_view_javascript_message_handler_add(_realHandle, callback, name))
450             {
451                 lock (_javaScriptMessageHandlerMap)
452                 {
453                     _javaScriptMessageHandlerMap.Remove(name);
454                     return false;
455                 }
456             }
457             return true;
458         }
459
460         /// <summary>
461         /// Requests the execution of a given name and the result to the JavaScript runtime.
462         /// </summary>
463         /// <param name="name">The name used to expose the object in JavaScript.</param>
464         /// <param name="result">The result to the JavaScript runtime.</param>
465         /// <since_tizen> 4 </since_tizen>
466         public void EvalWithResult(string name, string result)
467         {
468             Interop.ChromiumEwk.ewk_view_evaluate_javascript(_realHandle, name, result);
469         }
470
471         /// <summary>
472         /// Requests the execution of the given script.
473         /// </summary>
474         /// <param name="script">The JavaScript code string to execute.</param>
475         /// <since_tizen> 4 </since_tizen>
476         public void Eval(string script)
477         {
478             Interop.ChromiumEwk.ewk_view_script_execute(_realHandle, script, null, IntPtr.Zero);
479         }
480
481         /// <summary>
482         /// Requests to set or unset a view as the currently focused one.
483         /// </summary>
484         /// <param name="focused">'true' to set the focus on the view, 'false' to remove the focus from the view.</param>
485         /// <since_tizen> 4 </since_tizen>
486         public void SetFocus(bool focused)
487         {
488             Interop.ChromiumEwk.ewk_view_focus_set(_realHandle, focused);
489         }
490
491         /// <summary>
492         /// Gets size of the content.
493         /// </summary>
494         /// <returns> size of the coordinate.</returns>
495         /// <since_tizen> 6 </since_tizen>
496         public Size ContentsSize
497         {
498             get
499             {
500                 int width, height;
501                 Interop.ChromiumEwk.ewk_view_contents_size_get(_realHandle, out width, out height);
502                 return new Size(width, height);
503             }
504         }
505
506         /// <summary>
507         /// Exit full screen.
508         /// </summary>
509         /// <since_tizen> 6 </since_tizen>
510         public void ExitFullscreen ()
511         {
512             Interop.ChromiumEwk.ewk_view_fullscreen_exit(_realHandle);
513         }
514
515         /// <summary>
516         /// Gets the current load progress of the page.
517         /// </summary>
518         /// <returns>'value 0.0 to 1.0' on success, otherwise '-1.0'.</returns>
519         /// <since_tizen> 6 </since_tizen>
520         public double LoadProgress
521         {
522             get
523             {
524                 return Interop.ChromiumEwk.ewk_view_load_progress_get(_realHandle);
525             }
526         }
527
528         /// <summary>
529         /// Sends the orientation of the device.
530         /// </summary>
531         /// <param name="orientation">The new orientation of the device in degree.</param>
532         /// <since_tizen> 6 </since_tizen>
533         public void SendOrientation (Orientation orientation)
534         {
535             Interop.ChromiumEwk.ewk_view_orientation_send(_realHandle, orientation);
536         }
537
538         /// <summary>
539         /// Suspends the operation associated with the view.
540         /// </summary>
541         /// <since_tizen> 6 </since_tizen>
542         public void Suspend ()
543         {
544             Interop.ChromiumEwk.ewk_view_suspend(_realHandle);
545         }
546
547         /// <summary>
548         /// Resumes the operation associated with the view.
549         /// </summary>
550         /// <since_tizen> 6 </since_tizen>
551         public void Resume ()
552         {
553             Interop.ChromiumEwk.ewk_view_resume(_realHandle);
554         }
555
556         /// <summary>
557         /// Gets the current scale factor of the page.
558         /// </summary>
559         /// <since_tizen> 6 </since_tizen>
560         public double Scale
561         {
562             get
563             {
564                 return Interop.ChromiumEwk.ewk_view_scale_get(_realHandle);
565             }
566         }
567
568         /// <summary>
569         /// Sets the current scale factor of the page.
570         /// </summary>
571         /// <param name="scaleFactor">A new level to set.</param>
572         /// <param name="scrollTo">The class Point object with X, Y coordinates.</param>
573         /// <since_tizen> 6 </since_tizen>
574         public void SetScale (double scaleFactor, Point scrollTo)
575         {
576             Interop.ChromiumEwk.ewk_view_scale_set(_realHandle, scaleFactor, scrollTo.X, scrollTo.Y);
577         }
578
579         /// <summary>
580         /// Sets the current page's visibility.
581         /// </summary>
582         /// <param name="enable">'true' to set on the visibility of the page, 'false' otherwise.</param>
583         /// <since_tizen> 6 </since_tizen>
584         public void SetViewVisibility (bool enable)
585         {
586             Interop.ChromiumEwk.ewk_view_visibility_set(_realHandle, enable);
587         }
588
589         /// <summary>
590         /// Get and Sets the scroll position of the page.
591         /// </summary>
592         /// <returns>The class Point object with X, Y coordinates.</returns>
593         /// <since_tizen> 6 </since_tizen>
594         public Point ScrollPosition
595         {
596             get
597             {
598                 Point p;
599                 Interop.ChromiumEwk.ewk_view_scroll_pos_get(_realHandle, out p.X, out p.Y);
600                 return p;
601             }
602             set
603             {
604                 Interop.ChromiumEwk.ewk_view_scroll_set(_realHandle, value.X, value.Y);
605             }
606         }
607
608         /// <summary>
609         /// Scrolls the webpage by the given amount.
610         /// </summary>
611         /// <param name="delta">The class Point object with X, Y coordinates.</param>
612         /// <since_tizen> 6 </since_tizen>
613         public void ScrollBy (Point delta)
614         {
615             Interop.ChromiumEwk.ewk_view_scroll_by(_realHandle, delta.X, delta.Y);
616         }
617
618         /// <summary>
619         /// Searches and highlights the given text string in the document.
620         /// </summary>
621         /// <param name="text">The text to find.</param>
622         /// <param name="option">The options to find.</param>
623         /// <param name="maxMatchCount">The maximum match count to find, unlimited if 0.</param>
624         /// <since_tizen> 6 </since_tizen>
625         public void FindText (string text, FindOption option, int maxMatchCount)
626         {
627             Interop.ChromiumEwk.ewk_view_text_find(_realHandle, text, option, maxMatchCount);
628         }
629
630         /// <summary>
631         /// Requests loading of the given request data.
632         /// </summary>
633         /// <param name="url">The uniform resource identifier to load.</param>
634         /// <param name="httpMethod">The http method.</param>
635         /// <param name="httpHeaders">The http headers.</param>
636         /// <param name="httpBody">The http body data.</param>
637         /// <since_tizen> 6 </since_tizen>
638         public void SetUrlRequest (string url, HttpMethod httpMethod, IDictionary<string, string> httpHeaders, string httpBody)
639         {
640             List<IntPtr> stringHandles = new List<IntPtr>();
641             IntPtr hashHttpHeaders = Interop.Eina.eina_hash_string_small_new(IntPtr.Zero);
642
643             foreach (KeyValuePair<string, string> entry in httpHeaders)
644             {
645                 IntPtr keyHandle = Marshal.StringToHGlobalAnsi(entry.Key);
646                 IntPtr valueHandle = Marshal.StringToHGlobalAnsi(entry.Value);
647                 Interop.Eina.eina_hash_add(hashHttpHeaders, keyHandle, valueHandle);
648                 stringHandles.Add(keyHandle);
649                 stringHandles.Add(valueHandle);
650              }
651              Interop.ChromiumEwk.ewk_view_url_request_set(_realHandle, url, httpMethod, hashHttpHeaders, httpBody);
652
653              foreach(IntPtr handle in stringHandles)
654              {
655                  Marshal.FreeHGlobal(handle);
656              }
657         }
658
659         /// <summary>
660         /// Creates a widget handle.
661         /// </summary>
662         /// <param name="parent">Parent EvasObject.</param>
663         /// <returns>IntPtr of the widget handle.</returns>
664         /// <since_tizen> 4 </since_tizen>
665         protected override IntPtr CreateHandle(EvasObject parent)
666         {
667             // focus dummy
668             _handle = Interop.Elementary.elm_layout_add((IntPtr)parent);
669             Interop.Elementary.elm_layout_theme_set(_handle, "layout", "elm_widget", "default");
670             Interop.Elementary.elm_object_focus_allow_set(_handle, true);
671
672             IntPtr evas = Interop.Evas.evas_object_evas_get(parent);
673             _realHandle = Interop.ChromiumEwk.ewk_view_add(evas);
674             Interop.Elementary.elm_object_part_content_set(_handle, "elm.swallow.content", _realHandle);
675
676             return _handle;
677         }
678
679         /// <summary>
680         /// Sets the delegate for context menu customization.
681         /// </summary>
682         /// <param name="contextMenuCustomizeDelegate">The delegate for context menu customization.</param>
683         /// <since_tizen> 6 </since_tizen>
684         public void SetContextMenuCustomizeDelegate(ContextMenuCustomize contextMenuCustomizeDelegate)
685         {
686             _contextMenuCustomizeDelegate = contextMenuCustomizeDelegate;
687         }
688
689         private void InitializeSmartEvent()
690         {
691             // focus dummy
692             _focusIn = new SmartEvent(this, "focused");
693             _focusOut = new SmartEvent(this, "unfocused");
694
695             _focusIn.On += (s, e) => { ((WebView)s).SetFocus(true); };
696             _focusOut.On += (s, e) => { ((WebView)s).SetFocus(false); };
697
698             _loadStarted = new SmartEvent(this, _realHandle, "load,started");
699             _loadFinished = new SmartEvent(this, _realHandle, "load,finished");
700             _loadError = new SmartEvent<SmartCallbackLoadErrorArgs>(this, _realHandle, "load,error", SmartCallbackLoadErrorArgs.CreateFromSmartEvent);
701             _titleChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "title,changed", SmartCallbackArgs.CreateFromSmartEvent);
702             _urlChanged = new SmartEvent<SmartCallbackArgs>(this, _realHandle, "url,changed", SmartCallbackArgs.CreateFromSmartEvent);
703             _contextMenuCustomize = new SmartEvent<ContextMenuCustomizeEventArgs>(this, _realHandle, "contextmenu,customize", ContextMenuCustomizeEventArgs.CreateFromSmartEvent);
704             _contextMenuItemSelected = new SmartEvent<ContextMenuItemEventArgs>(this, _realHandle, "contextmenu,selected", ContextMenuItemEventArgs.CreateFromSmartEvent);
705             _policyNavigationDecide = new SmartEvent<NavigationPolicyEventArgs>(this, _realHandle, "policy,navigation,decide", NavigationPolicyEventArgs.CreateFromSmartEvent);
706             _policyNewWindowDecide = new SmartEvent<NewWindowPolicyEventArgs>(this, _realHandle, "policy,newwindow,decide", NewWindowPolicyEventArgs.CreateFromSmartEvent);
707             _policyResponseDecide = new SmartEvent<ResponsePolicyEventArgs>(this, _realHandle, "policy,response,decide", ResponsePolicyEventArgs.CreateFromSmartEvent);
708
709             _loadStarted.On += (s, e) => { LoadStarted?.Invoke(this, EventArgs.Empty); };
710             _loadFinished.On += (s, e) => { LoadFinished?.Invoke(this, EventArgs.Empty); };
711             _loadError.On += (s, e) => { LoadError?.Invoke(this, e); };
712             _titleChanged.On += (s, e) => { TitleChanged?.Invoke(this, e); };
713             _urlChanged.On += (s, e) => { UrlChanged?.Invoke(this, e); };
714             _policyNavigationDecide.On += (s, e) => { NavigationPolicyDecideRequested?.Invoke(this, e); };
715             _policyNewWindowDecide.On += (s, e) => { NewWindowPolicyDecideRequested?.Invoke(this, e); };
716             _policyResponseDecide.On += (s, e) => { ResponsePolicyDecideRequested?.Invoke(this, e); };
717             _contextMenuItemSelected.On += (s, e) => { ContextMenuItemSelected?.Invoke(this, e); };
718             _contextMenuCustomize.On += (s, e) => { _contextMenuCustomizeDelegate?.Invoke(e.Menu); };
719         }
720
721     }
722 }