Bug 1479125 - Migrate calls that expect an element to be returned to use element variation firstChild etc to firstElementChild etc;r=Paolo
authorBrian Grinstead <bgrinstead@mozilla.com>
Wed, 08 Aug 2018 15:22:53 -0700
changeset 485883 c266a7f4237e42503d320f81e82fb822dadd1002
parent 485882 0b8b186eb7126908aade4bc17db7843ac8b850cd
child 485884 b493b05dcbd5574c81e4834bf23c9b6c61b8a1e3
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersPaolo
bugs1479125
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1479125 - Migrate calls that expect an element to be returned to use element variation firstChild etc to firstElementChild etc;r=Paolo This allows the JS to work in HTML documents, where whitespace is preserved. In XUL documents, whitespace is ignored when parsing so text nodes are generally not returned. The following changes were made, with manual cleanups as necessary (i.e. when firstChild actually refers to a text node, or when firstChild is used in a loop to empty out an element): firstChild->firstElementChild lastChild->lastElementChild nextSibling->nextElementSibling previousSibling->previousElementSibling childNodes->children MozReview-Commit-ID: 95NQ8syBhYw
browser/base/content/browser-addons.js
browser/base/content/browser-ctrlTab.js
browser/base/content/browser-customization.js
browser/base/content/browser-pageActions.js
browser/base/content/browser-sidebar.js
browser/base/content/browser-sync.js
browser/base/content/browser.js
browser/base/content/tabbrowser.js
browser/base/content/tabbrowser.xml
browser/base/content/urlbarBindings.xml
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/CustomizableWidgets.jsm
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/DragPositionManager.jsm
browser/components/customizableui/PanelMultiView.jsm
browser/components/customizableui/content/panelUI.js
browser/components/customizableui/content/toolbar.xml
browser/components/downloads/DownloadsSubview.jsm
browser/components/downloads/content/downloads.js
browser/components/extensions/parent/ext-menus.js
browser/components/extensions/test/browser/browser_ext_tabs_hide.js
browser/components/places/content/browserPlacesViews.js
browser/components/places/content/controller.js
browser/components/places/content/editBookmark.js
browser/components/places/content/menu.xml
browser/components/search/content/search.xml
browser/components/syncedtabs/TabListView.js
browser/modules/AsyncTabSwitcher.jsm
browser/modules/TabsList.jsm
toolkit/components/contextualidentity/ContextualIdentityService.jsm
toolkit/components/printing/content/printPreviewToolbar.js
toolkit/content/widgets/autocomplete.xml
toolkit/content/widgets/findbar.xml
toolkit/content/widgets/general.js
toolkit/content/widgets/menu.xml
toolkit/content/widgets/menulist.xml
toolkit/content/widgets/popup.xml
toolkit/content/widgets/richlistbox.xml
toolkit/content/widgets/scrollbox.xml
toolkit/content/widgets/tabbox.xml
toolkit/modules/PageMenu.jsm
toolkit/modules/PopupNotifications.jsm
toolkit/modules/SelectParentHelper.jsm
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -319,17 +319,17 @@ var gXPInstallObserver = {
       messageString = PluralForm.get(installInfo.installs.length, messageString);
       messageString = messageString.replace("#1", installInfo.installs.length);
       options.installs = installInfo.installs;
       options.contentWindow = browser.contentWindow;
       options.sourceURI = browser.currentURI;
       options.eventCallback = function(aEvent) {
         switch (aEvent) {
           case "shown":
-            let notificationElement = [...this.owner.panel.childNodes]
+            let notificationElement = [...this.owner.panel.children]
                                       .find(n => n.notification == this);
             if (notificationElement) {
               if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
                 notificationElement.setAttribute("mainactiondisabled", "true");
               } else {
                 notificationElement.button.hidden = true;
               }
             }
--- a/browser/base/content/browser-ctrlTab.js
+++ b/browser/base/content/browser-ctrlTab.js
@@ -260,18 +260,18 @@ var ctrlTab = {
   },
 
   updatePreview: function ctrlTab_updatePreview(aPreview, aTab) {
     if (aPreview == this.showAllButton)
       return;
 
     aPreview._tab = aTab;
 
-    if (aPreview._canvas.firstChild) {
-      aPreview._canvas.firstChild.remove();
+    if (aPreview._canvas.firstElementChild) {
+      aPreview._canvas.firstElementChild.remove();
     }
 
     if (aTab) {
       aPreview._canvas.appendChild(tabPreviews.get(aTab));
       aPreview._label.setAttribute("value", aTab.label);
       aPreview.setAttribute("tooltiptext", aTab.label);
       if (aTab.image) {
         aPreview._favicon.setAttribute("src", aTab.image);
--- a/browser/base/content/browser-customization.js
+++ b/browser/base/content/browser-customization.js
@@ -25,17 +25,17 @@ var CustomizationHandler = {
 
   isCustomizing() {
     return document.documentElement.hasAttribute("customizing");
   },
 
   _customizationStarting() {
     // Disable the toolbar context menu items
     let menubar = document.getElementById("main-menubar");
-    for (let childNode of menubar.childNodes)
+    for (let childNode of menubar.children)
       childNode.setAttribute("disabled", true);
 
     let cmd = document.getElementById("cmd_CustomizeToolbars");
     cmd.setAttribute("disabled", "true");
 
     UpdateUrlbarSearchSplitterState();
 
     PlacesToolbarHelper.customizeStart();
@@ -64,16 +64,16 @@ var CustomizationHandler = {
     UpdateUrlbarSearchSplitterState();
 
     // Update the urlbar
     URLBarSetURI();
     XULBrowserWindow.asyncUpdateUI();
 
     // Re-enable parts of the UI we disabled during the dialog
     let menubar = document.getElementById("main-menubar");
-    for (let childNode of menubar.childNodes)
+    for (let childNode of menubar.children)
       childNode.setAttribute("disabled", false);
     let cmd = document.getElementById("cmd_CustomizeToolbars");
     cmd.removeAttribute("disabled");
 
     gBrowser.selectedBrowser.focus();
   }
 };
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -1018,17 +1018,17 @@ BrowserPageActions.sendToDevice = {
     notReady.classList.add(
       "subviewbutton",
       "subviewbutton-iconic",
       "pageAction-sendToDevice-notReady"
     );
     notReady.setAttribute("label", "sendToDevice-notReadyTitle");
     notReady.setAttribute("disabled", "true");
     bodyNode.appendChild(notReady);
-    for (let node of bodyNode.childNodes) {
+    for (let node of bodyNode.children) {
       BrowserPageActions.takeNodeAttributeFromPanel(node, "title");
       BrowserPageActions.takeNodeAttributeFromPanel(node, "shortcut");
     }
   },
 
   onLocationChange() {
     let action = PageActions.actionForID("sendToDevice");
     let browser = gBrowser.selectedBrowser;
@@ -1213,17 +1213,17 @@ BrowserPageActions.shareURL = {
     BrowserPageActions.takeActionTitleFromPanel(action);
   },
 
   onShowingSubview(panelViewNode) {
     let bodyNode = panelViewNode.querySelector(".panel-subview-body");
 
     // We cache the providers + the UI if the user selects the share
     // panel multiple times while the panel is open.
-    if (this._cached && bodyNode.childNodes.length > 0) {
+    if (this._cached && bodyNode.children.length > 0) {
       return;
     }
 
     let sharingService = this._sharingService;
     let url = gBrowser.selectedBrowser.currentURI;
     let currentURI = gURLBar.makeURIReadable(url).displaySpec;
     let shareProviders = sharingService.getSharingProviders(currentURI);
     let fragment = document.createDocumentFragment();
--- a/browser/base/content/browser-sidebar.js
+++ b/browser/base/content/browser-sidebar.js
@@ -165,17 +165,17 @@ var SidebarUI = {
 
   /**
    * Read the positioning pref and position the sidebar and the splitter
    * appropriately within the browser container.
    */
   setPosition() {
     // First reset all ordinals to match DOM ordering.
     let browser = document.getElementById("browser");
-    [...browser.childNodes].forEach((node, i) => {
+    [...browser.children].forEach((node, i) => {
       node.ordinal = i + 1;
     });
 
     if (!this._positionStart) {
       // DOM ordering is:     |  sidebar-box  | splitter |   appcontent  |
       // Want to display as:  |   appcontent  | splitter |  sidebar-box  |
       // So we just swap box and appcontent ordering
       let appcontent = document.getElementById("appcontent");
--- a/browser/base/content/browser-sync.js
+++ b/browser/base/content/browser-sync.js
@@ -368,18 +368,18 @@ var gSync = {
     if (!createDeviceNodeFn) {
       createDeviceNodeFn = (clientId, name, clientType, lastModified) => {
         let eltName = name ? "menuitem" : "menuseparator";
         return document.createXULElement(eltName);
       };
     }
 
     // remove existing menu items
-    for (let i = devicesPopup.childNodes.length - 1; i >= 0; --i) {
-      let child = devicesPopup.childNodes[i];
+    for (let i = devicesPopup.children.length - 1; i >= 0; --i) {
+      let child = devicesPopup.children[i];
       if (child.classList.contains("sync-menuitem")) {
         child.remove();
       }
     }
 
     if (gSync.syncConfiguredAndLoading) {
       // We can only be in this case in the page action menu.
       return;
@@ -471,17 +471,17 @@ var gSync = {
     signInItem.setAttribute("label", signInToSync);
     // Show an icon if opened in the page action panel:
     if (signInItem.classList.contains("subviewbutton")) {
       signInItem.classList.add("subviewbutton-iconic", "signintosync");
     }
     signInItem.addEventListener("command", () => {
       this.openPrefs("sendtab");
     });
-    fragment.insertBefore(signInItem, fragment.lastChild);
+    fragment.insertBefore(signInItem, fragment.lastElementChild);
   },
 
   _appendSendTabInfoItems(fragment, createDeviceNodeFn, statusLabel, actions) {
     const status = createDeviceNodeFn(null, statusLabel, null);
     status.setAttribute("label", statusLabel);
     status.setAttribute("disabled", true);
     status.classList.add("sync-menuitem");
     fragment.appendChild(status);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -393,17 +393,17 @@ const gClickAndHoldListenersOnElement = 
 
   _mousedownHandler(aEvent) {
     if (aEvent.button != 0 ||
         aEvent.currentTarget.open ||
         aEvent.currentTarget.disabled)
       return;
 
     // Prevent the menupopup from opening immediately
-    aEvent.currentTarget.firstChild.hidden = true;
+    aEvent.currentTarget.firstElementChild.hidden = true;
 
     aEvent.currentTarget.addEventListener("mouseout", this);
     aEvent.currentTarget.addEventListener("mouseup", this);
     this._timers.set(aEvent.currentTarget, setTimeout((b) => this._openMenu(b), 500, aEvent.currentTarget));
   },
 
   _clickHandler(aEvent) {
     if (aEvent.button == 0 &&
@@ -420,17 +420,17 @@ const gClickAndHoldListenersOnElement = 
       // dom.click() triggers a command even if there is a click handler
       // however this can now be prevented with preventDefault().
       aEvent.preventDefault();
     }
   },
 
   _openMenu(aButton) {
     this._cancelHold(aButton);
-    aButton.firstChild.hidden = false;
+    aButton.firstElementChild.hidden = false;
     aButton.open = true;
   },
 
   _mouseoutHandler(aEvent) {
     let buttonRect = aEvent.currentTarget.getBoundingClientRect();
     if (aEvent.clientX >= buttonRect.left &&
         aEvent.clientX <= buttonRect.right &&
         aEvent.clientY >= buttonRect.bottom)
@@ -748,19 +748,19 @@ var gPopupBlockerObserver = {
       // Show the separator if we added any
       // showable popup addresses to the menu.
       if (foundUsablePopupURI)
         blockedPopupsSeparator.removeAttribute("hidden");
     }, null);
   },
 
   onPopupHiding(aEvent) {
-    let item = aEvent.target.lastChild;
+    let item = aEvent.target.lastElementChild;
     while (item && item.id != "blockedPopupsSeparator") {
-      let next = item.previousSibling;
+      let next = item.previousElementSibling;
       item.remove();
       item = next;
     }
   },
 
   showBlockedPopup(aEvent) {
     var target = aEvent.target;
     var popupReportIndex = target.getAttribute("popupReportIndex");
@@ -2762,26 +2762,26 @@ function UpdateUrlbarSearchSplitterState
     if (splitter) {
       splitter.remove();
     }
     return;
   }
 
   // If the splitter is already in the right place, we don't need to do anything:
   if (splitter &&
-      ((splitter.nextSibling == searchbar && splitter.previousSibling == urlbar) ||
-       (splitter.nextSibling == urlbar && splitter.previousSibling == searchbar))) {
+      ((splitter.nextElementSibling == searchbar && splitter.previousElementSibling == urlbar) ||
+       (splitter.nextElementSibling == urlbar && splitter.previousElementSibling == searchbar))) {
     return;
   }
 
   var ibefore = null;
   if (urlbar && searchbar) {
-    if (urlbar.nextSibling == searchbar)
+    if (urlbar.nextElementSibling == searchbar)
       ibefore = searchbar;
-    else if (searchbar.nextSibling == urlbar)
+    else if (searchbar.nextElementSibling == urlbar)
       ibefore = urlbar;
   }
 
   if (ibefore) {
     if (!splitter) {
       splitter = document.createXULElement("splitter");
       splitter.id = "urlbar-search-splitter";
       splitter.setAttribute("resizebefore", "flex");
@@ -4115,17 +4115,17 @@ function FillHistoryMenu(aParent) {
     aParent.addEventListener("DOMMenuItemInactive", function() {
       XULBrowserWindow.setOverLink("");
     });
 
     aParent.hasStatusListener = true;
   }
 
   // Remove old entries if any
-  let children = aParent.childNodes;
+  let children = aParent.children;
   for (var i = children.length - 1; i >= 0; --i) {
     if (children[i].hasAttribute("index"))
       aParent.removeChild(children[i]);
   }
 
   const MAX_HISTORY_MENU_ITEMS = 15;
 
   const tooltipBack = gNavigatorBundle.getString("tabHistory.goBack");
@@ -4199,17 +4199,17 @@ function FillHistoryMenu(aParent) {
       }
 
       existingIndex++;
     }
 
     if (!initial) {
       let existingLength = children.length;
       while (existingIndex < existingLength) {
-        aParent.removeChild(aParent.lastChild);
+        aParent.removeChild(aParent.lastElementChild);
         existingIndex++;
       }
     }
   }
 
   let sessionHistory = SessionStore.getSessionHistory(gBrowser.selectedTab, updateSessionHistory);
   if (!sessionHistory)
     return false;
@@ -5506,25 +5506,25 @@ nsBrowserAccess.prototype = {
 };
 
 function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
   var popup = aEvent.target;
   if (popup != aEvent.currentTarget)
     return;
 
   // Empty the menu
-  for (var i = popup.childNodes.length - 1; i >= 0; --i) {
-    var deadItem = popup.childNodes[i];
+  for (var i = popup.children.length - 1; i >= 0; --i) {
+    var deadItem = popup.children[i];
     if (deadItem.hasAttribute("toolbarId"))
       popup.removeChild(deadItem);
   }
 
-  var firstMenuItem = aInsertPoint || popup.firstChild;
-
-  let toolbarNodes = gNavToolbox.childNodes;
+  var firstMenuItem = aInsertPoint || popup.firstElementChild;
+
+  let toolbarNodes = gNavToolbox.children;
 
   for (let toolbar of toolbarNodes) {
     if (!toolbar.hasAttribute("toolbarname")) {
       continue;
     }
 
     let menuItem = document.createXULElement("menuitem");
     let hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
@@ -5550,17 +5550,17 @@ function onViewToolbarsPopupShowing(aEve
   if (!moveToPanel || !removeFromToolbar) {
     return;
   }
 
   // triggerNode can be a nested child element of a toolbaritem.
   let toolbarItem = popup.triggerNode;
 
   if (toolbarItem && toolbarItem.localName == "toolbarpaletteitem") {
-    toolbarItem = toolbarItem.firstChild;
+    toolbarItem = toolbarItem.firstElementChild;
   } else if (toolbarItem && toolbarItem.localName != "toolbar") {
     while (toolbarItem && toolbarItem.parentNode) {
       let parent = toolbarItem.parentNode;
       if (parent.nodeType !== Node.ELEMENT_NODE ||
           (parent.classList && parent.classList.contains("customization-target")) ||
           parent.getAttribute("overflowfortoolbar") || // Needs to work in the overflow list as well.
           parent.localName == "toolbarpaletteitem" ||
           parent.localName == "toolbar")
@@ -6234,17 +6234,17 @@ function onDownloadsAutoHideChange(event
   let autoHide = event.target.getAttribute("checked") == "true";
   Services.prefs.setBoolPref("browser.download.autohideButton", autoHide);
 }
 
 function getUnwrappedTriggerNode(popup) {
   // Toolbar buttons are wrapped in customize mode. Unwrap if necessary.
   let {triggerNode} = popup;
   if (triggerNode && gCustomizeMode.isWrappedToolbarItem(triggerNode)) {
-    return triggerNode.firstChild;
+    return triggerNode.firstElementChild;
   }
   return triggerNode;
 }
 
 function UpdateManageExtension(popup) {
   let checkbox = popup.querySelector(".customize-context-manageExtension");
   let separator = checkbox.nextElementSibling;
   let node = getUnwrappedTriggerNode(popup);
@@ -6331,21 +6331,21 @@ var gPageStyleMenu = {
       };
     }
 
     return data;
   },
 
   fillPopup(menuPopup) {
     let styleSheetInfo = this._getStyleSheetInfo(gBrowser.selectedBrowser);
-    var noStyle = menuPopup.firstChild;
-    var persistentOnly = noStyle.nextSibling;
-    var sep = persistentOnly.nextSibling;
-    while (sep.nextSibling)
-      menuPopup.removeChild(sep.nextSibling);
+    var noStyle = menuPopup.firstElementChild;
+    var persistentOnly = noStyle.nextElementSibling;
+    var sep = persistentOnly.nextElementSibling;
+    while (sep.nextElementSibling)
+      menuPopup.removeChild(sep.nextElementSibling);
 
     let styleSheets = styleSheetInfo.filteredStyleSheets;
     var currentStyleSheets = {};
     var styleDisabled = styleSheetInfo.authorStyleDisabled;
     var haveAltSheets = false;
     var altStyleSelected = false;
 
     for (let currentStyleSheet of styleSheets) {
@@ -8071,17 +8071,17 @@ TabModalPromptBox.prototype = {
     }
     onCloseCallback.apply(this, args);
   },
 
   appendPrompt(args, onCloseCallback) {
     const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
     let browser = this.browser;
-    browser.parentNode.insertBefore(newPrompt, browser.nextSibling);
+    browser.parentNode.insertBefore(newPrompt, browser.nextElementSibling);
     browser.setAttribute("tabmodalPromptShowing", true);
 
     newPrompt.clientTop; // style flush to assure binding is attached
 
     let prompts = this.listPrompts();
     if (prompts.length > 1) {
       // Let's hide ourself behind the current prompt.
       newPrompt.hidden = true;
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -204,17 +204,17 @@ window._gBrowser = {
 
   get tabContainer() {
     delete this.tabContainer;
     return this.tabContainer = document.getElementById("tabbrowser-tabs");
   },
 
   get tabs() {
     delete this.tabs;
-    return this.tabs = this.tabContainer.childNodes;
+    return this.tabs = this.tabContainer.children;
   },
 
   get tabbox() {
     delete this.tabbox;
     return this.tabbox = document.getElementById("tabbrowser-tabbox");
   },
 
   get tabpanels() {
@@ -312,17 +312,17 @@ window._gBrowser = {
     for (let attribute in this._defaultBrowserAttributes) {
       this._defaultBrowserAttributes[attribute] = browser.getAttribute(attribute);
     }
 
     let tab = this.tabs[0];
     this._selectedTab = tab;
 
     let uniqueId = this._generateUniquePanelID();
-    this.tabpanels.childNodes[0].id = uniqueId;
+    this.tabpanels.children[0].id = uniqueId;
     tab.linkedPanel = uniqueId;
     tab.permanentKey = browser.permanentKey;
     tab._tPos = 0;
     tab._fullyOpen = true;
     tab.linkedBrowser = browser;
     this._tabForBrowser.set(browser, tab);
 
     // Hook the browser up with a progress listener.
@@ -534,17 +534,17 @@ window._gBrowser = {
     aTab.dispatchEvent(event);
 
     return findBar;
   },
 
   _appendStatusPanel() {
     let browser = this.selectedBrowser;
     let browserContainer = this.getBrowserContainer(browser);
-    browserContainer.insertBefore(StatusPanel.panel, browser.parentNode.nextSibling);
+    browserContainer.insertBefore(StatusPanel.panel, browser.parentNode.nextElementSibling);
   },
 
   _updateTabBarForPinnedTabs() {
     this.tabContainer._unlockTabSizing();
     this.tabContainer._positionPinnedTabs();
     this.tabContainer._updateCloseButtons();
   },
 
@@ -3021,24 +3021,24 @@ window._gBrowser = {
       remainingTabs = Array.filter(this.tabs, function(tab) {
         return !tab.closing;
       }, this);
     }
 
     // Try to find a remaining tab that comes after the given tab
     let tab = aTab;
     do {
-      tab = tab.nextSibling;
+      tab = tab.nextElementSibling;
     } while (tab && !remainingTabs.includes(tab));
 
     if (!tab) {
       tab = aTab;
 
       do {
-        tab = tab.previousSibling;
+        tab = tab.previousElementSibling;
       } while (tab && !remainingTabs.includes(tab));
     }
 
     return tab;
   },
 
   _blurTab(aTab) {
     this.selectedTab = this._findTabToBlurTo(aTab);
@@ -3557,19 +3557,19 @@ window._gBrowser = {
     this.tabContainer._setPositionalAttributes();
 
     var evt = document.createEvent("UIEvents");
     evt.initUIEvent("TabMove", true, false, window, oldPosition);
     aTab.dispatchEvent(evt);
   },
 
   moveTabForward() {
-    let nextTab = this.selectedTab.nextSibling;
+    let nextTab = this.selectedTab.nextElementSibling;
     while (nextTab && nextTab.hidden)
-      nextTab = nextTab.nextSibling;
+      nextTab = nextTab.nextElementSibling;
 
     if (nextTab)
       this.moveTabTo(this.selectedTab, nextTab._tPos);
     else if (this.arrowKeysShouldWrap)
       this.moveTabToStart();
   },
 
   /**
@@ -3624,19 +3624,19 @@ window._gBrowser = {
       // for our new tab after we've done swapBrowsersAndCloseOther.
       this.updateCurrentBrowser(true);
     }
 
     return newTab;
   },
 
   moveTabBackward() {
-    let previousTab = this.selectedTab.previousSibling;
+    let previousTab = this.selectedTab.previousElementSibling;
     while (previousTab && previousTab.hidden)
-      previousTab = previousTab.previousSibling;
+      previousTab = previousTab.previousElementSibling;
 
     if (previousTab)
       this.moveTabTo(this.selectedTab, previousTab._tPos);
     else if (this.arrowKeysShouldWrap)
       this.moveTabToEnd();
   },
 
   moveTabToStart() {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -10,17 +10,17 @@
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="tabbrowser-arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox-clicktoscroll">
     <implementation>
       <!-- Override scrollbox.xml method, since our scrollbox's children are
            inherited from the binding parent -->
       <method name="_getScrollableElements">
         <body><![CDATA[
-          return Array.filter(document.getBindingParent(this).childNodes,
+          return Array.filter(document.getBindingParent(this).children,
                               this._canScrollToElement, this);
         ]]></body>
       </method>
       <method name="_canScrollToElement">
         <parameter name="tab"/>
         <body><![CDATA[
           return !tab._pinnedUnscrollable && !tab.hidden;
         ]]></body>
@@ -104,17 +104,17 @@
         <![CDATA[
           this._tabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
           this._hiddenSoundPlayingTabs = new Set();
 
           let strId = PrivateBrowsingUtils.isWindowPrivate(window) ?
               "emptyPrivateTabTitle" : "emptyTabTitle";
           this.emptyTabTitle = gTabBrowserBundle.GetStringFromName("tabs." + strId);
 
-          var tab = this.firstChild;
+          var tab = this.firstElementChild;
           tab.label = this.emptyTabTitle;
 
           window.addEventListener("resize", this);
 
           Services.prefs.addObserver("privacy.userContext", this);
           this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
 
           XPCOMUtils.defineLazyPreferenceGetter(this, "_tabMinWidthPref",
@@ -198,18 +198,18 @@
               const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button");
 
               for (let parent of [newTab, newTab2]) {
                 if (!parent)
                   continue;
 
                 gClickAndHoldListenersOnElement.remove(parent);
                 parent.removeAttribute("type");
-                if (parent.firstChild) {
-                  parent.firstChild.remove();
+                if (parent.firstElementChild) {
+                  parent.firstElementChild.remove();
                 }
 
                 if (containersEnabled) {
                   let popup = document.createElementNS(
                                 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                 "menupopup");
                   if (parent.id) {
                     popup.id = "newtab-popup";
@@ -246,17 +246,17 @@
           return document.documentElement.getAttribute("customizing") == "true";
         ]]></getter>
       </property>
 
       <method name="_getVisibleTabs">
         <body><![CDATA[
           // Cannot access gBrowser before it's initialized.
           if (!gBrowser) {
-            return [ this.firstChild ];
+            return [ this.firstElementChild ];
           }
 
           return gBrowser.visibleTabs;
         ]]></body>
       </method>
 
       <method name="_setPositionalAttributes">
         <body><![CDATA[
@@ -512,34 +512,34 @@
 
             let layoutData = this._pinnedTabsLayoutCache;
             let uiDensity = document.documentElement.getAttribute("uidensity");
             if (!layoutData ||
                 layoutData.uiDensity != uiDensity) {
               let arrowScrollbox = this.arrowScrollbox;
               layoutData = this._pinnedTabsLayoutCache = {
                 uiDensity,
-                pinnedTabWidth: this.childNodes[0].getBoundingClientRect().width,
+                pinnedTabWidth: this.children[0].getBoundingClientRect().width,
                 scrollButtonWidth: arrowScrollbox._scrollButtonDown.getBoundingClientRect().width
               };
             }
 
             let width = 0;
             for (let i = numPinned - 1; i >= 0; i--) {
-              let tab = this.childNodes[i];
+              let tab = this.children[i];
               width += layoutData.pinnedTabWidth;
               tab.style.marginInlineStart = -(width + layoutData.scrollButtonWidth) + "px";
               tab._pinnedUnscrollable = true;
             }
             this.style.paddingInlineStart = width + "px";
           } else {
             this.removeAttribute("positionpinnedtabs");
 
             for (let i = 0; i < numPinned; i++) {
-              let tab = this.childNodes[i];
+              let tab = this.children[i];
               tab.style.marginInlineStart = "";
               tab._pinnedUnscrollable = false;
             }
 
             this.style.paddingInlineStart = "";
           }
 
           if (this._lastNumPinned != numPinned) {
@@ -774,17 +774,17 @@
           return tab;
         ]]></body>
       </method>
 
       <method name="_getDropIndex">
         <parameter name="event"/>
         <parameter name="isLink"/>
         <body><![CDATA[
-          var tabs = this.childNodes;
+          var tabs = this.children;
           var tab = this._getDragTargetTab(event, isLink);
           if (window.getComputedStyle(this).direction == "ltr") {
             for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
               if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
                 return i;
           } else {
             for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
               if (event.screenX > tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
@@ -873,17 +873,17 @@
         <body>
         <![CDATA[
           if (!aTab) {
             return null;
           }
 
           // Cannot access gBrowser before it's initialized.
           if (!gBrowser) {
-            return this.tabbox.tabpanels.firstChild;
+            return this.tabbox.tabpanels.firstElementChild;
           }
 
           // If the tab's browser is lazy, we need to `_insertBrowser` in order
           // to have a linkedPanel.  This will also serve to bind the browser
           // and make it ready to use when the tab is selected.
           gBrowser._insertBrowser(aTab);
           return document.getElementById(aTab.linkedPanel);
         ]]>
@@ -1354,24 +1354,24 @@
           let maxMargin = Math.min(minMargin + scrollRect.width,
                                    scrollRect.right);
           if (!ltr)
             [minMargin, maxMargin] = [this.clientWidth - maxMargin,
                                       this.clientWidth - minMargin];
           newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
         } else {
           let newIndex = this._getDropIndex(event, effects == "link");
-          if (newIndex == this.childNodes.length) {
-            let tabRect = this.childNodes[newIndex - 1].getBoundingClientRect();
+          if (newIndex == this.children.length) {
+            let tabRect = this.children[newIndex - 1].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.right - rect.left;
             else
               newMargin = rect.right - tabRect.left;
           } else {
-            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
+            let tabRect = this.children[newIndex].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.left - rect.left;
             else
               newMargin = rect.right - tabRect.right;
           }
         }
 
         ind.collapsed = false;
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -106,29 +106,29 @@ file, You can obtain one at http://mozil
           var controller = document.commandDispatcher.getControllerForCommand("cmd_paste");
           var enabled = controller.isCommandEnabled("cmd_paste");
           if (enabled)
             pasteAndGo.removeAttribute("disabled");
           else
             pasteAndGo.setAttribute("disabled", "true");
         });
 
-        var insertLocation = cxmenu.firstChild;
-        while (insertLocation.nextSibling &&
+        var insertLocation = cxmenu.firstElementChild;
+        while (insertLocation.nextElementSibling &&
                insertLocation.getAttribute("cmd") != "cmd_paste")
-          insertLocation = insertLocation.nextSibling;
+          insertLocation = insertLocation.nextElementSibling;
         if (insertLocation) {
           pasteAndGo = document.createXULElement("menuitem");
           let label = Services.strings.createBundle("chrome://browser/locale/browser.properties").
                                    GetStringFromName("pasteAndGo.label");
           pasteAndGo.setAttribute("label", label);
           pasteAndGo.setAttribute("anonid", "paste-and-go");
           pasteAndGo.setAttribute("oncommand",
               "gURLBar.select(); goDoCommand('cmd_paste'); gURLBar.handleCommand();");
-          cxmenu.insertBefore(pasteAndGo, insertLocation.nextSibling);
+          cxmenu.insertBefore(pasteAndGo, insertLocation.nextElementSibling);
         }
 
         this.popup.addEventListener("popupshowing", () => {
           this._enableOrDisableOneOffSearches();
         }, {capture: true, once: true});
 
         // history dropmarker open state
         this.popup.addEventListener("popupshowing", () => {
@@ -2230,34 +2230,34 @@ file, You can obtain one at http://mozil
             window.windowUtils.getBoundsWithoutFlushing(document.getElementById("nav-bar")).bottom -
             window.windowUtils.getBoundsWithoutFlushing(aInput).bottom);
 
           this.openPopup(aElement, "after_start", 0, yOffset, false, false);
 
           // Do this immediately after we've requested the popup to open. This
           // will cause sync reflows but prevents flickering.
           if (needsHandleOverUnderflow) {
-            for (let item of this.richlistbox.childNodes) {
+            for (let item of this.richlistbox.children) {
               item.handleOverUnderflow();
             }
           }
         ]]></body>
       </method>
 
       <method name="adjustHeight">
         <body>
           <![CDATA[
           // If we were going to shrink later, cancel that for now:
           if (this._shrinkTimeout) {
             clearTimeout(this._shrinkTimeout);
             this._shrinkTimeout = null;
           }
           let lastRowCount = this._lastRowCount;
           // Figure out how many rows to show
-          let rows = this.richlistbox.childNodes;
+          let rows = this.richlistbox.children;
           this._lastRowCount = rows.length;
           let numRows = Math.min(this.matchCount, this.maxRows, rows.length);
 
           // If we're going from 0 to non-0 rows, we might need to remove
           // the height attribute to allow the popup to size. The attribute
           // is set from XUL popup management code.
           if (!lastRowCount && rows.length) {
             this.removeAttribute("height");
@@ -2386,17 +2386,17 @@ file, You can obtain one at http://mozil
           ]]>
         </body>
       </method>
 
       <method name="_selectedOneOffChanged">
         <body><![CDATA[
           // Update all searchengine result items to use the newly selected
           // engine.
-          for (let item of this.richlistbox.childNodes) {
+          for (let item of this.richlistbox.children) {
             if (item.collapsed) {
               break;
             }
             let url = item.getAttribute("url");
             if (url) {
               let action = item._parseActionUrl(url);
               if (action && action.type == "searchengine") {
                 item._adjustAcItem();
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -786,30 +786,30 @@ var CustomizableUIInternal = {
     // through a migration path (bug 938980) or an add-on.
     if (aArea == CustomizableUI.AREA_NAVBAR) {
       aAreaNode.collapsed = false;
     }
 
     this.beginBatchUpdate();
 
     try {
-      let currentNode = container.firstChild;
+      let currentNode = container.firstElementChild;
       let placementsToRemove = new Set();
       for (let id of aPlacements) {
         while (currentNode && currentNode.getAttribute("skipintoolbarset") == "true") {
-          currentNode = currentNode.nextSibling;
+          currentNode = currentNode.nextElementSibling;
         }
 
         // Fix ids for specials and continue, for correctly placed specials.
         if (currentNode && (!currentNode.id || CustomizableUI.isSpecialWidget(currentNode)) &&
             this.matchingSpecials(id, currentNode)) {
           currentNode.id = id;
         }
         if (currentNode && currentNode.id == id) {
-          currentNode = currentNode.nextSibling;
+          currentNode = currentNode.nextElementSibling;
           continue;
         }
 
         if (this.isSpecialWidget(id) && areaIsPanel) {
           placementsToRemove.add(id);
           continue;
         }
 
@@ -849,20 +849,20 @@ var CustomizableUIInternal = {
           this.notifyListeners("onWidgetReset", node, container);
         } else if (gUndoResetting) {
           this.notifyListeners("onWidgetUndoMove", node, container);
         }
       }
 
       if (currentNode) {
         let palette = aAreaNode.toolbox ? aAreaNode.toolbox.palette : null;
-        let limit = currentNode.previousSibling;
-        let node = container.lastChild;
+        let limit = currentNode.previousElementSibling;
+        let node = container.lastElementChild;
         while (node && node != limit) {
-          let previousSibling = node.previousSibling;
+          let previousSibling = node.previousElementSibling;
           // Nodes opt-in to removability. If they're removable, and we haven't
           // seen them in the placements array, then we toss them into the palette
           // if one exists. If no palette exists, we just remove the node. If the
           // node is not removable, we leave it where it is. However, we can only
           // safely touch elements that have an ID - both because we depend on
           // IDs (or are specials), and because such elements are not intended to
           // be widgets (eg, titlebar-placeholder elements).
           if ((node.id || this.isSpecialWidget(node)) &&
@@ -3898,17 +3898,17 @@ var CustomizableUI = {
     for (let menuChild of aMenuItems) {
       if (menuChild.hidden)
         continue;
 
       let subviewItem;
       if (menuChild.localName == "menuseparator") {
         // Don't insert duplicate or leading separators. This can happen if there are
         // menus (which we don't copy) above the separator.
-        if (!fragment.lastChild || fragment.lastChild.localName == "menuseparator") {
+        if (!fragment.lastElementChild || fragment.lastElementChild.localName == "menuseparator") {
           continue;
         }
         subviewItem = doc.createElementNS(kNSXUL, "menuseparator");
       } else if (menuChild.localName == "menuitem") {
         subviewItem = doc.createElementNS(kNSXUL, "toolbarbutton");
         CustomizableUI.addShortcut(menuChild, subviewItem);
 
         let item = menuChild;
@@ -4435,39 +4435,39 @@ OverflowableToolbar.prototype = {
    *        in some cases (e.g. when we run this method after overflow handling
    *        is re-enabled from customize mode, to ensure correct handling of
    *        initial overflow).
    */
   async onOverflow(aEvent) {
     if (!this._enabled)
       return;
 
-    let child = this._target.lastChild;
+    let child = this._target.lastElementChild;
 
     let thisOverflowResponse = ++this._lastOverflowCounter;
 
     let win = this._target.ownerGlobal;
     let [scrollLeftMin, scrollLeftMax] = await win.promiseDocumentFlushed(() => {
       return [this._target.scrollLeftMin, this._target.scrollLeftMax];
     });
     if (win.closed || this._lastOverflowCounter != thisOverflowResponse) {
       return;
     }
 
     while (child && scrollLeftMin != scrollLeftMax) {
-      let prevChild = child.previousSibling;
+      let prevChild = child.previousElementSibling;
 
       if (child.getAttribute("overflows") != "false") {
         this._collapsed.set(child.id, this._target.clientWidth);
         child.setAttribute("overflowedItem", true);
         child.setAttribute("cui-anchorid", this._chevron.id);
         CustomizableUIInternal.ensureButtonContextMenu(child, this._toolbar, true);
         CustomizableUIInternal.notifyListeners("onWidgetOverflow", child, this._target);
 
-        this._list.insertBefore(child, this._list.firstChild);
+        this._list.insertBefore(child, this._list.firstElementChild);
         if (!this._addedListener) {
           CustomizableUI.addListener(this);
         }
         if (!CustomizableUI.isSpecialWidget(child.id)) {
           this._toolbar.setAttribute("overflowing", "true");
         }
       }
       child = prevChild;
@@ -4508,18 +4508,18 @@ OverflowableToolbar.prototype = {
    *        While there are items in the list, this width won't change, and so
    *        we can avoid flushing layout by providing it and/or caching it.
    *        Note that if `shouldMoveAllItems` is true, we never need the width
    *        anyway.
    */
   _moveItemsBackToTheirOrigin(shouldMoveAllItems, targetWidth) {
     let placements = gPlacements.get(this._toolbar.id);
     let win = this._target.ownerGlobal;
-    while (this._list.firstChild) {
-      let child = this._list.firstChild;
+    while (this._list.firstElementChild) {
+      let child = this._list.firstElementChild;
       let minSize = this._collapsed.get(child.id);
 
       if (!shouldMoveAllItems && minSize) {
         if (!targetWidth) {
           let dwu = win.windowUtils;
           targetWidth = Math.floor(dwu.getBoundsWithoutFlushing(this._target).width);
         }
         if (targetWidth <= minSize) {
@@ -4603,26 +4603,26 @@ OverflowableToolbar.prototype = {
     if (aContainer != this._target && aContainer != this._list) {
       return;
     }
     // When we (re)move an item, update all the items that come after it in the list
     // with the minsize *of the item before the to-be-removed node*. This way, we
     // ensure that we try to move items back as soon as that's possible.
     if (aNode.parentNode == this._list) {
       let updatedMinSize;
-      if (aNode.previousSibling) {
-        updatedMinSize = this._collapsed.get(aNode.previousSibling.id);
+      if (aNode.previousElementSibling) {
+        updatedMinSize = this._collapsed.get(aNode.previousElementSibling.id);
       } else {
         // Force (these) items to try to flow back into the bar:
         updatedMinSize = 1;
       }
-      let nextItem = aNode.nextSibling;
+      let nextItem = aNode.nextElementSibling;
       while (nextItem) {
         this._collapsed.set(nextItem.id, updatedMinSize);
-        nextItem = nextItem.nextSibling;
+        nextItem = nextItem.nextElementSibling;
       }
     }
   },
 
   onWidgetAfterDOMChange(aNode, aNextNode, aContainer) {
     if (aContainer != this._target && aContainer != this._list) {
       return;
     }
@@ -4632,17 +4632,17 @@ OverflowableToolbar.prototype = {
     let wasOverflowed = this._collapsed.has(aNode.id);
 
     // If this wasn't overflowed before...
     if (!wasOverflowed) {
       // ... but it is now, then we added to the overflow panel. Exciting stuff:
       if (nowOverflowed) {
         // NB: we're guaranteed that it has a previousSibling, because if it didn't,
         // we would have added it to the toolbar instead. See getOverflowedNextNode.
-        let prevId = aNode.previousSibling.id;
+        let prevId = aNode.previousElementSibling.id;
         let minSize = this._collapsed.get(prevId);
         this._collapsed.set(aNode.id, minSize);
         aNode.setAttribute("cui-anchorid", this._chevron.id);
         aNode.setAttribute("overflowedItem", true);
         CustomizableUIInternal.ensureButtonContextMenu(aNode, aContainer, true);
         CustomizableUIInternal.notifyListeners("onWidgetOverflow", aNode, this._target);
       } else if (!nowInBar) {
         // If it is not overflowed and not in the toolbar, and was not overflowed
@@ -4664,19 +4664,19 @@ OverflowableToolbar.prototype = {
       let collapsedWidgetIds = Array.from(this._collapsed.keys());
       if (collapsedWidgetIds.every(w => CustomizableUI.isSpecialWidget(w))) {
         this._toolbar.removeAttribute("overflowing");
       }
       if (this._addedListener && !this._collapsed.size) {
         CustomizableUI.removeListener(this);
         this._addedListener = false;
       }
-    } else if (aNode.previousSibling) {
+    } else if (aNode.previousElementSibling) {
       // but if it still is, it must have changed places. Bookkeep:
-      let prevId = aNode.previousSibling.id;
+      let prevId = aNode.previousElementSibling.id;
       let minSize = this._collapsed.get(prevId);
       this._collapsed.set(aNode.id, minSize);
     } else {
       // If it's now the first item in the overflow list,
       // maybe we can return it:
       this._moveItemsBackToTheirOrigin(false);
     }
   },
@@ -4740,17 +4740,17 @@ OverflowableToolbar.prototype = {
   _hideTimeoutId: null,
   _showWithTimeout() {
     this.show().then(() => {
       let window = this._toolbar.ownerGlobal;
       if (this._hideTimeoutId) {
         window.clearTimeout(this._hideTimeoutId);
       }
       this._hideTimeoutId = window.setTimeout(() => {
-        if (!this._panel.firstChild.matches(":hover")) {
+        if (!this._panel.firstElementChild.matches(":hover")) {
           PanelMultiView.hidePopup(this._panel);
         }
       }, OVERFLOW_PANEL_HIDE_DELAY_MS);
     });
   },
 };
 
 CustomizableUIInternal.initialize();
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -142,17 +142,17 @@ const CustomizableWidgets = [
       if (!elementCount)
         return;
 
       let body = document.createElement("vbox");
       body.className = "panel-subview-body";
       body.appendChild(fragment);
       let footer;
       while (--elementCount >= 0) {
-        let element = body.childNodes[elementCount];
+        let element = body.children[elementCount];
         CustomizableUI.addShortcut(element);
         element.classList.add("subviewbutton");
         if (element.classList.contains("restoreallitem")) {
           footer = element;
           element.classList.add("panel-subview-footer");
         } else {
           element.classList.add("subviewbutton-iconic", "bookmark-item");
         }
@@ -396,29 +396,29 @@ const CustomizableWidgets = [
       }
     },
     updateCurrentCharset(aDocument) {
       let currentCharset = aDocument.defaultView.gBrowser.selectedBrowser.characterSet;
       currentCharset = CharsetMenu.foldCharset(currentCharset);
 
       let pinnedContainer = aDocument.getElementById("PanelUI-characterEncodingView-pinned");
       let charsetContainer = aDocument.getElementById("PanelUI-characterEncodingView-charsets");
-      let elements = [...(pinnedContainer.childNodes), ...(charsetContainer.childNodes)];
+      let elements = [...(pinnedContainer.children), ...(charsetContainer.children)];
 
       this._updateElements(elements, currentCharset);
     },
     updateCurrentDetector(aDocument) {
       let detectorContainer = aDocument.getElementById("PanelUI-characterEncodingView-autodetect");
       let currentDetector;
       try {
         currentDetector = Services.prefs.getComplexValue(
           "intl.charset.detector", Ci.nsIPrefLocalizedString).data;
       } catch (e) {}
 
-      this._updateElements(detectorContainer.childNodes, currentDetector);
+      this._updateElements(detectorContainer.children, currentDetector);
     },
     _updateElements(aElements, aCurrentItem) {
       if (!aElements.length) {
         return;
       }
       let disabled = this.maybeDisableMenu(aElements[0].ownerDocument);
       for (let elem of aElements) {
         if (disabled) {
@@ -638,17 +638,17 @@ if (Services.prefs.getBoolPref("identity
 
         this.setDeckIndex(this.deckIndices.DECKINDEX_TABS);
         this._clearTabList();
         SyncedTabs.sortTabClientsByLastUsed(clients);
         let fragment = doc.createDocumentFragment();
 
         for (let client of clients) {
           // add a menu separator for all clients other than the first.
-          if (fragment.lastChild) {
+          if (fragment.lastElementChild) {
             let separator = doc.createElementNS(kNSXUL, "menuseparator");
             fragment.appendChild(separator);
           }
           if (paginationInfo && paginationInfo.clientId == client.id) {
             this._appendClient(client, fragment, paginationInfo.maxTabs);
           } else {
             this._appendClient(client, fragment);
           }
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -436,17 +436,17 @@ CustomizeMode.prototype = {
       // And drop all area references.
       this.areas.clear();
 
       // Let everybody in this window know that we're starting to
       // exit customization mode.
       CustomizableUI.dispatchToolboxEvent("customizationending", {}, window);
 
       window.PanelUI.menuButton.disabled = false;
-      let overflowContainer = document.getElementById("widget-overflow-mainView").firstChild;
+      let overflowContainer = document.getElementById("widget-overflow-mainView").firstElementChild;
       overflowContainer.appendChild(window.PanelUI.overflowFixedList);
       document.getElementById("nav-bar-overflow-button").disabled = false;
       let panelContextMenu = document.getElementById(kPanelItemContextMenu);
       this._previousPanelContextMenuParent.appendChild(panelContextMenu);
 
       // We need to set this._customizing to false before removing the tab
       // or the TabSelect event handler will think that we are exiting
       // customization mode for a second time.
@@ -579,18 +579,18 @@ CustomizeMode.prototype = {
           animationNode.addEventListener("animationend", cleanupWidgetAnimationEnd);
         });
       });
     });
   },
 
   async addToToolbar(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
-    if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
-      aNode = aNode.firstChild;
+    if (aNode.localName == "toolbarpaletteitem" && aNode.firstElementChild) {
+      aNode = aNode.firstElementChild;
     }
     let widgetAnimationPromise = this._promiseWidgetAnimationOut(aNode);
     if (widgetAnimationPromise) {
       await widgetAnimationPromise;
     }
 
     let widgetToAdd = aNode.id;
     if (CustomizableUI.isSpecialWidget(widgetToAdd) && aNode.closest("#customization-palette")) {
@@ -616,18 +616,18 @@ CustomizeMode.prototype = {
       } else {
         aNode.classList.remove("animate-out");
       }
     }
   },
 
   async addToPanel(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
-    if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
-      aNode = aNode.firstChild;
+    if (aNode.localName == "toolbarpaletteitem" && aNode.firstElementChild) {
+      aNode = aNode.firstElementChild;
     }
     let widgetAnimationPromise = this._promiseWidgetAnimationOut(aNode);
     if (widgetAnimationPromise) {
       await widgetAnimationPromise;
     }
 
     let panel = CustomizableUI.AREA_FIXED_OVERFLOW_PANEL;
     CustomizableUI.addWidgetToArea(aNode.id, panel);
@@ -664,18 +664,18 @@ CustomizeMode.prototype = {
           }
         });
       });
     }
   },
 
   async removeFromArea(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
-    if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
-      aNode = aNode.firstChild;
+    if (aNode.localName == "toolbarpaletteitem" && aNode.firstElementChild) {
+      aNode = aNode.firstElementChild;
     }
     let widgetAnimationPromise = this._promiseWidgetAnimationOut(aNode);
     if (widgetAnimationPromise) {
       await widgetAnimationPromise;
     }
 
     CustomizableUI.removeWidgetFromArea(aNode.id);
     if (!this._customizing) {
@@ -741,21 +741,21 @@ CustomizeMode.prototype = {
     let wrapper = this.createOrUpdateWrapper(widgetNode, aPlace);
     wrapper.appendChild(widgetNode);
     return wrapper;
   },
 
   depopulatePalette() {
     return (async () => {
       this.visiblePalette.hidden = true;
-      let paletteChild = this.visiblePalette.firstChild;
+      let paletteChild = this.visiblePalette.firstElementChild;
       let nextChild;
       while (paletteChild) {
         nextChild = paletteChild.nextElementSibling;
-        let itemId = paletteChild.firstChild.id;
+        let itemId = paletteChild.firstElementChild.id;
         if (CustomizableUI.isSpecialWidget(itemId)) {
           this.visiblePalette.removeChild(paletteChild);
         } else {
           // XXXunf Currently this doesn't destroy the (now unused) node in the
           //       API provider case. It would be good to do so, but we need to
           //       keep strong refs to it in CustomizableUI (can't iterate of
           //       WeakMaps), and there's the question of what behavior
           //       wrappers should have if consumers keep hold of them.
@@ -920,17 +920,17 @@ CustomizeMode.prototype = {
     if (aWrapper.nodeName != "toolbarpaletteitem") {
       return aWrapper;
     }
     aWrapper.removeEventListener("mousedown", this);
     aWrapper.removeEventListener("mouseup", this);
 
     let place = aWrapper.getAttribute("place");
 
-    let toolbarItem = aWrapper.firstChild;
+    let toolbarItem = aWrapper.firstElementChild;
     if (!toolbarItem) {
       log.error("no toolbarItem child for " + aWrapper.tagName + "#" + aWrapper.id);
       aWrapper.remove();
       return null;
     }
 
     if (aWrapper.hasAttribute("itemobserves")) {
       toolbarItem.setAttribute("observes", aWrapper.getAttribute("itemobserves"));
@@ -1454,27 +1454,27 @@ CustomizeMode.prototype = {
         LightweightThemeManager.setLocalTheme(button.theme);
         recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.theme.id; });
         lwthemePrefs.setStringPref("recommendedThemes",
                                    JSON.stringify(recommendedThemes));
         onThemeSelected(panel);
       });
       panel.insertBefore(button, footer);
     }
-    let hideRecommendedLabel = (footer.previousSibling == recommendedLabel);
+    let hideRecommendedLabel = (footer.previousElementSibling == recommendedLabel);
     recommendedLabel.hidden = hideRecommendedLabel;
   },
 
   _clearLWThemesMenu(panel) {
     let footer = this.$("customization-lwtheme-menu-footer");
     let recommendedLabel = this.$("customization-lwtheme-menu-recommended");
     for (let element of [footer, recommendedLabel]) {
-      while (element.previousSibling &&
-             element.previousSibling.localName == "toolbarbutton") {
-        element.previousSibling.remove();
+      while (element.previousElementSibling &&
+             element.previousElementSibling.localName == "toolbarbutton") {
+        element.previousElementSibling.remove();
       }
     }
 
     // Workaround for bug 1059934
     panel.removeAttribute("height");
   },
 
   _onUIChange() {
@@ -1662,17 +1662,17 @@ CustomizeMode.prototype = {
     while (item && item.localName != "toolbarpaletteitem") {
       if (item.localName == "toolbar" || item.id == kPaletteId ||
           item.id == "customization-panelHolder") {
         return;
       }
       item = item.parentNode;
     }
 
-    let draggedItem = item.firstChild;
+    let draggedItem = item.firstElementChild;
     let placeForItem = CustomizableUI.getPlaceForItem(item);
 
     let dt = aEvent.dataTransfer;
     let documentId = aEvent.target.ownerDocument.documentElement.id;
 
     dt.mozSetDataAt(kDragDataTypePrefix + documentId, draggedItem.id, 0);
     dt.effectAllowed = "move";
 
@@ -1695,22 +1695,22 @@ CustomizeMode.prototype = {
     this._initializeDragAfterMove = () => {
       // For automated tests, we sometimes start exiting customization mode
       // before this fires, which leaves us with placeholders inserted after
       // we've exited. So we need to check that we are indeed customizing.
       if (this._customizing && !this._transitioning) {
         item.hidden = true;
         DragPositionManager.start(this.window);
         let canUsePrevSibling = placeForItem == "toolbar" || placeForItem == "menu-panel";
-        if (item.nextSibling) {
-          this._setDragActive(item.nextSibling, "before", draggedItem.id, placeForItem);
-          this._dragOverItem = item.nextSibling;
-        } else if (canUsePrevSibling && item.previousSibling) {
-          this._setDragActive(item.previousSibling, "after", draggedItem.id, placeForItem);
-          this._dragOverItem = item.previousSibling;
+        if (item.nextElementSibling) {
+          this._setDragActive(item.nextElementSibling, "before", draggedItem.id, placeForItem);
+          this._dragOverItem = item.nextElementSibling;
+        } else if (canUsePrevSibling && item.previousElementSibling) {
+          this._setDragActive(item.previousElementSibling, "after", draggedItem.id, placeForItem);
+          this._dragOverItem = item.previousElementSibling;
         }
         let currentArea = this._getCustomizableParent(item);
         currentArea.setAttribute("draggingover", "true");
       }
       this._initializeDragAfterMove = null;
       this.window.clearTimeout(this._dragInitializeTimeout);
     };
     this._dragInitializeTimeout = this.window.setTimeout(this._initializeDragAfterMove, 0);
@@ -1760,27 +1760,27 @@ CustomizeMode.prototype = {
 
     // We need to determine the place that the widget is being dropped in
     // the target.
     let dragOverItem, dragValue;
     if (targetNode == targetArea.customizationTarget) {
       // We'll assume if the user is dragging directly over the target, that
       // they're attempting to append a child to that target.
       dragOverItem = (targetAreaType == "toolbar"
-                        ? this._findVisiblePreviousSiblingNode(targetNode.lastChild)
-                        : targetNode.lastChild) ||
+                        ? this._findVisiblePreviousSiblingNode(targetNode.lastElementChild)
+                        : targetNode.lastElementChild) ||
                      targetNode;
       dragValue = "after";
     } else {
       let targetParent = targetNode.parentNode;
       let position = Array.indexOf(targetParent.children, targetNode);
       if (position == -1) {
         dragOverItem = (targetAreaType == "toolbar"
-                          ? this._findVisiblePreviousSiblingNode(targetNode.lastChild)
-                          : targetNode.lastChild);
+                          ? this._findVisiblePreviousSiblingNode(targetNode.lastElementChild)
+                          : targetNode.lastElementChild);
         dragValue = "after";
       } else {
         dragOverItem = targetParent.children[position];
         if (targetAreaType == "toolbar") {
           // Check if the aDraggedItem is hovered past the first half of dragOverItem
           let itemRect = this._getBoundsWithoutFlushing(dragOverItem);
           let dropTargetCenter = itemRect.left + (itemRect.width / 2);
           let existingDir = dragOverItem.getAttribute("dragover");
@@ -1846,24 +1846,24 @@ CustomizeMode.prototype = {
     // Do nothing if the target area or origin area are not customizable.
     if (!targetArea || !originArea) {
       return;
     }
     let targetNode = this._dragOverItem;
     let dropDir = targetNode.getAttribute("dragover");
     // Need to insert *after* this node if we promised the user that:
     if (targetNode != targetArea && dropDir == "after") {
-      if (targetNode.nextSibling) {
-        targetNode = targetNode.nextSibling;
+      if (targetNode.nextElementSibling) {
+        targetNode = targetNode.nextElementSibling;
       } else {
         targetNode = targetArea;
       }
     }
     if (targetNode.tagName == "toolbarpaletteitem") {
-      targetNode = targetNode.firstChild;
+      targetNode = targetNode.firstElementChild;
     }
 
     this._cancelDragActive(this._dragOverItem, null, true);
 
     try {
       this._applyDrop(aEvent, targetArea, originArea, draggedItemId, targetNode);
     } catch (ex) {
       log.error(ex, ex.stack);
@@ -1954,24 +1954,24 @@ CustomizeMode.prototype = {
     // We need to determine the place that the widget is being dropped in
     // the target.
     let placement;
     let itemForPlacement = aTargetNode;
     // Skip the skipintoolbarset items when determining the place of the item:
     while (itemForPlacement && itemForPlacement.getAttribute("skipintoolbarset") == "true" &&
            itemForPlacement.parentNode &&
            itemForPlacement.parentNode.nodeName == "toolbarpaletteitem") {
-      itemForPlacement = itemForPlacement.parentNode.nextSibling;
+      itemForPlacement = itemForPlacement.parentNode.nextElementSibling;
       if (itemForPlacement && itemForPlacement.nodeName == "toolbarpaletteitem") {
-        itemForPlacement = itemForPlacement.firstChild;
+        itemForPlacement = itemForPlacement.firstElementChild;
       }
     }
     if (itemForPlacement) {
       let targetNodeId = (itemForPlacement.nodeName == "toolbarpaletteitem") ?
-                            itemForPlacement.firstChild && itemForPlacement.firstChild.id :
+                            itemForPlacement.firstElementChild && itemForPlacement.firstElementChild.id :
                             itemForPlacement.id;
       placement = CustomizableUI.getPlacementOfWidget(targetNodeId);
     }
     if (!placement) {
       log.debug("Could not get a position for " + aTargetNode.nodeName + "#" + aTargetNode.id + "." + aTargetNode.className);
     }
     let position = placement ? placement.position : null;
 
@@ -2188,17 +2188,17 @@ CustomizeMode.prototype = {
     let currentArea = this._getCustomizableParent(aDraggedItem);
     // Return the size for this target from cache, if it exists.
     let size = itemMap.get(targetArea);
     if (size)
       return size;
 
     // Calculate size of the item when it'd be dropped in this position.
     let currentParent = aDraggedItem.parentNode;
-    let currentSibling = aDraggedItem.nextSibling;
+    let currentSibling = aDraggedItem.nextElementSibling;
     const kAreaType = "cui-areatype";
     let areaType, currentType;
 
     if (targetArea != currentArea) {
       // Move the widget temporarily next to the placeholder.
       aDragOverNode.parentNode.insertBefore(aDraggedItem, aDragOverNode);
       // Update the node's areaType.
       areaType = CustomizableUI.getAreaType(targetArea.id);
@@ -2317,18 +2317,18 @@ CustomizeMode.prototype = {
       aElement = aElement.parentNode;
     }
     return aElement;
   },
 
   _findVisiblePreviousSiblingNode(aReferenceNode) {
     while (aReferenceNode &&
            aReferenceNode.localName == "toolbarpaletteitem" &&
-           aReferenceNode.firstChild.hidden) {
-      aReferenceNode = aReferenceNode.previousSibling;
+           aReferenceNode.firstElementChild.hidden) {
+      aReferenceNode = aReferenceNode.previousElementSibling;
     }
     return aReferenceNode;
   },
 
   onPaletteContextMenuShowing(event) {
    let isFlexibleSpace = event.target.triggerNode.id.includes("wrapper-customizableui-special-spring");
    event.target.querySelector(".customize-context-addToPanel").disabled = isFlexibleSpace;
  },
--- a/browser/components/customizableui/DragPositionManager.jsm
+++ b/browser/components/customizableui/DragPositionManager.jsm
@@ -86,17 +86,17 @@ AreaPositionManager.prototype = {
       let targetBounds = this._lazyStoreGet(closest);
       let farSide = this._dir == "ltr" ? "right" : "left";
       let outsideX = targetBounds[farSide];
       // Check if we're closer to the next target than to this one:
       // Only move if we're not targeting a node in a different row:
       if (aY > targetBounds.top && aY < targetBounds.bottom) {
         if ((this._dir == "ltr" && aX > outsideX) ||
             (this._dir == "rtl" && aX < outsideX)) {
-          return closest.nextSibling || aContainer;
+          return closest.nextElementSibling || aContainer;
         }
       }
     }
     return closest;
   },
 
   /**
    * "Insert" a "placeholder" by shifting the subsequent children out of the
@@ -123,20 +123,20 @@ AreaPositionManager.prototype = {
         }
         // Determine the CSS transform based on the next node:
         child.style.transform = this._diffWithNext(child, aSize);
       } else {
         // If we're not shifting this node, reset the transform
         child.style.transform = "";
       }
     }
-    if (aContainer.lastChild && aIsFromThisArea &&
+    if (aContainer.lastElementChild && aIsFromThisArea &&
         !this._lastPlaceholderInsertion) {
       // Flush layout:
-      aContainer.lastChild.getBoundingClientRect();
+      aContainer.lastElementChild.getBoundingClientRect();
       // then remove all the [notransition]
       for (let child of aContainer.children) {
         child.removeAttribute("notransition");
       }
     }
     this._lastPlaceholderInsertion = aBefore;
   },
 
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -567,19 +567,19 @@ var PanelMultiView = class extends Assoc
    * sure they will not be removed together with the <panelmultiview> element.
    */
   _moveOutKids() {
     let viewCacheId = this.node.getAttribute("viewCacheId");
     if (!viewCacheId) {
       return;
     }
 
-    // Node.children and Node.childNodes is live to DOM changes like the
+    // Node.children and Node.children is live to DOM changes like the
     // ones we're about to do, so iterate over a static copy:
-    let subviews = Array.from(this._viewStack.childNodes);
+    let subviews = Array.from(this._viewStack.children);
     let viewCache = this.document.getElementById(viewCacheId);
     for (let subview of subviews) {
       viewCache.appendChild(subview);
     }
   }
 
   /**
    * Slides in the specified view as a subview.
@@ -870,17 +870,17 @@ var PanelMultiView = class extends Assoc
       // getter also provides an indication that the view node shouldn't be
       // moved around, otherwise the state of the browser would get disrupted.
       let width = prevPanelView.knownWidth;
       let height = prevPanelView.knownHeight;
       viewRect = Object.assign({height, width}, viewNode.customRectGetter());
       nextPanelView.visible = true;
       // Until the header is visible, it has 0 height.
       // Wait for layout before measuring it
-      let header = viewNode.firstChild;
+      let header = viewNode.firstElementChild;
       if (header && header.classList.contains("panel-header")) {
         viewRect.height += await window.promiseDocumentFlushed(() => {
           return this._dwu.getBoundsWithoutFlushing(header).height;
         });
       }
       await nextPanelView.descriptionHeightWorkaround();
     } else {
       this._offscreenViewStack.style.minHeight = olderView.knownHeight + "px";
@@ -1198,17 +1198,17 @@ var PanelView = class extends Associated
     }
   }
 
   /**
    * Adds a header with the given title, or removes it if the title is empty.
    */
   set headerText(value) {
     // If the header already exists, update or remove it as requested.
-    let header = this.node.firstChild;
+    let header = this.node.firstElementChild;
     if (header && header.classList.contains("panel-header")) {
       if (value) {
         header.querySelector("label").setAttribute("value", value);
       } else {
         header.remove();
       }
       return;
     }
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -94,17 +94,17 @@ const PanelUI = {
     for (let event of this.kEvents) {
       this.notificationPanel.addEventListener(event, this);
     }
 
     // We do this sync on init because in order to have the overflow button show up
     // we need to know whether anything is in the permanent panel area.
     this.overflowFixedList.hidden = false;
     // Also unhide the separator. We use CSS to hide/show it based on the panel's content.
-    this.overflowFixedList.previousSibling.hidden = false;
+    this.overflowFixedList.previousElementSibling.hidden = false;
     CustomizableUI.registerMenuPanel(this.overflowFixedList, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
     this.updateOverflowStatus();
 
     Services.obs.notifyObservers(null, "appMenu-notifications-request", "refresh");
 
     this._initialized = true;
   },
 
@@ -503,18 +503,18 @@ const PanelUI = {
     // panel is shown, so their space is reserved. The part of this function
     // that adds the elements is the least expensive anyways.
     this.clearLibraryRecentHighlights();
     if (!highlights.length) {
       return;
     }
 
     let container = this.libraryRecentHighlights;
-    container.hidden = container.previousSibling.hidden =
-      container.previousSibling.previousSibling.hidden = false;
+    container.hidden = container.previousElementSibling.hidden =
+      container.previousElementSibling.previousElementSibling.hidden = false;
     let fragment = document.createDocumentFragment();
     for (let highlight of highlights) {
       let button = document.createElement("toolbarbutton");
       button.classList.add("subviewbutton", "highlight", "subviewbutton-iconic", "bookmark-item");
       let title = highlight.title || highlight.url;
       button.setAttribute("label", title);
       button.setAttribute("tooltiptext", title);
       button.setAttribute("type", "highlight-" + highlight.type);
@@ -542,18 +542,18 @@ const PanelUI = {
   /**
    * Remove all the nodes from the 'Recent Highlights' section and hide it as well.
    */
   clearLibraryRecentHighlights() {
     let container = this.libraryRecentHighlights;
     while (container.firstChild) {
       container.firstChild.remove();
     }
-    container.hidden = container.previousSibling.hidden =
-      container.previousSibling.previousSibling.hidden = true;
+    container.hidden = container.previousElementSibling.hidden =
+      container.previousElementSibling.previousElementSibling.hidden = true;
   },
 
   /**
    * Event handler; invoked when an item of the Recent Highlights is clicked.
    *
    * @param {MouseEvent} event Click event, originating from the Highlight.
    */
   onLibraryHighlightClick(event) {
--- a/browser/components/customizableui/content/toolbar.xml
+++ b/browser/components/customizableui/content/toolbar.xml
@@ -25,17 +25,17 @@
                 toolbox.palette = node;
                 toolbox.removeChild(node);
                 break;
               }
             }
           }
 
           // pass the current set of children for comparison with placements:
-          let children = Array.from(this.childNodes)
+          let children = Array.from(this.children)
                               .filter(node => node.getAttribute("skipintoolbarset") != "true" && node.id)
                               .map(node => node.id);
           CustomizableUI.registerToolbarNode(this, children);
       ]]></constructor>
 
       <method name="insertItem">
         <parameter name="aId"/>
         <parameter name="aBeforeElt"/>
@@ -104,26 +104,26 @@
           return this._toolbox;
         ]]></getter>
       </property>
 
       <property name="currentSet">
         <getter><![CDATA[
           let currentWidgets = new Set();
           for (let node of this.customizationTarget.children) {
-            let realNode = node.localName == "toolbarpaletteitem" ? node.firstChild : node;
+            let realNode = node.localName == "toolbarpaletteitem" ? node.firstElementChild : node;
             if (realNode.getAttribute("skipintoolbarset") != "true") {
               currentWidgets.add(realNode.id);
             }
           }
           if (this.getAttribute("overflowing") == "true") {
             let overflowTarget = this.getAttribute("overflowtarget");
             let overflowList = this.ownerDocument.getElementById(overflowTarget);
             for (let node of overflowList.children) {
-              let realNode = node.localName == "toolbarpaletteitem" ? node.firstChild : node;
+              let realNode = node.localName == "toolbarpaletteitem" ? node.firstElementChild : node;
               if (realNode.getAttribute("skipintoolbarset") != "true") {
                 currentWidgets.add(realNode.id);
               }
             }
           }
           let orderedPlacements = CustomizableUI.getWidgetIdsInArea(this.id);
           return orderedPlacements.filter(w => currentWidgets.has(w)).join(",");
         ]]></getter>
--- a/browser/components/downloads/DownloadsSubview.jsm
+++ b/browser/components/downloads/DownloadsSubview.jsm
@@ -58,17 +58,17 @@ class DownloadsSubview extends Downloads
       contextMenu.setAttribute("closemenu", "none");
       contextMenu.setAttribute("id", this.context);
       contextMenu.removeAttribute("onpopupshown");
       contextMenu.setAttribute("onpopupshowing",
         "DownloadsSubview.updateContextMenu(document.popupNode, this);");
       contextMenu.setAttribute("onpopuphidden", "DownloadsSubview.onContextMenuHidden(this);");
       let clearButton = contextMenu.querySelector("menuitem[command='downloadsCmd_clearDownloads']");
       clearButton.hidden = false;
-      clearButton.previousSibling.hidden = true;
+      clearButton.previousElementSibling.hidden = true;
       contextMenu.querySelector("menuitem[command='cmd_delete']")
         .setAttribute("command", "downloadsCmd_delete");
     }
     this.panelview.appendChild(contextMenu);
     this.container.setAttribute("context", this.context);
 
     this._downloadsData = DownloadsCommon.getData(this.window, true, true, true);
     this._downloadsData.addView(this);
@@ -96,17 +96,17 @@ class DownloadsSubview extends Downloads
    * downloads.
    */
   onDownloadBatchEnded() {
     let {window} = this;
     window.clearTimeout(this._batchTimeout);
     let waitForMs = 200;
     if (this.batchFragment.childElementCount) {
       // Prepend the batch fragment.
-      this.container.insertBefore(this.batchFragment, this.container.firstChild || null);
+      this.container.insertBefore(this.batchFragment, this.container.firstElementChild || null);
       waitForMs = 0;
     }
     // Wait a wee bit to dispatch the event, because another batch may start
     // right away.
     this._batchTimeout = window.setTimeout(() => {
       this._updateStatsFromDisk();
       this.panelview.dispatchEvent(new window.CustomEvent("DownloadsLoaded"));
     }, waitForMs);
@@ -169,17 +169,17 @@ class DownloadsSubview extends Downloads
       let idleOptions = { timeout: kMaxWaitForIdleMs };
       // Start with getting an idle moment to (maybe) refresh the list of downloads.
       await new Promise(resolve => this.window.requestIdleCallback(resolve), idleOptions);
       // In the meantime, this instance could have been destroyed, so take note.
       if (this.destroyed)
         return;
 
       let count = 0;
-      for (let button of this.container.childNodes) {
+      for (let button of this.container.children) {
         if (this.destroyed)
           return;
         if (!button._shell)
           continue;
 
         await button._shell.refresh();
 
         // Make sure to request a new idle moment every `kRefreshBatchSize` buttons.
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -396,17 +396,17 @@ var DownloadsPanel = {
       }
       aEvent.preventDefault();
       return;
     }
 
     if (aEvent.keyCode == aEvent.DOM_VK_DOWN) {
       // If the last element in the list is selected, or the footer is already
       // focused, focus the footer.
-      if (richListBox.selectedItem === richListBox.lastChild ||
+      if (richListBox.selectedItem === richListBox.lastElementChild ||
           document.activeElement.parentNode.id === "downloadsFooter") {
         DownloadsFooter.focus();
         aEvent.preventDefault();
         return;
       }
     }
 
     // Pass keypress events to the richlistbox view when it's focused.
@@ -420,19 +420,19 @@ var DownloadsPanel = {
    * as the the accel-V "paste" event, which initiates a file download if the
    * pasted item can be resolved to a URI.
    */
   _onKeyDown(aEvent) {
     // If the footer is focused and the downloads list has at least 1 element
     // in it, focus the last element in the list when going up.
     if (aEvent.keyCode == aEvent.DOM_VK_UP &&
         document.activeElement.parentNode.id === "downloadsFooter" &&
-        DownloadsView.richListBox.firstChild) {
+        DownloadsView.richListBox.firstElementChild) {
       DownloadsView.richListBox.focus();
-      DownloadsView.richListBox.selectedItem = DownloadsView.richListBox.lastChild;
+      DownloadsView.richListBox.selectedItem = DownloadsView.richListBox.lastElementChild;
       aEvent.preventDefault();
       return;
     }
 
     let pasting = aEvent.keyCode == aEvent.DOM_VK_V &&
                   aEvent.getModifierState("Accel");
 
     if (!pasting) {
@@ -723,17 +723,17 @@ var DownloadsView = {
     DownloadsCommon.log("Adding a new DownloadsViewItem to the downloads list.",
                         "aNewest =", aNewest);
 
     let element = document.createElement("richlistitem");
     let viewItem = new DownloadsViewItem(download, element);
     this._visibleViewItems.set(download, viewItem);
     this._itemsForElements.set(element, viewItem);
     if (aNewest) {
-      this.richListBox.insertBefore(element, this.richListBox.firstChild);
+      this.richListBox.insertBefore(element, this.richListBox.firstElementChild);
     } else {
       this.richListBox.appendChild(element);
     }
   },
 
   /**
    * Removes the view item associated with the specified data item.
    */
--- a/browser/components/extensions/parent/ext-menus.js
+++ b/browser/components/extensions/parent/ext-menus.js
@@ -71,32 +71,32 @@ var gMenuBuilder = {
     const children = this.buildChildren(root, contextData);
     const visible = children.slice(0, ACTION_MENU_TOP_LEVEL_LIMIT);
 
     this.xulMenu = menu;
     menu.addEventListener("popuphidden", this);
 
     if (visible.length) {
       const separator = menu.ownerDocument.createElement("menuseparator");
-      menu.insertBefore(separator, menu.firstChild);
+      menu.insertBefore(separator, menu.firstElementChild);
       this.itemsToCleanUp.add(separator);
 
       for (const child of visible) {
         this.itemsToCleanUp.add(child);
         menu.insertBefore(child, separator);
       }
     }
     this.afterBuildingMenu(contextData);
   },
 
   buildElementWithChildren(item, contextData) {
     const element = this.buildSingleElement(item, contextData);
     const children = this.buildChildren(item, contextData);
     if (children.length) {
-      element.firstChild.append(...children);
+      element.firstElementChild.append(...children);
     }
     return element;
   },
 
   buildChildren(item, contextData) {
     let groupName;
     let children = [];
     for (let child of item.children) {
@@ -113,17 +113,17 @@ var gMenuBuilder = {
         children.push(this.buildElementWithChildren(child, contextData));
       }
     }
     return children;
   },
 
   createTopLevelElement(root, contextData) {
     let rootElement = this.buildElementWithChildren(root, contextData);
-    if (!rootElement.firstChild || !rootElement.firstChild.childNodes.length) {
+    if (!rootElement.firstElementChild || !rootElement.firstElementChild.children.length) {
       // If the root has no visible children, there is no reason to show
       // the root menu item itself either.
       return null;
     }
     rootElement.setAttribute("ext-type", "top-level-menu");
     rootElement = this.removeTopLevelMenuIfNeeded(rootElement);
 
     // Display the extension icon on the root element.
@@ -151,19 +151,19 @@ var gMenuBuilder = {
       separator.remove();
       this.itemsToCleanUp.clear();
     }
   },
 
   removeTopLevelMenuIfNeeded(element) {
     // If there is only one visible top level element we don't need the
     // root menu element for the extension.
-    let menuPopup = element.firstChild;
-    if (menuPopup && menuPopup.childNodes.length == 1) {
-      let onlyChild = menuPopup.firstChild;
+    let menuPopup = element.firstElementChild;
+    if (menuPopup && menuPopup.children.length == 1) {
+      let onlyChild = menuPopup.firstElementChild;
 
       // Keep single checkbox items in the submenu on Linux since
       // the extension icon overlaps the checkbox otherwise.
       if (AppConstants.platform === "linux" && onlyChild.getAttribute("type") === "checkbox") {
         return element;
       }
 
       onlyChild.remove();
--- a/browser/components/extensions/test/browser/browser_ext_tabs_hide.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_hide.js
@@ -198,17 +198,17 @@ add_task(async function test_tabs_showhi
   // hidden.  The rest of the tabs should be hidden at this point.  Hidden
   // status was already validated inside the extension, this double checks
   // from chrome code.
   let otherwin;
   for (let win of BrowserWindowIterator()) {
     if (win != window) {
       otherwin = win;
     }
-    let tabs = Array.from(win.gBrowser.tabs.values());
+    let tabs = Array.from(win.gBrowser.tabs);
     ok(!tabs[0].hidden, "first tab not hidden");
     for (let i = 1; i < tabs.length; i++) {
       ok(tabs[i].hidden, "tab hidden value is correct");
       let id = SessionStore.getCustomTabValue(tabs[i], "hiddenBy");
       is(id, extension.id, "tab hiddenBy value is correct");
       await TabStateFlusher.flush(tabs[i].linkedBrowser);
     }
 
@@ -217,17 +217,17 @@ add_task(async function test_tabs_showhi
   }
 
   // Close the other window then restore it to test that the tabs are
   // restored with proper hidden state, and the correct extension id.
   await BrowserTestUtils.closeWindow(otherwin);
 
   otherwin = SessionStore.undoCloseWindow(0);
   await BrowserTestUtils.waitForEvent(otherwin, "load");
-  let tabs = Array.from(otherwin.gBrowser.tabs.values());
+  let tabs = Array.from(otherwin.gBrowser.tabs);
   ok(!tabs[0].hidden, "first tab not hidden");
   for (let i = 1; i < tabs.length; i++) {
     ok(tabs[i].hidden, "tab hidden value is correct");
     let id = SessionStore.getCustomTabValue(tabs[i], "hiddenBy");
     is(id, extension.id, "tab hiddenBy value is correct");
   }
 
   // Test closing the last visible tab, the next tab which is hidden should become
@@ -237,17 +237,17 @@ add_task(async function test_tabs_showhi
   ok(!otherwin.gBrowser.selectedTab.hidden, "tab was unhidden");
 
   // Showall will unhide any remaining hidden tabs.
   extension.sendMessage("showall");
   await extension.awaitMessage("shown");
 
   // Check from chrome code that all tabs are visible again.
   for (let win of BrowserWindowIterator()) {
-    let tabs = Array.from(win.gBrowser.tabs.values());
+    let tabs = Array.from(win.gBrowser.tabs);
     for (let i = 0; i < tabs.length; i++) {
       ok(!tabs[i].hidden, "tab hidden value is correct");
     }
   }
 
   // Close second window.
   await BrowserTestUtils.closeWindow(otherwin);
 
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -228,47 +228,47 @@ PlacesViewBase.prototype = {
     return this.controller.buildContextMenu(aPopup);
   },
 
   destroyContextMenu: function PVB_destroyContextMenu(aPopup) {
     this._contextMenuShown = null;
   },
 
   clearAllContents(aPopup) {
-    let kid = aPopup.firstChild;
+    let kid = aPopup.firstElementChild;
     while (kid) {
-      let next = kid.nextSibling;
+      let next = kid.nextElementSibling;
       if (!kid.classList.contains("panel-header")) {
         kid.remove();
       }
       kid = next;
     }
     aPopup._emptyMenuitem = aPopup._startMarker = aPopup._endMarker = null;
   },
 
   _cleanPopup: function PVB_cleanPopup(aPopup, aDelay) {
     // Ensure markers are here when `invalidateContainer` is called before the
     // popup is shown, which may the case for panelviews, for example.
     this._ensureMarkers(aPopup);
     // Remove Places nodes from the popup.
     let child = aPopup._startMarker;
-    while (child.nextSibling != aPopup._endMarker) {
-      let sibling = child.nextSibling;
+    while (child.nextElementSibling != aPopup._endMarker) {
+      let sibling = child.nextElementSibling;
       if (sibling._placesNode && !aDelay) {
         aPopup.removeChild(sibling);
       } else if (sibling._placesNode && aDelay) {
         // HACK (bug 733419): the popups originating from the OS X native
         // menubar don't live-update while open, thus we don't clean it
         // until the next popupshowing, to avoid zombie menuitems.
         if (!aPopup._delayedRemovals)
           aPopup._delayedRemovals = [];
         aPopup._delayedRemovals.push(sibling);
-        child = child.nextSibling;
+        child = child.nextElementSibling;
       } else {
-        child = child.nextSibling;
+        child = child.nextElementSibling;
       }
     }
   },
 
   _rebuildPopup: function PVB__rebuildPopup(aPopup) {
     let resultNode = aPopup._placesNode;
     if (!resultNode.containerOpen)
       return;
@@ -317,18 +317,18 @@ PlacesViewBase.prototype = {
       aPopup._emptyMenuitem.className = "bookmark-item";
       if (typeof this.options.extraClasses.entry == "string")
         aPopup._emptyMenuitem.classList.add(this.options.extraClasses.entry);
     }
 
     if (aEmpty) {
       aPopup.setAttribute("emptyplacesresult", "true");
       // Don't add the menuitem if there is static content.
-      if (!aPopup._startMarker.previousSibling &&
-          !aPopup._endMarker.nextSibling)
+      if (!aPopup._startMarker.previousElementSibling &&
+          !aPopup._endMarker.nextElementSibling)
         aPopup.insertBefore(aPopup._emptyMenuitem, aPopup._endMarker);
     } else {
       aPopup.removeAttribute("emptyplacesresult");
       try {
         aPopup.removeChild(aPopup._emptyMenuitem);
       } catch (ex) {}
     }
   },
@@ -480,18 +480,18 @@ PlacesViewBase.prototype = {
     }
 
     if (aStatus == Ci.mozILivemark.STATUS_LOADING ||
         aStatus == Ci.mozILivemark.STATUS_FAILED) {
       // Status has changed, update the cached status menuitem.
       let stringId = aStatus == Ci.mozILivemark.STATUS_LOADING ?
                        "bookmarksLivemarkLoading" : "bookmarksLivemarkFailed";
       statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
-      if (aPopup._startMarker.nextSibling != statusMenuitem)
-        aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextSibling);
+      if (aPopup._startMarker.nextElementSibling != statusMenuitem)
+        aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextElementSibling);
     } else if (aPopup._statusMenuitem.parentNode == aPopup) {
       // The livemark has finished loading.
       aPopup.removeChild(aPopup._statusMenuitem);
     }
   },
 
   toggleCutNode: function PVB_toggleCutNode(aPlacesNode, aValue) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
@@ -592,30 +592,30 @@ PlacesViewBase.prototype = {
       elt = elt.parentNode;
 
     if (parentElt._built) {
       parentElt.removeChild(elt);
 
       // Figure out if we need to show the "<Empty>" menu-item.
       // TODO Bug 517701: This doesn't seem to handle the case of an empty
       // root.
-      if (parentElt._startMarker.nextSibling == parentElt._endMarker)
+      if (parentElt._startMarker.nextElementSibling == parentElt._endMarker)
         this._setEmptyPopupStatus(parentElt, true);
     }
   },
 
   nodeHistoryDetailsChanged:
   function PVB_nodeHistoryDetailsChanged(aPlacesNode, aTime, aCount) {
     if (aPlacesNode.parent &&
         this.controller.hasCachedLivemarkInfo(aPlacesNode.parent)) {
       // Find the node in the parent.
       let popup = this._getDOMNodeForPlacesNode(aPlacesNode.parent);
-      for (let child = popup._startMarker.nextSibling;
+      for (let child = popup._startMarker.nextElementSibling;
            child != popup._endMarker;
-           child = child.nextSibling) {
+           child = child.nextElementSibling) {
         if (child._placesNode && child._placesNode.uri == aPlacesNode.uri) {
           if (aPlacesNode.accessCount)
             child.setAttribute("visited", "true");
           else
             child.removeAttribute("visited");
           break;
         }
       }
@@ -630,20 +630,20 @@ PlacesViewBase.prototype = {
   batching() { },
 
   nodeInserted:
   function PVB_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aParentPlacesNode);
     if (!parentElt._built)
       return;
 
-    let index = Array.prototype.indexOf.call(parentElt.childNodes, parentElt._startMarker) +
+    let index = Array.prototype.indexOf.call(parentElt.children, parentElt._startMarker) +
                 aIndex + 1;
     this._insertNewItemToPopup(aPlacesNode, parentElt,
-                               parentElt.childNodes[index] || parentElt._endMarker);
+                               parentElt.children[index] || parentElt._endMarker);
     this._setEmptyPopupStatus(parentElt, false);
   },
 
   nodeMoved:
   function PBV_nodeMoved(aPlacesNode,
                          aOldParentPlacesNode, aOldIndex,
                          aNewParentPlacesNode, aNewIndex) {
     // Note: the current implementation of moveItem does not actually
@@ -660,19 +660,19 @@ PlacesViewBase.prototype = {
     // we need to do in that case.
     if (elt == this._rootElt)
       return;
 
     let parentElt = this._getDOMNodeForPlacesNode(aNewParentPlacesNode);
     if (parentElt._built) {
       // Move the node.
       parentElt.removeChild(elt);
-      let index = Array.prototype.indexOf.call(parentElt.childNodes, parentElt._startMarker) +
+      let index = Array.prototype.indexOf.call(parentElt.children, parentElt._startMarker) +
                   aNewIndex + 1;
-      parentElt.insertBefore(elt, parentElt.childNodes[index]);
+      parentElt.insertBefore(elt, parentElt.children[index]);
     }
   },
 
   containerStateChanged:
   function PVB_containerStateChanged(aPlacesNode, aOldState, aNewState) {
     if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED ||
         aNewState == Ci.nsINavHistoryContainerResultNode.STATE_CLOSED) {
       this.invalidateContainer(aPlacesNode);
@@ -705,17 +705,17 @@ PlacesViewBase.prototype = {
           }, () => undefined);
       }
     }
   },
 
   _populateLivemarkPopup: function PVB__populateLivemarkPopup(aPopup) {
     this._setLivemarkSiteURIMenuItem(aPopup);
     // Show the loading status only if there are no entries yet.
-    if (aPopup._startMarker.nextSibling == aPopup._endMarker)
+    if (aPopup._startMarker.nextElementSibling == aPopup._endMarker)
       this._setLivemarkStatusMenuItem(aPopup, Ci.mozILivemark.STATUS_LOADING);
 
     PlacesUtils.livemarks.getLivemark({ id: aPopup._placesNode.itemId })
       .then(aLivemark => {
         let placesNode = aPopup._placesNode;
         if (!placesNode.containerOpen)
           return;
 
@@ -805,24 +805,24 @@ PlacesViewBase.prototype = {
       return;
 
     let hasMultipleURIs = false;
 
     // Check if the popup contains at least 2 menuitems with places nodes.
     // We don't currently support opening multiple uri nodes when they are not
     // populated by the result.
     if (aPopup._placesNode.childCount > 0) {
-      let currentChild = aPopup.firstChild;
+      let currentChild = aPopup.firstElementChild;
       let numURINodes = 0;
       while (currentChild) {
         if (currentChild.localName == "menuitem" && currentChild._placesNode) {
           if (++numURINodes == 2)
             break;
         }
-        currentChild = currentChild.nextSibling;
+        currentChild = currentChild.nextElementSibling;
       }
       hasMultipleURIs = numURINodes > 1;
     }
 
     let isLiveMark = false;
     if (this.controller.hasCachedLivemarkInfo(aPopup._placesNode)) {
       hasMultipleURIs = true;
       isLiveMark = true;
@@ -877,34 +877,34 @@ PlacesViewBase.prototype = {
 
   _ensureMarkers: function PVB__ensureMarkers(aPopup) {
     if (aPopup._startMarker)
       return;
 
     // _startMarker is an hidden menuseparator that lives before places nodes.
     aPopup._startMarker = document.createElement("menuseparator");
     aPopup._startMarker.hidden = true;
-    aPopup.insertBefore(aPopup._startMarker, aPopup.firstChild);
+    aPopup.insertBefore(aPopup._startMarker, aPopup.firstElementChild);
 
     // _endMarker is a DOM node that lives after places nodes, specified with
     // the 'insertionPoint' option or will be a hidden menuseparator.
     let node = this.options.insertionPoint ?
                aPopup.querySelector(this.options.insertionPoint) : null;
     if (node) {
       aPopup._endMarker = node;
     } else {
       aPopup._endMarker = document.createElement("menuseparator");
       aPopup._endMarker.hidden = true;
     }
     aPopup.appendChild(aPopup._endMarker);
 
     // Move the markers to the right position.
     let firstNonStaticNodeFound = false;
-    for (let i = 0; i < aPopup.childNodes.length; i++) {
-      let child = aPopup.childNodes[i];
+    for (let i = 0; i < aPopup.children.length; i++) {
+      let child = aPopup.children[i];
       // Menus that have static content at the end, but are initially empty,
       // use a special "builder" attribute to figure out where to start
       // inserting places nodes.
       if (child.getAttribute("builder") == "end") {
         aPopup.insertBefore(aPopup._endMarker, child);
         break;
       }
 
@@ -1153,20 +1153,20 @@ PlacesToolbar.prototype = {
     else
       aInsertionNode.appendChild(button);
     return button;
   },
 
   _updateChevronPopupNodesVisibility:
   function PT__updateChevronPopupNodesVisibility() {
     // Note the toolbar by default builds less nodes than the chevron popup.
-    for (let toolbarNode = this._rootElt.firstChild,
-         node = this._chevronPopup._startMarker.nextSibling;
+    for (let toolbarNode = this._rootElt.firstElementChild,
+         node = this._chevronPopup._startMarker.nextElementSibling;
          toolbarNode && node;
-         toolbarNode = toolbarNode.nextSibling, node = node.nextSibling) {
+         toolbarNode = toolbarNode.nextElementSibling, node = node.nextElementSibling) {
       node.hidden = toolbarNode.style.visibility != "hidden";
     }
   },
 
   _onChevronPopupShowing:
   function PT__onChevronPopupShowing(aEvent) {
     // Handle popupshowing only for the chevron popup, not for nested ones.
     if (aEvent.target != this._chevronPopup)
@@ -1287,17 +1287,17 @@ PlacesToolbar.prototype = {
 
     let childOverflowed = false;
 
     // We're about to potentially update a bunch of nodes, so we do it
     // in a requestAnimationFrame so that other JS that's might execute
     // in the same tick can avoid flushing styles and layout for these
     // changes.
     window.requestAnimationFrame(() => {
-      for (let child of this._rootElt.childNodes) {
+      for (let child of this._rootElt.children) {
         // Once a child overflows, all the next ones will.
         if (!childOverflowed) {
           let childRect = dwu.getBoundsWithoutFlushing(child);
           childOverflowed = this.isRTL ? (childRect.left < scrollRect.left)
                                        : (childRect.right > scrollRect.right);
         }
 
         if (childOverflowed) {
@@ -1323,32 +1323,32 @@ PlacesToolbar.prototype = {
 
     this._updatingNodesVisibility = false;
   },
 
   nodeInserted:
   function PT_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aParentPlacesNode);
     if (parentElt == this._rootElt) { // Node is on the toolbar.
-      let children = this._rootElt.childNodes;
+      let children = this._rootElt.children;
       // Nothing to do if it's a never-visible node, but note it's possible
       // we are appending.
       if (aIndex > children.length)
         return;
 
       // Note that childCount is already accounting for the node being added,
       // thus we must subtract one node from it.
       if (this._resultNode.childCount - 1 > children.length) {
         if (aIndex == children.length) {
           // If we didn't build all the nodes and new node is being appended,
           // we can skip it as well.
           return;
         }
         // Keep the number of built nodes consistent.
-        this._rootElt.removeChild(this._rootElt.lastChild);
+        this._rootElt.removeChild(this._rootElt.lastElementChild);
       }
 
       let button = this._insertNewItem(aPlacesNode, this._rootElt,
                                        children[aIndex] || null);
       let prevSiblingOverflowed = aIndex > 0 && aIndex <= children.length &&
                                   children[aIndex - 1].style.visibility == "hidden";
       if (prevSiblingOverflowed) {
         button.style.visibility = "hidden";
@@ -1374,19 +1374,19 @@ PlacesToolbar.prototype = {
         return;
 
       // Here we need the <menu>.
       if (elt.localName == "menupopup")
         elt = elt.parentNode;
 
       let overflowed = elt.style.visibility == "hidden";
       this._removeChild(elt);
-      if (this._resultNode.childCount > this._rootElt.childNodes.length) {
+      if (this._resultNode.childCount > this._rootElt.children.length) {
         // A new node should be built to keep a coherent number of children.
-        this._insertNewItem(this._resultNode.getChild(this._rootElt.childNodes.length),
+        this._insertNewItem(this._resultNode.getChild(this._rootElt.children.length),
                             this._rootElt);
       }
       if (!overflowed)
         this.updateNodesVisibility();
       return;
     }
 
     PlacesViewBase.prototype.nodeRemoved.apply(this, arguments);
@@ -1394,46 +1394,46 @@ PlacesToolbar.prototype = {
 
   nodeMoved:
   function PT_nodeMoved(aPlacesNode,
                         aOldParentPlacesNode, aOldIndex,
                         aNewParentPlacesNode, aNewIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aNewParentPlacesNode);
     if (parentElt == this._rootElt) { // Node is on the toolbar.
       // Do nothing if the node will never be visible.
-      let lastBuiltIndex = this._rootElt.childNodes.length - 1;
+      let lastBuiltIndex = this._rootElt.children.length - 1;
       if (aOldIndex > lastBuiltIndex && aNewIndex > lastBuiltIndex + 1)
         return;
 
       let elt = this._getDOMNodeForPlacesNode(aPlacesNode, true);
       if (elt) {
         // Here we need the <menu>.
         if (elt.localName == "menupopup")
           elt = elt.parentNode;
         this._removeChild(elt);
       }
 
       if (aNewIndex > lastBuiltIndex + 1) {
-        if (this._resultNode.childCount > this._rootElt.childNodes.length) {
+        if (this._resultNode.childCount > this._rootElt.children.length) {
           // If the element was built and becomes non built, another node should
           // be built to keep a coherent number of children.
-          this._insertNewItem(this._resultNode.getChild(this._rootElt.childNodes.length),
+          this._insertNewItem(this._resultNode.getChild(this._rootElt.children.length),
                               this._rootElt);
         }
         return;
       }
 
       if (!elt) {
         // The node has not been inserted yet, so we must create it.
-        elt = this._insertNewItem(aPlacesNode, this._rootElt, this._rootElt.childNodes[aNewIndex]);
+        elt = this._insertNewItem(aPlacesNode, this._rootElt, this._rootElt.children[aNewIndex]);
         let icon = aPlacesNode.icon;
         if (icon)
           elt.setAttribute("image", icon);
       } else {
-        this._rootElt.insertBefore(elt, this._rootElt.childNodes[aNewIndex]);
+        this._rootElt.insertBefore(elt, this._rootElt.children[aNewIndex]);
       }
 
       // The chevron view may get nodeMoved after the toolbar.  In such a case,
       // we should ensure (by manually swapping menuitems) that the actual nodes
       // are in the final position before updateNodesVisibility tries to update
       // their visibility, or the chevron may go out of sync.
       // Luckily updateNodesVisibility runs on a timer, so, by the time it updates
       // nodes, the menu has already handled the notification.
@@ -1511,19 +1511,19 @@ PlacesToolbar.prototype = {
                  openTimer: null,
                  hoverTime: 350,
                  closeTimer: null },
 
   _clearOverFolder: function PT__clearOverFolder() {
     // The mouse is no longer dragging over the stored menubutton.
     // Close the menubutton, clear out drag styles, and clear all
     // timers for opening/closing it.
-    if (this._overFolder.elt && this._overFolder.elt.lastChild) {
-      if (!this._overFolder.elt.lastChild.hasAttribute("dragover")) {
-        this._overFolder.elt.lastChild.hidePopup();
+    if (this._overFolder.elt && this._overFolder.elt.lastElementChild) {
+      if (!this._overFolder.elt.lastElementChild.hasAttribute("dragover")) {
+        this._overFolder.elt.lastElementChild.hidePopup();
       }
       this._overFolder.elt.removeAttribute("dragover");
       this._overFolder.elt = null;
     }
     if (this._overFolder.openTimer) {
       this._overFolder.openTimer.cancel();
       this._overFolder.openTimer = null;
     }
@@ -1544,17 +1544,17 @@ PlacesToolbar.prototype = {
     if (!PlacesUtils.nodeIsFolder(this._resultNode))
       return null;
 
     let dropPoint = { ip: null, beforeIndex: null, folderElt: null };
     let elt = aEvent.target;
     if (elt._placesNode && elt != this._rootElt &&
         elt.localName != "menupopup") {
       let eltRect = elt.getBoundingClientRect();
-      let eltIndex = Array.prototype.indexOf.call(this._rootElt.childNodes, elt);
+      let eltIndex = Array.prototype.indexOf.call(this._rootElt.children, elt);
       if (PlacesUtils.nodeIsFolder(elt._placesNode) &&
           !PlacesUIUtils.isFolderReadOnly(elt._placesNode, this)) {
         // This is a folder.
         // If we are in the middle of it, drop inside it.
         // Otherwise, drop before it, with regards to RTL mode.
         let threshold = eltRect.width * 0.25;
         if (this.isRTL ? (aEvent.clientX > eltRect.right - threshold)
                        : (aEvent.clientX < eltRect.left + threshold)) {
@@ -1578,17 +1578,17 @@ PlacesToolbar.prototype = {
               parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode),
               tagName
             });
           dropPoint.beforeIndex = eltIndex;
           dropPoint.folderElt = elt;
         } else {
           // Drop after this folder.
           let beforeIndex =
-            (eltIndex == this._rootElt.childNodes.length - 1) ?
+            (eltIndex == this._rootElt.children.length - 1) ?
             -1 : eltIndex + 1;
 
           dropPoint.ip =
             new PlacesInsertionPoint({
               parentId: PlacesUtils.getConcreteItemId(this._resultNode),
               parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
               index: beforeIndex,
               orientation: Ci.nsITreeView.DROP_BEFORE
@@ -1608,17 +1608,17 @@ PlacesToolbar.prototype = {
               parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
               index: eltIndex,
               orientation: Ci.nsITreeView.DROP_BEFORE
             });
           dropPoint.beforeIndex = eltIndex;
         } else {
           // Drop after this bookmark.
           let beforeIndex =
-            eltIndex == this._rootElt.childNodes.length - 1 ?
+            eltIndex == this._rootElt.children.length - 1 ?
             -1 : eltIndex + 1;
           dropPoint.ip =
             new PlacesInsertionPoint({
               parentId: PlacesUtils.getConcreteItemId(this._resultNode),
               parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
               index: beforeIndex,
               orientation: Ci.nsITreeView.DROP_BEFORE
             });
@@ -1653,17 +1653,17 @@ PlacesToolbar.prototype = {
     } else if (aTimer == this._ibTimer) {
       // * Timer to turn off indicator bar.
       this._dropIndicator.collapsed = true;
       this._ibTimer = null;
     } else if (aTimer == this._overFolder.openTimer) {
       // * Timer to open a menubutton that's being dragged over.
       // Set the autoopen attribute on the folder's menupopup so that
       // the menu will automatically close when the mouse drags off of it.
-      this._overFolder.elt.lastChild.setAttribute("autoopened", "true");
+      this._overFolder.elt.lastElementChild.setAttribute("autoopened", "true");
       this._overFolder.elt.open = true;
       this._overFolder.openTimer = null;
     } else if (aTimer == this._overFolder.closeTimer) {
       // * Timer to close a menubutton that's been dragged off of.
       // Close the menubutton if we are not dragging over it or one of
       // its children.  The autoopened attribute will let the menu know to
       // close later if the menu is still being dragged over.
       let currentPlacesNode = PlacesControllerDragHelper.currentDropTarget;
@@ -1723,17 +1723,17 @@ PlacesToolbar.prototype = {
         aEvent.preventDefault();
         // Open the menu.
         draggedElt.open = true;
         return;
       }
 
       // If the menu is open, close it.
       if (draggedElt.open) {
-        draggedElt.lastChild.hidePopup();
+        draggedElt.lastElementChild.hidePopup();
         draggedElt.open = false;
       }
     }
 
     // Activate the view and cache the dragged element.
     this._draggedElt = draggedElt._placesNode;
     this._rootElt.focus();
 
@@ -1777,33 +1777,33 @@ PlacesToolbar.prototype = {
       // show indicator bar and move it to the appropriate drop point.
       let ind = this._dropIndicator;
       ind.parentNode.collapsed = false;
       let halfInd = ind.clientWidth / 2;
       let translateX;
       if (this.isRTL) {
         halfInd = Math.ceil(halfInd);
         translateX = 0 - this._rootElt.getBoundingClientRect().right - halfInd;
-        if (this._rootElt.firstChild) {
+        if (this._rootElt.firstElementChild) {
           if (dropPoint.beforeIndex == -1)
-            translateX += this._rootElt.lastChild.getBoundingClientRect().left;
+            translateX += this._rootElt.lastElementChild.getBoundingClientRect().left;
           else {
-            translateX += this._rootElt.childNodes[dropPoint.beforeIndex]
+            translateX += this._rootElt.children[dropPoint.beforeIndex]
                               .getBoundingClientRect().right;
           }
         }
       } else {
         halfInd = Math.floor(halfInd);
         translateX = 0 - this._rootElt.getBoundingClientRect().left +
                      halfInd;
-        if (this._rootElt.firstChild) {
+        if (this._rootElt.firstElementChild) {
           if (dropPoint.beforeIndex == -1)
-            translateX += this._rootElt.lastChild.getBoundingClientRect().right;
+            translateX += this._rootElt.lastElementChild.getBoundingClientRect().right;
           else {
-            translateX += this._rootElt.childNodes[dropPoint.beforeIndex]
+            translateX += this._rootElt.children[dropPoint.beforeIndex]
                               .getBoundingClientRect().left;
           }
         }
       }
 
       ind.style.transform = "translate(" + Math.round(translateX) + "px)";
       ind.style.marginInlineStart = (-ind.clientWidth) + "px";
       ind.collapsed = false;
@@ -2048,17 +2048,17 @@ PlacesPanelMenuView.prototype = {
   },
 
   nodeInserted:
   function PAMV_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aParentPlacesNode);
     if (parentElt != this._rootElt)
       return;
 
-    let children = this._rootElt.childNodes;
+    let children = this._rootElt.children;
     this._insertNewItem(aPlacesNode, this._rootElt,
       aIndex < children.length ? children[aIndex] : null);
   },
 
   nodeRemoved:
   function PAMV_nodeRemoved(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aParentPlacesNode);
     if (parentElt != this._rootElt)
@@ -2073,17 +2073,17 @@ PlacesPanelMenuView.prototype = {
                           aOldParentPlacesNode, aOldIndex,
                           aNewParentPlacesNode, aNewIndex) {
     let parentElt = this._getDOMNodeForPlacesNode(aNewParentPlacesNode);
     if (parentElt != this._rootElt)
       return;
 
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
     this._removeChild(elt);
-    this._rootElt.insertBefore(elt, this._rootElt.childNodes[aNewIndex]);
+    this._rootElt.insertBefore(elt, this._rootElt.children[aNewIndex]);
   },
 
   nodeAnnotationChanged:
   function PAMV_nodeAnnotationChanged(aPlacesNode, aAnno) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
     // There's no UI representation for the root node.
     if (elt == this._rootElt)
       return;
@@ -2265,17 +2265,17 @@ this.PlacesPanelview = class extends Pla
     }
 
     if (empty) {
       panelview.setAttribute("emptyplacesresult", "true");
       // Don't add the menuitem if there is static content.
       // We also support external usage for custom crafted panels - which'll have
       // no markers present.
       if (!panelview._startMarker ||
-          (!panelview._startMarker.previousSibling && !panelview._endMarker.nextSibling)) {
+          (!panelview._startMarker.previousElementSibling && !panelview._endMarker.nextElementSibling)) {
         panelview.insertBefore(panelview._emptyMenuitem, panelview._endMarker);
       }
     } else {
       panelview.removeAttribute("emptyplacesresult");
       try {
         panelview.removeChild(panelview._emptyMenuitem);
       } catch (ex) {}
     }
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -559,18 +559,18 @@ PlacesController.prototype = {
   buildContextMenu: function PC_buildContextMenu(aPopup) {
     var metadata = this._buildSelectionMetadata();
     var ip = this._view.insertionPoint;
     var noIp = !ip || ip.isTag;
 
     var separator = null;
     var visibleItemsBeforeSep = false;
     var usableItemCount = 0;
-    for (var i = 0; i < aPopup.childNodes.length; ++i) {
-      var item = aPopup.childNodes[i];
+    for (var i = 0; i < aPopup.children.length; ++i) {
+      var item = aPopup.children[i];
       if (item.getAttribute("ignoreitem") == "true") {
         continue;
       }
       if (item.localName != "menuseparator") {
         // We allow pasting into tag containers, so special case that.
         var hideIfNoIP = item.getAttribute("hideifnoinsertionpoint") == "true" &&
                          noIp && !(ip && ip.isTag && item.id == "placesContext_paste");
         var hideIfPrivate = item.getAttribute("hideifprivatebrowsing") == "true" &&
--- a/browser/components/places/content/editBookmark.js
+++ b/browser/components/places/content/editBookmark.js
@@ -355,18 +355,18 @@ var gEditItemOverlay = {
     folderMenuItem.className = "menuitem-iconic folder-icon";
     aMenupopup.appendChild(folderMenuItem);
     return folderMenuItem;
   },
 
   async _initFolderMenuList(aSelectedFolderGuid) {
     // clean up first
     var menupopup = this._folderMenuList.menupopup;
-    while (menupopup.childNodes.length > 6)
-      menupopup.removeChild(menupopup.lastChild);
+    while (menupopup.children.length > 6)
+      menupopup.removeChild(menupopup.lastElementChild);
 
     // Build the static list
     if (!this._staticFoldersListBuilt) {
       let unfiledItem = this._element("unfiledRootItem");
       unfiledItem.label = PlacesUtils.getString("OtherBookmarksFolderTitle");
       unfiledItem.folderGuid = PlacesUtils.bookmarks.unfiledGuid;
       let bmMenuItem = this._element("bmRootItem");
       bmMenuItem.label = PlacesUtils.getString("BookmarksMenuFolderTitle");
@@ -409,17 +409,17 @@ var gEditItemOverlay = {
     var defaultItem = this._getFolderMenuItem(aSelectedFolderGuid, title);
     this._folderMenuList.selectedItem = defaultItem;
 
     // Set a selectedIndex attribute to show special icons
     this._folderMenuList.setAttribute("selectedIndex",
                                       this._folderMenuList.selectedIndex);
 
     // Hide the folders-separator if no folder is annotated as recently-used
-    this._element("foldersSeparator").hidden = (menupopup.childNodes.length <= 6);
+    this._element("foldersSeparator").hidden = (menupopup.children.length <= 6);
     this._folderMenuList.disabled = this.readOnly;
   },
 
   QueryInterface:
   ChromeUtils.generateQI([Ci.nsINavBookmarkObserver]),
 
   _element(aID) {
     return document.getElementById("editBMPanel_" + aID);
@@ -659,23 +659,23 @@ var gEditItemOverlay = {
    *        The identifier of the bookmarks folder.
    * @param aTitle
    *        The title to use in case of menuitem creation.
    * @return handle to the menuitem.
    */
   _getFolderMenuItem(aFolderGuid, aTitle) {
     let menupopup = this._folderMenuList.menupopup;
     let menuItem = Array.prototype.find.call(
-      menupopup.childNodes, item => item.folderGuid === aFolderGuid);
+      menupopup.children, item => item.folderGuid === aFolderGuid);
     if (menuItem !== undefined)
       return menuItem;
 
     // 3 special folders + separator + folder-items-count limit
-    if (menupopup.childNodes.length == 4 + MAX_FOLDER_ITEM_IN_MENU_LIST)
-      menupopup.removeChild(menupopup.lastChild);
+    if (menupopup.children.length == 4 + MAX_FOLDER_ITEM_IN_MENU_LIST)
+      menupopup.removeChild(menupopup.lastElementChild);
 
     return this._appendFolderItemToMenupopup(menupopup, aFolderGuid, aTitle);
   },
 
   async onFolderMenuListCommand(aEvent) {
     // Check for _paneInfo existing as the dialog may be closing but receiving
     // async updates from unresolved promises.
     if (!this._paneInfo) {
@@ -747,17 +747,17 @@ var gEditItemOverlay = {
     if (tagsSelectorRow.collapsed)
       return;
 
     let selectedIndex = tagsSelector.selectedIndex;
     let selectedTag = selectedIndex >= 0 ? tagsSelector.selectedItem.label
                                          : null;
 
     while (tagsSelector.hasChildNodes()) {
-      tagsSelector.removeChild(tagsSelector.lastChild);
+      tagsSelector.removeChild(tagsSelector.lastElementChild);
     }
 
     let tagsInField = this._getTagsArrayFromTagsInputField();
     let allTags = await PlacesUtils.bookmarks.fetchTags();
     let fragment = document.createDocumentFragment();
     for (let i = 0; i < allTags.length; i++) {
       let tag = allTags[i].name;
       let elt = document.createElement("richlistitem");
@@ -945,17 +945,17 @@ var gEditItemOverlay = {
     if (aItemId == this._paneInfo.itemId || aGuid == this._paneInfo.itemGuid) {
       this._paneInfo.title = aNewTitle;
       this._initTextField(this._namePicker, aNewTitle);
     } else if (this._paneInfo.visibleRows.has("folderRow")) {
       // If the title of a folder which is listed within the folders
       // menulist has been changed, we need to update the label of its
       // representing element.
       let menupopup = this._folderMenuList.menupopup;
-      for (let menuitem of menupopup.childNodes) {
+      for (let menuitem of menupopup.children) {
         if ("folderGuid" in menuitem && menuitem.folderGuid == aGuid) {
           menuitem.label = aNewTitle;
           break;
         }
       }
     }
     // We need to also update title of recent folders.
     if (this._recentFolders) {
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -95,18 +95,18 @@
                 parentId: PlacesUtils.getConcreteItemId(resultNode),
                 parentGuid: PlacesUtils.getConcreteItemGuid(resultNode)
               });
               // We can set folderElt if we are dropping over a static menu that
               // has an internal placespopup.
               let isMenu = elt.localName == "menu" ||
                  (elt.localName == "toolbarbutton" &&
                   elt.getAttribute("type") == "menu");
-              if (isMenu && elt.lastChild &&
-                  elt.lastChild.hasAttribute("placespopup"))
+              if (isMenu && elt.lastElementChild &&
+                  elt.lastElementChild.hasAttribute("placespopup"))
                 dropPoint.folderElt = elt;
               return dropPoint;
             }
 
             let tagName = PlacesUtils.nodeIsTagQuery(elt._placesNode) ?
                             elt._placesNode.title : null;
             if ((PlacesUtils.nodeIsFolder(elt._placesNode) &&
                  !PlacesUIUtils.isFolderReadOnly(elt._placesNode, this._rootView)) ||
@@ -209,18 +209,18 @@
           return timer;
         },
 
         notify: function OF__notify(aTimer) {
           // Function to process all timer notifications.
 
           if (aTimer == this._folder.openTimer) {
             // Timer to open a submenu that's being dragged over.
-            this._folder.elt.lastChild.setAttribute("autoopened", "true");
-            this._folder.elt.lastChild.openPopup();
+            this._folder.elt.lastElementChild.setAttribute("autoopened", "true");
+            this._folder.elt.lastElementChild.openPopup();
             this._folder.openTimer = null;
           } else if (aTimer == this._folder.closeTimer) {
             // Timer to close a submenu that's been dragged off of.
             // Only close the submenu if the mouse isn't being dragged over any
             // of its child menus.
             var draggingOverChild = PlacesControllerDragHelper
                                     .draggingOverChildNode(this._folder.elt);
             if (draggingOverChild)
@@ -264,19 +264,19 @@
             parent = parent.parentNode;
           }
         },
 
         //  The mouse is no longer dragging over the stored menubutton.
         //  Close the menubutton, clear out drag styles, and clear all
         //  timers for opening/closing it.
         clear: function OF__clear() {
-          if (this._folder.elt && this._folder.elt.lastChild) {
-            if (!this._folder.elt.lastChild.hasAttribute("dragover"))
-              this._folder.elt.lastChild.hidePopup();
+          if (this._folder.elt && this._folder.elt.lastElementChild) {
+            if (!this._folder.elt.lastElementChild.hasAttribute("dragover"))
+              this._folder.elt.lastElementChild.hidePopup();
             // remove menuactive style
             this._folder.elt.removeAttribute("_moz-menuactive");
             this._folder.elt = null;
           }
           if (this._folder.openTimer) {
             this._folder.openTimer.cancel();
             this._folder.openTimer = null;
           }
@@ -431,28 +431,28 @@
           event.stopPropagation();
           return;
         }
 
         // We should display the drop indicator relative to the arrowscrollbox.
         let scrollbox = this._scrollBox.boxObject;
         let newMarginTop = 0;
         if (scrollDir == 0) {
-          let elt = this.firstChild;
+          let elt = this.firstElementChild;
           while (elt && event.screenY > elt.boxObject.screenY +
                                         elt.boxObject.height / 2)
-            elt = elt.nextSibling;
+            elt = elt.nextElementSibling;
           newMarginTop = elt ? elt.boxObject.screenY - scrollbox.screenY :
                                scrollbox.height;
         } else if (scrollDir == 1)
           newMarginTop = scrollbox.height;
 
         // Set the new marginTop based on arrowscrollbox.
         newMarginTop += scrollbox.y - this._scrollBox.boxObject.y;
-        this._indicatorBar.firstChild.style.marginTop = newMarginTop + "px";
+        this._indicatorBar.firstElementChild.style.marginTop = newMarginTop + "px";
         this._indicatorBar.hidden = false;
 
         event.preventDefault();
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragexit"><![CDATA[
         PlacesControllerDragHelper.currentDropTarget = null;
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -535,27 +535,27 @@
           let stringBundle = document.getBindingParent(this)._stringBundle;
 
           let pasteAndSearch, suggestMenuItem;
           let element, label, akey;
 
           element = document.createElementNS(kXULNS, "menuseparator");
           aMenu.appendChild(element);
 
-          let insertLocation = aMenu.firstChild;
-          while (insertLocation.nextSibling &&
+          let insertLocation = aMenu.firstElementChild;
+          while (insertLocation.nextElementSibling &&
                  insertLocation.getAttribute("cmd") != "cmd_paste")
-            insertLocation = insertLocation.nextSibling;
+            insertLocation = insertLocation.nextElementSibling;
           if (insertLocation) {
             element = document.createElementNS(kXULNS, "menuitem");
             label = stringBundle.getString("cmd_pasteAndSearch");
             element.setAttribute("label", label);
             element.setAttribute("anonid", "paste-and-search");
             element.setAttribute("oncommand", "BrowserSearch.pasteAndSearch(event)");
-            aMenu.insertBefore(element, insertLocation.nextSibling);
+            aMenu.insertBefore(element, insertLocation.nextElementSibling);
             pasteAndSearch = element;
           }
 
           element = document.createElementNS(kXULNS, "menuitem");
           label = stringBundle.getString("cmd_clearHistory");
           akey = stringBundle.getString("cmd_clearHistory_accesskey");
           element.setAttribute("label", label);
           element.setAttribute("accesskey", akey);
@@ -1381,19 +1381,19 @@
           let isOneOffSelected =
             this.selectedButton &&
             this.selectedButton.classList.contains("searchbar-engine-one-off-item");
           // Typing de-selects the settings or opensearch buttons at the bottom
           // of the search panel, as typing shows the user intends to search.
           if (this.selectedButton && !isOneOffSelected)
             this.selectedButton = null;
           if (this.query) {
-            groupText = headerSearchText.previousSibling.value +
+            groupText = headerSearchText.previousElementSibling.value +
                         '"' + headerSearchText.value + '"' +
-                        headerSearchText.nextSibling.value;
+                        headerSearchText.nextElementSibling.value;
             if (!isOneOffSelected)
               this.header.selectedIndex = 1;
           } else {
             let noSearchHeader =
               document.getAnonymousElementByAttribute(this, "anonid",
                                                       "searchbar-oneoffheader-search");
             groupText = noSearchHeader.value;
             if (!isOneOffSelected)
@@ -1450,22 +1450,22 @@
             // width has changed.
             if (this._engines && this._textboxWidth == textboxWidth) {
               return;
             }
             this._textboxWidth = textboxWidth;
           }
 
           // Finally, build the list of one-off buttons.
-          while (this.buttons.firstChild != this.settingsButtonCompact)
-            this.buttons.firstChild.remove();
+          while (this.buttons.firstElementChild != this.settingsButtonCompact)
+            this.buttons.firstElementChild.remove();
           // Remove the trailing empty text node introduced by the binding's
           // content markup above.
-          if (this.settingsButtonCompact.nextSibling)
-            this.settingsButtonCompact.nextSibling.remove();
+          if (this.settingsButtonCompact.nextElementSibling)
+            this.settingsButtonCompact.nextElementSibling.remove();
 
           let engines = this.engines;
           let oneOffCount = engines.length;
           let collapsed = !oneOffCount ||
                           (oneOffCount == 1 && engines[0].name == Services.search.currentEngine.name);
 
           // header is a xul:deck so collapsed doesn't work on it, see bug 589569.
           this.header.hidden = this.buttons.collapsed = collapsed;
@@ -1555,17 +1555,17 @@
             if (rowCount == 1 && hasDummyItems) {
               // When there's only one row, make the compact settings button
               // hug the right edge of the panel.  It may not due to the panel's
               // width not being an integral multiple of the button width.  (See
               // the "There will be an emtpy area" comment above.)  Increase the
               // width of the last dummy item by the remainder.
               let remainder = panelWidth - (enginesPerRow * buttonWidth);
               let width = remainder + buttonWidth;
-              let lastDummyItem = this.settingsButtonCompact.previousSibling;
+              let lastDummyItem = this.settingsButtonCompact.previousElementSibling;
               lastDummyItem.setAttribute("width", width);
             }
           }
         ]]></body>
       </method>
 
       <!-- If a page offers more than this number of engines, the add-engines
            menu button is shown, instead of showing the engines directly in the
@@ -1736,31 +1736,31 @@
           }
         ]]></body>
       </method>
 
       <method name="getSelectableButtons">
         <parameter name="aIncludeNonEngineButtons"/>
         <body><![CDATA[
           let buttons = [];
-          for (let oneOff = this.buttons.firstChild; oneOff; oneOff = oneOff.nextSibling) {
+          for (let oneOff = this.buttons.firstElementChild; oneOff; oneOff = oneOff.nextElementSibling) {
             // oneOff may be a text node since the list xul:description contains
             // whitespace and the compact settings button.  See the markup
             // above.  _rebuild removes text nodes, but it may not have been
             // called yet (because e.g. the popup hasn't been opened yet).
             if (oneOff.nodeType == Node.ELEMENT_NODE) {
               if (oneOff.classList.contains("dummy") ||
                   oneOff.classList.contains("search-setting-button-compact"))
                 break;
               buttons.push(oneOff);
             }
           }
 
           if (aIncludeNonEngineButtons) {
-            for (let addEngine = this.addEngines.firstChild; addEngine; addEngine = addEngine.nextSibling) {
+            for (let addEngine = this.addEngines.firstElementChild; addEngine; addEngine = addEngine.nextElementSibling) {
               buttons.push(addEngine);
             }
             buttons.push(this.compact ? this.settingsButtonCompact : this.settingsButton);
           }
 
           return buttons;
         ]]></body>
       </method>
--- a/browser/components/syncedtabs/TabListView.js
+++ b/browser/components/syncedtabs/TabListView.js
@@ -90,18 +90,18 @@ TabListView.prototype = {
     this._clearChilden(this.list);
     for (let client of state.clients) {
       if (state.filter) {
         this._renderFilteredClient(client);
       } else {
         this._renderClient(client);
       }
     }
-    if (this.list.firstChild) {
-      const firstTab = this.list.firstChild.querySelector(".item.tab:first-child .item-title");
+    if (this.list.firstElementChild) {
+      const firstTab = this.list.firstElementChild.querySelector(".item.tab:first-child .item-title");
       if (firstTab) {
         firstTab.setAttribute("tabindex", 2);
       }
     }
   },
 
   destroy() {
     this._teardownContextMenu();
@@ -516,17 +516,17 @@ TabListView.prototype = {
 
     menu.openPopupAtScreen(event.screenX, event.screenY, true, event);
   },
 
   adjustContextMenu(menu) {
     let item = this.container.querySelector(".item.selected");
     let showTabOptions = this._isTab(item);
 
-    let el = menu.firstChild;
+    let el = menu.firstElementChild;
 
     while (el) {
       let show = false;
       if (showTabOptions) {
         if (el.getAttribute("id") == "syncedTabsOpenSelectedInPrivateWindow") {
           show = PrivateBrowsingUtils.enabled;
         } else if (el.getAttribute("id") != "syncedTabsOpenAllInTabs" &&
                    el.getAttribute("id") != "syncedTabsManageDevices") {
@@ -537,17 +537,17 @@ TabListView.prototype = {
         show = tabs.length > 0;
       } else if (el.getAttribute("id") == "syncedTabsRefresh") {
         show = true;
       } else if (el.getAttribute("id") == "syncedTabsManageDevices") {
         show = true;
       }
       el.hidden = !show;
 
-      el = el.nextSibling;
+      el = el.nextElementSibling;
     }
   },
 
   /**
    * Find the parent item element, from a given child element.
    * @param {Element} node - Child element.
    * @return {Element} Element for the item, or null if not found.
    */
@@ -584,25 +584,25 @@ TabListView.prototype = {
     // if the node is not a client, find its position within the parent
     if (parent !== itemNode) {
       childPosition = this._indexOfNode(itemNode.parentNode, itemNode);
     }
     return [parentPosition, childPosition];
   },
 
   _indexOfNode(parent, child) {
-    return Array.prototype.indexOf.call(parent.childNodes, child);
+    return Array.prototype.indexOf.call(parent.children, child);
   },
 
   _isTab(item) {
     return item && item.classList.contains("tab");
   },
 
   _isClient(item) {
     return item && item.classList.contains("client");
   },
 
   _openAllClientTabs(clientNode, where) {
-    const tabs = clientNode.querySelector(".item-tabs-list").childNodes;
+    const tabs = clientNode.querySelector(".item-tabs-list").children;
     const urls = [...tabs].map(tab => tab.dataset.url);
     this.props.onOpenTabs(urls, where);
   }
 };
--- a/browser/modules/AsyncTabSwitcher.jsm
+++ b/browser/modules/AsyncTabSwitcher.jsm
@@ -409,17 +409,17 @@ class AsyncTabSwitcher {
     if (this.visibleTab !== showTab) {
       this.tabbrowser._adjustFocusBeforeTabSwitch(this.visibleTab, showTab);
       this.visibleTab = showTab;
 
       this.maybeVisibleTabs.add(showTab);
 
       let tabpanels = this.tabbrowser.tabpanels;
       let showPanel = this.tabbrowser.tabContainer.getRelatedElement(showTab);
-      let index = Array.indexOf(tabpanels.childNodes, showPanel);
+      let index = Array.indexOf(tabpanels.children, showPanel);
       if (index != -1) {
         this.log(`Switch to tab ${index} - ${this.tinfo(showTab)}`);
         tabpanels.setAttribute("selectedIndex", index);
         if (showTab === this.requestedTab) {
           if (this._requestingTab) {
             /*
              * If _requestingTab is set, that means that we're switching the
              * visibility of the tab synchronously, and we need to wait for
--- a/browser/modules/TabsList.jsm
+++ b/browser/modules/TabsList.jsm
@@ -114,20 +114,20 @@ class TabsListBase {
     } else if (this.filterFn(tab)) {
       // The tab now matches our criteria, add a row for it.
       this._addTab(tab);
     }
   }
 
   _addTab(newTab) {
     let newRow = this._createRow(newTab);
-    let nextTab = newTab.nextSibling;
+    let nextTab = newTab.nextElementSibling;
 
     while (nextTab && !this.filterFn(nextTab)) {
-      nextTab = nextTab.nextSibling;
+      nextTab = nextTab.nextElementSibling;
     }
 
     if (nextTab) {
       // If we found a tab after this one in the list, insert the new row before it.
       let nextRow = this.tabToElement.get(nextTab);
       nextRow.parentNode.insertBefore(newRow, nextRow);
     } else {
       // If there's no next tab then insert it as usual.
@@ -152,17 +152,17 @@ const TABS_PANEL_EVENTS = {
   show: "ViewShowing",
   hide: "PanelMultiViewHidden",
 };
 
 class TabsPanel extends TabsListBase {
   constructor(opts) {
     super({
       ...opts,
-      containerNode: opts.containerNode || opts.view.firstChild,
+      containerNode: opts.containerNode || opts.view.firstElementChild,
     });
     this.view = opts.view;
     this.view.addEventListener(TABS_PANEL_EVENTS.show, this);
     this.panelMultiView = null;
   }
 
   handleEvent(event) {
     switch (event.type) {
@@ -245,17 +245,17 @@ class TabsPanel extends TabsListBase {
 
     return row;
   }
 
   _setRowAttributes(row, tab) {
     setAttributes(row, {selected: tab.selected});
 
     let busy = tab.getAttribute("busy");
-    let button = row.firstChild;
+    let button = row.firstElementChild;
     setAttributes(button, {
       busy,
       label: tab.label,
       image: !busy && tab.getAttribute("image"),
       iconloadingprincipal: tab.getAttribute("iconloadingprincipal"),
     });
 
     this._setImageAttributes(row, tab);
@@ -264,17 +264,17 @@ class TabsPanel extends TabsListBase {
     setAttributes(secondaryButton, {
       muted: tab.muted,
       soundplaying: tab.soundPlaying,
       hidden: !(tab.muted || tab.soundPlaying),
     });
   }
 
   _setImageAttributes(row, tab) {
-    let button = row.firstChild;
+    let button = row.firstElementChild;
     let image = this.doc.getAnonymousElementByAttribute(
       button, "class", "toolbarbutton-icon") ||
       this.doc.getAnonymousElementByAttribute(
         button, "class", "toolbarbutton-icon tab-throbber-fallback");
 
     if (image) {
       let busy = tab.getAttribute("busy");
       let progress = tab.getAttribute("progress");
--- a/toolkit/components/contextualidentity/ContextualIdentityService.jsm
+++ b/toolkit/components/contextualidentity/ContextualIdentityService.jsm
@@ -477,18 +477,18 @@ function _ContextualIdentityService(path
     while (windowList.hasMoreElements()) {
       let win = windowList.getNext();
 
       if (win.closed || !win.gBrowser) {
         continue;
       }
 
       let tabbrowser = win.gBrowser;
-      for (let i = tabbrowser.tabContainer.childNodes.length - 1; i >= 0; --i) {
-        let tab = tabbrowser.tabContainer.childNodes[i];
+      for (let i = tabbrowser.tabContainer.children.length - 1; i >= 0; --i) {
+        let tab = tabbrowser.tabContainer.children[i];
         if (tab.hasAttribute("usercontextid") &&
                   (!userContextId ||
                    parseInt(tab.getAttribute("usercontextid"), 10) == userContextId)) {
           callback(tab, tabbrowser);
         }
       }
     }
   },
--- a/toolkit/components/printing/content/printPreviewToolbar.js
+++ b/toolkit/components/printing/content/printPreviewToolbar.js
@@ -92,17 +92,17 @@ customElements.define("printpreview-tool
     this.mPortaitButton = document.getElementById("print-preview-portrait-button");
 
     this.mLandscapeButton = document.getElementById("print-preview-landscape-button");
 
     this.mSimplifyPageCheckbox = document.getElementById("print-preview-simplify");
 
     this.mSimplifyPageNotAllowed = this.mSimplifyPageCheckbox.disabled;
 
-    this.mSimplifyPageToolbarSeparator = this.mSimplifyPageCheckbox.nextSibling;
+    this.mSimplifyPageToolbarSeparator = this.mSimplifyPageCheckbox.nextElementSibling;
 
     this.mPrintPreviewObs = "";
 
     this.mWebProgress = "";
 
     this.mPPBrowser = null;
 
     this.mMessageManager = null;
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -740,17 +740,17 @@
           // invoke it only if there may be a scrollbar, so if we could fetch
           // more results than we can show at once.
           // maxResults is the maximum number of fetched results, maxRows is the
           // maximum number of rows we show at once, without a scrollbar.
           if (this.mPopupOpen && this.maxResults > this.maxRows) {
             // when clearing the selection (val == -1, so selectedItem will be
             // null), we want to scroll back to the top.  see bug #406194
             this.richlistbox.ensureElementIsVisible(
-              this.richlistbox.selectedItem || this.richlistbox.firstChild);
+              this.richlistbox.selectedItem || this.richlistbox.firstElementChild);
           }
           return val;
         ]]>
         </setter>
       </property>
 
       <method name="onSearchBegin">
         <body><![CDATA[
@@ -864,34 +864,34 @@
           return Math.min(this.mInput.controller.matchCount, this.maxResults);
           ]]>
         </getter>
       </property>
 
       <method name="_collapseUnusedItems">
         <body>
           <![CDATA[
-            let existingItemsCount = this.richlistbox.childNodes.length;
+            let existingItemsCount = this.richlistbox.children.length;
             for (let i = this.matchCount; i < existingItemsCount; ++i) {
-              let item = this.richlistbox.childNodes[i];
+              let item = this.richlistbox.children[i];
 
               item.collapsed = true;
               if (typeof item._onCollapse == "function") {
                 item._onCollapse();
               }
             }
           ]]>
         </body>
       </method>
 
       <method name="adjustHeight">
         <body>
           <![CDATA[
           // Figure out how many rows to show
-          let rows = this.richlistbox.childNodes;
+          let rows = this.richlistbox.children;
           let numRows = Math.min(this.matchCount, this.maxRows, rows.length);
 
           // Default the height to 0 if we have no rows to show
           let height = 0;
           if (numRows) {
             let firstRowRect = rows[0].getBoundingClientRect();
             if (this._rlbPadding == undefined) {
               let style = window.getComputedStyle(this.richlistbox);
@@ -926,17 +926,17 @@
       </method>
 
       <method name="_appendCurrentResult">
         <parameter name="invalidateReason"/>
         <body>
           <![CDATA[
           var controller = this.mInput.controller;
           var matchCount = this.matchCount;
-          var existingItemsCount = this.richlistbox.childNodes.length;
+          var existingItemsCount = this.richlistbox.children.length;
 
           // Process maxRows per chunk to improve performance and user experience
           for (let i = 0; i < this.maxRows; i++) {
             if (this._currentIndex >= matchCount) {
               break;
             }
             let item;
             let reusable = false;
@@ -952,17 +952,17 @@
               controller.getValueAt(this._currentIndex);
             let label = controller.getLabelAt(this._currentIndex);
             let comment = controller.getCommentAt(this._currentIndex);
             let image = controller.getImageAt(this._currentIndex);
             // trim the leading/trailing whitespace
             let trimmedSearchString = controller.searchString.replace(/^\s+/, "").replace(/\s+$/, "");
 
             if (itemExists) {
-              item = this.richlistbox.childNodes[this._currentIndex];
+              item = this.richlistbox.children[this._currentIndex];
 
               // Url may be a modified version of value, see _adjustAcItem().
               originalValue = item.getAttribute("url") || item.getAttribute("ac-value");
               originalText = item.getAttribute("ac-text");
               originalType = item.getAttribute("originaltype");
 
               // The styles on the list which have different <content> structure and overrided
               // _adjustAcItem() are unreusable.
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -925,17 +925,17 @@
       <!--
         - Determines whether minimalist or general-purpose search UI is to be
         - displayed when the find bar is activated.
         -->
       <method name="_updateFindUI">
         <body><![CDATA[
           let showMinimalUI = this._findMode != this.FIND_NORMAL;
 
-          let nodes = this.getElement("findbar-container").childNodes;
+          let nodes = this.getElement("findbar-container").children;
           let wrapper = this.getElement("findbar-textbox-wrapper");
           let foundMatches = this._foundMatches;
           for (let node of nodes) {
             if (node == wrapper || node == foundMatches)
                continue;
             node.hidden = showMinimalUI;
           }
           this.getElement("find-next").hidden =
--- a/toolkit/content/widgets/general.js
+++ b/toolkit/content/widgets/general.js
@@ -17,33 +17,33 @@ class MozDeck extends MozXULElement {
   }
 
   get selectedIndex() {
     return this.getAttribute("selectedIndex") || "0";
   }
 
   set selectedPanel(val) {
     var selectedIndex = -1;
-    for (var panel = val; panel != null; panel = panel.previousSibling)
+    for (var panel = val; panel != null; panel = panel.previousElementSibling)
       ++selectedIndex;
     this.selectedIndex = selectedIndex;
     return val;
   }
 
   get selectedPanel() {
-    return this.childNodes[this.selectedIndex];
+    return this.children[this.selectedIndex];
   }
 }
 
 customElements.define("deck", MozDeck);
 
 class MozDropmarker extends MozXULElement {
   connectedCallback() {
     // Only create the image the first time we are connected
-    if (!this.firstChild) {
+    if (!this.firstElementChild) {
       let image = document.createXULElement("image");
       image.classList.add("dropmarker-icon");
       this.appendChild(image);
     }
   }
 }
 
 customElements.define("dropmarker", MozDropmarker);
--- a/toolkit/content/widgets/menu.xml
+++ b/toolkit/content/widgets/menu.xml
@@ -79,58 +79,58 @@
 
           return menupopup.appendChild(menuitem);
         </body>
       </method>
 
       <property name="itemCount" readonly="true">
         <getter>
           var menupopup = this.menupopup;
-          return menupopup ? menupopup.childNodes.length : 0;
+          return menupopup ? menupopup.children.length : 0;
         </getter>
       </property>
 
       <method name="getIndexOfItem">
         <parameter name="aItem"/>
         <body>
         <![CDATA[
           var menupopup = this.menupopup;
           if (menupopup) {
-            var items = menupopup.childNodes;
+            var items = menupopup.children;
             var length = items.length;
             for (var index = 0; index < length; ++index) {
               if (items[index] == aItem)
                 return index;
             }
           }
           return -1;
         ]]>
         </body>
       </method>
 
       <method name="getItemAtIndex">
         <parameter name="aIndex"/>
         <body>
         <![CDATA[
           var menupopup = this.menupopup;
-          if (!menupopup || aIndex < 0 || aIndex >= menupopup.childNodes.length)
+          if (!menupopup || aIndex < 0 || aIndex >= menupopup.children.length)
             return null;
 
-          return menupopup.childNodes[aIndex];
+          return menupopup.children[aIndex];
         ]]>
         </body>
       </method>
 
       <property name="menupopup" readonly="true">
         <getter>
         <![CDATA[
           const XUL_NS =
             "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
-          for (var child = this.firstChild; child; child = child.nextSibling) {
+          for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
             if (child.namespaceURI == XUL_NS && child.localName == "menupopup")
               return child;
           }
           return null;
         ]]>
         </getter>
       </property>
     </implementation>
--- a/toolkit/content/widgets/menulist.xml
+++ b/toolkit/content/widgets/menulist.xml
@@ -140,24 +140,24 @@
         </setter>
       </property>
 
       <property name="open" onset="this.menuBoxObject.openMenu(val);
                                    return val;"
                             onget="return this.hasAttribute('open');"/>
 
       <property name="itemCount" readonly="true"
-                onget="return this.menupopup ? this.menupopup.childNodes.length : 0"/>
+                onget="return this.menupopup ? this.menupopup.children.length : 0"/>
 
       <property name="menupopup" readonly="true">
         <getter>
           <![CDATA[
-            var popup = this.firstChild;
+            var popup = this.firstElementChild;
             while (popup && popup.localName != "menupopup")
-              popup = popup.nextSibling;
+              popup = popup.nextElementSibling;
             return popup;
           ]]>
         </getter>
       </property>
 
       <method name="contains">
         <parameter name="item"/>
         <body>
@@ -175,31 +175,31 @@
         <getter>
           <![CDATA[
             // Quick and dirty. We won't deal with hierarchical menulists yet.
             if (!this.selectedItem ||
                 !this.mSelectedInternal.parentNode ||
                 this.mSelectedInternal.parentNode.parentNode != this)
               return -1;
 
-            var children = this.mSelectedInternal.parentNode.childNodes;
+            var children = this.mSelectedInternal.parentNode.children;
             var i = children.length;
             while (i--)
               if (children[i] == this.mSelectedInternal)
                 break;
 
             return i;
           ]]>
         </getter>
         <setter>
           <![CDATA[
             var popup = this.menupopup;
             if (popup && 0 <= val) {
-              if (val < popup.childNodes.length)
-                this.selectedItem = popup.childNodes[val];
+              if (val < popup.children.length)
+                this.selectedItem = popup.children[val];
             } else
               this.selectedItem = null;
             return val;
           ]]>
         </setter>
       </property>
 
       <property name="selectedItem">
@@ -281,34 +281,34 @@
       </method>
 
       <method name="getIndexOfItem">
         <parameter name="item"/>
         <body>
         <![CDATA[
           var popup = this.menupopup;
           if (popup) {
-            var children = popup.childNodes;
+            var children = popup.children;
             var i = children.length;
             while (i--)
               if (children[i] == item)
                 return i;
           }
           return -1;
         ]]>
         </body>
       </method>
 
       <method name="getItemAtIndex">
         <parameter name="index"/>
         <body>
         <![CDATA[
           var popup = this.menupopup;
           if (popup) {
-            var children = popup.childNodes;
+            var children = popup.children;
             if (index >= 0 && index < children.length)
               return children[index];
           }
           return null;
         ]]>
         </body>
       </method>
 
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -25,17 +25,17 @@
       </field>
     </implementation>
 
     <handlers>
       <handler event="popupshowing" phase="target">
         <![CDATA[
           var array = [];
           var width = 0;
-          for (var menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
+          for (var menuitem = this.firstElementChild; menuitem; menuitem = menuitem.nextElementSibling) {
             if (menuitem.localName == "menuitem" && menuitem.hasAttribute("acceltext")) {
               var accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
               if (accel && accel.boxObject) {
                 array.push(accel);
                 if (accel.boxObject.width > width)
                   width = accel.boxObject.width;
               }
             }
--- a/toolkit/content/widgets/richlistbox.xml
+++ b/toolkit/content/widgets/richlistbox.xml
@@ -581,17 +581,17 @@
         </body>
       </method>
 
       <property name="children" readonly="true">
         <getter>
           <![CDATA[
             let iface = Ci.nsIDOMXULSelectControlItemElement;
             let children = Array.from(this.childNodes)
-                                .filter(node => node instanceof iface);
+                                .filter(node => node.nodeType == 1 && node instanceof iface);
             if (this.dir == "reverse" && this._mayReverse) {
               children.reverse();
             }
             return children;
           ]]>
         </getter>
       </property>
 
@@ -625,18 +625,18 @@
                 if (this.selType != "multiple" && this.selectedCount == 0)
                   this.selectedItem = currentItem;
 
                 if (this._scrollbox.boxObject.height) {
                   this.ensureElementIsVisible(currentItem);
                 } else {
                   // XXX hack around a bug in ensureElementIsVisible as it will
                   // scroll beyond the last element, bug 493645.
-                  var previousElement = this.dir == "reverse" ? currentItem.nextSibling :
-                                                                currentItem.previousSibling;
+                  var previousElement = this.dir == "reverse" ? currentItem.nextElementSibling :
+                                                                currentItem.previousElementSibling;
                   this.ensureElementIsVisible(previousElement);
                 }
               }
               this._suppressOnSelect = suppressSelect;
               // XXX actually it's just a refresh, but at least
               // the Extensions manager expects this:
               this._fireOnSelect();
               return;
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -218,39 +218,39 @@
             return;
 
           var targetElement;
           if (this._isRTLScrollbox)
             index *= -1;
           while (index < 0 && nextElement) {
             if (this._canScrollToElement(nextElement))
               targetElement = nextElement;
-            nextElement = nextElement.previousSibling;
+            nextElement = nextElement.previousElementSibling;
             index++;
           }
           while (index > 0 && nextElement) {
             if (this._canScrollToElement(nextElement))
               targetElement = nextElement;
-            nextElement = nextElement.nextSibling;
+            nextElement = nextElement.nextElementSibling;
             index--;
           }
           if (!targetElement)
             return;
 
           this.ensureElementIsVisible(targetElement, aInstant);
         ]]></body>
       </method>
 
       <method name="_getScrollableElements">
         <body><![CDATA[
-          var nodes = this.childNodes;
+          var nodes = this.children;
           if (nodes.length == 1 &&
               nodes[0].localName == "children" &&
               nodes[0].namespaceURI == "http://www.mozilla.org/xbl") {
-            nodes = document.getBindingParent(this).childNodes;
+            nodes = document.getBindingParent(this).children;
           }
 
           return Array.filter(nodes, this._canScrollToElement, this);
         ]]></body>
       </method>
 
       <method name="_elementFromPoint">
         <parameter name="aX"/>
@@ -747,18 +747,18 @@
             else
               x = this.scrollClientRect[end] + this.scrollClientSize;
             targetElement = this._elementFromPoint(x, scrollLeftOrUp ? -1 : 1);
 
             // the next partly-hidden element will become fully visible,
             // so don't scroll too far
             if (targetElement)
               targetElement = scrollBack ?
-                              targetElement.nextSibling :
-                              targetElement.previousSibling;
+                              targetElement.nextElementSibling :
+                              targetElement.previousElementSibling;
           }
 
           if (!targetElement) {
             // scroll to the first resp. last element
             let elements = this._getScrollableElements();
             targetElement = scrollBack ?
                             elements[0] :
                             elements[elements.length - 1];
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -235,17 +235,17 @@
           this.setAttribute("orient", "horizontal");
 
         if (this.tabbox && this.tabbox.hasAttribute("selectedIndex")) {
           let selectedIndex = parseInt(this.tabbox.getAttribute("selectedIndex"));
           this.selectedIndex = selectedIndex > 0 ? selectedIndex : 0;
           return;
         }
 
-        var children = this.childNodes;
+        var children = this.children;
         var length = children.length;
         for (var i = 0; i < length; i++) {
           if (children[i].getAttribute("selected") == "true") {
             this.selectedIndex = i;
             return;
           }
         }
 
@@ -293,30 +293,30 @@
                                                              linkedPanelId);
 
             return ownerDoc.getElementById(linkedPanelId);
           }
 
           // otherwise linked tabpanel element has the same index as the given
           // tab element.
           let tabElmIdx = this.getIndexOfItem(aTabElm);
-          return tabpanelsElm.childNodes[tabElmIdx];
+          return tabpanelsElm.children[tabElmIdx];
         ]]>
         </body>
       </method>
 
       <!-- nsIDOMXULSelectControlElement -->
       <property name="itemCount" readonly="true"
-                onget="return this.childNodes.length"/>
+                onget="return this.children.length"/>
 
       <property name="value" onget="return this.getAttribute('value');">
         <setter>
           <![CDATA[
             this.setAttribute("value", val);
-            var children = this.childNodes;
+            var children = this.children;
             for (var c = children.length - 1; c >= 0; c--) {
               if (children[c].value == val) {
                 this.selectedIndex = c;
                 break;
               }
             }
             return val;
           ]]>
@@ -347,30 +347,30 @@
       <!-- _tabbox is deprecated, it exists only for backwards compatibility. -->
       <field name="_tabbox" readonly="true"><![CDATA[
         this.tabbox;
       ]]></field>
 
       <property name="selectedIndex">
         <getter>
         <![CDATA[
-          const tabs = this.childNodes;
+          const tabs = this.children;
           for (var i = 0; i < tabs.length; i++) {
             if (tabs[i].selected)
               return i;
           }
           return -1;
         ]]>
         </getter>
 
         <setter>
         <![CDATA[
           var tab = this.getItemAtIndex(val);
           if (tab) {
-            Array.forEach(this.childNodes, function(aTab) {
+            Array.forEach(this.children, function(aTab) {
               if (aTab.selected && aTab != tab)
                 aTab._selected = false;
             });
             tab._selected = true;
 
             this.setAttribute("value", tab.value);
 
             let linkedPanel = this.getRelatedElement(tab);
@@ -385,17 +385,17 @@
           return val;
         ]]>
         </setter>
       </property>
 
       <property name="selectedItem">
         <getter>
         <![CDATA[
-          const tabs = this.childNodes;
+          const tabs = this.children;
           for (var i = 0; i < tabs.length; i++) {
             if (tabs[i].selected)
               return tabs[i];
           }
           return null;
         ]]>
         </getter>
 
@@ -409,42 +409,42 @@
         ]]>
         </setter>
       </property>
 
       <method name="getIndexOfItem">
         <parameter name="item"/>
         <body>
         <![CDATA[
-          return Array.indexOf(this.childNodes, item);
+          return Array.indexOf(this.children, item);
         ]]>
         </body>
       </method>
 
       <method name="getItemAtIndex">
         <parameter name="index"/>
         <body>
         <![CDATA[
-          return this.childNodes.item(index);
+          return this.children.item(index);
         ]]>
         </body>
       </method>
 
       <method name="_selectNewTab">
         <parameter name="aNewTab"/>
         <parameter name="aFallbackDir"/>
         <parameter name="aWrap"/>
         <body>
         <![CDATA[
           var requestedTab = aNewTab;
           while (aNewTab.hidden || aNewTab.disabled || !this._canAdvanceToTab(aNewTab)) {
-            aNewTab = aFallbackDir == -1 ? aNewTab.previousSibling : aNewTab.nextSibling;
+            aNewTab = aFallbackDir == -1 ? aNewTab.previousElementSibling : aNewTab.nextElementSibling;
             if (!aNewTab && aWrap)
-              aNewTab = aFallbackDir == -1 ? this.childNodes[this.childNodes.length - 1] :
-                                             this.childNodes[0];
+              aNewTab = aFallbackDir == -1 ? this.children[this.children.length - 1] :
+                                             this.children[0];
             if (!aNewTab || aNewTab == requestedTab)
               return;
           }
 
           var isTabFocused = false;
           try {
             isTabFocused =
               (document.commandDispatcher.focusedElement == this.selectedItem);
@@ -486,18 +486,18 @@
       <method name="advanceSelectedTab">
         <parameter name="aDir"/>
         <parameter name="aWrap"/>
         <body>
         <![CDATA[
           var startTab = this.selectedItem;
           var next = startTab[aDir == -1 ? "previousSibling" : "nextSibling"];
           if (!next && aWrap) {
-            next = aDir == -1 ? this.childNodes[this.childNodes.length - 1] :
-                                this.childNodes[0];
+            next = aDir == -1 ? this.children[this.children.length - 1] :
+                                this.children[0];
           }
           if (next && next != startTab) {
             this._selectNewTab(next, aDir, aWrap);
           }
         ]]>
         </body>
       </method>
 
@@ -552,21 +552,21 @@
             return null;
 
           let tabsElm = tabboxElm.tabs;
           if (!tabsElm)
             return null;
 
           // Return tab element having 'linkedpanel' attribute equal to the id
           // of the tab panel or the same index as the tab panel element.
-          let tabpanelIdx = Array.indexOf(this.childNodes, aTabPanelElm);
+          let tabpanelIdx = Array.indexOf(this.children, aTabPanelElm);
           if (tabpanelIdx == -1)
             return null;
 
-          let tabElms = tabsElm.childNodes;
+          let tabElms = tabsElm.children;
           let tabElmFromIndex = tabElms[tabpanelIdx];
 
           let tabpanelId = aTabPanelElm.id;
           if (tabpanelId) {
             for (let idx = 0; idx < tabElms.length; idx++) {
               var tabElm = tabElms[idx];
               if (tabElm.linkedPanel == tabpanelId)
                 return tabElm;
@@ -595,38 +595,38 @@
             }
             parent = parent.parentNode;
           }
 
           return this._tabbox = parent;
         ]]></getter>
       </property>
 
-      <field name="_selectedPanel">this.childNodes.item(this.selectedIndex)</field>
+      <field name="_selectedPanel">this.children.item(this.selectedIndex)</field>
 
       <property name="selectedIndex">
         <getter>
         <![CDATA[
           var indexStr = this.getAttribute("selectedIndex");
           return indexStr ? parseInt(indexStr) : -1;
         ]]>
         </getter>
 
         <setter>
         <![CDATA[
-          if (val < 0 || val >= this.childNodes.length)
+          if (val < 0 || val >= this.children.length)
             return val;
 
           // Give the tabbrowser a chance to run logic regardless of
           // whether the panel is going to change:
           this.dispatchEvent(new CustomEvent("preselect",
-            { detail: this.getRelatedElement(this.childNodes[val]) }));
+            { detail: this.getRelatedElement(this.children[val]) }));
 
           var panel = this._selectedPanel;
-          this._selectedPanel = this.childNodes[val];
+          this._selectedPanel = this.children[val];
           this.setAttribute("selectedIndex", val);
           if (this._selectedPanel != panel) {
             var event = document.createEvent("Events");
             event.initEvent("select", true, true);
             this.dispatchEvent(event);
           }
           return val;
         ]]>
@@ -638,17 +638,17 @@
           <![CDATA[
             return this._selectedPanel;
           ]]>
         </getter>
 
         <setter>
           <![CDATA[
             var selectedIndex = -1;
-            for (var panel = val; panel != null; panel = panel.previousSibling)
+            for (var panel = val; panel != null; panel = panel.previousElementSibling)
               ++selectedIndex;
             this.selectedIndex = selectedIndex;
             return val;
           ]]>
         </setter>
       </property>
     </implementation>
   </binding>
@@ -786,22 +786,22 @@
       <handler event="keydown" keycode="VK_DOWN" group="system" preventdefault="true">
       <![CDATA[
         this.parentNode.advanceSelectedTab(1, this.arrowKeysShouldWrap);
       ]]>
       </handler>
 
       <handler event="keydown" keycode="VK_HOME" group="system" preventdefault="true">
       <![CDATA[
-        this.parentNode._selectNewTab(this.parentNode.childNodes[0]);
+        this.parentNode._selectNewTab(this.parentNode.children[0]);
       ]]>
       </handler>
 
       <handler event="keydown" keycode="VK_END" group="system" preventdefault="true">
       <![CDATA[
-        var tabs = this.parentNode.childNodes;
+        var tabs = this.parentNode.children;
         this.parentNode._selectNewTab(tabs[tabs.length - 1], -1);
       ]]>
       </handler>
     </handlers>
   </binding>
 
 </bindings>
--- a/toolkit/modules/PageMenu.jsm
+++ b/toolkit/modules/PageMenu.jsm
@@ -71,17 +71,17 @@ PageMenu.prototype = {
     }
 
     let fragment = aPopup.ownerDocument.createDocumentFragment();
     this.buildXULMenu(aMenu, fragment);
 
     let pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
     if (pos == "start") {
       insertionPoint.insertBefore(fragment,
-                                  insertionPoint.firstChild);
+                                  insertionPoint.firstElementChild);
     } else if (pos.startsWith("#")) {
       insertionPoint.insertBefore(fragment, insertionPoint.querySelector(pos));
     } else {
       insertionPoint.appendChild(fragment);
     }
 
     this._browser = aBrowser;
     this._popup = aPopup;
@@ -175,64 +175,64 @@ PageMenu.prototype = {
       this._popup = null;
       this._builder = null;
       this._browser = null;
     }
   },
 
   // Get the first child of the given element with the given tag name.
   getImmediateChild(element, tag) {
-    let child = element.firstChild;
+    let child = element.firstElementChild;
     while (child) {
       if (child.localName == tag) {
         return child;
       }
-      child = child.nextSibling;
+      child = child.nextElementSibling;
     }
     return null;
   },
 
   // Return the location where the generated items should be inserted into the
   // given popup. They should be inserted as the next sibling of the returned
   // element.
   getInsertionPoint(aPopup) {
     if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
       return aPopup;
 
-    let element = aPopup.firstChild;
+    let element = aPopup.firstElementChild;
     while (element) {
       if (element.localName == "menu") {
         let popup = this.getImmediateChild(element, "menupopup");
         if (popup) {
           let result = this.getInsertionPoint(popup);
           if (result) {
             return result;
           }
         }
       }
-      element = element.nextSibling;
+      element = element.nextElementSibling;
     }
 
     return null;
   },
 
   // Remove the generated content from the given popup.
   removeGeneratedContent(aPopup) {
     let ungenerated = [];
     ungenerated.push(aPopup);
 
     let count;
     while (0 != (count = ungenerated.length)) {
       let last = count - 1;
       let element = ungenerated[last];
       ungenerated.splice(last, 1);
 
-      let i = element.childNodes.length;
+      let i = element.children.length;
       while (i-- > 0) {
-        let child = element.childNodes[i];
+        let child = element.children[i];
         if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
           ungenerated.push(child);
           continue;
         }
         element.removeChild(child);
       }
     }
   }
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -233,17 +233,17 @@ function PopupNotifications(tabbrowser, 
   // This listener will be attached to the chrome window whenever a notification
   // is showing, to allow the user to dismiss notifications using the escape key.
   this._handleWindowKeyPress = aEvent => {
     if (aEvent.keyCode != aEvent.DOM_VK_ESCAPE) {
       return;
     }
 
     // Esc key cancels the topmost notification, if there is one.
-    let notification = this.panel.firstChild;
+    let notification = this.panel.firstElementChild;
     if (!notification) {
       return;
     }
 
     let doc = this.window.document;
     let focusedElement = Services.focus.focusedElement;
 
     // If the chrome window has a focused element, let it handle the ESC key instead.
@@ -695,18 +695,18 @@ PopupNotifications.prototype = {
     // non-persistent.
     if (event && telemetryReason == TELEMETRY_STAT_DISMISSAL_CLOSE_BUTTON) {
       let notificationEl = getNotificationFromElement(event.target);
       if (notificationEl) {
         notificationEl.notification.options.persistent = false;
       }
     }
 
-    let browser = this.panel.firstChild &&
-                  this.panel.firstChild.notification.browser;
+    let browser = this.panel.firstElementChild &&
+                  this.panel.firstElementChild.notification.browser;
     this.panel.hidePopup();
     if (browser)
       browser.focus();
   },
 
   /**
    * Hides the notification popup.
    */
@@ -723,30 +723,30 @@ PopupNotifications.prototype = {
     return deferred.promise;
   },
 
   /**
    * Removes all notifications from the notification popup.
    */
   _clearPanel() {
     let popupnotification;
-    while ((popupnotification = this.panel.lastChild)) {
+    while ((popupnotification = this.panel.lastElementChild)) {
       this.panel.removeChild(popupnotification);
 
       // If this notification was provided by the chrome document rather than
       // created ad hoc, move it back to where we got it from.
       let originalParent = gNotificationParents.get(popupnotification);
       if (originalParent) {
         popupnotification.notification = null;
 
         // Remove nodes dynamically added to the notification's menu button
         // in _refreshPanel.
-        let contentNode = popupnotification.lastChild;
+        let contentNode = popupnotification.lastElementChild;
         while (contentNode) {
-          let previousSibling = contentNode.previousSibling;
+          let previousSibling = contentNode.previousElementSibling;
           if (contentNode.nodeName == "menuitem" ||
               contentNode.nodeName == "menuseparator")
             popupnotification.removeChild(contentNode);
           contentNode = previousSibling;
         }
 
         // Re-hide the notification such that it isn't rendered in the chrome
         // document. _refreshPanel will unhide it again when needed.
@@ -1022,17 +1022,17 @@ PopupNotifications.prototype = {
       if (notificationsToShow.some(n => n.options.persistent)) {
         this.panel.setAttribute("noautohide", "true");
       } else {
         this.panel.removeAttribute("noautohide");
       }
 
       // On OS X and Linux we need a different panel arrow color for
       // click-to-play plugins, so copy the popupid and use css.
-      this.panel.setAttribute("popupid", this.panel.firstChild.getAttribute("popupid"));
+      this.panel.setAttribute("popupid", this.panel.firstElementChild.getAttribute("popupid"));
       notificationsToShow.forEach(function(n) {
         // Record that the notification was actually displayed on screen.
         // Notifications that were opened a second time or that were originally
         // shown with "options.dismissed" will be recorded in a separate bucket.
         n._recordTelemetryStat(TELEMETRY_STAT_OFFERED);
         // Remember the time the notification was shown for the security delay.
         n.timeShown = this.window.performance.now();
       }, this);
@@ -1410,24 +1410,24 @@ PopupNotifications.prototype = {
     this._dismissOrRemoveCurrentNotifications();
 
     this._clearPanel();
 
     this._update();
   },
 
   _dismissOrRemoveCurrentNotifications() {
-    let browser = this.panel.firstChild &&
-                  this.panel.firstChild.notification.browser;
+    let browser = this.panel.firstElementChild &&
+                  this.panel.firstElementChild.notification.browser;
     if (!browser)
       return;
 
     let notifications = this._getNotificationsForBrowser(browser);
     // Mark notifications as dismissed and call dismissal callbacks
-    Array.forEach(this.panel.childNodes, function(nEl) {
+    Array.forEach(this.panel.children, function(nEl) {
       let notificationObj = nEl.notification;
       // Never call a dismissal handler on a notification that's been removed.
       if (!notifications.includes(notificationObj))
         return;
 
       // Record the time of the first notification dismissal if the main action
       // was not triggered in the meantime.
       let timeSinceShown = this.window.performance.now() - notificationObj.timeShown;
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -140,19 +140,19 @@ var SelectParentHelper = {
     closedWithEnter = false;
     selectRect = rect;
     this._registerListeners(browser, menulist.menupopup);
 
     let win = browser.ownerGlobal;
 
     // Set the maximum height to show exactly MAX_ROWS items.
     let menupopup = menulist.menupopup;
-    let firstItem = menupopup.firstChild;
+    let firstItem = menupopup.firstElementChild;
     while (firstItem && firstItem.hidden) {
-      firstItem = firstItem.nextSibling;
+      firstItem = firstItem.nextElementSibling;
     }
 
     if (firstItem) {
       let itemHeight = firstItem.getBoundingClientRect().height;
 
       // Include the padding and border on the popup.
       let cs = win.getComputedStyle(menupopup);
       let bpHeight = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth) +
@@ -464,39 +464,39 @@ function populateChildren(menulist, opti
       switch (event.key) {
         case "Escape":
           searchbox.parentElement.hidePopup();
           break;
         case "ArrowDown":
         case "Enter":
         case "Tab":
           searchbox.blur();
-          if (searchbox.nextSibling.localName == "menuitem" &&
-              !searchbox.nextSibling.hidden) {
-            menulist.menuBoxObject.activeChild = searchbox.nextSibling;
+          if (searchbox.nextElementSibling.localName == "menuitem" &&
+              !searchbox.nextElementSibling.hidden) {
+            menulist.menuBoxObject.activeChild = searchbox.nextElementSibling;
           } else {
-            var currentOption = searchbox.nextSibling;
+            var currentOption = searchbox.nextElementSibling;
             while (currentOption && (currentOption.localName != "menuitem" ||
                   currentOption.hidden)) {
-              currentOption = currentOption.nextSibling;
+              currentOption = currentOption.nextElementSibling;
             }
             if (currentOption) {
               menulist.menuBoxObject.activeChild = currentOption;
             } else {
               searchbox.focus();
             }
           }
           break;
         default:
           return;
       }
       event.preventDefault();
     }, true);
 
-    element.insertBefore(searchbox, element.childNodes[0]);
+    element.insertBefore(searchbox, element.children[0]);
   }
 
   return nthChildIndex;
 }
 
 function onSearchInput() {
   let searchObj = this;
 
@@ -527,17 +527,17 @@ function onSearchInput() {
       } else if (currentItem.localName == "menucaption") {
         if (prevCaption != null) {
           prevCaption.hidden = allHidden;
         }
         prevCaption = currentItem;
         allHidden = true;
       } else {
         if (!currentItem.classList.contains("contentSelectDropdown-ingroup") &&
-            currentItem.previousSibling.classList.contains("contentSelectDropdown-ingroup")) {
+            currentItem.previousElementSibling.classList.contains("contentSelectDropdown-ingroup")) {
           if (prevCaption != null) {
             prevCaption.hidden = allHidden;
           }
           prevCaption = null;
           allHidden = true;
         }
         if (itemLabel.includes(input) || itemTooltip.includes(input)) {
           currentItem.hidden = false;