mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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">
This commit is contained in:
commit
0f4e59a464
7 changed files with 140 additions and 34 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue