//
// UniWebView.cs
// Created by Wang Wei (@onevcat) on 2017-04-11.
//
// This file is a part of UniWebView Project (https://uniwebview.com)
// By purchasing the asset, you are allowed to use this code in as many as projects
// you want, only if you publish the final products under the name of the same account
// used for the purchase.
//
// This asset and all corresponding files (such as source code) are provided on an
// “as is” basis, without warranty of any kind, express of implied, including but not
// limited to the warranties of merchantability, fitness for a particular purpose, and
// noninfringement. In no event shall the authors or copyright holders be liable for any
// claim, damages or other liability, whether in action of contract, tort or otherwise,
// arising from, out of or in connection with the software or the use of other dealing in the software.
//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
///
/// Main class of UniWebView. Any `GameObject` instance with this script can represent a webview object in the scene.
/// Use this class to create, load, show and interact with a general-purpose web view.
///
public class UniWebView: MonoBehaviour {
///
/// Delegate for page started event.
///
/// The web view component which raises this event.
/// The url which the web view is about to load.
public delegate void PageStartedDelegate(UniWebView webView, string url);
///
/// Raised when the web view starts loading a url.
///
/// This event will be invoked for both url loading with `Load` method or by a link navigating from page.
///
public event PageStartedDelegate OnPageStarted;
///
/// Delegate for page finished event.
///
/// The web view component which raises this event.
/// HTTP status code received from response.
/// The url which the web view loaded.
public delegate void PageFinishedDelegate(UniWebView webView, int statusCode, string url);
///
/// Raised when the web view finished to load a url successfully.
///
/// This method will be invoked when a valid response received from the url, regardless of the response status.
/// If a url loading fails before reaching to the server and getting a response, `OnPageErrorReceived` will be
/// raised instead.
///
public event PageFinishedDelegate OnPageFinished;
///
/// Delegate for page error received event.
///
/// The web view component which raises this event.
///
/// The error code which indicates the error type.
/// It can be different from systems and platforms.
///
/// The error message which indicates the error.
public delegate void PageErrorReceivedDelegate(UniWebView webView, int errorCode, string errorMessage);
///
/// Raised when an error encountered during the loading process.
/// Such as the "host not found" error or "no Internet connection" error will raise this event.
///
public event PageErrorReceivedDelegate OnPageErrorReceived;
///
/// Delegate for page progress changed event.
///
/// The web view component which raises this event.
/// A value indicates the loading progress of current page. It is a value between 0.0f and 1.0f.
public delegate void PageProgressChangedDelegate(UniWebView webView, float progress);
///
/// Raised when the loading progress value changes in current web view.
///
public event PageProgressChangedDelegate OnPageProgressChanged;
///
/// Delegate for message received event.
///
/// The web view component which raises this event.
/// Message received from web view.
public delegate void MessageReceivedDelegate(UniWebView webView, UniWebViewMessage message);
///
/// Raised when a message from web view is received.
///
/// Generally, the message comes from a navigation to
/// a scheme which is observed by current web view. You could use `AddUrlScheme` and
/// `RemoveUrlScheme` to manipulate the scheme list.
///
/// "uniwebview://" scheme is default in the list, so a clicking on link starting with "uniwebview://"
/// will raise this event, if it is not removed.
///
public event MessageReceivedDelegate OnMessageReceived;
///
/// Delegate for should close event.
///
/// The web view component which raises this event.
/// Whether the web view should be closed and destroyed.
public delegate bool ShouldCloseDelegate(UniWebView webView);
///
/// Raised when the web view is about to close itself.
///
/// This event is raised when the users close the web view by Back button on Android, Done button on iOS,
/// or Close button on Unity Editor. It gives a chance to make final decision whether the web view should
/// be closed and destroyed. You can also clean all related resources you created (such as a reference to
/// the web view) in this event.
///
public event ShouldCloseDelegate OnShouldClose;
///
/// Delegate for orientation changed event.
///
/// The web view component which raises this event.
/// The screen orientation for current state.
public delegate void OrientationChangedDelegate(UniWebView webView, ScreenOrientation orientation);
///
/// Raised when the screen orientation is changed. It is a good time to set the web view frame if you
/// need to support multiple orientations in your game.
///
public event OrientationChangedDelegate OnOrientationChanged;
///
/// Delegate for content loading terminated event.
///
/// The web view component which raises this event.
public delegate void OnWebContentProcessTerminatedDelegate(UniWebView webView);
///
/// Raised when on iOS, when system calls `webViewWebContentProcessDidTerminate` method.
/// It is usually due to a low memory when loading the web content and leave you a blank white screen.
/// You need to free as much as memory you could and then do a page reload.
///
public event OnWebContentProcessTerminatedDelegate OnWebContentProcessTerminated;
///
/// Delegate for file download task starting event.
///
/// The web view component which raises this event.
/// The remote URL of this download task. This is also the download URL for the task.
/// The file name which user chooses to use.
public delegate void FileDownloadStarted(UniWebView webView, string remoteUrl, string fileName);
///
/// Raised when a file download task starts.
///
public event FileDownloadStarted OnFileDownloadStarted;
///
/// Delegate for file download task finishing event.
///
/// The web view component which raises this event.
///
/// The error code of the download task result. Value `0` means the download finishes without a problem.
/// Any other non-`0` value indicates an issue. The detail meaning of the error code depends on system.
/// On iOS, it is usually the `errorCode` of the received `NSURLError`. On Android, the value usually represents
/// an `ERROR_*` value in `DownloadManager`.
///
/// The remote URL of this download task.
///
/// The file path of the downloaded file. On iOS, the downloader file is in a temporary folder of your app sandbox.
/// On Android, it is in the "Download" folder of your app.
///
public delegate void FileDownloadFinished(UniWebView webView, int errorCode, string remoteUrl, string diskPath);
///
/// Raised when a file download task finishes with either an error or success.
///
public event FileDownloadFinished OnFileDownloadFinished;
///
/// Delegate for capturing snapshot finished event.
///
/// The web view component which raises this event.
///
/// The error code of the event. If the snapshot is captured and stored without a problem, the error code is 0.
/// Any other number indicates an error happened. In most cases, the screenshot capturing only fails due to lack
/// of disk storage.
///
///
/// An accessible disk path to the captured snapshot image. If an error happens, it is an empty string.
///
public delegate void CaptureSnapshotFinished(UniWebView webView, int errorCode, string diskPath);
///
/// Raised when an image captured and stored in a cache path on disk.
///
public event CaptureSnapshotFinished OnCaptureSnapshotFinished;
///
/// Delegate for multiple window opening event.
///
/// The web view component which opens the new multiple (pop-up) window.
/// The identifier of the opened new window.
public delegate void MultipleWindowOpenedDelegate(UniWebView webView, string multipleWindowId);
///
/// Raised when a new window is opened. This happens when you enable the `SetSupportMultipleWindows` and open a
/// new pop-up window.
///
public event MultipleWindowOpenedDelegate OnMultipleWindowOpened;
///
/// Delegate for multiple window closing event.
///
/// The web view component which closes the multiple window.
/// The identifier of the closed window.
public delegate void MultipleWindowClosedDelegate(UniWebView webView, string multipleWindowId);
///
/// Raised when the multiple window is closed. This happens when the pop-up window is closed by navigation operation
/// or by a invocation of `close()` on the page.
///
public event MultipleWindowClosedDelegate OnMultipleWindowClosed;
private string id = Guid.NewGuid().ToString();
private UniWebViewNativeListener listener;
///
/// Represents the embedded toolbar in the current web view.
///
public UniWebViewEmbeddedToolbar EmbeddedToolbar { get; private set; }
private bool isPortrait;
[SerializeField]
#pragma warning disable 0649
private string urlOnStart;
[SerializeField]
private bool showOnStart = false;
[SerializeField]
private bool fullScreen;
[Obsolete("Use Toolbar is deprecated. Use the embedded toolbar instead.", false)]
[SerializeField]
private bool useToolbar;
[Obsolete("Use Toolbar is deprecated. Use the embedded toolbar instead.", false)]
[SerializeField]
private UniWebViewToolbarPosition toolbarPosition;
[SerializeField]
private bool useEmbeddedToolbar;
[SerializeField]
private UniWebViewToolbarPosition embeddedToolbarPosition;
#pragma warning restore 0649
// Action callback holders
private Dictionary actions = new Dictionary();
private Dictionary> payloadActions = new Dictionary>();
[SerializeField]
private Rect frame;
///
/// Gets or sets the frame of current web view. The value is based on current `Screen.width` and `Screen.height`.
/// The first two values of `Rect` is `x` and `y` position and the followed two `width` and `height`.
///
public Rect Frame {
get { return frame; }
set {
frame = value;
UpdateFrame();
}
}
[SerializeField]
private RectTransform referenceRectTransform;
///
/// A reference rect transform which the web view should change its position and size to.
/// Set it to a Unity UI element (which contains a `RectTransform`) under a canvas to determine
/// the web view frame by a certain UI element.
///
/// By using this, you could get benefit from [Multiple Resolutions UI](https://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html).
///
///
public RectTransform ReferenceRectTransform {
get {
return referenceRectTransform;
}
set {
referenceRectTransform = value;
UpdateFrame();
}
}
private bool started;
private bool backButtonEnabled = true;
///
/// The url of current loaded web page.
///
public string Url {
get { return UniWebViewInterface.GetUrl(listener.Name); }
}
///
/// Updates and sets current frame of web view to match the setting.
///
/// This is useful if the `referenceRectTransform` is changed and you need to sync the frame change
/// to the web view. This method follows the frame determining rules.
///
public void UpdateFrame() {
Rect rect = NextFrameRect();
UniWebViewInterface.SetFrame(listener.Name, (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
}
Rect NextFrameRect() {
if (referenceRectTransform == null) {
UniWebViewLogger.Instance.Info("Using Frame setting to determine web view frame.");
return frame;
} else {
UniWebViewLogger.Instance.Info("Using reference RectTransform to determine web view frame.");
var worldCorners = new Vector3[4];
referenceRectTransform.GetWorldCorners(worldCorners);
var bottomLeft = worldCorners[0];
var topLeft = worldCorners[1];
var topRight = worldCorners[2];
var bottomRight = worldCorners[3];
var canvas = referenceRectTransform.GetComponentInParent