diff options
author | bors-servo <servo-ops@mozilla.com> | 2020-06-19 17:50:01 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-19 17:50:01 -0400 |
commit | 0f4e59a46447c9f6514f3f9403a5dcaf6552fdac (patch) | |
tree | 4a212264d20d695d7c06298d89f515862b5e5aa5 | |
parent | d71847b2bf400820ad9f5b26a077296b9ca8b921 (diff) | |
parent | c722b5fdca6d6552dec9debcbc55212066286e1c (diff) | |
download | servo-0f4e59a46447c9f6514f3f9403a5dcaf6552fdac.tar.gz servo-0f4e59a46447c9f6514f3f9403a5dcaf6552fdac.zip |
Auto merge of #26985 - paulrouget:gridview, r=jdm
UWP console: better output + JS input
This adds a textbox to enter javascript, and also redesign the output with better XAML controls.
<img width="656" alt="Screen Shot 2020-06-19 at 08 05 50" src="https://user-images.githubusercontent.com/373579/85102037-08794500-b204-11ea-892b-69f436846499.png">
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.cpp | 52 | ||||
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.h | 26 | ||||
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.idl | 10 | ||||
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.xaml | 39 | ||||
-rw-r--r-- | support/hololens/ServoApp/Devtools/Client.cpp | 42 | ||||
-rw-r--r-- | support/hololens/ServoApp/Devtools/Client.h | 3 | ||||
-rw-r--r-- | support/hololens/ServoApp/pch.h | 2 |
7 files changed, 140 insertions, 34 deletions
diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index 29b18a3e439..e4f460d3497 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -6,6 +6,7 @@ #include "strutils.h" #include "BrowserPage.h" #include "BrowserPage.g.cpp" +#include "ConsoleLog.g.cpp" #include "DefaultUrl.h" #include "Devtools/Client.h" @@ -26,6 +27,7 @@ namespace winrt::ServoApp::implementation { BrowserPage::BrowserPage() { InitializeComponent(); BindServoEvents(); + mLogs = winrt::single_threaded_observable_vector<IInspectable>(); } void BrowserPage::BindServoEvents() { @@ -274,39 +276,22 @@ void BrowserPage::OnPrefererenceSearchboxEdited( } void BrowserPage::ClearConsole() { - Dispatcher().RunAsync(CoreDispatcherPriority::Low, - [=] { DevtoolsConsoleOutput().Blocks().Clear(); }); + Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] { mLogs.Clear(); }); } void BrowserPage::OnDevtoolsMessage(DevtoolsMessageLevel level, hstring source, hstring body) { - Dispatcher().RunAsync(CoreDispatcherPriority::Low, [=] { - // Temporary text-based logs. Should use gridview. - auto paragraph = Documents::Paragraph(); - - auto run1 = Documents::Run(); - if (level == DevtoolsMessageLevel::Warn) { - run1.Text(L"warn: "); - } else if (level == DevtoolsMessageLevel::Error) { - run1.Text(L"error: "); - } else if (level == DevtoolsMessageLevel::None) { - run1.Text(L""); + Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] { + auto fgColor = UI::Colors::White(); + auto bgColor = UI::Colors::White(); + if (level == servo::DevtoolsMessageLevel::Error) { + fgColor = UI::Colors::Red(); + bgColor = UI::Colors::LightPink(); + } else if (level == servo::DevtoolsMessageLevel::Warn) { + fgColor = UI::Colors::Orange(); + bgColor = UI::Colors::LightYellow(); } - paragraph.Inlines().Append(run1); - - auto run2 = Documents::Run(); - run2.Text(body); - paragraph.Inlines().Append(run2); - - auto run3 = Documents::Run(); - run3.Text(L" " + source); - paragraph.Inlines().Append(run3); - - DevtoolsConsoleOutput().Blocks().Append(paragraph); - - // Scroll to last message - auto offset = DevtoolsConsoleScrollViewer().ExtentHeight(); - DevtoolsConsoleScrollViewer().ChangeView(nullptr, offset, nullptr); + mLogs.Append(make<ConsoleLog>(fgColor, bgColor, body, source)); }); } @@ -317,7 +302,7 @@ void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &, if (toolbox().Visibility() == Visibility::Visible) { prefList().Children().Clear(); toolbox().Visibility(Visibility::Collapsed); - DevtoolsConsoleOutput().Blocks().Clear(); + ClearConsole(); if (mDevtoolsClient != nullptr) { mDevtoolsClient->Stop(); } @@ -350,6 +335,15 @@ void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &, } } +void BrowserPage::OnJSInputEdited(IInspectable const &, + Input::KeyRoutedEventArgs const &e) { + if (e.Key() == Windows::System::VirtualKey::Enter) { + auto input = JSInput().Text(); + JSInput().Text(L""); + mDevtoolsClient->Evaluate(input); + } +} + void BrowserPage::OnURLEdited(IInspectable const &, Input::KeyRoutedEventArgs const &e) { if (e.Key() == Windows::System::VirtualKey::Enter) { diff --git a/support/hololens/ServoApp/BrowserPage.h b/support/hololens/ServoApp/BrowserPage.h index db127cdf569..454baee9076 100644 --- a/support/hololens/ServoApp/BrowserPage.h +++ b/support/hololens/ServoApp/BrowserPage.h @@ -5,6 +5,7 @@ #pragma once #include "BrowserPage.g.h" +#include "ConsoleLog.g.h" #include "ServoControl/ServoControl.h" #include "Devtools/Client.h" @@ -14,6 +15,7 @@ using namespace winrt::Windows; using namespace winrt::Windows::Data::Json; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::UI::Xaml::Media; static const hstring SERVO_SCHEME = L"fxr"; static const hstring SERVO_SCHEME_SLASH_SLASH = L"fxr://"; @@ -28,6 +30,7 @@ public: void OnStopButtonClicked(IInspectable const &, RoutedEventArgs const &); void OnHomeButtonClicked(IInspectable const &, RoutedEventArgs const &); void OnDevtoolsButtonClicked(IInspectable const &, RoutedEventArgs const &); + void OnJSInputEdited(IInspectable const &, Input::KeyRoutedEventArgs const &); void OnURLEdited(IInspectable const &, Input::KeyRoutedEventArgs const &); void OnURLFocused(IInspectable const &); void @@ -46,6 +49,7 @@ public: void OnDevtoolsMessage(servo::DevtoolsMessageLevel, hstring, hstring); void ClearConsole(); void OnDevtoolsDetached(); + Collections::IObservableVector<IInspectable> ConsoleLogs() { return mLogs; }; private: void UpdatePref(ServoApp::Pref, Controls::Control); @@ -54,9 +58,31 @@ private: DevtoolsStatus mDevtoolsStatus = DevtoolsStatus::Stopped; unsigned int mDevtoolsPort = 0; std::unique_ptr<servo::DevtoolsClient> mDevtoolsClient; + Collections::IObservableVector<IInspectable> mLogs; }; + +struct ConsoleLog : ConsoleLogT<ConsoleLog> { +public: + ConsoleLog(Windows::UI::Color fg, Windows::UI::Color bg, hstring b, hstring s) + : mSource(s), mBody(b) { + mFgColor = UI::Xaml::Media::SolidColorBrush(fg); + mBgColor = UI::Xaml::Media::SolidColorBrush(bg); + }; + SolidColorBrush FgColor() { return mFgColor; }; + SolidColorBrush BgColor() { return mBgColor; }; + hstring Source() { return mSource; }; + hstring Body() { return mBody; }; + +private: + SolidColorBrush mFgColor; + SolidColorBrush mBgColor; + hstring mSource; + hstring mBody; +}; + } // namespace winrt::ServoApp::implementation namespace winrt::ServoApp::factory_implementation { struct BrowserPage : BrowserPageT<BrowserPage, implementation::BrowserPage> {}; +struct ConsoleLog : ConsoleLogT<ConsoleLog, implementation::ConsoleLog> {}; } // namespace winrt::ServoApp::factory_implementation diff --git a/support/hololens/ServoApp/BrowserPage.idl b/support/hololens/ServoApp/BrowserPage.idl index 47de6a4ed66..1f1c32342bc 100644 --- a/support/hololens/ServoApp/BrowserPage.idl +++ b/support/hololens/ServoApp/BrowserPage.idl @@ -4,5 +4,15 @@ namespace ServoApp runtimeclass BrowserPage : Windows.UI.Xaml.Controls.Page { BrowserPage(); + Windows.Foundation.Collections.IObservableVector<IInspectable> ConsoleLogs{ get; }; + } + + runtimeclass ConsoleLog + { + ConsoleLog(Windows.UI.Color fgColor, Windows.UI.Color bgColor, String body, String source); + Windows.UI.Xaml.Media.SolidColorBrush FgColor { get; }; + Windows.UI.Xaml.Media.SolidColorBrush BgColor { get; }; + String Body{ get; }; + String Source{ get; }; } } diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index bb034bba5fb..7f1f051a444 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -150,10 +150,41 @@ </Grid> </muxc:TabView.TabStripFooter> <muxc:TabViewItem x:Uid="devtoolsTabConsole" IsClosable="False"> - <ScrollViewer x:Name="DevtoolsConsoleScrollViewer" VerticalScrollMode="Enabled" HorizontalScrollMode="Enabled"> - <RichTextBlock x:Name="DevtoolsConsoleOutput" FontSize="10" FontFamily="Consolas" LineHeight="14"> - </RichTextBlock> - </ScrollViewer> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="*"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + <ListView ItemsSource="{x:Bind ConsoleLogs}"> + <ListView.ItemsPanel> + <ItemsPanelTemplate> + <ItemsStackPanel Orientation="Vertical" ItemsUpdatingScrollMode="KeepLastItemInView"/> + </ItemsPanelTemplate> + </ListView.ItemsPanel> + <ListView.ItemTemplate> + <DataTemplate x:DataType="local:ConsoleLog"> + <Grid Background="{x:Bind BgColor}" Padding="2"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="Auto"/> + </Grid.ColumnDefinitions> + <Ellipse Width="8" Height="8" Fill="{x:Bind FgColor}" Grid.Column="0" Margin="10,0"/> + <TextBlock FontFamily="Consolas" FontSize="12" Text="{x:Bind Body}" Grid.Column="1"/> + <TextBlock FontFamily="Consolas" FontSize="12" Text="{x:Bind Source}" Foreground="Gray" Grid.Column="2" Margin="10,0"/> + </Grid> + </DataTemplate> + </ListView.ItemTemplate> + <ListView.ItemContainerStyle> + <Style TargetType="ListViewItem"> + <Setter Property="Padding" Value="0"/> + <Setter Property="MinHeight" Value="0"/> + <Setter Property="HorizontalContentAlignment" Value="Stretch"/> + </Style> + </ListView.ItemContainerStyle> + </ListView> + <TextBox MinHeight="12" FontFamily="Consolas" FontSize="12" Grid.Row="1" IsTabStop="true" x:Name="JSInput" VerticalAlignment="Center" KeyUp="OnJSInputEdited" IsSpellCheckEnabled="False"/> + </Grid> </muxc:TabViewItem> <muxc:TabViewItem x:Uid="devtoolsTabServer" IsClosable="False"> <TextBlock x:Name="DevtoolsStatusMessage" Margin="10"></TextBlock> diff --git a/support/hololens/ServoApp/Devtools/Client.cpp b/support/hololens/ServoApp/Devtools/Client.cpp index c7d1b7cfc89..65fb51df892 100644 --- a/support/hololens/ServoApp/Devtools/Client.cpp +++ b/support/hololens/ServoApp/Devtools/Client.cpp @@ -42,6 +42,16 @@ void DevtoolsClient::Run() { }); } +void DevtoolsClient::Evaluate(hstring code) { + if (!code.empty() && mConsoleActor.has_value()) { + JsonObject out; + out.Insert(L"to", *mConsoleActor); + out.Insert(L"type", JsonValue::CreateStringValue(L"evaluateJSAsync")); + out.Insert(L"text", JsonValue::CreateStringValue(code)); + Send(out); + } +} + IAsyncAction DevtoolsClient::Loop() { auto cancellation = co_await winrt::get_cancellation_token(); cancellation.callback([=] { @@ -101,11 +111,12 @@ void DevtoolsClient::HandleMessage(JsonObject obj) { if (tab.HasKey(L"actor")) { // Attach to tab, and ask for cached messaged JsonObject msg1; + mConsoleActor = tab.GetNamedValue(L"consoleActor"); msg1.Insert(L"to", tab.GetNamedValue(L"actor")); msg1.Insert(L"type", JsonValue::CreateStringValue(L"attach")); Send(msg1); JsonObject msg2; - msg2.Insert(L"to", tab.GetNamedValue(L"consoleActor")); + msg2.Insert(L"to", *mConsoleActor); msg2.Insert(L"type", JsonValue::CreateStringValue(L"getCachedMessages")); JsonArray types; @@ -116,6 +127,12 @@ void DevtoolsClient::HandleMessage(JsonObject obj) { return; } } + } else if (obj.HasKey(L"resultID")) { + // evaluateJSAsync response. + if (obj.GetNamedString(L"type", L"") == L"evaluationResult") { + HandleEvaluationResult(obj); + } + return; } else if (obj.HasKey(L"type")) { // Not from root if (obj.GetNamedString(L"type") == L"pageError") { // Got a page error @@ -196,6 +213,29 @@ void DevtoolsClient::HandlePageError(JsonObject message) { mDelegate.OnDevtoolsMessage(level, source, body); } +void DevtoolsClient::HandleEvaluationResult(JsonObject message) { + auto level = DevtoolsMessageLevel::None; + hstring body = L""; + if (message.HasKey(L"result")) { + auto value = message.GetNamedValue(L"result"); + if (value.ValueType() == JsonValueType::Object) { + auto type = value.GetObject().GetNamedString(L"type"); + if (type == L"undefined") { + body = L"undefined"; + } else { + body = L"<object>"; + } + } else { + body = value.Stringify(); + } + } else if (message.GetNamedValue(L"exception").ValueType() != + JsonValueType::Null) { + level = DevtoolsMessageLevel::Error; + body = message.GetNamedString(L"exceptionMessage", L""); + } + mDelegate.OnDevtoolsMessage(level, L"", body); +} + void DevtoolsClient::HandleConsoleMessage(JsonObject message) { auto source = ParseSource(message); auto level = ParseLevel(message); diff --git a/support/hololens/ServoApp/Devtools/Client.h b/support/hololens/ServoApp/Devtools/Client.h index 3764c201d46..67e11c3fe79 100644 --- a/support/hololens/ServoApp/Devtools/Client.h +++ b/support/hololens/ServoApp/Devtools/Client.h @@ -26,6 +26,7 @@ public: void Run(); void Stop(); void Send(JsonObject); + void Evaluate(hstring); private: hstring mPort; @@ -46,6 +47,8 @@ private: void HandlePageError(JsonObject); void HandleConsoleMessage(JsonObject); void HandleNonHandledMessage(JsonObject); + void HandleEvaluationResult(JsonObject); + std::optional<JsonValue> mConsoleActor; }; class DevtoolsDelegate { diff --git a/support/hololens/ServoApp/pch.h b/support/hololens/ServoApp/pch.h index fe0197dd58d..49cffb0f3ab 100644 --- a/support/hololens/ServoApp/pch.h +++ b/support/hololens/ServoApp/pch.h @@ -54,8 +54,10 @@ #include <winrt/Windows.UI.Xaml.Documents.h> #include <winrt/Windows.UI.Xaml.Input.h> #include <winrt/Windows.UI.Xaml.Interop.h> +#include <winrt/Windows.UI.Xaml.Media.h> #include <winrt/Windows.UI.Xaml.Markup.h> #include <winrt/Windows.UI.Xaml.Navigation.h> +#include <winrt/Windows.UI.Xaml.Shapes.h> #include <winrt/Windows.UI.Notifications.h> #include <winrt/Windows.UI.Text.h> #include <winrt/Windows.Data.Xml.Dom.h> |