Skip to content

Commit

Permalink
Spec-correctness for Document#createElement() and `Document#createE…
Browse files Browse the repository at this point in the history
…lementNS()`

The spec (and its test suite) is itself a bit confused; see
web-platform-tests/wpt#12202 and
whatwg/dom#671 for more details.

Used proper exception type (InvalidCharacterError in more cases, after
whatwg/dom#319) and ensured that we did the
proper WebIDL type coercion thing if given null/undefined as arguments.
  • Loading branch information
cscott committed Jul 27, 2018
1 parent 2985402 commit 9d3d86a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Handle null/undefined/negative values in `CharacterData` interface methods
* More spec-correctness fixes for `DOMTokenList`
* Fix `[src=...]` selectors
* Spec-correctness fixes for `Document#createElement()` and
`Document#createElementNS()`

# domino 2.0.3 (12 Jul 2018)
* Define `blur()`, `focus()` and `forceSpellCheck()` on `HTMLElement` (#125)
Expand Down
57 changes: 38 additions & 19 deletions lib/Document.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,35 +146,54 @@ Document.prototype = Object.create(ContainerNode.prototype, {
}},

createElement: { value: function(localName) {
localName = String(localName);
if (!xml.isValidName(localName)) utils.InvalidCharacterError();
if (this.isHTML) localName = utils.toASCIILowerCase(localName);
return html.createElement(this, localName, null);
// Per spec, namespace should be HTML namespace if "context object is
// an HTML document or context object's content type is
// "application/xhtml+xml", and null otherwise.
// XXX we don't track "context object's content type"
if (this.isHTML) {
localName = utils.toASCIILowerCase(localName);
return html.createElement(this, localName, null);
} else {
return new Element(this, localName, null, null);
}
}, writable: isApiWritable },

createElementNS: { value: function(namespace, qualifiedName) {
if (!xml.isValidName(qualifiedName)) utils.InvalidCharacterError();
if (!xml.isValidQName(qualifiedName)) utils.NamespaceError();

var pos, prefix, localName;
if ((pos = qualifiedName.indexOf(':')) !== -1) {
// Convert parameter types according to WebIDL
namespace =
(namespace === null || namespace === undefined || namespace === '') ? null :
String(namespace);
qualifiedName = String(qualifiedName);
// See https://github.com/whatwg/dom/issues/671
// and https://github.com/whatwg/dom/issues/319
if (!xml.isValidQName(qualifiedName)) {
utils.InvalidCharacterError();
}

prefix = null;
localName = qualifiedName;

pos = qualifiedName.indexOf(':');
if (pos >= 0) {
prefix = qualifiedName.substring(0, pos);
localName = qualifiedName.substring(pos+1);

if (namespace === '' ||
(prefix === 'xml' && namespace !== NAMESPACE.XML))
utils.NamespaceError();
}
else {
prefix = null;
localName = qualifiedName;
if (prefix !== null && namespace === null) {
utils.NamespaceError();
}

if (((qualifiedName === 'xmlns' || prefix === 'xmlns') &&
namespace !== NAMESPACE.XMLNS) ||
(namespace === NAMESPACE.XMLNS &&
qualifiedName !== 'xmlns' &&
prefix !== 'xmlns'))
if (prefix === 'xml' && namespace !== NAMESPACE.XML) {
utils.NamespaceError();
}
if ((prefix === 'xmlns' || qualifiedName === 'xmlns') &&
namespace !== NAMESPACE.XMLNS) {
utils.NamespaceError();
}
if (namespace === NAMESPACE.XMLNS && !(prefix==='xmlns' || qualifiedName==='xmlns')) {
utils.NamespaceError();
}

if (namespace === NAMESPACE.HTML) {
return html.createElement(this, localName, prefix);
Expand Down

0 comments on commit 9d3d86a

Please sign in to comment.