You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
5.9 KiB
164 lines
5.9 KiB
using Monaco.Helpers; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Diagnostics; |
|
using System.Linq; |
|
using System.Text; |
|
using System.Threading.Tasks; |
|
using System.Reflection; |
|
using Windows.Foundation; |
|
using Windows.UI.Xaml; |
|
using Windows.UI.Xaml.Controls; |
|
using Windows.UI.Xaml.Input; |
|
|
|
namespace Monaco |
|
{ |
|
public partial class CodeEditor |
|
{ |
|
// Override default Loaded/Loading event so we can make sure we've initialized our WebView contents with the CodeEditor. |
|
|
|
/// <summary> |
|
/// When Editor is Loading, it is ready to receive commands to the Monaco Engine. |
|
/// </summary> |
|
public new event RoutedEventHandler Loading; |
|
|
|
/// <summary> |
|
/// When Editor is Loaded, it has been rendered and is ready to be displayed. |
|
/// </summary> |
|
public new event RoutedEventHandler Loaded; |
|
|
|
/// <summary> |
|
/// Called when a link is Ctrl+Clicked on in the editor, set Handled to true to prevent opening. |
|
/// </summary> |
|
public event TypedEventHandler<WebView, WebViewNewWindowRequestedEventArgs> OpenLinkRequested; |
|
|
|
/// <summary> |
|
/// Called when an internal exception is encountered while executing a command. (for testing/reporting issues) |
|
/// </summary> |
|
public event TypedEventHandler<CodeEditor, Exception> InternalException; |
|
|
|
/// <summary> |
|
/// Custom Keyboard Handler. |
|
/// </summary> |
|
public new event WebKeyEventHandler KeyDown; |
|
|
|
private ThemeListener _themeListener; |
|
|
|
private void WebView_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args) |
|
{ |
|
#if DEBUG |
|
Debug.WriteLine("DOM Content Loaded"); |
|
#endif |
|
this._initialized = true; |
|
} |
|
|
|
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args) |
|
{ |
|
this.IsLoaded = true; |
|
|
|
// Make sure inner editor is focused |
|
await SendScriptAsync("editor.focus();"); |
|
|
|
// If we're supposed to have focus, make sure we try and refocus on our now loaded webview. |
|
if (FocusManager.GetFocusedElement() == this) |
|
{ |
|
this._view.Focus(FocusState.Programmatic); |
|
} |
|
|
|
Loaded?.Invoke(this, new RoutedEventArgs()); |
|
} |
|
|
|
internal ParentAccessor _parentAccessor; |
|
private KeyboardListener _keyboardListener; |
|
private long _themeToken; |
|
|
|
private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) |
|
{ |
|
#if DEBUG |
|
Debug.WriteLine("Navigation Starting"); |
|
#endif |
|
_parentAccessor = new ParentAccessor(this); |
|
_parentAccessor.AddAssemblyForTypeLookup(typeof(Range).GetTypeInfo().Assembly); |
|
_parentAccessor.RegisterAction("Loaded", CodeEditorLoaded); |
|
|
|
_themeListener = new ThemeListener(); |
|
_themeListener.ThemeChanged += _themeListener_ThemeChanged; |
|
_themeToken = RegisterPropertyChangedCallback(RequestedThemeProperty, RequestedTheme_PropertyChanged); |
|
|
|
_keyboardListener = new KeyboardListener(this); |
|
|
|
this._view.AddWebAllowedObject("Debug", new DebugLogger()); |
|
this._view.AddWebAllowedObject("Parent", _parentAccessor); |
|
this._view.AddWebAllowedObject("Theme", _themeListener); |
|
this._view.AddWebAllowedObject("Keyboard", _keyboardListener); |
|
} |
|
|
|
private async void CodeEditorLoaded() |
|
{ |
|
if (Decorations != null && Decorations.Count > 0) |
|
{ |
|
// Need to retrigger highlights after load if they were set before load. |
|
await DeltaDecorationsHelperAsync(Decorations.ToArray()); |
|
} |
|
|
|
// Now we're done loading |
|
Loading?.Invoke(this, new RoutedEventArgs()); |
|
} |
|
|
|
private void WebView_NewWindowRequested(WebView sender, WebViewNewWindowRequestedEventArgs args) |
|
{ |
|
// TODO: Should probably create own event args here as we don't want to expose the referrer to our internal page? |
|
OpenLinkRequested?.Invoke(sender, args); |
|
} |
|
|
|
private async void RequestedTheme_PropertyChanged(DependencyObject obj, DependencyProperty property) |
|
{ |
|
var editor = obj as CodeEditor; |
|
var theme = editor.RequestedTheme; |
|
var tstr = string.Empty; |
|
|
|
if (theme == ElementTheme.Default) |
|
{ |
|
tstr = _themeListener.CurrentThemeName; |
|
} |
|
else |
|
{ |
|
tstr = theme.ToString(); |
|
} |
|
|
|
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => |
|
{ |
|
await this.InvokeScriptAsync("changeTheme", new string[] { tstr, _themeListener.IsHighContrast.ToString() }); |
|
}); |
|
} |
|
|
|
private async void _themeListener_ThemeChanged(ThemeListener sender) |
|
{ |
|
if (RequestedTheme == ElementTheme.Default) |
|
{ |
|
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => |
|
{ |
|
await this.InvokeScriptAsync("changeTheme", args: new string[] { sender.CurrentTheme.ToString(), sender.IsHighContrast.ToString() }); |
|
}); |
|
} |
|
} |
|
|
|
internal bool TriggerKeyDown(WebKeyEventArgs args) |
|
{ |
|
this.KeyDown?.Invoke(this, args); |
|
|
|
return args.Handled; |
|
} |
|
|
|
protected override void OnGotFocus(RoutedEventArgs e) |
|
{ |
|
base.OnGotFocus(e); |
|
|
|
if (this._view != null && FocusManager.GetFocusedElement() == this) |
|
{ |
|
// Forward Focus onto our inner WebView |
|
this._view.Focus(FocusState.Programmatic); |
|
} |
|
} |
|
} |
|
}
|
|
|