Bug 1551320 - Replace all CreateElement calls in XUL documents with CreateXULElement. r=mossop
authorBrendan Dahl <bdahl@mozilla.com>
Mon, 20 May 2019 16:50:28 +0000
changeset 474564 8b074e2a3b68a339928e5b9f1d52f712e4bfce44
parent 474563 2adbd9cb0977c797d152abbc7b6411ce1e507e1e
child 474565 5a721a7648f2db40785729ed8fc7c7444c1afcaf
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmossop
bugs1551320
milestone69.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 1551320 - Replace all CreateElement calls in XUL documents with CreateXULElement. r=mossop Differential Revision: https://phabricator.services.mozilla.com/D31295
accessible/tests/mochitest/treeupdate/test_listbox.xul
browser/base/content/test/general/browser_clipboard_pastefile.js
browser/base/content/test/general/browser_gestureSupport.js
browser/components/BrowserGlue.jsm
browser/components/migration/content/migration.js
browser/components/newtab/lib/CFRPageActions.jsm
browser/components/places/content/places.js
browser/components/preferences/browserLanguages.js
devtools/client/performance/modules/marker-dom-utils.js
devtools/client/performance/modules/widgets/tree-view.js
devtools/client/shared/widgets/AbstractTreeItem.jsm
devtools/client/styleeditor/StyleEditorUI.jsm
devtools/client/webide/content/newapp.js
devtools/shared/fronts/css-properties.js
devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
docshell/test/chrome/test_bug453650.xul
docshell/test/chrome/test_bug846906.xul
docshell/test/chrome/test_principalInherit.xul
dom/base/test/chrome/file_bug549682.xul
dom/base/test/chrome/file_bug990812-1.xul
dom/base/test/chrome/file_bug990812.xul
dom/base/test/chrome/test_bug120684.xul
dom/base/test/chrome/test_bug683852.xul
dom/base/test/test_domrequesthelper.xul
dom/events/test/bug418986-3.js
dom/l10n/DOMOverlays.cpp
dom/l10n/tests/mochitest/test_domoverlays.xul
dom/messagechannel/tests/test_messageChannel.xul
dom/tests/browser/browser_bug396843.js
dom/tests/browser/browser_xhr_sandbox.js
dom/tests/mochitest/chrome/DOMWindowCreated_chrome.xul
dom/tests/mochitest/chrome/window_focus.xul
dom/tests/mochitest/general/test_offsets.js
dom/tests/mochitest/webcomponents/test_custom_element_namespace.xul
dom/xbl/crashtests/406900-1.xul
dom/xbl/test/test_bug398492.xul
dom/xul/test/test_import_xul_to_content.xul
js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
layout/base/tests/browser_bug617076.js
layout/reftests/bugs/272646-1.xul
layout/reftests/bugs/472020-1a.xul
layout/reftests/bugs/472020-1b.xul
layout/reftests/bugs/472020-2.xul
layout/style/test/chrome/bug418986-2.js
layout/xul/crashtests/538308-1.xul
layout/xul/grid/examples/dynamicgrid.xul
layout/xul/grid/examples/javascriptappend.xul
mobile/android/chrome/content/browser.js
mobile/android/chrome/geckoview/geckoview.js
testing/marionette/harness/marionette_harness/tests/unit/test_findelement_chrome.py
toolkit/components/extensions/ExtensionXPCShellUtils.jsm
toolkit/content/tests/chrome/test_bug437844.xul
toolkit/content/tests/chrome/test_custom_element_base.xul
toolkit/content/tests/chrome/window_largemenu.xul
toolkit/content/tests/chrome/window_panel.xul
toolkit/content/tests/chrome/xul_selectcontrol.js
toolkit/content/widgets/tree.js
toolkit/modules/CharsetMenu.jsm
toolkit/mozapps/extensions/test/browser/browser_html_message_bar.js
toolkit/mozapps/handling/content/dialog.js
--- a/accessible/tests/mochitest/treeupdate/test_listbox.xul
+++ b/accessible/tests/mochitest/treeupdate/test_listbox.xul
@@ -19,18 +19,18 @@
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
     function insertListitem(aListboxID)
     {
       this.listboxNode = getNode(aListboxID);
 
-      this.listitemNode = document.createElement("richlistitem");
-      var label = document.createElement("label");
+      this.listitemNode = document.createXULElement("richlistitem");
+      var label = document.createXULElement("label");
       label.setAttribute("value", "item1");
       this.listitemNode.appendChild(label);
 
       this.eventSeq = [
         new invokerChecker(EVENT_SHOW, this.listitemNode),
         new invokerChecker(EVENT_REORDER, this.listboxNode)
       ];
 
--- a/browser/base/content/test/general/browser_clipboard_pastefile.js
+++ b/browser/base/content/test/general/browser_clipboard_pastefile.js
@@ -1,13 +1,13 @@
 // This test is used to check that pasting files removes all non-file data from
 // event.clipboardData.
 
 add_task(async function() {
-  var textbox = document.createElement("textbox");
+  var textbox = document.createXULElement("textbox");
   document.documentElement.appendChild(textbox);
 
   textbox.focus();
   textbox.value = "Text";
   textbox.select();
 
   await new Promise((resolve, reject) => {
     textbox.addEventListener("copy", function(event) {
--- a/browser/base/content/test/general/browser_gestureSupport.js
+++ b/browser/base/content/test/general/browser_gestureSupport.js
@@ -331,17 +331,17 @@ function test_emitLatchedEvents(eventPre
   }
 
   // Send the wrap-up event. No commands should be triggered.
   test_utils.sendSimpleGestureEvent(eventPrefix, 0, 0, 0, cumulativeDelta, 0);
   checkBoth(6, "Increasing command was triggered", "Decreasing command was triggered");
 }
 
 function test_addCommand(prefName, id) {
-  let cmd = test_commandset.appendChild(document.createElement("command"));
+  let cmd = test_commandset.appendChild(document.createXULElement("command"));
   cmd.setAttribute("id", id);
   cmd.setAttribute("oncommand", "this.callCount++;");
 
   cmd.origPrefName = prefName;
   cmd.origPrefValue = Services.prefs.getCharPref(prefName);
   Services.prefs.setCharPref(prefName, id);
 
   return cmd;
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -3365,26 +3365,26 @@ var DefaultBrowserCheck = {
     Services.telemetry.getHistogramById("BROWSER_IS_USER_DEFAULT")
                       .add(!setAsDefaultError);
     Services.telemetry.getHistogramById("BROWSER_SET_DEFAULT_ERROR")
                       .add(setAsDefaultError);
   },
 
   _createPopup(win, notNowStrings, neverStrings) {
     let doc = win.document;
-    let popup = doc.createElement("menupopup");
+    let popup = doc.createXULElement("menupopup");
     popup.id = this.OPTIONPOPUP;
 
-    let notNowItem = doc.createElement("menuitem");
+    let notNowItem = doc.createXULElement("menuitem");
     notNowItem.id = "defaultBrowserNotNow";
     notNowItem.setAttribute("label", notNowStrings.label);
     notNowItem.setAttribute("accesskey", notNowStrings.accesskey);
     popup.appendChild(notNowItem);
 
-    let neverItem = doc.createElement("menuitem");
+    let neverItem = doc.createXULElement("menuitem");
     neverItem.id = "defaultBrowserNever";
     neverItem.setAttribute("label", neverStrings.label);
     neverItem.setAttribute("accesskey", neverStrings.accesskey);
     popup.appendChild(neverItem);
 
     popup.addEventListener("command", this);
 
     let popupset = doc.getElementById("mainPopupSet");
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -212,17 +212,17 @@ var MigrationWizard = { /* exported Migr
       profiles.firstChild.remove();
 
     // Note that this block is still reached even if the user chose 'From File'
     // and we canceled the dialog.  When that happens, _migrator will be null.
     if (this._migrator) {
       var sourceProfiles = this.spinResolve(this._migrator.getSourceProfiles());
 
       for (let profile of sourceProfiles) {
-        var item = document.createElement("radio");
+        var item = document.createXULElement("radio");
         item.id = profile.id;
         item.setAttribute("label", profile.name);
         profiles.appendChild(item);
       }
     }
 
     profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild;
   },
@@ -253,17 +253,17 @@ var MigrationWizard = { /* exported Migr
     while (dataSources.hasChildNodes())
       dataSources.firstChild.remove();
 
     var items = this.spinResolve(this._migrator.getMigrateData(this._selectedProfile,
                                                                this._autoMigrate));
     for (var i = 0; i < 16; ++i) {
       var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0;
       if (itemID > 0) {
-        var checkbox = document.createElement("checkbox");
+        var checkbox = document.createXULElement("checkbox");
         checkbox.id = itemID;
         checkbox.setAttribute("label",
           MigrationUtils.getLocalizedString(itemID + "_" + this._source));
         dataSources.appendChild(checkbox);
         if (!this._itemsFlags || this._itemsFlags & itemID)
           checkbox.checked = true;
       }
     }
@@ -339,17 +339,17 @@ var MigrationWizard = { /* exported Migr
     var items = document.getElementById(aID);
     while (items.hasChildNodes())
       items.firstChild.remove();
 
     var itemID;
     for (var i = 0; i < 16; ++i) {
       itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0;
       if (itemID > 0) {
-        var label = document.createElement("label");
+        var label = document.createXULElement("label");
         label.id = itemID + "_migrated";
         try {
           label.setAttribute("value",
             MigrationUtils.getLocalizedString(itemID + "_" + this._source));
           items.appendChild(label);
         } catch (e) {
           // if the block above throws, we've enumerated all the import data types we
           // currently support and are now just wasting time, break.
--- a/browser/components/newtab/lib/CFRPageActions.jsm
+++ b/browser/components/newtab/lib/CFRPageActions.jsm
@@ -286,17 +286,17 @@ class PageAction {
     if (rating || users) {
       footerSpacer.removeAttribute("hidden");
     } else {
       footerSpacer.setAttribute("hidden", true);
     }
   }
 
   _createElementAndAppend({type, id}, parent) {
-    let element = this.window.document.createElement(type);
+    let element = this.window.document.createXULElement(type);
     if (id) {
       element.setAttribute("id", id);
     }
     parent.appendChild(element);
     return element;
   }
 
   async _renderPinTabAnimation() {
@@ -392,22 +392,22 @@ class PageAction {
         RecommendationMap.delete(browser);
       };
       panelTitle = await this.getStrings(content.heading_text);
 
       if (stepsContainer) { // If it exists we need to empty it
         stepsContainer.remove();
         stepsContainer = stepsContainer.cloneNode(false);
       } else {
-        stepsContainer = this.window.document.createElement("vbox");
+        stepsContainer = this.window.document.createXULElement("vbox");
         stepsContainer.setAttribute("id", stepsContainerId);
       }
       footerText.parentNode.appendChild(stepsContainer);
       for (let step of content.descriptionDetails.steps) {
-        const li = this.window.document.createElement("li");
+        const li = this.window.document.createXULElement("li");
         this._l10n.setAttributes(li, step.string_id);
         stepsContainer.appendChild(li);
       }
       await this._l10n.translateElements([...stepsContainer.children]);
 
       await this._renderPinTabAnimation();
     }
 
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -482,26 +482,26 @@ var PlacesOrganizer = {
                                                    bookmarkCount,
                                                    [bookmarkCount]) +
                      ")";
         } else {
           sizeInfo = " (" + sizeString + ")";
         }
 
         let backupDate = PlacesBackups.getDateForFile(backupFiles[i]);
-        let m = restorePopup.insertBefore(document.createElement("menuitem"),
+        let m = restorePopup.insertBefore(document.createXULElement("menuitem"),
                                           document.getElementById("restoreFromFile"));
         m.setAttribute("label", dateFormatter.format(backupDate) + sizeInfo);
         m.setAttribute("value", OS.Path.basename(backupFiles[i]));
         m.setAttribute("oncommand",
                        "PlacesOrganizer.onRestoreMenuItemClick(this);");
       }
 
       // Add the restoreFromFile item.
-      restorePopup.insertBefore(document.createElement("menuseparator"),
+      restorePopup.insertBefore(document.createXULElement("menuseparator"),
                                 document.getElementById("restoreFromFile"));
     })();
   },
 
   /**
    * Called when a menuitem is selected from the restore menu.
    */
   async onRestoreMenuItemClick(aMenuItem) {
@@ -967,17 +967,17 @@ var ViewMenu = {
   fillWithColumns: function VM_fillWithColumns(event, startID, endID, type, propertyPrefix) {
     var popup = event.target;
     var pivot = this._clean(popup, startID, endID);
 
     var content = document.getElementById("placeContent");
     var columns = content.columns;
     for (var i = 0; i < columns.count; ++i) {
       var column = columns.getColumnAt(i).element;
-      var menuitem = document.createElement("menuitem");
+      var menuitem = document.createXULElement("menuitem");
       menuitem.id = "menucol_" + column.id;
       menuitem.column = column;
       var label = column.getAttribute("label");
       if (propertyPrefix) {
         var menuitemPrefix = propertyPrefix;
         // for string properties, use "name" as the id, instead of "title"
         // see bug #386287 for details
         var columnId = column.getAttribute("anonid");
--- a/browser/components/preferences/browserLanguages.js
+++ b/browser/components/preferences/browserLanguages.js
@@ -165,21 +165,21 @@ class OrderedListBox {
     }
     this.richlistbox.appendChild(frag);
 
     this.richlistbox.selectedIndex = 0;
     this.richlistbox.ensureElementIsVisible(this.richlistbox.selectedItem);
   }
 
   createItem({id, label, value}) {
-    let listitem = document.createElement("richlistitem");
+    let listitem = document.createXULElement("richlistitem");
     listitem.id = id;
     listitem.setAttribute("value", value);
 
-    let labelEl = document.createElement("label");
+    let labelEl = document.createXULElement("label");
     labelEl.textContent = label;
     listitem.appendChild(labelEl);
 
     return listitem;
   }
 }
 
 class SortedItemSelectList {
@@ -244,17 +244,17 @@ class SortedItemSelectList {
     let i = items.findIndex(el => compareFn(el, item) >= 0);
     items.splice(i, 0, item);
     popup.insertBefore(this.createItem(item), menulist.getItemAtIndex(i));
 
     menulist.disabled = menulist.itemCount == 0;
   }
 
   createItem({label, value, className, disabled}) {
-    let item = document.createElement("menuitem");
+    let item = document.createXULElement("menuitem");
     item.setAttribute("label", label);
     if (value)
       item.value = value;
     if (className)
       item.classList.add(className);
     if (disabled)
       item.setAttribute("disabled", "true");
     return item;
--- a/devtools/client/performance/modules/marker-dom-utils.js
+++ b/devtools/client/performance/modules/marker-dom-utils.js
@@ -34,24 +34,24 @@ exports.MarkerDOMUtils = {
    *
    * @param document doc
    * @param object marker
    * @return Node
    */
   buildTitle: function(doc, marker) {
     const blueprint = MarkerBlueprintUtils.getBlueprintFor(marker);
 
-    const hbox = doc.createElement("hbox");
+    const hbox = doc.createXULElement("hbox");
     hbox.setAttribute("align", "center");
 
-    const bullet = doc.createElement("hbox");
+    const bullet = doc.createXULElement("hbox");
     bullet.className = `marker-details-bullet marker-color-${blueprint.colorName}`;
 
     const title = MarkerBlueprintUtils.getMarkerLabel(marker);
-    const label = doc.createElement("label");
+    const label = doc.createXULElement("label");
     label.className = "marker-details-type";
     label.setAttribute("value", title);
 
     hbox.appendChild(bullet);
     hbox.appendChild(label);
 
     return hbox;
   },
@@ -82,25 +82,25 @@ exports.MarkerDOMUtils = {
    * E.g. "Start: 100ms", "Duration: 200ms", ...
    *
    * @param document doc
    * @param string field
    * @param string value
    * @return Node
    */
   buildNameValueLabel: function(doc, field, value) {
-    const hbox = doc.createElement("hbox");
+    const hbox = doc.createXULElement("hbox");
     hbox.className = "marker-details-labelcontainer";
 
-    const nameLabel = doc.createElement("label");
+    const nameLabel = doc.createXULElement("label");
     nameLabel.className = "plain marker-details-name-label";
     nameLabel.setAttribute("value", field);
     hbox.appendChild(nameLabel);
 
-    const valueLabel = doc.createElement("label");
+    const valueLabel = doc.createXULElement("label");
     valueLabel.className = "plain marker-details-value-label";
     valueLabel.setAttribute("value", value);
     hbox.appendChild(valueLabel);
 
     return hbox;
   },
 
   /**
@@ -114,17 +114,17 @@ exports.MarkerDOMUtils = {
    *          - number frameIndex: the index of the topmost stack frame
    *          - array frames: array of stack frames
    */
   buildStackTrace: function(doc, { type, frameIndex, frames }) {
     const container = doc.createXULElement("vbox");
     container.className = "marker-details-stack";
     container.setAttribute("type", type);
 
-    const nameLabel = doc.createElement("label");
+    const nameLabel = doc.createXULElement("label");
     nameLabel.className = "plain marker-details-name-label";
     nameLabel.setAttribute("value", L10N.getStr(`marker.field.${type}`));
     container.appendChild(nameLabel);
 
     // Workaround for profiles that have looping stack traces.  See
     // bug 1246555.
     let wasAsyncParent = false;
     const seen = new Set();
@@ -139,64 +139,64 @@ exports.MarkerDOMUtils = {
       const url = frame.source;
       const displayName = frame.functionDisplayName;
       const line = frame.line;
 
       // If the previous frame had an async parent, then the async
       // cause is in this frame and should be displayed.
       if (wasAsyncParent) {
         const asyncStr = L10N.getFormatStr("marker.field.asyncStack", frame.asyncCause);
-        const asyncBox = doc.createElement("hbox");
-        const asyncLabel = doc.createElement("label");
+        const asyncBox = doc.createXULElement("hbox");
+        const asyncLabel = doc.createXULElement("label");
         asyncLabel.className = "devtools-monospace";
         asyncLabel.setAttribute("value", asyncStr);
         asyncBox.appendChild(asyncLabel);
         container.appendChild(asyncBox);
         wasAsyncParent = false;
       }
 
-      const hbox = doc.createElement("hbox");
+      const hbox = doc.createXULElement("hbox");
 
       if (displayName) {
-        const functionLabel = doc.createElement("label");
+        const functionLabel = doc.createXULElement("label");
         functionLabel.className = "devtools-monospace";
         functionLabel.setAttribute("value", displayName);
         hbox.appendChild(functionLabel);
       }
 
       if (url) {
-        const linkNode = doc.createElement("a");
+        const linkNode = doc.createXULElement("a");
         linkNode.className = "waterfall-marker-location devtools-source-link";
         linkNode.href = url;
         linkNode.draggable = false;
         linkNode.setAttribute("title", url);
 
-        const urlLabel = doc.createElement("label");
+        const urlLabel = doc.createXULElement("label");
         urlLabel.className = "filename";
         urlLabel.setAttribute("value", getSourceNames(url).short);
         linkNode.appendChild(urlLabel);
 
-        const lineLabel = doc.createElement("label");
+        const lineLabel = doc.createXULElement("label");
         lineLabel.className = "line-number";
         lineLabel.setAttribute("value", `:${line}`);
         linkNode.appendChild(lineLabel);
 
         hbox.appendChild(linkNode);
 
         // Clicking here will bubble up to the parent,
         // which handles the view source.
         linkNode.setAttribute("data-action", JSON.stringify({
           url: url,
           line: line,
           action: "view-source",
         }));
       }
 
       if (!displayName && !url) {
-        const unknownLabel = doc.createElement("label");
+        const unknownLabel = doc.createXULElement("label");
         unknownLabel.setAttribute("value", L10N.getStr("marker.value.unknownFrame"));
         hbox.appendChild(unknownLabel);
       }
 
       container.appendChild(hbox);
 
       if (frame.asyncParent) {
         frameIndex = frame.asyncParent;
@@ -216,20 +216,20 @@ exports.MarkerDOMUtils = {
    * @param object marker
    * @param object options
    * @return array<Node>
    */
   buildCustom: function(doc, marker, options) {
     const elements = [];
 
     if (options.allocations && shouldShowAllocationsTrigger(marker)) {
-      const hbox = doc.createElement("hbox");
+      const hbox = doc.createXULElement("hbox");
       hbox.className = "marker-details-customcontainer";
 
-      const label = doc.createElement("label");
+      const label = doc.createXULElement("label");
       label.className = "custom-button";
       label.setAttribute("value", "Show allocation triggers");
       label.setAttribute("type", "show-allocations");
       label.setAttribute("data-action", JSON.stringify({
         endTime: marker.start,
         action: "show-allocations",
       }));
 
--- a/devtools/client/performance/modules/widgets/tree-view.js
+++ b/devtools/client/performance/modules/widgets/tree-view.js
@@ -194,17 +194,17 @@ CallView.prototype = extend(AbstractTree
       }
     }
 
     if (this.visibleCells.function) {
       cells.push(this._createFunctionCell(document, arrowNode, frameInfo.name, frameInfo,
                                           this.level));
     }
 
-    const targetNode = document.createElement("hbox");
+    const targetNode = document.createXULElement("hbox");
     targetNode.className = "call-tree-item";
     targetNode.setAttribute("origin", frameInfo.isContent ? "content" : "chrome");
     targetNode.setAttribute("category", frameInfo.categoryData.abbrev || "");
     targetNode.setAttribute("tooltiptext", frameInfo.tooltiptext);
 
     if (this.hidden) {
       targetNode.style.display = "none";
     }
@@ -238,45 +238,45 @@ CallView.prototype = extend(AbstractTree
     children.sort(this.sortingPredicate.bind(this));
   },
 
   /**
    * Functions creating each cell in this call view.
    * Invoked by `_displaySelf`.
    */
   _createCell: function(doc, value, type) {
-    const cell = doc.createElement("description");
+    const cell = doc.createXULElement("description");
     cell.className = "plain call-tree-cell";
     cell.setAttribute("type", type);
     cell.setAttribute("crop", "end");
     // Add a tabulation to the cell text in case it's is selected and copied.
     cell.textContent = value + "\t";
     return cell;
   },
 
   _createFunctionCell: function(doc, arrowNode, frameName, frameInfo, frameLevel) {
-    const cell = doc.createElement("hbox");
+    const cell = doc.createXULElement("hbox");
     cell.className = "call-tree-cell";
     cell.style.marginInlineStart = (frameLevel * CALL_TREE_INDENTATION) + "px";
     cell.setAttribute("type", "function");
     cell.appendChild(arrowNode);
 
     // Render optimization hint if this frame has opt data.
     if (this.root.showOptimizationHint && frameInfo.hasOptimizations &&
         !frameInfo.isMetaCategory) {
-      const icon = doc.createElement("description");
+      const icon = doc.createXULElement("description");
       icon.setAttribute("tooltiptext", VIEW_OPTIMIZATIONS_TOOLTIP);
       icon.className = "opt-icon";
       cell.appendChild(icon);
     }
 
     // Don't render a name label node if there's no function name. A different
     // location label node will be rendered instead.
     if (frameName) {
-      const nameNode = doc.createElement("description");
+      const nameNode = doc.createXULElement("description");
       nameNode.className = "plain call-tree-name";
       nameNode.textContent = frameName;
       cell.appendChild(nameNode);
     }
 
     // Don't render detailed labels for meta category frames
     if (!frameInfo.isMetaCategory) {
       this._appendFunctionDetailsCells(doc, cell, frameInfo);
@@ -299,47 +299,47 @@ CallView.prototype = extend(AbstractTree
     const levelIndicator = frameLevel > 0 ? " ".repeat(frameLevel) : "";
     firstDescription.textContent = levelIndicator + firstDescription.textContent;
 
     return cell;
   },
 
   _appendFunctionDetailsCells: function(doc, cell, frameInfo) {
     if (frameInfo.fileName) {
-      const urlNode = doc.createElement("description");
+      const urlNode = doc.createXULElement("description");
       urlNode.className = "plain call-tree-url";
       urlNode.textContent = frameInfo.fileName;
       urlNode.setAttribute("tooltiptext", URL_LABEL_TOOLTIP + " → " + frameInfo.url);
       urlNode.addEventListener("mousedown", this._onUrlClick);
       cell.appendChild(urlNode);
     }
 
     if (frameInfo.line) {
-      const lineNode = doc.createElement("description");
+      const lineNode = doc.createXULElement("description");
       lineNode.className = "plain call-tree-line";
       lineNode.textContent = ":" + frameInfo.line;
       cell.appendChild(lineNode);
     }
 
     if (frameInfo.column) {
-      const columnNode = doc.createElement("description");
+      const columnNode = doc.createXULElement("description");
       columnNode.className = "plain call-tree-column";
       columnNode.textContent = ":" + frameInfo.column;
       cell.appendChild(columnNode);
     }
 
     if (frameInfo.host) {
-      const hostNode = doc.createElement("description");
+      const hostNode = doc.createXULElement("description");
       hostNode.className = "plain call-tree-host";
       hostNode.textContent = frameInfo.host;
       cell.appendChild(hostNode);
     }
 
     if (frameInfo.categoryData.label) {
-      const categoryNode = doc.createElement("description");
+      const categoryNode = doc.createXULElement("description");
       categoryNode.className = "plain call-tree-category";
       categoryNode.style.color = frameInfo.categoryData.color;
       categoryNode.textContent = frameInfo.categoryData.label;
       cell.appendChild(categoryNode);
     }
   },
 
   /**
--- a/devtools/client/shared/widgets/AbstractTreeItem.jsm
+++ b/devtools/client/shared/widgets/AbstractTreeItem.jsm
@@ -32,17 +32,17 @@ this.EXPORTED_SYMBOLS = ["AbstractTreeIt
  *
  * function MyCustomTreeItem(dataSrc, properties) {
  *   AbstractTreeItem.call(this, properties);
  *   this.itemDataSrc = dataSrc;
  * }
  *
  * MyCustomTreeItem.prototype = extend(AbstractTreeItem.prototype, {
  *   _displaySelf: function(document, arrowNode) {
- *     let node = document.createElement("hbox");
+ *     let node = document.createXULElement("hbox");
  *     ...
  *     // Append the provided arrow node wherever you want.
  *     node.appendChild(arrowNode);
  *     ...
  *     // Use `this.itemDataSrc` to customize the tree item and
  *     // `this.level` to calculate the indentation.
  *     node.style.marginInlineStart = (this.level * 10) + "px";
  *     node.appendChild(document.createTextNode(this.itemDataSrc.label));
@@ -438,17 +438,17 @@ AbstractTreeItem.prototype = {
     this._onClick = this._onClick.bind(this);
     this._onDoubleClick = this._onDoubleClick.bind(this);
     this._onKeyDown = this._onKeyDown.bind(this);
     this._onFocus = this._onFocus.bind(this);
     this._onBlur = this._onBlur.bind(this);
 
     const document = this.document;
 
-    const arrowNode = this._arrowNode = document.createElement("hbox");
+    const arrowNode = this._arrowNode = document.createXULElement("hbox");
     arrowNode.className = "arrow theme-twisty";
     arrowNode.addEventListener("mousedown", this._onArrowClick);
 
     const targetNode = this._targetNode = this._displaySelf(document, arrowNode);
     targetNode.style.MozUserFocus = "normal";
 
     targetNode.addEventListener("mousedown", this._onClick);
     targetNode.addEventListener("dblclick", this._onDoubleClick);
--- a/devtools/client/styleeditor/StyleEditorUI.jsm
+++ b/devtools/client/styleeditor/StyleEditorUI.jsm
@@ -33,16 +33,18 @@ loader.lazyRequireGetter(this, "copyStri
 const LOAD_ERROR = "error-load";
 const STYLE_EDITOR_TEMPLATE = "stylesheet";
 const SELECTOR_HIGHLIGHTER_TYPE = "SelectorHighlighter";
 const PREF_MEDIA_SIDEBAR = "devtools.styleeditor.showMediaSidebar";
 const PREF_SIDEBAR_WIDTH = "devtools.styleeditor.mediaSidebarWidth";
 const PREF_NAV_WIDTH = "devtools.styleeditor.navSidebarWidth";
 const PREF_ORIG_SOURCES = "devtools.source-map.client-service.enabled";
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
 /**
  * StyleEditorUI is controls and builds the UI of the Style Editor, including
  * maintaining a list of editors for each stylesheet on a debuggee.
  *
  * Emits events:
  *   'editor-added': A new editor was added to the UI
  *   'editor-selected': An editor was selected
  *   'error': An error occured
@@ -892,34 +894,34 @@ StyleEditorUI.prototype = {
         }
 
         // this @media rule is from a different original source
         if (location.source != editor.styleSheet.href) {
           continue;
         }
         inSource = true;
 
-        const div = this._panelDoc.createElement("div");
+        const div = this._panelDoc.createElementNS(HTML_NS, "div");
         div.className = "media-rule-label";
         div.addEventListener("click",
                              this._jumpToLocation.bind(this, location));
 
-        const cond = this._panelDoc.createElement("div");
+        const cond = this._panelDoc.createElementNS(HTML_NS, "div");
         cond.className = "media-rule-condition";
         if (!rule.matches) {
           cond.classList.add("media-condition-unmatched");
         }
         if (this._target.isLocalTab) {
           this._setConditionContents(cond, rule.conditionText);
         } else {
           cond.textContent = rule.conditionText;
         }
         div.appendChild(cond);
 
-        const link = this._panelDoc.createElement("div");
+        const link = this._panelDoc.createElementNS(HTML_NS, "div");
         link.className = "media-rule-line theme-link";
         if (location.line != -1) {
           link.textContent = ":" + location.line;
         }
         div.appendChild(link);
 
         list.appendChild(div);
       }
@@ -945,17 +947,17 @@ StyleEditorUI.prototype = {
     let lastParsed = 0;
     while (match && match.index != minMaxPattern.lastIndex) {
       const matchEnd = match.index + match[0].length;
       const node = this._panelDoc.createTextNode(
         rawText.substring(lastParsed, match.index)
       );
       element.appendChild(node);
 
-      const link = this._panelDoc.createElement("a");
+      const link = this._panelDoc.createElementNS(HTML_NS, "a");
       link.href = "#";
       link.className = "media-responsive-mode-toggle";
       link.textContent = rawText.substring(match.index, matchEnd);
       link.addEventListener("click", this._onMediaConditionClick.bind(this));
       element.appendChild(link);
 
       match = minMaxPattern.exec(rawText);
       lastParsed = matchEnd;
--- a/devtools/client/webide/content/newapp.js
+++ b/devtools/client/webide/content/newapp.js
@@ -32,24 +32,24 @@ function getTemplatesJSON() {
     }
     if (list.length == 0) {
       throw new Error("JSON response is an empty array");
     }
     gTemplateList = list;
     const templatelistNode = document.querySelector("#templatelist");
     templatelistNode.innerHTML = "";
     for (const template of list) {
-      const richlistitemNode = document.createElement("richlistitem");
-      const imageNode = document.createElement("image");
+      const richlistitemNode = document.createXULElement("richlistitem");
+      const imageNode = document.createXULElement("image");
       imageNode.setAttribute("src", template.icon);
-      const labelNode = document.createElement("label");
+      const labelNode = document.createXULElement("label");
       labelNode.setAttribute("value", template.name);
-      const descriptionNode = document.createElement("description");
+      const descriptionNode = document.createXULElement("description");
       descriptionNode.textContent = template.description;
-      const vboxNode = document.createElement("vbox");
+      const vboxNode = document.createXULElement("vbox");
       vboxNode.setAttribute("flex", "1");
       richlistitemNode.appendChild(imageNode);
       vboxNode.appendChild(labelNode);
       vboxNode.appendChild(descriptionNode);
       richlistitemNode.appendChild(vboxNode);
       templatelistNode.appendChild(richlistitemNode);
     }
     templatelistNode.selectedIndex = 0;
--- a/devtools/shared/fronts/css-properties.js
+++ b/devtools/shared/fronts/css-properties.js
@@ -119,17 +119,17 @@ CssProperties.prototype = {
    * @param {String} Property name.
    * @param {String} Property value.
    * @param {Document} The client's document object.
    * @return {Boolean}
    */
   isValidOnClient(name, value, doc) {
     let dummyElement = this._dummyElements.get(doc);
     if (!dummyElement) {
-      dummyElement = doc.createElement("div");
+      dummyElement = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
       this._dummyElements.set(doc, dummyElement);
     }
 
     // `!important` is not a valid value when setting a style declaration in the
     // CSS Object Model.
     const sanitizedValue = ("" + value).replace(/!\s*important\s*$/, "");
 
     // Test the style on the element.
--- a/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
+++ b/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js
@@ -1,61 +1,62 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests that the markup localization works properly.
 
 const { localizeMarkup, LocalizationHelper } = require("devtools/shared/l10n");
+const HTML_NS = "http://www.w3.org/1999/xhtml";
 
 add_task(async function() {
   info("Check that the strings used for this test are still valid");
   const STARTUP_L10N =
     new LocalizationHelper("devtools/client/locales/startup.properties");
   const TOOLBOX_L10N =
     new LocalizationHelper("devtools/client/locales/toolbox.properties");
   const str1 = STARTUP_L10N.getStr("inspector.label");
   const str2 = STARTUP_L10N.getStr("inspector.accesskey");
   const str3 = TOOLBOX_L10N.getStr("toolbox.defaultTitle");
   ok(str1 && str2 && str3, "If this failed, strings should be updated in the test");
 
   info("Create the test markup");
-  const div = document.createElement("div");
+  const div = document.createElementNS(HTML_NS, "div");
   div.setAttribute("data-localization-bundle",
                    "devtools/client/locales/startup.properties");
-  const div0 = document.createElement("div");
+  const div0 = document.createElementNS(HTML_NS, "div");
   div0.setAttribute("id", "d0");
   div0.setAttribute("data-localization", "content=inspector.someInvalidKey");
   div.appendChild(div0);
-  const div1 = document.createElement("div");
+  const div1 = document.createElementNS(HTML_NS, "div");
   div1.setAttribute("id", "d1");
   div1.setAttribute("data-localization", "content=inspector.label");
   div.appendChild(div1);
   div1.append("Text will disappear");
-  const div2 = document.createElement("div");
+  const div2 = document.createElementNS(HTML_NS, "div");
   div2.setAttribute("id", "d2");
   div2.setAttribute("data-localization",
                     "content=inspector.label;title=inspector.accesskey");
   div.appendChild(div2);
-  const div3 = document.createElement("div");
+  const div3 = document.createElementNS(HTML_NS, "div");
   div3.setAttribute("id", "d3");
   div3.setAttribute("data-localization",
                     "content=inspector.label;title=inspector.accesskey");
   div.appendChild(div3);
-  const div4 = document.createElement("div");
+  const div4 = document.createElementNS(HTML_NS, "div");
   div4.setAttribute("id", "d4");
   div4.setAttribute("data-localization", "aria-label=inspector.label");
   div.appendChild(div4);
   div4.append("Some content");
-  const toolboxDiv = document.createElement("div");
+  const toolboxDiv = document.createElementNS(HTML_NS, "div");
   toolboxDiv.setAttribute("data-localization-bundle",
                           "devtools/client/locales/toolbox.properties");
   div.appendChild(toolboxDiv);
-  const div5 = document.createElement("div");
+  const div5 = document.createElementNS(HTML_NS, "div");
   div5.setAttribute("id", "d5");
   div5.setAttribute("data-localization", "content=toolbox.defaultTitle");
   toolboxDiv.appendChild(div5);
 
   info("Use localization helper to localize the test markup");
   localizeMarkup(div);
 
   is(div1.innerHTML, str1, "The content of #d1 is localized");
--- a/docshell/test/chrome/test_bug453650.xul
+++ b/docshell/test/chrome/test_bug453650.xul
@@ -15,17 +15,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   /** Test for Bug 453650 **/
   SimpleTest.waitForExplicitFinish();
 
   var iter = runTests();
   nextTest();
 
   function* runTests() {
-    var iframe = document.createElement("iframe");
+    var iframe = document.createXULElement("iframe");
     iframe.style.width = "300px";
     iframe.style.height = "300px";
     iframe.setAttribute("src", "data:text/html,<h1 id='h'>hello</h1>");
 
     document.documentElement.appendChild(iframe);
     yield whenLoaded(iframe);
     info("iframe loaded");
 
--- a/docshell/test/chrome/test_bug846906.xul
+++ b/docshell/test/chrome/test_bug846906.xul
@@ -33,17 +33,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   ok(interfaceRequestor, "Should be able to query interface requestor interface");
 
   var docShell = windowlessBrowser.docShell;
   ok(docShell, "Should be able to get doc shell interface");
 
   var document = webNavigation.document;
   ok(document, "Should be able to get document");
 
-  var iframe = document.createElement("iframe");
+  var iframe = document.createXULElement("iframe");
   ok(iframe, "Should be able to create iframe");
 
   iframe.onload = function () {
     ok(true, "Should receive initial onload event");
 
     iframe.onload = function () {
         ok(true, "Should receive onload event");
 
--- a/docshell/test/chrome/test_principalInherit.xul
+++ b/docshell/test/chrome/test_principalInherit.xul
@@ -33,17 +33,17 @@ var gFrame;
 // This test file is loaded in a type=content docshell whose principal is
 // the system principal.
 
 // Using data: URIs here instead of javascript: URIs, since javascript: URIs
 // fail to load when there's no principal to load them against. This only
 // matters when these tests fail (produces better error messages).
 var tests = [
   function testInheritFromParent(cb) {
-    gFrame = document.createElement("iframe");
+    gFrame = document.createXULElement("iframe");
     loadListener(gFrame, function () {
       is(window.inheritedFromParent, true, "load in type=content iframe inherited principal of same type parent");
       cb();
     });
     gFrame.setAttribute("type", "content");
     gFrame.setAttribute("src", "data:text/html,<script>parent.inheritedFromParent = true;</script>");
     document.documentElement.appendChild(gFrame);
   },
@@ -58,17 +58,17 @@ var tests = [
     // Open a new chrome window with a type="content" iframe, so that it has no
     // same-type parent.
     // Load a javascript: URI in it to ensure that GetInheritedPrincipal will
     // force creation of a content viewer.
     let xulWinURL = 'data:application/vnd.mozilla.xul+xml,<?xml version="1.0"?>' +
                     '<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>';
     let newWin = window.openDialog(xulWinURL, "chrome_window", "chrome");
     loadListener(newWin, function () {
-      let frame = newWin.document.createElement("iframe");
+      let frame = newWin.document.createXULElement("iframe");
       frame.setAttribute("type", "content");
       frame.setAttribute("src", "javascript:'1';");
       loadListener(frame, function () {
         is(frame.contentWindow.document.body.textContent, "1", "content viewer was created");
         SimpleTest.executeSoon(function () {
           newWin.close();
           cb();
         })
--- a/dom/base/test/chrome/file_bug549682.xul
+++ b/dom/base/test/chrome/file_bug549682.xul
@@ -168,17 +168,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       is(c, 1, "Should be called only once!");
     });
     // This loads the script in the existing <browser>
     messageManager.loadFrameScript(toBeRemovedScript, true);
     // But it won't be loaded in the dynamically created <browser>
     messageManager.removeDelayedFrameScript(toBeRemovedScript);
 
     var oldValue = globalListenerCallCount;
-    var b = document.createElement("browser");
+    var b = document.createXULElement("browser");
     b.setAttribute("type", "content");
     document.documentElement.appendChild(b);
     is(globalListenerCallCount, oldValue + 1,
                               "Wrong message count");
 
     localmm.addWeakMessageListener('weak', weakListener);
     localmm.addMessageListener('weakdone', weakDoneListener);
 
--- a/dom/base/test/chrome/file_bug990812-1.xul
+++ b/dom/base/test/chrome/file_bug990812-1.xul
@@ -40,17 +40,17 @@ https://bugzilla.mozilla.org/show_bug.cg
         opener.wrappedJSObject.is(msg.data, next, "received test:" + next);
 
         if (order.length == 0) {
           opener.setTimeout(function() { this.next(); });
           window.close();
         }
       });
 
-      var browser = document.createElement("browser");
+      var browser = document.createXULElement("browser");
       browser.setAttribute("messagemanagergroup", "test");
       browser.setAttribute("src", "about:mozilla");
       browser.setAttribute("type", "content");
       document.documentElement.appendChild(browser);
 
       globalMM.removeDelayedFrameScript(FRAME_SCRIPT_GLOBAL);
       messageManager.removeDelayedFrameScript(FRAME_SCRIPT_WINDOW);
       getGroupMessageManager("test").removeDelayedFrameScript(FRAME_SCRIPT_GROUP);
--- a/dom/base/test/chrome/file_bug990812.xul
+++ b/dom/base/test/chrome/file_bug990812.xul
@@ -34,17 +34,17 @@ https://bugzilla.mozilla.org/show_bug.cg
         opener.wrappedJSObject.is(msg.data, next, "received test:" + next);
 
         if (order.length == 0) {
           opener.setTimeout("next()");
           window.close();
         }
       });
 
-      var browser = document.createElement("browser");
+      var browser = document.createXULElement("browser");
       browser.setAttribute("messagemanagergroup", "test");
       browser.setAttribute("src", "about:mozilla");
       browser.setAttribute("type", "content");
       document.documentElement.appendChild(browser);
 
       globalMM.removeDelayedFrameScript(FRAME_SCRIPT_GLOBAL);
       messageManager.removeDelayedFrameScript(FRAME_SCRIPT_WINDOW);
       getGroupMessageManager("test").removeDelayedFrameScript(FRAME_SCRIPT_GROUP);
--- a/dom/base/test/chrome/test_bug120684.xul
+++ b/dom/base/test/chrome/test_bug120684.xul
@@ -40,27 +40,27 @@ https://bugzilla.mozilla.org/show_bug.cg
   is(list.length, 0, "Length should be 0.");
 
   list.append(document.documentElement);
   is(list.length, 1, "Length should be 1.");
   is(list[0], document.documentElement);
   is(list[1], undefined);
 
   // Removing element which isn't in the list shouldn't do anything.
-  list.remove(document.createElement("foo"));
+  list.remove(document.createXULElement("foo"));
   is(list.length, 1, "Length should be 1.");
   is(list[0], document.documentElement);
 
   list.remove(document.documentElement);
   is(list.length, 0, "Length should be 0.");
   is(list[0], undefined);
 
-  var e1 = document.createElement("foo");
-  var e2 = document.createElement("foo");
-  var e3 = document.createElement("foo");
+  var e1 = document.createXULElement("foo");
+  var e2 = document.createXULElement("foo");
+  var e3 = document.createXULElement("foo");
 
   list.append(e1);
   list.append(e2);
   list.append(e3);
 
   is(list[0], e1);
   is(list[1], e2);
   is(list[2], e3);
--- a/dom/base/test/chrome/test_bug683852.xul
+++ b/dom/base/test/chrome/test_bug683852.xul
@@ -35,17 +35,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     let box = document.getElementById("xbl-host");
     is(document.contains(box), true, "Document should contain element in it!");
     is(box.contains(box), true, "Element should contain itself.")
     let anon = document.getAnonymousElementByAttribute(box, "anonid", "xbl-anon");
     is(document.contains(anon), false, "Document should not contain anonymous element in it!");
     is(box.contains(anon), false, "Element should not contain anonymous element in it!");
     is(anon.contains(anon), true, "Anonymous element should contain itself.")
     is(document.documentElement.contains(box), true, "Element should contain element in it!");
-    is(document.contains(document.createElement("foo")), false, "Document shouldn't contain element which is't in the document");
+    is(document.contains(document.createXULElement("foo")), false, "Document shouldn't contain element which is't in the document");
     is(document.contains(document.createTextNode("foo")), false, "Document shouldn't contain text node which is't in the document");
 
     var link = document.getElementById("link");
     is(document.contains(link.firstChild), true,
        "Document should contain a text node in it.");
     is(link.contains(link.firstChild), true,
        "Element should contain a text node in it.");
     is(link.firstChild.contains(link), false, "text node shouldn't contain its parent.");
--- a/dom/base/test/test_domrequesthelper.xul
+++ b/dom/base/test/test_domrequesthelper.xul
@@ -136,17 +136,17 @@
           }
           obs.removeObserver(observer, TOPIC);
           setTimeout(function() {
             aCallback(uninitCalled);
           });
         }
       };
 
-      let frame = document.createElement("iframe");
+      let frame = document.createXULElement("iframe");
       frame.onload = function() {
         obs.addObserver(observer, TOPIC);
         // Create dummy DOMRequestHelper specific to checkWindowDestruction()
         let cwdDummy = new DummyHelperSubclass();
         cwdDummy.onuninit = function() {
           uninitCalled = true;
 
           if (!aOptions.messages || !aOptions.messages.length) {
--- a/dom/events/test/bug418986-3.js
+++ b/dom/events/test/bug418986-3.js
@@ -38,17 +38,17 @@ var test = function (isContent) {
   // suppressing absolute screen coordinates.
   nextTest = function () {
     let [eventType, prefVal] = eventDefs[testCounter];
     SpecialPowers.pushPrefEnv({set:[["privacy.resistFingerprinting", prefVal]]},
       function () {
         // The following code creates a new div for each event in eventDefs,
         // attaches a listener to listen for the event, and then generates
         // a fake event at the center of the div.
-        let div = document.createElement("div");
+        let div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
         div.style.width = "10px";
         div.style.height = "10px";
         div.style.backgroundColor = "red";
         // Name the div after the event we're listening for.
         div.id = eventType;
         document.getElementById("body").appendChild(div);
         // Seems we can't add an event listener in chrome unless we run
         // it in a later task.
--- a/dom/l10n/DOMOverlays.cpp
+++ b/dom/l10n/DOMOverlays.cpp
@@ -309,19 +309,21 @@ bool DOMOverlays::IsElementAllowed(Eleme
          nameAtom == nsGkAtoms::wbr;
 }
 
 already_AddRefed<Element> DOMOverlays::CreateSanitizedElement(
     Element* aElement, ErrorResult& aRv) {
   // Start with an empty element of the same type to remove nested children
   // and non-localizable attributes defined by the translation.
 
+  nsAutoString nameSpaceURI;
+  aElement->NodeInfo()->GetNamespaceURI(nameSpaceURI);
   ElementCreationOptionsOrString options;
-  RefPtr<Element> clone = aElement->OwnerDoc()->CreateElement(
-      aElement->NodeInfo()->LocalName(), options, aRv);
+  RefPtr<Element> clone = aElement->OwnerDoc()->CreateElementNS(
+      nameSpaceURI, aElement->NodeInfo()->LocalName(), options, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   ShallowPopulateUsing(aElement, clone, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
--- a/dom/l10n/tests/mochitest/test_domoverlays.xul
+++ b/dom/l10n/tests/mochitest/test_domoverlays.xul
@@ -15,17 +15,17 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript">
   <![CDATA[
   /* global DOMOverlays */
 
   function elem(name) {
     return function(str) {
-      const element = document.createElement(name);
+      const element = document.createXULElement(name);
       // eslint-disable-next-line no-unsanitized/property
       element.innerHTML = str;
       return element;
     };
   }
 
   const { translateElement } = DOMOverlays;
 
--- a/dom/messagechannel/tests/test_messageChannel.xul
+++ b/dom/messagechannel/tests/test_messageChannel.xul
@@ -17,17 +17,17 @@
   var channel = new MessageChannel();
   ok(channel, "MessageChannel is created");
 
   channel.port1.onmessage = function(evt) {
     ok(true, "message received!");
     SimpleTest.finish();
   }
 
-  var ifr = document.createElement('browser');
+  var ifr = document.createXULElement('browser');
   ifr.setAttribute("src", "iframe_messageChannel_chrome.html");
   ifr.setAttribute("flex", "1");
   ifr.addEventListener('load', function() {
     ifr.contentWindow.postMessage(channel.port2, '*', [channel.port2]);
   });
 
   var body = document.getElementById("body");
   body.appendChild(ifr);
--- a/dom/tests/browser/browser_bug396843.js
+++ b/dom/tests/browser/browser_bug396843.js
@@ -1,17 +1,17 @@
 /** Test for Bug 396843 **/
 
 function testInDocument(doc, documentID) {
     var allNodes = [];
     var XMLNodes = [];
 
     // HTML
     function HTML_TAG(name) {
-        allNodes.push(doc.createElement(name));
+        allNodes.push(doc.createElementNS("http://www.w3.org/1999/xhtml", name));
     }
 
     /* List copy/pasted from nsHTMLTagList.h */
     HTML_TAG("a", "Anchor");
     HTML_TAG("abbr", "Span");
     HTML_TAG("acronym", "Span");
     HTML_TAG("address", "Span");
     HTML_TAG("applet", "Unknown");
--- a/dom/tests/browser/browser_xhr_sandbox.js
+++ b/dom/tests/browser/browser_xhr_sandbox.js
@@ -19,17 +19,17 @@ var sandboxCode = (function() {
     }
   };
   req.send(null);
 }).toSource() + "();";
 
 add_task(async function test() {
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
 
-  let frame = newWin.document.createElement("iframe");
+  let frame = newWin.document.createXULElement("iframe");
   frame.setAttribute("type", "content");
   frame.setAttribute("src", "http://mochi.test:8888/browser/dom/tests/browser/browser_xhr_sandbox.js");
 
   newWin.document.documentElement.appendChild(frame);
   await BrowserTestUtils.waitForEvent(frame, "load", true);
 
   let contentWindow = frame.contentWindow;
   let sandbox = new Cu.Sandbox(contentWindow);
--- a/dom/tests/mochitest/chrome/DOMWindowCreated_chrome.xul
+++ b/dom/tests/mochitest/chrome/DOMWindowCreated_chrome.xul
@@ -20,14 +20,14 @@ document.addEventListener("DOMWindowCrea
   otherWindow.doneFunction = function() {
     SimpleTest.ok(true, "doneFunction was called");
     SimpleTest.finish();
     window.close();
   };
 }, false);
 
 var root = getRootDirectory(window.location.href);
-var el = document.createElement("iframe");
+var el = document.createXULElement("iframe");
 el.setAttribute('type', 'content');
 el.setAttribute('src', root + 'DOMWindowCreated_content.html');
 document.documentElement.appendChild(el);
 </script>
 </window>
--- a/dom/tests/mochitest/chrome/window_focus.xul
+++ b/dom/tests/mochitest/chrome/window_focus.xul
@@ -786,20 +786,20 @@ function startTest()
   getById("t9").focus();
   getById("inpopup1").focus();
   is(fm.focusedElement, getById("t9"), "focus in closed popup");
 
   // ---- tests to check if tabbing out of a textbox works
 
   setFocusTo("t1", window);
 
-  var textbox1 = document.createElement("textbox");
+  var textbox1 = document.createXULElement("textbox");
   $("innerbox").appendChild(textbox1);
 
-  var textbox2 = document.createElement("textbox");
+  var textbox2 = document.createXULElement("textbox");
   $("innerbox").appendChild(textbox2);
 
   gLastFocusMethod = 0;
   expectFocusShift(() => textbox2.focus(),
                    null, textbox2.inputField, true, "focus on textbox");
   gLastFocusMethod = fm.FLAG_BYKEY;
   expectFocusShift(() => synthesizeKey("KEY_Tab", {shiftKey: true}),
                    null, textbox1.inputField, true, "shift+tab on textbox");
--- a/dom/tests/mochitest/general/test_offsets.js
+++ b/dom/tests/mochitest/general/test_offsets.js
@@ -18,17 +18,17 @@ function testElements(baseid, callback)
     let buttonParent = element.closest("button");
     if (buttonParent && buttonParent !== element) {
       continue;
     }
 
     testElement(element);
   }
 
-  var nonappended = document.createElement("div");
+  var nonappended = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
   nonappended.id = "nonappended";
   nonappended.setAttribute("_offsetParent", "null");
   testElement(nonappended);
 
   checkScrolledElement($("scrollbox"), $("scrollchild"));
 
   var div = $("noscroll");
   div.scrollLeft = 10;
--- a/dom/tests/mochitest/webcomponents/test_custom_element_namespace.xul
+++ b/dom/tests/mochitest/webcomponents/test_custom_element_namespace.xul
@@ -66,18 +66,18 @@
       checkElement(element, XUL_NS, true, "instantiated XUL");
 
       element = document.getElementById("xul1");
       checkElement(element, XUL_NS, true, "parsed XUL as XUL");
 
       element = document.getElementById("xul2");
       checkElement(element, HTML_NS, false, "parsed XUL as HTML");
 
-      element = document.createElement("test-xul-element");
-      checkElement(element, XUL_NS, true, "document.createElement(XUL)");
+      element = document.createXULElement("test-xul-element");
+      checkElement(element, XUL_NS, true, "document.createXULElement(XUL)");
 
       element = document.createXULElement("test-xul-element");
       checkElement(element, XUL_NS, true, "document.createXULElement(XUL)");
 
       element = document.createElementNS(XUL_NS, "test-xul-element");
       checkElement(element, XUL_NS, true, "document.createElementNS(XUL, XUL)");
 
       element = document.createElementNS(HTML_NS, "test-xul-element");
@@ -96,18 +96,18 @@
       checkElement(element, HTML_NS, true, "parsed HTML as HTML");
 
       element = document.getElementById("html3");
       checkElement(element, HTML_NS, true, "parsed HTML as HTML");
 
       element = document.getElementById("html4");
       checkElement(element, HTML_NS, true, "parsed HTML as HTML");
 
-      element = document.createElement("test-html-element");
-      checkElement(element, XUL_NS, false, "document.createElement(HTML)");
+      element = document.createXULElement("test-html-element");
+      checkElement(element, XUL_NS, false, "document.createXULElement(HTML)");
 
       element = document.createXULElement("test-html-element");
       checkElement(element, XUL_NS, false, "document.createXULElement(HTML)");
 
       element = document.createElementNS(XUL_NS, "test-html-element");
       checkElement(element, XUL_NS, false, "document.createElementNS(XUL, HTML)");
 
       element = document.createElementNS(HTML_NS, "test-html-element");
--- a/dom/xbl/crashtests/406900-1.xul
+++ b/dom/xbl/crashtests/406900-1.xul
@@ -17,17 +17,17 @@
 <script type="text/javascript"> 
 
 function boom()
 {
   var x = document.getElementById("x");
   var anon = document.getAnonymousNodes(x)[0];
   document.documentElement.removeChild(x);
   document.documentElement.appendChild(x);
-  var hbox = document.createElement('hbox');
+  var hbox = document.createXULElement('hbox');
   anon.appendChild(hbox);
 }
 
 </script>
 
 <hbox id="x" style="-moz-binding: url(#lit)" />
 
 </window>
--- a/dom/xbl/test/test_bug398492.xul
+++ b/dom/xbl/test/test_bug398492.xul
@@ -45,17 +45,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       is(anonKid instanceof XULElement, true, "Must be a XUL element");
       is(anonKid, getXBLParent(kid), "Unexpected anonymous nodes");
 
       var n2 = n.cloneNode(true);
       var kid2 = n2.firstChild;
       var anonKids = document.getAnonymousNodes(n2);
       is(anonKids, null, "No XBL binding attached to cloned node");
 
-      var n3 = document.createElement("hbox");
+      var n3 = document.createXULElement("hbox");
       document.documentElement.appendChild(n3);
       var kid3 = document.createTextNode("Text");
       n3.appendChild(kid3);
 
       // Note - we rely on the fact that the binding is preloaded
       // by the other hbox here, so that the binding will be applied
       // sync.
       n3.style.MozBinding = "url(" + document.location.href + "#test)";
--- a/dom/xul/test/test_import_xul_to_content.xul
+++ b/dom/xul/test/test_import_xul_to_content.xul
@@ -50,17 +50,17 @@
     var video = doc.createElement("video");
     expectWarning(false, "appending video", function() {
       doc.documentElement.appendChild(video);
       // Force a layout flush to make sure the anonymous content is added.
       let dummy = doc.documentElement.offsetLeft;
     });
 
     // We add some XUL to a content document. This should generate a warning.
-    var elt = document.createElement("label");
+    var elt = document.createXULElement("label");
     var newElt = doc.importNode(elt, false);
     expectWarning(true, "appending XUL", function() {
       doc.documentElement.appendChild(newElt);
     });
 
     SimpleTest.finish();
   });
 
--- a/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
+++ b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
@@ -22,22 +22,22 @@ https://bugzilla.mozilla.org/show_bug.cg
   SpecialPowers.DOMWindowUtils.garbageCollect();
 
   let get_live_dom = function () {
     return document.getElementById("testelem");
   };
 
   let wrappers_as_keys_test = function () {
     let e = new MessageEvent("foo", { bubbles: false, cancellable: false,
-                                      data: { dummy: document.createElement("foo") }});
+                                      data: { dummy: document.createXULElement("foo") }});
     window.eeeevent = e;
 
     let live_dom = e.data.dummy;
-    let dead_dom = document.createElement("div");
-    let dead_child = document.createElement("div");
+    let dead_dom = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+    let dead_child = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
     dead_dom.appendChild(dead_child);
     is(dead_dom.children.length, 1, "children have wrong length");
     let wrappee = new Object();
 
     dead_dom.abcxyz = wrappee;
 
     let system = Cc["@mozilla.org/systemprincipal;1"].createInstance();
     let sandbox = Cu.Sandbox(system);
--- a/layout/base/tests/browser_bug617076.js
+++ b/layout/base/tests/browser_bug617076.js
@@ -11,17 +11,17 @@
 
 add_task(async function test() {
   // Open the test tab
   let testTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:addons");
 
   // insert button into test page content
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
     let doc = content.document;
-    let e = doc.createElement("button");
+    let e = doc.createXULElement("button");
     e.setAttribute("label", "hello");
     e.setAttribute("tooltiptext", "world");
     e.setAttribute("id", "test-button");
     doc.documentElement.insertBefore(e, doc.documentElement.firstChild);
   });
 
   // open a second tab and select it
   let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true);
--- a/layout/reftests/bugs/272646-1.xul
+++ b/layout/reftests/bugs/272646-1.xul
@@ -1,13 +1,13 @@
 <?xml version="1.0"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:nc="http://home.netscape.com/NC-rdf#"
         title="insertBefore - Weirdness"
-        onload="var atab = document.createElement('tab'); atab.setAttribute('label','new'); document.getElementById('tabs-id').insertBefore(atab,document.getElementById('tabs-id').lastChild);" >
+        onload="var atab = document.createXULElement('tab'); atab.setAttribute('label','new'); document.getElementById('tabs-id').insertBefore(atab,document.getElementById('tabs-id').lastChild);" >
 <tabbox>
  <tabs id="tabs-id">
   <tab label="foo" />
   <tab label="bar" />
  </tabs>
  <tabpanels>
   <tabpanel>
    <vbox>
--- a/layout/reftests/bugs/472020-1a.xul
+++ b/layout/reftests/bugs/472020-1a.xul
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-	onload="document.getElementById('o').appendChild(document.createElement('box'));">
+	onload="document.getElementById('o').appendChild(document.createXULElement('box'));">
 
 <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
   outer {
     -moz-binding: url(472020-xbl.xml#outer);
     border: 2px solid yellow;
   }
   inner {
     -moz-binding: url(472020-xbl.xml#inner);
--- a/layout/reftests/bugs/472020-1b.xul
+++ b/layout/reftests/bugs/472020-1b.xul
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-	onload="var p = document.getElementById('o'); p.insertBefore(document.createElement('box'), p.firstChild);">
+	onload="var p = document.getElementById('o'); p.insertBefore(document.createXULElement('box'), p.firstChild);">
 
 <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
   outer {
     -moz-binding: url(472020-xbl.xml#outer);
     border: 2px solid yellow;
   }
   inner {
     -moz-binding: url(472020-xbl.xml#inner);
--- a/layout/reftests/bugs/472020-2.xul
+++ b/layout/reftests/bugs/472020-2.xul
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-	onload="document.getElementById('o').appendChild(document.createElement('box'));">
+	onload="document.getElementById('o').appendChild(document.createXULElement('box'));">
 
 <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
   outer {
     -moz-binding: url(472020-xbl.xml#outer);
     border: 2px solid yellow;
   }
   inner {
     -moz-binding: url(472020-xbl.xml#inner);
--- a/layout/style/test/chrome/bug418986-2.js
+++ b/layout/style/test/chrome/bug418986-2.js
@@ -140,33 +140,33 @@ var testWindowsSpecific = function (resi
 // `<div class='spoof' id='resolution'>resolution</div>`,
 // where each line corresponds to a different media query.
 var generateHtmlLines = function (resisting) {
   let fragment = document.createDocumentFragment();
   expected_values.forEach(
     function ([key, offVal, onVal]) {
       let val = resisting ? onVal : offVal;
       if (val) {
-        let div = document.createElement("div");
+        let div = document.createElementNS(HTML_NS, "div");
         div.setAttribute("class", "spoof");
         div.setAttribute("id", key);
         div.textContent = key;
         fragment.appendChild(div);
       }
     });
   suppressed_toggles.forEach(
     function (key) {
-      let div = document.createElement("div");
+      let div = document.createElementNS(HTML_NS, "div");
       div.setAttribute("class", "suppress");
       div.setAttribute("id", key);
       div.textContent = key;
       fragment.appendChild(div);
     });
   if (OS === "WINNT") {
-    let div = document.createElement("div");
+    let div = document.createElementNS(HTML_NS, "div");
     div.setAttribute("class", "windows");
     div.setAttribute("id", "-moz-os-version");
     div.textContent = "-moz-os-version";
     fragment.appendChild(div);
   }
   return fragment;
 };
 
@@ -248,17 +248,17 @@ var testCSS = function (resisting) {
     ok(color === green, "CSS for '" + div.id + "'");
   }
 };
 
 // __testOSXFontSmoothing(resisting)__.
 // When fingerprinting resistance is enabled, the `getComputedStyle`
 // should always return `undefined` for `MozOSXFontSmoothing`.
 var testOSXFontSmoothing = function (resisting) {
-  let div = document.createElement("div");
+  let div = document.createElementNS(HTML_NS, "div");
   div.style.MozOsxFontSmoothing = "unset";
   document.documentElement.appendChild(div);
   let readBack = window.getComputedStyle(div).MozOsxFontSmoothing;
   div.remove();
   let smoothingPref = SpecialPowers.getBoolPref("layout.css.osx-font-smoothing.enabled", false);
   is(readBack, resisting ? "" : (smoothingPref ? "auto" : ""),
                "-moz-osx-font-smoothing");
 };
--- a/layout/xul/crashtests/538308-1.xul
+++ b/layout/xul/crashtests/538308-1.xul
@@ -12,17 +12,17 @@
                 <html:option id="victim" label="never see this"/>
             </html:optgroup>
         </treechildren>
     </tree>
 
     <script type="text/javascript"><![CDATA[
     function run() {
         group = document.getElementById("group");
-        tc = document.createElement("treechildren");
+        tc = document.createXULElement("treechildren");
         group.appendChild(tc);
 
         v = document.getElementById("victim");
         v.remove();
         v = null;
 
         tree = document.getElementById("tr");
         col = tree.columns[0];
--- a/layout/xul/grid/examples/dynamicgrid.xul
+++ b/layout/xul/grid/examples/dynamicgrid.xul
@@ -58,43 +58,43 @@
 
    function addRowColumnSelectionHandle(box)
    {
 	 box.setAttribute("onclick", "selectIt(this);");
    }
 
    function createButton(str)
    {
-	 var b = document.createElement("button");
+	 var b = document.createXULElement("button");
 	 b.setAttribute("label", str+count);
 	 count++;
 	 addCellSelectionHandle(b);
 	 return b;
    }
 
    function createRow()
    {
-	 var b = document.createElement("row");
+	 var b = document.createXULElement("row");
  	 b.setAttribute("dynamic","true");
 
 	 addRowColumnSelectionHandle(b);
 	 return b;
    }
 
    function createColumn()
    {
-	 var b = document.createElement("column");
+	 var b = document.createXULElement("column");
 	 b.setAttribute("dynamic","true");
 	 addRowColumnSelectionHandle(b);
 	 return b;
    }
 
    function createText(str)
    {
-	 var text = document.createElement("text");
+	 var text = document.createXULElement("text");
 	 text.setAttribute("value", str+count);
 	 count++;
 	 text.setAttribute("style", "font-size: 40pt");
 	 addCellSelectionHandle(text);
 	 return text;
    }
 
    function appendElement(element, prepend)
--- a/layout/xul/grid/examples/javascriptappend.xul
+++ b/layout/xul/grid/examples/javascriptappend.xul
@@ -11,17 +11,17 @@
 
 <window orient="vertical" style="border: 2px solid green"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 
 
   <script>
     function start()
 	{
 	   var row = document.getElementById("row");
-	   var text = document.createElement("text");
+	   var text = document.createXULElement("text");
 	   text.setAttribute("value", "foo");
 	   row.appendChild(text);
 	}
 
   </script>
 
   <hbox>
     <grid style="border: 2px solid red;" id="grid">
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3610,17 +3610,17 @@ function getBaseDomain(aURI) {
 Tab.prototype = {
   // eslint-disable-next-line complexity
   create: function(aURL, aParams) {
     if (this.browser)
       return;
 
     aParams = aParams || {};
 
-    this.browser = document.createElement("browser");
+    this.browser = document.createXULElement("browser");
     this.browser.setAttribute("type", "content");
     this.browser.setAttribute("messagemanagergroup", "browsers");
 
     if (Preferences.get("browser.tabs.remote.force-enable", false)) {
       this.browser.setAttribute("remote", "true");
     }
 
     this.browser.permanentKey = {};
--- a/mobile/android/chrome/geckoview/geckoview.js
+++ b/mobile/android/chrome/geckoview/geckoview.js
@@ -373,17 +373,17 @@ class ModuleInfo {
       module: this._name,
       enabled: this.enabled,
       settings: aIncludeSettings ? this._manager.settings : null,
     });
   }
 }
 
 function createBrowser() {
-  const browser = window.browser = document.createElement("browser");
+  const browser = window.browser = document.createXULElement("browser");
   // Identify this `<browser>` element uniquely to Marionette, devtools, etc.
   browser.permanentKey = {};
 
   browser.setAttribute("type", "content");
   browser.setAttribute("primary", "true");
   browser.setAttribute("flex", "1");
 
   const settings = window.arguments[0].QueryInterface(Ci.nsIAndroidView).initData.settings;
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_findelement_chrome.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_findelement_chrome.py
@@ -80,16 +80,16 @@ class TestElementsChrome(WindowManagerMi
         self.assertRaises(NoSuchElementException,
                           self.marionette.find_element, By.ID, "I'm not on the page")
 
     def test_timeout(self):
         self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "myid")
         self.marionette.timeout.implicit = 4
         self.marionette.execute_script("""
             window.setTimeout(function () {
-              var b = window.document.createElement('button');
+              var b = window.document.createXULElement('button');
               b.id = 'myid';
               document.getElementById('things').appendChild(b);
             }, 1000); """)
         self.assertEqual(HTMLElement, type(self.marionette.find_element(By.ID, "myid")))
         self.marionette.execute_script("""
             var elem = window.document.getElementById('things');
             elem.removeChild(window.document.getElementById('myid')); """)
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -146,17 +146,17 @@ class ContentPage {
     };
     chromeShell.loadURI("chrome://extensions/content/dummy.xul", loadURIOptions);
 
     await promiseObserved("chrome-document-global-created",
                           win => win.document == chromeShell.document);
 
     let chromeDoc = await promiseDocumentLoaded(chromeShell.document);
 
-    let browser = chromeDoc.createElement("browser");
+    let browser = chromeDoc.createXULElement("browser");
     browser.setAttribute("type", "content");
     browser.setAttribute("disableglobalhistory", "true");
     if (this.userContextId) {
       browser.setAttribute("usercontextid", this.userContextId);
     }
 
     if (this.extension && this.extension.remote) {
       this.remote = true;
--- a/toolkit/content/tests/chrome/test_bug437844.xul
+++ b/toolkit/content/tests/chrome/test_bug437844.xul
@@ -58,28 +58,28 @@ https://bugzilla.mozilla.org/show_bug.cg
         manifest = "content rtlchrome " + tempProfileDir.path + "\n";
       }
       manifest += "override chrome://global/locale/intl.css chrome://rtlchrome/content/rtlchrome/rtl.css\n";
       manifest += "override chrome://global/locale/global.dtd chrome://rtlchrome/content/rtlchrome/rtl.dtd\n";
 
       let cleanupFunc = createManifestTemporarily(tempProfileDir, manifest);
 
       // Load about:plugins in an iframe
-      let frame = document.createElement("iframe");
+      let frame = document.createXULElement("iframe");
       frame.setAttribute("src", "about:plugins");
       frame.addEventListener("load", function () {
           frame.removeEventListener("load", arguments.callee, false);
           is(frame.contentDocument.dir, "rtl", "about:plugins should be RTL in RTL locales");
 
           let gDirSvc    = Cc["@mozilla.org/file/directory_service;1"].
                                       getService(Ci.nsIDirectoryService).
                                       QueryInterface(Ci.nsIProperties);
           let tmpd = gDirSvc.get("ProfD", Ci.nsIFile);
 
-          frame = document.createElement("iframe");
+          frame = document.createXULElement("iframe");
           frame.setAttribute("src", "file://" + tmpd.path); // a file:// URI, bug 348233
           frame.addEventListener("load", function () {
               frame.removeEventListener("load", arguments.callee, false);
 
               is(frame.contentDocument.body.dir, "rtl", "file:// listings should be RTL in RTL locales");
 
               cleanupFunc();
               prefs.clearUserPref("intl.uidirection");
--- a/toolkit/content/tests/chrome/test_custom_element_base.xul
+++ b/toolkit/content/tests/chrome/test_custom_element_base.xul
@@ -59,17 +59,17 @@
     testBaseControl();
     testBaseControlMixin();
     testBaseText();
     testParseXULToFragment();
     testInheritAttributes();
     await testCustomInterface();
 
     let htmlWin = await new Promise(resolve => {
-      let htmlIframe = document.createElement("iframe");
+      let htmlIframe = document.createXULElement("iframe");
       htmlIframe.src = "file_empty.xhtml";
       htmlIframe.onload = () => resolve(htmlIframe.contentWindow);
       document.documentElement.appendChild(htmlIframe);
     });
 
     ok(htmlWin.MozXULElement, "MozXULElement defined on a chrome HTML window");
     SimpleTest.finish();
   }
--- a/toolkit/content/tests/chrome/window_largemenu.xul
+++ b/toolkit/content/tests/chrome/window_largemenu.xul
@@ -68,17 +68,17 @@ function nextTest()
   else
     y /= 2;
 
   var popup = document.getElementById("popup");
   if (gTestIndex == 2) {
     // add some more menuitems so that scrolling will be necessary
     var moreItemCount = Math.round(screen.height / popup.firstChild.getBoundingClientRect().height);
     for (var t = 1; t <= moreItemCount; t++) {
-      var menu = document.createElement("menuitem");
+      var menu = document.createXULElement("menuitem");
       menu.setAttribute("label", "More" + t);
       popup.appendChild(menu);
     }
   }
   else if (gTestIndex == 4) {
     // remove the items added in test 2 above
     while (popup.childNodes.length > 15)
       popup.removeChild(popup.lastChild);
@@ -294,17 +294,17 @@ function contextMenuPopupHidden()
 
 function nextContextMenuTest(desiredHeight)
 {
   if (desiredHeight >= 0) {
     var popup = document.getElementById("popup");
     var height = popup.getBoundingClientRect().height;
     var itemheight = document.getElementById("firstitem").getBoundingClientRect().height;
     while (height < desiredHeight) {
-      var menu = document.createElement("menuitem");
+      var menu = document.createXULElement("menuitem");
       menu.setAttribute("label", "Item");
       popup.appendChild(menu);
       height += itemheight;
     }
   }
 
   synthesizeMouse(document.getElementById("label"), 4, 4, { type: "contextmenu", button: 2 });
 }
--- a/toolkit/content/tests/chrome/window_panel.xul
+++ b/toolkit/content/tests/chrome/window_panel.xul
@@ -86,22 +86,22 @@ function popupShown(event)
   }
 
   currentTest.result(currentTest.testname + " ", panel);
   panel.hidePopup();
 }
 
 function createPanel(attrs)
 {
-  var panel = document.createElement("panel");
+  var panel = document.createXULElement("panel");
   for (var a in attrs) {
     panel.setAttribute(a, attrs[a]);
   }
 
-  var button = document.createElement("button");
+  var button = document.createXULElement("button");
   panel.appendChild(button);
   button.label = "OK";
   button.width = 120;
   button.height = 40;
   button.setAttribute("style", "-moz-appearance: none; border: 0; margin: 0;");
   panel.setAttribute("style", "-moz-appearance: none; border: 0; margin: 0;");
   return document.documentElement.appendChild(panel);
 }
--- a/toolkit/content/tests/chrome/xul_selectcontrol.js
+++ b/toolkit/content/tests/chrome/xul_selectcontrol.js
@@ -79,17 +79,17 @@ function test_nsIDOMXULSelectControlElem
   test_nsIDOMXULSelectControlElement_States(element, testid + "selectedItem 2", 2,
         selectionRequired ? seconditem : null, selectionRequired ? 1 : -1,
         selectionRequired ? "second" : "");
 
   // 'getIndexOfItem' - check if getIndexOfItem returns the right index
   is(element.getIndexOfItem(firstitem), 0, testid + "getIndexOfItem - first item at index 0");
   is(element.getIndexOfItem(seconditem), 1, testid + "getIndexOfItem - second item at index 1");
 
-  var otheritem = element.ownerDocument.createElement(childtag);
+  var otheritem = element.ownerDocument.createXULElement(childtag);
   is(element.getIndexOfItem(otheritem), -1, testid + "getIndexOfItem - other item not found");
 
   // 'getItemAtIndex' - check if getItemAtIndex returns the right item
   is(element.getItemAtIndex(0), firstitem, testid + "getItemAtIndex - index 0 is first item");
   is(element.getItemAtIndex(1), seconditem, testid + "getItemAtIndex - index 0 is second item");
   is(element.getItemAtIndex(-1), null, testid + "getItemAtIndex - index -1 is null");
   is(element.getItemAtIndex(2), null, testid + "getItemAtIndex - index 2 is null");
 
--- a/toolkit/content/widgets/tree.js
+++ b/toolkit/content/widgets/tree.js
@@ -221,17 +221,17 @@
       var refChild = aPopup.firstChild;
 
       var tree = this.parentNode.parentNode;
       for (var currCol = tree.columns.getFirstColumn(); currCol; currCol = currCol.getNext()) {
         // Construct an entry for each column in the row, unless
         // it is not being shown.
         var currElement = currCol.element;
         if (!currElement.hasAttribute("ignoreincolumnpicker")) {
-          var popupChild = document.createElement("menuitem");
+          var popupChild = document.createXULElement("menuitem");
           popupChild.setAttribute("type", "checkbox");
           var columnName = currElement.getAttribute("display") ||
             currElement.getAttribute("label");
           popupChild.setAttribute("label", columnName);
           popupChild.setAttribute("colindex", currCol.index);
           if (currElement.getAttribute("hidden") != "true")
             popupChild.setAttribute("checked", "true");
           if (currCol.primary)
--- a/toolkit/modules/CharsetMenu.jsm
+++ b/toolkit/modules/CharsetMenu.jsm
@@ -118,17 +118,17 @@ var gDetectorInfoCache, gCharsetInfoCach
 
 var CharsetMenu = {
   build(parent, deprecatedShowAccessKeys = true, showDetector = true) {
     if (!deprecatedShowAccessKeys) {
       Deprecated.warning("CharsetMenu no longer supports building a menu with no access keys.",
                          "https://bugzilla.mozilla.org/show_bug.cgi?id=1088710");
     }
     function createDOMNode(doc, nodeInfo) {
-      let node = doc.createElement("menuitem");
+      let node = doc.createXULElement("menuitem");
       node.setAttribute("type", "radio");
       node.setAttribute("name", nodeInfo.name + "Group");
       node.setAttribute(nodeInfo.name, nodeInfo.value);
       node.setAttribute("label", nodeInfo.label);
       if (nodeInfo.accesskey) {
         node.setAttribute("accesskey", nodeInfo.accesskey);
       }
       return node;
@@ -137,32 +137,32 @@ var CharsetMenu = {
     if (parent.hasChildNodes()) {
       // Detector menu or charset menu already built
       return;
     }
     this._ensureDataReady();
     let doc = parent.ownerDocument;
 
     if (showDetector) {
-      let menuNode = doc.createElement("menu");
+      let menuNode = doc.createXULElement("menu");
       menuNode.setAttribute("label", gBundle.GetStringFromName("charsetMenuAutodet"));
       menuNode.setAttribute("accesskey", gBundle.GetStringFromName("charsetMenuAutodet.key"));
       parent.appendChild(menuNode);
 
-      let menuPopupNode = doc.createElement("menupopup");
+      let menuPopupNode = doc.createXULElement("menupopup");
       menuNode.appendChild(menuPopupNode);
       menuPopupNode.addEventListener("command", SetDetector);
       menuPopupNode.addEventListener("popupshown", UpdateDetectorMenu);
 
       gDetectorInfoCache.forEach(detectorInfo => menuPopupNode.appendChild(createDOMNode(doc, detectorInfo)));
-      parent.appendChild(doc.createElement("menuseparator"));
+      parent.appendChild(doc.createXULElement("menuseparator"));
     }
 
     gPinnedInfoCache.forEach(charsetInfo => parent.appendChild(createDOMNode(doc, charsetInfo)));
-    parent.appendChild(doc.createElement("menuseparator"));
+    parent.appendChild(doc.createXULElement("menuseparator"));
     gCharsetInfoCache.forEach(charsetInfo => parent.appendChild(createDOMNode(doc, charsetInfo)));
   },
 
   getData() {
     this._ensureDataReady();
     return {
       detectors: gDetectorInfoCache,
       pinnedCharsets: gPinnedInfoCache,
--- a/toolkit/mozapps/extensions/test/browser/browser_html_message_bar.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_html_message_bar.js
@@ -1,23 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* eslint max-len: ["error", 80] */
 
 let htmlAboutAddonsWindow;
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
 function clickElement(el) {
   el.dispatchEvent(new CustomEvent("click"));
 }
 
 function createMessageBar(messageBarStack, {attrs, children, onclose} = {}) {
   const win = messageBarStack.ownerGlobal;
-  const messageBar = win.document.createElement("message-bar");
+  const messageBar = win.document.createElementNS(HTML_NS, "message-bar");
   if (attrs) {
     for (const [k, v] of Object.entries(attrs)) {
       messageBar.setAttribute(k, v);
     }
   }
   if (children) {
     if (Array.isArray(children)) {
       messageBar.append(...children);
@@ -56,19 +58,19 @@ add_task(async function test_message_bar
   is(messageBarStack.childElementCount, 0,
      "message-bar-stack is initially empty");
 });
 
 add_task(async function test_create_message_bar_create_and_onclose() {
   const win = htmlAboutAddonsWindow;
   const messageBarStack = win.document.querySelector("message-bar-stack");
 
-  let messageEl = win.document.createElement("span");
+  let messageEl = win.document.createElementNS(HTML_NS, "span");
   messageEl.textContent = "A message bar text";
-  let buttonEl = win.document.createElement("button");
+  let buttonEl = win.document.createElementNS(HTML_NS, "button");
   buttonEl.textContent = "An action button";
 
   let messageBar;
   let onceMessageBarClosed = new Promise(resolve => {
     messageBar = createMessageBar(messageBarStack, {
       children: [messageEl, buttonEl],
       onclose: resolve,
     });
@@ -95,17 +97,17 @@ add_task(async function test_create_mess
      "message-bar-stack has no child elements");
 });
 
 add_task(async function test_max_message_bar_count() {
   const win = htmlAboutAddonsWindow;
   const messageBarStack = win.document.querySelector("message-bar-stack");
 
   info("Create a new message-bar");
-  let messageElement = document.createElement("span");
+  let messageElement = document.createElementNS(HTML_NS, "span");
   messageElement = "message bar label";
 
   let onceMessageBarClosed = new Promise(resolve => {
     createMessageBar(messageBarStack, {
       children: messageElement,
       onclose: resolve,
     });
   });
--- a/toolkit/mozapps/handling/content/dialog.js
+++ b/toolkit/mozapps/handling/content/dialog.js
@@ -152,17 +152,17 @@ var dialog = {
   * Populates the list that a user can choose from.
   */
   populateList: function populateList() {
     var items = document.getElementById("items");
     var possibleHandlers = this._handlerInfo.possibleApplicationHandlers;
     var preferredHandler = this._handlerInfo.preferredApplicationHandler;
     for (let i = possibleHandlers.length - 1; i >= 0; --i) {
       let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp);
-      let elm = document.createElement("richlistitem", {is: "mozapps-handler"});
+      let elm = document.createXULElement("richlistitem", {is: "mozapps-handler"});
       elm.setAttribute("name", app.name);
       elm.obj = app;
 
       if (app instanceof Ci.nsILocalHandlerApp) {
         // See if we have an nsILocalHandlerApp and set the icon
         let uri = Services.io.newFileURI(app.executable);
         elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
       } else if (app instanceof Ci.nsIWebHandlerApp) {
@@ -200,17 +200,17 @@ var dialog = {
       }
 
       items.insertBefore(elm, this._itemChoose);
       if (preferredHandler && app == preferredHandler)
         this.selectedItem = elm;
     }
 
     if (this._handlerInfo.hasDefaultHandler) {
-      let elm = document.createElement("richlistitem", {is: "mozapps-handler"});
+      let elm = document.createXULElement("richlistitem", {is: "mozapps-handler"});
       elm.id = "os-default-handler";
       elm.setAttribute("name", this._handlerInfo.defaultDescription);
 
       items.insertBefore(elm, items.firstChild);
       if (this._handlerInfo.preferredAction ==
           Ci.nsIHandlerInfo.useSystemDefault)
           this.selectedItem = elm;
     }
@@ -231,17 +231,17 @@ var dialog = {
           let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp);
           // nsGIOMimeApp::Equals is able to compare with nsILocalHandlerApp
           if (handler.equals(app)) {
             appAlreadyInHandlers = true;
             break;
           }
         }
         if (!appAlreadyInHandlers) {
-          let elm = document.createElement("richlistitem", {is: "mozapps-handler"});
+          let elm = document.createXULElement("richlistitem", {is: "mozapps-handler"});
           elm.setAttribute("name", handler.name);
           elm.obj = handler;
           items.insertBefore(elm, this._itemChoose);
         }
       }
     }
 
     items.ensureSelectedElementIsVisible();
@@ -272,17 +272,17 @@ var dialog = {
           let elm = parent.childNodes[i];
           if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) {
             parent.selectedItem = elm;
             parent.ensureSelectedElementIsVisible();
             return;
           }
         }
 
-        let elm = document.createElement("richlistitem", {is: "mozapps-handler"});
+        let elm = document.createXULElement("richlistitem", {is: "mozapps-handler"});
         elm.setAttribute("name", fp.file.leafName);
         elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
         elm.obj = handlerApp;
 
         parent.selectedItem = parent.insertBefore(elm, parent.firstChild);
         parent.ensureSelectedElementIsVisible();
       }
     });