Merge branch 'features/code-quality-js' of https://github.com/Tiktack/Wino-Mail
This commit is contained in:
@@ -8,7 +8,7 @@ namespace Wino.Core.Domain.Interfaces
|
|||||||
{
|
{
|
||||||
string GetWebAuthenticationBrokerUri();
|
string GetWebAuthenticationBrokerUri();
|
||||||
Task<string> GetMimeMessageStoragePath();
|
Task<string> GetMimeMessageStoragePath();
|
||||||
Task<string> GetQuillEditorBundlePathAsync();
|
Task<string> GetEditorBundlePathAsync();
|
||||||
Task LaunchFileAsync(string filePath);
|
Task LaunchFileAsync(string filePath);
|
||||||
Task LaunchUriAsync(Uri uri);
|
Task LaunchUriAsync(Uri uri);
|
||||||
bool IsAppRunning();
|
bool IsAppRunning();
|
||||||
|
|||||||
9
Wino.Core.Domain/Models/Requests/WebViewMessage.cs
Normal file
9
Wino.Core.Domain/Models/Requests/WebViewMessage.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Wino.Core.Domain.Models.Requests
|
||||||
|
{
|
||||||
|
// Used to pass messages from the webview to the app.
|
||||||
|
public class WebViewMessage
|
||||||
|
{
|
||||||
|
public string type { get; set; }
|
||||||
|
public string value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
"ClipboardTextCopyFailed_Message": "Failed to copy {0} to clipboard.",
|
"ClipboardTextCopyFailed_Message": "Failed to copy {0} to clipboard.",
|
||||||
"ComposerToPlaceholder": "click enter to input addresses",
|
"ComposerToPlaceholder": "click enter to input addresses",
|
||||||
"ComposerAttachmentsDropZone_Message": "Drop your files here",
|
"ComposerAttachmentsDropZone_Message": "Drop your files here",
|
||||||
|
"ComposerImagesDropZone_Message": "Drop your images here",
|
||||||
"ComposerAttachmentsDragDropAttach_Message": "Attach",
|
"ComposerAttachmentsDragDropAttach_Message": "Attach",
|
||||||
"CustomThemeBuilder_AccentColorDescription": "Set custom accent color if you wish. Not selecting a color will use your Windows accent color.",
|
"CustomThemeBuilder_AccentColorDescription": "Set custom accent color if you wish. Not selecting a color will use your Windows accent color.",
|
||||||
"CustomThemeBuilder_AccentColorTitle": "Accent color",
|
"CustomThemeBuilder_AccentColorTitle": "Accent color",
|
||||||
|
|||||||
541
Wino.Core.Domain/Translator.Designer.cs
generated
541
Wino.Core.Domain/Translator.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -77,11 +77,11 @@ namespace Wino.Services
|
|||||||
return new GoogleAuthorizationRequest(state, code_verifier, code_challenge);
|
return new GoogleAuthorizationRequest(state, code_verifier, code_challenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetQuillEditorBundlePathAsync()
|
public async Task<string> GetEditorBundlePathAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_editorBundlePath))
|
if (string.IsNullOrEmpty(_editorBundlePath))
|
||||||
{
|
{
|
||||||
var editorFileFromBundle = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///JS/Quill/full.html"))
|
var editorFileFromBundle = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///JS/editor.html"))
|
||||||
.AsTask()
|
.AsTask()
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
|||||||
@@ -670,16 +670,13 @@ namespace Wino.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
message.Headers.Add("Thread-Topic", referenceMessage.Subject);
|
message.Headers.Add("Thread-Topic", referenceMessage.Subject);
|
||||||
}
|
|
||||||
|
|
||||||
var previewer = new HtmlTextPreviewer();
|
builder.HtmlBody = CreateHtmlForReferencingMessage(referenceMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (reason == DraftCreationReason.Forward)
|
if (reason == DraftCreationReason.Forward)
|
||||||
{
|
{
|
||||||
var visitor = _mimeFileService.CreateHTMLPreviewVisitor(referenceMessage, string.Empty);
|
builder.HtmlBody = CreateHtmlForReferencingMessage(referenceMessage);
|
||||||
visitor.Visit(referenceMessage);
|
|
||||||
|
|
||||||
builder.HtmlBody = visitor.HtmlBody;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append signatures if needed.
|
// Append signatures if needed.
|
||||||
@@ -695,11 +692,11 @@ namespace Wino.Core.Services
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(builder.HtmlBody))
|
if (string.IsNullOrWhiteSpace(builder.HtmlBody))
|
||||||
{
|
{
|
||||||
builder.HtmlBody = @$"<html><br><br>{signature.HtmlBody}</html>";
|
builder.HtmlBody = $"<br><br><br>{signature.HtmlBody}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builder.HtmlBody += @$"{signature.HtmlBody}";
|
builder.HtmlBody = $"<br><br><br>{signature.HtmlBody}" + builder.HtmlBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -772,6 +769,37 @@ namespace Wino.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
|
// Generates html representation of To/Cc/From/Time and so on from referenced message.
|
||||||
|
string CreateHtmlForReferencingMessage(MimeMessage referenceMessage)
|
||||||
|
{
|
||||||
|
var htmlMimeInfo = string.Empty;
|
||||||
|
// Separation Line
|
||||||
|
htmlMimeInfo += "<br><br><hr style='display:inline-block;width:100%' tabindex='-1'>";
|
||||||
|
|
||||||
|
var visitor = _mimeFileService.CreateHTMLPreviewVisitor(referenceMessage, string.Empty);
|
||||||
|
visitor.Visit(referenceMessage);
|
||||||
|
|
||||||
|
htmlMimeInfo += $"""
|
||||||
|
<div id="divRplyFwdMsg" dir="ltr">
|
||||||
|
<font face="Calibri, sans-serif" style="font-size: 11pt;" color="#000000">
|
||||||
|
<b>From:</b> {ParticipantsToHtml(referenceMessage.From)}<br>
|
||||||
|
<b>Sent:</b> {referenceMessage.Date.ToLocalTime()}<br>
|
||||||
|
<b>To:</b> {ParticipantsToHtml(referenceMessage.To)}<br>
|
||||||
|
{(referenceMessage.Cc.Count > 0 ? $"<b>Cc:</b> {ParticipantsToHtml(referenceMessage.Cc)}<br>" : string.Empty)}
|
||||||
|
<b>Subject:</b> {referenceMessage.Subject}
|
||||||
|
</font>
|
||||||
|
<div> </div>
|
||||||
|
{visitor.HtmlBody}
|
||||||
|
</div>
|
||||||
|
""";
|
||||||
|
|
||||||
|
return htmlMimeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string ParticipantsToHtml(InternetAddressList internetAddresses) =>
|
||||||
|
string.Join("; ", internetAddresses.Mailboxes
|
||||||
|
.Select(x => $"{x.Name ?? Translator.UnknownSender} <<a href=\"mailto:{x.Address ?? Translator.UnknownAddress}\">{x.Address ?? Translator.UnknownAddress}</a>>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId)
|
public async Task<bool> MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId)
|
||||||
|
|||||||
@@ -72,7 +72,10 @@ namespace Wino.Mail.ViewModels
|
|||||||
private bool isDraggingOverComposerGrid;
|
private bool isDraggingOverComposerGrid;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool isDraggingOverDropZone;
|
private bool isDraggingOverFilesDropZone;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool isDraggingOverImagesDropZone;
|
||||||
|
|
||||||
public ObservableCollection<MailAttachmentViewModel> IncludedAttachments { get; set; } = new ObservableCollection<MailAttachmentViewModel>();
|
public ObservableCollection<MailAttachmentViewModel> IncludedAttachments { get; set; } = new ObservableCollection<MailAttachmentViewModel>();
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,9 @@
|
|||||||
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
||||||
</AppBarToggleButton.Icon>
|
</AppBarToggleButton.Icon>
|
||||||
</AppBarToggleButton>
|
</AppBarToggleButton>
|
||||||
|
|
||||||
|
<AppBarSeparator />
|
||||||
|
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="DecreaseIndentButton"
|
x:Name="DecreaseIndentButton"
|
||||||
Width="48"
|
Width="48"
|
||||||
@@ -157,22 +160,14 @@
|
|||||||
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarSeparator />
|
|
||||||
|
|
||||||
<AppBarToggleButton
|
|
||||||
x:Name="DirectionButton"
|
|
||||||
Width="48"
|
|
||||||
Click="DirectionButtonClicked"
|
|
||||||
Label="Direction"
|
|
||||||
ToolTipService.ToolTip="Direction">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource ParagraphPathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
|
|
||||||
<AppBarElementContainer VerticalAlignment="Center">
|
<AppBarElementContainer VerticalAlignment="Center">
|
||||||
<ComboBox x:Name="AlignmentListView" SelectionChanged="AlignmentChanged">
|
<ComboBox
|
||||||
<ComboBoxItem Tag="left">
|
x:Name="AlignmentListView"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
SelectionChanged="AlignmentChanged">
|
||||||
|
<ComboBoxItem IsSelected="True" Tag="left">
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
||||||
@@ -238,43 +233,30 @@
|
|||||||
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarButton
|
|
||||||
x:Name="LinkButton"
|
<AppBarToggleButton
|
||||||
|
x:Name="WebviewToolBarButton"
|
||||||
Width="48"
|
Width="48"
|
||||||
Click="LinkButtonClicked"
|
Click="WebViewToggleButtonClicked"
|
||||||
FrameworkElement.AllowFocusOnInteraction="True"
|
Label="Webview ToolBar"
|
||||||
Label="Add HyperLink"
|
ToolTipService.ToolTip="Webview ToolBar">
|
||||||
ToolTipService.ToolTip="Add HyperLink">
|
<AppBarToggleButton.Icon>
|
||||||
<AppBarButton.Flyout>
|
<PathIcon Data="{StaticResource WebviewToolBarPathIcon}" />
|
||||||
<Flyout x:Name="HyperlinkFlyout">
|
</AppBarToggleButton.Icon>
|
||||||
<StackPanel Width="250" Spacing="6">
|
</AppBarToggleButton>
|
||||||
<TextBox x:Name="HyperlinkTextBox" Header="Text" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="LinkUrlTextBox"
|
|
||||||
Header="Link"
|
|
||||||
PlaceholderText="https://" />
|
|
||||||
<Button
|
|
||||||
x:Name="AddHyperlinkButton"
|
|
||||||
Margin="0,6"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Click="HyperlinkAddClicked"
|
|
||||||
Content="{x:Bind domain:Translator.AddHyperlink}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</AppBarButton.Flyout>
|
|
||||||
<AppBarButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource AddLinkPathIcon}" />
|
|
||||||
</AppBarButton.Icon>
|
|
||||||
</AppBarButton>
|
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
<Grid
|
<Border
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Margin="0,6,0,0"
|
Margin="0,6,0,0"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
||||||
|
BorderThickness="1"
|
||||||
CornerRadius="3">
|
CornerRadius="3">
|
||||||
<Grid Background="White" Visibility="{x:Bind IsComposerDarkMode, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
<Grid CornerRadius="3">
|
||||||
|
<Grid Background="White" Visibility="{x:Bind IsComposerDarkMode, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
||||||
|
|
||||||
<muxc:WebView2 x:Name="Chromium" />
|
<muxc:WebView2 x:Name="Chromium" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Requests;
|
||||||
using Wino.Views.Settings;
|
using Wino.Views.Settings;
|
||||||
|
|
||||||
namespace Wino.Dialogs
|
namespace Wino.Dialogs
|
||||||
@@ -71,9 +72,9 @@ namespace Wino.Dialogs
|
|||||||
|
|
||||||
_getHTMLBodyFunction = new Func<Task<string>>(async () =>
|
_getHTMLBodyFunction = new Func<Task<string>>(async () =>
|
||||||
{
|
{
|
||||||
var quillContent = await InvokeScriptSafeAsync("GetHTMLContent();");
|
var editorContent = await InvokeScriptSafeAsync("GetHTMLContent();");
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<string>(quillContent);
|
return JsonConvert.DeserializeObject<string>(editorContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
var underlyingThemeService = App.Current.Services.GetService<IUnderlyingThemeService>();
|
var underlyingThemeService = App.Current.Services.GetService<IUnderlyingThemeService>();
|
||||||
@@ -121,57 +122,44 @@ namespace Wino.Dialogs
|
|||||||
Hide();
|
Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void HyperlinkAddClicked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
await InvokeScriptSafeAsync($"addHyperlink('{LinkUrlTextBox.Text}')");
|
|
||||||
|
|
||||||
LinkUrlTextBox.Text = string.Empty;
|
|
||||||
HyperlinkFlyout.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void BoldButtonClicked(object sender, RoutedEventArgs e)
|
private async void BoldButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('boldButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('bold')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ItalicButtonClicked(object sender, RoutedEventArgs e)
|
private async void ItalicButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('italicButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('italic')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UnderlineButtonClicked(object sender, RoutedEventArgs e)
|
private async void UnderlineButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('underlineButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('underline')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StrokeButtonClicked(object sender, RoutedEventArgs e)
|
private async void StrokeButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('strikeButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('strikethrough')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void BulletListButtonClicked(object sender, RoutedEventArgs e)
|
private async void BulletListButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('bulletListButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('insertunorderedlist')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OrderedListButtonClicked(object sender, RoutedEventArgs e)
|
private async void OrderedListButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('orderedListButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('insertorderedlist')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void IncreaseIndentClicked(object sender, RoutedEventArgs e)
|
private async void IncreaseIndentClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('increaseIndentButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('indent')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void DecreaseIndentClicked(object sender, RoutedEventArgs e)
|
private async void DecreaseIndentClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('decreaseIndentButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('outdent')");
|
||||||
}
|
|
||||||
|
|
||||||
private async void DirectionButtonClicked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
await InvokeScriptSafeAsync("document.getElementById('directionButton').click();");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AlignmentChanged(object sender, SelectionChangedEventArgs e)
|
private async void AlignmentChanged(object sender, SelectionChangedEventArgs e)
|
||||||
@@ -182,16 +170,16 @@ namespace Wino.Dialogs
|
|||||||
switch (alignment)
|
switch (alignment)
|
||||||
{
|
{
|
||||||
case "left":
|
case "left":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-left').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyleft')");
|
||||||
break;
|
break;
|
||||||
case "center":
|
case "center":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-center').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifycenter')");
|
||||||
break;
|
break;
|
||||||
case "right":
|
case "right":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-right').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyright')");
|
||||||
break;
|
break;
|
||||||
case "justify":
|
case "justify":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-justify').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyfull')");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,19 +206,22 @@ namespace Wino.Dialogs
|
|||||||
{
|
{
|
||||||
return await Chromium.ExecuteScriptAsync(function);
|
return await Chromium.ExecuteScriptAsync(function);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddImageClicked(object sender, RoutedEventArgs e)
|
private async void AddImageClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('addImageButton').click();");
|
await InvokeScriptSafeAsync("imageInput.click();");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FocusEditorAsync()
|
private async Task FocusEditorAsync()
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("quill.focus();");
|
await InvokeScriptSafeAsync("editor.selection.focus();");
|
||||||
|
|
||||||
Chromium.Focus(FocusState.Keyboard);
|
Chromium.Focus(FocusState.Keyboard);
|
||||||
Chromium.Focus(FocusState.Programmatic);
|
Chromium.Focus(FocusState.Programmatic);
|
||||||
@@ -254,12 +245,10 @@ namespace Wino.Dialogs
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LinkButtonClicked(object sender, RoutedEventArgs e)
|
private async void WebViewToggleButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Get selected text from Quill.
|
var enable = WebviewToolBarButton.IsChecked == true ? "true" : "false";
|
||||||
HyperlinkTextBox.Text = await TryGetSelectedTextAsync();
|
await InvokeScriptSafeAsync($"toggleToolbar('{enable}');");
|
||||||
|
|
||||||
HyperlinkFlyout.ShowAt(LinkButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateEditorThemeAsync()
|
private async Task UpdateEditorThemeAsync()
|
||||||
@@ -298,10 +287,10 @@ namespace Wino.Dialogs
|
|||||||
|
|
||||||
private async void ChromiumInitialized(Microsoft.UI.Xaml.Controls.WebView2 sender, Microsoft.UI.Xaml.Controls.CoreWebView2InitializedEventArgs args)
|
private async void ChromiumInitialized(Microsoft.UI.Xaml.Controls.WebView2 sender, Microsoft.UI.Xaml.Controls.CoreWebView2InitializedEventArgs args)
|
||||||
{
|
{
|
||||||
var editorBundlePath = (await _nativeAppService.GetQuillEditorBundlePathAsync()).Replace("full.html", string.Empty);
|
var editorBundlePath = (await _nativeAppService.GetEditorBundlePathAsync()).Replace("editor.html", string.Empty);
|
||||||
|
|
||||||
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.example", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.editor", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
||||||
Chromium.Source = new Uri("https://app.example/full.html");
|
Chromium.Source = new Uri("https://app.editor/editor.html");
|
||||||
|
|
||||||
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
||||||
Chromium.CoreWebView2.DOMContentLoaded += DOMLoaded;
|
Chromium.CoreWebView2.DOMContentLoaded += DOMLoaded;
|
||||||
@@ -320,46 +309,52 @@ namespace Wino.Dialogs
|
|||||||
|
|
||||||
private void ScriptMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
|
private void ScriptMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||||
{
|
{
|
||||||
var change = JsonConvert.DeserializeObject<string>(args.WebMessageAsJson);
|
var change = JsonConvert.DeserializeObject<WebViewMessage>(args.WebMessageAsJson);
|
||||||
|
|
||||||
bool isEnabled = change.EndsWith("ql-active");
|
if (change.type == "bold")
|
||||||
|
|
||||||
if (change.StartsWith("ql-bold"))
|
|
||||||
BoldButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-italic"))
|
|
||||||
ItalicButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-underline"))
|
|
||||||
UnderlineButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-strike"))
|
|
||||||
StrokeButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("orderedListButton"))
|
|
||||||
OrderedListButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("bulletListButton"))
|
|
||||||
BulletListButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-direction"))
|
|
||||||
DirectionButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-align-left"))
|
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
BoldButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 0;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-center"))
|
else if (change.type == "italic")
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
ItalicButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 1;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-right"))
|
else if (change.type == "underline")
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
UnderlineButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 2;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-justify"))
|
else if (change.type == "strikethrough")
|
||||||
{
|
{
|
||||||
|
StrokeButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "ol")
|
||||||
|
{
|
||||||
|
OrderedListButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "ul")
|
||||||
|
{
|
||||||
|
BulletListButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "indent")
|
||||||
|
{
|
||||||
|
IncreaseIndentButton.IsEnabled = change.value == "disabled" ? false : true;
|
||||||
|
}
|
||||||
|
else if (change.type == "outdent")
|
||||||
|
{
|
||||||
|
DecreaseIndentButton.IsEnabled = change.value == "disabled" ? false : true;
|
||||||
|
}
|
||||||
|
else if (change.type == "alignment")
|
||||||
|
{
|
||||||
|
var parsedValue = change.value switch
|
||||||
|
{
|
||||||
|
"jodit-icon_left" => 0,
|
||||||
|
"jodit-icon_center" => 1,
|
||||||
|
"jodit-icon_right" => 2,
|
||||||
|
"jodit-icon_justify" => 3,
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
||||||
AlignmentListView.SelectedIndex = 3;
|
AlignmentListView.SelectedIndex = parsedValue;
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
AlignmentListView.SelectionChanged += AlignmentChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,278 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="language" content="english">
|
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://app.example/katex.min.css" />
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://app.example/monokai-sublime.min.css" />
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://app.example/quill.snow.css" />
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body >
|
|
||||||
/* #standalone-container {
|
|
||||||
margin: 50px auto;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
} */
|
|
||||||
|
|
||||||
#editor-container {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wino-original-message-container {
|
|
||||||
border: solid #636e72;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body bgcolor="white">
|
|
||||||
<div id="standalone-container">
|
|
||||||
<!-- remove display none to enable toolbar -->
|
|
||||||
<div id="toolbar-container" style="display: none;">
|
|
||||||
<span class="ql-formats">
|
|
||||||
<!-- <button id="ql-font-monospace" class="ql-font" value="monospace" />
|
|
||||||
<button id="ql-font-serif" class="ql-font" value="serif" />
|
|
||||||
<button id="ql-font-sans-serif" class="ql-font" /> -->
|
|
||||||
<select class="ql-font"></select>
|
|
||||||
<select class="ql-size"></select>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="boldButton" class="ql-bold"></button>
|
|
||||||
<button id="italicButton" class="ql-italic"></button>
|
|
||||||
<button id="underlineButton" class="ql-underline"></button>
|
|
||||||
<button id="strikeButton" class="ql-strike"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<select class="ql-color"></select>
|
|
||||||
<select class="ql-background"></select>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-script" value="sub"></button>
|
|
||||||
<button class="ql-script" value="super"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-header" value="1"></button>
|
|
||||||
<button class="ql-header" value="2"></button>
|
|
||||||
<button class="ql-blockquote"></button>
|
|
||||||
<button class="ql-code-block"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="orderedListButton" class="ql-list" value="ordered"></button>
|
|
||||||
<button id="bulletListButton" class="ql-list" value="bullet"></button>
|
|
||||||
<button id="decreaseIndentButton" class="ql-indent" value="-1"></button>
|
|
||||||
<button id="increaseIndentButton" class="ql-indent" value="+1"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="directionButton" class="ql-direction" value="rtl"></button>
|
|
||||||
<button id="ql-align-left" class="ql-align" value=""></button>
|
|
||||||
<button id="ql-align-center" class="ql-align" value="center"></button>
|
|
||||||
<button id="ql-align-right" class="ql-align" value="right"></button>
|
|
||||||
<button id="ql-align-justify" class="ql-align" value="justify"></button>
|
|
||||||
<!--<select id="alignmentButton" class="ql-align"></select>-->
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-link"></button>
|
|
||||||
<button id=addImageButton class="ql-image"></button>
|
|
||||||
<button class="ql-video"></button>
|
|
||||||
<button class="ql-formula"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-clean"></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="editor-container" style="background-color: white;">
|
|
||||||
<br><br>Sent from <a href="https://github.com/bkaankose/Wino-Mail/">Wino Mail</a> for Windows
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div id="mail-container-parent" hidden="true" style="border: solid #636e72; padding: 10px; margin-top: 5px; margin-right: 16px; margin-bottom: 5px; margin-left: 5px;">
|
|
||||||
<center>
|
|
||||||
Original message<br>
|
|
||||||
</center>
|
|
||||||
|
|
||||||
<div id="mail-container" style="margin-top: 5px;">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<script src="https://app.example/katex.min.js"></script>
|
|
||||||
|
|
||||||
<script src="https://app.example/highlight.min.js"></script>
|
|
||||||
|
|
||||||
<!-- <script src="../quill.min.js"></script>
|
|
||||||
<script src="../image-resize.min.js"></script> -->
|
|
||||||
|
|
||||||
<script src="https://app.example/quill.min.js"></script>
|
|
||||||
<script src="https://app.example/image-resize.min.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// configure Quill to use inline styles so the email's format properly
|
|
||||||
var resizer = Quill.import('modules/imageResize');
|
|
||||||
Quill.register(resizer, true);
|
|
||||||
|
|
||||||
var DirectionAttribute = Quill.import('attributors/attribute/direction');
|
|
||||||
Quill.register(DirectionAttribute, true);
|
|
||||||
|
|
||||||
var AlignClass = Quill.import('attributors/class/align');
|
|
||||||
Quill.register(AlignClass, true);
|
|
||||||
|
|
||||||
var BackgroundClass = Quill.import('attributors/class/background');
|
|
||||||
Quill.register(BackgroundClass, true);
|
|
||||||
|
|
||||||
var ColorClass = Quill.import('attributors/class/color');
|
|
||||||
Quill.register(ColorClass, true);
|
|
||||||
|
|
||||||
var DirectionClass = Quill.import('attributors/class/direction');
|
|
||||||
Quill.register(DirectionClass, true);
|
|
||||||
|
|
||||||
var FontClass = Quill.import('attributors/class/font');
|
|
||||||
Quill.register(FontClass, true);
|
|
||||||
|
|
||||||
var SizeClass = Quill.import('attributors/class/size');
|
|
||||||
Quill.register(SizeClass, true);
|
|
||||||
|
|
||||||
var AlignStyle = Quill.import('attributors/style/align');
|
|
||||||
Quill.register(AlignStyle, true);
|
|
||||||
|
|
||||||
var BackgroundStyle = Quill.import('attributors/style/background');
|
|
||||||
Quill.register(BackgroundStyle, true);
|
|
||||||
|
|
||||||
var ColorStyle = Quill.import('attributors/style/color');
|
|
||||||
Quill.register(ColorStyle, true);
|
|
||||||
|
|
||||||
var DirectionStyle = Quill.import('attributors/style/direction');
|
|
||||||
Quill.register(DirectionStyle, true);
|
|
||||||
|
|
||||||
var FontStyle = Quill.import('attributors/style/font');
|
|
||||||
Quill.register(FontStyle, true);
|
|
||||||
|
|
||||||
var SizeStyle = Quill.import('attributors/style/size');
|
|
||||||
Quill.register(SizeStyle, true);
|
|
||||||
|
|
||||||
var quill = new Quill('#editor-container', {
|
|
||||||
modules: {
|
|
||||||
toolbar: '#toolbar-container',
|
|
||||||
imageResize: {}
|
|
||||||
},
|
|
||||||
placeholder: '',
|
|
||||||
theme: 'snow'
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var boldButton = document.getElementById('boldButton');
|
|
||||||
var italicButton = document.getElementById('italicButton');
|
|
||||||
var underlineButton = document.getElementById('underlineButton');
|
|
||||||
var strikeButton = document.getElementById('strikeButton');
|
|
||||||
|
|
||||||
var orderedListButton = document.getElementById('orderedListButton');
|
|
||||||
var bulletListButton = document.getElementById('bulletListButton');
|
|
||||||
|
|
||||||
var directionButton = document.getElementById('directionButton');
|
|
||||||
|
|
||||||
var alignLeftButton = document.getElementById('ql-align-left');
|
|
||||||
var alignCenterButton = document.getElementById('ql-align-center');
|
|
||||||
var alignRightButton = document.getElementById('ql-align-right');
|
|
||||||
var alignJustifyButton = document.getElementById('ql-align-justify');
|
|
||||||
|
|
||||||
// The mutation observer
|
|
||||||
var boldObserver = new MutationObserver(function() { classChanged(boldButton); });
|
|
||||||
boldObserver.observe(boldButton, { attributes: true, attributeFilter: ["class"]});
|
|
||||||
|
|
||||||
var italicObserver = new MutationObserver(function() { classChanged(italicButton); });
|
|
||||||
italicObserver.observe(italicButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var underlineObserver = new MutationObserver(function () { classChanged(underlineButton); });
|
|
||||||
underlineObserver.observe(underlineButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var strikeObserver = new MutationObserver(function () { classChanged(strikeButton); });
|
|
||||||
strikeObserver.observe(strikeButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var orderedListObserver = new MutationObserver(function () { classAndValueChanged(orderedListButton); });
|
|
||||||
orderedListObserver.observe(orderedListButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var bulletListObserver = new MutationObserver(function () { classAndValueChanged(bulletListButton); });
|
|
||||||
bulletListObserver.observe(bulletListButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var directionObserver = new MutationObserver(function () { classChanged(directionButton); });
|
|
||||||
directionObserver.observe(directionButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserver = new MutationObserver(function () { alignmentDataValueChanged(alignLeftButton); });
|
|
||||||
alignmentObserver.observe(alignLeftButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverCenter = new MutationObserver(function () { alignmentDataValueChanged(alignCenterButton); });
|
|
||||||
alignmentObserverCenter.observe(alignCenterButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverRight = new MutationObserver(function () { alignmentDataValueChanged(alignRightButton); });
|
|
||||||
alignmentObserverRight.observe(alignRightButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverJustify = new MutationObserver(function () { alignmentDataValueChanged(alignJustifyButton); });
|
|
||||||
alignmentObserverJustify.observe(alignJustifyButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
function classChanged(button) {
|
|
||||||
window.external.notify(`${button.className}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function classAndValueChanged(button) {
|
|
||||||
window.external.notify(`${button.id} ${button.className}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function alignmentDataValueChanged(button) {
|
|
||||||
if (button.className.endsWith('ql-active'))
|
|
||||||
window.external.notify(`${button.id}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function RenderHTML(htmlString) {
|
|
||||||
quill.root.innerHTML = htmlString;
|
|
||||||
// quill.clipboard.dangerouslyPasteHTML(htmlString);
|
|
||||||
// const delta = quill.clipboard.convert(htmlString)
|
|
||||||
|
|
||||||
// quill.setContents(delta, 'silent')
|
|
||||||
|
|
||||||
// document.getElementById('mail-container-parent').hidden = false;
|
|
||||||
// document.getElementById('editor-container').innerHTML = htmlString;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function ShowToolbar() {
|
|
||||||
// document.getElementById('editor-container').style.display = 'block';
|
|
||||||
// quill.focus();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function HideToolbar() {
|
|
||||||
// document.getElementById('editor-container').style.display = 'none';
|
|
||||||
// }
|
|
||||||
|
|
||||||
function getSelectedText() {
|
|
||||||
var range = quill.getSelection();
|
|
||||||
if (range)
|
|
||||||
{
|
|
||||||
if (range.length == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return quill.getText(range.index, range.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addHyperlink(url)
|
|
||||||
{
|
|
||||||
var range = quill.getSelection();
|
|
||||||
|
|
||||||
if (range)
|
|
||||||
{
|
|
||||||
quill.formatText(range.index, range.length, 'link', url);
|
|
||||||
quill.setSelection(0,0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="language" content="english">
|
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
<link rel="stylesheet" href="https://app.example/katex.min.css" />
|
|
||||||
<link rel="stylesheet" href="https://app.example/monokai-sublime.min.css" />
|
|
||||||
<link rel="stylesheet" href="https://app.example/quill.snow.css" />
|
|
||||||
<link rel="stylesheet" href="https://app.example/global.css" />
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body >
|
|
||||||
/* #standalone-container {
|
|
||||||
margin: 50px auto;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
} */
|
|
||||||
#editor-container {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wino-original-message-container {
|
|
||||||
border: solid #636e72;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<meta name="color-scheme" content="dark light">
|
|
||||||
<div id="standalone-container">
|
|
||||||
<!-- remove display none to enable toolbar -->
|
|
||||||
<div id="toolbar-container" style="display: none;">
|
|
||||||
<span class="ql-formats">
|
|
||||||
<!-- <button id="ql-font-monospace" class="ql-font" value="monospace" />
|
|
||||||
<button id="ql-font-serif" class="ql-font" value="serif" />
|
|
||||||
<button id="ql-font-sans-serif" class="ql-font" /> -->
|
|
||||||
<select class="ql-font"></select>
|
|
||||||
<select class="ql-size"></select>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="boldButton" class="ql-bold"></button>
|
|
||||||
<button id="italicButton" class="ql-italic"></button>
|
|
||||||
<button id="underlineButton" class="ql-underline"></button>
|
|
||||||
<button id="strikeButton" class="ql-strike"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<select class="ql-color"></select>
|
|
||||||
<select class="ql-background"></select>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-script" value="sub"></button>
|
|
||||||
<button class="ql-script" value="super"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-header" value="1"></button>
|
|
||||||
<button class="ql-header" value="2"></button>
|
|
||||||
<button class="ql-blockquote"></button>
|
|
||||||
<button class="ql-code-block"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="orderedListButton" class="ql-list" value="ordered"></button>
|
|
||||||
<button id="bulletListButton" class="ql-list" value="bullet"></button>
|
|
||||||
<button id="decreaseIndentButton" class="ql-indent" value="-1"></button>
|
|
||||||
<button id="increaseIndentButton" class="ql-indent" value="+1"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button id="directionButton" class="ql-direction" value="rtl"></button>
|
|
||||||
<button id="ql-align-left" class="ql-align" value=""></button>
|
|
||||||
<button id="ql-align-center" class="ql-align" value="center"></button>
|
|
||||||
<button id="ql-align-right" class="ql-align" value="right"></button>
|
|
||||||
<button id="ql-align-justify" class="ql-align" value="justify"></button>
|
|
||||||
<!--<select id="alignmentButton" class="ql-align"></select>-->
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-link"></button>
|
|
||||||
<button id=addImageButton class="ql-image"></button>
|
|
||||||
<button class="ql-video"></button>
|
|
||||||
<button class="ql-formula"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-clean"></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--style="background-color: white;"-->
|
|
||||||
<div id="editor-container">
|
|
||||||
<!--<br><br>Sent from <a href="https://github.com/bkaankose/Wino-Mail/">Wino Mail</a> for Windows-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div id="mail-container-parent" hidden="true" style="border: solid #636e72; padding: 10px; margin-top: 5px; margin-right: 16px; margin-bottom: 5px; margin-left: 5px;">
|
|
||||||
<center>
|
|
||||||
Original message<br>
|
|
||||||
</center>
|
|
||||||
|
|
||||||
<div id="mail-container" style="margin-top: 5px;">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<script src="https://app.example/katex.min.js"></script>
|
|
||||||
|
|
||||||
<script src="https://app.example/highlight.min.js"></script>
|
|
||||||
|
|
||||||
<!-- <script src="../quill.min.js"></script>
|
|
||||||
<script src="../image-resize.min.js"></script> -->
|
|
||||||
|
|
||||||
<script src="https://app.example/quill.min.js"></script>
|
|
||||||
<script src="https://app.example/image-resize.min.js"></script>
|
|
||||||
<script src="https://app.example/darkreader.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// configure Quill to use inline styles so the email's format properly
|
|
||||||
var resizer = Quill.import('modules/imageResize');
|
|
||||||
Quill.register(resizer, true);
|
|
||||||
|
|
||||||
var DirectionAttribute = Quill.import('attributors/attribute/direction');
|
|
||||||
Quill.register(DirectionAttribute, true);
|
|
||||||
|
|
||||||
var AlignClass = Quill.import('attributors/class/align');
|
|
||||||
Quill.register(AlignClass, true);
|
|
||||||
|
|
||||||
var BackgroundClass = Quill.import('attributors/class/background');
|
|
||||||
Quill.register(BackgroundClass, true);
|
|
||||||
|
|
||||||
var ColorClass = Quill.import('attributors/class/color');
|
|
||||||
Quill.register(ColorClass, true);
|
|
||||||
|
|
||||||
var DirectionClass = Quill.import('attributors/class/direction');
|
|
||||||
Quill.register(DirectionClass, true);
|
|
||||||
|
|
||||||
var FontClass = Quill.import('attributors/class/font');
|
|
||||||
Quill.register(FontClass, true);
|
|
||||||
|
|
||||||
var SizeClass = Quill.import('attributors/class/size');
|
|
||||||
Quill.register(SizeClass, true);
|
|
||||||
|
|
||||||
var AlignStyle = Quill.import('attributors/style/align');
|
|
||||||
Quill.register(AlignStyle, true);
|
|
||||||
|
|
||||||
var BackgroundStyle = Quill.import('attributors/style/background');
|
|
||||||
Quill.register(BackgroundStyle, true);
|
|
||||||
|
|
||||||
var ColorStyle = Quill.import('attributors/style/color');
|
|
||||||
Quill.register(ColorStyle, true);
|
|
||||||
|
|
||||||
var DirectionStyle = Quill.import('attributors/style/direction');
|
|
||||||
Quill.register(DirectionStyle, true);
|
|
||||||
|
|
||||||
var FontStyle = Quill.import('attributors/style/font');
|
|
||||||
Quill.register(FontStyle, true);
|
|
||||||
|
|
||||||
var SizeStyle = Quill.import('attributors/style/size');
|
|
||||||
Quill.register(SizeStyle, true);
|
|
||||||
|
|
||||||
var quill = new Quill('#editor-container', {
|
|
||||||
modules: {
|
|
||||||
toolbar: '#toolbar-container',
|
|
||||||
imageResize: {}
|
|
||||||
},
|
|
||||||
placeholder: '',
|
|
||||||
theme: 'snow'
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var boldButton = document.getElementById('boldButton');
|
|
||||||
var italicButton = document.getElementById('italicButton');
|
|
||||||
var underlineButton = document.getElementById('underlineButton');
|
|
||||||
var strikeButton = document.getElementById('strikeButton');
|
|
||||||
|
|
||||||
var orderedListButton = document.getElementById('orderedListButton');
|
|
||||||
var bulletListButton = document.getElementById('bulletListButton');
|
|
||||||
|
|
||||||
var directionButton = document.getElementById('directionButton');
|
|
||||||
|
|
||||||
var alignLeftButton = document.getElementById('ql-align-left');
|
|
||||||
var alignCenterButton = document.getElementById('ql-align-center');
|
|
||||||
var alignRightButton = document.getElementById('ql-align-right');
|
|
||||||
var alignJustifyButton = document.getElementById('ql-align-justify');
|
|
||||||
|
|
||||||
// The mutation observer
|
|
||||||
var boldObserver = new MutationObserver(function () { classChanged(boldButton); });
|
|
||||||
boldObserver.observe(boldButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var italicObserver = new MutationObserver(function () { classChanged(italicButton); });
|
|
||||||
italicObserver.observe(italicButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var underlineObserver = new MutationObserver(function () { classChanged(underlineButton); });
|
|
||||||
underlineObserver.observe(underlineButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var strikeObserver = new MutationObserver(function () { classChanged(strikeButton); });
|
|
||||||
strikeObserver.observe(strikeButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var orderedListObserver = new MutationObserver(function () { classAndValueChanged(orderedListButton); });
|
|
||||||
orderedListObserver.observe(orderedListButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var bulletListObserver = new MutationObserver(function () { classAndValueChanged(bulletListButton); });
|
|
||||||
bulletListObserver.observe(bulletListButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var directionObserver = new MutationObserver(function () { classChanged(directionButton); });
|
|
||||||
directionObserver.observe(directionButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserver = new MutationObserver(function () { alignmentDataValueChanged(alignLeftButton); });
|
|
||||||
alignmentObserver.observe(alignLeftButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverCenter = new MutationObserver(function () { alignmentDataValueChanged(alignCenterButton); });
|
|
||||||
alignmentObserverCenter.observe(alignCenterButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverRight = new MutationObserver(function () { alignmentDataValueChanged(alignRightButton); });
|
|
||||||
alignmentObserverRight.observe(alignRightButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
var alignmentObserverJustify = new MutationObserver(function () { alignmentDataValueChanged(alignJustifyButton); });
|
|
||||||
alignmentObserverJustify.observe(alignJustifyButton, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
function classChanged(button) {
|
|
||||||
window.chrome.webview.postMessage(`${button.className}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function classAndValueChanged(button) {
|
|
||||||
window.chrome.webview.postMessage(`${button.id} ${button.className}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function alignmentDataValueChanged(button) {
|
|
||||||
if (button.className.endsWith('ql-active'))
|
|
||||||
window.chrome.webview.postMessage(`${button.id}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function RenderHTML(htmlString) {
|
|
||||||
const delta = quill.clipboard.convert(htmlString)
|
|
||||||
|
|
||||||
quill.setContents(delta, 'silent')
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetHTMLContent() {
|
|
||||||
return quill.root.innerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetTextContent() {
|
|
||||||
return quill.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetLightEditor(){
|
|
||||||
DarkReader.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetDarkEditor(){
|
|
||||||
DarkReader.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
// function ShowToolbar() {
|
|
||||||
// document.getElementById('editor-container').style.display = 'block';
|
|
||||||
// quill.focus();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function HideToolbar() {
|
|
||||||
// document.getElementById('editor-container').style.display = 'none';
|
|
||||||
// }
|
|
||||||
|
|
||||||
function getSelectedText() {
|
|
||||||
var range = quill.getSelection();
|
|
||||||
if (range) {
|
|
||||||
if (range.length == 0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return quill.getText(range.index, range.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addHyperlink(url) {
|
|
||||||
var range = quill.getSelection();
|
|
||||||
|
|
||||||
if (range) {
|
|
||||||
quill.formatText(range.index, range.length, 'link', url);
|
|
||||||
quill.setSelection(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
3
Wino.Mail/JS/Quill/highlight.min.js
vendored
3
Wino.Mail/JS/Quill/highlight.min.js
vendored
File diff suppressed because one or more lines are too long
1
Wino.Mail/JS/Quill/image-resize.min.js
vendored
1
Wino.Mail/JS/Quill/image-resize.min.js
vendored
File diff suppressed because one or more lines are too long
1
Wino.Mail/JS/Quill/katex.min.css
vendored
1
Wino.Mail/JS/Quill/katex.min.css
vendored
File diff suppressed because one or more lines are too long
4
Wino.Mail/JS/Quill/katex.min.js
vendored
4
Wino.Mail/JS/Quill/katex.min.js
vendored
File diff suppressed because one or more lines are too long
1
Wino.Mail/JS/Quill/monokai-sublime.min.css
vendored
1
Wino.Mail/JS/Quill/monokai-sublime.min.css
vendored
@@ -1 +0,0 @@
|
|||||||
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#23241f}.hljs,.hljs-tag,.hljs-subst{color:#f8f8f2}.hljs-strong,.hljs-emphasis{color:#a8a8a2}.hljs-bullet,.hljs-quote,.hljs-number,.hljs-regexp,.hljs-literal,.hljs-link{color:#ae81ff}.hljs-code,.hljs-title,.hljs-section,.hljs-selector-class{color:#a6e22e}.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-name,.hljs-attr{color:#f92672}.hljs-symbol,.hljs-attribute{color:#66d9ef}.hljs-params,.hljs-class .hljs-title{color:#f8f8f2}.hljs-string,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-selector-id,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-addition,.hljs-variable,.hljs-template-variable{color:#e6db74}.hljs-comment,.hljs-deletion,.hljs-meta{color:#75715e}
|
|
||||||
@@ -1,397 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Quill Editor v1.3.6
|
|
||||||
* https://quilljs.com/
|
|
||||||
* Copyright (c) 2014, Jason Chen
|
|
||||||
* Copyright (c) 2013, salesforce.com
|
|
||||||
*/
|
|
||||||
.ql-container {
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.ql-container.ql-disabled .ql-tooltip {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ql-clipboard {
|
|
||||||
left: -100000px;
|
|
||||||
height: 1px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
}
|
|
||||||
.ql-clipboard p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.ql-editor {
|
|
||||||
box-sizing: border-box;
|
|
||||||
line-height: 1.42;
|
|
||||||
height: 100%;
|
|
||||||
outline: none;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 12px 15px;
|
|
||||||
tab-size: 4;
|
|
||||||
-moz-tab-size: 4;
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.ql-editor > * {
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
.ql-editor p,
|
|
||||||
.ql-editor ol,
|
|
||||||
.ql-editor ul,
|
|
||||||
.ql-editor pre,
|
|
||||||
.ql-editor blockquote,
|
|
||||||
.ql-editor h1,
|
|
||||||
.ql-editor h2,
|
|
||||||
.ql-editor h3,
|
|
||||||
.ql-editor h4,
|
|
||||||
.ql-editor h5,
|
|
||||||
.ql-editor h6 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol,
|
|
||||||
.ql-editor ul {
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol > li,
|
|
||||||
.ql-editor ul > li {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
.ql-editor ul > li::before {
|
|
||||||
content: '\2022';
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true],
|
|
||||||
.ql-editor ul[data-checked=false] {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li *,
|
|
||||||
.ql-editor ul[data-checked=false] > li * {
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li::before,
|
|
||||||
.ql-editor ul[data-checked=false] > li::before {
|
|
||||||
color: #777;
|
|
||||||
cursor: pointer;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li::before {
|
|
||||||
content: '\2611';
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=false] > li::before {
|
|
||||||
content: '\2610';
|
|
||||||
}
|
|
||||||
.ql-editor li::before {
|
|
||||||
display: inline-block;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 1.2em;
|
|
||||||
}
|
|
||||||
.ql-editor li:not(.ql-direction-rtl)::before {
|
|
||||||
margin-left: -1.5em;
|
|
||||||
margin-right: 0.3em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-direction-rtl::before {
|
|
||||||
margin-left: 0.3em;
|
|
||||||
margin-right: -1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li:not(.ql-direction-rtl),
|
|
||||||
.ql-editor ul li:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-direction-rtl,
|
|
||||||
.ql-editor ul li.ql-direction-rtl {
|
|
||||||
padding-right: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li {
|
|
||||||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
counter-increment: list-0;
|
|
||||||
}
|
|
||||||
.ql-editor ol li:before {
|
|
||||||
content: counter(list-0, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1 {
|
|
||||||
counter-increment: list-1;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1:before {
|
|
||||||
content: counter(list-1, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1 {
|
|
||||||
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2 {
|
|
||||||
counter-increment: list-2;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2:before {
|
|
||||||
content: counter(list-2, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2 {
|
|
||||||
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3 {
|
|
||||||
counter-increment: list-3;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3:before {
|
|
||||||
content: counter(list-3, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3 {
|
|
||||||
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4 {
|
|
||||||
counter-increment: list-4;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4:before {
|
|
||||||
content: counter(list-4, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4 {
|
|
||||||
counter-reset: list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5 {
|
|
||||||
counter-increment: list-5;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5:before {
|
|
||||||
content: counter(list-5, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5 {
|
|
||||||
counter-reset: list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6 {
|
|
||||||
counter-increment: list-6;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6:before {
|
|
||||||
content: counter(list-6, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6 {
|
|
||||||
counter-reset: list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7 {
|
|
||||||
counter-increment: list-7;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7:before {
|
|
||||||
content: counter(list-7, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7 {
|
|
||||||
counter-reset: list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8 {
|
|
||||||
counter-increment: list-8;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8:before {
|
|
||||||
content: counter(list-8, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8 {
|
|
||||||
counter-reset: list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-9 {
|
|
||||||
counter-increment: list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-9:before {
|
|
||||||
content: counter(list-9, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-1:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 3em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-1:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 4.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 3em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 4.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-2:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 6em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-2:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 7.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 6em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 7.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-3:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 9em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-3:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 10.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 9em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 10.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-4:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 12em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-4:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 13.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 12em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 13.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-5:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 15em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-5:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 16.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 15em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 16.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-6:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 18em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-6:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 19.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 18em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 19.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-7:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 21em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-7:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 22.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 21em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 22.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-8:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 24em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-8:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 25.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 24em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 25.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-9:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 27em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-9:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 28.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 27em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 28.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video.ql-align-center {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video.ql-align-right {
|
|
||||||
margin: 0 0 0 auto;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-black {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-red {
|
|
||||||
background-color: #e60000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-orange {
|
|
||||||
background-color: #f90;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-yellow {
|
|
||||||
background-color: #ff0;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-green {
|
|
||||||
background-color: #008a00;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-blue {
|
|
||||||
background-color: #06c;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-purple {
|
|
||||||
background-color: #93f;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-white {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-red {
|
|
||||||
color: #e60000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-orange {
|
|
||||||
color: #f90;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-yellow {
|
|
||||||
color: #ff0;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-green {
|
|
||||||
color: #008a00;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-blue {
|
|
||||||
color: #06c;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-purple {
|
|
||||||
color: #93f;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-font-serif {
|
|
||||||
font-family: Georgia, Times New Roman, serif;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-font-monospace {
|
|
||||||
font-family: Monaco, Courier New, monospace;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-small {
|
|
||||||
font-size: 0.75em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-large {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-huge {
|
|
||||||
font-size: 2.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-direction-rtl {
|
|
||||||
direction: rtl;
|
|
||||||
text-align: inherit;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-justify {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.ql-editor.ql-blank::before {
|
|
||||||
color: rgba(0,0,0,0.6);
|
|
||||||
content: attr(data-placeholder);
|
|
||||||
font-style: italic;
|
|
||||||
left: 15px;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
8
Wino.Mail/JS/Quill/quill.min.js
vendored
8
Wino.Mail/JS/Quill/quill.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,947 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Quill Editor v1.3.6
|
|
||||||
* https://quilljs.com/
|
|
||||||
* Copyright (c) 2014, Jason Chen
|
|
||||||
* Copyright (c) 2013, salesforce.com
|
|
||||||
*/
|
|
||||||
.ql-container {
|
|
||||||
|
|
||||||
font-family: Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
height: 1000px !important;
|
|
||||||
resize: vertical;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
.ql-container.ql-disabled .ql-tooltip {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ql-clipboard {
|
|
||||||
left: -100000px;
|
|
||||||
height: 1px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
}
|
|
||||||
.ql-clipboard p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.ql-editor {
|
|
||||||
line-height: 1.40;
|
|
||||||
height: 100%;
|
|
||||||
outline: none;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 4px 4px;
|
|
||||||
tab-size: 4;
|
|
||||||
-moz-tab-size: 4;
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reply Border */
|
|
||||||
.ql-container.ql-snow {
|
|
||||||
/* border: solid #636e72; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.ql-editor > * {
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
.ql-editor p,
|
|
||||||
.ql-editor ol,
|
|
||||||
.ql-editor ul,
|
|
||||||
.ql-editor pre,
|
|
||||||
.ql-editor blockquote,
|
|
||||||
.ql-editor h1,
|
|
||||||
.ql-editor h2,
|
|
||||||
.ql-editor h3,
|
|
||||||
.ql-editor h4,
|
|
||||||
.ql-editor h5,
|
|
||||||
.ql-editor h6 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol,
|
|
||||||
.ql-editor ul {
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol > li,
|
|
||||||
.ql-editor ul > li {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
.ql-editor ul > li::before {
|
|
||||||
content: '\2022';
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true],
|
|
||||||
.ql-editor ul[data-checked=false] {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li *,
|
|
||||||
.ql-editor ul[data-checked=false] > li * {
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li::before,
|
|
||||||
.ql-editor ul[data-checked=false] > li::before {
|
|
||||||
color: #777;
|
|
||||||
cursor: pointer;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=true] > li::before {
|
|
||||||
content: '\2611';
|
|
||||||
}
|
|
||||||
.ql-editor ul[data-checked=false] > li::before {
|
|
||||||
content: '\2610';
|
|
||||||
}
|
|
||||||
.ql-editor li::before {
|
|
||||||
display: inline-block;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 1.2em;
|
|
||||||
}
|
|
||||||
.ql-editor li:not(.ql-direction-rtl)::before {
|
|
||||||
margin-left: -1.5em;
|
|
||||||
margin-right: 0.3em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-direction-rtl::before {
|
|
||||||
margin-left: 0.3em;
|
|
||||||
margin-right: -1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li:not(.ql-direction-rtl),
|
|
||||||
.ql-editor ul li:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-direction-rtl,
|
|
||||||
.ql-editor ul li.ql-direction-rtl {
|
|
||||||
padding-right: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor ol li {
|
|
||||||
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
counter-increment: list-0;
|
|
||||||
}
|
|
||||||
.ql-editor ol li:before {
|
|
||||||
content: counter(list-0, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1 {
|
|
||||||
counter-increment: list-1;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1:before {
|
|
||||||
content: counter(list-1, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-1 {
|
|
||||||
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2 {
|
|
||||||
counter-increment: list-2;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2:before {
|
|
||||||
content: counter(list-2, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-2 {
|
|
||||||
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3 {
|
|
||||||
counter-increment: list-3;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3:before {
|
|
||||||
content: counter(list-3, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-3 {
|
|
||||||
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4 {
|
|
||||||
counter-increment: list-4;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4:before {
|
|
||||||
content: counter(list-4, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-4 {
|
|
||||||
counter-reset: list-5 list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5 {
|
|
||||||
counter-increment: list-5;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5:before {
|
|
||||||
content: counter(list-5, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-5 {
|
|
||||||
counter-reset: list-6 list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6 {
|
|
||||||
counter-increment: list-6;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6:before {
|
|
||||||
content: counter(list-6, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-6 {
|
|
||||||
counter-reset: list-7 list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7 {
|
|
||||||
counter-increment: list-7;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7:before {
|
|
||||||
content: counter(list-7, lower-alpha) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-7 {
|
|
||||||
counter-reset: list-8 list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8 {
|
|
||||||
counter-increment: list-8;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8:before {
|
|
||||||
content: counter(list-8, lower-roman) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-8 {
|
|
||||||
counter-reset: list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-9 {
|
|
||||||
counter-increment: list-9;
|
|
||||||
}
|
|
||||||
.ql-editor ol li.ql-indent-9:before {
|
|
||||||
content: counter(list-9, decimal) '. ';
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-1:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 3em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-1:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 4.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 3em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 4.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-2:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 6em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-2:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 7.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 6em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 7.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-3:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 9em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-3:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 10.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 9em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 10.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-4:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 12em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-4:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 13.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 12em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 13.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-5:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 15em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-5:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 16.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 15em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 16.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-6:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 18em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-6:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 19.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 18em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 19.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-7:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 21em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-7:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 22.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 21em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 22.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-8:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 24em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-8:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 25.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 24em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 25.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-9:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 27em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-9:not(.ql-direction-rtl) {
|
|
||||||
padding-left: 28.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 27em;
|
|
||||||
}
|
|
||||||
.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right {
|
|
||||||
padding-right: 28.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video.ql-align-center {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-video.ql-align-right {
|
|
||||||
margin: 0 0 0 auto;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-black {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-red {
|
|
||||||
background-color: #e60000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-orange {
|
|
||||||
background-color: #f90;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-yellow {
|
|
||||||
background-color: #ff0;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-green {
|
|
||||||
background-color: #008a00;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-blue {
|
|
||||||
background-color: #06c;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-bg-purple {
|
|
||||||
background-color: #93f;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-white {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-red {
|
|
||||||
color: #e60000;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-orange {
|
|
||||||
color: #f90;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-yellow {
|
|
||||||
color: #ff0;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-green {
|
|
||||||
color: #008a00;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-blue {
|
|
||||||
color: #06c;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-color-purple {
|
|
||||||
color: #93f;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-font-serif {
|
|
||||||
font-family: Georgia, Times New Roman, serif;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-font-monospace {
|
|
||||||
font-family: Monaco, Courier New, monospace;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-small {
|
|
||||||
font-size: 0.75em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-large {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-size-huge {
|
|
||||||
font-size: 2.5em;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-direction-rtl {
|
|
||||||
direction: rtl;
|
|
||||||
text-align: inherit;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-justify {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
.ql-editor .ql-align-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.ql-editor.ql-blank::before {
|
|
||||||
color: rgba(0,0,0,0.6);
|
|
||||||
content: attr(data-placeholder);
|
|
||||||
left: 4px;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 4px;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar:after,
|
|
||||||
.ql-snow .ql-toolbar:after {
|
|
||||||
clear: both;
|
|
||||||
content: '';
|
|
||||||
display: table;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button,
|
|
||||||
.ql-snow .ql-toolbar button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
float: left;
|
|
||||||
height: 24px;
|
|
||||||
padding: 3px 5px;
|
|
||||||
width: 28px;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button svg,
|
|
||||||
.ql-snow .ql-toolbar button svg {
|
|
||||||
float: left;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:active:hover,
|
|
||||||
.ql-snow .ql-toolbar button:active:hover {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar input.ql-image[type=file],
|
|
||||||
.ql-snow .ql-toolbar input.ql-image[type=file] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:hover,
|
|
||||||
.ql-snow .ql-toolbar button:hover,
|
|
||||||
.ql-snow.ql-toolbar button:focus,
|
|
||||||
.ql-snow .ql-toolbar button:focus,
|
|
||||||
.ql-snow.ql-toolbar button.ql-active,
|
|
||||||
.ql-snow .ql-toolbar button.ql-active,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label:hover,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label:hover,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label.ql-active,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label.ql-active,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item:hover,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item:hover,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item.ql-selected,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item.ql-selected {
|
|
||||||
color: #06c;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:hover .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:hover .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button:focus .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:focus .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button.ql-active .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button.ql-active .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill {
|
|
||||||
fill: #06c;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:hover .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar button:hover .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar button:focus .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar button:focus .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar button.ql-active .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar button.ql-active .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar button:hover .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar button:hover .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar button:focus .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar button:focus .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter,
|
|
||||||
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter {
|
|
||||||
stroke: #06c;
|
|
||||||
}
|
|
||||||
@media (pointer: coarse) {
|
|
||||||
.ql-snow.ql-toolbar button:hover:not(.ql-active),
|
|
||||||
.ql-snow .ql-toolbar button:hover:not(.ql-active) {
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-fill,
|
|
||||||
.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill,
|
|
||||||
.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill {
|
|
||||||
fill: #444;
|
|
||||||
}
|
|
||||||
.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke,
|
|
||||||
.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke,
|
|
||||||
.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter,
|
|
||||||
.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter {
|
|
||||||
stroke: #444;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ql-snow {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.ql-snow * {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-out-bottom,
|
|
||||||
.ql-snow .ql-out-top {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip a {
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip.ql-flip {
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
.ql-snow .ql-formats {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-formats:after {
|
|
||||||
clear: both;
|
|
||||||
content: '';
|
|
||||||
display: table;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-stroke {
|
|
||||||
fill: none;
|
|
||||||
stroke: #444;
|
|
||||||
stroke-linecap: round;
|
|
||||||
stroke-linejoin: round;
|
|
||||||
stroke-width: 2;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-stroke-miter {
|
|
||||||
fill: none;
|
|
||||||
stroke: #444;
|
|
||||||
stroke-miterlimit: 10;
|
|
||||||
stroke-width: 2;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-fill,
|
|
||||||
.ql-snow .ql-stroke.ql-fill {
|
|
||||||
fill: #444;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-empty {
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-even {
|
|
||||||
fill-rule: evenodd;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-thin,
|
|
||||||
.ql-snow .ql-stroke.ql-thin {
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-transparent {
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-direction svg:last-child {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-direction.ql-active svg:last-child {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-direction.ql-active svg:first-child {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h2 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h3 {
|
|
||||||
font-size: 1.17em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h4 {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h5 {
|
|
||||||
font-size: 0.83em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor h6 {
|
|
||||||
font-size: 0.67em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor a {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor blockquote {
|
|
||||||
border-left: 4px solid #ccc;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding-left: 16px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor code,
|
|
||||||
.ql-snow .ql-editor pre {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor pre {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor code {
|
|
||||||
font-size: 85%;
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor pre.ql-syntax {
|
|
||||||
background-color: #23241f;
|
|
||||||
color: #f8f8f2;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-editor img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker {
|
|
||||||
color: #444;
|
|
||||||
display: inline-block;
|
|
||||||
float: left;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
height: 24px;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker-label {
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
height: 100%;
|
|
||||||
padding-left: 8px;
|
|
||||||
padding-right: 2px;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker-label::before {
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker-options {
|
|
||||||
background-color: #fff;
|
|
||||||
display: none;
|
|
||||||
min-width: 100%;
|
|
||||||
padding: 4px 8px;
|
|
||||||
position: absolute;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker-options .ql-picker-item {
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-expanded .ql-picker-label {
|
|
||||||
color: #ccc;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill {
|
|
||||||
fill: #ccc;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke {
|
|
||||||
stroke: #ccc;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-expanded .ql-picker-options {
|
|
||||||
display: block;
|
|
||||||
margin-top: -1px;
|
|
||||||
top: 100%;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker,
|
|
||||||
.ql-snow .ql-icon-picker {
|
|
||||||
width: 28px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker .ql-picker-label,
|
|
||||||
.ql-snow .ql-icon-picker .ql-picker-label {
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker .ql-picker-label svg,
|
|
||||||
.ql-snow .ql-icon-picker .ql-picker-label svg {
|
|
||||||
right: 4px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-icon-picker .ql-picker-options {
|
|
||||||
padding: 4px 0px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-icon-picker .ql-picker-item {
|
|
||||||
height: 24px;
|
|
||||||
width: 24px;
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker .ql-picker-options {
|
|
||||||
padding: 3px 5px;
|
|
||||||
width: 152px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker .ql-picker-item {
|
|
||||||
border: 1px solid transparent;
|
|
||||||
float: left;
|
|
||||||
height: 16px;
|
|
||||||
margin: 2px;
|
|
||||||
padding: 0px;
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg {
|
|
||||||
position: absolute;
|
|
||||||
margin-top: -9px;
|
|
||||||
right: 0;
|
|
||||||
top: 50%;
|
|
||||||
width: 18px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before,
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before,
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before {
|
|
||||||
content: attr(data-label);
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header {
|
|
||||||
width: 98px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
|
||||||
content: 'Normal';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
|
|
||||||
content: 'Heading 1';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
|
|
||||||
content: 'Heading 2';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
|
|
||||||
content: 'Heading 3';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
|
|
||||||
content: 'Heading 4';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
|
|
||||||
content: 'Heading 5';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
|
||||||
content: 'Heading 6';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
|
|
||||||
font-size: 1.17em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
|
|
||||||
font-size: 0.83em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
|
||||||
font-size: 0.67em;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font {
|
|
||||||
width: 108px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
|
||||||
content: 'Sans Serif';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
|
|
||||||
content: 'Serif';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
|
|
||||||
content: 'Monospace';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
|
|
||||||
font-family: Georgia, Times New Roman, serif;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
|
|
||||||
font-family: Monaco, Courier New, monospace;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size {
|
|
||||||
width: 98px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
|
||||||
content: 'Normal';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
|
|
||||||
content: 'Small';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
|
|
||||||
content: 'Large';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
|
|
||||||
content: 'Huge';
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker.ql-background .ql-picker-item {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-color-picker.ql-color .ql-picker-item {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-formats {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-picker-label {
|
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-picker-options {
|
|
||||||
border: 1px solid transparent;
|
|
||||||
box-shadow: rgba(0,0,0,0.2) 0 2px 8px;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label {
|
|
||||||
border-color: #ccc;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
|
|
||||||
border-color: #ccc;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected,
|
|
||||||
.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover {
|
|
||||||
border-color: #000;
|
|
||||||
}
|
|
||||||
.ql-toolbar.ql-snow + .ql-container.ql-snow {
|
|
||||||
border-top: 0px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-shadow: 0px 0px 5px #ddd;
|
|
||||||
color: #444;
|
|
||||||
padding: 5px 12px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip::before {
|
|
||||||
content: "Visit URL:";
|
|
||||||
line-height: 26px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip input[type=text] {
|
|
||||||
display: none;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
font-size: 13px;
|
|
||||||
height: 26px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 3px 5px;
|
|
||||||
width: 170px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip a.ql-preview {
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 200px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip a.ql-action::after {
|
|
||||||
border-right: 1px solid #ccc;
|
|
||||||
content: 'Edit';
|
|
||||||
margin-left: 16px;
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip a.ql-remove::before {
|
|
||||||
content: 'Remove';
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip a {
|
|
||||||
line-height: 26px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip.ql-editing a.ql-preview,
|
|
||||||
.ql-snow .ql-tooltip.ql-editing a.ql-remove {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip.ql-editing input[type=text] {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
|
|
||||||
border-right: 0px;
|
|
||||||
content: 'Save';
|
|
||||||
padding-right: 0px;
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip[data-mode=link]::before {
|
|
||||||
content: "Enter link:";
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip[data-mode=formula]::before {
|
|
||||||
content: "Enter formula:";
|
|
||||||
}
|
|
||||||
.ql-snow .ql-tooltip[data-mode=video]::before {
|
|
||||||
content: "Enter video:";
|
|
||||||
}
|
|
||||||
.ql-snow a {
|
|
||||||
color: #06c;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#readerDiv {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
background-color: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@font-face {
|
|
||||||
font-family: Starborn;
|
|
||||||
src: url(Fonts/Starborn.ttf);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
51
Wino.Mail/JS/editor.html
Normal file
51
Wino.Mail/JS/editor.html
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="language" content="english">
|
||||||
|
<script src="./libs/jodit.min.js"></script>
|
||||||
|
<script src="./libs/darkreader.js"></script>
|
||||||
|
<link rel="stylesheet" href="./libs/jodit.min.css" />
|
||||||
|
<link rel="stylesheet" href="./global.css" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.jodit-toolbar-button__trigger svg > path {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#editor {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jodit-container:not(.jodit_inline) {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jodit-wysiwyg {
|
||||||
|
min-height: 200px
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide taskbar in css. Should not be hidden from configuration, because it's used to sync state with native buttons. */
|
||||||
|
.jodit-toolbar__box {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
|
<textarea id="editor" name="editor"></textarea>
|
||||||
|
|
||||||
|
<!-- hidden input to handle image uploads -->
|
||||||
|
<input type="file" id="imageInput" style="display:none;">
|
||||||
|
<script src="/editor.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
104
Wino.Mail/JS/editor.js
Normal file
104
Wino.Mail/JS/editor.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
const editor = Jodit.make("#editor", {
|
||||||
|
"useSearch": false,
|
||||||
|
"toolbar": true,
|
||||||
|
"buttons": "bold,italic,underline,strikethrough,brush,ul,ol,font,fontsize,paragraph,image,link,indent,outdent,align,lineHeight,table",
|
||||||
|
"inline": true,
|
||||||
|
"toolbarAdaptive": false,
|
||||||
|
"toolbarInlineForSelection": false,
|
||||||
|
"showCharsCounter": false,
|
||||||
|
"showWordsCounter": false,
|
||||||
|
"showXPathInStatusbar": false,
|
||||||
|
"disablePlugins": "add-new-line",
|
||||||
|
"showPlaceholder": false,
|
||||||
|
"uploader": {
|
||||||
|
"insertImageAsBase64URI": true
|
||||||
|
},
|
||||||
|
"enter": "DIV",
|
||||||
|
"minHeight": 200
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle the image input change event
|
||||||
|
imageInput.addEventListener('change', () => {
|
||||||
|
const file = imageInput.files[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function (event) {
|
||||||
|
const base64Image = event.target.result;
|
||||||
|
insertImages([base64Image]);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const disabledButtons = ["indent", "outdent"];
|
||||||
|
const ariaPressedButtons = ["bold", "italic", "underline", "strikethrough", "ul", "ol"];
|
||||||
|
|
||||||
|
const alignmentButton = document.querySelector(`[ref='left']`).firstChild.firstChild;
|
||||||
|
const alignmentObserver = new MutationObserver(function () {
|
||||||
|
const value = alignmentButton.firstChild.getAttribute('class').split(' ')[0];
|
||||||
|
window.chrome.webview.postMessage({ type: 'alignment', value: value });
|
||||||
|
});
|
||||||
|
alignmentObserver.observe(alignmentButton, { childList: true, attributes: true, attributeFilter: ["class"] });
|
||||||
|
|
||||||
|
const ariaObservers = ariaPressedButtons.map(button => {
|
||||||
|
const buttonContainer = document.querySelector(`[ref='${button}']`);
|
||||||
|
const observer = new MutationObserver(function () { pressedChanged(buttonContainer) });
|
||||||
|
observer.observe(buttonContainer.firstChild, { attributes: true, attributeFilter: ["aria-pressed"] });
|
||||||
|
|
||||||
|
return observer;
|
||||||
|
});
|
||||||
|
|
||||||
|
const disabledObservers = disabledButtons.map(button => {
|
||||||
|
const buttonContainer = document.querySelector(`[ref='${button}']`);
|
||||||
|
const observer = new MutationObserver(function () { disabledButtonChanged(buttonContainer) });
|
||||||
|
observer.observe(buttonContainer.firstChild, { attributes: true, attributeFilter: ["disabled"] });
|
||||||
|
|
||||||
|
return observer;
|
||||||
|
});
|
||||||
|
|
||||||
|
function pressedChanged(buttonContainer) {
|
||||||
|
const ref = buttonContainer.getAttribute('ref');
|
||||||
|
const value = buttonContainer.firstChild.getAttribute('aria-pressed');
|
||||||
|
window.chrome.webview.postMessage({ type: ref, value: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
function disabledButtonChanged(buttonContainer) {
|
||||||
|
const ref = buttonContainer.getAttribute('ref');
|
||||||
|
const value = buttonContainer.firstChild.getAttribute('disabled');
|
||||||
|
console.log(buttonContainer, ref, value);
|
||||||
|
window.chrome.webview.postMessage({ type: ref, value: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function RenderHTML(htmlString) {
|
||||||
|
editor.s.insertHTML(htmlString);
|
||||||
|
editor.synchronizeValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetHTMLContent() {
|
||||||
|
return editor.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetLightEditor() {
|
||||||
|
DarkReader.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetDarkEditor() {
|
||||||
|
DarkReader.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleToolbar(enable) {
|
||||||
|
const toolbar = document.querySelector('.jodit-toolbar__box');
|
||||||
|
if (enable == 'true') {
|
||||||
|
toolbar.style.display = 'flex';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toolbar.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertImages(images) {
|
||||||
|
images.forEach(image => {
|
||||||
|
editor.selection.insertHTML(`<img src="${image}" alt="Embedded Image">`);
|
||||||
|
});
|
||||||
|
};
|
||||||
5664
Wino.Mail/JS/libs/jodit.min.css
vendored
Normal file
5664
Wino.Mail/JS/libs/jodit.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10
Wino.Mail/JS/libs/jodit.min.js
vendored
Normal file
10
Wino.Mail/JS/libs/jodit.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,8 +1,25 @@
|
|||||||
<html>
|
<html>
|
||||||
<body style="padding-left:12px; padding-right:12px; padding-top:8px; padding-bottom: 8px; margin: 0px; border-radius: 8px;">
|
<head>
|
||||||
<meta name="color-scheme" content="dark light">
|
<link rel="stylesheet" href="./global.css" />
|
||||||
<script src="https://app.reader/darkreader.js"></script>
|
<script src="./libs/darkreader.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-right: 12px;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
margin: 0px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#readerDiv {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
<script>
|
<script>
|
||||||
function RenderHTML(htmlString) {
|
function RenderHTML(htmlString) {
|
||||||
var containerDiv = document.getElementById("readerDiv");
|
var containerDiv = document.getElementById("readerDiv");
|
||||||
@@ -29,10 +46,6 @@
|
|||||||
DarkReader.enable();
|
DarkReader.enable();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<div id="readerDiv"></div>
|
||||||
<link rel="stylesheet" href="https://app.reader/reader.css" />
|
|
||||||
<div id="readerDiv">
|
|
||||||
</div>
|
|
||||||
<link rel="stylesheet" href="https://app.reader/global.css" />
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
File diff suppressed because one or more lines are too long
@@ -151,13 +151,25 @@
|
|||||||
OverflowButtonVisibility="Collapsed">
|
OverflowButtonVisibility="Collapsed">
|
||||||
<CommandBar.PrimaryCommands>
|
<CommandBar.PrimaryCommands>
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="ComposerThemeToggleButton"
|
|
||||||
Click="InvertComposerThemeClicked"
|
Click="InvertComposerThemeClicked"
|
||||||
LabelPosition="Collapsed">
|
LabelPosition="Collapsed"
|
||||||
|
ToolTipService.ToolTip="Light Theme"
|
||||||
|
Visibility="{x:Bind IsComposerDarkMode, Mode=OneWay}">
|
||||||
|
<AppBarButton.Icon>
|
||||||
|
<controls:WinoFontIcon Icon="LightEditor" />
|
||||||
|
</AppBarButton.Icon>
|
||||||
|
</AppBarButton>
|
||||||
|
|
||||||
|
<AppBarButton
|
||||||
|
Click="InvertComposerThemeClicked"
|
||||||
|
LabelPosition="Collapsed"
|
||||||
|
ToolTipService.ToolTip="Dark Theme"
|
||||||
|
Visibility="{x:Bind IsComposerDarkMode, Mode=OneWay, Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<controls:WinoFontIcon Icon="DarkEditor" />
|
<controls:WinoFontIcon Icon="DarkEditor" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
|
|
||||||
<AppBarButton Command="{x:Bind ViewModel.DiscardCommand}" Label="Discard">
|
<AppBarButton Command="{x:Bind ViewModel.DiscardCommand}" Label="Discard">
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<controls:WinoFontIcon Icon="Delete" />
|
<controls:WinoFontIcon Icon="Delete" />
|
||||||
@@ -186,281 +198,220 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Editor Options -->
|
<!-- Editor Options -->
|
||||||
<ScrollViewer
|
<Grid Grid.Row="1" Padding="26,0,6,6">
|
||||||
Grid.Row="1"
|
<CommandBar
|
||||||
Margin="0,6"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
DefaultLabelPosition="Collapsed"
|
||||||
HorizontalScrollBarVisibility="Hidden"
|
IsDynamicOverflowEnabled="True"
|
||||||
HorizontalScrollMode="Enabled"
|
Visibility="{x:Bind helpers:XamlHelpers.IsFormatSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
||||||
VerticalScrollBarVisibility="Hidden"
|
<AppBarToggleButton
|
||||||
VerticalScrollMode="Disabled">
|
x:Name="BoldButton"
|
||||||
<Grid Margin="16,0,16,20" Padding="8,0">
|
Click="BoldButtonClicked"
|
||||||
<!-- Format Panel -->
|
Label="Bold">
|
||||||
<Grid x:Name="FormatPanel" Visibility="{x:Bind helpers:XamlHelpers.IsFormatSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
<AppBarToggleButton.Icon>
|
||||||
<StackPanel Orientation="Horizontal" Spacing="12">
|
<PathIcon Data="{StaticResource BoldPathIcon}" />
|
||||||
<ToggleButton
|
</AppBarToggleButton.Icon>
|
||||||
x:Name="BoldButton"
|
</AppBarToggleButton>
|
||||||
Height="32"
|
<AppBarToggleButton
|
||||||
Click="BoldButtonClicked">
|
x:Name="ItalicButton"
|
||||||
<ToggleButton.Content>
|
Click="ItalicButtonClicked"
|
||||||
|
Label="Italic">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource ItalicPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="UnderlineButton"
|
||||||
|
Click="UnderlineButtonClicked"
|
||||||
|
Label="Underline">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource UnderlinePathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="StrokeButton"
|
||||||
|
Click="StrokeButtonClicked"
|
||||||
|
Label="Stroke">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource StrikePathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
|
||||||
|
<AppBarSeparator />
|
||||||
|
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="BulletListButton"
|
||||||
|
Click="BulletListButtonClicked"
|
||||||
|
Label="Bullet List">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource BulletedListPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="OrderedListButton"
|
||||||
|
Click="OrderedListButtonClicked"
|
||||||
|
Label="Ordered List">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
|
||||||
|
<AppBarSeparator />
|
||||||
|
|
||||||
|
<AppBarButton
|
||||||
|
x:Name="DecreaseIndentButton"
|
||||||
|
Click="DecreaseIndentClicked"
|
||||||
|
Label="Outdent">
|
||||||
|
<AppBarButton.Content>
|
||||||
|
<Viewbox Width="16">
|
||||||
|
<PathIcon Data="{StaticResource DecreaseIndentPathIcon}" />
|
||||||
|
</Viewbox>
|
||||||
|
</AppBarButton.Content>
|
||||||
|
</AppBarButton>
|
||||||
|
|
||||||
|
<AppBarButton
|
||||||
|
x:Name="IncreaseIndentButton"
|
||||||
|
Click="IncreaseIndentClicked"
|
||||||
|
Label="Indent">
|
||||||
|
<AppBarButton.Content>
|
||||||
|
<Viewbox Width="16">
|
||||||
|
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
||||||
|
</Viewbox>
|
||||||
|
</AppBarButton.Content>
|
||||||
|
</AppBarButton>
|
||||||
|
|
||||||
|
<AppBarElementContainer HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<ComboBox
|
||||||
|
x:Name="AlignmentListView"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
SelectionChanged="AlignmentChanged">
|
||||||
|
<ComboBoxItem IsSelected="True" Tag="left">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource BoldPathIcon}" />
|
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</ToggleButton.Content>
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Left}" />
|
||||||
</ToggleButton>
|
</StackPanel>
|
||||||
<ToggleButton
|
</ComboBoxItem>
|
||||||
x:Name="ItalicButton"
|
|
||||||
Height="32"
|
<ComboBoxItem Tag="center">
|
||||||
Click="ItalicButtonClicked">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<ToggleButton.Content>
|
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource ItalicPathIcon}" />
|
<PathIcon Data="{StaticResource AlignCenterPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</ToggleButton.Content>
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Center}" />
|
||||||
</ToggleButton>
|
</StackPanel>
|
||||||
<ToggleButton
|
</ComboBoxItem>
|
||||||
x:Name="UnderlineButton"
|
|
||||||
Height="32"
|
<ComboBoxItem Tag="right">
|
||||||
Click="UnderlineButtonClicked">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<ToggleButton.Content>
|
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource UnderlinePathIcon}" />
|
<PathIcon Data="{StaticResource AlignRightPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</ToggleButton.Content>
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Right}" />
|
||||||
</ToggleButton>
|
</StackPanel>
|
||||||
<ToggleButton
|
</ComboBoxItem>
|
||||||
x:Name="StrokeButton"
|
|
||||||
Height="32"
|
<ComboBoxItem Tag="justify">
|
||||||
Click="StrokeButtonClicked">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<ToggleButton.Content>
|
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource StrikePathIcon}" />
|
<PathIcon Data="{StaticResource AlignJustifyPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</ToggleButton.Content>
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Justify}" />
|
||||||
</ToggleButton>
|
</StackPanel>
|
||||||
|
</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</AppBarElementContainer>
|
||||||
|
|
||||||
<AppBarSeparator />
|
<AppBarSeparator />
|
||||||
|
|
||||||
<ToggleButton
|
<AppBarToggleButton
|
||||||
x:Name="BulletListButton"
|
x:Name="WebviewToolBarButton"
|
||||||
Height="32"
|
Click="WebViewToggleButtonClicked"
|
||||||
Click="BulletListButtonClicked">
|
Label="Webview ToolBar"
|
||||||
<ToggleButton.Content>
|
ToolTipService.ToolTip="Webview ToolBar">
|
||||||
<Viewbox Width="16">
|
<AppBarToggleButton.Icon>
|
||||||
<PathIcon Data="{StaticResource BulletedListPathIcon}" />
|
<PathIcon Data="{StaticResource WebviewToolBarPathIcon}" />
|
||||||
</Viewbox>
|
</AppBarToggleButton.Icon>
|
||||||
</ToggleButton.Content>
|
</AppBarToggleButton>
|
||||||
</ToggleButton>
|
</CommandBar>
|
||||||
|
|
||||||
<ToggleButton
|
<!-- Insert Panel -->
|
||||||
x:Name="OrderedListButton"
|
<CommandBar
|
||||||
Height="32"
|
HorizontalAlignment="Left"
|
||||||
Click="OrderedListButtonClicked">
|
DefaultLabelPosition="Right"
|
||||||
<ToggleButton.Content>
|
IsDynamicOverflowEnabled="True"
|
||||||
<Viewbox Width="16">
|
Visibility="{x:Bind helpers:XamlHelpers.IsInsertSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
||||||
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
<AppBarButton
|
||||||
</Viewbox>
|
x:Name="FilesButton"
|
||||||
</ToggleButton.Content>
|
Click="AddFilesClicked"
|
||||||
</ToggleButton>
|
Label="{x:Bind domain:Translator.Files}">
|
||||||
|
<AppBarButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource AttachPathIcon}" />
|
||||||
|
</AppBarButton.Icon>
|
||||||
|
</AppBarButton>
|
||||||
|
|
||||||
<Button
|
<AppBarButton
|
||||||
x:Name="DecreaseIndentButton"
|
x:Name="AddImageButton"
|
||||||
Height="32"
|
Click="AddImageClicked"
|
||||||
Click="DecreaseIndentClicked">
|
Label="{x:Bind domain:Translator.Photos}">
|
||||||
<Button.Content>
|
<AppBarButton.Icon>
|
||||||
<Viewbox Width="16">
|
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
|
||||||
<PathIcon Data="{StaticResource DecreaseIndentPathIcon}" />
|
</AppBarButton.Icon>
|
||||||
</Viewbox>
|
</AppBarButton>
|
||||||
</Button.Content>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
<AppBarButton
|
||||||
x:Name="IncreaseIndentButton"
|
x:Name="EmojiButton"
|
||||||
Height="32"
|
Click="EmojiButtonClicked"
|
||||||
Click="IncreaseIndentClicked">
|
Label="{x:Bind domain:Translator.Emoji}">
|
||||||
<Button.Content>
|
<AppBarButton.Icon>
|
||||||
<Viewbox Width="16">
|
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
||||||
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
</AppBarButton.Icon>
|
||||||
</Viewbox>
|
</AppBarButton>
|
||||||
</Button.Content>
|
</CommandBar>
|
||||||
</Button>
|
|
||||||
|
|
||||||
<AppBarSeparator />
|
<!-- Draw Panel -->
|
||||||
|
<Grid x:Name="DrawPanel" Visibility="{x:Bind helpers:XamlHelpers.IsDrawSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
||||||
<ToggleButton
|
<TextBlock Text="{x:Bind domain:Translator.ComingSoon}" />
|
||||||
x:Name="DirectionButton"
|
|
||||||
Height="32"
|
|
||||||
Click="DirectionButtonClicked">
|
|
||||||
<ToggleButton.Content>
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource ParagraphPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
</ToggleButton.Content>
|
|
||||||
</ToggleButton>
|
|
||||||
|
|
||||||
<ComboBox
|
|
||||||
x:Name="AlignmentListView"
|
|
||||||
Width="120"
|
|
||||||
Height="32"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
SelectionChanged="AlignmentChanged">
|
|
||||||
<ComboBoxItem Tag="left">
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Left}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
|
|
||||||
<ComboBoxItem Tag="center">
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignCenterPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Center}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
|
|
||||||
<ComboBoxItem Tag="right">
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignRightPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Right}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
|
|
||||||
<ComboBoxItem Tag="justify">
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignJustifyPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Justify}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
</ComboBox>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Insert Panel -->
|
|
||||||
<Grid x:Name="InsertPanel" Visibility="{x:Bind helpers:XamlHelpers.IsInsertSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="12">
|
|
||||||
<Button
|
|
||||||
x:Name="FilesButton"
|
|
||||||
Height="32"
|
|
||||||
Click="AddFilesClicked">
|
|
||||||
<Button.Content>
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16" VerticalAlignment="Center">
|
|
||||||
<PathIcon Data="{StaticResource AttachPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock Text="{x:Bind domain:Translator.Files}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button.Content>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
x:Name="AddImageButton"
|
|
||||||
Height="32"
|
|
||||||
Click="AddImageClicked">
|
|
||||||
<Button.Content>
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16" VerticalAlignment="Center">
|
|
||||||
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock Text="{x:Bind domain:Translator.Photos}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button.Content>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
x:Name="EmojiButton"
|
|
||||||
Height="32"
|
|
||||||
Click="EmojiButtonClicked">
|
|
||||||
<Button.Content>
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16" VerticalAlignment="Center">
|
|
||||||
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock Text="{x:Bind domain:Translator.Emoji}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button.Content>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
x:Name="LinkButton"
|
|
||||||
Height="32"
|
|
||||||
Click="LinkButtonClicked">
|
|
||||||
<Button.Flyout>
|
|
||||||
<Flyout x:Name="HyperlinkFlyout">
|
|
||||||
<StackPanel Width="250" Spacing="6">
|
|
||||||
<TextBox x:Name="HyperlinkTextBox" Header="Text" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="LinkUrlTextBox"
|
|
||||||
Header="Link"
|
|
||||||
PlaceholderText="https://" />
|
|
||||||
<Button
|
|
||||||
x:Name="AddHyperlinkButton"
|
|
||||||
Margin="0,6"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Click="HyperlinkAddClicked"
|
|
||||||
Content="{x:Bind domain:Translator.AddHyperlink}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</Button.Flyout>
|
|
||||||
<Button.Content>
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16" VerticalAlignment="Center">
|
|
||||||
<PathIcon Data="{StaticResource AddLinkPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock Text="Link" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button.Content>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Draw Panel -->
|
|
||||||
<Grid x:Name="DrawPanel" Visibility="{x:Bind helpers:XamlHelpers.IsDrawSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
|
||||||
<TextBlock Text="{x:Bind domain:Translator.ComingSoon}" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Options Panel -->
|
|
||||||
<Grid x:Name="OptionsPanel" Visibility="{x:Bind helpers:XamlHelpers.IsOptionsSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
|
||||||
<muxc:ToggleSplitButton x:Name="ImportanceSplitButton" IsChecked="{x:Bind ViewModel.IsImportanceSelected, Mode=TwoWay}">
|
|
||||||
<SymbolIcon x:Name="ImportanceSplitButtonContent" Symbol="Important" />
|
|
||||||
<muxc:ToggleSplitButton.Flyout>
|
|
||||||
<Flyout x:Name="ImportanceFlyout" Placement="Bottom">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<StackPanel.Resources>
|
|
||||||
<Style TargetType="Button">
|
|
||||||
<Setter Property="Padding" Value="4" />
|
|
||||||
<Setter Property="MinWidth" Value="0" />
|
|
||||||
<Setter Property="MinHeight" Value="0" />
|
|
||||||
<Setter Property="Margin" Value="6" />
|
|
||||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
|
||||||
</Style>
|
|
||||||
</StackPanel.Resources>
|
|
||||||
<Button Click="ImportanceClicked">
|
|
||||||
<Button.Tag>
|
|
||||||
<mailkit:MessageImportance>High</mailkit:MessageImportance>
|
|
||||||
</Button.Tag>
|
|
||||||
<SymbolIcon Symbol="Important" />
|
|
||||||
</Button>
|
|
||||||
<Button Click="ImportanceClicked">
|
|
||||||
<Button.Tag>
|
|
||||||
<mailkit:MessageImportance>Low</mailkit:MessageImportance>
|
|
||||||
</Button.Tag>
|
|
||||||
<SymbolIcon Symbol="Download" />
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</muxc:ToggleSplitButton.Flyout>
|
|
||||||
</muxc:ToggleSplitButton>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
|
||||||
|
<!-- Options Panel -->
|
||||||
|
<Grid x:Name="OptionsPanel" Visibility="{x:Bind helpers:XamlHelpers.IsOptionsSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
||||||
|
<muxc:ToggleSplitButton x:Name="ImportanceSplitButton" IsChecked="{x:Bind ViewModel.IsImportanceSelected, Mode=TwoWay}">
|
||||||
|
<SymbolIcon x:Name="ImportanceSplitButtonContent" Symbol="Important" />
|
||||||
|
<muxc:ToggleSplitButton.Flyout>
|
||||||
|
<Flyout x:Name="ImportanceFlyout" Placement="Bottom">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<StackPanel.Resources>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="Padding" Value="4" />
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="MinHeight" Value="0" />
|
||||||
|
<Setter Property="Margin" Value="6" />
|
||||||
|
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||||
|
</Style>
|
||||||
|
</StackPanel.Resources>
|
||||||
|
<Button Click="ImportanceClicked">
|
||||||
|
<Button.Tag>
|
||||||
|
<mailkit:MessageImportance>High</mailkit:MessageImportance>
|
||||||
|
</Button.Tag>
|
||||||
|
<SymbolIcon Symbol="Important" />
|
||||||
|
</Button>
|
||||||
|
<Button Click="ImportanceClicked">
|
||||||
|
<Button.Tag>
|
||||||
|
<mailkit:MessageImportance>Low</mailkit:MessageImportance>
|
||||||
|
</Button.Tag>
|
||||||
|
<SymbolIcon Symbol="Download" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</Flyout>
|
||||||
|
</muxc:ToggleSplitButton.Flyout>
|
||||||
|
</muxc:ToggleSplitButton>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<!-- Mime Info -->
|
<!-- Mime Info -->
|
||||||
<Grid
|
<Grid
|
||||||
@@ -644,7 +595,7 @@
|
|||||||
Visibility="{x:Bind ViewModel.IsDraggingOverComposerGrid, Mode=OneWay}">
|
Visibility="{x:Bind ViewModel.IsDraggingOverComposerGrid, Mode=OneWay}">
|
||||||
<Grid Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}" CornerRadius="9">
|
<Grid Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}" CornerRadius="9">
|
||||||
<Rectangle
|
<Rectangle
|
||||||
x:Name="DropZoneBorder"
|
x:Name="FilesDropZoneBorder"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
Opacity="0.5"
|
Opacity="0.5"
|
||||||
RadiusX="9"
|
RadiusX="9"
|
||||||
@@ -653,7 +604,7 @@
|
|||||||
StrokeDashArray="3,4"
|
StrokeDashArray="3,4"
|
||||||
StrokeThickness="2" />
|
StrokeThickness="2" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
x:Name="DropZoneText"
|
x:Name="FilesDropZoneText"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontSize="20"
|
FontSize="20"
|
||||||
@@ -662,38 +613,6 @@
|
|||||||
Text="{x:Bind domain:Translator.ComposerAttachmentsDropZone_Message}" />
|
Text="{x:Bind domain:Translator.ComposerAttachmentsDropZone_Message}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
|
||||||
<VisualStateGroup x:Name="ComposerThemeToggleButtonStates">
|
|
||||||
<VisualState x:Name="DarkMode">
|
|
||||||
<VisualState.StateTriggers>
|
|
||||||
<StateTrigger IsActive="{x:Bind IsComposerDarkMode, Mode=OneWay}" />
|
|
||||||
</VisualState.StateTriggers>
|
|
||||||
<VisualState.Setters>
|
|
||||||
<Setter Target="ComposerThemeToggleButton.Label" Value="Light Reader" />
|
|
||||||
<Setter Target="ComposerThemeToggleButton.Icon">
|
|
||||||
<Setter.Value>
|
|
||||||
<controls:WinoFontIcon Icon="LightEditor" />
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</VisualState.Setters>
|
|
||||||
</VisualState>
|
|
||||||
|
|
||||||
<VisualState x:Name="LightMode" />
|
|
||||||
</VisualStateGroup>
|
|
||||||
<VisualStateGroup x:Name="DropZoneState">
|
|
||||||
<VisualState x:Name="Hovered">
|
|
||||||
<VisualState.StateTriggers>
|
|
||||||
<StateTrigger IsActive="{x:Bind ViewModel.IsDraggingOverDropZone, Mode=OneWay}" />
|
|
||||||
</VisualState.StateTriggers>
|
|
||||||
<VisualState.Setters>
|
|
||||||
<Setter Target="DropZoneText.Opacity" Value="1" />
|
|
||||||
<Setter Target="DropZoneBorder.Opacity" Value="1" />
|
|
||||||
</VisualState.Setters>
|
|
||||||
</VisualState>
|
|
||||||
<VisualState x:Name="NotHovered" />
|
|
||||||
</VisualStateGroup>
|
|
||||||
</VisualStateManager.VisualStateGroups>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border
|
<Border
|
||||||
@@ -701,13 +620,67 @@
|
|||||||
Background="{ThemeResource WinoContentZoneBackgroud}"
|
Background="{ThemeResource WinoContentZoneBackgroud}"
|
||||||
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="10">
|
CornerRadius="7">
|
||||||
<Grid>
|
<Grid Margin="1" CornerRadius="7">
|
||||||
<Grid Background="White" Visibility="{x:Bind IsComposerDarkMode, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
<Grid Background="White" Visibility="{x:Bind IsComposerDarkMode, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
||||||
|
|
||||||
<muxc:WebView2 x:Name="Chromium" />
|
<muxc:WebView2 x:Name="Chromium" />
|
||||||
|
|
||||||
|
<!-- Dropzone for images -->
|
||||||
|
<Grid
|
||||||
|
AllowDrop="True"
|
||||||
|
DragEnter="OnImageDropGridDragEnter"
|
||||||
|
DragLeave="OnImageDropGridDragLeave"
|
||||||
|
Drop="OnImageDropGridImageDropped"
|
||||||
|
Visibility="{x:Bind ViewModel.IsDraggingOverComposerGrid, Mode=OneWay}">
|
||||||
|
<Grid Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}" CornerRadius="9">
|
||||||
|
<Rectangle
|
||||||
|
x:Name="ImagesDropZoneBorder"
|
||||||
|
Fill="Transparent"
|
||||||
|
Opacity="0.5"
|
||||||
|
RadiusX="9"
|
||||||
|
RadiusY="9"
|
||||||
|
Stroke="{ThemeResource TextFillColorPrimaryBrush}"
|
||||||
|
StrokeDashArray="3,4"
|
||||||
|
StrokeThickness="2" />
|
||||||
|
<TextBlock
|
||||||
|
x:Name="ImagesDropZoneText"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="20"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Opacity="0.5"
|
||||||
|
Text="{x:Bind domain:Translator.ComposerImagesDropZone_Message}" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="FilesDropZoneState">
|
||||||
|
<VisualState x:Name="FilesDropZoneHovered">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<StateTrigger IsActive="{x:Bind ViewModel.IsDraggingOverFilesDropZone, Mode=OneWay}" />
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="FilesDropZoneText.Opacity" Value="1" />
|
||||||
|
<Setter Target="FilesDropZoneBorder.Opacity" Value="1" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="FilesDropZoneNotHovered" />
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="ImagesDropZoneState">
|
||||||
|
<VisualState x:Name="ImagesDropZoneHovered">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<StateTrigger IsActive="{x:Bind ViewModel.IsDraggingOverImagesDropZone, Mode=OneWay}" />
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="ImagesDropZoneText.Opacity" Value="1" />
|
||||||
|
<Setter Target="ImagesDropZoneBorder.Opacity" Value="1" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="ImagesDropZoneNotHovered" />
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using CommunityToolkit.Mvvm.Messaging;
|
|||||||
using CommunityToolkit.WinUI.Controls;
|
using CommunityToolkit.WinUI.Controls;
|
||||||
using EmailValidation;
|
using EmailValidation;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Toolkit.Uwp.Helpers;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.Web.WebView2.Core;
|
using Microsoft.Web.WebView2.Core;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
@@ -26,6 +27,7 @@ using Wino.Core.Domain;
|
|||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Requests;
|
||||||
using Wino.Core.Messages.Mails;
|
using Wino.Core.Messages.Mails;
|
||||||
using Wino.Core.Messages.Shell;
|
using Wino.Core.Messages.Shell;
|
||||||
using Wino.Extensions;
|
using Wino.Extensions;
|
||||||
@@ -121,7 +123,7 @@ namespace Wino.Views
|
|||||||
|
|
||||||
private void OnFileDropGridDragOver(object sender, DragEventArgs e)
|
private void OnFileDropGridDragOver(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
ViewModel.IsDraggingOverDropZone = true;
|
ViewModel.IsDraggingOverFilesDropZone = true;
|
||||||
|
|
||||||
e.AcceptedOperation = DataPackageOperation.Copy;
|
e.AcceptedOperation = DataPackageOperation.Copy;
|
||||||
e.DragUIOverride.Caption = Translator.ComposerAttachmentsDragDropAttach_Message;
|
e.DragUIOverride.Caption = Translator.ComposerAttachmentsDragDropAttach_Message;
|
||||||
@@ -132,21 +134,94 @@ namespace Wino.Views
|
|||||||
|
|
||||||
private void OnFileDropGridDragLeave(object sender, DragEventArgs e)
|
private void OnFileDropGridDragLeave(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
ViewModel.IsDraggingOverDropZone = false;
|
ViewModel.IsDraggingOverFilesDropZone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnFileDropGridFileDropped(object sender, DragEventArgs e)
|
private async void OnFileDropGridFileDropped(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (e.DataView.Contains(StandardDataFormats.StorageItems))
|
||||||
|
{
|
||||||
|
var storageItems = await e.DataView.GetStorageItemsAsync();
|
||||||
|
var files = storageItems.OfType<StorageFile>();
|
||||||
|
|
||||||
|
await AttachFiles(files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// State should be reset even when an exception occurs, otherwise the UI will be stuck in a dragging state.
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ViewModel.IsDraggingOverComposerGrid = false;
|
||||||
|
ViewModel.IsDraggingOverFilesDropZone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void OnImageDropGridDragEnter(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = false;
|
||||||
if (e.DataView.Contains(StandardDataFormats.StorageItems))
|
if (e.DataView.Contains(StandardDataFormats.StorageItems))
|
||||||
{
|
{
|
||||||
var storageItems = await e.DataView.GetStorageItemsAsync();
|
// We can't use async/await here because DragUIOverride becomes inaccessible.
|
||||||
var files = storageItems.OfType<StorageFile>();
|
// https://github.com/microsoft/microsoft-ui-xaml/issues/9296
|
||||||
|
var files = e.DataView.GetStorageItemsAsync().GetAwaiter().GetResult().OfType<StorageFile>();
|
||||||
|
|
||||||
await AttachFiles(files);
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (ValidateImageFile(file))
|
||||||
|
{
|
||||||
|
isValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewModel.IsDraggingOverComposerGrid = false;
|
e.AcceptedOperation = isValid ? DataPackageOperation.Copy : DataPackageOperation.None;
|
||||||
ViewModel.IsDraggingOverDropZone = false;
|
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
ViewModel.IsDraggingOverImagesDropZone = true;
|
||||||
|
e.DragUIOverride.Caption = Translator.ComposerAttachmentsDragDropAttach_Message;
|
||||||
|
e.DragUIOverride.IsCaptionVisible = true;
|
||||||
|
e.DragUIOverride.IsGlyphVisible = true;
|
||||||
|
e.DragUIOverride.IsContentVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnImageDropGridDragLeave(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
ViewModel.IsDraggingOverImagesDropZone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnImageDropGridImageDropped(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (e.DataView.Contains(StandardDataFormats.StorageItems))
|
||||||
|
{
|
||||||
|
var storageItems = await e.DataView.GetStorageItemsAsync();
|
||||||
|
var files = storageItems.OfType<StorageFile>();
|
||||||
|
|
||||||
|
var imageDataURLs = new List<string>();
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (ValidateImageFile(file))
|
||||||
|
imageDataURLs.Add(await GetDataURL(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
await InvokeScriptSafeAsync($"insertImages({JsonConvert.SerializeObject(imageDataURLs)});");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// State should be reset even when an exception occurs, otherwise the UI will be stuck in a dragging state.
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ViewModel.IsDraggingOverComposerGrid = false;
|
||||||
|
ViewModel.IsDraggingOverImagesDropZone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<string> GetDataURL(StorageFile file)
|
||||||
|
{
|
||||||
|
return $"data:image/{file.FileType.Replace(".", "")};base64,{Convert.ToBase64String(await file.ReadBytesAsync())}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AttachFiles(IEnumerable<StorageFile> files)
|
private async Task AttachFiles(IEnumerable<StorageFile> files)
|
||||||
@@ -165,49 +240,52 @@ namespace Wino.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ValidateImageFile(StorageFile file)
|
||||||
|
{
|
||||||
|
string[] allowedTypes = new string[] { ".jpg", ".jpeg", ".png" };
|
||||||
|
var fileType = file.FileType.ToLower();
|
||||||
|
|
||||||
|
return allowedTypes.Contains(fileType);
|
||||||
|
}
|
||||||
|
|
||||||
private async void BoldButtonClicked(object sender, RoutedEventArgs e)
|
private async void BoldButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('boldButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('bold')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ItalicButtonClicked(object sender, RoutedEventArgs e)
|
private async void ItalicButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('italicButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('italic')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UnderlineButtonClicked(object sender, RoutedEventArgs e)
|
private async void UnderlineButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('underlineButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('underline')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StrokeButtonClicked(object sender, RoutedEventArgs e)
|
private async void StrokeButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('strikeButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('strikethrough')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void BulletListButtonClicked(object sender, RoutedEventArgs e)
|
private async void BulletListButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('bulletListButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('insertunorderedlist')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OrderedListButtonClicked(object sender, RoutedEventArgs e)
|
private async void OrderedListButtonClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('orderedListButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('insertorderedlist')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void IncreaseIndentClicked(object sender, RoutedEventArgs e)
|
private async void IncreaseIndentClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('increaseIndentButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('indent')");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void DecreaseIndentClicked(object sender, RoutedEventArgs e)
|
private async void DecreaseIndentClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('decreaseIndentButton').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('outdent')");
|
||||||
}
|
|
||||||
|
|
||||||
private async void DirectionButtonClicked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
await InvokeScriptSafeAsync("document.getElementById('directionButton').click();");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AlignmentChanged(object sender, SelectionChangedEventArgs e)
|
private async void AlignmentChanged(object sender, SelectionChangedEventArgs e)
|
||||||
@@ -218,20 +296,26 @@ namespace Wino.Views
|
|||||||
switch (alignment)
|
switch (alignment)
|
||||||
{
|
{
|
||||||
case "left":
|
case "left":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-left').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyleft')");
|
||||||
break;
|
break;
|
||||||
case "center":
|
case "center":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-center').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifycenter')");
|
||||||
break;
|
break;
|
||||||
case "right":
|
case "right":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-right').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyright')");
|
||||||
break;
|
break;
|
||||||
case "justify":
|
case "justify":
|
||||||
await InvokeScriptSafeAsync("document.getElementById('ql-align-justify').click();");
|
await InvokeScriptSafeAsync("editor.execCommand('justifyfull')");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void WebViewToggleButtonClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var enable = WebviewToolBarButton.IsChecked == true ? "true" : "false";
|
||||||
|
await InvokeScriptSafeAsync($"toggleToolbar('{enable}');");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<string> ExecuteScriptFunctionAsync(string functionName, params object[] parameters)
|
public async Task<string> ExecuteScriptFunctionAsync(string functionName, params object[] parameters)
|
||||||
{
|
{
|
||||||
string script = functionName + "(";
|
string script = functionName + "(";
|
||||||
@@ -252,21 +336,24 @@ namespace Wino.Views
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await Chromium.ExecuteScriptAsync(function);
|
return await Chromium?.ExecuteScriptAsync(function);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddImageClicked(object sender, RoutedEventArgs e)
|
private async void AddImageClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("document.getElementById('addImageButton').click();");
|
await InvokeScriptSafeAsync("imageInput.click();");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FocusEditorAsync()
|
private async Task FocusEditorAsync()
|
||||||
{
|
{
|
||||||
await InvokeScriptSafeAsync("quill.focus();");
|
await InvokeScriptSafeAsync("editor.selection.focus();");
|
||||||
|
|
||||||
Chromium.Focus(FocusState.Keyboard);
|
Chromium.Focus(FocusState.Keyboard);
|
||||||
Chromium.Focus(FocusState.Programmatic);
|
Chromium.Focus(FocusState.Programmatic);
|
||||||
@@ -279,24 +366,6 @@ namespace Wino.Views
|
|||||||
await FocusEditorAsync();
|
await FocusEditorAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> TryGetSelectedTextAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await Chromium.ExecuteScriptAsync("getSelectedText();");
|
|
||||||
}
|
|
||||||
catch (Exception) { }
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void LinkButtonClicked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
// Get selected text from Quill.
|
|
||||||
|
|
||||||
HyperlinkTextBox.Text = await TryGetSelectedTextAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateEditorThemeAsync()
|
public async Task UpdateEditorThemeAsync()
|
||||||
{
|
{
|
||||||
await DOMLoadedTask.Task;
|
await DOMLoadedTask.Task;
|
||||||
@@ -346,7 +415,7 @@ namespace Wino.Views
|
|||||||
if (Chromium.CoreWebView2 != null)
|
if (Chromium.CoreWebView2 != null)
|
||||||
{
|
{
|
||||||
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
||||||
Chromium.CoreWebView2.WebMessageReceived -= ScriptMessageRecieved;
|
Chromium.CoreWebView2.WebMessageReceived -= ScriptMessageReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chromium.Close();
|
Chromium.Close();
|
||||||
@@ -379,9 +448,9 @@ namespace Wino.Views
|
|||||||
|
|
||||||
ViewModel.GetHTMLBodyFunction = new Func<Task<string>>(async () =>
|
ViewModel.GetHTMLBodyFunction = new Func<Task<string>>(async () =>
|
||||||
{
|
{
|
||||||
var quillContent = await InvokeScriptSafeAsync("GetHTMLContent();");
|
var editorContent = await InvokeScriptSafeAsync("GetHTMLContent();");
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<string>(quillContent);
|
return JsonConvert.DeserializeObject<string>(editorContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
var underlyingThemeService = App.Current.Services.GetService<IUnderlyingThemeService>();
|
var underlyingThemeService = App.Current.Services.GetService<IUnderlyingThemeService>();
|
||||||
@@ -391,60 +460,66 @@ namespace Wino.Views
|
|||||||
|
|
||||||
private async void ChromiumInitialized(Microsoft.UI.Xaml.Controls.WebView2 sender, Microsoft.UI.Xaml.Controls.CoreWebView2InitializedEventArgs args)
|
private async void ChromiumInitialized(Microsoft.UI.Xaml.Controls.WebView2 sender, Microsoft.UI.Xaml.Controls.CoreWebView2InitializedEventArgs args)
|
||||||
{
|
{
|
||||||
var editorBundlePath = (await ViewModel.NativeAppService.GetQuillEditorBundlePathAsync()).Replace("full.html", string.Empty);
|
var editorBundlePath = (await ViewModel.NativeAppService.GetEditorBundlePathAsync()).Replace("editor.html", string.Empty);
|
||||||
|
|
||||||
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.example", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.editor", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
||||||
Chromium.Source = new Uri("https://app.example/full.html");
|
Chromium.Source = new Uri("https://app.editor/editor.html");
|
||||||
|
|
||||||
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
Chromium.CoreWebView2.DOMContentLoaded -= DOMLoaded;
|
||||||
Chromium.CoreWebView2.DOMContentLoaded += DOMLoaded;
|
Chromium.CoreWebView2.DOMContentLoaded += DOMLoaded;
|
||||||
|
|
||||||
Chromium.CoreWebView2.WebMessageReceived -= ScriptMessageRecieved;
|
Chromium.CoreWebView2.WebMessageReceived -= ScriptMessageReceived;
|
||||||
Chromium.CoreWebView2.WebMessageReceived += ScriptMessageRecieved;
|
Chromium.CoreWebView2.WebMessageReceived += ScriptMessageReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScriptMessageRecieved(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
|
private void ScriptMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||||
{
|
{
|
||||||
var change = JsonConvert.DeserializeObject<string>(args.WebMessageAsJson);
|
var change = JsonConvert.DeserializeObject<WebViewMessage>(args.WebMessageAsJson);
|
||||||
|
|
||||||
bool isEnabled = change.EndsWith("ql-active");
|
if (change.type == "bold")
|
||||||
|
|
||||||
if (change.StartsWith("ql-bold"))
|
|
||||||
BoldButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-italic"))
|
|
||||||
ItalicButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-underline"))
|
|
||||||
UnderlineButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-strike"))
|
|
||||||
StrokeButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("orderedListButton"))
|
|
||||||
OrderedListButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("bulletListButton"))
|
|
||||||
BulletListButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-direction"))
|
|
||||||
DirectionButton.IsChecked = isEnabled;
|
|
||||||
else if (change.StartsWith("ql-align-left"))
|
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
BoldButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 0;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-center"))
|
else if (change.type == "italic")
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
ItalicButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 1;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-right"))
|
else if (change.type == "underline")
|
||||||
{
|
{
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
UnderlineButton.IsChecked = change.value == "true";
|
||||||
AlignmentListView.SelectedIndex = 2;
|
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
|
||||||
}
|
}
|
||||||
else if (change.StartsWith("ql-align-justify"))
|
else if (change.type == "strikethrough")
|
||||||
{
|
{
|
||||||
|
StrokeButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "ol")
|
||||||
|
{
|
||||||
|
OrderedListButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "ul")
|
||||||
|
{
|
||||||
|
BulletListButton.IsChecked = change.value == "true";
|
||||||
|
}
|
||||||
|
else if (change.type == "indent")
|
||||||
|
{
|
||||||
|
IncreaseIndentButton.IsEnabled = change.value == "disabled" ? false : true;
|
||||||
|
}
|
||||||
|
else if (change.type == "outdent")
|
||||||
|
{
|
||||||
|
DecreaseIndentButton.IsEnabled = change.value == "disabled" ? false : true;
|
||||||
|
}
|
||||||
|
else if (change.type == "alignment")
|
||||||
|
{
|
||||||
|
var parsedValue = change.value switch
|
||||||
|
{
|
||||||
|
"jodit-icon_left" => 0,
|
||||||
|
"jodit-icon_center" => 1,
|
||||||
|
"jodit-icon_right" => 2,
|
||||||
|
"jodit-icon_justify" => 3,
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
AlignmentListView.SelectionChanged -= AlignmentChanged;
|
||||||
AlignmentListView.SelectedIndex = 3;
|
AlignmentListView.SelectedIndex = parsedValue;
|
||||||
AlignmentListView.SelectionChanged += AlignmentChanged;
|
AlignmentListView.SelectionChanged += AlignmentChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,14 +539,6 @@ namespace Wino.Views
|
|||||||
await RenderInternalAsync(message.RenderModel.RenderHtml);
|
await RenderInternalAsync(message.RenderModel.RenderHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void HyperlinkAddClicked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
await InvokeScriptSafeAsync($"addHyperlink('{LinkUrlTextBox.Text}')");
|
|
||||||
|
|
||||||
LinkUrlTextBox.Text = string.Empty;
|
|
||||||
HyperlinkFlyout.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BarDynamicOverflowChanging(CommandBar sender, DynamicOverflowItemsChangingEventArgs args)
|
private void BarDynamicOverflowChanging(CommandBar sender, DynamicOverflowItemsChangingEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Action == CommandBarDynamicOverflowAction.AddingToOverflow)
|
if (args.Action == CommandBarDynamicOverflowAction.AddingToOverflow)
|
||||||
|
|||||||
@@ -371,7 +371,7 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Background="{ThemeResource WinoContentZoneBackgroud}"
|
Background="{ThemeResource WinoContentZoneBackgroud}"
|
||||||
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
||||||
BorderThickness="0"
|
BorderThickness="1"
|
||||||
CornerRadius="7">
|
CornerRadius="7">
|
||||||
<Grid Margin="1" CornerRadius="7">
|
<Grid Margin="1" CornerRadius="7">
|
||||||
<Grid Background="White" Visibility="{x:Bind IsDarkEditor, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
<Grid Background="White" Visibility="{x:Bind IsDarkEditor, Converter={StaticResource ReverseBooleanToVisibilityConverter}, Mode=OneWay}" />
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ namespace Wino.Views
|
|||||||
{
|
{
|
||||||
if (Chromium.CoreWebView2 == null) return;
|
if (Chromium.CoreWebView2 == null) return;
|
||||||
|
|
||||||
var editorBundlePath = (await ViewModel.NativeAppService.GetQuillEditorBundlePathAsync()).Replace("full.html", string.Empty);
|
var editorBundlePath = (await ViewModel.NativeAppService.GetEditorBundlePathAsync()).Replace("editor.html", string.Empty);
|
||||||
|
|
||||||
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.reader", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
Chromium.CoreWebView2.SetVirtualHostNameToFolderMapping("app.reader", editorBundlePath, CoreWebView2HostResourceAccessKind.Allow);
|
||||||
|
|
||||||
|
|||||||
@@ -754,22 +754,14 @@
|
|||||||
<Content Include="BackgroundImages\Mica.jpg" />
|
<Content Include="BackgroundImages\Mica.jpg" />
|
||||||
<Content Include="BackgroundImages\Nighty.jpg" />
|
<Content Include="BackgroundImages\Nighty.jpg" />
|
||||||
<Content Include="BackgroundImages\Snowflake.jpg" />
|
<Content Include="BackgroundImages\Snowflake.jpg" />
|
||||||
<Content Include="JS\Quill\darkreader.js" />
|
<Content Include="JS\libs\darkreader.js" />
|
||||||
<Content Include="JS\Quill\full.html" />
|
<Content Include="JS\editor.html" />
|
||||||
<Content Include="JS\Quill\global.css" />
|
<Content Include="JS\editor.js" />
|
||||||
<Content Include="JS\Quill\highlight.min.js" />
|
<Content Include="JS\global.css" />
|
||||||
<Content Include="JS\Quill\image-resize.min.js" />
|
|
||||||
<Content Include="JS\Quill\katex.min.css" />
|
|
||||||
<Content Include="JS\Quill\katex.min.js" />
|
|
||||||
<Content Include="JS\Quill\monokai-sublime.min.css" />
|
|
||||||
<Content Include="JS\Quill\quill.core.css" />
|
|
||||||
<Content Include="JS\Quill\quill.core.js" />
|
|
||||||
<Content Include="JS\Quill\quill.js" />
|
|
||||||
<Content Include="JS\Quill\quill.min.js" />
|
|
||||||
<Content Include="JS\Quill\quill.snow.css" />
|
|
||||||
<Content Include="Assets\WinoIcons.ttf" />
|
<Content Include="Assets\WinoIcons.ttf" />
|
||||||
<Content Include="JS\Quill\reader.css" />
|
<Content Include="JS\libs\jodit.min.css" />
|
||||||
<Content Include="JS\Quill\reader.html" />
|
<Content Include="JS\libs\jodit.min.js" />
|
||||||
|
<Content Include="JS\reader.html" />
|
||||||
<Content Include="Assets\ReleaseNotes\172.md" />
|
<Content Include="Assets\ReleaseNotes\172.md" />
|
||||||
<None Include="Package.StoreAssociation.xml" />
|
<None Include="Package.StoreAssociation.xml" />
|
||||||
<Content Include="Properties\Default.rd.xml" />
|
<Content Include="Properties\Default.rd.xml" />
|
||||||
@@ -782,7 +774,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Assets\Thumbnails\uber.com.png" />
|
<Content Include="Assets\Thumbnails\uber.com.png" />
|
||||||
<None Include="JS\Quill\quill.min.js.map" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="App.xaml">
|
<ApplicationDefinition Include="App.xaml">
|
||||||
@@ -817,9 +808,7 @@
|
|||||||
<Name>Windows Desktop Extensions for the UWP</Name>
|
<Name>Windows Desktop Extensions for the UWP</Name>
|
||||||
</SDKReference>
|
</SDKReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="JS\Quill\Fonts\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -895,4 +884,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user