Bug 839279 - Code cleanup in /editor/: Use new String methods like startsWith, endsWith, contains and use querySelector instead of NodeList calls. r=IanN, r=mconley
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sun, 10 Mar 2013 11:32:06 +0100
changeset 12476 72aff817d8abd1892c342c7051368c9873515048
parent 12475 62360fc75a3cbd1012f4e56e1c222431cb59b5d2
child 12477 8fc54bbfaa0b1c4da0a5cacdd25dd8d439209e76
push id9193
push userryanvm@gmail.com
push dateMon, 20 May 2013 12:00:17 +0000
treeherdercomm-central@0b43c4940181 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN, mconley
bugs839279
Bug 839279 - Code cleanup in /editor/: Use new String methods like startsWith, endsWith, contains and use querySelector instead of NodeList calls. r=IanN, r=mconley
editor/ui/composer/content/ComposerCommands.js
editor/ui/composer/content/editingOverlay.js
editor/ui/composer/content/editor.js
editor/ui/composer/content/editorUtilities.js
editor/ui/composer/content/publishprefs.js
editor/ui/dialogs/content/EdAECSSAttributes.js
editor/ui/dialogs/content/EdAEHTMLAttributes.js
editor/ui/dialogs/content/EdAEJSEAttributes.js
editor/ui/dialogs/content/EdConvertToTable.js
editor/ui/dialogs/content/EdDialogCommon.js
editor/ui/dialogs/content/EdFieldSetProps.js
editor/ui/dialogs/content/EdFormProps.js
editor/ui/dialogs/content/EdHLineProps.js
editor/ui/dialogs/content/EdImageOverlay.js
editor/ui/dialogs/content/EdInsertTOC.js
editor/ui/dialogs/content/EdLabelProps.js
editor/ui/dialogs/content/EdLinkChecker.js
editor/ui/dialogs/content/EdPageProps.js
editor/ui/dialogs/content/EdReplace.js
editor/ui/dialogs/content/EditorPublishProgress.js
editor/ui/dialogs/content/EditorSaveAsCharset.js
--- a/editor/ui/composer/content/ComposerCommands.js
+++ b/editor/ui/composer/content/ComposerCommands.js
@@ -322,22 +322,17 @@ function pokeStyleUI(uiID, aDesiredState
  try {
   var commandNode = top.document.getElementById(uiID);
   if (!commandNode)
     return;
 
   var uiState = ("true" == commandNode.getAttribute("state"));
   if (aDesiredState != uiState)
   {
-    var newState;
-    if (aDesiredState)
-      newState = "true";
-    else
-      newState = "false";
-    commandNode.setAttribute("state", newState);
+    commandNode.setAttribute("state", aDesiredState ? "true" : "false");
   }
  } catch(e) { dump("poking UI for "+uiID+" failed: "+e+"\n"); }
 }
 
 function doStyleUICommand(cmdStr)
 {
   try
   {
@@ -1081,17 +1076,17 @@ var gEditorOutputProgressListener =
       // We abort publishing for all errors except if image src file is not found
       var abortPublishing = (aStatus != 0 && aStatus != kFileNotFound);
 
       // Notify progress dialog when we receive the STOP
       //  notification for a file if there was an error
       //  or a successful finish
       //  (Check requestSpec to be sure message is for destination url)
       if (aStatus != 0
-           || (requestSpec && requestSpec.indexOf(GetScheme(gPublishData.publishUrl)) == 0))
+           || (requestSpec && requestSpec.startsWith(GetScheme(gPublishData.publishUrl))))
       {
         try {
           gProgressDialog.SetProgressFinished(GetFilename(requestSpec), aStatus);
         } catch(e) {}
       }
 
 
       if (abortPublishing)
@@ -1294,21 +1289,21 @@ var gEditorOutputProgressListener =
     || aIID.equals(Components.interfaces.nsIAuthPrompt))
       return this;
     throw Components.results.NS_NOINTERFACE;
   },
 
 // nsIPrompt
   alert : function(dlgTitle, text)
   {
-    AlertWithTitle(dlgTitle, text, gProgressDialog ? gProgressDialog : window);
+    Services.prompt.alert(gProgressDialog ? gProgressDialog : window, dlgTitle, text);
   },
   alertCheck : function(dialogTitle, text, checkBoxLabel, checkObj)
   {
-    AlertWithTitle(dialogTitle, text);
+    Services.prompt.alert(window, dialogTitle, text);
   },
   confirm : function(dlgTitle, text)
   {
     return ConfirmWithTitle(dlgTitle, text, null, null);
   },
   confirmCheck : function(dlgTitle, text, checkBoxLabel, checkObj)
   {
     Services.prompt.confirmEx(window, dlgTitle, text, nsIPromptService.STD_OK_CANCEL_BUTTONS,
@@ -1578,18 +1573,17 @@ function SaveDocument(aSaveAs, aSaveCopy
     throw Components.results.NS_ERROR_NOT_INITIALIZED;
 
   var editorDoc = editor.document;
   if (!editorDoc)
     throw Components.results.NS_ERROR_NOT_INITIALIZED;
 
   // if we don't have the right editor type bail (we handle text and html)
   var editorType = GetCurrentEditorType();
-  if (editorType != "text" && editorType != "html"
-      && editorType != "htmlmail" && editorType != "textmail")
+  if (["text", "html", "htmlmail", "textmail"].indexOf(editorType) == -1)
     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
 
   var saveAsTextFile = IsSupportedTextMimeType(aMimeType);
 
   // check if the file is to be saved is a format we don't understand; if so, bail
   if (aMimeType != kHTMLMimeType && aMimeType != kXHTMLMimeType && !saveAsTextFile)
     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
 
@@ -1686,21 +1680,17 @@ function SaveDocument(aSaveAs, aSaveCopy
           {
             var relatedFilesDirString = urlstring.slice(0, lastSlash + 1);  // include last slash
             relatedFilesDir = Services.io.newURI(relatedFilesDirString, editor.documentCharacterSet, null);
           }
         }
       } catch(e) { relatedFilesDir = null; }
     }
 
-    var destinationLocation;
-    if (tempLocalFile)
-      destinationLocation = tempLocalFile;
-    else
-      destinationLocation = docURI;
+    let destinationLocation = tempLocalFile ? tempLocalFile : docURI;
 
     success = OutputFileWithPersistAPI(editorDoc, destinationLocation, relatedFilesDir, aMimeType);
   }
   catch (e)
   {
     success = false;
   }
 
@@ -1727,19 +1717,17 @@ function SaveDocument(aSaveAs, aSaveCopy
       // this should cause notification to listeners that document has changed
 
       // Set UI based on whether we're editing a remote or local url
       SetSaveAndPublishUI(urlstring);
     } catch (e) {}
   }
   else
   {
-    var saveDocStr = GetString("SaveDocument");
-    var failedStr = GetString("SaveFileFailed");
-    AlertWithTitle(saveDocStr, failedStr);
+    Services.prompt.alert(window, GetString("SaveDocument"), GetString("SaveFileFailed"));
   }
   return success;
 }
 
 function SetDocumentURI(uri)
 {
   try {
     // XXX WE'LL NEED TO GET "CURRENT" CONTENT FRAME ONCE MULTIPLE EDITORS ARE ALLOWED
@@ -1762,17 +1750,17 @@ function Publish(publishData)
   // Set data in global for username password requests
   //  and to do "post saving" actions after monitoring nsIWebProgressListener messages
   //  and we are sure file transfer was successful
   gPublishData = publishData;
 
   gPublishData.docURI = CreateURIFromPublishData(publishData, true);
   if (!gPublishData.docURI)
   {
-    AlertWithTitle(GetString("Publish"), GetString("PublishFailed"));
+    Services.prompt.alert(window, GetString("Publish"), GetString("PublishFailed"));
     return false;
   }
 
   if (gPublishData.publishOtherFiles)
     gPublishData.otherFilesURI = CreateURIFromPublishData(publishData, false);
   else
     gPublishData.otherFilesURI = null;
 
--- a/editor/ui/composer/content/editingOverlay.js
+++ b/editor/ui/composer/content/editingOverlay.js
@@ -29,17 +29,17 @@ function EditorOnLoad()
     {
       // Opened via window.openDialog with URL as argument.
       url = window.arguments[0];
     }
 
     // get default character set if provided
     if (window.arguments.length > 1 && window.arguments[1])
     {
-      if (window.arguments[1].indexOf("charset=") != -1)
+      if (window.arguments[1].contains("charset="))
       {
         var arrayArgComponents = window.arguments[1].split("=");
         if (arrayArgComponents)
           charset = arrayArgComponents[1];
       }
     }
   }
 
--- a/editor/ui/composer/content/editor.js
+++ b/editor/ui/composer/content/editor.js
@@ -148,17 +148,17 @@ nsPrefListener.prototype =
           cmd.setAttribute("state", "transparent");
           cmd.collapsed = true;
         }
 
         if (editor)
           editor.isCSSEnabled = useCSS;
       }
     }
-    else if (prefName.substr(0, kEditorToolbarPrefs.length) == kEditorToolbarPrefs)
+    else if (prefName.startsWith(kEditorToolbarPrefs))
     {
       let id = prefName.substr(kEditorToolbarPrefs.length) + "Button";
       let button = document.getElementById(id);
       if (button) {
         button.hidden = !Services.prefs.getBoolPref(prefName);
         ShowHideToolbarSeparators(button.parentNode);
       }
     }
@@ -256,17 +256,17 @@ var gEditorDocumentObserver =
               break;
             case nsIEditingSession.eEditorErrorUnknown:
               errorStringId = "CantEditDocumentMsg";
               break;
             // Note that for "eEditorErrorFileNotFound, 
             // network code popped up an alert dialog, so we don't need to
           }
           if (errorStringId)
-            AlertWithTitle("", GetString(errorStringId));
+            Services.prompt.alert(window, "", GetString(errorStringId));
         } catch(e) { dump("EXCEPTION GETTING obs_documentCreated state "+e+"\n"); }
 
         // We have a bad editor -- nsIEditingSession will rebuild an editor
         //   with a blank page, so simply abort here
         if (editorStatus)
           return; 
 
         if (!("InsertCharWindow" in window))
@@ -340,27 +340,19 @@ var gEditorDocumentObserver =
             HideItem("viewNormalMode");
             HideItem("viewAllTagsMode");
             HideItem("viewSourceMode");
             HideItem("viewPreviewMode");
 
             HideItem("structSpacer");
 
             // Hide everything in "Insert" except for "Symbols"
-            var menuPopup = document.getElementById("insertMenuPopup");
-            if (menuPopup)
-            {
-              var children = menuPopup.childNodes;
-              for (var i=0; i < children.length; i++) 
-              {
-                var item = children.item(i);
-                if (item.id != "insertChars")
-                  item.hidden = true;
-              }
-            }
+            let menuPopupChildren = document.querySelectorAll('[id="insertMenuPopup"] > :not(#insertChars)');
+            for (let i = 0; i < menuPopupChildren.length; i++)
+              menuPopupChildren.item(i).hidden = true;
           }
     
           // Set window title
           UpdateWindowTitle();
 
           // We must wait until document is created to get proper Url
           // (Windows may load with local file paths)
           SetSaveAndPublishUI(GetDocumentUrl());
@@ -1551,17 +1543,17 @@ function SetEditMode(mode)
       {
         if (dt)
         {
           doctypeNode.collapsed = false;
           var doctypeText = "<!DOCTYPE " + domdoc.doctype.name;
           if (dt.publicId)
             doctypeText += " PUBLIC \"" + domdoc.doctype.publicId;
           if (dt.systemId)
-            doctypeText += " "+"\"" + dt.systemId;
+            doctypeText += " \"" + dt.systemId;
           doctypeText += "\">"
           doctypeNode.setAttribute("value", doctypeText);
         }
         else
           doctypeNode.collapsed = true;
       }
     }
     // Get the entire document's source string
@@ -1622,25 +1614,18 @@ function SetEditMode(mode)
           editor.enableUndo(false);
           editor.document.documentElement.removeChild(GetBodyElement());
           editor.document.replaceChild(fragment.firstChild, editor.document.documentElement);
           editor.enableUndo(true);
         }
 
         // Get the text for the <title> from the newly-parsed document
         // (must do this for proper conversion of "escaped" characters)
-        var title = "";
-        var titlenodelist = editor.document.getElementsByTagName("title");
-        if (titlenodelist)
-        {
-          var titleNode = titlenodelist.item(0);
-          if (titleNode && titleNode.firstChild && titleNode.firstChild.data)
-            title = titleNode.firstChild.data;
-        }
-        SetDocumentTitle(title);
+        let titleNode = editor.document.querySelector("title");
+        SetDocumentTitle(titleNode ? titleNode.textContent : "");
 
       } catch (ex) {
         dump(ex);
       }
       editor.endTransaction();
 
       // Restore unlimited undo count
       try {
@@ -2105,101 +2090,74 @@ function EditorSetDefaultPrefsAndDoctype
   if (!domdoc.doctype)
   {
     var newdoctype = domdoc.implementation.createDocumentType("HTML", "-//W3C//DTD HTML 4.01 Transitional//EN","");
     if (newdoctype)
       domdoc.insertBefore(newdoctype, domdoc.firstChild);
   }
   
   // search for head; we'll need this for meta tag additions
-  var headelement = 0;
-  var headnodelist = domdoc.getElementsByTagName("head");
-  if (headnodelist)
-  {
-    var sz = headnodelist.length;
-    if ( sz >= 1 )
-      headelement = headnodelist.item(0);
-  }
-  else
+  let headelement = domdoc.querySelector("head");
+  if (!headelement)
   {
     headelement = domdoc.createElement("head");
     if (headelement)
       domdoc.insertAfter(headelement, domdoc.firstChild);
   }
 
   /* only set default prefs for new documents */
   if (!IsUrlAboutBlank(GetDocumentUrl()))
     return;
 
   // search for author meta tag.
   // if one is found, don't do anything.
   // if not, create one and make it a child of the head tag
   //   and set its content attribute to the value of the editor.author preference.
 
-  var nodelist = domdoc.getElementsByTagName("meta");
-  if ( nodelist )
+  if (domdoc.querySelector("meta"))
   {
     // we should do charset first since we need to have charset before
     // hitting other 8-bit char in other meta tags
     // grab charset pref and make it the default charset
     var element;
     var prefCharsetString = 0;
     try
     {
       prefCharsetString = Services.prefs.getComplexValue("intl.charset.default",
                                                          Components.interfaces.nsIPrefLocalizedString).data;
     }
     catch (ex) {}
     if ( prefCharsetString && prefCharsetString != 0)
       editor.documentCharacterSet = prefCharsetString;
 
-    var node = 0;
-    var listlength = nodelist.length;
-
     // let's start by assuming we have an author in case we don't have the pref
-    var authorFound = false;
-    for (var i = 0; i < listlength && !authorFound; i++)
-    {
-      node = nodelist.item(i);
-      if ( node )
-      {
-        var value = node.getAttribute("name");
-        if (value && value.toLowerCase() == "author")
-        {
-          authorFound = true;
-        }
-      }
-    }
-
-    var prefAuthorString = 0;
+
+    var prefAuthorString = null;
+    let authorFound = domdoc.querySelector('meta[name="author"]');
     try
     {
       prefAuthorString = Services.prefs.getComplexValue("editor.author",
                                                         Components.interfaces.nsISupportsString).data;
     }
     catch (ex) {}
-    if ( prefAuthorString && prefAuthorString != 0)
+    if (prefAuthorString && prefAuthorString != 0 && !authorFound && headelement)
     {
-      if ( !authorFound && headelement)
+      // create meta tag with 2 attributes
+      element = domdoc.createElement("meta");
+      if (element)
       {
-        /* create meta tag with 2 attributes */
-        element = domdoc.createElement("meta");
-        if ( element )
-        {
-          element.setAttribute("name", "author");
-          element.setAttribute("content", prefAuthorString);
-          headelement.appendChild( element );
-        }
+        element.setAttribute("name", "author");
+        element.setAttribute("content", prefAuthorString);
+        headelement.appendChild(element);
       }
     }
   }
 
   // add title tag if not present
-  var titlenodelist = editor.document.getElementsByTagName("title");
-  if (headelement && titlenodelist && titlenodelist.length == 0)
+  if (headelement && !editor.document.querySelector("title"))
   {
      var titleElement = domdoc.createElement("title");
      if (titleElement)
        headelement.appendChild(titleElement);
   }
 
   // find body node
   var bodyelement = GetBodyElement();
@@ -3068,31 +3026,15 @@ function InitTOCMenu()
 function RemoveTOC()
 {
   var theDocument = GetCurrentEditor().document;
   var elt = theDocument.getElementById("mozToc");
   if (elt) {
     elt.parentNode.removeChild(elt);
   }
 
-  function acceptNode(node)
-  {
-    if (node.nodeName.toLowerCase() == "a" &&
-        node.hasAttribute("name") &&
-        node.getAttribute("name").substr(0, 8) == "mozTocId") {
-      return NodeFilter.FILTER_ACCEPT;
-    }
-    return NodeFilter.FILTER_SKIP;
-  }
-
-  var treeWalker = theDocument.createTreeWalker(theDocument.documentElement,
-                                                NodeFilter.SHOW_ELEMENT,
-                                                acceptNode,
-                                                true);
-  if (treeWalker) {
-    var anchorNode = treeWalker.nextNode();
-    while (anchorNode) {
-      var tmp = treeWalker.nextNode();
-      anchorNode.parentNode.removeChild(anchorNode);
-      anchorNode = tmp;
+  let anchorNodes = theDocument.querySelectorAll('a[name^="mozTocId"]');
+  for (let node of anchorNodes) {
+    if (node.parentNode) {
+      node.parentNode.removeChild(node);
     }
   }
 }
--- a/editor/ui/composer/content/editorUtilities.js
+++ b/editor/ui/composer/content/editorUtilities.js
@@ -31,22 +31,16 @@ const gUNIX = "UNIX";
 const gMac = "Mac";
 
 const kWebComposerWindowID = "editorWindow";
 const kMailComposerWindowID = "msgcomposeWindow";
 
 var gIsHTMLEditor;
 /************* Message dialogs ***************/
 
-function AlertWithTitle(title, message, parentWindow)
-{
-  // "window" is the calling dialog window
-  Services.prompt.alert(parentWindow || window, title || GetString("Alert"), message);
-}
-
 // Optional: Caller may supply text to substitue for "Ok" and/or "Cancel"
 function ConfirmWithTitle(title, message, okButtonText, cancelButtonText)
 {
   let okFlag = okButtonText ? Services.prompt.BUTTON_TITLE_IS_STRING : Services.prompt.BUTTON_TITLE_OK;
   let cancelFlag = cancelButtonText ? Services.prompt.BUTTON_TITLE_IS_STRING : Services.prompt.BUTTON_TITLE_CANCEL;
 
   return Services.prompt.confirmEx(window, title, message,
                                    (okFlag * Services.prompt.BUTTON_POS_0) +
@@ -107,21 +101,16 @@ function TrimStringRight(string)
 // Remove whitespace from both ends of a string
 function TrimString(string)
 {
   if (!string)
     return "";
   return string.trim();
 }
 
-function IsWhitespace(string)
-{
-  return /^\s/.test(string);
-}
-
 function TruncateStringAtWordEnd(string, maxLength, addEllipses)
 {
   // Return empty if string is null, undefined, or the empty string
   if (!string)
     return "";
 
   // We assume they probably don't want whitespace at the beginning
   string = string.trimLeft();
@@ -202,21 +191,21 @@ function GetCurrentTableEditor()
 }
 
 function GetCurrentEditorElement()
 {
   var tmpWindow = window;
 
   do {
     // Get the <editor> element(s)
-    var editorList = tmpWindow.document.getElementsByTagName("editor");
+    let editorItem = tmpWindow.document.querySelector("editor");
 
     // This will change if we support > 1 editor element
-    if (editorList.item(0))
-      return editorList.item(0);
+    if (editorItem)
+      return editorItem;
 
     tmpWindow = tmpWindow.opener;
   }
   while (tmpWindow);
 
   return null;
 }
 
@@ -524,17 +513,17 @@ function TextIsURI(selectedText)
 
 function IsUrlAboutBlank(urlString)
 {
   return (urlString == "about:blank");
 }
 
 function MakeRelativeUrl(url)
 {
-  var inputUrl = TrimString(url);
+  let inputUrl = url.trim();
   if (!inputUrl)
     return inputUrl;
 
   // Get the filespec relative to current document's location
   // NOTE: Can't do this if file isn't saved yet!
   var docUrl = GetDocumentBaseUrl();
   var docScheme = GetScheme(docUrl);
 
@@ -593,17 +582,17 @@ function MakeRelativeUrl(url)
       // Remove filename for named anchors in the same file
       if (nextDocSlash == -1 && docFilename)
       {
         var anchorIndex = urlPath.indexOf("#");
         if (anchorIndex > 0)
         {
           var urlFilename = doCaseInsensitive ? urlPath.toLowerCase() : urlPath;
 
-          if (urlFilename.indexOf(docFilename) == 0)
+          if (urlFilename.startsWith(docFilename))
             urlPath = urlPath.slice(anchorIndex);
         }
       }
     }
     else if (nextDocSlash >= 0)
     {
       // Test for matching subdir
       var docDir = docPath.slice(0, nextDocSlash);
@@ -685,23 +674,19 @@ function MakeAbsoluteUrl(url)
 // Get the HREF of the page's <base> tag or the document location
 // returns empty string if no base href and document hasn't been saved yet
 function GetDocumentBaseUrl()
 {
   try {
     var docUrl;
 
     // if document supplies a <base> tag, use that URL instead
-    var baseList = GetCurrentEditor().document.getElementsByTagName("base");
-    if (baseList)
-    {
-      var base = baseList.item(0);
-      if (base)
-        docUrl = base.getAttribute("href");
-    }
+    let base = GetCurrentEditor().document.querySelector("base");
+    if (base)
+      docUrl = base.getAttribute("href");
     if (!docUrl)
       docUrl = GetDocumentUrl();
 
     if (!IsUrlAboutBlank(docUrl))
       return docUrl;
   } catch (e) {}
   return "";
 }
@@ -885,21 +870,21 @@ function InsertUsernameIntoUrl(urlspec, 
 
 function GetOS()
 {
   if (gOS)
     return gOS;
 
   var platform = navigator.platform.toLowerCase();
 
-  if (platform.indexOf("win") != -1)
+  if (platform.contains("win"))
     gOS = gWin;
-  else if (platform.indexOf("mac") != -1)
+  else if (platform.contains("mac"))
     gOS = gMac;
-  else if (platform.indexOf("unix") != -1 || platform.indexOf("linux") != -1 || platform.indexOf("sun") != -1)
+  else if (platform.contains("unix") || platform.contains("linux") || platform.contains("sun"))
     gOS = gUNIX;
   else
     gOS = "";
   // Add other tests?
 
   return gOS;
 }
 
--- a/editor/ui/composer/content/publishprefs.js
+++ b/editor/ui/composer/content/publishprefs.js
@@ -690,20 +690,18 @@ function FillInMatchingPublishData(publi
   //  are stored separately in publishData, never embedded in the publishUrl
   // If both docUrl and publishData contain usernames,
   //   we must match that as well as the url
   var username = {value:""};
   baseUrl = StripUsernamePassword(baseUrl, username); 
   username = username.value;
 
   var matchedLength = 0;
-  var pubUrlFound = publishData.publishUrl ?
-                      baseUrl.indexOf(publishData.publishUrl) == 0 : false;
-  var browseUrlFound = publishData.browseUrl ?
-                          baseUrl.indexOf(publishData.browseUrl) == 0 : false;
+  let pubUrlFound = publishData.publishUrl && baseUrl.startsWith(publishData.publishUrl);
+  let browseUrlFound = publishData.browseUrl && baseUrl.startsWith(publishData.browseUrl);
 
   if ((pubUrlFound || browseUrlFound) 
       && (!username || !publishData.username || username == publishData.username))
   {
     // We found a match
     matchedLength = pubUrlFound ? publishData.publishUrl.length 
                             : publishData.browseUrl.length;
 
@@ -794,24 +792,24 @@ function FormatDirForPublishing(dir)
   dir = TrimString(dir);
 
   // The "//" case is an expected "typo" filter
   //  that simplifies code below!
   if (!dir || dir == "/" || dir == "//")
     return "";
 
   // Remove leading "/"
-  if (dir.charAt(0) == "/")
+  if (dir.startsWith("/"))
     dir = dir.slice(1);
 
   // Append "/" at the end if necessary
   var dirLen = dir.length;
   var lastChar = dir.charAt(dirLen-1);
-  if (dirLen > 1 && lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar  != "?")
-    return (dir + "/");
+  if (dirLen > 1 && ["/", "=", "&", "?"].indexOf(lastChar) == -1)
+    dir += "/";
 
   return dir;
 }
 
 function GetSavedPassword(publishData)
 {
   if (!publishData || !publishData.publishUrl)
     return "";
--- a/editor/ui/dialogs/content/EdAECSSAttributes.js
+++ b/editor/ui/dialogs/content/EdAECSSAttributes.js
@@ -96,20 +96,20 @@ function UpdateCSSAttributes()
   for(var i = 0; i < CSSAList.childNodes.length; i++)
   {
     var item = CSSAList.childNodes[i];
     var name = GetTreeItemAttributeStr(item);
     var value = GetTreeItemValueStr(item);
     // this code allows users to be sloppy in typing in values, and enter
     // things like "foo: " and "bar;". This will trim off everything after the
     // respective character.
-    if (name.indexOf(":") != -1)
-      name = name.substring(0,name.lastIndexOf(":"));
-    if (value.indexOf(";") != -1)
-      value = value.substring(0,value.lastIndexOf(";"));
+    if (name.contains(":"))
+      name = name.substring(0, name.lastIndexOf(":"));
+    if (value.contains(";"))
+      value = value.substring(0, value.lastIndexOf(";"));
     if (i == (CSSAList.childNodes.length - 1))
       styleString += name + ": " + value + ";";   // last property
     else
       styleString += name + ": " + value + "; ";
   }
   if (styleString)
   {
     // Use editor transactions if modifying the element directly in the document
--- a/editor/ui/dialogs/content/EdAEHTMLAttributes.js
+++ b/editor/ui/dialogs/content/EdAEHTMLAttributes.js
@@ -11,29 +11,27 @@ function BuildHTMLAttributeNameList()
 
   if (attNames && attNames.length)
   {
     var menuitem;
 
     for (var i = 0; i < attNames.length; i++)
     {
       var name = attNames[i];
-      var limitFirstChar;
 
       if (name == "_core")
       {
         // Signal to append the common 'core' attributes.
         for (var j = 0; j < gCoreHTMLAttr.length; j++)
         {
           name = gCoreHTMLAttr[j];
 
-          // "limitFirstChar" is the only filtering rule used for core attributes as of 8-20-01
-          // Add more rules if necessary          
-          limitFirstChar = name.indexOf("^") >= 0;
-          if (limitFirstChar)
+          // only filtering rule used for core attributes as of 8-20-01
+          // Add more rules if necessary.
+          if (name.contains("^"))
           {
             menuitem = gDialog.AddHTMLAttributeNameInput.appendItem(name.replace(/\^/g, ""));
             menuitem.setAttribute("limitFirstChar", "true");
           }
           else
             gDialog.AddHTMLAttributeNameInput.appendItem(name);
         }
       }
@@ -46,22 +44,22 @@ function BuildHTMLAttributeNameList()
           var sep = document.createElementNS(XUL_NS, "menuseparator");
           if (sep)
             popup.appendChild(sep);
         }        
       }
       else
       {
         // Get information about value filtering
-        var forceOneChar = name.indexOf("!") >= 0;
-        var forceInteger = name.indexOf("#") >= 0;
-        var forceSignedInteger = name.indexOf("+") >= 0;
-        var forceIntOrPercent = name.indexOf("%") >= 0;
-        limitFirstChar = name.indexOf("\^") >= 0;
-        //var required = name.indexOf("$") >= 0;
+        let forceOneChar = name.contains("!");
+        let forceInteger = name.contains("#");
+        let forceSignedInteger = name.contains("+");
+        let forceIntOrPercent = name.contains("%");
+        let limitFirstChar = name.contains("\^");
+        //let required = name.contains("$");
 
         // Strip flag characters
         name = name.replace(/[!^#%$+]/g, "");
 
         menuitem = gDialog.AddHTMLAttributeNameInput.appendItem(name);
         if (menuitem)
         {
           // Signify "required" attributes by special style
@@ -92,24 +90,23 @@ function BuildHTMLAttributeTable()
 {
   var nodeMap = gElement.attributes;
   var i;
   if (nodeMap.length > 0) 
   {
     var added = false;
     for(i = 0; i < nodeMap.length; i++)
     {
+      let name = nodeMap[i].name.toLowerCase();
       if ( CheckAttributeNameSimilarity( nodeMap[i].nodeName, HTMLAttrs ) ||
-          IsEventHandler( nodeMap[i].nodeName ) ||
-          TrimString( nodeMap[i].nodeName.toLowerCase() ) == "style" ) {
+           name.startsWith("on") || name == "style" ) {
         continue;   // repeated or non-HTML attribute, ignore this one and go to next
       }
-      var name  = nodeMap[i].name.toLowerCase();
-      if ( name.indexOf("_moz") != 0 &&
-           AddTreeItem(name, nodeMap[i].value, "HTMLAList", HTMLAttrs) )
+      if (!name.startsWith("_moz") &&
+          AddTreeItem(name, nodeMap[i].value, "HTMLAList", HTMLAttrs))
       {
         added = true;
       }
     }
 
     if (added)
       SelectHTMLTree(0);
   }
@@ -147,17 +144,17 @@ function onSelectHTMLTreeItem()
       // Change value input based on new selected name
       onInputHTMLAttributeName();
     }
   }
 }
 
 function onInputHTMLAttributeName()
 {
-  var attName = TrimString(gDialog.AddHTMLAttributeNameInput.value).toLowerCase();
+  let attName = gDialog.AddHTMLAttributeNameInput.value.toLowerCase().trim();
 
   // Clear value widget, but prevent triggering update in tree
   gUpdateTreeValue = false;
   gDialog.AddHTMLAttributeValueInput.value = "";
   gUpdateTreeValue = true; 
 
   if (attName)
   {
@@ -168,17 +165,17 @@ function onInputHTMLAttributeName()
     //   so we have just one array for the allowed values instead
     //   requiring duplicate entries for each element in EdAEAttributes.js
     if (attName == "dir")
       valueListName = "all_dir";
     else
       valueListName = gElement.localName.toLowerCase() + "_" + attName;
 
     // Strip off leading "_" we sometimes use (when element name is reserved word)
-    if (valueListName[0] == "_")
+    if (valueListName.startsWith("_"))
       valueListName = valueListName.slice(1);
 
     var newValue = "";
     var listLen = 0;
 
     // Index to which widget we were using to edit the value
     var deckIndex = gDialog.AddHTMLAttributeValueDeck.getAttribute("selectedIndex");
 
@@ -299,17 +296,17 @@ function onInputHTMLAttributeValue()
       // Update once only if it changed
       if (value != gDialog.AddHTMLAttributeValueInput.value)
         gDialog.AddHTMLAttributeValueInput.value = value;
     }
   }
 
   // Update value in the tree list
   // If not found, add new attribute
-  if ( !UpdateExistingAttribute(name, value, "HTMLAList" ) && value)
+  if (!UpdateExistingAttribute(name, value, "HTMLAList") && value)
     AddTreeItem(name, value, "HTMLAList", HTMLAttrs);
 }
 
 function editHTMLAttributeValue(targetCell)
 {
   if (IsNotTreeHeader(targetCell))
     gDialog.AddHTMLAttributeValueInput.inputField.select();
 }
--- a/editor/ui/dialogs/content/EdAEJSEAttributes.js
+++ b/editor/ui/dialogs/content/EdAEJSEAttributes.js
@@ -68,43 +68,32 @@ function BuildJSEAttributeNameList()
 function BuildJSEAttributeTable()
 {
   var nodeMap = gElement.attributes;
   if (nodeMap.length > 0)
   {
     var added = false;
     for (var i = 0; i < nodeMap.length; i++)
     {
+      let name = nodeMap[i].nodeName.toLowerCase();
       if( CheckAttributeNameSimilarity( nodeMap[i].nodeName, JSEAttrs ) )
         continue;   // repeated or non-JS handler, ignore this one and go to next
-      if( !IsEventHandler( nodeMap[i].nodeName ) )
+      if (!name.startsWith("on"))
         continue; // attribute isn't an event handler.
-      var name  = nodeMap[i].nodeName.toLowerCase();
       var value = gElement.getAttribute(nodeMap[i].nodeName);
       if (AddTreeItem( name, value, "JSEAList", JSEAttrs )) // add item to tree
         added = true;
     }
 
     // Select first item
     if (added)
       gDialog.AddJSEAttributeTree.selectedIndex = 0;
   }
 }
 
-// check to see if given string is an event handler.
-function IsEventHandler( which )
-{
-  var handlerName = which.toLowerCase();
-  var firstTwo = handlerName.substring(0,2);
-  if (firstTwo == "on")
-    return true;
-  else
-    return false;
-}
-
 function onSelectJSEAttribute()
 {
   if(!gDoOnSelectTree)
     return;
 
   gDialog.AddJSEAttributeValueInput.value = 
       GetAndSelectExistingAttributeValue(gDialog.AddJSEAttributeNameList.label, "JSEAList");
 }
--- a/editor/ui/dialogs/content/EdConvertToTable.js
+++ b/editor/ui/dialogs/content/EdConvertToTable.js
@@ -133,17 +133,17 @@ function onAccept()
   do {
     start = str.indexOf("<", searchStart);
 
     if (start >= 0)
     {
       end = str.indexOf(">", start+1);
       if (end > start)
       {
-        var tagContent = TrimString(str.slice(start+1, end));
+        let tagContent = str.slice(start + 1, end).trim();
 
         if (/^ol|^ul|^dl/.test(tagContent))
         {
           //  Replace list tag with <BR> to start new row 
           //   at begining of second or greater list tag
           str = str.slice(0, start) + listSeparator + str.slice(end+1);
           if (listSeparator == "")
             listSeparator = "<br>";
@@ -203,17 +203,17 @@ function onAccept()
   }
 
   replaceString += "<td>"; 
 
   if (sepCharacter.length > 0)
   {
     var tempStr = sepCharacter;
     var regExpChars = ".!@#$%^&*-+[]{}()\|\\\/";
-    if (regExpChars.indexOf(sepCharacter) >= 0)
+    if (regExpChars.contains(sepCharacter))
       tempStr = "\\" + sepCharacter;
 
     if (gIndex == gSpaceIndex)
     {
       // If checkbox is checked, 
       //   one or more adjacent spaces are one separator
       if (gDialog.collapseSpaces.checked)
           tempStr = "\\s+"
--- a/editor/ui/dialogs/content/EdDialogCommon.js
+++ b/editor/ui/dialogs/content/EdDialogCommon.js
@@ -177,17 +177,17 @@ function SetTextboxFocus(textbox)
     //XXX Using the setTimeout is hacky workaround for bug 103197
     // Must create a new function to keep "textbox" in scope
     setTimeout( function(textbox) { textbox.focus(); textbox.select(); }, 0, textbox );
   }
 }
 
 function ShowInputErrorMessage(message)
 {
-  AlertWithTitle(GetString("InputError"), message);
+  Services.prompt.alert(window, GetString("InputError"), message);
   window.focus();
 }
 
 // Get the text appropriate to parent container
 //  to determine what a "%" value is referring to.
 // elementForAtt is element we are actually setting attributes on
 //  (a temporary copy of element in the doc to allow canceling),
 //  but elementInDoc is needed to find parent context in document
@@ -256,28 +256,28 @@ function InitPixelOrPercentMenulist(elem
   pixelItem = menulist.appendItem(GetString("Pixels"));
 
   if (!pixelItem) return 0;
 
   percentItem = menulist.appendItem(GetAppropriatePercentString(elementForAtt, elementInDoc));
   if (size && size.length > 0)
   {
     // Search for a "%" or "px"
-    if (/%/.test(size))
+    if (size.contains("%"))
     {
       // Strip out the %
-      size = RegExp.leftContext;
+      size = size.substr(0, size.indexOf("%"));
       if (percentItem)
         menulist.selectedItem = percentItem;
     }
     else
     {
-      if (/px/.test(size))
+      if (size.contains("px"))
         // Strip out the px
-        size = RegExp.leftContext;
+        size = size.substr(0, size.indexOf("px"));
       menulist.selectedItem = pixelItem;
     }
   }
   else
     menulist.selectedIndex = defaultIndex;
 
   return size;
 }
@@ -395,27 +395,27 @@ function GetLocalFileURL(filterType)
   if (filterType == "img")
   {
     fp.init(window, GetString("SelectImageFile"), nsIFilePicker.modeOpen);
     fp.appendFilters(nsIFilePicker.filterImages);
     fileType = "image";
   }
   // Current usage of this is in Link dialog,
   //  where we always want HTML first
-  else if (filterType.indexOf("html") == 0)
+  else if (filterType.startsWith("html"))
   {
     fp.init(window, GetString("OpenHTMLFile"), nsIFilePicker.modeOpen);
 
     // When loading into Composer, direct user to prefer HTML files and text files,
     //   so we call separately to control the order of the filter list
     fp.appendFilters(nsIFilePicker.filterHTML);
     fp.appendFilters(nsIFilePicker.filterText);
 
     // Link dialog also allows linking to images
-    if (filterType.indexOf("img") > 0)
+    if (filterType.contains("img", 1))
       fp.appendFilters(nsIFilePicker.filterImages);
 
   }
   // Default or last filter is "All Files"
   fp.appendFilters(nsIFilePicker.filterAll);
 
   // set the file picker's current directory to last-opened location saved in prefs
   SetFilePickerDirectory(fp, fileType);
@@ -432,97 +432,39 @@ function GetLocalFileURL(filterType)
     return null;
   }
   SaveFilePickerDirectory(fp, fileType);
   
   var fileHandler = GetFileProtocolHandler();
   return fp.file ? fileHandler.getURLSpecFromFile(fp.file) : null;
 }
 
-function GetMetaElement(name)
-{
-  if (name)
-  {
-    name = name.toLowerCase();
-    if (name != "")
-    {
-      var editor = GetCurrentEditor();
-      try {
-        var metaNodes = editor.document.getElementsByTagName("meta");
-        for (var i = 0; i < metaNodes.length; i++)
-        {
-          var metaNode = metaNodes.item(i);
-          if (metaNode && metaNode.getAttribute("name") == name)
-            return metaNode;
-        }
-      } catch (e) {}
-    }
-  }
-  return null;
-}
-
-function CreateMetaElement(name)
-{
-  var editor = GetCurrentEditor();
-  try {
-    var metaElement = editor.createElementWithDefaults("meta");
-    metaElement.setAttribute("name", name);
-    return metaElement;
-  } catch (e) {}
-
-  return null;
-}
-
-function GetHTTPEquivMetaElement(name)
+function GetMetaElementByAttribute(name, value)
 {
   if (name)
   {
     name = name.toLowerCase();
-    if (name != "")
-    {
-      var editor = GetCurrentEditor();
-      try {
-        var metaNodes = editor.document.getElementsByTagName("meta");
-        for (var i = 0; i < metaNodes.length; i++)
-        {
-          var metaNode = metaNodes.item(i);
-          if (metaNode)
-          {
-            var httpEquiv = metaNode.getAttribute("http-equiv");
-            if (httpEquiv && httpEquiv.toLowerCase() == name)
-              return metaNode;
-          }
-        }
-      } catch (e) {}
-    }
+    let editor = GetCurrentEditor();
+    try {
+      return editor.document.querySelector('meta[' + name + '="' + value + '"]');
+    } catch (e) {}
   }
   return null;
 }
 
-function CreateHTTPEquivMetaElement(name)
+function CreateMetaElementWithAttribute(name, value)
 {
-  var editor = GetCurrentEditor();
+  let editor = GetCurrentEditor();
   try {
-    var metaElement = editor.createElementWithDefaults("meta");
-    metaElement.setAttribute("http-equiv", name);
+    let metaElement = editor.createElementWithDefaults("meta");
+    if (name) {
+      metaElement.setAttribute(name, value);
+    }
     return metaElement;
   } catch (e) {}
-
-  return null;
-}
-
-function CreateHTTPEquivElement(name)
-{
-  var editor = GetCurrentEditor();
-  try {
-    var metaElement = editor.createElementWithDefaults("meta");
-    metaElement.setAttribute("http-equiv", name);
-    return metaElement;
-  } catch (e) {}
-
   return null;
 }
 
 // Change "content" attribute on a META element,
 //   or delete entire element it if content is empty
 // This uses undoable editor transactions
 function SetMetaElementContent(metaElement, content, insertNew, prepend)
 {
@@ -551,18 +493,17 @@ function SetMetaElementContent(metaEleme
     } catch (e) {}
   }
 }
 
 function GetHeadElement()
 {
   var editor = GetCurrentEditor();
   try {
-    var headList = editor.document.getElementsByTagName("head");
-    return headList.item(0);
+    return editor.document.querySelector("head");
   } catch (e) {}
 
   return null;
 }
 
 function PrependHeadElement(element)
 {
   var head = GetHeadElement();
@@ -697,17 +638,17 @@ function MakeInputValueRelativeOrAbsolut
   if (!input)
     return;
 
   var docUrl = GetDocumentBaseUrl();
   if (!docUrl)
   {
     // Checkbox should be disabled if not saved,
     //  but keep this error message in case we change that
-    AlertWithTitle("", GetString("SaveToUseRelativeUrl"));
+    Services.prompt.alert(window, "", GetString("SaveToUseRelativeUrl"));
     window.focus();
   }
   else 
   {
     // Note that "checked" is opposite of its last state,
     //  which determines what we want to do here
     if (checkbox.checked)
       input.value = MakeRelativeUrl(input.value);
--- a/editor/ui/dialogs/content/EdFieldSetProps.js
+++ b/editor/ui/dialogs/content/EdFieldSetProps.js
@@ -60,17 +60,17 @@ function Startup()
 
   legendElement = fieldsetElement.firstChild;
   if (legendElement && legendElement.localName == "LEGEND")
   {
     newLegend = false;
     var range = editor.document.createRange();
     range.selectNode(legendElement);
     gDialog.legendText.value = range.toString();
-    if (/</.test(legendElement.innerHTML))
+    if (legendElement.innerHTML.contains("<"))
     {
       gDialog.editText.checked = false;
       gDialog.editText.disabled = false;
       gDialog.legendText.disabled = true;
       gDialog.editText.addEventListener("command", onEditText, false);
       gDialog.RemoveFieldSet.focus();
     }
     else
@@ -104,17 +104,17 @@ function Startup()
 function InitDialog()
 {
   gDialog.legendAlign.value = GetHTMLOrCSSStyleValue(globalElement, "align", "caption-side");
 }
 
 function onEditText()
 {
   gDialog.editText.removeEventListener("command", onEditText, false);
-  AlertWithTitle(GetString("Alert"), GetString("EditTextWarning"));
+  Services.prompt.alert(window, GetString("Alert"), GetString("EditTextWarning"));
 }
 
 function RemoveFieldSet()
 {
   var editor = GetCurrentEditor();
   editor.beginTransaction();
   try {
     if (!newLegend)
--- a/editor/ui/dialogs/content/EdFormProps.js
+++ b/editor/ui/dialogs/content/EdFormProps.js
@@ -101,17 +101,17 @@ function ValidateData()
   }
   return true;
 }
 
 function onAccept()
 {
   if (formActionWarning && !gForm.Action.value)
   {
-    AlertWithTitle(GetString("Alert"), GetString("NoFormAction"));
+    Services.prompt.alert(window, GetString("Alert"), GetString("NoFormAction"));
     gForm.Action.focus();
     formActionWarning = false;
     return false;
   }
   // All values are valid - copy to actual element in doc or
   //   element created to insert
   ValidateData();
 
--- a/editor/ui/dialogs/content/EdHLineProps.js
+++ b/editor/ui/dialogs/content/EdHLineProps.js
@@ -56,18 +56,18 @@ function Startup()
 // Set dialog widgets with attribute data
 // We get them from globalElement copy so this can be used
 //   by AdvancedEdit(), which is shared by all property dialogs
 function InitDialog()
 {
   // Just to be confusing, "size" is used instead of height because it does
   // not accept % values, only pixels
   var height = GetHTMLOrCSSStyleValue(globalElement, "size", "height")
-  if (/px/.test(height)) {
-    height = RegExp.leftContext;
+  if (height.contains("px")) {
+    height = height.substr(0, height.indexOf("px"));
   }
   if(!height) {
     height = 2; //Default value
   }
 
   // We will use "height" here and in UI
   gDialog.heightInput.value = height;
 
@@ -111,19 +111,19 @@ function onSaveDefault()
     Services.prefs.setIntPref("editor.hrule.align", alignInt);
 
     var percent;
     var widthInt;
     var heightInt;
 
     if (width)
     {
-      if (/%/.test(width)) {
+      if (width.contains("%")) {
         percent = true;
-        widthInt = Number(RegExp.leftContext);
+        widthInt = Number(width.substr(0, width.indexOf("%")));
       } else {
         percent = false;
         widthInt = Number(width);
       }
     }
     else
     {
       percent = true;
--- a/editor/ui/dialogs/content/EdImageOverlay.js
+++ b/editor/ui/dialogs/content/EdImageOverlay.js
@@ -112,20 +112,20 @@ function InitImage()
   gDialog.heightInput.value = gConstrainHeight = height ? height : (gActualHeight ? gActualHeight : "");
 
   // set spacing editfields
   gDialog.imagelrInput.value = globalElement.getAttribute("hspace");
   gDialog.imagetbInput.value = globalElement.getAttribute("vspace");
 
   // dialog.border.value       = globalElement.getAttribute("border");
   var bv = GetHTMLOrCSSStyleValue(globalElement, "border", "border-top-width");
-  if (/px/.test(bv))
+  if (bv.contains("px"))
   {
     // Strip out the px
-    bv = RegExp.leftContext;
+    bv = bv.substr(0, bv.indexOf("px"));
   }
   else if (bv == "thin")
   {
     bv = "1";
   }
   else if (bv == "medium")
   {
     bv = "3";
@@ -188,25 +188,20 @@ function SetAltTextDisabled(disable)
 }
 
 function GetImageMap()
 {
   var usemap = globalElement.getAttribute("usemap");
   if (usemap)
   {
     gCanRemoveImageMap = true;
-    var mapname = usemap.substring(1, usemap.length);
-    var mapCollection;
+    let mapname = usemap.substr(1);
     try {
-      mapCollection = GetCurrentEditor().document.getElementsByName(mapname);
+      return GetCurrentEditor().document.querySelector('[name="' + mapname + '"]');
     } catch (e) {}
-    if (mapCollection && mapCollection[0] != null)
-    {
-      return mapCollection[0];
-    }
   }
   else
   {
     gCanRemoveImageMap = false;
   }
 
   return null;
 }
@@ -450,38 +445,36 @@ function ValidateImage()
 {
   var editor = GetCurrentEditor();
   if (!editor)
     return false;
 
   gValidateTab = gDialog.tabLocation;
   if (!gDialog.srcInput.value)
   {
-    AlertWithTitle(null, GetString("MissingImageError"));
+    Services.prompt.alert(window, GetString("Alert"), GetString("MissingImageError"));
     SwitchToValidatePanel();
     gDialog.srcInput.focus();
     return false;
   }
 
   // We must convert to "file:///" or "http://" format else image doesn't load!
-  var src = TrimString(gDialog.srcInput.value);
+  let src = gDialog.srcInput.value.trim();
   var checkbox = document.getElementById("MakeRelativeCheckbox");
   try
   {
     if (checkbox && !checkbox.checked)
     {
-      var URIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
-                               .getService(Components.interfaces.nsIURIFixup);
-      src = URIFixup.createFixupURI(src, Components.interfaces.nsIURIFixup.FIXUP_FLAG_NONE).spec;
+      src = Services.uriFixup.createFixupURI(src, Components.interfaces.nsIURIFixup.FIXUP_FLAG_NONE).spec;
     }
   } catch (e) { }
 
   globalElement.setAttribute("src", src);
 
-  var title = TrimString(gDialog.titleInput.value);
+  let title = gDialog.titleInput.value.trim();
   if (title)
     globalElement.setAttribute("title", title);
   else
     globalElement.removeAttribute("title");
 
   // Force user to enter Alt text only if "Alternate text" radio is checked
   // Don't allow just spaces in alt text
   var alt = "";
@@ -494,17 +487,17 @@ function ValidateImage()
     globalElement.setAttribute("alt", alt);
   }
   else if (!gDoAltTextError)
   {
     globalElement.removeAttribute("alt");
   }
   else
   {
-    AlertWithTitle(null, GetString("NoAltText"));
+    Services.prompt.alert(window, GetString("Alert"), GetString("NoAltText"));
     SwitchToValidatePanel();
     gDialog.altTextInput.focus();
     return false;
   }
 
   var width = "";
   var height = "";
 
--- a/editor/ui/dialogs/content/EdInsertTOC.js
+++ b/editor/ui/dialogs/content/EdInsertTOC.js
@@ -71,17 +71,17 @@ function Startup()
     orderedList = (toc.nodeName.toLowerCase() == "ol");
     orderedListCheckbox.checked = orderedList;
 
     var nodeList = toc.childNodes;
     // let's look at the children of the TOC ; if we find a comment beginning
     // with "mozToc", it contains the TOC definition
     for (i = 0; i< nodeList.length; ++i) {
       if (nodeList.item(i).nodeType == Node.COMMENT_NODE &&
-          nodeList.item(i).data.substr(0, kMozTocLength) == kMozToc) {
+          nodeList.item(i).data.startsWith(kMozToc)) {
         // yep, there is already a definition here; parse it !
         headers = nodeList.item(i).data.substr(kMozTocLength + 1,
                                     nodeList.item(i).length - kMozTocLength - 1);
         break;
       }
     }
   }
 
@@ -201,17 +201,17 @@ function BuildTOC(update)
         headerText += textNode.data;
         textNode = textTreeWalker.nextNode();
       }
 
       var anchor = tocSourceNode.firstChild, id;
       // do we have a named anchor as 1st child of our node ?
       if (anchor.nodeName.toLowerCase() == "a" &&
           anchor.hasAttribute("name") &&
-          anchor.getAttribute("name").substr(0, kMozTocIdPrefixLength) == kMozTocIdPrefix) {
+          anchor.getAttribute("name").startsWith(kMozTocIdPrefix)) {
         // yep, get its name
         id = anchor.getAttribute("name");
       }
       else {
         // no we don't and we need to create one
         anchor = theDocument.createElement("a");
         tocSourceNode.insertBefore(anchor, tocSourceNode.firstChild);
         // let's give it a random ID
--- a/editor/ui/dialogs/content/EdLabelProps.js
+++ b/editor/ui/dialogs/content/EdLabelProps.js
@@ -27,17 +27,17 @@ function Startup()
   globalElement = labelElement.cloneNode(false);
 
   InitDialog();
 
   var range = editor.document.createRange();
   range.selectNode(labelElement);
   gDialog.labelText.value = range.toString();
 
-  if (/</.test(labelElement.innerHTML))
+  if (labelElement.innerHTML.contains("<"))
   {
     gDialog.editText.checked = false;
     gDialog.editText.disabled = false;
     gDialog.labelText.disabled = true;
     gDialog.editText.addEventListener("command", onEditText, false);
     SetTextboxFocus(gDialog.labelFor);
   }
   else
@@ -50,17 +50,17 @@ function InitDialog()
 {
   gDialog.labelFor.value = globalElement.getAttribute("for");
   gDialog.labelAccessKey.value = globalElement.getAttribute("accesskey");
 }
 
 function onEditText()
 {
   gDialog.editText.removeEventListener("command", onEditText, false);
-  AlertWithTitle(GetString("Alert"), GetString("EditTextWarning"));
+  Services.prompt.alert(window, GetString("Alert"), GetString("EditTextWarning"));
 }
 
 function RemoveLabel()
 {
   RemoveContainer(labelElement);
   SaveWindowLocation();
   window.close();
 }
--- a/editor/ui/dialogs/content/EdLinkChecker.js
+++ b/editor/ui/dialogs/content/EdLinkChecker.js
@@ -51,17 +51,17 @@ function Startup()
   // Get all objects that refer to other locations
   var objects;
   try {
     objects = editor.getLinkedObjects();
   } catch (e) {}
 
   if (!objects || objects.Count() == 0)
   {
-    AlertWithTitle(GetString("Alert"), GetString("NoLinksToCheck"));
+    Services.prompt.alert(window, GetString("Alert"), GetString("NoLinksToCheck"));
     window.close();
     return;
   }
 
   gDialog.LinksList = document.getElementById("LinksList");
 
   // Set window location relative to parent window (based on persisted attributes)
   SetWindowLocation();
@@ -150,31 +150,25 @@ function SetItemStatus(url, status)
   if (!url)
     return false;
 
   if (!status)
     status = "busy";
 
   // Just set attribute for status icon 
   // if we already have this url 
-  var listitems = document.getElementsByTagName("listitem");
-  if (listitems)
+  let listitem = document.querySelector('listitem[label="' + url + '"]');
+  if (listitem)
   {
-    for (var i=0; i < listitems.length; i++)
-    {
-      if (listitems[i].getAttribute("label") == url)
-      {
-        listitems[i].setAttribute("progress", status);
-        return true;
-      }
-    }
+    listitem.setAttribute("progress", status);
+    return true;
   }
 
   // We're adding a new item to list
-  var listitem = document.createElementNS(XUL_NS, "listitem");
+  listitem = document.createElementNS(XUL_NS, "listitem");
   if (listitem)
   {
     listitem.setAttribute("class", "listitem-iconic progressitem");
     // This triggers CSS to show icon for each status state
     listitem.setAttribute("progress", status);
     listitem.setAttribute("label", url);
     gDialog.LinksList.appendChild(listitem);
   }
--- a/editor/ui/dialogs/content/EdPageProps.js
+++ b/editor/ui/dialogs/content/EdPageProps.js
@@ -66,32 +66,32 @@ function Startup()
                                       lastModDate.getHours(),
                                       lastModDate.getMinutes(),
                                       lastModDate.getSeconds());
       } catch (e) {}
     }
   }
   gDialog.PageModDate.value = lastmodString;
 
-  gAuthorElement = GetMetaElement("author");
+  gAuthorElement = GetMetaElementByAttribute("name", "author");
   if (!gAuthorElement)
   {
-    gAuthorElement = CreateMetaElement("author");
+    gAuthorElement = CreateMetaElementWithAttribute("name", "author");
     if (!gAuthorElement)
     {
       window.close();
       return;
     }
     gInsertNewAuthor = true;
   }
 
-  gDescriptionElement = GetMetaElement("description");
+  gDescriptionElement = GetMetaElementByAttribute("name", "description");
   if (!gDescriptionElement)
   {
-    gDescriptionElement = CreateMetaElement("description");
+    gDescriptionElement = CreateMetaElementWithAttribute("name", "description");
     if (!gDescriptionElement)
       window.close();
 
     gInsertNewDescription = true;
   }
   
   InitDialog();
 
--- a/editor/ui/dialogs/content/EdReplace.js
+++ b/editor/ui/dialogs/content/EdReplace.js
@@ -116,17 +116,17 @@ function onFindNext()
   setUpFindInst();
 
   // Search.
   var result = gFindInst.findNext();
 
   if (!result)
   {
     var bundle = document.getElementById("findBundle");
-    AlertWithTitle(null, bundle.getString("notFoundWarning"));
+    Services.prompt.alert(window, GetString("Alert"), bundle.getString("notFoundWarning"));
     SetTextboxFocus(gReplaceDialog.findInput);
     gReplaceDialog.findInput.select();
     gReplaceDialog.findInput.focus();
     return false;
   } 
   return true;
 }
 
--- a/editor/ui/dialogs/content/EditorPublishProgress.js
+++ b/editor/ui/dialogs/content/EditorPublishProgress.js
@@ -115,57 +115,48 @@ function Startup()
   gPersistObj = window.opener.StartPublishing();
 }
 
 // this function is to be used when we cancel persist's saving
 // since not all messages will be returned to us if we cancel
 // this function changes status for all non-done/non-failure to failure
 function SetProgressStatusCancel()
 {
-  var listitems = document.getElementsByTagName("listitem");
+  let listitems = document.querySelectorAll('listitem:not([progress="done"]):not([progress="failed"])');
   if (!listitems)
     return;
 
   for (var i=0; i < listitems.length; i++)
   {
-    var attr = listitems[i].getAttribute("progress");
-    if (attr != "done" && attr != "failed")
-      listitems[i].setAttribute("progress", "failed");
+    listitems[i].setAttribute("progress", "failed");
   }
 }
 
 // Add filename to list of files to publish
 // or set status for file already in the list
 // Returns true if file was in the list
 function SetProgressStatus(filename, status)
 {
   if (!filename)
     return false;
 
   if (!status)
     status = "busy";
 
-  // Just set attribute for status icon 
-  // if we already have this filename 
-  var listitems = document.getElementsByTagName("listitem");
-  if (listitems)
+  // Just set attribute for status icon if we already have this filename.
+  let listitem = document.querySelector('listitem[label="' + filename + '"]');
+  if (listitem)
   {
-    for (var i=0; i < listitems.length; i++)
-    {
-      if (listitems[i].getAttribute("label") == filename)
-      {
-        listitems[i].setAttribute("progress", status);
-        return true;
-      }
-    }
+    listitem.setAttribute("progress", status);
+    return true;
   }
   // We're adding a new file item to list
   gTotalFileCount++;
 
-  var listitem = document.createElementNS(XUL_NS, "listitem");
+  listitem = document.createElementNS(XUL_NS, "listitem");
   if (listitem)
   {
     listitem.setAttribute("class", "listitem-iconic progressitem");
     // This triggers CSS to show icon for each status state
     listitem.setAttribute("progress", status);
     listitem.setAttribute("label", filename);
     gDialog.FileList.appendChild(listitem);
   }
--- a/editor/ui/dialogs/content/EditorSaveAsCharset.js
+++ b/editor/ui/dialogs/content/EditorSaveAsCharset.js
@@ -21,20 +21,20 @@ function Startup()
   }
 
   Services.obs.notifyObservers(null, "charsetmenu-selected", "other");
 
   gDialog.TitleInput    = document.getElementById("TitleInput");
   gDialog.charsetTree   = document.getElementById('CharsetTree'); 
   gDialog.exportToText  = document.getElementById('ExportToText');
 
-  gContenttypeElement = GetHTTPEquivMetaElement("content-type");
+  gContenttypeElement = GetMetaElementByAttribute("http-equiv", "content-type");
   if (!gContenttypeElement && (editor.contentsMIMEType != 'text/plain')) 
   {
-    gContenttypeElement = CreateHTTPEquivMetaElement("content-type");
+    gContenttypeElement = CreateMetaElementWithAttribute("http-equiv", "content-type");
     if (!gContenttypeElement ) 
 	{
       window.close();
       return;
     }
     gInsertNewContentType = true;
   }