2017-07-24 17:31:28 +02:00
|
|
|
|
/*
|
2022-01-21 16:33:52 +01:00
|
|
|
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
2017-07-24 17:31:28 +02:00
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2021-08-13 14:33:12 +02:00
|
|
|
|
using System;
|
2018-08-31 15:29:36 +02:00
|
|
|
|
using CefSharp;
|
2021-12-20 11:44:41 +01:00
|
|
|
|
using SafeExamBrowser.Browser.Content;
|
2022-02-23 13:59:36 +01:00
|
|
|
|
using SafeExamBrowser.Browser.Wrapper;
|
|
|
|
|
using SafeExamBrowser.Browser.Wrapper.Events;
|
2021-12-20 11:44:41 +01:00
|
|
|
|
using SafeExamBrowser.Configuration.Contracts;
|
|
|
|
|
using SafeExamBrowser.Configuration.Contracts.Cryptography;
|
|
|
|
|
using SafeExamBrowser.I18n.Contracts;
|
2019-08-30 09:55:26 +02:00
|
|
|
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
|
|
|
|
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
|
2017-07-24 17:31:28 +02:00
|
|
|
|
|
|
|
|
|
namespace SafeExamBrowser.Browser
|
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
internal class BrowserControl : IBrowserControl
|
2017-07-24 17:31:28 +02:00
|
|
|
|
{
|
2021-12-20 11:44:41 +01:00
|
|
|
|
private readonly AppConfig appConfig;
|
|
|
|
|
private readonly ContentLoader contentLoader;
|
2022-02-23 13:59:36 +01:00
|
|
|
|
private readonly ICefSharpControl control;
|
2021-10-18 12:06:10 +02:00
|
|
|
|
private readonly IDialogHandler dialogHandler;
|
|
|
|
|
private readonly IDisplayHandler displayHandler;
|
|
|
|
|
private readonly IDownloadHandler downloadHandler;
|
|
|
|
|
private readonly IKeyboardHandler keyboardHandler;
|
2022-02-23 13:59:36 +01:00
|
|
|
|
private readonly IKeyGenerator generator;
|
2021-10-18 12:06:10 +02:00
|
|
|
|
private readonly IRequestHandler requestHandler;
|
2018-03-01 08:50:08 +01:00
|
|
|
|
|
2022-02-23 13:59:36 +01:00
|
|
|
|
public string Address => control.Address;
|
|
|
|
|
public bool CanNavigateBackwards => control.BrowserCore.CanGoBack;
|
|
|
|
|
public bool CanNavigateForwards => control.BrowserCore.CanGoForward;
|
|
|
|
|
public object EmbeddableControl => control;
|
2019-01-23 09:37:47 +01:00
|
|
|
|
|
2022-02-23 13:59:36 +01:00
|
|
|
|
public event AddressChangedEventHandler AddressChanged;
|
|
|
|
|
public event LoadFailedEventHandler LoadFailed;
|
|
|
|
|
public event LoadingStateChangedEventHandler LoadingStateChanged;
|
|
|
|
|
public event TitleChangedEventHandler TitleChanged;
|
2017-07-31 20:22:53 +02:00
|
|
|
|
|
2019-01-11 08:25:40 +01:00
|
|
|
|
public BrowserControl(
|
2021-12-20 11:44:41 +01:00
|
|
|
|
AppConfig appConfig,
|
2022-02-23 13:59:36 +01:00
|
|
|
|
ICefSharpControl control,
|
2020-01-20 16:13:08 +01:00
|
|
|
|
IDialogHandler dialogHandler,
|
2019-01-17 16:15:10 +01:00
|
|
|
|
IDisplayHandler displayHandler,
|
2019-01-11 08:25:40 +01:00
|
|
|
|
IDownloadHandler downloadHandler,
|
2019-01-17 11:12:17 +01:00
|
|
|
|
IKeyboardHandler keyboardHandler,
|
2022-02-23 13:59:36 +01:00
|
|
|
|
IKeyGenerator generator,
|
2019-01-17 11:12:17 +01:00
|
|
|
|
IRequestHandler requestHandler,
|
2022-02-23 13:59:36 +01:00
|
|
|
|
IText text)
|
2017-07-31 20:22:53 +02:00
|
|
|
|
{
|
2021-12-20 11:44:41 +01:00
|
|
|
|
this.appConfig = appConfig;
|
|
|
|
|
this.contentLoader = new ContentLoader(text);
|
2022-02-23 13:59:36 +01:00
|
|
|
|
this.control = control;
|
2020-01-20 16:13:08 +01:00
|
|
|
|
this.dialogHandler = dialogHandler;
|
2019-01-17 16:15:10 +01:00
|
|
|
|
this.displayHandler = displayHandler;
|
2019-01-11 08:25:40 +01:00
|
|
|
|
this.downloadHandler = downloadHandler;
|
2019-01-17 11:12:17 +01:00
|
|
|
|
this.keyboardHandler = keyboardHandler;
|
2022-02-23 13:59:36 +01:00
|
|
|
|
this.generator = generator;
|
2019-01-17 11:12:17 +01:00
|
|
|
|
this.requestHandler = requestHandler;
|
2018-06-21 07:56:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-06-23 16:53:43 +02:00
|
|
|
|
public void Destroy()
|
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
if (!control.IsDisposed)
|
2020-06-23 16:53:43 +02:00
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.Dispose(true);
|
2020-06-23 16:53:43 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
public void Initialize()
|
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.AddressChanged += (o, e) => AddressChanged?.Invoke(e.Address);
|
|
|
|
|
control.AuthCredentialsRequired += (w, b, o, i, h, p, r, s, c, a) => a.Value = requestHandler.GetAuthCredentials(w, b, o, i, h, p, r, s, c);
|
|
|
|
|
control.BeforeBrowse += (w, b, f, r, u, i, a) => a.Value = requestHandler.OnBeforeBrowse(w, b, f, r, u, i);
|
|
|
|
|
control.BeforeDownload += (w, b, d, c) => downloadHandler.OnBeforeDownload(w, b, d, c);
|
|
|
|
|
control.DownloadUpdated += (w, b, d, c) => downloadHandler.OnDownloadUpdated(w, b, d, c);
|
|
|
|
|
control.FaviconUrlChanged += (w, b, u) => displayHandler.OnFaviconUrlChange(w, b, u);
|
|
|
|
|
control.FileDialogRequested += (w, b, m, f, t, d, a, s, c) => dialogHandler.OnFileDialog(w, b, m, f, t, d, a, s, c);
|
|
|
|
|
control.FrameLoadStart += Control_FrameLoadStart;
|
|
|
|
|
control.IsBrowserInitializedChanged += Control_IsBrowserInitializedChanged;
|
|
|
|
|
control.KeyEvent += (w, b, t, k, n, m, s) => keyboardHandler.OnKeyEvent(w, b, t, k, n, m, s);
|
|
|
|
|
control.LoadError += (o, e) => LoadFailed?.Invoke((int) e.ErrorCode, e.ErrorText, e.FailedUrl);
|
|
|
|
|
control.LoadingProgressChanged += (w, b, p) => displayHandler.OnLoadingProgressChange(w, b, p);
|
|
|
|
|
control.LoadingStateChanged += (o, e) => LoadingStateChanged?.Invoke(e.IsLoading);
|
|
|
|
|
control.OpenUrlFromTab += (w, b, f, u, t, g, a) => a.Value = requestHandler.OnOpenUrlFromTab(w, b, f, u, t, g);
|
|
|
|
|
control.PreKeyEvent += (IWebBrowser w, IBrowser b, KeyType t, int k, int n, CefEventFlags m, bool i, ref bool s, GenericEventArgs a) => a.Value = keyboardHandler.OnPreKeyEvent(w, b, t, k, n, m, i, ref s);
|
|
|
|
|
control.ResourceRequestHandlerRequired += (IWebBrowser w, IBrowser b, IFrame f, IRequest r, bool n, bool d, string i, ref bool h, ResourceRequestEventArgs a) => a.Handler = requestHandler.GetResourceRequestHandler(w, b, f, r, n, d, i, ref h);
|
|
|
|
|
control.TitleChanged += (o, e) => TitleChanged?.Invoke(e.Title);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Control_FrameLoadStart(object sender, FrameLoadStartEventArgs e)
|
2021-12-20 11:44:41 +01:00
|
|
|
|
{
|
|
|
|
|
var browserExamKey = generator.CalculateBrowserExamKeyHash(e.Url);
|
|
|
|
|
var configurationKey = generator.CalculateConfigurationKeyHash(e.Url);
|
|
|
|
|
var api = contentLoader.LoadApi(browserExamKey, configurationKey, appConfig.ProgramBuildVersion);
|
|
|
|
|
|
|
|
|
|
e.Frame.ExecuteJavaScriptAsync(api);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-23 13:59:36 +01:00
|
|
|
|
private void Control_IsBrowserInitializedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (control.IsBrowserInitialized)
|
|
|
|
|
{
|
|
|
|
|
control.BrowserCore.GetHost().SetFocus(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-10 21:42:51 +02:00
|
|
|
|
public void Find(string term, bool isInitial, bool caseSensitive, bool forward = true)
|
|
|
|
|
{
|
2022-03-21 09:39:45 +01:00
|
|
|
|
control.Find(term, forward, caseSensitive, !isInitial);
|
2020-08-10 21:42:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-31 20:22:53 +02:00
|
|
|
|
public void NavigateBackwards()
|
2017-07-25 11:36:50 +02:00
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.BrowserCore.GoBack();
|
2017-07-31 20:22:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void NavigateForwards()
|
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.BrowserCore.GoForward();
|
2017-07-31 20:22:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void NavigateTo(string address)
|
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.Load(address);
|
2017-07-31 20:22:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 11:42:31 +02:00
|
|
|
|
public void ShowDeveloperConsole()
|
2017-07-31 20:22:53 +02:00
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.BrowserCore.ShowDevTools();
|
2017-07-31 20:22:53 +02:00
|
|
|
|
}
|
2019-01-18 16:11:33 +01:00
|
|
|
|
|
2019-05-22 11:42:31 +02:00
|
|
|
|
public void Reload()
|
2019-01-18 16:11:33 +01:00
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.BrowserCore.Reload();
|
2019-01-18 16:11:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 11:42:31 +02:00
|
|
|
|
public void Zoom(double level)
|
2019-01-18 16:11:33 +01:00
|
|
|
|
{
|
2022-02-23 13:59:36 +01:00
|
|
|
|
control.BrowserCore.SetZoomLevel(level);
|
2020-03-13 15:56:32 +01:00
|
|
|
|
}
|
2021-11-24 08:42:07 +01:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the given Javascript code in the browser.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public async void ExecuteJavascript(string javascript, System.Action<dynamic> callback)
|
|
|
|
|
{
|
|
|
|
|
var result = await this.control.EvaluateScriptAsync(javascript);
|
|
|
|
|
callback(result);
|
|
|
|
|
}
|
2017-07-24 17:31:28 +02:00
|
|
|
|
}
|
|
|
|
|
}
|