Possibility of include raw?

14 views
Skip to first unread message

DeanoC

unread,
Oct 25, 2010, 2:30:52 AM10/25/10
to v8cgi
Hello,
Would it be possible to get an include that doesn't follow CommonJS
spec with regard export rules?

The reason is that many existing javascript libraries don't follow the
CommonJS specs yet and so when included, don't export anything into
the global table.

Specifically I'm implementing server side jquery (which I have working
with some patches) but currently I have to modify jquery.js which I'd
prefer not to. I have to manually add an export table to it, to export
$ into the global space, if there was a non protected include it would
solve that issue.

Also I will be sending in some patches to dom.js to support jquery use
of the DOM, do you have a perferred format and style guide for the
patches?

Thanks,
Deano

Ondřej Žára

unread,
Oct 25, 2010, 4:56:22 AM10/25/10
to v8...@googlegroups.com
Hi Deano,

v8cgi offers the "global" variable, which references the top-level global JS object (similar to "window") in browsers.

So, if your module needs to modify the global object, you can achieve this by adjusting properties of "global" variable. Generally, "var window = global" might be the only thing necessary to accomodate code written intially for client side. On the other hand, I am not aware of any method of requiring client-side code without modifying it a little bit.

As for the style/format-guide - I have no written form, but following the existing code (dom.js) might be the best practice. Generally, I follow these rules:

- semantic indentation (by tabs);
- curly braces even if only one statement is used;
- closing braces on a new line;
- opening braces *not* on a new line.

There might be more of these, but I can live with patches written in a (little bit) different style...


Sincerely,
Ondrej Zara



2010/10/25 DeanoC <dean....@gmail.com>

--
You received this message because you are subscribed to the Google Groups "v8cgi" group.
To post to this group, send email to v8...@googlegroups.com.
To unsubscribe from this group, send email to v8cgi+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/v8cgi?hl=en.


Deano

unread,
Oct 25, 2010, 10:11:04 AM10/25/10
to v8...@googlegroups.com

Hi Ondrej,

 

window = global, made include(‘FOO’) work perfectly for me on js files without an export table. Thanks for that tip.

 

Regard the DOM, its seems that most client side library require the DOM to support some features not really required by the specification, I’d like to implement them, as a part of the client compatibility mode (As a part of JS Platform I’m working to allow the server to be able to be a  ‘headless’ client), however I don’t want to pollute the DOM with things that can only be described as quirks.

 

Do you have any preference to how I should organize it?

1)      Just add non-standard things to dom.js by default.

a.       Pro : Pretty much what the browsers do, so likely to be what most programmers think of ‘correct’ dom behavior.

b.      Con : Pollutes the purity of your dom.js implementation with not always nice browser inherited behavior

2)      Make a sub-class of DOM something like QuirkyDOM, which builds via inheritance all the quirks that the browsers DOM have.

a.       Pro : Separates the quirky stuff out, whilst sharing the core DOM behavior

b.      Con : Some of the quirks are quite low level, so the master dom.js might have to be implemented with callbacks, maybe slowing down the pure DOM a bit.

3)      Add a Quirks mode to DOM, which replaces the relevant functions internal to DOM with quirky ones.

a.       Pro : Separates quirkyness out of the normal DOM but switchable at runtime and changes are internal to dom.js so can fiddle with the internals easier and make sure doesn’t cost pure DOM any overhead

b.      Con : Requires replaces functions inside DOM if (for example) DOM.EnableQuirkMode() is called, will make dom.js a bit messier

 

I personally like the 3rd option, so that default is the nice pure DOM we have now, and as it grows we are still left with a pure standard complaint DOM implementation, but a quick Quirky Mode call and then the DOM objects works enough like the browser ones to fool most client side libraries that they are running in a browser DOM implementation.

 

A couple of examples of why this is necessary, Elements like Div come into existence on the browsers with properties like style, which are expected in browser side code (e.g. jquery does createElement(‘div’); div.style.FOO = BAR;),  another is that its expected that when innerHtml is changed, that the DOM is updated to reflect the new string. Its standard practice to ‘parse’ strings into DOM just by setting innerHtml and then accessing the DOM object.

 

Thanks,

Deano

Deano

unread,
Oct 25, 2010, 11:20:27 AM10/25/10
to DeanoC, v8cgi
Hello,
Thinking a bit more about more previous email about DOM extension, I
realized I'm talking about !DOCTYPE support, so what I propose, is that I
implement a !DOCTYPE extension to the DOM module. Default is to no !DOCTYPE
so giving you the existing behavior, however you can optionally tell it to
use a DOCTYPE and then it will follow that spec.

i.e.
var doc = new DOM.Document( "XHTML1.0 Transitional" ); // adds !DOCTYPE
header to document and uses the DTD to apply defaults and behavior implied
by this doctype.
doc.createElement( 'div' ); // would now be created standard properties and
defaults.


Implementation wise, I think most flexible would be an extension system
inside DOM.Document.
e.g.
var KnownDocType[] = { "XHTML1.0 Transitional": XHTML1TranCreateFunc,
// Other doc types can go here (or more
likely adaption of the same one)
}
var Document = function( docTypeName ) {
var docType = KnownDocType[ docTypeName || "" ];
if( docType ) {
return docType()
} else
{
// use existing non doctype'd DOM document code
}
}

Then the doctype implementation can have a hash look up in createElement
that instead standard properties and attributes based on the doctype.

Can anybody see anything wrong with that, I'm quite a newbie at Javascript
even though have been a professional C++ coder for too many years, so
perhaps I'm missing some obvious no-no in Javascript land?

Thanks,
Deano


Ondřej Žára

unread,
Oct 25, 2010, 12:50:31 PM10/25/10
to v8...@googlegroups.com
Hi Dean,

from a pragmatic user's view, I see two available solutions:

a) add these features to DOM, as long as they are implemented in all browsers (innerHTML), or standardized (.style property is DOM level 2). I am not aware of any scenario where having these available (atop of DOM lvl 1) can break anything. (this point is identical to your #1 ;)

b) offering a richer "htmldom" module, which *modifies* dom.js by adding the mentioned stuff:

var dom = require("dom");
var htmldom = require("htmldom").modify(dom);

var htmlDocument = new htmldom.Document();
var div = htmlDocument.createElement("div");
div.style.color = ".....";


Currently, I am not sure about my preference, both solutions are okay for me. It would be best if you can list all the properties and features you want to add; then we can decide which approach is most suitable.

Also note that some browser-DOM features, such as .offsetWidth or .getComputedStyle(), do not make sense on server side - and it is probably illogical to try to implement them.


Ondrej






2010/10/25 Deano <dean....@gmail.com>

Ondřej Žára

unread,
Oct 25, 2010, 1:38:43 PM10/25/10
to v8...@googlegroups.com, DeanoC
Hi,

your doctype-based proposal does not sound bad, but it conflicts a bit with the current - standardized - doctype implementation in dom.js.

The DOM standard already specifies the DocumentType node, which can be created with document.createDocumentType. This adds the relevant DOCTYPE declaration to resulting XML. This behavior is already present in dom.js.

Also, there are many valid HTML doctypes (for instance: HTML5 doctype <!doctype html>) and you would probably want to add your extended behavior to all of these... generally speaking, I am not a huge fan of this approach. Instead, one of those ideas I outlined in my previous reply would be IMHO better and more consistent.

On a different note, regarding your C++ proficiency - this project can benefit from a code review from some skilled C++ coder, as my experience and skills are much higher with Javascript then with C/C++. Let me know if you have time and will to dig into my poor c++ file...


Sincerely,
Ondrej





2010/10/25 Deano <dean....@gmail.com>

Deano

unread,
Oct 25, 2010, 1:54:56 PM10/25/10
to v8...@googlegroups.com

Hi Ondrej,

 

Your Htmldom sounds like a nice solution to me, it allows for different implementation without messing up dom.js which can stay focused on pure DOM standards and not on lots if browser-DOM behaviours. Also if the user want it to become option a, they can with

 

var dom = require(“dom”)

Dom = require(“htmldom”).modify(dom);

 

It will also allow both to be live at the same time if I implement it properly, so that where necessarily the script writer has total control. If I also implement documentImplementation property correctly, a well written script can clone documents etc. safely.

 

As for when which browser-DOM features, I’m not sure… I totally agree that many make no sense. My aim is purely to provide a fairly standard complaint browser environment under v8cgi, so scripts that make sense can run headless on the server. So any that are too quirky or don’t make sense won’t be added except where specific useful client side libraries require it.

 

Thanks for the suggestion, I’ll get on with an implementation as per your suggestion, tackling the first few big items I’ve hit (innerHTML and standard properties), as a proof of concept and then it can reviewed (and my bad javascriptism  pointed out) and then worked on further as per any suggestions.

Deano

unread,
Oct 25, 2010, 1:55:40 PM10/25/10
to Ondřej Žára, v8...@googlegroups.com

Deano

unread,
Oct 25, 2010, 1:57:08 PM10/25/10
to Ondřej Žára, v8...@googlegroups.com

Yep agree, I’m going to use your htmldoc approach. And happy to give the c++ side a look over J Had a quick look and it seemed fairly readable, which tbh is usually the most important thing J

 

Thanks,

Deano

 

From: Ondřej Žára [mailto:ondre...@gmail.com]
Sent: 25 October 2010 18:39
To: v8...@googlegroups.com
Cc: DeanoC
Subject: Re: DOM DocTypes

 

Hi,

Deano

unread,
Oct 28, 2010, 4:29:34 PM10/28/10
to Ondřej Žára, v8...@googlegroups.com

Hi,

I’ve produced a working htmldom, that enabled jquery and pure client side libraries to work on v8cgi. I needed to fix a few bugs and add a few features to dom.js so here is the patch for that, a separate htmldom.js incoming soon (its actually another htmlparser file as well).

 

What it does:

Adds document fragment nodes to dom, it should be DOM level 2 compliant (main feature is that it removes itself when appending to a normal node).

Throws some more errors when passed invalid nodes in places

Fixed bug insertBefore not set the newNodes parent

Similar bug fix for replaceChild

new Element/Attribute/etc. changed to createElement/Attribute/etc.

Exports most dom.classes to allow inheritance (unfortunately can’t fine a way to have c++ style protected, so made then public outside the module)

 

Patch below,

Bye,

Deano

 

Index: dom.js

===================================================================

--- dom.js            (revision 815)

+++ dom.js         (working copy)

@@ -35,11 +35,28 @@

 Node.prototype.__defineGetter__("prefix", function() { return null; });

 

 Node.prototype.appendChild = function(node) {

+             if (!node) { throw new Error("Cannot appendChild an undefined node"); }

+             if (node.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {

+                             var childToReturn = null;

+

+                             var tmp = []

+                             for (var i = 0; i < node.childNodes.length; ++i) {

+                                             tmp.push(node.childNodes[i])

+                             }

+                             for (var i = 0; i < tmp.length; ++i) {

+                                             var child = tmp[i];

+                                             child._removeReferences();

+                                             this.childNodes.push(child);

+                                             child.parentNode = this;

+                                             child._addReferences();

+                                             childToReturn = child;

+                             }

+                             return childToReturn;

+             }

+

                node._removeReferences();

-

                this.childNodes.push(node);

                node.parentNode = this;

-

                node._addReferences();

 

                return node;

@@ -58,12 +75,31 @@

 }

 

 Node.prototype.insertBefore = function(newNode, referenceNode) {

+             if (!newNode) { throw new Error("Cannot appendChild an undefined node"); }

+

                if (!referenceNode) { return this.appendChild(newNode); }

 

                var index = this.childNodes.indexOf(referenceNode);

                if (index == -1) { throw new Error("Cannot insert before non-existent child"); }

+

+             if (node.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {

+                             var childToReturn = null;

+

+                             var tmp = []

+                             for (var i = 0; i < node.childNodes.length; ++i) {

+                                             tmp.push(node.childNodes[i])

+                             }

+                             for (var i = 0; i < tmp.length; ++i) {

+                                             var child = tmp[i];

+                                             this.insertBefore(child, referenceNode);

+                                             childToReturn = child;

+                             }

+                             return childToReturn;

+             }

+

                newNode._removeReferences();

                this.childNodes.splice(index, 0, newNode);

+             newNode.parentNode = this;

                newNode._addReferences();

                referenceNode._addReferences();

 

@@ -81,6 +117,7 @@

                oldChild._removeReferences();

                newChild._removeReferences();

                this.childNodes.splice(index, 0, newChild);

+             node.parentNode = this;

                newChild._addReferences();

               

                return newChild;

@@ -470,7 +507,7 @@

 }

 

 Document.prototype.createElementNS = function(ns, name) {

-              var elm = new Element(this, name);

+             var elm = createElement(name);

                elm.namespaceURI = ns;

                return elm;

 }

@@ -496,7 +533,7 @@

 }

 

 Document.prototype.createAttributeNS = function(ns, name) {

-              var attr = new Attr(this, name);

+             var attr = createAttribute(name);

                attr.namespaceURI = ns;

                return attr;

 }

@@ -547,6 +584,7 @@

                this._map[Node.PROCESSING_INSTRUCTION_NODE] = this._serializeProcessingInstruction;

                this._map[Node.COMMENT_NODE] = this._serializeComment;

                this._map[Node.DOCUMENT_TYPE_NODE] = this._serializeDocumentType;

+             this._map[Node.DOCUMENT_FRAGMENT_NODE] = this._serializeDocumentFragment;

 }

 

 XMLSerializer.prototype.serializeToString = function(document) {

@@ -570,6 +608,12 @@

                return str;

 }

 

+XMLSerializer.prototype._serializeDocumentFragment = function (document) {

+             var str = "";

+             str += this._serializeChildNodes(document);

+             return str;

+}

+

 XMLSerializer.prototype._serializeDocumentType = function(dt) {

                var str = "<!DOCTYPE " + dt.nodeName;

                var arr = [];

@@ -1160,3 +1204,10 @@

 exports.XMLSerializer = XMLSerializer;

 exports.DOMParser = DOMParser;

 exports.Node = Node;

+exports.Attr = Attr;

+exports.Element = Element;

+exports.CharacterData = CharacterData;

+exports.Text = Text;

+exports.CDATASection = CDATASection;

+exports.Comment = Comment;

+exports.ProcessingInstruction = ProcessingInstruction;

\ No newline at end of file

 

 

From: Ondřej Žára [mailto:ondre...@gmail.com]
Sent: 25 October 2010 18:39
To: v8...@googlegroups.com
Cc: DeanoC
Subject: Re: DOM DocTypes

 

Hi,

Deano

unread,
Oct 28, 2010, 6:45:02 PM10/28/10
to Ondřej Žára, v8...@googlegroups.com

Isn’t it always the way!, I  managed to use a slightly wrong file to patch from (I was being careful and reapplying and then missed a chunk grrr).

 

In dom.js, Line 85 insertBefore function, replace the if(node.nodeType == Node.DOCUMENT_FRAGMENT_NODE) with the following

         if (newNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
                 var childToReturn = null;
 
                 var tmp = []
                 for (var i = 0i < newNode.childNodes.length++i) {
                          tmp.push(newNode.childNodes[i])


                 }
                 for (var i = 0i < tmp.length++i) {

                          var child = tmp[i];

                          this.insertBefore(child, referenceNode);
                          childToReturn = child;
                 }
                 return childToReturn;
         }

 

Sorry for the mistake,

Deano

Hi,

Ondřej Žára

unread,
Oct 29, 2010, 3:26:47 AM10/29/10
to Deano, v8...@googlegroups.com
Hi Deano!

Thanks a lot for your patch. Prior to applying it, I have some minor questions:

1) can you please mix your patch with the fix described in the last mail? I am not sure about the correct order of applying those...

2) replacing "new Element" with "createElement" makes sense, but the call to createElement should be prefixed with "this.", am I correct? The same for createAttribute...

3) I am very happy about the documentFragment implementation (I recall some users asking for this feature), but I am missing the document.createDocumentFragment method... are you able to supply it as well?

4) exporting additional classes is totally OK for me. There is no way to make them protected with JS/modules, so having them public is the only way.


Thank you,
Ondrej



2010/10/28 Deano <dean....@gmail.com>

Deano

unread,
Oct 29, 2010, 4:59:23 AM10/29/10
to Ondřej Žára, v8...@googlegroups.com

Hi Ondrej,

 

Below is a new patch, with the points raised fixed.

Has my bug fix applied, fixes that issues with this in create[Element|Attribute] and added the createDocumentFragment (missed as I’m mostly testing with htmldoc sub-class which I had added it). Sorry for the missing this, still a bit of javascript newbie so remembering where and how to apply this, sometimes catches me out.

 

Style wise I expect I should apply the special DOCUMENT_FRAGMENT_NODE behavior of appendChild and insertBefore to a custom overload of those functions… but that’s just a tidy up and a small optimization, so I’ll leave that for now, its that’s okay?

 

Thanks,

+             if (newNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {

+                             var childToReturn = null;

+

+                             var tmp = []

+                             for (var i = 0; i < newNode.childNodes.length; ++i) {

+                                             tmp.push(newNode.childNodes[i])

+                             }

+                             for (var i = 0; i < tmp.length; ++i) {

+                                             var child = tmp[i];

+                                             this.insertBefore(child, referenceNode);

+                                             childToReturn = child;

+                             }

+                             return childToReturn;

+             }

+

                newNode._removeReferences();

                this.childNodes.splice(index, 0, newNode);

+             newNode.parentNode = this;

                newNode._addReferences();

                referenceNode._addReferences();

 

@@ -81,6 +117,7 @@

                oldChild._removeReferences();

                newChild._removeReferences();

                this.childNodes.splice(index, 0, newChild);

+             node.parentNode = this;

                newChild._addReferences();

               

                return newChild;

@@ -470,7 +507,7 @@

 }

 

 Document.prototype.createElementNS = function(ns, name) {

-              var elm = new Element(this, name);

+             var elm = this.createElement(name);

                elm.namespaceURI = ns;

                return elm;

 }

@@ -496,7 +533,7 @@

 }

 

 Document.prototype.createAttributeNS = function(ns, name) {

-              var attr = new Attr(this, name);

+             var attr = this.createAttribute(name);

                attr.namespaceURI = ns;

                return attr;

 }

@@ -508,6 +545,12 @@

                return dt;

 }

 

+Document.prototype.createDocumentFragment = function () {

+             var df = new Node(this, "#document-fragment");

+             df.nodeType = Node.DOCUMENT_FRAGMENT_NODE;

+             return df;

+}

+

 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;

 

 Document.prototype.cloneNode = function(deep) {

@@ -547,6 +590,7 @@

                this._map[Node.PROCESSING_INSTRUCTION_NODE] = this._serializeProcessingInstruction;

                this._map[Node.COMMENT_NODE] = this._serializeComment;

                this._map[Node.DOCUMENT_TYPE_NODE] = this._serializeDocumentType;

+             this._map[Node.DOCUMENT_FRAGMENT_NODE] = this._serializeDocumentFragment;

 }

 

 XMLSerializer.prototype.serializeToString = function(document) {

@@ -570,6 +614,12 @@

                return str;

 }

 

+XMLSerializer.prototype._serializeDocumentFragment = function (document) {

+             var str = "";

+             str += this._serializeChildNodes(document);

+             return str;

+}

+

 XMLSerializer.prototype._serializeDocumentType = function(dt) {

                var str = "<!DOCTYPE " + dt.nodeName;

                var arr = [];

@@ -1160,3 +1210,10 @@

Ondřej Žára

unread,
Oct 29, 2010, 5:09:00 AM10/29/10
to Deano, v8...@googlegroups.com

Below is a new patch, with the points raised fixed.

Has my bug fix applied, fixes that issues with this in create[Element|Attribute] and added the createDocumentFragment (missed as I’m mostly testing with htmldoc sub-class which I had added it). Sorry for the missing this, still a bit of javascript newbie so remembering where and how to apply this, sometimes catches me out.



Cool, I will commit your patch soon.
 

Style wise I expect I should apply the special DOCUMENT_FRAGMENT_NODE behavior of appendChild and insertBefore to a custom overload of those functions… but that’s just a tidy up and a small optimization, so I’ll leave that for now, its that’s okay?

 


All features related to document fragments are totally relevant for the base dom.js module, so I opt for leaving them in.

I will also refactor the createDocumentFragment: the aim is to have a DocumentFragment class (similar to Element, Attribute etc), which will implement the DocumentFragment (https://developer.mozilla.org/En/DOM/DocumentFragment) interface.

One can then test for "instanceof DocumentFragment", which is IMHO better than the current ".nodeType == DOCUMENT_FRAGMENT_NODE" test.


Sincerely,
Ondrej


 

Ondřej Žára

unread,
Oct 29, 2010, 5:15:58 AM10/29/10
to Deano, v8...@googlegroups.com
> Below is a new patch, with the points raised fixed.

Oops, the patch gets broken when inserted into mail body. Please
attach the diff file as an attachment...


Sorry,
Ondrej


>
> Has my bug fix applied, fixes that issues with this in create[Element|Attribute] and added the createDocumentFragment (missed as I'm mostly testing with htmldoc sub-class which I had added it). Sorry for the missing this, still a bit of javascript newbie so remembering where and how to apply this, sometimes catches me out.
>
>
>

> Style wise I expect I should apply the special DOCUMENT_FRAGMENT_NODE behavior of appendChild and insertBefore to a custom overload of those functions... but that's just a tidy up and a small optimization, so I'll leave that for now, its that's okay?

Deano

unread,
Oct 29, 2010, 5:43:44 AM10/29/10
to Ondřej Žára, v8...@googlegroups.com
Attached patch file, also implemented your re0factor suggestion, to make
DocumentFragment a class so as to fit the DOM spec (pretty easy as its does
nothing except be a node ;) ).

I have added a specific cloneNode function to DocumentFragment, even tho the
DOM spec state that it should act exactly as Node, in practice I've found
that's it's expected to be able to clone itself, so either our base Node
class should also have a clone that does something or it is an area where
spec and practice differ.

Any problems, happy to fix :)
Deano

dom.js.patch

Ondřej Žára

unread,
Oct 29, 2010, 6:32:31 AM10/29/10
to Deano, v8...@googlegroups.com
2010/10/29 Deano <dean....@gmail.com>:

> Attached patch file, also implemented your re0factor suggestion, to make
> DocumentFragment a class so as to fit the DOM spec (pretty easy as its does
> nothing except be a node ;) ).
>

Commited in r816. Thanks!

> I have added a specific cloneNode function to DocumentFragment, even tho the
> DOM spec state that it should act exactly as Node, in practice I've found
> that's it's expected to be able to clone itself, so either our base Node
> class should also have a clone that does something or it is an area where
> spec and practice differ.
>

In my opinion, the DOM states that DocumentFragment exposes the same
interface, but it is not forbidden for DF::cloneNode()'s
implementation to differ from Node::cloneNode() or
Element::cloneNode(). This being said, I am happy with the way you
implemented DF::cloneNode(). I also refactored the inheritance code a
bit, so all instances now have correct ".constructor" property (I
initially thought that this might allow us to have only one cloneNode
implementation in Node, but it turned out I was wrong).

Now can perhaps be a good time to add DocumentFragment unit test. I
will do this, if I have some spare time later.


Sincerely,
Ondrej

Deano

unread,
Oct 29, 2010, 9:57:20 AM10/29/10
to Ondřej Žára, v8...@googlegroups.com
>In my opinion, the DOM states that DocumentFragment exposes the same
>interface, but it is not forbidden for DF::cloneNode()'s
>implementation to differ from Node::cloneNode() or
>Element::cloneNode(). This being said, I am happy with the way you
>implemented DF::cloneNode(). I also refactored the inheritance code a
>bit, so all instances now have correct ".constructor" property (I
>initially thought that this might allow us to have only one cloneNode
>implementation in Node, but it turned out I was wrong).

Ahh think that caused the light bulb in my head to finally switch on :)

Node is what in C++ land we would think of as an abstract base class. It
sets up the shared interface for all sub-classes of nodes and shared
behavior in some cases. As cloneNode can't be implemented at the Node level
the Node::cloneNode returning null is effective the same as saying virtual
Node* cloneNode() = 0 in C++, stating that this is a part of the Node
interface and every valid child class must implement it.
Would it be better to throw an error in any of Node 'abstract' functions. As
that should only happen if a sub-class has not implemented that function (so
breaking the interface contract) or the user has explicitly created a Node,
which is also bad as its not meant to stand as a separate object?

Sorry if this is simple everyone knows Javascript, its freer implementation
of these things beyond more static languages with fixed object models, means
I'm still getting to grips with all the various forms of inheritance and
prototypes :).

Going to re-factor my HTMLDom with your new inherit function, much nicer
than the previous inherit code :)

For unit testing, would you like me to write some tonight? My testing so far
has been applying jquery and pure functions through it and eye-balling the
correct results.

Thanks,

Ondřej Žára

unread,
Oct 29, 2010, 11:01:02 AM10/29/10
to Deano, v8...@googlegroups.com
> Node is what in C++ land we would think of as an abstract base class. It
> sets up the shared interface for all sub-classes of nodes and shared
> behavior in some cases. As cloneNode can't be implemented at the Node level
> the Node::cloneNode returning null is effective the same as saying virtual
> Node* cloneNode() = 0 in C++, stating that this is a part of the Node
> interface and every valid child class must implement it.
> Would it be better to throw an error in any of Node 'abstract' functions. As
> that should only happen if a sub-class has not implemented that function (so
> breaking the interface contract) or the user has explicitly created a Node,
> which is also bad as its not meant to stand as a separate object?

Yeah, the correpondence with classical (class-based) inheritance is
very strong here. I am relatively indifferent about throwing an
exception in Node::cloneNode, mainly because the Node interface was
not exported (until your recent - and correct - change) so far. If you
wish, feel free to add the "throw" statement...

As for Node's creation - one can also "throw" in the Node constructor,
but there are ways to overcome this:

var tmp = function() {};
tmp.prototype = Node.prototype;
var a = new tmp();
a instanceof Node; // true, but no Node() function called!

Under these circumstances (prototypal inheritance can be tricky!), I
think that security measures preventing Node instantialization are not
very relevant.

> Going to re-factor my HTMLDom with your new inherit function, much nicer
> than the previous inherit code :)

As said before, the inheritance stuff can be complex. Feel free to ask
about how this works...

>
> For unit testing, would you like me to write some tonight? My testing so far
> has been applying jquery and pure functions through it and eye-balling the
> correct results.
>

I would appreciate that. There already is a unit test for the dom
module, written using standardized (commonjs-compliant) modules "test"
and "assert". I encourage you to modify it by adding more checks and
tests using the newly created DocumentFragment interface...


Ondrej

Deano

unread,
Oct 29, 2010, 5:17:39 PM10/29/10
to Ondřej Žára, v8...@googlegroups.com
Hi Ondrej,

Attached is an extension to dom.js unit test, checks the appendTo and
insertBefore works as expected on and to doc fragments and that when
appended to another node the doc fragment transfers its children not itself.

Also patch has a bug fix to dom.js createDocumentFragment found whilst
running the test (I had always created them via the sub-class I'm working on
so had never actually called createDocumentFragment before the unit test).

HTH,

dom.patch

Ondřej Žára

unread,
Oct 30, 2010, 3:58:52 AM10/30/10
to Deano, v8...@googlegroups.com
2010/10/29 Deano <dean....@gmail.com>:

> Hi Ondrej,
>
> Attached is an extension to dom.js unit test, checks the appendTo and
> insertBefore works as expected on and to doc fragments and that when
> appended to another node the doc fragment transfers its children not itself.
>
> Also patch has a bug fix to dom.js createDocumentFragment found whilst
> running the test (I had always created them via the sub-class I'm working on
> so had never actually called createDocumentFragment before the unit test).

Cool, commited in r817 ;)

O.

Deano

unread,
Nov 5, 2010, 9:57:55 AM11/5/10
to Ondřej Žára, v8...@googlegroups.com
Hi Ondrej,

Another patch for dom.js for you,
-------------------------
Fixes typo on removeChild
Changes all new ElementX to this.ownerDocument.createElementX in cloneNode
function, so sub-modules don't have to re-implement cloneNode just to change
new ElementX to new MyElementX
Added an early out in one place, and made newAttribute use node var name to
slightly reduce memory and be more consistent with other branch path.
Fix a typo in createDocumentFragment and exported it
Allowed _serializeNode to return undefined to skip the serialization of this
node, used in htmldom.js to skip default attribute. Making for prettier
serialization (excess white space without it)

Bye,

dom.patch

Ondřej Žára

unread,
Nov 6, 2010, 4:05:14 AM11/6/10
to Deano, v8...@googlegroups.com
Hi,

thanks a lot, commited in r818. I left your patch mostly unmodified -
I just simplified the attribute serialization condition so all "falsy"
values are respected.


O.


2010/11/5 Deano <dean....@gmail.com>:

Reply all
Reply to author
Forward
0 new messages