For JS running in browser.xul, please use children/firstElementChild/lastElementChild instead of childNodes/firstChild/lastChild if you expect to receive elements back

40 views
Skip to first unread message

Brian Grinstead

unread,
Aug 13, 2018, 2:17:52 PM8/13/18
to firefox-dev
We're starting to experiment with loading the main browser document (browser.xul) as an HTML document (browser.xhtml). Expect a separate update with more details about that project soon, but in the meantime I wanted to call out a frontend change that we needed to make to get that running.

In XUL documents, text nodes don't get created by the parser. So, given this markup:
```
<box>
<label />
</box>
```

`box.firstChild` is the label. However in HTML documents, where text nodes do get created, `box.firstChild` is a whitespace text node (`box.firstElementChild` is the label). Since the majority of our frontend code accesses `firstChild` assuming that it's an element, that means a bunch of the JS/DOM is broken when we introduce text nodes. In Bug 1479125, I landed an initial migration of the relevant callers in browser.xul.

Inconveniently, there are some cases where accessing `firstChild` continues to make sense to use in both XUL and HTML documents. For instance, when dealing with elements that explicitly have added textNodes, or when emptying out a DOM node like `while (box.hasChildNodes()) { box.firstChild.remove();`.

Because of that, it's tricky to write an eslint rule to prevent code from using those APIs. So this is mostly just an ask for help to use the "element" APIs when you are writing or reviewing code that runs in browser.xul. If you notice some callers that were missed, then letting me know or filing a bug blocking Bug 1453783 would be great. Since there's a lot of muscle memory involved and we don't yet have anything running in automation to prevent it, I'm expecting it'll take a few follow ups to get to all callers.

Here's the list of API changes:
childNodes->children
firstChild->firstElementChild
lastChild->lastElementChild
nextSibling->nextElementSibling
previousSibling->previousElementSibling

Thanks,
Brian
_______________________________________________
firefox-dev mailing list
firef...@mozilla.org
https://mail.mozilla.org/listinfo/firefox-dev
Reply all
Reply to author
Forward
0 new messages