L10N for UWP app.

This commit is contained in:
Paul Rouget 2020-06-08 12:35:52 +02:00
parent 562f4781c5
commit e5edd22208
10 changed files with 421 additions and 59 deletions

View file

@ -19,6 +19,7 @@ using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::UI::ViewManagement; using namespace winrt::Windows::UI::ViewManagement;
using namespace winrt::Windows::ApplicationModel::Core; using namespace winrt::Windows::ApplicationModel::Core;
using namespace winrt::Windows::ApplicationModel::Resources;
using namespace winrt::Windows::UI::Notifications; using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom; using namespace winrt::Windows::Data::Xml::Dom;
@ -181,6 +182,9 @@ void BrowserPage::BuildPrefList() {
// it's pretty difficiult to have different controls depending // it's pretty difficiult to have different controls depending
// on the pref type. // on the pref type.
prefList().Children().Clear(); prefList().Children().Clear();
auto resourceLoader = ResourceLoader::GetForCurrentView();
auto resetStr =
resourceLoader.GetString(L"devtoolsPreferenceResetButton/Content");
for (auto pref : ServoControl().Preferences()) { for (auto pref : ServoControl().Preferences()) {
auto value = pref.Value(); auto value = pref.Value();
auto type = value.as<IPropertyValue>().Type(); auto type = value.as<IPropertyValue>().Type();
@ -244,7 +248,7 @@ void BrowserPage::BuildPrefList() {
ctrl->Margin({4, 0, 40, 0}); ctrl->Margin({4, 0, 40, 0});
stack.Children().Append(*ctrl); stack.Children().Append(*ctrl);
auto reset = Controls::Button(); auto reset = Controls::Button();
reset.Content(winrt::box_value(L"reset")); reset.Content(winrt::box_value(resetStr));
reset.IsEnabled(!pref.IsDefault()); reset.IsEnabled(!pref.IsDefault());
reset.Click([=](const auto &, auto const &) { reset.Click([=](const auto &, auto const &) {
auto upref = ServoControl().ResetPref(pref.Key()); auto upref = ServoControl().ResetPref(pref.Key());
@ -284,18 +288,19 @@ void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &,
BuildPrefList(); BuildPrefList();
// FIXME: we could use template + binding for this. auto resourceLoader = ResourceLoader::GetForCurrentView();
auto ok = mDevtoolsStatus == DevtoolsStatus::Running ? Visibility::Visible
: Visibility::Collapsed;
auto ko = mDevtoolsStatus == DevtoolsStatus::Failed ? Visibility::Visible
: Visibility::Collapsed;
auto wip = mDevtoolsStatus == DevtoolsStatus::Stopped ? Visibility::Visible
: Visibility::Collapsed;
DevtoolsStatusOK().Visibility(ok);
DevtoolsStatusKO().Visibility(ko);
DevtoolsStatusWIP().Visibility(wip);
if (mDevtoolsStatus == DevtoolsStatus::Running) { if (mDevtoolsStatus == DevtoolsStatus::Running) {
DevtoolsPort().Text(std::to_wstring(mDevtoolsPort)); std::wstring message =
resourceLoader.GetString(L"devtoolsStatus/Running").c_str();
std::wstring formatted =
format(message, std::to_wstring(mDevtoolsPort).c_str());
DevtoolsStatusMessage().Text(formatted);
} else if (mDevtoolsStatus == DevtoolsStatus::Failed) {
DevtoolsStatusMessage().Text(
resourceLoader.GetString(L"devtoolsStatus/Failed"));
} else if (mDevtoolsStatus == DevtoolsStatus::Stopped) {
DevtoolsStatusMessage().Text(
resourceLoader.GetString(L"devtoolsStatus/Stopped"));
} }
} }

View file

@ -9,8 +9,6 @@
xmlns:muxc="using:Microsoft.UI.Xaml.Controls" xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<Style x:Key="NavigationBarButton" TargetType="Button"> <Style x:Key="NavigationBarButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/> <Setter Property="Background" Value="Transparent"/>
@ -98,41 +96,41 @@
<ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0"> <StackPanel Orientation="Horizontal" Grid.Column="0">
<Button Style="{StaticResource NavigationBarButton}" x:Name="backButton" IsTabStop="true" IsEnabled="false" Click="OnBackButtonClicked" AutomationProperties.Name="Back" ToolTipService.ToolTip="Back"> <Button Style="{StaticResource NavigationBarButton}" x:Uid="backButton" x:Name="backButton" IsTabStop="true" IsEnabled="false" Click="OnBackButtonClicked">
<Image Source="Assets/UI/back.png" Height="18"></Image> <Image Source="Assets/UI/back.png" Height="18"></Image>
<Button.KeyboardAccelerators> <Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Left" Modifiers="Menu" /> <KeyboardAccelerator Key="Left" Modifiers="Menu" />
</Button.KeyboardAccelerators> </Button.KeyboardAccelerators>
</Button> </Button>
<Button Style="{StaticResource NavigationBarButton}" x:Name="forwardButton" IsTabStop="true" IsEnabled="false" Click="OnForwardButtonClicked" AutomationProperties.Name="Forward" ToolTipService.ToolTip="Forward"> <Button Style="{StaticResource NavigationBarButton}" x:Uid="forwardButton" x:Name="forwardButton" IsTabStop="true" IsEnabled="false" Click="OnForwardButtonClicked">
<Image Source="Assets/UI/forward.png" Height="18"></Image> <Image Source="Assets/UI/forward.png" Height="18"></Image>
<Button.KeyboardAccelerators> <Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Right" Modifiers="Menu" /> <KeyboardAccelerator Key="Right" Modifiers="Menu" />
</Button.KeyboardAccelerators> </Button.KeyboardAccelerators>
</Button> </Button>
<Button Style="{StaticResource NavigationBarButton}" x:Name="reloadButton" IsTabStop="true" IsEnabled="false" Visibility="Visible" Click="OnReloadButtonClicked" AutomationProperties.Name="Reload" ToolTipService.ToolTip="Reload"> <Button Style="{StaticResource NavigationBarButton}" x:Name="reloadButton" x:Uid="reloadButton" IsTabStop="true" IsEnabled="false" Visibility="Visible" Click="OnReloadButtonClicked">
<Image Source="Assets/UI/reload.png" Height="18"></Image> <Image Source="Assets/UI/reload.png" Height="18"></Image>
<Button.KeyboardAccelerators> <Button.KeyboardAccelerators>
<KeyboardAccelerator Key="R" Modifiers="Control" /> <KeyboardAccelerator Key="R" Modifiers="Control" />
</Button.KeyboardAccelerators> </Button.KeyboardAccelerators>
</Button> </Button>
<Button Style="{StaticResource NavigationBarButton}" x:Name="stopButton" IsTabStop="true" IsEnabled="false" Visibility="Collapsed" Click="OnStopButtonClicked" AutomationProperties.Name="Stop" ToolTipService.ToolTip="Stop"> <Button Style="{StaticResource NavigationBarButton}" x:Name="stopButton" x:Uid="stopButton" IsTabStop="true" IsEnabled="false" Visibility="Collapsed" Click="OnStopButtonClicked">
<Image Source="Assets/UI/cross.png" Height="18"></Image> <Image Source="Assets/UI/cross.png" Height="18"></Image>
<Button.KeyboardAccelerators> <Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Escape" Modifiers="None" /> <KeyboardAccelerator Key="Escape" Modifiers="None" />
</Button.KeyboardAccelerators> </Button.KeyboardAccelerators>
</Button> </Button>
<Button Style="{StaticResource NavigationBarButton}" x:Name="homeButton" IsTabStop="true" Click="OnHomeButtonClicked" AutomationProperties.Name="Home" ToolTipService.ToolTip="Home"> <Button Style="{StaticResource NavigationBarButton}" x:Name="homeButton" x:Uid="homeButton" IsTabStop="true" Click="OnHomeButtonClicked">
<Image Source="Assets/UI/home.png" Height="18"></Image> <Image Source="Assets/UI/home.png" Height="18"></Image>
</Button> </Button>
</StackPanel> </StackPanel>
<TextBox Text="" IsTabStop="true" InputScope="Url" PlaceholderText="Type a URL" x:Name="urlTextbox" VerticalAlignment="Center" Grid.Column="1" KeyUp="OnURLEdited" IsSpellCheckEnabled="False" Margin="3,0" KeyboardAcceleratorPlacementMode="Hidden"> <TextBox x:Uid="urlTextbox" Text="" IsTabStop="true" InputScope="Url" x:Name="urlTextbox" VerticalAlignment="Center" Grid.Column="1" KeyUp="OnURLEdited" IsSpellCheckEnabled="False" Margin="3,0" KeyboardAcceleratorPlacementMode="Hidden">
<TextBox.KeyboardAccelerators> <TextBox.KeyboardAccelerators>
<KeyboardAccelerator Key="L" Modifiers="Control" Invoked="OnURLKeyboardAccelerator"/> <KeyboardAccelerator Key="L" Modifiers="Control" Invoked="OnURLKeyboardAccelerator"/>
</TextBox.KeyboardAccelerators> </TextBox.KeyboardAccelerators>
</TextBox> </TextBox>
<StackPanel Orientation="Horizontal" Grid.Column="2"> <StackPanel Orientation="Horizontal" Grid.Column="2">
<Button Style="{StaticResource NavigationBarButton}" x:Name="devtoolsButton" IsTabStop="true" Click="OnDevtoolsButtonClicked" AutomationProperties.Name="Devtools" ToolTipService.ToolTip="Devtools"> <Button Style="{StaticResource NavigationBarButton}" x:Name="devtoolsButton" x:Uid="devtoolsButton" IsTabStop="true" Click="OnDevtoolsButtonClicked">
<Image Source="Assets/UI/devtools.png" Height="18"></Image> <Image Source="Assets/UI/devtools.png" Height="18"></Image>
</Button> </Button>
<ProgressRing x:Name="urlbarLoadingIndicator" Margin="10,0"/> <ProgressRing x:Name="urlbarLoadingIndicator" Margin="10,0"/>
@ -151,28 +149,16 @@
</Button> </Button>
</Grid> </Grid>
</muxc:TabView.TabStripFooter> </muxc:TabView.TabStripFooter>
<muxc:TabViewItem Header="Devtools Server" IsClosable="False"> <muxc:TabViewItem x:Uid="devtoolsTabServer" IsClosable="False">
<StackPanel> <TextBlock x:Name="DevtoolsStatusMessage" Margin="10"></TextBlock>
<TextBlock x:Name="DevtoolsStatusOK" Visibility="Collapsed" Margin="10">
<Run>Devtools server is listening on port </Run>
<Run FontWeight="Bold" x:Name="DevtoolsPort"></Run>
<Run>.</Run>
</TextBlock>
<TextBlock x:Name="DevtoolsStatusKO" Visibility="Collapsed">
<Run>Devtools server failed to start.</Run>
</TextBlock>
<TextBlock x:Name="DevtoolsStatusWIP" Visibility="Collapsed">
<Run>Devtools server is starting..</Run>
</TextBlock>
</StackPanel>
</muxc:TabViewItem> </muxc:TabViewItem>
<muxc:TabViewItem Header="Preferences" IsClosable="False"> <muxc:TabViewItem x:Uid="devtoolsTabPrefs" IsClosable="False">
<Grid VerticalAlignment="Stretch"> <Grid VerticalAlignment="Stretch">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="" IsTabStop="true" PlaceholderText="Search preferences" x:Name="preferenceSearchbox" VerticalAlignment="Center" KeyUp="OnPrefererenceSearchboxEdited" IsSpellCheckEnabled="False" Margin="3"/> <TextBox Grid.Row="0" IsTabStop="true" x:Uid="preferenceSearchbox" x:Name="preferenceSearchbox" VerticalAlignment="Center" KeyUp="OnPrefererenceSearchboxEdited" IsSpellCheckEnabled="False" Margin="3"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"> <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="prefList"/> <StackPanel x:Name="prefList"/>
</ScrollViewer> </ScrollViewer>
@ -181,8 +167,8 @@
</muxc:TabView> </muxc:TabView>
<ProgressBar x:Name="transientLoadingIndicator" Visibility="Collapsed" Grid.Row="3"/> <ProgressBar x:Name="transientLoadingIndicator" Visibility="Collapsed" Grid.Row="3"/>
<CommandBar Grid.Row="4" x:Name="mediaControls" Visibility="Collapsed"> <CommandBar Grid.Row="4" x:Name="mediaControls" Visibility="Collapsed">
<AppBarButton Icon="Play" Label="Play" x:Name="playButton" Visibility="Collapsed" Click="OnMediaControlsPlayClicked"/> <AppBarButton Icon="Play" x:Uid="playButton" x:Name="playButton" Visibility="Collapsed" Click="OnMediaControlsPlayClicked"/>
<AppBarButton Icon="Pause" Label="Pause" x:Name="pauseButton" Click="OnMediaControlsPauseClicked"/> <AppBarButton Icon="Pause" x:Uid="pauseButton" x:Name="pauseButton" Click="OnMediaControlsPauseClicked"/>
</CommandBar> </CommandBar>
</Grid> </Grid>

View file

@ -16,7 +16,7 @@
</Resources> </Resources>
<Applications> <Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ServoApp.App"> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ServoApp.App">
<uap:VisualElements DisplayName="Firefox Reality" Description="Firefox Reality brings the best and freshest content from the web that you know and love to Virtual Reality headsets. Our browser provides an open, accessible and secure way for everyone to explore the web. Experience sharp text, high quality videos, and a seamless transition from 2D to 3D immersive modes. Enjoy the best possible web browsing experience with Firefox Reality." Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent"> <uap:VisualElements DisplayName="Firefox Reality" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent" Description="ms-resource:appDescription">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="Firefox Reality" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"> <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="Firefox Reality" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
<uap:ShowNameOnTiles> <uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo" /> <uap:ShowOn Tile="square150x150Logo" />

View file

@ -942,6 +942,10 @@
</None> </None>
<None Include="PropertySheet.props" /> <None Include="PropertySheet.props" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PRIResource Include="Strings\en-US\Resources.resw" />
<PRIResource Include="Strings\fr-FR\Resources.resw" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> <Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" />

View file

@ -887,6 +887,15 @@
<Filter Include="Assets\UI"> <Filter Include="Assets\UI">
<UniqueIdentifier>{d49fe329-5e22-4470-8310-5b925419e6f8}</UniqueIdentifier> <UniqueIdentifier>{d49fe329-5e22-4470-8310-5b925419e6f8}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Strings">
<UniqueIdentifier>{49e23631-d899-4caf-bf7b-30776fee4d09}</UniqueIdentifier>
</Filter>
<Filter Include="Strings\en-US">
<UniqueIdentifier>{c12ff5d4-3730-4a0e-8b16-56ded3138875}</UniqueIdentifier>
</Filter>
<Filter Include="Strings\fr-FR">
<UniqueIdentifier>{b7d3273d-a27c-4176-87a1-3d5222b796b3}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="PropertySheet.props" /> <None Include="PropertySheet.props" />
@ -900,4 +909,12 @@
<ItemGroup> <ItemGroup>
<ApplicationDefinition Include="App.xaml" /> <ApplicationDefinition Include="App.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PRIResource Include="Strings\en-US\Resources.resw">
<Filter>Strings\en-US</Filter>
</PRIResource>
<PRIResource Include="Strings\fr-FR\Resources.resw">
<Filter>Strings\fr-FR</Filter>
</PRIResource>
</ItemGroup>
</Project> </Project>

View file

@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
using namespace std::placeholders; using namespace std::placeholders;
using namespace winrt::Windows::ApplicationModel::Resources;
using namespace winrt::Windows::Graphics::Display; using namespace winrt::Windows::Graphics::Display;
using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Popups; using namespace winrt::Windows::UI::Popups;
@ -22,6 +23,16 @@ ServoControl::ServoControl() {
mDPI = (float)DisplayInformation::GetForCurrentView().ResolutionScale() / 100; mDPI = (float)DisplayInformation::GetForCurrentView().ResolutionScale() / 100;
DefaultStyleKey(winrt::box_value(L"ServoApp.ServoControl")); DefaultStyleKey(winrt::box_value(L"ServoApp.ServoControl"));
Loaded(std::bind(&ServoControl::OnLoaded, this, _1, _2)); Loaded(std::bind(&ServoControl::OnLoaded, this, _1, _2));
auto r = ResourceLoader::GetForCurrentView();
L10NStrings l10NStrings = {r.GetString(L"ContextMenu/title"),
r.GetString(L"JavascriptPrompt/title"),
r.GetString(L"JavascriptPrompt/ok"),
r.GetString(L"JavascriptPrompt/cancel"),
r.GetString(L"JavascriptPrompt/yes"),
r.GetString(L"JavascriptPrompt/no"),
r.GetString(L"URINotValid/Alert")};
mL10NStrings = std::make_unique<L10NStrings>(l10NStrings);
} }
void ServoControl::Shutdown() { void ServoControl::Shutdown() {
@ -278,9 +289,11 @@ hstring ServoControl::LoadURIOrSearch(hstring input) {
// Doesn't look like a URI. Let's search for the string. // Doesn't look like a URI. Let's search for the string.
auto escapedInput = Uri::EscapeComponent(input); auto escapedInput = Uri::EscapeComponent(input);
std::wstring searchUri = unbox_value<hstring>(std::get<1>(Servo::GetPref(L"shell.searchpage"))).c_str(); std::wstring searchUri =
std::wstring formated = format(searchUri, escapedInput.c_str()); unbox_value<hstring>(std::get<1>(Servo::GetPref(L"shell.searchpage")))
hstring finalUri{formated}; .c_str();
std::wstring formatted = format(searchUri, escapedInput.c_str());
hstring finalUri{formatted};
TryLoadUri(finalUri); TryLoadUri(finalUri);
return finalUri; return finalUri;
} }
@ -299,7 +312,7 @@ void ServoControl::TryLoadUri(hstring input) {
RunOnGLThread([=] { RunOnGLThread([=] {
if (!mServo->LoadUri(input)) { if (!mServo->LoadUri(input)) {
RunOnUIThread([=] { RunOnUIThread([=] {
MessageDialog msg{L"URI not valid"}; MessageDialog msg{mL10NStrings->URINotValid};
msg.ShowAsync(); msg.ShowAsync();
}); });
} }
@ -509,14 +522,19 @@ ServoControl::PromptSync(hstring title, hstring message, hstring primaryButton,
} }
void ServoControl::OnServoPromptAlert(winrt::hstring message, bool trusted) { void ServoControl::OnServoPromptAlert(winrt::hstring message, bool trusted) {
auto title = trusted ? L"" : mCurrentUrl + L" says:"; auto titlefmt =
PromptSync(title, message, L"OK", {}, {}); format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
hstring title{trusted ? L"" : titlefmt};
PromptSync(title, message, mL10NStrings->PromptOk, {}, {});
} }
Servo::PromptResult Servo::PromptResult ServoControl::OnServoPromptOkCancel(winrt::hstring message,
ServoControl::OnServoPromptOkCancel(winrt::hstring message, bool trusted) { bool trusted) {
auto title = trusted ? L"" : mCurrentUrl + L" says:"; auto titlefmt =
auto [button, string] = PromptSync(title, message, L"OK", L"Cancel", {}); format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
hstring title{trusted ? L"" : titlefmt};
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptOk,
mL10NStrings->PromptCancel, {});
if (button == Controls::ContentDialogResult::Primary) { if (button == Controls::ContentDialogResult::Primary) {
return Servo::PromptResult::Primary; return Servo::PromptResult::Primary;
} else if (button == Controls::ContentDialogResult::Secondary) { } else if (button == Controls::ContentDialogResult::Secondary) {
@ -526,10 +544,13 @@ ServoControl::OnServoPromptOkCancel(winrt::hstring message, bool trusted) {
} }
} }
Servo::PromptResult Servo::PromptResult ServoControl::OnServoPromptYesNo(winrt::hstring message,
ServoControl::OnServoPromptYesNo(winrt::hstring message, bool trusted) { bool trusted) {
auto title = trusted ? L"" : mCurrentUrl + L" says:"; auto titlefmt =
auto [button, string] = PromptSync(title, message, L"Yes", L"No", {}); format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
hstring title{trusted ? L"" : titlefmt};
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptYes,
mL10NStrings->PromptNo, {});
if (button == Controls::ContentDialogResult::Primary) { if (button == Controls::ContentDialogResult::Primary) {
return Servo::PromptResult::Primary; return Servo::PromptResult::Primary;
} else if (button == Controls::ContentDialogResult::Secondary) { } else if (button == Controls::ContentDialogResult::Secondary) {
@ -542,8 +563,11 @@ ServoControl::OnServoPromptYesNo(winrt::hstring message, bool trusted) {
std::optional<hstring> ServoControl::OnServoPromptInput(winrt::hstring message, std::optional<hstring> ServoControl::OnServoPromptInput(winrt::hstring message,
winrt::hstring default, winrt::hstring default,
bool trusted) { bool trusted) {
auto title = trusted ? L"" : mCurrentUrl + L" says:"; auto titlefmt =
auto [button, string] = PromptSync(title, message, L"Ok", L"Cancel", default); format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
hstring title{trusted ? L"" : titlefmt};
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptOk,
mL10NStrings->PromptCancel, default);
return string; return string;
} }
@ -558,7 +582,8 @@ void ServoControl::OnServoDevtoolsStarted(bool success,
void ServoControl::OnServoShowContextMenu(std::optional<hstring> title, void ServoControl::OnServoShowContextMenu(std::optional<hstring> title,
std::vector<winrt::hstring> items) { std::vector<winrt::hstring> items) {
RunOnUIThread([=] { RunOnUIThread([=] {
MessageDialog msg{title.value_or(L"Menu")}; auto titlestr = mL10NStrings->ContextMenuTitle;
MessageDialog msg{title.value_or(titlestr)};
for (auto i = 0; i < items.size(); i++) { for (auto i = 0; i < items.size(); i++) {
UICommand cmd{items[i], [=](auto) { UICommand cmd{items[i], [=](auto) {
RunOnGLThread([=] { RunOnGLThread([=] {
@ -568,7 +593,7 @@ void ServoControl::OnServoShowContextMenu(std::optional<hstring> title,
}}; }};
msg.Commands().Append(cmd); msg.Commands().Append(cmd);
} }
UICommand cancel{L"Cancel", [=](auto) { UICommand cancel{mL10NStrings->PromptCancel, [=](auto) {
RunOnGLThread([=] { RunOnGLThread([=] {
mServo->ContextMenuClosed( mServo->ContextMenuClosed(
Servo::ContextMenuResult::Dismissed_, 0); Servo::ContextMenuResult::Dismissed_, 0);

View file

@ -26,6 +26,16 @@ private:
bool mIsDefault; bool mIsDefault;
}; };
struct L10NStrings {
hstring ContextMenuTitle;
hstring PromptTitle;
hstring PromptOk;
hstring PromptCancel;
hstring PromptYes;
hstring PromptNo;
hstring URINotValid;
};
struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate { struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
ServoControl(); ServoControl();
@ -266,8 +276,8 @@ private:
CONDITION_VARIABLE mGLCondVar; CONDITION_VARIABLE mGLCondVar;
std::unique_ptr<Concurrency::task<void>> mLoopTask; std::unique_ptr<Concurrency::task<void>> mLoopTask;
hstring mArgs; hstring mArgs;
std::optional<servo::Servo::MouseButton> mPressedMouseButton = {}; std::optional<servo::Servo::MouseButton> mPressedMouseButton = {};
std::unique_ptr<L10NStrings> mL10NStrings = nullptr;
}; };
} // namespace winrt::ServoApp::implementation } // namespace winrt::ServoApp::implementation

View file

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!-- A xx-XX/Resources.resw file doesn't need to 100% cover the en-US/Resources.resw counterpart.
The application falls back to the english resources if the string is not found -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="appDescription" xml:space="preserve">
<value>Firefox Reality brings the best and freshest content from the web that you know and love to Virtual Reality headsets. Our browser provides an open, accessible and secure way for everyone to explore the web. Experience sharp text, high quality videos, and a seamless transition from 2D to 3D immersive modes. Enjoy the best possible web browsing experience with Firefox Reality.</value>
</data>
<data name="backButton.AutomationProperties.Name" xml:space="preserve">
<value>Back</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="backButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Back</value>
</data>
<data name="devtoolsButton.AutomationProperties.Name" xml:space="preserve">
<value>Developer Tools</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="devtoolsButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Developer Tools</value>
</data>
<data name="forwardButton.AutomationProperties.Name" xml:space="preserve">
<value>Forward</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="forwardButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Forward</value>
</data>
<data name="homeButton.AutomationProperties.Name" xml:space="preserve">
<value>Home</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="homeButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Home</value>
</data>
<data name="reloadButton.AutomationProperties.Name" xml:space="preserve">
<value>Reload</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="reloadButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Reload</value>
</data>
<data name="stopButton.AutomationProperties.Name" xml:space="preserve">
<value>Stop</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="stopButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Stop</value>
</data>
<data name="urlTextbox.PlaceholderText" xml:space="preserve">
<value>Type a URL</value>
</data>
<data name="devtoolsTabServer.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve">
<value>Devtools Server</value>
</data>
<data name="devtoolsTabPrefs.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve">
<value>Preferences</value>
</data>
<data name="preferenceSearchbox.PlaceholderText" xml:space="preserve">
<value>Search Preferences</value>
</data>
<data name="playButton.Label" xml:space="preserve">
<value>Play</value>
</data>
<data name="pauseButton.Label" xml:space="preserve">
<value>Pause</value>
</data>
<data name="devtoolsStatus.Running" xml:space="preserve">
<value>Devtools server is listening on port %s.</value>
</data>
<data name="devtoolsStatus.Failed" xml:space="preserve">
<value>Devtools server failed to start.</value>
</data>
<data name="devtoolsStatus.Stopped" xml:space="preserve">
<value>Devtools server is starting.</value>
</data>
<data name="devtoolsPreferenceResetButton.Content" xml:space="preserve">
<value>reset</value>
</data>
<data name="URINotValid.Alert" xml:space="preserve">
<value>URI not valid</value>
</data>
<data name="JavascriptPrompt.ok" xml:space="preserve">
<value>ok</value>
</data>
<data name="JavascriptPrompt.cancel" xml:space="preserve">
<value>cancel</value>
</data>
<data name="JavascriptPrompt.yes" xml:space="preserve">
<value>yes</value>
</data>
<data name="JavascriptPrompt.no" xml:space="preserve">
<value>no</value>
</data>
<data name="JavascriptPrompt.title" xml:space="preserve">
<value>"%s" says:</value>
</data>
<data name="ContextMenu.title" xml:space="preserve">
<value>Menu</value>
</data>
</root>

View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="backButton.AutomationProperties.Name" xml:space="preserve">
<value>Retour</value>
<comment>Will be recognized by the speech recognition system</comment>
</data>
<data name="backButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Retour</value>
</data>
<data name="devtoolsButton.AutomationProperties.Name" xml:space="preserve">
<comment>Will be recognized by the speech recognition system</comment>
<value>Outils de développement</value>
</data>
<data name="devtoolsButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Outils de développement</value>
</data>
<data name="forwardButton.AutomationProperties.Name" xml:space="preserve">
<comment>Will be recognized by the speech recognition system</comment>
<value>Avancer</value>
</data>
<data name="forwardButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Avancer</value>
</data>
<data name="homeButton.AutomationProperties.Name" xml:space="preserve">
<comment>Will be recognized by the speech recognition system</comment>
<value>Accueil</value>
</data>
<data name="homeButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Accueil</value>
</data>
<data name="reloadButton.AutomationProperties.Name" xml:space="preserve">
<comment>Will be recognized by the speech recognition system</comment>
<value>Actualiser</value>
</data>
<data name="reloadButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Actualiser</value>
</data>
<data name="stopButton.AutomationProperties.Name" xml:space="preserve">
<comment>Will be recognized by the speech recognition system</comment>
<value>Arrêter</value>
</data>
<data name="stopButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Arrêter</value>
</data>
<data name="urlTextbox.PlaceholderText" xml:space="preserve">
<value>Saisir une adresse</value>
</data>
<data name="devtoolsTabServer.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve">
<value>Serveur DevTools</value>
</data>
<data name="devtoolsTabPrefs.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve">
<value>Préférences</value>
</data>
<data name="preferenceSearchbox.PlaceholderText" xml:space="preserve">
<value>Rechercher préférence</value>
</data>
<data name="playButton.Label" xml:space="preserve">
<value>Jouer</value>
</data>
<data name="pauseButton.Label" xml:space="preserve">
<value>Pause</value>
</data>
<data name="devtoolsStatus.Running" xml:space="preserve">
<value>Le serveur DevTools écoute sur le port %s.</value>
</data>
<data name="devtoolsStatus.Failed" xml:space="preserve">
<value>Le serveur DevTools n'a pas pu démarrer.</value>
</data>
<data name="devtoolsStatus.Stopped" xml:space="preserve">
<value>Le serveur DevTools démarre.</value>
</data>
<data name="devtoolsPreferenceResetButton.Content" xml:space="preserve">
<value>réinitialiser</value>
</data>
<data name="URINotValid.Alert" xml:space="preserve">
<value>URI invalide</value>
</data>
<data name="JavascriptPrompt.ok" xml:space="preserve">
<value>ok</value>
</data>
<data name="JavascriptPrompt.cancel" xml:space="preserve">
<value>annuler</value>
</data>
<data name="JavascriptPrompt.yes" xml:space="preserve">
<value>oui</value>
</data>
<data name="JavascriptPrompt.no" xml:space="preserve">
<value>non</value>
</data>
<data name="JavascriptPrompt.title" xml:space="preserve">
<value>"%s" dit:</value>
</data>
<data name="ContextMenu.title" xml:space="preserve">
<value>Menu</value>
</data>
</root>

View file

@ -29,6 +29,7 @@
#include <winrt/Windows.ApplicationModel.Activation.h> #include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.ApplicationModel.Core.h> #include <winrt/Windows.ApplicationModel.Core.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.Collections.h> #include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h> #include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Metadata.h> #include <winrt/Windows.Foundation.Metadata.h>