diff --git a/Ooui/Body.cs b/Ooui/Body.cs new file mode 100644 index 0000000..80b9a86 --- /dev/null +++ b/Ooui/Body.cs @@ -0,0 +1,13 @@ +using System; + +namespace Ooui +{ + public class Body : Element + { + public Body () + : base ("Body") + { + Id = "document.body"; + } + } +} diff --git a/Ooui/Document.cs b/Ooui/Document.cs new file mode 100644 index 0000000..0ce4df3 --- /dev/null +++ b/Ooui/Document.cs @@ -0,0 +1,23 @@ +using System; + +namespace Ooui +{ + public class Document : EventTarget + { + public Window Window { get; } = new Window (); + public Body Body { get; } = new Body (); + + public Document () + : base ("document") + { + Id = "document"; + Window.MessageSent += Proxy_MessageSent; + Body.MessageSent += Proxy_MessageSent; + } + + void Proxy_MessageSent (Message message) + { + Send (message); + } + } +} diff --git a/Ooui/Element.cs b/Ooui/Element.cs index 5e21649..2e066f0 100644 --- a/Ooui/Element.cs +++ b/Ooui/Element.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Threading; namespace Ooui { @@ -8,6 +9,8 @@ namespace Ooui { readonly Dictionary attributes = new Dictionary (); + Document document = null; + public string ClassName { get => GetStringAttribute ("class", ""); set => SetAttributeProperty ("class", value); @@ -90,6 +93,17 @@ namespace Ooui remove => RemoveEventListener ("wheel", value); } + public Document Document { + get { + if (document == null) { + if (Interlocked.CompareExchange (ref document, new Document (), null) == null) { + document.MessageSent += Document_MessageSent; + } + } + return document; + } + } + /// /// A signal to Ooui that this element should take up the /// entire browser window. @@ -229,6 +243,11 @@ namespace Ooui SendSet ("style." + Style.GetJsName (e.PropertyName), Style[e.PropertyName]); } + void Document_MessageSent (Message message) + { + Send (message); + } + protected virtual bool HtmlNeedsFullEndElement => false; #if !NO_XML diff --git a/Ooui/EventTarget.cs b/Ooui/EventTarget.cs index f13a255..84ee2f0 100644 --- a/Ooui/EventTarget.cs +++ b/Ooui/EventTarget.cs @@ -13,7 +13,7 @@ namespace Ooui readonly Dictionary> eventListeners = new Dictionary> (); - public string Id { get; private set; } = GenerateId (); + public string Id { get; protected set; } = GenerateId (); public string TagName { get; private set; } diff --git a/Ooui/Window.cs b/Ooui/Window.cs new file mode 100644 index 0000000..7a25879 --- /dev/null +++ b/Ooui/Window.cs @@ -0,0 +1,24 @@ +namespace Ooui +{ + public class Window : EventTarget + { + string location = ""; + + public string Location { + get => location; + set { + if (string.IsNullOrEmpty (value) || location == value) + return; + location = value; + Send (Message.Set ("window", "location", value)); + OnPropertyChanged ("Location"); + } + } + + public Window () + : base ("window") + { + Id = "window"; + } + } +} diff --git a/Tests/WindowTests.cs b/Tests/WindowTests.cs new file mode 100644 index 0000000..2da4624 --- /dev/null +++ b/Tests/WindowTests.cs @@ -0,0 +1,93 @@ +using System; + +#if NUNIT +using NUnit.Framework; +using TestClassAttribute = NUnit.Framework.TestFixtureAttribute; +using TestMethodAttribute = NUnit.Framework.TestCaseAttribute; +#else +using Microsoft.VisualStudio.TestTools.UnitTesting; +#endif + +using Ooui; + +namespace Tests +{ + [TestClass] + public class WindowTests + { + [TestMethod] + public void ElementDocumentNotNull () + { + var b = new Button (); + Assert.IsNotNull (b.Document); + } + + [TestMethod] + public void DocumentWindowNotNull () + { + var d = new Document (); + Assert.IsNotNull (d.Window); + } + + [TestMethod] + public void DocumentBodyNotNull () + { + var d = new Document (); + Assert.IsNotNull (d.Body); + } + + [TestMethod] + public void WindowIdIsWindow () + { + Assert.AreEqual ("window", new Window ().Id); + } + + [TestMethod] + public void DocumentIdIsDocument () + { + Assert.AreEqual ("document", new Document ().Id); + } + + [TestMethod] + public void BodyIdIsDocumentBody () + { + Assert.AreEqual ("document.body", new Body ().Id); + } + + [TestMethod] + public void DocumentGetsWindowMessages () + { + var d = new Document (); + var received = false; + d.MessageSent += m => { + received = m.TargetId == "window"; + }; + d.Window.Location = "http://google.com"; + Assert.IsTrue (received); + } + + [TestMethod] + public void ElementGetsWindowMessages () + { + var b = new Button (); + var received = false; + b.MessageSent += m => { + received = m.TargetId == "window"; + }; + b.Document.Window.Location = "http://google.com"; + Assert.IsTrue (received); + } + + [TestMethod] + public void ElementGetsBodyMessages () + { + var b = new Button (); + var received = false; + b.MessageSent += m => { + received = m.TargetId == "document.body"; + }; + b.Document.Body.Call ("foo"); + Assert.IsTrue (received); + } + } +}