1

I am writing a Firefox extension using JavaScript and XUL. Part of my code needs to be able to take some XUL markup and dynamically append it inside an existing container element. So basically I need to appendChild() but with a text string instead of a Node object. To do this, I tried the method listed in this question. Unfortunately this does not seem to work. It appears that div.childNodes returns an empty nodeList, which I can't even append to the container. The error is

Error: Could not convert JavaScript argument arg 0 [nsIDOMXULElement.appendChild]

I'm not quite sure what I am doing wrong. Is there a way to make this work, or some alternate method to dynamically set the container's markup?

Note: The container element is of type richlistbox.

    function updateContainerData(containerName){
      try{
        var resultsArray = DB.queryAsync("SELECT nodeData FROM waffleapps_privateurl");

        container = document.getElementById(containerName);

        for (var i = 0; i < resultsArray.length; i++) {

            /*
            // This works - appending an actual Node ( duplicate from a template)
            template = document.getElementById("list-item-template");
            dupNode = template.cloneNode(true);
            dupNode.setAttribute("hidden", false);
            container.appendChild(dupNode);
            */

            // This doesn't work
            div = document.createElement("div");
            //var s = '<li>text</li>';
var s = "<richlistitem id ='list-item-template'><hbox><checkbox label='' checked='true'/>  <description>DESCRIPTION</description><textbox>test</textbox><textbox></textbox></hbox></richlistitem>";

            div.innerHTML = s;
            var elements = div.childNodes;

            container.appendChild(elements); // error

        }
        }
        catch(err){
          alert( "Error: " + err.message);
        }
    }

I have gotten a bit further by using the following code. Now I am able to insert HTML elements in the container, but it appears that XUL elements are not parsed properly - the checkbox and textbox do not appear. I'm not sure how I would change this so it parses the HTML and XUL markup correctly.

    var s = "<richlistitem id ='list-item-template'><hbox><checkbox label='' checked='true'/>  <description>DESCRIPTION</description><textbox>test</textbox><textbox></textbox></hbox></richlistitem>";
    var dp = new DOMParser();
    container.appendChild(dp.parseFromString(s, "text/xml").documentElement);
Makyen
  • 31,849
  • 12
  • 86
  • 121
Bryan
  • 2,191
  • 20
  • 28

2 Answers2

0

You need to do an appendChild for each element in the "elements" nodeList (assuming there's more than one).

Also note: a list element should have a parent ol or ul element.

Yansky
  • 4,580
  • 8
  • 29
  • 24
0

I finally figured out how to properly parse and append a XUL markup string. I was able to use the parseFromString method from a new DOMParser(). I had to make sure that the element's markup specified the namespace (xmlns) so the parser knew it was XUL markup.

The code below shows a full example.

test.js:

test = function(){
    alert("testing");

    container = document.getElementById("testing");
    var dp = new DOMParser();

    // must specify namespace
    var s = "<textbox xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' value='test' size='20'></textbox>";

    element = dp.parseFromString(s, "text/xml").documentElement;

    container.appendChild(element);

    document.getElementById("testing");
}

test.xul:

<?xml version="1.0"?>

<?xml-stylesheet type="text/css" href="chrome://global/skin/" ?>
<?xml-stylesheet type="text/css"
  href="chrome://testextensionname/skin/test.css" ?>

<!DOCTYPE window SYSTEM
  "chrome://testextensionname/locale/test.dtd">

<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
        id="testWindow"
        orient="vertical" title="TEST" statictitle="TEST"
        width="50" height="50;" screenX="10" screenY="10"
       >
<script type="application/x-javascript" src="chrome://testextensionname/content/test.js" />

<hbox id="testing">
<button label="Go" oncommand="test()"/>
<textbox value='test' size='20'></textbox>
</hbox>

</window>
Bryan
  • 2,191
  • 20
  • 28