content/html/content/test/test_bug389797.html
author Ivan Enderlin <ivan.enderlin@hoa-project.net>, Mounir Lamouri <mounir.lamouri@gmail.com>, Ms2ger <ms2ger@gmail.com>
Wed, 23 Jun 2010 10:08:56 -0700
changeset 44192 b4149e2c40567006e4ad41e89fb2d22c5961e4c4
parent 43929 11aa64d1d6121f90b5b3050dad8622f1ea83952c
child 44193 40de8e1a9f13e192ab367fd3202ab23e4fc70ec8
permissions -rw-r--r--
Implement the mark element. r=jonas+timeless (Bug 485377)

<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=389797
-->
<head>
  <title>Test for Bug 389797</title>
  <script type="text/javascript" src="/MochiKit/packed.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=389797">Mozilla Bug 389797</a>
<p id="display"></p>
<div id="content" style="display: none">
  
</div>
<pre id="test">
<script class="testbody" type="text/javascript">

/** Test for Bug 389797 **/
var allTags = [];
var classInfos = {};
var interfaces = {};
var interfacesNonClassinfo = {};

function getClassName(tag) {
  return "HTML" + classInfos[tag] + "Element";
}

function HTML_TAG(aTagName, aImplClass) {
  allTags.push(aTagName);
  classInfos[aTagName] = aImplClass;
  interfaces[aTagName] =
    [ "nsIDOM3Node",
      "nsIDOMNSElement",
      "nsIDOMEventTarget",
      "nsIDOMNSEventTarget",
      "nsIDOMNSHTMLElement",
      "nsIDOMElementCSSInlineStyle",
      "nsIDOMNodeSelector" ];

  // Some interfaces don't appear in classinfo because other interfaces that
  // inherit from them do.
  interfacesNonClassinfo[aTagName] =
    [ "nsIDOMNode",
      "nsIDOMElement",
      "nsIDOM3EventTarget",
      "nsISupportsWeakReference" ];

  var interfaceName = "nsIDOM" + getClassName(aTagName);
  if (interfaceName in Components.interfaces) {  // no nsIDOMHTMLSpanElement
    interfaces[aTagName].push(interfaceName);
    interfacesNonClassinfo[aTagName].push("nsIDOMHTMLElement");
  } else if (aTagName != "ins" && aTagName != "del") {
    // Inherits directly from nsIDOMHTMLElement, unless it's "ins" or "del",
    // which are weird.
    interfaces[aTagName].push("nsIDOMHTMLElement");
    
  }

  var interfaceNameNS = "nsIDOMNS" + getClassName(aTagName);
  if (interfaceNameNS in Components.interfaces) {
    interfaces[aTagName].push(interfaceNameNS);
  }

  if (arguments.length > 2) {
    for (var i = 0; i < arguments[2].length; ++i) {
      interfaces[aTagName].push(arguments[2][i]);
    }
  }

  if (arguments.length > 3) {
    for (i = 0; i < arguments[3].length; ++i) {
      interfacesNonClassinfo[aTagName].push(arguments[3][i]);
    }
  }
}

const objectIfaces = [
    "imgIDecoderObserver", "nsIRequestObserver", "nsIStreamListener",
    "nsIFrameLoaderOwner", "nsIObjectLoadingContent", "nsIInterfaceRequestor",
    "nsIChannelEventSink"
  ];

var objectIfaces2 = [];
for each (var iface in objectIfaces) {
  objectIfaces2.push(iface);
}
objectIfaces2.push("nsIImageLoadingContent");

/* List copy/pasted from nsHTMLTagList.h, with the second field modified to the
   correct classinfo (instead of the impl class) in the following cases:

   applet
   base
   blockquote
   del
   dir
   dl
   embed
   ins
   isindex
   menu
   ol
   param
   q
   spacer
   ul
   wbr
   head
   html
 */

HTML_TAG("a", "Anchor", [ "nsIDOMNSHTMLAnchorElement2" ]);
HTML_TAG("abbr", "Span");
HTML_TAG("acronym", "Span");
HTML_TAG("address", "Span");
HTML_TAG("applet", "Applet", [], objectIfaces);
HTML_TAG("area", "Area", [ "nsIDOMNSHTMLAreaElement2" ]);
HTML_TAG("article", ""); // HTMLElement
HTML_TAG("aside", ""); // HTMLElement
HTML_TAG("b", "Span");
HTML_TAG("base", "Base");
HTML_TAG("bdo", "Span");
HTML_TAG("bgsound", "Span");
HTML_TAG("big", "Span");
HTML_TAG("blink", "Span");
HTML_TAG("blockquote", "Quote");
HTML_TAG("body", "Body");
HTML_TAG("br", "BR");
HTML_TAG("button", "Button");
HTML_TAG("canvas", "Canvas");
HTML_TAG("caption", "TableCaption");
HTML_TAG("center", "Span");
HTML_TAG("cite", "Span");
HTML_TAG("code", "Span");
HTML_TAG("col", "TableCol");
HTML_TAG("colgroup", "TableCol");
HTML_TAG("dd", "Span");
HTML_TAG("del", "Del", [ "nsIDOMHTMLModElement" ]);
HTML_TAG("dfn", "Span");
HTML_TAG("dir", "Directory");
HTML_TAG("div", "Div");
HTML_TAG("dl", "DList");
HTML_TAG("dt", "Span");
HTML_TAG("em", "Span");
HTML_TAG("embed", "Embed", [ "nsIDOMGetSVGDocument" ], objectIfaces);
HTML_TAG("fieldset", "FieldSet");
HTML_TAG("font", "Font");
HTML_TAG("footer", "") // HTMLElement
HTML_TAG("form", "Form", [], [ "nsIWebProgressListener" ]);
HTML_TAG("frame", "Frame", [], [ "nsIFrameLoaderOwner" ]);
HTML_TAG("frameset", "FrameSet");
HTML_TAG("h1", "Heading");
HTML_TAG("h2", "Heading");
HTML_TAG("h3", "Heading");
HTML_TAG("h4", "Heading");
HTML_TAG("h5", "Heading");
HTML_TAG("h6", "Heading");
HTML_TAG("head", "Head");
HTML_TAG("header", "") // HTMLElement
HTML_TAG("hgroup", "") // HTMLElement
HTML_TAG("hr", "HR");
HTML_TAG("html", "Html");
HTML_TAG("i", "Span");
HTML_TAG("iframe", "IFrame", [ "nsIDOMNSHTMLFrameElement", "nsIDOMGetSVGDocument" ],
                             [ "nsIFrameLoaderOwner" ]);
HTML_TAG("image", "Span");
HTML_TAG("img", "Image", [], [ "imgIDecoderObserver",
                               "nsIImageLoadingContent" ]);
HTML_TAG("input", "Input", [], [ "imgIDecoderObserver",
                                 "nsIImageLoadingContent",
                                 "nsIDOMNSEditableElement" ]);
HTML_TAG("ins", "Ins", [ "nsIDOMHTMLModElement" ]);
HTML_TAG("isindex", "IsIndex");
HTML_TAG("kbd", "Span");
HTML_TAG("keygen", "Span");
HTML_TAG("label", "Label");
HTML_TAG("legend", "Legend");
HTML_TAG("li", "LI");
HTML_TAG("link", "Link", [ "nsIDOMLinkStyle" ]);
HTML_TAG("listing", "Span");
HTML_TAG("map", "Map");
HTML_TAG("mark", ""); // HTMLElement
HTML_TAG("marquee", "Div");
HTML_TAG("menu", "Menu");
HTML_TAG("meta", "Meta");
HTML_TAG("multicol", "Span");
HTML_TAG("nav", "") // HTMLElement
HTML_TAG("nobr", "Span");
HTML_TAG("noembed", "Div");
HTML_TAG("noframes", "Div");
HTML_TAG("noscript", "Div");
HTML_TAG("object", "Object", [ "nsIDOMGetSVGDocument" ],
                             objectIfaces.concat([ "nsIImageLoadingContent" ]));
HTML_TAG("ol", "OList");
HTML_TAG("optgroup", "OptGroup");
HTML_TAG("option", "Option");
HTML_TAG("p", "Paragraph");
HTML_TAG("param", "Param");
HTML_TAG("plaintext", ""); // HTMLElement
HTML_TAG("pre", "Pre");
HTML_TAG("q", "Quote");
HTML_TAG("s", "Span");
HTML_TAG("samp", "Span");
HTML_TAG("script", "Script", [], [ "nsIScriptLoaderObserver" ]);
HTML_TAG("section", "") // HTMLElement
HTML_TAG("select", "Select");
HTML_TAG("small", "Span");
HTML_TAG("spacer", "Spacer");
HTML_TAG("span", "Span");
HTML_TAG("strike", "Span");
HTML_TAG("strong", "Span");
HTML_TAG("style", "Style", [ "nsIDOMLinkStyle" ]);
HTML_TAG("sub", "Span");
HTML_TAG("sup", "Span");
HTML_TAG("table", "Table");
HTML_TAG("tbody", "TableSection");
HTML_TAG("td", "TableCell");
HTML_TAG("textarea", "TextArea", [], [ "nsIDOMNSEditableElement" ]);
HTML_TAG("tfoot", "TableSection");
HTML_TAG("th", "TableCell");
HTML_TAG("thead", "TableSection");
HTML_TAG("title", "Title");
HTML_TAG("tr", "TableRow");
HTML_TAG("tt", "Span");
HTML_TAG("u", "Span");
HTML_TAG("ul", "UList");
HTML_TAG("var", "Span");
HTML_TAG("wbr", "WBR");
HTML_TAG("xmp", ""); // HTMLElement

function tagName(aTag) {
  return "<" + aTag + ">";
}

for each (var tag in allTags) {
  var node = document.createElement(tag);

  // Have to use the proto's toString(), since HTMLAnchorElement and company
  // override toString().
  var nodeString = HTMLElement.prototype.toString.apply(node);

  // Debug builds have extra info, so chop off after "Element" if it's followed
  // by ' ' or ']'
  nodeString = nodeString.replace(/Element[\] ].*/, "Element");

  var classInfoString = getClassName(tag);
  is(nodeString, "[object " + classInfoString,
     "Unexpected classname for " + tagName(tag));
  is(node instanceof window[classInfoString], true,
     tagName(tag) + " not an instance of " + classInfos[tag]);

  // Check that each node QIs to all the things we expect it to QI to
  for each (var iface in interfaces[tag].concat(interfacesNonClassinfo[tag])) {
    is(iface in Components.interfaces, true,
       iface + " not in Components.interfaces");
    is(node instanceof Components.interfaces[iface], true,
       tagName(tag) + " does not QI to " + iface);
  }

  // Now see what classinfo reports
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var nodeClassInfo = node.QueryInterface(Components.interfaces.nsIClassInfo);
  var count = {};
  var classInfoInterfaces =
    nodeClassInfo.getInterfaces(count).
    map(function(id) { return Components.interfacesByID[id].toString(); });

  // Make sure that we know about all the things classinfo claims
  for each (var classInfoInterface in classInfoInterfaces) {
    isnot(interfaces[tag].indexOf(classInfoInterface), -1,
          "Should know about " + tagName(tag) + " implementing " +
          classInfoInterface);
  }

  // And make sure classinfo claims all the things we know about
  for each (iface in interfaces[tag]) {
    isnot(classInfoInterfaces.indexOf(iface), -1,
          "Classinfo for " + tagName(tag) + " should claim to implement " +
          iface);
  }
}
</script>
</pre>
</body>
</html>