From 617b7e38e798be785f781b5163e931a58ad686af Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Thu, 9 Feb 2012 22:22:42 -0500 Subject: [PATCH] observer events --- dom.d | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/dom.d b/dom.d index bd93f51..210ba00 100644 --- a/dom.d +++ b/dom.d @@ -137,6 +137,8 @@ struct ElementStyle { _attribute ~= k ~ ": " ~ v ~ ";"; } + _element.setAttribute("style", _attribute); // this is to trigger the observer call + return value; } string get(string name) const { @@ -187,6 +189,20 @@ body { /// This represents almost everything in the DOM. class Element { + // this is a thing so i can remove observer support if it gets slow + // I have not implemented all these yet + private void sendObserverEvent(DomMutationOperations operation, string s1 = null, string s2 = null, Element r = null, Element r2 = null) { + if(parentDocument is null) return; + DomMutationEvent me; + me.operation = operation; + me.target = this; + me.relatedString = s1; + me.relatedString2 = s2; + me.related = r; + me.related2 = r2; + parentDocument.dispatchMutationEvent(me); + } + // putting all the members up front // this ought to be private. don't use it directly. @@ -330,6 +346,9 @@ class Element { if(_attributes !is null) attributes = _attributes; selfClosed = _selfClosed; + + version(dom_node_indexes) + this.dataset.nodeIndex = to!string(&(this.attributes)); } /// Convenience constructor when you don't care about the parentDocument. Note this might break things on the document. @@ -343,10 +362,16 @@ class Element { // this is meant to reserve some memory. It makes a small, but consistent improvement. //children.length = 8; //children.length = 0; + + version(dom_node_indexes) + this.dataset.nodeIndex = to!string(&(this.attributes)); } private this(Document _parentDocument) { parentDocument = _parentDocument; + + version(dom_node_indexes) + this.dataset.nodeIndex = to!string(&(this.attributes)); } @@ -609,6 +634,8 @@ class Element { attributes[name] = value; + sendObserverEvent(DomMutationOperations.setAttribute, name, value); + return this; } @@ -633,6 +660,8 @@ class Element { name = name.toLower(); if(name in attributes) attributes.remove(name); + + sendObserverEvent(DomMutationOperations.removeAttribute, name); } /** @@ -964,6 +993,9 @@ class Element { e.parentNode = this; e.parentDocument = this.parentDocument; children ~= e; + + sendObserverEvent(DomMutationOperations.appendChild, null, null, e); + return e; } @@ -3026,6 +3058,10 @@ class Document : FileResource { auto e = createElement(tagName); e.attributes = attributes; + version(dom_node_indexes) { + if(e.dataset.nodeIndex.length == 0) + e.dataset.nodeIndex = to!string(&(e.attributes)); + } e.selfClosed = selfClosed; e.parseAttributes(); @@ -3401,13 +3437,48 @@ class Document : FileResource { ///. bool loose; + + + // what follows are for mutation events that you can observe + void delegate(DomMutationEvent)[] eventObservers; + + void dispatchMutationEvent(DomMutationEvent e) { + foreach(o; eventObservers) + o(e); + } } - private static string[] selfClosedElements = [ - // html 4 - "img", "hr", "input", "br", "col", "link", "meta", - // html 5 - "source" ]; +// for the observers +enum DomMutationOperations { + setAttribute, + removeAttribute, + appendChild, // tagname, attributes[], innerHTML + insertBefore, + truncateChildren, + removeChild, + appendHtml, + replaceHtml, + appendText, + replaceText, + replaceTextOnly +} + +// and for observers too +struct DomMutationEvent { + DomMutationOperations operation; + Element target; + Element related; // what this means differs with the operation + Element related2; + string relatedString; + string relatedString2; +} + + +private static string[] selfClosedElements = [ + // html 4 + "img", "hr", "input", "br", "col", "link", "meta", + // html 5 + "source" ]; static import std.conv; @@ -4599,7 +4670,7 @@ struct ElementCollection { // dom event support, if you want to use it /// used for DOM events -alias void delegate(Element, Event) EventHandler; +alias void delegate(Element handlerAttachedTo, Event event) EventHandler; /// This is a DOM event, like in javascript. Note that this library never fires events - it is only here for you to use if you want it. class Event {