diff --git a/lib/DocumentType.js b/lib/DocumentType.js index c143037..536a596 100644 --- a/lib/DocumentType.js +++ b/lib/DocumentType.js @@ -9,12 +9,16 @@ function DocumentType(ownerDocument, name, publicId, systemId) { Leaf.call(this); this.nodeType = Node.DOCUMENT_TYPE_NODE; this.ownerDocument = ownerDocument || null; - this.name = name; + this._name = name; this.publicId = publicId || ""; this.systemId = systemId || ""; } DocumentType.prototype = Object.create(Leaf.prototype, { + name: { + get: function() { return this._name; }, + set: function() { /* no-op per spec */ } + }, nodeName: { get: function() { return this.name; }}, nodeValue: { get: function() { return null; }, diff --git a/lib/Element.js b/lib/Element.js index e9d5794..92c86e2 100644 --- a/lib/Element.js +++ b/lib/Element.js @@ -22,9 +22,9 @@ function Element(doc, localName, namespaceURI, prefix) { ContainerNode.call(this); this.nodeType = Node.ELEMENT_NODE; this.ownerDocument = doc; - this.localName = localName; + this._localName = localName; this.namespaceURI = namespaceURI; - this.prefix = prefix; + this._prefix = prefix; this._tagName = undefined; // These properties maintain the set of attributes @@ -44,6 +44,14 @@ function recursiveGetText(node, a) { } Element.prototype = Object.create(ContainerNode.prototype, { + localName: { + get: function () { return this._localName; }, + set: function () { /* no-op per spec */ } + }, + prefix: { + get: function () { return this._prefix; }, + set: function () { /* no-op per spec */ } + }, isHTML: { get: function isHTML() { return this.namespaceURI === NAMESPACE.HTML && this.ownerDocument.isHTML; }}, @@ -66,7 +74,9 @@ Element.prototype = Object.create(ContainerNode.prototype, { this._tagName = tn; } return this._tagName; - }}, + }, + set: function () { /* no-op per spec */ } + }, nodeName: { get: function() { return this.tagName; }}, nodeValue: { get: function() { @@ -985,8 +995,8 @@ attributes.registerChangeHandler(Element, 'class', function Attr(elt, lname, prefix, namespace, value) { // localName and namespace are constant for any attr object. // But value may change. And so can prefix, and so, therefore can name. - this.localName = lname; - this.prefix = (prefix===null || prefix==='') ? null : ('' + prefix); + this._localName = lname; + this._prefix = (prefix===null || prefix==='') ? null : ('' + prefix); this.namespaceURI = (namespace===null || namespace==='') ? null : ('' + namespace); this.data = value; // Set ownerElement last to ensure it is hooked up to onchange handler @@ -995,6 +1005,14 @@ function Attr(elt, lname, prefix, namespace, value) { // In DOM 3 Attr was supposed to extend Node; in DOM 4 that was abandoned. Attr.prototype = Object.create(Object.prototype, { + localName: { + get: function () { return this._localName; }, + set: function () { /* no-op per spec */ } + }, + prefix: { + get: function () { return this._prefix; }, + set: function () { /* no-op per spec */ } + }, ownerElement: { get: function() { return this._ownerElement; }, }, diff --git a/lib/ProcessingInstruction.js b/lib/ProcessingInstruction.js index ad71bd7..4d5cb2d 100644 --- a/lib/ProcessingInstruction.js +++ b/lib/ProcessingInstruction.js @@ -8,7 +8,7 @@ function ProcessingInstruction(doc, target, data) { CharacterData.call(this); this.nodeType = Node.PROCESSING_INSTRUCTION_NODE; this.ownerDocument = doc; - this.target = target; + this._target = target; this._data = data; } @@ -22,6 +22,10 @@ var nodeValue = { }; ProcessingInstruction.prototype = Object.create(CharacterData.prototype, { + target: { + get: function () { return this._target; }, + set: function () { /* no-op per spec */ } + }, nodeName: { get: function() { return this.target; }}, nodeValue: nodeValue, textContent: nodeValue, diff --git a/test/readonly.js b/test/readonly.js new file mode 100644 index 0000000..9398f01 --- /dev/null +++ b/test/readonly.js @@ -0,0 +1,43 @@ +'use strict'; + +var domino = require('../lib'); + +exports.readonly = {}; + +exports.readonly.attr = function () { + var doc = domino.createDocument(); + var attr = doc.createAttribute('test'); + + attr.localName = 'foo'; + attr.localName.should.equal('test'); + + attr.prefix = 'foo'; + (attr.prefix === null).should.be.true(); +}; + +exports.readonly.element = function () { + var doc = domino.createDocument(); + var el = doc.createElement('div'); + + el.localName = 'foo'; + el.localName.should.equal('div'); + + el.prefix = 'foo'; + (el.prefix === null).should.be.true(); +}; + +exports.readonly.processingInstruction = function () { + var doc = domino.createDocument(); + var pi = doc.createProcessingInstruction('target', 'data'); + + pi.target = 'foo'; + pi.target.should.equal('target'); +}; + +exports.readonly.documentType = function () { + var doc = domino.createDocument(); + var dt = doc.implementation.createDocumentType('name', 'public', 'system'); + + dt.name = 'foo'; + dt.name.should.equal('name'); +};