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