8

So let's say (in IE8) that we have a document.

Now normally we can assume that document.childNodes[0] is the doctype. So

var doctype = document.childNodes[0]

Now how do we confirm rather then assume it is the doctype?

doctype.nodeType === Node.COMMENT_NODE;
doctype.tagName === "!"; // same as a comment
doctype.data.indexOf("DOCTYPE ") > -1; // same as any comment containing the word DOCTYPE.
doctype === document.doctype; // false, document.doctype is undefined in IE8

Apart from assumptions, how am I supposed to know whether a given node is a doctype?

For those of you unfamiliar with DOM4 take a look at DocumentType

The DOM-shim get's document.doctype in IE8 by just returning document.childNodes[0]

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 4
    Is the doctype really part of the DOM? I was under the impression that it isn't. I can be wrong though. – Pekka Oct 28 '11 at 18:33
  • In Chrome/Mac, the node type is `Node.DOCUMENT_TYPE_NODE`. – millimoose Oct 28 '11 at 18:34
  • 4
    @Pekka Yes it is. Just check what `document.childNodes[0]` is on this page. – millimoose Oct 28 '11 at 18:34
  • @Pekka `document.doctype` aswell. – Raynos Oct 28 '11 at 18:43
  • @Inerdia my comedy title :( why did you ruin it and turn it into a sensible one. – Raynos Oct 28 '11 at 18:49
  • It seems to be in IE7 and IE8 – Russ Cam Oct 28 '11 at 18:52
  • I fear the answer is always `false`. The node at document.childNodes[0] in IE8 is *not* the doctype node, it's more like a placeholder (comment) node in lieu of where the doctype node ought to be. JS apart, there's really no need for IE to retain a real doctype node once the quirks vs standards flag's been set, and I suspect it simply didn't. – Alohci Oct 28 '11 at 19:02
  • @Alohci I see. IE8 does not have any concept of document node, it just has comment at `document.childNodes[0]`. This is a sad day. IE8 did another thing wrong :( – Raynos Oct 28 '11 at 19:21
  • Maybe `doctype.data.indexOf(" ") !== -1`? – Kevin Ji Oct 28 '11 at 19:38
  • @mc10 that sounds like just as bad of assumption as `document.childNodes[0]`. However I'd be interesting to see whether a DOCTYPE can have any other position in the DOM – Raynos Oct 28 '11 at 19:41
  • @Raynos - It might not be a smart thing to do, but comments that precede the doctype in the markup will take node positions that precede the doctype in the DOM. So it might not be at `childNodes[0]`. I believe that only comment nodes, (and anything treated by the parser as a comment node, e.g. an xml declaration) can precede the doctype. Anything else and the browser parser will ignore the doctype markup. – Alohci Oct 28 '11 at 23:29
  • If you know the form of your doctype, you could do something like http://stackoverflow.com/questions/6088972/get-doctype-of-an-html-as-string-with-javascript/6089056#6089056 – Kevin Ji Oct 29 '11 at 04:03
  • mc10's idea is probably correct. I don't know about ie8 but Python dom nodes have 2 attributes "publicId" and "systemId" that don't seem to appear in normal nodes. – AndrewStone Oct 29 '11 at 04:13
  • @AndrewStone `publicId`, `name` & `systemId` do not work in IE8 – Raynos Oct 29 '11 at 09:35

2 Answers2

2

I figured out that in IE7 and IE8 the .innerHTML property for comments is always the full "<!--comment here-->" and for the doctype node, it is "". Even for empty comments, the .innerHTML is "<!---->"

So based on this I created:

function isDocType(node) {
    return node && (
    node.nodeType === 10 || (node.nodeType === 8 && "innerHTML" in node && node.innerHTML === ""));
}

With the test page:

<!-- comment1 -->
<!-- comment2 -->
<!---->
<!-- -->
<!-- <!DOCTYPE html> -->

Running doctype and the comments through isDocType gives:

LOG: true 
LOG: false 
LOG: false 
LOG: false 
LOG: false 
LOG: false

See http://jsfiddle.net/AEYt4/

Esailija
  • 138,174
  • 23
  • 272
  • 326
0

IE8 says no. :(

Seriously though, apart from hacks and assumptions there is no clean way.

As suggested in the comments you can assume comments are not doctype like

doctype.data.indexOf("<!DOCTYPE html") !== -1 && doctype.data.indexOf(">") !== -1

Or make assumptions about the DOM structure

I believe that only comment nodes, (and anything treated by the parser as a comment node, e.g. an xml declaration) can precede the doctype

So you can just loop over the comment nodes in document.childNodes until you find one that matches the above regexp.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • No. You shouldn't be looking for comment nodes. You should be looking specifically for `node.nodeType === 10` (`DOCUMENT_TYPE_NODE`). Any other type is an incorrect implementation and best left ignored. –  Apr 12 '12 at 20:41
  • I believe any browser that actually has `nodeType === 10` for the doctype node has `document.doctype` – Raynos Apr 12 '12 at 20:47