author Brendan Dahl <>
Sat, 09 Mar 2019 01:00:23 +0000
changeset 521223 f996bb0f3d232ad13c8d9f87ecbe9baa868ebac2
parent 468339 427e3dce92c2eec8fa9a167fef3f2a726b4010a6
child 528459 0d9b9b96f5475adbed73922da696aeff7cbbaed3
permissions -rw-r--r--
Bug 1527977 - Share XUL prototype cache with XUL and XHTML. r=smaug Create a new parser (PrototypeDocumentParser) and content sink (PrototypeDocumentContentSink) that can be used by both XUL and XHTML. The new parser moves the code from XULDocument that handles creating and loading a nsXULPrototypeDocument from either the cache or the source file. Once the parser has finished loading the prototype it notifies the content sink. The parser is largely a stub and would be better suited for use as a nsBaseParser, but nsHTMLDocument unfortunately needs an nsIParser. The new content sink has the XULDocument code responsible for the prototype traversal that creates the DOM (XULDocument::ResumeWalk and friends) and fires off various events. To unify XUL and XHTML, the XHTML readystate event sequence is used in XUL. However, the layout path of XHTML loaded from the prototype cache more closely follows XUL, where frame initializers and layout don't start until the entire DOM is built. Differential Revision:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
<window title="Mozilla Bug 1411707"
  <script type="application/javascript"

  <!-- test results are displayed in the html:body -->
  <body xmlns="">
  <a href=""
     target="_blank">Mozilla Bug 1411707</a>

  <!-- test code goes here -->
  <script type="application/javascript"><![CDATA[

    const OUTER_URL = "chrome://mochitests/content/chrome/dom/base/test/chrome/file_document-element-inserted.xul";
    const INNER_URL = "chrome://mochitests/content/chrome/dom/base/test/chrome/file_document-element-inserted-inner.xul";

    async function waitForEvent(url) {
      return new Promise(resolve => {
        SpecialPowers.addObserver(function inserted(document) {
          is(document.documentURI, url, "Correct URL");
          is(document.readyState, "loading", "Correct readyState");
          SpecialPowers.removeObserver(inserted, "document-element-inserted");
        }, "document-element-inserted");

    // Load a XUL document that also has an iframe to a subdocument, and
    // expect both events to fire with the docs in the correct state.
    async function testEvents() {
      info(`Waiting for events after loading ${OUTER_URL}`);
      let win = window.openDialog(OUTER_URL, null, "chrome,dialog=no,all");
      await waitForEvent(OUTER_URL);
      await waitForEvent(INNER_URL);

    (async function() {
      // Test the same document twice to make to make sure we are
      // firing properly when loading the protype document.
      await testEvents();
      await testEvents();