SEBWIN-413: Implemented basic find toolbar for browser.

This commit is contained in:
Damian Büchel 2020-08-10 21:42:51 +02:00
parent a7e3657c6a
commit 7a91d34ca8
14 changed files with 222 additions and 4 deletions

View file

@ -137,6 +137,7 @@ namespace SafeExamBrowser.Browser
displayHandler.ProgressChanged += DisplayHandler_ProgressChanged;
downloadHandler.ConfigurationDownloadRequested += DownloadHandler_ConfigurationDownloadRequested;
downloadHandler.DownloadUpdated += DownloadHandler_DownloadUpdated;
keyboardHandler.FindRequested += KeyboardHandler_FindRequested;
keyboardHandler.ReloadRequested += ReloadRequested;
keyboardHandler.ZoomInRequested += ZoomInRequested;
keyboardHandler.ZoomOutRequested += ZoomOutRequested;
@ -201,6 +202,7 @@ namespace SafeExamBrowser.Browser
window.AddressChanged += Window_AddressChanged;
window.BackwardNavigationRequested += Window_BackwardNavigationRequested;
window.DeveloperConsoleRequested += Window_DeveloperConsoleRequested;
window.FindRequested += Window_FindRequested;
window.ForwardNavigationRequested += Window_ForwardNavigationRequested;
window.ReloadRequested += ReloadRequested;
window.ZoomInRequested += ZoomInRequested;
@ -353,6 +355,11 @@ namespace SafeExamBrowser.Browser
window.UpdateDownloadState(state);
}
private void KeyboardHandler_FindRequested()
{
window.ShowFindbar();
}
private void LifeSpanHandler_PopupRequested(PopupRequestedEventArgs args)
{
var validCurrentUri = Uri.TryCreate(control.Address, UriKind.Absolute, out var currentUri);
@ -492,6 +499,11 @@ namespace SafeExamBrowser.Browser
control.ShowDeveloperConsole();
}
private void Window_FindRequested(string term, bool isInitial, bool caseSensitive, bool forward = true)
{
control.Find(term, isInitial, caseSensitive, forward);
}
private void Window_ForwardNavigationRequested()
{
logger.Debug("Navigating forwards...");

View file

@ -98,6 +98,11 @@ namespace SafeExamBrowser.Browser
RequestHandler = requestHandler;
}
public void Find(string term, bool isInitial, bool caseSensitive, bool forward = true)
{
this.Find(0, term, forward, caseSensitive, !isInitial);
}
public void NavigateBackwards()
{
GetBrowser().GoBack();

View file

@ -14,16 +14,22 @@ namespace SafeExamBrowser.Browser.Handlers
{
internal class KeyboardHandler : IKeyboardHandler
{
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
public event ActionRequestedEventHandler ZoomOutRequested;
public event ActionRequestedEventHandler ZoomResetRequested;
internal event ActionRequestedEventHandler FindRequested;
internal event ActionRequestedEventHandler ReloadRequested;
internal event ActionRequestedEventHandler ZoomInRequested;
internal event ActionRequestedEventHandler ZoomOutRequested;
internal event ActionRequestedEventHandler ZoomResetRequested;
public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int keyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
{
var ctrl = modifiers.HasFlag(CefEventFlags.ControlDown);
var shift = modifiers.HasFlag(CefEventFlags.ShiftDown);
if (type == KeyType.KeyUp && ctrl && (keyCode == (int) Keys.F))
{
FindRequested?.Invoke();
}
if (type == KeyType.KeyUp && ((keyCode == (int) Keys.Add && ctrl) || (keyCode == (int) Keys.D1 && ctrl && shift)))
{
ZoomInRequested?.Invoke();

View file

@ -28,6 +28,8 @@ namespace SafeExamBrowser.I18n.Contracts
BrowserWindow_Downloading,
BrowserWindow_DownloadCancelled,
BrowserWindow_DownloadComplete,
BrowserWindow_FindCaseSensitive,
BrowserWindow_FindMenuItem,
BrowserWindow_ZoomMenuItem,
Build,
ExamSelectionDialog_Cancel,

View file

@ -42,6 +42,12 @@
<Entry key="BrowserWindow_DownloadComplete">
Heruntergeladen.
</Entry>
<Entry key="BrowserWindow_FindCaseSensitive">
Gross-/Kleinschreibung beachten
</Entry>
<Entry key="BrowserWindow_FindMenuItem">
Seite durchsuchen...
</Entry>
<Entry key="BrowserWindow_ZoomMenuItem">
Seiten-Zoom
</Entry>

View file

@ -42,6 +42,12 @@
<Entry key="BrowserWindow_DownloadComplete">
Downloaded.
</Entry>
<Entry key="BrowserWindow_FindCaseSensitive">
Case-sensitive search
</Entry>
<Entry key="BrowserWindow_FindMenuItem">
Search page...
</Entry>
<Entry key="BrowserWindow_ZoomMenuItem">
Page Zoom
</Entry>

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2020 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.UserInterface.Contracts.Browser.Events
{
/// <summary>
/// Indicates that a page search is being requested.
/// </summary>
public delegate void FindRequestedEventHandler(string term, bool isInitial, bool caseSensitive, bool forward = true);
}

View file

@ -56,6 +56,11 @@ namespace SafeExamBrowser.UserInterface.Contracts.Browser
/// </summary>
void Destroy();
/// <summary>
/// Attempts to find the given term on the current page according to the specified parameters.
/// </summary>
void Find(string term, bool isInitial, bool caseSensitive, bool forward = true);
/// <summary>
/// Initializes the browser control.
/// </summary>

View file

@ -49,6 +49,11 @@ namespace SafeExamBrowser.UserInterface.Contracts.Browser
/// </summary>
event ActionRequestedEventHandler DeveloperConsoleRequested;
/// <summary>
/// Event fired when the user would like to search the current page.
/// </summary>
event FindRequestedEventHandler FindRequested;
/// <summary>
/// Event fired when the user would like to navigate forwards.
/// </summary>
@ -74,6 +79,11 @@ namespace SafeExamBrowser.UserInterface.Contracts.Browser
/// </summary>
event ActionRequestedEventHandler ZoomResetRequested;
/// <summary>
/// Displays the find toolbar to search the content of a page.
/// </summary>
void ShowFindbar();
/// <summary>
/// Updates the address bar of the browser window to the given value.
/// </summary>

View file

@ -56,6 +56,7 @@
<ItemGroup>
<Compile Include="Browser\Data\DownloadItemState.cs" />
<Compile Include="Browser\Events\AddressChangedEventHandler.cs" />
<Compile Include="Browser\Events\FindRequestedEventHandler.cs" />
<Compile Include="Browser\Events\LoadFailedEventHandler.cs" />
<Compile Include="Browser\Events\LoadingStateChangedEventHandler.cs" />
<Compile Include="Browser\Events\TitleChangedEventHandler.cs" />

View file

@ -19,6 +19,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border x:Name="Toolbar" Grid.Row="0" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="5,0">
<Grid>
@ -71,6 +72,16 @@
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
<Grid x:Name="FindMenuItem" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="FindMenuText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="FindMenuButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Search" />
</Button>
</Grid>
<Grid x:Name="DeveloperConsoleMenuItem" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@ -89,5 +100,27 @@
</Grid>
</Border>
<WindowsFormsHost Grid.Row="1" x:Name="BrowserControlHost" />
<Border x:Name="Findbar" Grid.Row="2" BorderBrush="LightGray" BorderThickness="0,1,0,0" Margin="5,0" Visibility="Collapsed">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" Height="25" Margin="5,0">
<TextBox x:Name="FindTextBox" Padding="5,0" VerticalContentAlignment="Center" Width="200" />
<Button x:Name="FindPreviousButton" Cursor="Hand" Padding="5" VerticalContentAlignment="Center" Width="25">
<fa:ImageAwesome Icon="AngleUp" />
</Button>
<Button x:Name="FindNextButton" Cursor="Hand" Padding="5" VerticalContentAlignment="Center" Width="25">
<fa:ImageAwesome Icon="AngleDown" />
</Button>
<CheckBox Grid.Column="1" x:Name="FindCaseSensitiveCheckBox" Cursor="Hand" Margin="10,0" Padding="5,0" VerticalContentAlignment="Center" />
</StackPanel>
<Button Grid.Column="4" x:Name="FindbarCloseButton" Height="25" HorizontalAlignment="Center" Margin="5" Padding="7" Template="{StaticResource BrowserButton}" VerticalAlignment="Center">
<fa:ImageAwesome Icon="Close" />
</Button>
</Grid>
</Border>
</Grid>
</Window>

View file

@ -47,6 +47,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
public event AddressChangedEventHandler AddressChanged;
public event ActionRequestedEventHandler BackwardNavigationRequested;
public event ActionRequestedEventHandler DeveloperConsoleRequested;
public event FindRequestedEventHandler FindRequested;
public event ActionRequestedEventHandler ForwardNavigationRequested;
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
@ -102,6 +103,15 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
Dispatcher.Invoke(base.Show);
}
public void ShowFindbar()
{
Dispatcher.InvokeAsync(() =>
{
Findbar.Visibility = Visibility.Visible;
FindTextBox.Focus();
});
}
public void UpdateAddress(string url)
{
Dispatcher.Invoke(() => UrlTextBox.Text = url);
@ -186,6 +196,11 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
{
ReloadRequested?.Invoke();
}
if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && e.Key == Key.F)
{
ShowFindbar();
}
}
private void BrowserWindow_Loaded(object sender, RoutedEventArgs e)
@ -198,6 +213,26 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
}
}
private void FindbarCloseButton_Click(object sender, RoutedEventArgs e)
{
Findbar.Visibility = Visibility.Collapsed;
}
private void FindNextButton_Click(object sender, RoutedEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, false, FindCaseSensitiveCheckBox.IsChecked == true);
}
private void FindPreviousButton_Click(object sender, RoutedEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, false, FindCaseSensitiveCheckBox.IsChecked == true, false);
}
private void FindTextBox_KeyUp(object sender, KeyEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, true, FindCaseSensitiveCheckBox.IsChecked == true);
}
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
{
return new[]
@ -254,6 +289,11 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
DownloadsButton.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => DownloadsPopup.IsOpen = DownloadsPopup.IsMouseOver));
DownloadsPopup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
DownloadsPopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => DownloadsPopup.IsOpen = DownloadsPopup.IsMouseOver));
FindbarCloseButton.Click += FindbarCloseButton_Click;
FindNextButton.Click += FindNextButton_Click;
FindPreviousButton.Click += FindPreviousButton_Click;
FindMenuButton.Click += (o, args) => ShowFindbar();
FindTextBox.KeyUp += FindTextBox_KeyUp;
ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
Loaded += BrowserWindow_Loaded;
MenuButton.Click += (o, args) => MenuPopup.IsOpen = !MenuPopup.IsOpen;
@ -378,6 +418,8 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
FindCaseSensitiveCheckBox.Content = text.Get(TextKey.BrowserWindow_FindCaseSensitive);
FindMenuText.Text = text.Get(TextKey.BrowserWindow_FindMenuItem);
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
}
}

View file

@ -19,6 +19,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border x:Name="Toolbar" Grid.Row="0" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="5,0">
<Grid>
@ -71,6 +72,16 @@
<fa:ImageAwesome Icon="SearchMinus" />
</Button>
</Grid>
<Grid x:Name="FindMenuItem" Height="55">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="FindMenuText" HorizontalAlignment="Left" Margin="10,0" VerticalAlignment="Center" />
<Button Grid.Column="1" x:Name="FindMenuButton" Margin="5" Padding="5" Template="{StaticResource BrowserButton}">
<fa:ImageAwesome Icon="Search" />
</Button>
</Grid>
<Grid x:Name="DeveloperConsoleMenuItem" Height="55">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@ -89,5 +100,27 @@
</Grid>
</Border>
<WindowsFormsHost Grid.Row="1" x:Name="BrowserControlHost" />
<Border x:Name="Findbar" Grid.Row="2" BorderBrush="LightGray" BorderThickness="0,1,0,0" Margin="5,0" Visibility="Collapsed">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" Height="50" Margin="5,0">
<TextBox x:Name="FindTextBox" Padding="5,0" VerticalContentAlignment="Center" Width="200" />
<Button x:Name="FindPreviousButton" Cursor="Hand" Padding="5" VerticalContentAlignment="Center" Width="50">
<fa:ImageAwesome Icon="AngleUp" />
</Button>
<Button x:Name="FindNextButton" Cursor="Hand" Padding="5" VerticalContentAlignment="Center" Width="50">
<fa:ImageAwesome Icon="AngleDown" />
</Button>
<CheckBox Grid.Column="1" x:Name="FindCaseSensitiveCheckBox" Cursor="Hand" Margin="10,0" Padding="5,0" VerticalContentAlignment="Center" />
</StackPanel>
<Button Grid.Column="4" x:Name="FindbarCloseButton" Height="50" HorizontalAlignment="Center" Margin="5" Padding="10" Template="{StaticResource BrowserButton}" VerticalAlignment="Center">
<fa:ImageAwesome Icon="Close" />
</Button>
</Grid>
</Border>
</Grid>
</Window>

View file

@ -47,6 +47,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
public event AddressChangedEventHandler AddressChanged;
public event ActionRequestedEventHandler BackwardNavigationRequested;
public event ActionRequestedEventHandler DeveloperConsoleRequested;
public event FindRequestedEventHandler FindRequested;
public event ActionRequestedEventHandler ForwardNavigationRequested;
public event ActionRequestedEventHandler ReloadRequested;
public event ActionRequestedEventHandler ZoomInRequested;
@ -102,6 +103,15 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
Dispatcher.Invoke(base.Show);
}
public void ShowFindbar()
{
Dispatcher.InvokeAsync(() =>
{
Findbar.Visibility = Visibility.Visible;
FindTextBox.Focus();
});
}
public void UpdateAddress(string url)
{
Dispatcher.Invoke(() => UrlTextBox.Text = url);
@ -186,6 +196,11 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
{
ReloadRequested?.Invoke();
}
if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && e.Key == Key.F)
{
ShowFindbar();
}
}
private void BrowserWindow_Loaded(object sender, RoutedEventArgs e)
@ -198,6 +213,26 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
}
}
private void FindbarCloseButton_Click(object sender, RoutedEventArgs e)
{
Findbar.Visibility = Visibility.Collapsed;
}
private void FindNextButton_Click(object sender, RoutedEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, false, FindCaseSensitiveCheckBox.IsChecked == true);
}
private void FindPreviousButton_Click(object sender, RoutedEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, false, FindCaseSensitiveCheckBox.IsChecked == true, false);
}
private void FindTextBox_KeyUp(object sender, KeyEventArgs e)
{
FindRequested?.Invoke(FindTextBox.Text, true, FindCaseSensitiveCheckBox.IsChecked == true);
}
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
{
return new[]
@ -254,6 +289,11 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
DownloadsButton.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => DownloadsPopup.IsOpen = DownloadsPopup.IsMouseOver));
DownloadsPopup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
DownloadsPopup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => DownloadsPopup.IsOpen = DownloadsPopup.IsMouseOver));
FindbarCloseButton.Click += FindbarCloseButton_Click;
FindNextButton.Click += FindNextButton_Click;
FindPreviousButton.Click += FindPreviousButton_Click;
FindMenuButton.Click += (o, args) => ShowFindbar();
FindTextBox.KeyUp += FindTextBox_KeyUp;
ForwardButton.Click += (o, args) => ForwardNavigationRequested?.Invoke();
Loaded += BrowserWindow_Loaded;
MenuButton.Click += (o, args) => MenuPopup.IsOpen = !MenuPopup.IsOpen;
@ -388,6 +428,8 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
private void LoadText()
{
DeveloperConsoleText.Text = text.Get(TextKey.BrowserWindow_DeveloperConsoleMenuItem);
FindCaseSensitiveCheckBox.Content = text.Get(TextKey.BrowserWindow_FindCaseSensitive);
FindMenuText.Text = text.Get(TextKey.BrowserWindow_FindMenuItem);
ZoomText.Text = text.Get(TextKey.BrowserWindow_ZoomMenuItem);
}
}