IWebView.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /**
  2. * Copyright (c) 2021 Vuplex Inc. All rights reserved.
  3. *
  4. * Licensed under the Vuplex Commercial Software Library License, you may
  5. * not use this file except in compliance with the License. You may obtain
  6. * a copy of the License at
  7. *
  8. * https://vuplex.com/commercial-library-license
  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. using System;
  17. using System.Collections.Generic;
  18. using UnityEngine;
  19. #if NET_4_6 || NET_STANDARD_2_0
  20. using System.Threading.Tasks;
  21. #endif
  22. namespace Vuplex.WebView {
  23. /// <summary>
  24. /// `IWebView` is the primary interface for loading and interacting with web content.
  25. /// </summary>
  26. /// <remarks>
  27. /// `WebViewPrefab` takes care of creating one for you and hooking it up to the materials
  28. /// in its prefab. If you want to create an `IWebView` outside of the prefab (to connect
  29. /// to your own custom GameObject) you can use `Web.CreateWebView()`.
  30. /// </remarks>
  31. public interface IWebView {
  32. /// <summary>
  33. /// Indicates that the page has requested to close (i.e. via `window.close()`).
  34. /// </summary>
  35. event EventHandler CloseRequested;
  36. /// <summary>
  37. /// Indicates that a message was logged to the JavaScript console.
  38. /// </summary>
  39. /// <remarks>
  40. /// The 3D WebView packages for Android with Gecko, iOS, and UWP have the following limitations:
  41. /// - Messages from iframes aren't captured
  42. /// - Messages logged early when the page starts loading may be missed
  43. /// </remarks>
  44. event EventHandler<ConsoleMessageEventArgs> ConsoleMessageLogged;
  45. /// <summary>
  46. /// Indicates that an input field was focused or unfocused. This can be used,
  47. /// for example, to determine when to show or hide an on-screen keyboard.
  48. /// </summary>
  49. event EventHandler<FocusedInputFieldChangedEventArgs> FocusedInputFieldChanged;
  50. /// <summary>
  51. /// Indicates that the page load percentage changed.
  52. /// </summary>
  53. event EventHandler<ProgressChangedEventArgs> LoadProgressChanged;
  54. /// <summary>
  55. /// Indicates that JavaScript running in the page used the `window.vuplex.postMessage`
  56. /// JavaScript API to emit a message to the Unity application.
  57. /// </summary>
  58. /// <example>
  59. /// // JavaScript example
  60. /// function sendMessageToCSharp() {
  61. /// // This object passed to `postMessage()` is automatically serialized as JSON
  62. /// // and is emitted via the C# MessageEmitted event. This API mimics the window.postMessage API.
  63. /// window.vuplex.postMessage({ type: 'greeting', message: 'Hello from JavaScript!' });
  64. /// }
  65. ///
  66. /// if (window.vuplex) {
  67. /// // The window.vuplex object has already been initialized after page load,
  68. /// // so we can go ahead and send the message.
  69. /// sendMessageToCSharp();
  70. /// } else {
  71. /// // The window.vuplex object hasn't been initialized yet because the page is still
  72. /// // loading, so add an event listener to send the message once it's initialized.
  73. /// window.addEventListener('vuplexready', sendMessageToCSharp);
  74. /// }
  75. /// </example>
  76. event EventHandler<EventArgs<string>> MessageEmitted;
  77. /// <summary>
  78. /// Indicates that the page failed to load. This can happen, for instance,
  79. /// if DNS is unable to resolve the hostname.
  80. /// </summary>
  81. event EventHandler PageLoadFailed;
  82. /// <summary>
  83. /// Indicates that the page's title changed.
  84. /// </summary>
  85. event EventHandler<EventArgs<string>> TitleChanged;
  86. /// <summary>
  87. /// Indicates that the URL of the webview changed, either
  88. /// due to user interaction or JavaScript.
  89. /// </summary>
  90. event EventHandler<UrlChangedEventArgs> UrlChanged;
  91. /// <summary>
  92. /// Indicates that the rect of the playing video changed.
  93. /// </summary>
  94. /// <remarks>
  95. /// Note that `WebViewPrefab` automatically handles this event for you.
  96. /// </remarks>
  97. event EventHandler<EventArgs<Rect>> VideoRectChanged;
  98. /// <summary>
  99. /// Indicates whether the instance has been disposed via `Dispose()`.
  100. /// </summary>
  101. bool IsDisposed { get; }
  102. /// <summary>
  103. /// Indicates whether the instance has been initialized via `Init()`.
  104. /// </summary>
  105. bool IsInitialized { get; }
  106. /// <summary>
  107. /// JavaScript scripts that are automatically executed in every new
  108. /// page that is loaded. This list is empty by default, but the application
  109. /// can add scripts.
  110. /// </summary>
  111. List<string> PageLoadScripts { get; }
  112. /// <summary>
  113. /// Indicates the instance's plugin type.
  114. /// </summary>
  115. WebPluginType PluginType { get; }
  116. /// <summary>
  117. /// The webview's resolution in pixels per Unity unit.
  118. /// </summary>
  119. /// <seealso cref="SizeInPixels"/>
  120. float Resolution { get; }
  121. /// <summary>
  122. /// The webview's current size in Unity units.
  123. /// </summary>
  124. Vector2 Size { get; }
  125. /// <summary>
  126. /// The webview's current size in pixels.
  127. /// </summary>
  128. /// <seealso cref="Resolution"/>
  129. Vector2 SizeInPixels { get; }
  130. /// <summary>
  131. /// The texture for the webview's web content.
  132. /// </summary>
  133. /// <remarks>
  134. /// This texture is an "external texture" created with
  135. /// `Texture2D.CreateExternalTexture()`. An undocumented characteristic
  136. /// of external textures in Unity is that not all `Texture2D` methods work for them.
  137. /// For example, `Texture2D.GetRawTextureData()` and `ImageConversion.EncodeToPNG()`
  138. /// fail for external textures. To compensate, the `IWebView` interface includes
  139. // its own`GetRawTextureData()` and `CaptureScreenshot()` methods to replace them.
  140. /// </remarks>
  141. Texture2D Texture { get; }
  142. /// <summary>
  143. /// The current URL.
  144. /// </summary>
  145. string Url { get; }
  146. /// <summary>
  147. /// The texture for the webview's video content.
  148. /// Note that iOS uses this separate texture for video.
  149. /// </summary>
  150. Texture2D VideoTexture { get; }
  151. /// <summary>
  152. /// Initializes a newly created webview with the given textures created with
  153. /// `Web.CreateMaterial()` and the dimensions in Unity units.
  154. /// </summary>
  155. /// <remarks>
  156. /// Important notes:
  157. /// - If you're using `WebViewPrefab`, you don't need to call this method, because it calls it for you.
  158. /// - A separate video texture is only used on Android and iOS.
  159. /// - A webview's default resolution is 1300px per Unity unit but can be changed with
  160. /// `IWebView.SetResolution()`.
  161. /// </remarks>
  162. void Init(Texture2D viewportTexture, float width, float height, Texture2D videoTexture);
  163. /// <summary>
  164. /// Like the other `Init()` method, but with video support disabled on Android and iOS.
  165. /// </summary>
  166. void Init(Texture2D viewportTexture, float width, float height);
  167. /// <summary>
  168. /// Makes the webview relinquish focus.
  169. /// </summary>
  170. void Blur();
  171. #if NET_4_6 || NET_STANDARD_2_0
  172. /// <summary>
  173. /// Checks whether the webview can go back with a call to `GoBack()`.
  174. /// </summary>
  175. Task<bool> CanGoBack();
  176. /// <summary>
  177. /// Checks whether the webview can go forward with a call to `GoForward()`.
  178. /// </summary>
  179. Task<bool> CanGoForward();
  180. #endif
  181. /// <summary>
  182. /// Like the other version of `CanGoBack()`, except it uses a callback
  183. /// instead of a `Task` in order to be compatible with legacy .NET.
  184. /// </summary>
  185. void CanGoBack(Action<bool> callback);
  186. /// <summary>
  187. /// Like the other version of `CanGoForward()`, except it uses a callback
  188. /// instead of a `Task` in order to be compatible with legacy .NET.
  189. /// </summary>
  190. void CanGoForward(Action<bool> callback);
  191. #if NET_4_6 || NET_STANDARD_2_0
  192. /// <summary>
  193. /// Returns a PNG image of the content visible in the webview.
  194. /// </summary>
  195. /// <remarks>
  196. /// Note that on iOS, screenshots do not include video content, which appears black.
  197. /// </remarks>
  198. Task<byte[]> CaptureScreenshot();
  199. #endif
  200. /// <summary>
  201. /// Like the other version of `CaptureScreenshot()`, except it uses a callback
  202. /// instead of a `Task` in order to be compatible with legacy .NET.
  203. /// </summary>
  204. void CaptureScreenshot(Action<byte[]> callback);
  205. /// <summary>
  206. /// Clicks at the given point in the webpage, dispatching both a mouse
  207. /// down and a mouse up event.
  208. /// </summary>
  209. /// <param name="point">
  210. /// The x and y components of the point are values
  211. /// between 0 and 1 that are normalized to the width and height, respectively. For example,
  212. /// `point.x = x in Unity units / width in Unity units`.
  213. /// Like in the browser, the origin is in the upper-left corner,
  214. /// the positive direction of the y-axis is down, and the positive
  215. /// direction of the x-axis is right.
  216. /// </param>
  217. void Click(Vector2 point);
  218. /// <summary>
  219. /// Like `Click()` but with an additional option to prevent stealing focus.
  220. /// </summary>
  221. void Click(Vector2 point, bool preventStealingFocus);
  222. /// <summary>
  223. /// Copies the selected text to the clipboard.
  224. /// </summary>
  225. void Copy();
  226. /// <summary>
  227. /// Copies the selected text to the clipboard and removes it.
  228. /// </summary>
  229. void Cut();
  230. /// <summary>
  231. /// Disables the webview from rendering to its texture.
  232. /// </summary>
  233. void DisableViewUpdates();
  234. /// <summary>
  235. /// Destroys the webview, releasing all of its resources.
  236. /// </summary>
  237. /// <remarks>
  238. /// Note that if you're using `WebViewPrefab`, you should call
  239. /// `WebViewPrefab.Destroy()` instead.
  240. /// </remarks>
  241. void Dispose();
  242. /// <summary>
  243. /// Re-enables rendering after a call to `DisableViewUpdates()`.
  244. /// </summary>
  245. void EnableViewUpdates();
  246. #if NET_4_6 || NET_STANDARD_2_0
  247. /// <summary>
  248. /// Executes the given script in the context of the webpage's main frame
  249. /// and returns the result.
  250. /// </summary>
  251. /// <remarks>
  252. /// When targeting legacy .NET, this method returns `void` instead of a `Task`.
  253. /// </remarks>
  254. Task<string> ExecuteJavaScript(string javaScript);
  255. #else
  256. /// <summary>
  257. /// Executes the given script in the context of the webpage's main frame.
  258. /// </summary>
  259. /// <remarks>
  260. /// When targeting legacy .NET, this method returns `void` instead of a `Task`.
  261. /// </remarks>
  262. void ExecuteJavaScript(string javaScript);
  263. #endif
  264. /// <summary>
  265. /// Executes the given script in the context of the webpage's main frame
  266. /// and calls the given callback with the result.
  267. /// </summary>
  268. /// <remarks>
  269. /// This method is functionally equivalent to the version of `ExecuteJavaScript()`
  270. /// that returns a `Task`, except it uses a callback instead of a `Task` in order
  271. /// to be compatible with legacy .NET.
  272. /// </remarks>
  273. void ExecuteJavaScript(string javaScript, Action<string> callback);
  274. /// <summary>
  275. /// Makes the webview take focus.
  276. /// </summary>
  277. void Focus();
  278. #if NET_4_6 || NET_STANDARD_2_0
  279. /// <summary>
  280. /// A replacement for [`Texture2D.GetRawTextureData()`](https://docs.unity3d.com/ScriptReference/Texture2D.GetRawTextureData.html)
  281. /// for IWebView.Texture.
  282. /// </summary>
  283. /// <remarks>
  284. /// Unity's `Texture2D.GetRawTextureData()` method currently does not work for textures created with
  285. /// `Texture2D.CreateExternalTexture()`. So, this method serves as a replacement by providing
  286. /// the equivalent functionality. You can load the bytes returned by this method into another
  287. /// texture using [`Texture2D.LoadRawTextureData()`](https://docs.unity3d.com/ScriptReference/Texture2D.LoadRawTextureData.html).
  288. /// Note that on iOS, the texture data excludes video content, which appears black.
  289. /// </remarks>
  290. /// <example>
  291. /// var textureData = await webView.GetRawTextureData();
  292. /// var texture = new Texture2D(
  293. /// (int)webView.SizeInPixels.x,
  294. /// (int)webView.SizeInPixels.y,
  295. /// TextureFormat.RGBA32,
  296. /// false,
  297. /// false
  298. /// );
  299. /// texture.LoadRawTextureData(textureData);
  300. /// texture.Apply();
  301. /// </example>
  302. Task<byte[]> GetRawTextureData();
  303. #endif
  304. /// <summary>
  305. /// Like the other version of `GetRawTextureData()`, except it uses a callback
  306. /// instead of a `Task` in order to be compatible with legacy .NET.
  307. /// </summary>
  308. void GetRawTextureData(Action<byte[]> callback);
  309. /// <summary>
  310. /// Navigates back to the previous page in the webview's history.
  311. /// </summary>
  312. void GoBack();
  313. /// <summary>
  314. /// Navigates forward to the next page in the webview's history.
  315. /// </summary>
  316. void GoForward();
  317. /// <summary>
  318. /// Dispatches a keystroke to the webview.
  319. /// </summary>
  320. /// <param name="key">
  321. /// A key can either be a single character representing
  322. /// a unicode character (e.g. "A", "b", "?") or a [JavaScript Key value](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)
  323. /// (e.g. "ArrowUp", "Enter").
  324. /// </param>
  325. void HandleKeyboardInput(string key);
  326. /// <summary>
  327. /// Loads the webpage contained in the given HTML string.
  328. /// </summary>
  329. /// <![CDATA[
  330. /// Example:
  331. /// ```
  332. /// webView.LoadHtml(@"
  333. /// <!DOCTYPE html>
  334. /// <html>
  335. /// <head>
  336. /// <title>Test Page</title>
  337. /// <style>
  338. /// h1 {
  339. /// font-family: Helvetica, Arial, Sans-Serif;
  340. /// }
  341. /// </style>
  342. /// </head>
  343. /// <body>
  344. /// <h1>LoadHtml Example</h1>
  345. /// <script>
  346. /// console.log('This page was loaded!');
  347. /// </script>
  348. /// </body>
  349. /// </html>"
  350. /// );
  351. /// ```
  352. /// ]]>
  353. void LoadHtml(string html);
  354. /// <summary>
  355. /// Loads the given URL. Supported URL schemes:
  356. /// - `http://`, `https://` - loads a remote page over HTTP
  357. /// - `streaming-assets://` - loads a local page from StreamingAssets
  358. /// (equivalent to `"file://" + Application.streamingAssetsPath + path`)
  359. /// - `file://` - some platforms support loading arbitrary file URLs
  360. /// </summary>
  361. void LoadUrl(string url);
  362. /// <summary>
  363. /// Like `LoadUrl(string url)`, but also sends the given HTTP request headers
  364. /// when loading the URL.
  365. /// </summary>
  366. void LoadUrl(string url, Dictionary<string, string> additionalHttpHeaders);
  367. /// <summary>
  368. /// Pastes text from the clipboard.
  369. /// </summary>
  370. void Paste();
  371. /// <summary>
  372. /// Posts a message that JavaScript within the webview can listen for
  373. /// using `window.vuplex.addEventListener('message', function(message) {})`.
  374. /// </summary>
  375. /// <param name="data">
  376. /// String that is passed as the data property of the message object.
  377. /// </param>
  378. void PostMessage(string data);
  379. /// <summary>
  380. /// Reloads the current page.
  381. /// </summary>
  382. void Reload();
  383. /// <summary>
  384. /// Resizes the webview to the dimensions given in Unity units.
  385. /// </summary>
  386. /// <remarks>
  387. /// Important notes:
  388. /// - If you're using `WebViewPrefab`, you should call
  389. /// `WebViewPrefab.Resize()` instead.
  390. /// - A webview's default resolution is 1300px per Unity unit but can be changed with
  391. /// `IWebView.SetResolution()`.
  392. /// </remarks>
  393. void Resize(float width, float height);
  394. /// <summary>
  395. /// Scrolls the webview's top-level body by the given delta.
  396. /// If you want to scroll a specific section of the page,
  397. /// see `Scroll(Vector2 scrollDelta, Vector2 point)` instead.
  398. /// </summary>
  399. /// <param name="scrollDelta">
  400. /// The scroll delta in Unity units. Because the browser's origin
  401. /// is in the upper-left corner, the y-axis' positive direction
  402. /// is down and the x-axis' positive direction is right.
  403. /// </param>
  404. void Scroll(Vector2 scrollDelta);
  405. /// <summary>
  406. /// Scrolls by the given delta at the given pointer position.
  407. /// </summary>
  408. /// <param name="scrollDelta">
  409. /// The scroll delta in Unity units. Because the browser's origin
  410. /// is in the upper-left corner, the y-axis' positive direction
  411. /// is down and the x-axis' positive direction is right.
  412. /// </param>
  413. /// <param name="point">
  414. /// The pointer position at the time of the scroll. The x and y components of are values
  415. /// between 0 and 1 that are normalized to the width and height, respectively. For example,
  416. /// `point.x = x in Unity units / width in Unity units`.
  417. /// </param>
  418. void Scroll(Vector2 scrollDelta, Vector2 point);
  419. /// <summary>
  420. /// Selects all text, depending on the page's focused element.
  421. /// </summary>
  422. void SelectAll();
  423. /// <summary>
  424. /// Sets the webview's resolution in pixels per Unity unit.
  425. /// You can change the resolution to make web content appear larger or smaller.
  426. /// </summary>
  427. /// <remarks>
  428. /// The default resolution is 1300 pixels per Unity unit.
  429. /// Setting a lower resolution decreases the pixel density, but has the effect
  430. /// of making web content appear larger. Setting a higher resolution increases
  431. /// the pixel density, but has the effect of making content appear smaller.
  432. /// For more information on scaling web content, see
  433. /// [this support article](https://support.vuplex.com/articles/how-to-scale-web-content).
  434. /// </remarks>
  435. void SetResolution(float pixelsPerUnityUnit);
  436. /// <summary>
  437. /// Zooms into the currently loaded web content.
  438. /// </summary>
  439. /// <remarks>
  440. /// Note that the zoom level gets reset when a new page is loaded.
  441. /// </remarks>
  442. void ZoomIn();
  443. /// <summary>
  444. /// Zooms back out after a previous call to `ZoomIn()`.
  445. /// </summary>
  446. /// <remarks>
  447. /// Note that the zoom level gets reset when a new page is loaded.
  448. /// </remarks>
  449. void ZoomOut();
  450. }
  451. }