176 lines
5 KiB
C#
176 lines
5 KiB
C#
/*
|
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
*
|
|
* 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/.
|
|
*/
|
|
|
|
using System;
|
|
using CefSharp;
|
|
using CefSharp.WinForms;
|
|
using SafeExamBrowser.Browser.Content;
|
|
using SafeExamBrowser.Configuration.Contracts;
|
|
using SafeExamBrowser.Configuration.Contracts.Cryptography;
|
|
using SafeExamBrowser.I18n.Contracts;
|
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
|
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
|
|
|
|
namespace SafeExamBrowser.Browser
|
|
{
|
|
internal class BrowserControl : ChromiumWebBrowser, IBrowserControl
|
|
{
|
|
private readonly AppConfig appConfig;
|
|
private readonly ContentLoader contentLoader;
|
|
private readonly IContextMenuHandler contextMenuHandler;
|
|
private readonly IDialogHandler dialogHandler;
|
|
private readonly IDisplayHandler displayHandler;
|
|
private readonly IDownloadHandler downloadHandler;
|
|
private readonly IKeyGenerator generator;
|
|
private readonly IKeyboardHandler keyboardHandler;
|
|
private readonly ILifeSpanHandler lifeSpanHandler;
|
|
private readonly IRequestHandler requestHandler;
|
|
private readonly IText text;
|
|
|
|
private AddressChangedEventHandler addressChanged;
|
|
private LoadFailedEventHandler loadFailed;
|
|
private LoadingStateChangedEventHandler loadingStateChanged;
|
|
private TitleChangedEventHandler titleChanged;
|
|
|
|
public bool CanNavigateBackwards => GetBrowser().CanGoBack;
|
|
public bool CanNavigateForwards => GetBrowser().CanGoForward;
|
|
|
|
event AddressChangedEventHandler IBrowserControl.AddressChanged
|
|
{
|
|
add { addressChanged += value; }
|
|
remove { addressChanged -= value; }
|
|
}
|
|
|
|
event LoadFailedEventHandler IBrowserControl.LoadFailed
|
|
{
|
|
add { loadFailed += value; }
|
|
remove { loadFailed -= value; }
|
|
}
|
|
|
|
event LoadingStateChangedEventHandler IBrowserControl.LoadingStateChanged
|
|
{
|
|
add { loadingStateChanged += value; }
|
|
remove { loadingStateChanged -= value; }
|
|
}
|
|
|
|
event TitleChangedEventHandler IBrowserControl.TitleChanged
|
|
{
|
|
add { titleChanged += value; }
|
|
remove { titleChanged -= value; }
|
|
}
|
|
|
|
public BrowserControl(
|
|
AppConfig appConfig,
|
|
IContextMenuHandler contextMenuHandler,
|
|
IDialogHandler dialogHandler,
|
|
IDisplayHandler displayHandler,
|
|
IDownloadHandler downloadHandler,
|
|
IKeyGenerator generator,
|
|
IKeyboardHandler keyboardHandler,
|
|
ILifeSpanHandler lifeSpanHandler,
|
|
IRequestHandler requestHandler,
|
|
IText text,
|
|
string url) : base(url)
|
|
{
|
|
this.appConfig = appConfig;
|
|
this.contentLoader = new ContentLoader(text);
|
|
this.contextMenuHandler = contextMenuHandler;
|
|
this.dialogHandler = dialogHandler;
|
|
this.displayHandler = displayHandler;
|
|
this.downloadHandler = downloadHandler;
|
|
this.generator = generator;
|
|
this.keyboardHandler = keyboardHandler;
|
|
this.lifeSpanHandler = lifeSpanHandler;
|
|
this.requestHandler = requestHandler;
|
|
this.text = text;
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
if (!IsDisposed)
|
|
{
|
|
Dispose(true);
|
|
}
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
AddressChanged += (o, args) => addressChanged?.Invoke(args.Address);
|
|
FrameLoadStart += BrowserControl_FrameLoadStart;
|
|
IsBrowserInitializedChanged += BrowserControl_IsBrowserInitializedChanged;
|
|
LoadError += BrowserControl_LoadError;
|
|
LoadingStateChanged += (o, args) => loadingStateChanged?.Invoke(args.IsLoading);
|
|
TitleChanged += (o, args) => titleChanged?.Invoke(args.Title);
|
|
|
|
DialogHandler = dialogHandler;
|
|
DisplayHandler = displayHandler;
|
|
DownloadHandler = downloadHandler;
|
|
KeyboardHandler = keyboardHandler;
|
|
LifeSpanHandler = lifeSpanHandler;
|
|
MenuHandler = contextMenuHandler;
|
|
RequestHandler = requestHandler;
|
|
}
|
|
|
|
private void BrowserControl_FrameLoadStart(object sender, FrameLoadStartEventArgs e)
|
|
{
|
|
var browserExamKey = generator.CalculateBrowserExamKeyHash(e.Url);
|
|
var configurationKey = generator.CalculateConfigurationKeyHash(e.Url);
|
|
var api = contentLoader.LoadApi(browserExamKey, configurationKey, appConfig.ProgramBuildVersion);
|
|
|
|
e.Frame.ExecuteJavaScriptAsync(api);
|
|
}
|
|
|
|
public void Find(string term, bool isInitial, bool caseSensitive, bool forward = true)
|
|
{
|
|
this.Find(0, term, forward, caseSensitive, !isInitial);
|
|
}
|
|
|
|
public void NavigateBackwards()
|
|
{
|
|
GetBrowser().GoBack();
|
|
}
|
|
|
|
public void NavigateForwards()
|
|
{
|
|
GetBrowser().GoForward();
|
|
}
|
|
|
|
public void NavigateTo(string address)
|
|
{
|
|
Load(address);
|
|
}
|
|
|
|
public void ShowDeveloperConsole()
|
|
{
|
|
GetBrowser().ShowDevTools();
|
|
}
|
|
|
|
public void Reload()
|
|
{
|
|
GetBrowser().Reload();
|
|
}
|
|
|
|
public void Zoom(double level)
|
|
{
|
|
GetBrowser().SetZoomLevel(level);
|
|
}
|
|
|
|
private void BrowserControl_IsBrowserInitializedChanged(object sender, EventArgs e)
|
|
{
|
|
if (IsBrowserInitialized)
|
|
{
|
|
GetBrowser().GetHost().SetFocus(true);
|
|
}
|
|
}
|
|
|
|
private void BrowserControl_LoadError(object sender, LoadErrorEventArgs e)
|
|
{
|
|
loadFailed?.Invoke((int) e.ErrorCode, e.ErrorText, e.FailedUrl);
|
|
}
|
|
}
|
|
}
|