SEBWIN-329: URL textbox is now hidden when disabled and the developer console is accessible via the browser menu. Removed spinning wheel and introduced loading progress indicator.

This commit is contained in:
dbuechel 2019-05-22 11:42:31 +02:00
parent d472bb1f3c
commit 8b0cc6db71
22 changed files with 319 additions and 257 deletions

View file

@ -26,6 +26,8 @@ namespace SafeExamBrowser.Browser
{
internal class BrowserApplicationInstance : IApplicationInstance
{
private const double ZOOM_FACTOR = 0.2;
private AppConfig appConfig;
private IBrowserControl control;
private IBrowserWindow window;
@ -37,6 +39,7 @@ namespace SafeExamBrowser.Browser
private IText text;
private IUserInterfaceFactory uiFactory;
private string url;
private double zoomLevel;
private BrowserWindowSettings WindowSettings
{
@ -78,7 +81,7 @@ namespace SafeExamBrowser.Browser
internal void Initialize()
{
var contextMenuHandler = new ContextMenuHandler(settings, text);
var contextMenuHandler = new ContextMenuHandler();
var displayHandler = new DisplayHandler();
var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} {Id}");
var downloadHandler = new DownloadHandler(appConfig, settings, downloadLogger);
@ -87,6 +90,7 @@ namespace SafeExamBrowser.Browser
var requestHandler = new RequestHandler(appConfig);
displayHandler.FaviconChanged += DisplayHandler_FaviconChanged;
displayHandler.ProgressChanged += DisplayHandler_ProgressChanged;
downloadHandler.ConfigurationDownloadRequested += DownloadHandler_ConfigurationDownloadRequested;
keyboardHandler.ReloadRequested += ReloadRequested;
keyboardHandler.ZoomInRequested += ZoomInRequested;
@ -105,12 +109,14 @@ namespace SafeExamBrowser.Browser
window = uiFactory.CreateBrowserWindow(control, settings, isMainInstance);
window.Closing += () => Terminated?.Invoke(Id);
window.AddressChanged += Window_AddressChanged;
window.ReloadRequested += ReloadRequested;
window.BackwardNavigationRequested += Window_BackwardNavigationRequested;
window.DeveloperConsoleRequested += Window_DeveloperConsoleRequested;
window.ForwardNavigationRequested += Window_ForwardNavigationRequested;
window.ReloadRequested += ReloadRequested;
window.ZoomInRequested += ZoomInRequested;
window.ZoomOutRequested += ZoomOutRequested;
window.ZoomResetRequested += ZoomResetRequested;
window.UpdateZoomLevel(CalculateZoomPercentage());
logger.Debug("Initialized browser window.");
}
@ -149,6 +155,11 @@ namespace SafeExamBrowser.Browser
});
}
private void DisplayHandler_ProgressChanged(double value)
{
window.UpdateProgress(value);
}
private void DownloadHandler_ConfigurationDownloadRequested(string fileName, DownloadEventArgs args)
{
if (settings.AllowConfigurationDownloads)
@ -221,31 +232,41 @@ namespace SafeExamBrowser.Browser
private void Window_BackwardNavigationRequested()
{
logger.Debug($"Navigating backwards...");
logger.Debug("Navigating backwards...");
control.NavigateBackwards();
}
private void Window_DeveloperConsoleRequested()
{
logger.Debug("Showing developer console...");
control.ShowDeveloperConsole();
}
private void Window_ForwardNavigationRequested()
{
logger.Debug($"Navigating forwards...");
logger.Debug("Navigating forwards...");
control.NavigateForwards();
}
private void ZoomInRequested()
{
if (settings.AllowPageZoom)
if (settings.AllowPageZoom && CalculateZoomPercentage() < 300)
{
control.ZoomIn();
logger.Debug("Increased page zoom.");
zoomLevel += ZOOM_FACTOR;
control.Zoom(zoomLevel);
window.UpdateZoomLevel(CalculateZoomPercentage());
logger.Debug($"Increased page zoom to {CalculateZoomPercentage()}%.");
}
}
private void ZoomOutRequested()
{
if (settings.AllowPageZoom)
if (settings.AllowPageZoom && CalculateZoomPercentage() > 25)
{
control.ZoomOut();
logger.Debug("Decreased page zoom.");
zoomLevel -= ZOOM_FACTOR;
control.Zoom(zoomLevel);
window.UpdateZoomLevel(CalculateZoomPercentage());
logger.Debug($"Decreased page zoom to {CalculateZoomPercentage()}%.");
}
}
@ -253,9 +274,16 @@ namespace SafeExamBrowser.Browser
{
if (settings.AllowPageZoom)
{
control.ZoomReset();
logger.Debug("Reset page zoom.");
zoomLevel = 0;
control.Zoom(0);
window.UpdateZoomLevel(CalculateZoomPercentage());
logger.Debug($"Reset page zoom to {CalculateZoomPercentage()}%.");
}
}
private double CalculateZoomPercentage()
{
return (zoomLevel * 25.0) + 100.0;
}
}
}

View file

@ -17,7 +17,6 @@ namespace SafeExamBrowser.Browser
internal class BrowserControl : ChromiumWebBrowser, IBrowserControl
{
private const uint WS_EX_NOACTIVATE = 0x08000000;
private const double ZOOM_FACTOR = 0.1;
private IContextMenuHandler contextMenuHandler;
private IDisplayHandler displayHandler;
@ -97,36 +96,19 @@ namespace SafeExamBrowser.Browser
Load(address);
}
public void ShowDeveloperConsole()
{
GetBrowser().ShowDevTools();
}
public void Reload()
{
GetBrowser().Reload();
}
public void ZoomReset()
public void Zoom(double level)
{
GetBrowser().SetZoomLevel(0);
}
public void ZoomIn()
{
GetBrowser().GetZoomLevelAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
GetBrowser().SetZoomLevel(task.Result + ZOOM_FACTOR);
}
});
}
public void ZoomOut()
{
GetBrowser().GetZoomLevelAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
GetBrowser().SetZoomLevel(task.Result - ZOOM_FACTOR);
}
});
GetBrowser().SetZoomLevel(level);
}
/// <summary>

View file

@ -7,8 +7,6 @@
*/
using CefSharp;
using SafeExamBrowser.Contracts.I18n;
using BrowserSettings = SafeExamBrowser.Contracts.Configuration.Settings.BrowserSettings;
namespace SafeExamBrowser.Browser.Handlers
{
@ -17,36 +15,13 @@ namespace SafeExamBrowser.Browser.Handlers
/// </remarks>
internal class ContextMenuHandler : IContextMenuHandler
{
private const int DEV_CONSOLE_COMMAND = (int) CefMenuCommand.UserFirst + 1;
private BrowserSettings settings;
private IText text;
public ContextMenuHandler(BrowserSettings settings, IText text)
{
this.settings = settings;
this.text = text;
}
public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
{
model.Clear();
if (settings.AllowDeveloperConsole)
{
model.AddItem((CefMenuCommand) DEV_CONSOLE_COMMAND, text.Get(TextKey.Browser_ShowDeveloperConsole));
}
}
public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
{
if ((int) commandId == DEV_CONSOLE_COMMAND)
{
browser.ShowDevTools();
return true;
}
return false;
}

View file

@ -11,6 +11,7 @@ using System.Linq;
using CefSharp;
using CefSharp.Structs;
using SafeExamBrowser.Browser.Events;
using SafeExamBrowser.Contracts.Browser;
namespace SafeExamBrowser.Browser.Handlers
{
@ -20,6 +21,7 @@ namespace SafeExamBrowser.Browser.Handlers
internal class DisplayHandler : IDisplayHandler
{
public event FaviconChangedEventHandler FaviconChanged;
public event ProgressChangedEventHandler ProgressChanged;
public void OnAddressChanged(IWebBrowser chromiumWebBrowser, AddressChangedEventArgs addressChangedArgs)
{
@ -49,6 +51,7 @@ namespace SafeExamBrowser.Browser.Handlers
public void OnLoadingProgressChange(IWebBrowser chromiumWebBrowser, IBrowser browser, double progress)
{
ProgressChanged?.Invoke(progress);
}
public void OnStatusMessage(IWebBrowser chromiumWebBrowser, StatusMessageEventArgs statusMessageArgs)

View file

@ -13,6 +13,22 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
{
internal partial class DataMapper
{
private void MapAllowAddressBar(Settings settings, object value)
{
if (value is bool allow)
{
settings.Browser.MainWindowSettings.AllowAddressBar = allow;
}
}
private void MapAllowAddressBarAdditionalWindow(Settings settings, object value)
{
if (value is bool allow)
{
settings.Browser.AdditionalWindowSettings.AllowAddressBar = allow;
}
}
private void MapAllowConfigurationDownloads(Settings settings, object value)
{
if (value is bool allow)
@ -21,6 +37,15 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
}
}
private void MapAllowDeveloperConsole(Settings settings, object value)
{
if (value is bool allow)
{
settings.Browser.MainWindowSettings.AllowDeveloperConsole = allow;
settings.Browser.AdditionalWindowSettings.AllowDeveloperConsole = allow;
}
}
private void MapAllowDownloads(Settings settings, object value)
{
if (value is bool allow)

View file

@ -35,34 +35,43 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
case Keys.Browser.AllowConfigurationDownloads:
MapAllowConfigurationDownloads(settings, value);
break;
case Keys.Browser.AllowDeveloperConsole:
MapAllowDeveloperConsole(settings, value);
break;
case Keys.Browser.AllowDownloads:
MapAllowDownloads(settings, value);
break;
case Keys.Browser.AllowNavigation:
MapAllowNavigation(settings, value);
break;
case Keys.Browser.AllowNavigationAdditionalWindow:
MapAllowNavigationAdditionalWindow(settings, value);
break;
case Keys.Browser.AllowPageZoom:
MapAllowPageZoom(settings, value);
break;
case Keys.Browser.AllowPopups:
MapAllowPopups(settings, value);
break;
case Keys.Browser.AllowReload:
MapAllowReload(settings, value);
break;
case Keys.Browser.AllowReloadAdditionalWindow:
MapAllowReloadAdditionalWindow(settings, value);
break;
case Keys.Browser.MainWindowMode:
MapMainWindowMode(settings, value);
break;
case Keys.Browser.ShowReloadWarning:
case Keys.Browser.MainWindow.AllowAddressBar:
MapAllowAddressBar(settings, value);
break;
case Keys.Browser.MainWindow.AllowNavigation:
MapAllowNavigation(settings, value);
break;
case Keys.Browser.MainWindow.AllowReload:
MapAllowReload(settings, value);
break;
case Keys.Browser.MainWindow.ShowReloadWarning:
MapShowReloadWarning(settings, value);
break;
case Keys.Browser.ShowReloadWarningAdditionalWindow:
case Keys.Browser.AdditionalWindow.AllowAddressBar:
MapAllowAddressBarAdditionalWindow(settings, value);
break;
case Keys.Browser.AdditionalWindow.AllowNavigation:
MapAllowNavigationAdditionalWindow(settings, value);
break;
case Keys.Browser.AdditionalWindow.AllowReload:
MapAllowReloadAdditionalWindow(settings, value);
break;
case Keys.Browser.AdditionalWindow.ShowReloadWarning:
MapShowReloadWarningAdditionalWindow(settings, value);
break;
}

View file

@ -97,18 +97,19 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
settings.Browser.StartUrl = "https://www.safeexambrowser.org/start";
settings.Browser.AllowConfigurationDownloads = true;
settings.Browser.AllowDeveloperConsole = false;
settings.Browser.AllowDownloads = true;
settings.Browser.AllowPageZoom = true;
settings.Browser.AllowPopups = true;
settings.Browser.AdditionalWindowSettings.AllowAddressBar = false;
settings.Browser.AdditionalWindowSettings.AllowBackwardNavigation = true;
settings.Browser.AdditionalWindowSettings.AllowDeveloperConsole = false;
settings.Browser.AdditionalWindowSettings.AllowForwardNavigation = true;
settings.Browser.AdditionalWindowSettings.AllowReloading = true;
settings.Browser.AdditionalWindowSettings.FullScreenMode = false;
settings.Browser.AdditionalWindowSettings.ShowReloadWarning = false;
settings.Browser.MainWindowSettings.AllowAddressBar = false;
settings.Browser.MainWindowSettings.AllowBackwardNavigation = false;
settings.Browser.MainWindowSettings.AllowDeveloperConsole = false;
settings.Browser.MainWindowSettings.AllowForwardNavigation = false;
settings.Browser.MainWindowSettings.AllowReloading = true;
settings.Browser.MainWindowSettings.FullScreenMode = false;
@ -152,10 +153,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
settings.UserInterfaceMode = UserInterfaceMode.Desktop;
// TODO: Default value overrides for alpha version, remove for final release!
settings.ActionCenter.ShowApplicationLog = true;
settings.Browser.AllowDeveloperConsole = true;
return settings;
}
}

View file

@ -21,20 +21,31 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal static class Browser
{
internal const string AllowConfigurationDownloads = "downloadAndOpenSebConfig";
internal const string AllowDeveloperConsole = "allowDeveloperConsole";
internal const string AllowDownloads = "allowDownUploads";
internal const string AllowNavigation = "allowBrowsingBackForward";
internal const string AllowNavigationAdditionalWindow = "newBrowserWindowNavigation";
internal const string AllowPageZoom = "enableZoomPage";
internal const string AllowPopups = "blockPopUpWindows";
internal const string AllowReload = "browserWindowAllowReload";
internal const string AllowReloadAdditionalWindow = "newBrowserWindowAllowReload";
internal const string CustomUserAgentDesktop = "browserUserAgentWinDesktopModeCustom";
internal const string CustomUserAgentMobile = "browserUserAgentWinTouchModeCustom";
internal const string MainWindowMode = "browserViewMode";
internal const string ShowReloadWarning = "showReloadWarning";
internal const string ShowReloadWarningAdditionalWindow = "newBrowserWindowShowReloadWarning";
internal const string UserAgentModeDesktop = "browserUserAgentWinDesktopMode";
internal const string UserAgentModeMobile = "browserUserAgentWinTouchMode";
internal static class MainWindow
{
internal const string AllowAddressBar = "browserWindowAllowAddressBar";
internal const string AllowNavigation = "allowBrowsingBackForward";
internal const string AllowReload = "browserWindowAllowReload";
internal const string ShowReloadWarning = "showReloadWarning";
}
internal static class AdditionalWindow
{
internal const string AllowAddressBar = "newBrowserWindowAllowAddressBar";
internal const string AllowNavigation = "newBrowserWindowNavigation";
internal const string AllowReload = "newBrowserWindowAllowReload";
internal const string ShowReloadWarning = "newBrowserWindowShowReloadWarning";
}
}
internal static class ConfigurationFile

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2019 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/.
*/
namespace SafeExamBrowser.Contracts.Browser
{
/// <summary>
/// Event handler used to indicate the current progress value of the page load process (from <c>0.0</c> to <c>1.0</c>).
/// </summary>
public delegate void ProgressChangedEventHandler(double value);
}

View file

@ -26,11 +26,6 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// </summary>
public bool AllowConfigurationDownloads { get; set; }
/// <summary>
/// Determines whether the user will be allowed to open the developer console of a browser window.
/// </summary>
public bool AllowDeveloperConsole { get; set; }
/// <summary>
/// Determines whether the user will be allowed to download files (excluding configuration files).
/// </summary>

View file

@ -25,6 +25,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// Determines whether the user will be allowed to navigate backwards.
/// </summary>
public bool AllowBackwardNavigation { get; set; }
/// <summary>
/// Determines whether the user will be allowed to open the developer console.
/// </summary>
public bool AllowDeveloperConsole { get; set; }
/// <summary>
/// Determines whether the user will be allowed to navigate forwards.

View file

@ -14,7 +14,7 @@ namespace SafeExamBrowser.Contracts.I18n
/// </summary>
public enum TextKey
{
Browser_ShowDeveloperConsole,
BrowserWindow_DeveloperConsoleMenuItem,
BrowserWindow_ZoomMenuItem,
LogWindow_Title,
MessageBox_ApplicationError,

View file

@ -53,6 +53,7 @@
<Reference Include="System.ServiceModel" />
</ItemGroup>
<ItemGroup>
<Compile Include="Browser\ProgressChangedEventHandler.cs" />
<Compile Include="Communication\Data\MessageBoxReplyMessage.cs" />
<Compile Include="Communication\Data\MessageBoxRequestMessage.cs" />
<Compile Include="Communication\Events\ClientConfigurationEventArgs.cs" />

View file

@ -61,24 +61,19 @@ namespace SafeExamBrowser.Contracts.UserInterface.Browser
/// </summary>
void NavigateTo(string address);
/// <summary>
/// Opens the developer console or actives it, if it is already open.
/// </summary>
void ShowDeveloperConsole();
/// <summary>
/// Reloads the current web page.
/// </summary>
void Reload();
/// <summary>
/// Increases the page zoom.
/// Sets the page zoom to the given level. A value of <c>0</c> resets the page zoom.
/// </summary>
void ZoomIn();
/// <summary>
/// Decreases the page zoom.
/// </summary>
void ZoomOut();
/// <summary>
/// Resets the page zoom.
/// </summary>
void ZoomReset();
void Zoom(double level);
}
}

View file

@ -37,6 +37,11 @@ namespace SafeExamBrowser.Contracts.UserInterface.Browser
/// </summary>
event ActionRequestedEventHandler BackwardNavigationRequested;
/// <summary>
/// Event fired when the user would like to open the developer console.
/// </summary>
event ActionRequestedEventHandler DeveloperConsoleRequested;
/// <summary>
/// Event fired when the user would like to navigate forwards.
/// </summary>
@ -63,7 +68,7 @@ namespace SafeExamBrowser.Contracts.UserInterface.Browser
event ActionRequestedEventHandler ZoomResetRequested;
/// <summary>
/// Updates the address bar of the browser window to the given value;
/// Updates the address bar of the browser window to the given value.
/// </summary>
void UpdateAddress(string adress);
@ -78,8 +83,18 @@ namespace SafeExamBrowser.Contracts.UserInterface.Browser
void UpdateLoadingState(bool isLoading);
/// <summary>
/// Sets the title of the browser window to the given value;
/// Updates the page load progress according to the given value.
/// </summary>
void UpdateProgress(double value);
/// <summary>
/// Sets the title of the browser window to the given value.
/// </summary>
void UpdateTitle(string title);
/// <summary>
/// Updates the display value of the current page zoom. Value is expected to be in percentage.
/// </summary>
void UpdateZoomLevel(double value);
}
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<Text>
<Entry key="Browser_ShowDeveloperConsole">
Open Console
<Entry key="BrowserWindow_DeveloperConsoleMenuItem">
Developer Console
</Entry>
<Entry key="BrowserWindow_ZoomMenuItem">
Page Zoom

View file

@ -22,47 +22,61 @@
</Grid.RowDefinitions>
<Border x:Name="Toolbar" Grid.Row="0" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="5,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BackwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ForwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="2" x:Name="ReloadButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Grid Grid.Column="3" Height="25" Margin="5,0">
<TextBox x:Name="UrlTextBox" HorizontalAlignment="Stretch" Padding="5,0" VerticalContentAlignment="Center" />
<Grid Background="#CCFFFFFF" HorizontalAlignment="Right" Margin="2" Visibility="{Binding ElementName=LoadingIcon, Path=Visibility}">
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" HorizontalAlignment="Right" Icon="Spinner" Margin="2,1" SpinDuration="1.5" Visibility="Collapsed" />
</Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BackwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ForwardButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="2" x:Name="ReloadButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<TextBox Grid.Column="3" x:Name="UrlTextBox" Height="25" HorizontalAlignment="Stretch" Margin="5,0" Padding="5,0" VerticalContentAlignment="Center" />
<Button Grid.Column="4" x:Name="MenuButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}">
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="250">
<StackPanel Orientation="Vertical">
<Grid Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="ZoomText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ZoomInButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchPlus" />
</Button>
<Button Grid.Column="2" x:Name="ZoomResetButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<Viewbox Stretch="Uniform">
<TextBlock x:Name="ZoomLevel" />
</Viewbox>
</Button>
<Button Grid.Column="3" x:Name="ZoomOutButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
<Grid x:Name="DeveloperConsoleMenuItem" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="DeveloperConsoleText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="DeveloperConsoleButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Wrench" />
</Button>
</Grid>
</StackPanel>
</Border>
</Popup>
</Grid>
<Button Grid.Column="4" x:Name="MenuButton" Height="30" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}">
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="250">
<StackPanel Orientation="Vertical">
<Grid Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="ZoomText" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ZoomInButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchPlus" />
</Button>
<Button Grid.Column="2" x:Name="ZoomResetButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Refresh" />
</Button>
<Button Grid.Column="3" x:Name="ZoomOutButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
</StackPanel>
</Border>
</Popup>
<ProgressBar Grid.Row="1" x:Name="ProgressBar" Background="Transparent" BorderThickness="0" Foreground="DodgerBlue" Height="2" Margin="0,0,0,-1" />
</Grid>
</Border>
<WindowsFormsHost Grid.Row="1" x:Name="BrowserControlHost" />

View file

@ -43,6 +43,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
public event AddressChangedEventHandler AddressChanged;
public event ActionRequestedEventHandler BackwardNavigationRequested;
public event ActionRequestedEventHandler DeveloperConsoleRequested;
public event ActionRequestedEventHandler ForwardNavigationRequested;
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
@ -100,7 +101,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
public void UpdateAddress(string url)
{
Dispatcher.Invoke(() => UrlTextBox.Text = WindowSettings.AllowAddressBar ? url : UrlRandomizer.Randomize(url));
Dispatcher.Invoke(() => UrlTextBox.Text = url);
}
public void UpdateIcon(IIconResource icon)
@ -110,11 +111,12 @@ namespace SafeExamBrowser.UserInterface.Desktop
public void UpdateLoadingState(bool isLoading)
{
Dispatcher.Invoke(() =>
{
LoadingIcon.Visibility = isLoading ? Visibility.Visible : Visibility.Collapsed;
LoadingIcon.Spin = isLoading;
});
Dispatcher.Invoke(() => ProgressBar.Visibility = isLoading ? Visibility.Visible : Visibility.Hidden);
}
public void UpdateProgress(double value)
{
Dispatcher.Invoke(() => ProgressBar.Value = value * 100);
}
public void UpdateTitle(string title)
@ -122,6 +124,11 @@ namespace SafeExamBrowser.UserInterface.Desktop
Dispatcher.Invoke(() => Title = title);
}
public void UpdateZoomLevel(double value)
{
Dispatcher.Invoke(() => ZoomLevel.Text = $"{value}%");
}
private void BrowserWindow_Closing(object sender, CancelEventArgs e)
{
if (isMainWindow)
@ -203,6 +210,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
BackwardButton.Click += (o, args) => BackwardNavigationRequested?.Invoke();
Closing += BrowserWindow_Closing;
DeveloperConsoleButton.Click += (o, args) => DeveloperConsoleRequested?.Invoke();
ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
Loaded += BrowserWindow_Loaded;
MenuButton.Click += (o, args) => MenuPopup.IsOpen = !MenuPopup.IsOpen;
@ -227,16 +235,18 @@ namespace SafeExamBrowser.UserInterface.Desktop
private void ApplySettings()
{
UrlTextBox.IsEnabled = WindowSettings.AllowAddressBar;
BackwardButton.IsEnabled = WindowSettings.AllowBackwardNavigation;
BackwardButton.Visibility = WindowSettings.AllowBackwardNavigation ? Visibility.Visible : Visibility.Collapsed;
DeveloperConsoleMenuItem.Visibility = WindowSettings.AllowDeveloperConsole ? Visibility.Visible : Visibility.Collapsed;
ForwardButton.IsEnabled = WindowSettings.AllowForwardNavigation;
ForwardButton.Visibility = WindowSettings.AllowForwardNavigation ? Visibility.Visible : Visibility.Collapsed;
ReloadButton.IsEnabled = WindowSettings.AllowReloading;
ReloadButton.Visibility = WindowSettings.AllowReloading ? Visibility.Visible : Visibility.Collapsed;
BackwardButton.IsEnabled = WindowSettings.AllowBackwardNavigation;
BackwardButton.Visibility = WindowSettings.AllowBackwardNavigation ? Visibility.Visible : Visibility.Collapsed;
ForwardButton.IsEnabled = WindowSettings.AllowForwardNavigation;
ForwardButton.Visibility = WindowSettings.AllowForwardNavigation ? Visibility.Visible : Visibility.Collapsed;
UrlTextBox.Visibility = WindowSettings.AllowAddressBar ? Visibility.Visible : Visibility.Hidden;
}
private void InitializeBounds()
@ -285,6 +295,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
}
}

View file

@ -22,47 +22,61 @@
</Grid.RowDefinitions>
<Border x:Name="Toolbar" Grid.Row="0" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="5,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BackwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ForwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="2" x:Name="ReloadButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Grid Grid.Column="3" Height="50" Margin="5,0">
<TextBox x:Name="UrlTextBox" HorizontalAlignment="Stretch" Margin="5" Padding="8" VerticalContentAlignment="Center" />
<Grid Background="#CCFFFFFF" HorizontalAlignment="Right" Margin="8" Visibility="{Binding ElementName=LoadingIcon, Path=Visibility}">
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" HorizontalAlignment="Right" Icon="Spinner" Margin="6,4" SpinDuration="1.5" Visibility="Collapsed" />
</Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BackwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ForwardButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Button Grid.Column="2" x:Name="ReloadButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<TextBox Grid.Column="3" x:Name="UrlTextBox" Height="50" HorizontalAlignment="Stretch" Margin="5,10" Padding="8" VerticalContentAlignment="Center" />
<Button Grid.Column="4" x:Name="MenuButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}">
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="350">
<StackPanel Orientation="Vertical">
<Grid Height="55">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="ZoomText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ZoomInButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchPlus" />
</Button>
<Button Grid.Column="2" x:Name="ZoomResetButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<Viewbox Stretch="Uniform">
<TextBlock x:Name="ZoomLevel" />
</Viewbox>
</Button>
<Button Grid.Column="3" x:Name="ZoomOutButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
<Grid x:Name="DeveloperConsoleMenuItem" Height="55">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="DeveloperConsoleText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="DeveloperConsoleButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Wrench" />
</Button>
</Grid>
</StackPanel>
</Border>
</Popup>
</Grid>
<Button Grid.Column="4" x:Name="MenuButton" Height="50" HorizontalAlignment="Center" Margin="5" Template="{StaticResource BrowserButton}" VerticalAlignment="Center" />
<Popup x:Name="MenuPopup" IsOpen="False" AllowsTransparency="True" PopupAnimation="Slide" Placement="Custom" PlacementTarget="{Binding ElementName=BrowserControlHost}">
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="LightGray" BorderThickness="1,0,1,1" Width="350">
<StackPanel Orientation="Vertical">
<Grid Height="55">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="ZoomText" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="ZoomInButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchPlus" />
</Button>
<Button Grid.Column="2" x:Name="ZoomResetButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Refresh" />
</Button>
<Button Grid.Column="3" x:Name="ZoomOutButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
</StackPanel>
</Border>
</Popup>
<ProgressBar Grid.Row="1" x:Name="ProgressBar" Background="Transparent" BorderThickness="0" Foreground="DodgerBlue" Height="2" Margin="0,0,0,-1" />
</Grid>
</Border>
<WindowsFormsHost Grid.Row="1" x:Name="BrowserControlHost" />

View file

@ -43,6 +43,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
public event AddressChangedEventHandler AddressChanged;
public event ActionRequestedEventHandler BackwardNavigationRequested;
public event ActionRequestedEventHandler DeveloperConsoleRequested;
public event ActionRequestedEventHandler ForwardNavigationRequested;
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
@ -100,7 +101,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
public void UpdateAddress(string url)
{
Dispatcher.Invoke(() => UrlTextBox.Text = WindowSettings.AllowAddressBar ? url : UrlRandomizer.Randomize(url));
Dispatcher.Invoke(() => UrlTextBox.Text = url);
}
public void UpdateIcon(IIconResource icon)
@ -110,11 +111,12 @@ namespace SafeExamBrowser.UserInterface.Mobile
public void UpdateLoadingState(bool isLoading)
{
Dispatcher.Invoke(() =>
{
LoadingIcon.Visibility = isLoading ? Visibility.Visible : Visibility.Collapsed;
LoadingIcon.Spin = isLoading;
});
Dispatcher.Invoke(() => ProgressBar.Visibility = isLoading ? Visibility.Visible : Visibility.Hidden);
}
public void UpdateProgress(double value)
{
Dispatcher.Invoke(() => ProgressBar.Value = value * 100);
}
public void UpdateTitle(string title)
@ -122,6 +124,11 @@ namespace SafeExamBrowser.UserInterface.Mobile
Dispatcher.Invoke(() => Title = title);
}
public void UpdateZoomLevel(double value)
{
Dispatcher.Invoke(() => ZoomLevel.Text = $"{value}%");
}
private void BrowserWindow_Closing(object sender, CancelEventArgs e)
{
if (isMainWindow)
@ -203,6 +210,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
BackwardButton.Click += (o, args) => BackwardNavigationRequested?.Invoke();
Closing += BrowserWindow_Closing;
DeveloperConsoleButton.Click += (o, args) => DeveloperConsoleRequested?.Invoke();
ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
Loaded += BrowserWindow_Loaded;
MenuButton.Click += (o, args) => MenuPopup.IsOpen = !MenuPopup.IsOpen;
@ -227,16 +235,18 @@ namespace SafeExamBrowser.UserInterface.Mobile
private void ApplySettings()
{
UrlTextBox.IsEnabled = WindowSettings.AllowAddressBar;
BackwardButton.IsEnabled = WindowSettings.AllowBackwardNavigation;
BackwardButton.Visibility = WindowSettings.AllowBackwardNavigation ? Visibility.Visible : Visibility.Collapsed;
DeveloperConsoleMenuItem.Visibility = WindowSettings.AllowDeveloperConsole ? Visibility.Visible : Visibility.Collapsed;
ForwardButton.IsEnabled = WindowSettings.AllowForwardNavigation;
ForwardButton.Visibility = WindowSettings.AllowForwardNavigation ? Visibility.Visible : Visibility.Collapsed;
ReloadButton.IsEnabled = WindowSettings.AllowReloading;
ReloadButton.Visibility = WindowSettings.AllowReloading ? Visibility.Visible : Visibility.Collapsed;
BackwardButton.IsEnabled = WindowSettings.AllowBackwardNavigation;
BackwardButton.Visibility = WindowSettings.AllowBackwardNavigation ? Visibility.Visible : Visibility.Collapsed;
ForwardButton.IsEnabled = WindowSettings.AllowForwardNavigation;
ForwardButton.Visibility = WindowSettings.AllowForwardNavigation ? Visibility.Visible : Visibility.Collapsed;
UrlTextBox.Visibility = WindowSettings.AllowAddressBar ? Visibility.Visible : Visibility.Hidden;
}
private void InitializeBounds()
@ -285,6 +295,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
}
}

View file

@ -65,7 +65,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Utilities\IconResourceLoader.cs" />
<Compile Include="Utilities\UrlRandomizer.cs" />
<Compile Include="Utilities\VisualExtensions.cs" />
<Compile Include="Utilities\WindowUtility.cs" />
<Compile Include="Utilities\XamlIconResource.cs" />

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2019 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 System.Text;
namespace SafeExamBrowser.UserInterface.Shared.Utilities
{
public static class UrlRandomizer
{
private const string DIGITS = "0123456789";
private const string LETTERS = "abcdefghijklmnopqrstuvwxyz";
public static string Randomize(string url)
{
var generator = new Random();
var result = new StringBuilder();
foreach (var character in url)
{
if (Char.IsDigit(character))
{
result.Append(DIGITS[generator.Next(DIGITS.Length)]);
}
else if (Char.IsLetter(character))
{
result.Append(LETTERS[generator.Next(LETTERS.Length)]);
}
else
{
result.Append(character);
}
}
return result.ToString();
}
}
}