Add Initialization for Content/CodeType Property (to change)
Add MIT License File
This commit is contained in:
groot 2017-07-22 23:01:23 -07:00
Родитель c58497fd55
Коммит 4c9a03408e
12 изменённых файлов: 319 добавлений и 20 удалений

7
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,7 @@
Copyright 2017 Michael A. Hawker
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Просмотреть файл

@ -1,23 +1,37 @@
using Monaco.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Monaco
{
public partial class EditorComponent
{
// Override default Loaded event so we can make sure we've initialized our WebView contents with the Editor.
public new event RoutedEventHandler Loaded;
private void WebView_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
Debug.WriteLine("DOM Content Loaded");
this._initialized = true;
}
private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
Debug.WriteLine("Navigation Starting");
var parent = new ParentAccessor(this);
parent.RegisterAction("Loaded", () =>
{
Loaded?.Invoke(this, new RoutedEventArgs());
});
this._view.AddWebAllowedObject("Debug", new DebugLogger());
this._view.AddWebAllowedObject("Parent", parent);
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
namespace Monaco
{
partial class EditorComponent
{
public string Content
{
get { return (string)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
// Using a DependencyProperty as the backing store for HorizontalLayout. This enables animation, styling, binding, etc...
private static readonly DependencyProperty ContentPropertyField =
DependencyProperty.Register("Content", typeof(string), typeof(EditorComponent), new PropertyMetadata("", (d, e) => {
//(d as Canvas)?.InvokeScriptAsync("updateToolbox", new string[] { e.NewValue.ToString() });
//(d as EditorComponent).CodeChanged?.Invoke(d, e);
}));
internal static DependencyProperty ContentProperty
{
get
{
return ContentPropertyField;
}
}
public string CodeLanguage
{
get { return (string)GetValue(CodeLanguageProperty); }
set { SetValue(CodeLanguageProperty, value); }
}
// Using a DependencyProperty as the backing store for HorizontalLayout. This enables animation, styling, binding, etc...
private static readonly DependencyProperty CodeLanguagePropertyField =
DependencyProperty.Register("CodeLanguage", typeof(string), typeof(EditorComponent), new PropertyMetadata("csharp", (d, e) => {
//(d as Canvas)?.InvokeScriptAsync("updateToolbox", new string[] { e.NewValue.ToString() });
//(d as EditorComponent).CodeChanged?.Invoke(d, e);
}));
internal static DependencyProperty CodeLanguageProperty
{
get
{
return CodeLanguagePropertyField;
}
}
}
}

Просмотреть файл

@ -1,14 +1,8 @@
using Monaco.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235
@ -45,5 +39,25 @@ namespace Monaco
base.OnApplyTemplate();
}
internal async Task<string> SendScriptAsync(string script)
{
if (_initialized)
{
return await this._view.InvokeScriptAsync("eval", new string[] { script });
}
return string.Empty;
}
internal async Task<string> InvokeScriptAsync(string method, params string[] args)
{
if (_initialized)
{
return await this._view.InvokeScriptAsync(method, args);
}
return string.Empty;
}
}
}

Просмотреть файл

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Windows.Foundation.Metadata;
namespace Monaco.Helpers
{
/// <summary>
/// Class to aid in accessing WinRT values from JavaScript.
/// </summary>
[AllowForWeb]
public sealed class ParentAccessor
{
private object parent;
private TypeInfo typeinfo;
private Dictionary<string, Action> actions;
/// <summary>
/// Constructs a new reflective parent Accessor for the provided object.
/// </summary>
/// <param name="parent">Object to provide Property Access.</param>
public ParentAccessor(object parent)
{
this.parent = parent;
this.typeinfo = parent.GetType().GetTypeInfo();
this.actions = new Dictionary<string, Action>();
}
/// <summary>
/// Registers an action from the .NET side which can be called from within the JavaScript code.
/// </summary>
/// <param name="name">String Key.</param>
/// <param name="action">Action to perform.</param>
internal void RegisterAction(string name, Action action)
{
actions[name] = action;
}
/// <summary>
/// Calls an Action registered before with <see cref="RegisterAction(string, Action)"/>.
/// </summary>
/// <param name="name">String Key.</param>
/// <returns>True if method was found in registration.</returns>
public bool CallAction(string name)
{
if (actions.ContainsKey(name))
{
actions[name].Invoke();
return true;
}
return false;
}
/// <summary>
/// Returns the winrt primative object value for the specified Property.
/// </summary>
/// <param name="name">Property name on Parent Object.</param>
/// <returns>Property Value or null.</returns>
public object GetValue(string name)
{
var propinfo = typeinfo.GetDeclaredProperty(name);
return propinfo?.GetValue(this.parent);
}
/// <summary>
/// Returns the winrt primative object value for a child property off of the specified Property.
///
/// Useful for providing complex types to users of Parent but still access primatives in JavaScript.
/// </summary>
/// <param name="name">Parent Property name.</param>
/// <param name="child">Property's Property name to retrieve.</param>
/// <returns>Value of Child Property or null.</returns>
public object GetChildValue(string name, string child)
{
var propinfo = typeinfo.GetDeclaredProperty(name);
var prop = propinfo?.GetValue(this.parent);
if (prop != null)
{
var childinfo = prop.GetType().GetTypeInfo().GetDeclaredProperty(child);
return childinfo?.GetValue(prop);
}
return null;
}
/// <summary>
/// Sets the value for the specified Property.
/// </summary>
/// <param name="name">Parent Property name.</param>
/// <param name="value">Value to set.</param>
public void SetValue(string name, object value)
{
var propinfo = typeinfo.GetDeclaredProperty(name); // TODO: Cache these?
propinfo?.SetValue(this.parent, value);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Json;
namespace Monaco.Languages
{
/// <summary>
/// Object Parser for https://microsoft.github.io/monaco-editor/api/interfaces/monaco.languages.ilanguageextensionpoint.html
/// </summary>
public sealed class ILanguageExtensionPoint
{
public string Id { get; private set; }
public string[] Aliases { get; private set; }
public string Configuration { get; private set; }
public string[] Extensions { get; private set; }
public string[] Filenames { get; private set; }
public string[] FilenamePatterns { get; private set; }
public string FirstLine { get; private set; }
public string[] Mimetypes { get; private set; }
public static ILanguageExtensionPoint Create(IJsonValue languageValue)
{
ILanguageExtensionPoint language = new ILanguageExtensionPoint();
var jsonObject = languageValue.GetObject();
language.Id = jsonObject.GetNamedString("id");
language.Aliases = jsonObject.GetNamedArray("aliases", new JsonArray()).Select(value => value.GetString()).ToArray();
if (jsonObject.ContainsKey("configuration"))
{
language.Configuration = jsonObject.GetNamedString("configuration", string.Empty);
}
language.Extensions = jsonObject.GetNamedArray("extensions", new JsonArray()).Select(value => value.GetString()).ToArray();
language.Filenames = jsonObject.GetNamedArray("filenames", new JsonArray()).Select(value => value.GetString()).ToArray();
language.FilenamePatterns = jsonObject.GetNamedArray("filenamePatterns", new JsonArray()).Select(value => value.GetString()).ToArray();
if (jsonObject.ContainsKey("firstLine"))
{
language.FirstLine = jsonObject.GetNamedString("firstLine", string.Empty);
}
language.Mimetypes = jsonObject.GetNamedArray("mimetypes", new JsonArray()).Select(value => value.GetString()).ToArray();
return language;
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
using Monaco.Languages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.Foundation;
namespace Monaco
{
/// <summary>
/// Helper to static Monaco.Languages Namespace methods.
/// https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html
/// </summary>
public sealed class LanguagesHelper
{
private EditorComponent editor;
public LanguagesHelper(EditorComponent editor)
{
// We need the editor component in order to execute JavaScript within
// the WebView environment to retrieve data (even though this Monaco class is static).
this.editor = editor;
}
public IAsyncOperation<IList<ILanguageExtensionPoint>> GetLanguagesAsync()
{
var json = editor.SendScriptAsync("JSON.stringify(monaco.languages.getLanguages())");
return json.ContinueWith((result) =>
{
var jsonlanguages = JsonArray.Parse(result.Result);
IList<ILanguageExtensionPoint> languages = new List<ILanguageExtensionPoint>(jsonlanguages.Count);
for (int i = 0; i < jsonlanguages.Count; i++)
{
languages.Add(ILanguageExtensionPoint.Create(jsonlanguages[i]));
}
return languages;
}).AsAsyncOperation();
}
}
}

Просмотреть файл

@ -26,14 +26,14 @@
require.config({ paths: { 'vs': 'ms-appx-web:///Monaco/monaco-editor/dev/vs' }});
require(['vs/editor/editor.main'], function() {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'javascript'
});
});
value: Parent.getValue("Content"), // TODO: Move to IModel.Value?
language: Parent.getValue("CodeLanguage") // TODO: Move to an IEditorOptions
});
// Callback to Parent that we're loaded
Debug.log("Loaded Monaco");
Parent.callAction("Loaded");
});
</script>
</body>
</html>

Просмотреть файл

@ -108,7 +108,11 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="EditorComponent.cs" />
<Compile Include="EditorComponent.Properties.cs" />
<Compile Include="Helpers\DebugLogger.cs" />
<Compile Include="Helpers\ParentAccessor.cs" />
<Compile Include="Monaco\Languages\ILanguageExtensionPoint.cs" />
<Compile Include="Monaco\LanguagesHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -9,6 +9,7 @@
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<monaco:EditorComponent></monaco:EditorComponent>
<monaco:EditorComponent x:Name="Editor">
</monaco:EditorComponent>
</Grid>
</Page>

Просмотреть файл

@ -25,6 +25,16 @@ namespace MonacoEditorTestApp
public MainPage()
{
this.InitializeComponent();
Editor.Content = "public class Program {\n\tpublic static void Main(string[] args) {\n\t\tConsole.WriteLine(\"Hello, World!\");\n\t}\n}";
Editor.Loaded += Editor_Loaded;
}
private async void Editor_Loaded(object sender, RoutedEventArgs e)
{
var languages = await new Monaco.LanguagesHelper(Editor).GetLanguagesAsync();
}
}
}

Просмотреть файл

@ -1,9 +1,15 @@
Monaco Editor UWP
=================
A Windows Runtime Component Wrapper around the Web-based [Monaco Editor](https://microsoft.github.io/monaco-editor/). This allows the Monaco Editor to be more easily comsumed directly in XAML for C#/C++ UWP based projects.
A *Windows Runtime Component* wrapper around the web-based [Monaco Editor](https://microsoft.github.io/monaco-editor/). This allows the Monaco Editor to be more easily consumed directly in XAML for C#/C++ UWP based projects.
This project is not affiliated with the Monaco team and is provided for convenience. Please direct issues related to the use of this control wrapper to this repository.
Build Notes
-----------
Built using Visual Studio 2017 for Windows 10 14393 and above.
The **released** complete Monaco build is used as a reference, this is not included in this repository and can be downloaded from the [Monaco site](https://microsoft.github.io/monaco-editor/). The contents of its uncompressed 'package' directory should be placed in the *MonacoEditorComponent/monaco-editor* directory.
The **released** complete Monaco build is used as a reference, this is not included in this repository and can be downloaded from the [Monaco site](https://microsoft.github.io/monaco-editor/). The contents of its uncompressed 'package' directory should be placed in the *MonacoEditorComponent/monaco-editor* directory.
License
-------
MIT