From 15b0dfe15bcbd3a474f2ceee22c9bc3f3f42c4f3 Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Mon, 23 Nov 2020 20:22:16 +0100 Subject: [PATCH] More experimenting with web text box --- .gitignore | 1 + src/ui/Controls/SETextBox.cs | 2 +- .../Controls/WebBrowser/WebBrowserEditBox.cs | 131 +++++++++++++++++- .../WebBrowser/WebBrowserEditBox.html | 25 +++- 4 files changed, 151 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 4f0745fc5..d48672da5 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ SubtitleEditBeta /src/ui/packages /src/ui/ILRepack* /src/ui/NHunspell* +/build_beta.bat diff --git a/src/ui/Controls/SETextBox.cs b/src/ui/Controls/SETextBox.cs index f087f70ae..e21d9e634 100644 --- a/src/ui/Controls/SETextBox.cs +++ b/src/ui/Controls/SETextBox.cs @@ -1193,7 +1193,7 @@ namespace Nikse.SubtitleEdit.Controls Color c; if (color.StartsWith("rgb(", StringComparison.Ordinal)) { - string[] arr = color.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + var arr = color.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2])); } else diff --git a/src/ui/Controls/WebBrowser/WebBrowserEditBox.cs b/src/ui/Controls/WebBrowser/WebBrowserEditBox.cs index d225a8d5f..1a4c7954a 100644 --- a/src/ui/Controls/WebBrowser/WebBrowserEditBox.cs +++ b/src/ui/Controls/WebBrowser/WebBrowserEditBox.cs @@ -2,6 +2,7 @@ using System; using System.Drawing; using System.IO; +using System.Net; using System.Reflection; using System.Text; using System.Threading; @@ -41,10 +42,22 @@ namespace Nikse.SubtitleEdit.Controls.WebBrowser var assembly = Assembly.GetExecutingAssembly(); BringToFront(); + LoadHtml(assembly); + + IsWebBrowserContextMenuEnabled = false; + AllowWebBrowserDrop = false; + ObjectForScripting = this; + } + + private void LoadHtml(Assembly assembly) + { using (var stream = assembly.GetManifestResourceStream("Nikse.SubtitleEdit.Controls.WebBrowser.WebBrowserEditBox.html")) using (var reader = new StreamReader(stream)) { var s = reader.ReadToEnd(); + s = s.Replace("color: brown;", "color: " + ColorTranslator.ToHtml(Configuration.Settings.General.SubtitleFontColor) + ";"); + s = s.Replace("background-color: lightblue;", "background-color: " + ColorTranslator.ToHtml(Configuration.Settings.General.SubtitleBackgroundColor) + ";"); + DocumentText = s; } @@ -56,10 +69,6 @@ namespace Nikse.SubtitleEdit.Controls.WebBrowser Application.DoEvents(); Thread.Sleep(5); } - - IsWebBrowserContextMenuEnabled = false; - AllowWebBrowserDrop = false; - ObjectForScripting = this; } public override string Text @@ -124,7 +133,8 @@ namespace Nikse.SubtitleEdit.Controls.WebBrowser Document.InvokeScript("setTextDirection", new object[] { align, dir }); } - Document.InvokeScript("setText", new object[] { value }); + UpdateSyntaxColor(value); + //Document.InvokeScript("setText", new object[] { value }); } } } @@ -333,5 +343,116 @@ namespace Nikse.SubtitleEdit.Controls.WebBrowser public void ClearUndo() { } + + private string _lastHtml = null; + + public void UpdateSyntaxColor(string text) + { + var html = HighLightHtml(text); + if (html.Contains("\n")) + { + html = html.Replace("\r\n\r\n", "
"); + html = html.Replace("\r\n", "
"); + html = html.Replace("\n", "
"); + } + + if (html != _lastHtml && Document != null) + { + Document.InvokeScript("setHtml", new object[] { html }); + _lastHtml = html; + } + } + + public string HighLightHtml(string text) + { + if (text == null) + { + return string.Empty; + } + + bool htmlTagOn = false; + bool htmlTagFontOn = false; + int htmlTagStart = -1; + bool assaTagOn = false; + bool assaPrimaryColorTagOn = false; + bool assaSecondaryColorTagOn = false; + bool assaBorderColorTagOn = false; + bool assaShadowColorTagOn = false; + var assaTagStart = -1; + int tagOn = -1; + var textLength = text.Length; + int i = 0; + var sb = new StringBuilder(); + + while (i < textLength) + { + var ch = text[i]; + if (assaTagOn) + { + if (ch == '}' && tagOn >= 0) + { + assaTagOn = false; + sb.Append($""); + var inner = text.Substring(assaTagStart, i - assaTagStart + 1); + sb.Append(WebUtility.HtmlEncode(inner)); + sb.Append(""); + assaTagStart = -1; + } + } + else if (htmlTagOn) + { + if (ch == '>' && tagOn >= 0) + { + htmlTagOn = false; + sb.Append($""); + var inner = text.Substring(htmlTagStart, i - htmlTagStart + 1); + sb.Append(WebUtility.HtmlEncode(inner)); + sb.Append(""); + htmlTagStart = -1; + } + } + else if (ch == '{' && i < textLength - 1 && text[i + 1] == '\\' && text.IndexOf('}', i) > 0) + { + var s = text.Substring(i); + assaTagOn = true; + tagOn = i; + assaTagStart = i; + } + else if (ch == '<') + { + var s = text.Substring(i); + if (s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + s.StartsWith("", StringComparison.OrdinalIgnoreCase) || + (s.StartsWith("", i, StringComparison.OrdinalIgnoreCase) > 0)) + { + htmlTagOn = true; + htmlTagStart = i; + htmlTagFontOn = s.StartsWith(" 100) { + window.external.UpdateSyntaxColor(getById("myContent").innerText); + } + }, 150); + millisecondsLastActivity = Date.now(); + } + function initEvents() { getById("myContent").addEventListener("focus", function (e) { window.external.ClientFocus(); @@ -82,10 +94,12 @@ getById("myContent").addEventListener("keyup", function (e) { window.external.ClientKeyUp(e.keyCode, e.ctrlKey, e.shiftKey, e.altKey); + syntaxColorIfNotActive(); }); getById("myContent").addEventListener("click", function (e) { window.external.ClientClick(); + syntaxColorIfNotActive(); }); getById("myContent").addEventListener("mousemove", function (e) { @@ -149,7 +163,8 @@ idx += 2; } else if (node.nodeType === 3) { // #text if (node.nodeValue.indexOf("\n") >= 0) { - getById("div1").innerText = getById("div1").innerText + "\ntext with new-line found!"; + //ext with new-line found!"; + idx += node.length; } else { idx += node.length; } @@ -299,6 +314,12 @@ document.getElementById("myContent").setAttribute('class', 'disabled'); } } + + function setHtml(newHtml) { + var r = getCursorPosition(); + document.getElementById("myContent").innerHTML = newHtml; + setCursorPosition(r); + } \ No newline at end of file