Bug 1231828: Fix JS parsing errors in toolkit and browser XBL files. r=felipe
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 10 Dec 2015 16:53:46 -0500
changeset 311642 d897127c0000a478c24e29ce10f85837a16450c6
parent 311641 1df6ac95af8fa997a588a2089d97beabccdfa262
child 311643 eee9845be760b1dba1962c9a44ac0c1a2e702601
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs1231828
milestone46.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 1231828: Fix JS parsing errors in toolkit and browser XBL files. r=felipe
browser/base/content/socialchat.xml
browser/base/content/tabbrowser.xml
browser/components/search/content/search.xml
toolkit/components/prompts/content/tabprompts.xml
toolkit/content/jar.mn
toolkit/content/widgets/autocomplete.xml
toolkit/content/widgets/dialog.xml
toolkit/content/widgets/filefield.xml
toolkit/content/widgets/findbar.xml
toolkit/content/widgets/listbox.xml
toolkit/content/widgets/preferences.xml
toolkit/content/widgets/remote-browser.xml
toolkit/content/widgets/tabbox.xml
toolkit/content/widgets/tree.xml
toolkit/content/widgets/videocontrols.xml
toolkit/content/widgets/wizard.xml
toolkit/modules/AppConstants.jsm
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -384,45 +384,51 @@
           return !!this.querySelector("[collapsed]");
         ]]></getter>
       </property>
 
       <property name="collapsedChildren">
         <getter><![CDATA[
           // A generator yielding all collapsed chatboxes, in the order in
           // which they should be restored.
-          let child = this.lastElementChild;
-          while (child) {
-            if (child.collapsed)
-              yield child;
-            child = child.previousElementSibling;
+          return function*() {
+            let child = this.lastElementChild;
+            while (child) {
+              if (child.collapsed)
+                yield child;
+              child = child.previousElementSibling;
+            }
           }
         ]]></getter>
       </property>
 
       <property name="visibleChildren">
         <getter><![CDATA[
           // A generator yielding all non-collapsed chatboxes.
-          let child = this.firstElementChild;
-          while (child) {
-            if (!child.collapsed)
-              yield child;
-            child = child.nextElementSibling;
+          return function*() {
+            let child = this.firstElementChild;
+            while (child) {
+              if (!child.collapsed)
+                yield child;
+              child = child.nextElementSibling;
+            }
           }
         ]]></getter>
       </property>
 
       <property name="collapsibleChildren">
         <getter><![CDATA[
           // A generator yielding all children which are able to be collapsed
           // in the order in which they should be collapsed.
           // (currently this is all visible ones other than the selected one.)
-          for (let child of this.visibleChildren)
-            if (child != this.selectedChat)
-              yield child;
+          return function*() {
+            for (let child of this.visibleChildren())
+              if (child != this.selectedChat)
+                yield child;
+          }
         ]]></getter>
       </property>
 
       <method name="_selectAnotherChat">
         <body><![CDATA[
           // Select a different chat (as the currently selected one is no
           // longer suitable as the selection - maybe it is being minimized or
           // closed.)  We only select non-minimized and non-collapsed chats,
@@ -622,39 +628,39 @@
         // So we go the more complicated but more efficient second option...
         let availWidth = this.getBoundingClientRect().width;
         let currentWidth = 0;
         if (!this.nub.collapsed) { // the nub is visible.
           if (!this.cachedWidthNub)
             this.cachedWidthNub = this.calcTotalWidthOf(this.nub);
           currentWidth += this.cachedWidthNub;
         }
-        for (let child of this.visibleChildren) {
+        for (let child of this.visibleChildren()) {
           currentWidth += this.getTotalChildWidth(child);
         }
 
         if (currentWidth > availWidth) {
           // we need to collapse some.
           let toCollapse = [];
-          for (let child of this.collapsibleChildren) {
+          for (let child of this.collapsibleChildren()) {
             if (currentWidth <= availWidth)
               break;
             toCollapse.push(child);
             currentWidth -= this.getTotalChildWidth(child);
           }
           if (toCollapse.length) {
             for (let child of toCollapse)
               this.collapseChat(child);
           }
         } else if (currentWidth < availWidth) {
           // we *might* be able to expand some - see how many.
           // XXX - if this was clever, it could know when removing the nub
           // leaves enough space to show all collapsed
           let toShow = [];
-          for (let child of this.collapsedChildren) {
+          for (let child of this.collapsedChildren()) {
             currentWidth += this.getTotalChildWidth(child);
             if (currentWidth > availWidth)
               break;
             toShow.push(child);
           }
           for (let child of toShow)
             this._showChat(child);
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4022,30 +4022,30 @@
         <body><![CDATA[
           let json = aMessage.json;
           let browser = aMessage.target;
 
           switch (aMessage.name) {
             case "DOMTitleChanged": {
               let tab = this.getTabForBrowser(browser);
               if (!tab || tab.hasAttribute("pending"))
-                return;
+                return undefined;
               let titleChanged = this.setTabTitle(tab);
               if (titleChanged && !tab.selected && !tab.hasAttribute("busy"))
                 tab.setAttribute("titlechanged", "true");
               break;
             }
             case "DOMWindowClose": {
               if (this.tabs.length == 1) {
                 // We already did PermitUnload in the content process
                 // for this tab (the only one in the window). So we don't
                 // need to do it again for any tabs.
                 window.skipNextCanClose = true;
                 window.close();
-                return;
+                return undefined;
               }
 
               let tab = this.getTabForBrowser(browser);
               if (tab) {
                 // Skip running PermitUnload since it already happened in
                 // the content process.
                 this.removeTab(tab, {skipPermitUnload: true});
               }
@@ -4083,25 +4083,25 @@
               let event = gContextMenuContentData.event;
               popup.openPopupAtScreen(event.screenX, event.screenY, true);
               break;
             }
             case "DOMServiceWorkerFocusClient":
             case "DOMWebNotificationClicked": {
               let tab = this.getTabForBrowser(browser);
               if (!tab)
-                return;
+                return undefined;
               this.selectedTab = tab;
               window.focus();
               break;
             }
             case "Browser:Init": {
               let tab = this.getTabForBrowser(browser);
               if (!tab)
-                return;
+                return undefined;
 
               this._outerWindowIDBrowserMap.set(browser.outerWindowID, browser);
               browser.messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: tab.pinned })
               break;
             }
             case "Findbar:Keypress":
               if (!gFindBarInitialized) {
                 // If the find bar for this tab is not yet alive, change that,
@@ -5197,20 +5197,19 @@
         <parameter name="event"/>
         <body><![CDATA[
           var dt = event.dataTransfer;
           // Disallow dropping multiple items
           if (dt.mozItemCount > 1)
             return "none";
 
           var types = dt.mozTypesAt(0);
-          var sourceNode = null;
           // tabs are always added as the first type
           if (types[0] == TAB_DROP_TYPE) {
-            var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
             if (sourceNode instanceof XULElement &&
                 sourceNode.localName == "tab" &&
                 sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
                 sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                 sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) {
               // Do not allow transfering a private tab to a non-private window
               // and vice versa.
               if (PrivateBrowsingUtils.isWindowPrivate(window) !=
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -676,21 +676,19 @@
             popup.showImageColumn = this.showImageColumn;
 
             document.popupNode = null;
 
             const isRTL = getComputedStyle(this, "").direction == "rtl";
 
             var outerRect = this.getBoundingClientRect();
             var innerRect = this.inputField.getBoundingClientRect();
-            if (isRTL) {
-              var width = innerRect.right - outerRect.left;
-            } else {
-              var width = outerRect.right - innerRect.left;
-            }
+            let width = isRTL ?
+                        innerRect.right - outerRect.left :
+                        outerRect.right - innerRect.left;
             popup.setAttribute("width", width > 100 ? width : 100);
 
             var yOffset = outerRect.bottom - innerRect.bottom;
             popup.openPopup(this.inputField, "after_start", 0, yOffset, false, false);
           }
         ]]></body>
       </method>
 
--- a/toolkit/components/prompts/content/tabprompts.xml
+++ b/toolkit/components/prompts/content/tabprompts.xml
@@ -306,29 +306,31 @@
 #ifdef XP_MACOSX
         <handler event="keypress" key="." modifiers="meta"
                  group="system" action="this.onKeyAction('cancel', event);"/>
 #endif
         <handler event="focus" phase="capturing">
             let bnum = this.args.defaultButtonNum || 0;
             let defaultButton = this.ui["button" + bnum];
 
-#ifdef XP_MACOSX
-            // On OS X, the default button always stays marked as such (until
-            // the entire prompt blurs).
-            defaultButton.setAttribute("default", true);
-#else
-            // On other platforms, the default button is only marked as such
-            // when no other button has focus. XUL buttons on not-OSX will
-            // react to pressing enter as a command, so you can't trigger the
-            // default without tabbing to it or something that isn't a button.
-            let focusedDefault = (event.originalTarget == defaultButton);
-            let someButtonFocused = event.originalTarget instanceof Ci.nsIDOMXULButtonElement;
-            defaultButton.setAttribute("default", focusedDefault || !someButtonFocused);
-#endif
+            let { AppConstants } =
+                Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+            if (AppConstants.platform == "macosx") {
+              // On OS X, the default button always stays marked as such (until
+              // the entire prompt blurs).
+              defaultButton.setAttribute("default", true);
+            } else {
+              // On other platforms, the default button is only marked as such
+              // when no other button has focus. XUL buttons on not-OSX will
+              // react to pressing enter as a command, so you can't trigger the
+              // default without tabbing to it or something that isn't a button.
+              let focusedDefault = (event.originalTarget == defaultButton);
+              let someButtonFocused = event.originalTarget instanceof Ci.nsIDOMXULButtonElement;
+              defaultButton.setAttribute("default", focusedDefault || !someButtonFocused);
+            }
         </handler>
         <handler event="blur">
             // If focus shifted to somewhere else in the browser, don't make
             // the default button look active.
             let bnum = this.args.defaultButtonNum || 0;
             let button = this.ui["button" + bnum];
             button.setAttribute("default", false);
         </handler>
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -59,30 +59,30 @@ toolkit.jar:
    content/global/resetProfile.css
    content/global/resetProfile.js
    content/global/resetProfile.xul
    content/global/resetProfileProgress.xul
    content/global/select-child.js
    content/global/TopLevelVideoDocument.js
    content/global/treeUtils.js
    content/global/viewZoomOverlay.js
-*+ content/global/bindings/autocomplete.xml    (widgets/autocomplete.xml)
++  content/global/bindings/autocomplete.xml    (widgets/autocomplete.xml)
    content/global/bindings/browser.xml         (widgets/browser.xml)
    content/global/bindings/button.xml          (widgets/button.xml)
    content/global/bindings/checkbox.xml        (widgets/checkbox.xml)
    content/global/bindings/colorpicker.xml     (widgets/colorpicker.xml)
    content/global/bindings/datetimepicker.xml  (widgets/datetimepicker.xml)
 *+ content/global/bindings/dialog.xml          (widgets/dialog.xml)
    content/global/bindings/editor.xml          (widgets/editor.xml)
    content/global/bindings/expander.xml        (widgets/expander.xml)
-*  content/global/bindings/filefield.xml       (widgets/filefield.xml)
+   content/global/bindings/filefield.xml       (widgets/filefield.xml)
 *+ content/global/bindings/findbar.xml         (widgets/findbar.xml)
    content/global/bindings/general.xml         (widgets/general.xml)
    content/global/bindings/groupbox.xml        (widgets/groupbox.xml)
-*+ content/global/bindings/listbox.xml         (widgets/listbox.xml)
++  content/global/bindings/listbox.xml         (widgets/listbox.xml)
    content/global/bindings/menu.xml            (widgets/menu.xml)
    content/global/bindings/menulist.xml        (widgets/menulist.xml)
    content/global/bindings/notification.xml    (widgets/notification.xml)
    content/global/bindings/numberbox.xml       (widgets/numberbox.xml)
    content/global/bindings/popup.xml           (widgets/popup.xml)
 *+ content/global/bindings/preferences.xml     (widgets/preferences.xml)
    content/global/bindings/progressmeter.xml   (widgets/progressmeter.xml)
    content/global/bindings/radio.xml           (widgets/radio.xml)
@@ -96,15 +96,15 @@ toolkit.jar:
    content/global/bindings/spinbuttons.xml     (widgets/spinbuttons.xml)
    content/global/bindings/stringbundle.xml    (widgets/stringbundle.xml)
 *+ content/global/bindings/tabbox.xml          (widgets/tabbox.xml)
    content/global/bindings/text.xml            (widgets/text.xml)
 *+ content/global/bindings/textbox.xml         (widgets/textbox.xml)
    content/global/bindings/toolbar.xml         (widgets/toolbar.xml)
    content/global/bindings/toolbarbutton.xml   (widgets/toolbarbutton.xml)
 *+ content/global/bindings/tree.xml            (widgets/tree.xml)
-*+ content/global/bindings/videocontrols.xml   (widgets/videocontrols.xml)
++  content/global/bindings/videocontrols.xml   (widgets/videocontrols.xml)
    content/global/bindings/videocontrols.css   (widgets/videocontrols.css)
 *+ content/global/bindings/wizard.xml          (widgets/wizard.xml)
 #ifdef XP_MACOSX
    content/global/macWindowMenu.js
 #endif
    content/global/svg/svgBindings.xml          (/layout/svg/resources/content/svgBindings.xml)
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -1,14 +1,12 @@
 <?xml version="1.0"?>
-
-# -*- Mode: HTML -*-
-# 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/.
+<!-- 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/. -->
 
 <bindings id="autocompleteBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="autocomplete" role="xul:combobox"
@@ -443,25 +441,23 @@
             return true; // Let child buttons of autocomplete take input
 
           //XXXpch this is so bogus...
           if (aEvent.defaultPrevented)
             return false;
 
           var cancel = false;
 
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
           // Catch any keys that could potentially move the caret. Ctrl can be
           // used in combination with these keys on Windows and Linux; and Alt
           // can be used on OS X, so make sure the unused one isn't used.
-          if (!this.disableKeyNavigation &&
-#ifdef XP_MACOSX
-              !aEvent.ctrlKey) {
-#else
-              !aEvent.altKey) {
-#endif
+          let metaKey = AppConstants.platform == "macosx" ? aEvent.ctrlKey : aEvent.altKey;
+          if (!this.disableKeyNavigation && !metaKey) {
             switch (aEvent.keyCode) {
               case KeyEvent.DOM_VK_LEFT:
               case KeyEvent.DOM_VK_RIGHT:
               case KeyEvent.DOM_VK_HOME:
                 cancel = this.mController.handleKeyNavigation(aEvent.keyCode);
                 break;
             }
           }
@@ -488,47 +484,51 @@
 
           // Handle keys we know aren't part of a shortcut, even with Alt or
           // Ctrl.
           switch (aEvent.keyCode) {
             case KeyEvent.DOM_VK_ESCAPE:
               cancel = this.mController.handleEscape();
               break;
             case KeyEvent.DOM_VK_RETURN:
-#ifdef XP_MACOSX
-              // Prevent the default action, since it will beep on Mac
-              if (aEvent.metaKey)
-                aEvent.preventDefault();
-#endif
+              if (AppConstants.platform == "macosx") {
+                // Prevent the default action, since it will beep on Mac
+                if (aEvent.metaKey)
+                  aEvent.preventDefault();
+              }
               this.mEnterEvent = aEvent;
               if (this.mController.selection) {
                 this._selectionDetails = {
                   index: this.mController.selection.currentIndex,
                   kind: "key"
                 };
               }
               cancel = this.handleEnter();
               break;
             case KeyEvent.DOM_VK_DELETE:
-#ifdef XP_MACOSX
+              if (AppConstants.platform == "macosx" && !aEvent.shiftKey) {
+                break;
+              }
+              cancel = this.handleDelete();
+              break;
             case KeyEvent.DOM_VK_BACK_SPACE:
-              if (aEvent.shiftKey)
-#endif
-              cancel = this.handleDelete();
+              if (AppConstants.platform == "macosx" && aEvent.shiftKey) {
+                cancel = this.handleDelete();
+              }
               break;
             case KeyEvent.DOM_VK_DOWN:
             case KeyEvent.DOM_VK_UP:
               if (aEvent.altKey)
                 this.toggleHistoryPopup();
               break;
-#ifndef XP_MACOSX
             case KeyEvent.DOM_VK_F4:
-              this.toggleHistoryPopup();
+              if (AppConstants.platform != "macosx") {
+                this.toggleHistoryPopup();
+              }
               break;
-#endif
           }
 
           if (cancel) {
             aEvent.stopPropagation();
             aEvent.preventDefault();
           }
 
           return true;
--- a/toolkit/content/widgets/dialog.xml
+++ b/toolkit/content/widgets/dialog.xml
@@ -158,16 +158,19 @@
         window.centerWindowOnScreen = this.centerWindowOnScreen;
       ]]>
       </constructor>
 
       <method name="postLoadInit">
         <parameter name="aEvent"/>
         <body>
         <![CDATA[
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+
           function focusInit() {
             const dialog = document.documentElement;
             const defaultButton = dialog.getButton(dialog.defaultButton);
             // give focus to the first focusable element in the dialog
             if (!document.commandDispatcher.focusedElement) {
               document.commandDispatcher.advanceFocusIntoSubtree(dialog);
 
               var focusedElt = document.commandDispatcher.focusedElement;
@@ -183,21 +186,20 @@
 
                 if (initialFocusedElt.localName == "tab") {
                   if (focusedElt.hasAttribute("dlgtype")) {
                     // We don't want to focus on anonymous OK, Cancel, etc. buttons,
                     // so return focus to the tab itself
                     initialFocusedElt.focus();
                   }
                 }
-#ifndef XP_MACOSX
-                else if (focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
+                else if (AppConstants.platform != "macosx" &&
+                         focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
                   defaultButton.focus();
                 }
-#endif
               }
             }
 
             try {
               if (defaultButton)
                 window.notifyDefaultButtonLoaded(defaultButton);
             } catch (e) { }
           }
@@ -304,23 +306,24 @@
                           disclosure: false, extra1: false, extra2: false };
             for (i = 0; i < list.length; ++i)
               shown[list[i].replace(/ /g, "")] = true;
 
             // hide/show the buttons we want
             for (dlgtype in buttons) 
               buttons[dlgtype].hidden = !shown[dlgtype];
 
-#ifdef XP_WIN
-#           show the spacer on Windows only when the extra2 button is present
-            var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
-            spacer.removeAttribute("hidden");
-            spacer.setAttribute("flex", shown["extra2"]?"1":"0");
-#endif
-
+            let { AppConstants } =
+                Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+            // show the spacer on Windows only when the extra2 button is present
+            if (AppConstants.platform == "win") {
+              var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
+              spacer.removeAttribute("hidden");
+              spacer.setAttribute("flex", shown["extra2"]?"1":"0");
+            }
           }
         ]]>
         </body>
       </method>
 
       <method name="_setDefaultButton">
         <parameter name="aNewDefault"/>
         <body>
--- a/toolkit/content/widgets/filefield.xml
+++ b/toolkit/content/widgets/filefield.xml
@@ -46,34 +46,35 @@
           return val;
         ]]>
         </setter>
       </property>      
       <method name="_getDisplayNameForFile">
         <parameter name="aFile"/>
         <body>
         <![CDATA[
-#ifdef XP_WIN
-          var lfw = aFile.QueryInterface(Components.interfaces.nsILocalFileWin);
-          try {
-            return lfw.getVersionInfoField("FileDescription"); 
-          }
-          catch (e) {
-            // fall through to the filename
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          if (AppConstants.platform == "win") {
+            var lfw = aFile.QueryInterface(Components.interfaces.nsILocalFileWin);
+            try {
+              return lfw.getVersionInfoField("FileDescription");
+            }
+            catch (e) {
+              // fall through to the filename
+            }
+          } else if (AppConstants.platform == "macosx") {
+            var lfm = aFile.QueryInterface(Components.interfaces.nsILocalFileMac);
+            try {
+              return lfm.bundleDisplayName;
+            }
+            catch (e) {
+              // fall through to the file name
+            }
           }
-#endif
-#ifdef XP_MACOSX
-          var lfm = aFile.QueryInterface(Components.interfaces.nsILocalFileMac);
-          try {
-            return lfm.bundleDisplayName;
-          }
-          catch (e) {
-            // fall through to the file name
-          }
-#endif
           var ios = Components.classes["@mozilla.org/network/io-service;1"]
                               .getService(Components.interfaces.nsIIOService);
           var url = ios.newFileURI(aFile).QueryInterface(Components.interfaces.nsIURL);
           return url.fileName;
         ]]>
         </body>
       </method>
       
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -29,21 +29,17 @@
 
       <method name="_handleEnter">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (this.findbar._findMode == this.findbar.FIND_NORMAL) {
             let findString = this.findbar._findField;
             if (!findString.value)
               return;
-#ifdef XP_MACOSX
-            if (aEvent.metaKey) {
-#else
-            if (aEvent.ctrlKey) {
-#endif
+            if (aEvent.getModifierState("Accel")) {
               this.findbar.getElement("highlight").click();
               return;
             }
 
             this.findbar.onFindAgainCommand(aEvent.shiftKey);
           } else {
             this.findbar._finishFAYT(aEvent);
           }
@@ -113,22 +109,24 @@
 
       <handler event="blur"><![CDATA[
         let findbar = this.findbar;
         // Note: This code used to remove the selection
         // if it matched an editable.
         findbar.browser.finder.enableSelection();
       ]]></handler>
 
-#ifdef XP_MACOSX
       <handler event="focus"><![CDATA[
-        let findbar = this.findbar;
-        findbar._onFindFieldFocus();
+        let { AppConstants } =
+            Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+        if (AppConstants.platform == "macosx") {
+          let findbar = this.findbar;
+          findbar._onFindFieldFocus();
+        }
       ]]></handler>
-#endif
 
       <handler event="compositionstart"><![CDATA[
         // Don't close the find toolbar while IME is composing.
         let findbar = this.findbar;
         findbar._isIMEComposing = true;
         if (findbar._quickFindTimeout) {
           clearTimeout(findbar._quickFindTimeout);
           findbar._quickFindTimeout = null;
@@ -1205,23 +1203,23 @@
         <parameter name="aSelectionString" />
         <parameter name="aIsInitialSelection" />
         <body><![CDATA[
           // Ignore the prefill if the user has already typed in the findbar,
           // it would have been overwritten anyway. See bug 1198465.
           if (aIsInitialSelection && !this._startFindDeferred)
             return;
 
-#ifdef XP_MACOSX
-          if (aIsInitialSelection && !aSelectionString) {
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          if (AppConstants.platform == "macosx" && aIsInitialSelection && !aSelectionString) {
             let clipboardSearchString = this.browser.finder.clipboardSearchString;
             if (clipboardSearchString)
               aSelectionString = clipboardSearchString;
           }
-#endif
 
           if (aSelectionString)
             this._findField.value = aSelectionString;
 
           if (aIsInitialSelection) {
             this._enableFindButtons(!!this._findField.value);
             this._findField.select();
             this._findField.focus();
--- a/toolkit/content/widgets/listbox.xml
+++ b/toolkit/content/widgets/listbox.xml
@@ -961,21 +961,20 @@
     <handlers>
       <!-- If there is no modifier key, we select on mousedown, not
            click, so that drags work correctly. -->
       <handler event="mousedown">
       <![CDATA[
         var control = this.control;
         if (!control || control.disabled)
           return;
-        if ((!event.ctrlKey
-#ifdef XP_MACOSX
-             || event.button == 2
-#endif
-            ) && !event.shiftKey && !event.metaKey) {
+        let { AppConstants } =
+            Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+        if ((!event.ctrlKey || (AppConstants.platform == "macosx" && event.button == 2)) &&
+            !event.shiftKey && !event.metaKey) {
           if (!this.selected) {
             control.selectItem(this);
           }
           control.currentItem = this;
         }
       ]]>
       </handler>
 
--- a/toolkit/content/widgets/preferences.xml
+++ b/toolkit/content/widgets/preferences.xml
@@ -626,29 +626,32 @@
                                  .getService(Components.interfaces.nsIPrefBranch);
             this.instantApply = psvc.getBoolPref("browser.preferences.instantApply");
           }
           if (this.instantApply) {
             var docElt = document.documentElement;
             var acceptButton = docElt.getButton("accept");
             acceptButton.hidden = true;
             var cancelButton  = docElt.getButton("cancel");
-#ifdef XP_MACOSX
-            // no buttons on Mac except Help
-            cancelButton.hidden = true;
-            // Move Help button to the end
-            document.getAnonymousElementByAttribute(this, "anonid", "spacer").hidden = true;         
-            // Also, don't fire onDialogAccept on enter
-            acceptButton.disabled = true;
-#else
-            // morph the Cancel button into the Close button
-            cancelButton.setAttribute ("icon", "close");
-            cancelButton.label = docElt.getAttribute("closebuttonlabel");
-            cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey");
-#endif
+
+            let { AppConstants } =
+                Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+            if (AppConstants.platform == "macosx") {
+              // no buttons on Mac except Help
+              cancelButton.hidden = true;
+              // Move Help button to the end
+              document.getAnonymousElementByAttribute(this, "anonid", "spacer").hidden = true;         
+              // Also, don't fire onDialogAccept on enter
+              acceptButton.disabled = true;
+            } else {
+              // morph the Cancel button into the Close button
+              cancelButton.setAttribute ("icon", "close");
+              cancelButton.label = docElt.getAttribute("closebuttonlabel");
+              cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey");
+            }
           }
         }
         this.setAttribute("animated", this._shouldAnimate ? "true" : "false");
         var panes = this.preferencePanes;
 
         var lastPane = null;
         if (this.lastSelected) {
           lastPane = document.getElementById(this.lastSelected);
@@ -808,21 +811,23 @@
         </body>
       </method>
       
       <field name="_initialized">false</field>
       <method name="_selectPane">
         <parameter name="aPaneElement"/>
         <body>
         <![CDATA[
-#ifdef XP_MACOSX
-          var paneTitle = aPaneElement.label;
-          if (paneTitle != "")
-            document.title = paneTitle;
-#endif
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          if (AppConstants.platform == "macosx") {
+            var paneTitle = aPaneElement.label;
+            if (paneTitle != "")
+              document.title = paneTitle;
+          }
           var helpButton = document.documentElement.getButton("help");
           if (aPaneElement.helpTopic)
             helpButton.hidden = false;
           else
             helpButton.hidden = true;
 
           // Find this pane's index in the deck and set the deck's 
           // selectedIndex to that value to switch to it.
@@ -882,23 +887,21 @@
           }
         ]]>
         </body>
       </method>
       
       <property name="_shouldAnimate">
         <getter>
         <![CDATA[
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
           var psvc = Components.classes["@mozilla.org/preferences-service;1"]
                                .getService(Components.interfaces.nsIPrefBranch);
-#ifdef XP_MACOSX
-          var animate = true;
-#else
-          var animate = false;
-#endif
+          var animate = AppConstants.platform == "macosx";
           try {
             animate = psvc.getBoolPref("browser.preferences.animateFadeIn");
           }
           catch (e) { }
           return animate;
         ]]>
         </getter>
       </property>
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -504,18 +504,21 @@
         </body>
       </method>
 
       <method name="purgeSessionHistory">
         <body>
           <![CDATA[
             try {
               this.messageManager.sendAsyncMessage("Browser:PurgeSessionHistory");
-            } catch (ex if ex.result == Components.results.NS_ERROR_NOT_INITIALIZED) {
+            } catch (ex) {
               // This can throw if the browser has started to go away.
+              if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED) {
+                throw ex;
+              }
             }
             this.webNavigation.canGoBack = false;
             this.webNavigation.canGoForward = false;
           ]]>
         </body>
       </method>
     </implementation>
 
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -42,21 +42,21 @@
         <getter>
         <![CDATA[
           return (this.getAttribute("handleCtrlPageUpDown") != "false");
         ]]>
         </getter>
       </property>
 
       <field name="_handleMetaAltArrows" readonly="true">
-#ifdef XP_MACOSX
-        true
-#else
-        false
-#endif
+        {
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          AppConstants.platform == "macosx";
+        }
       </field>
 
       <!-- _tabs and _tabpanels are deprecated, they exist only for
            backwards compatibility. -->
       <property name="_tabs" readonly="true" onget="return this.tabs;"/>
       <property name="_tabpanels" readonly="true" onget="return this.tabpanels;"/>
 
       <property name="tabs" readonly="true">
@@ -767,21 +767,21 @@
           }
         ]]></body>
       </method>
 
       <property name="linkedPanel" onget="return this.getAttribute('linkedpanel')"
                                    onset="this.setAttribute('linkedpanel', val); return val;"/>
 
       <field name="arrowKeysShouldWrap" readonly="true">
-#ifdef XP_MACOSX
-        true
-#else
-        false
-#endif
+        {
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          AppConstants.platform == "macosx";
+        }
       </field>
       <field name="TelemetryStopwatch" readonly="true">
         {
           let tmp = {};
           Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", tmp);
           tmp.TelemetryStopwatch;
         }
       </field>
--- a/toolkit/content/widgets/tree.xml
+++ b/toolkit/content/widgets/tree.xml
@@ -17,22 +17,17 @@
   <binding id="tree-base" extends="chrome://global/content/bindings/general.xml#basecontrol">
     <resources>
       <stylesheet src="chrome://global/skin/tree.css"/>
     </resources>
     <implementation>
       <method name="_isAccelPressed">
         <parameter name="aEvent"/>
         <body><![CDATA[
-# Workaround until bug 302174 is fixed
-#ifdef XP_MACOSX
-          return aEvent.metaKey;
-#else
-          return aEvent.ctrlKey;
-#endif
+          return aEvent.getModifierState("Accel");
         ]]></body>
       </method>
     </implementation>
   </binding>
 
   <binding id="tree" extends="chrome://global/content/bindings/tree.xml#tree-base" role="xul:tree">
     <content hidevscroll="true" hidehscroll="true" clickthrough="never">
       <children includes="treecols"/>
@@ -88,21 +83,21 @@
       <property name="contentView"
                 onget="return this.view; /*.QueryInterface(Components.interfaces.nsITreeContentView)*/"
                 readonly="true"/>
 # builderView is obsolete (see bug 202393)
       <property name="builderView"
                 onget="return this.view; /*.QueryInterface(Components.interfaces.nsIXULTreeBuilder)*/"
                 readonly="true"/>
       <field name="pageUpOrDownMovesSelection">
-#ifdef XP_MACOSX
-        false
-#else
-        true
-#endif
+        {
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          AppConstants.platform != "macosx";
+        }
       </field>
       <property name="keepCurrentInView"
                 onget="return (this.getAttribute('keepcurrentinview') == 'true');"
                 onset="if (val) this.setAttribute('keepcurrentinview', 'true');
                        else this.removeAttribute('keepcurrentinview'); return val;"/>
 
       <property name="enableColumnDrag"
                 onget="return this.hasAttribute('enableColumnDrag');"
@@ -671,26 +666,28 @@
         <parameter name="event"/>
         <body><![CDATA[
           if (this._editingColumn) {
             this.stopEditing(true);
             this.focus();
             return true;
           }
 
-#ifdef XP_MACOSX
-          // See if we can edit the cell.
-          var row = this.currentIndex;
-          if (this._cellSelType) {
-            var column = this.view.selection.currentColumn;
-            var startedEditing = this.startEditing(row, column);
-            if (startedEditing)
-              return true;
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
+          if (AppConstants.platform == "macosx") {
+            // See if we can edit the cell.
+            var row = this.currentIndex;
+            if (this._cellSelType) {
+              var column = this.view.selection.currentColumn;
+              var startedEditing = this.startEditing(row, column);
+              if (startedEditing)
+                return true;
+            }
           }
-#endif
           return this.changeOpenState(this.currentIndex);
         ]]></body>
       </method>
     </implementation>
     
     <handlers>
       <handler event="MozMousePixelScroll" preventdefault="true"/>
       <handler event="DOMMouseScroll" preventdefault="true">
@@ -1415,22 +1412,22 @@
           }
         }
       ]]></handler>
       <handler event="click" button="0" phase="target">
         <![CDATA[
           if (event.target != event.originalTarget)
             return;
 
-#ifdef XP_WIN
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
           // On Windows multiple clicking on tree columns only cycles one time
           // every 2 clicks.
-          if (event.detail % 2 == 0)
+          if (AppConstants.platform == "win" && event.detail % 2 == 0)
             return;
-#endif
 
           var tree = this.parentNode.parentNode;
           var column = tree.columns.getColumnFor(this);
           tree.view.cycleHeader(column);
         ]]>
       </handler>
     </handlers>
   </binding>
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -789,26 +789,28 @@
                     // XXX Can't set increment here, due to bug 473103. Also, doing so causes
                     // snapping when dragging with the mouse, so we can't just set a value for
                     // the arrow-keys.
                     //this.scrubber.increment = duration / 50;
                     this.scrubber.pageIncrement = Math.round(duration / 10);
                 },
 
                 seekToPosition : function(newPosition) {
+                    let { AppConstants } =
+                        Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
                     newPosition /= 1000; // convert from ms
                     this.log("+++ seeking to " + newPosition);
-#ifdef MOZ_WIDGET_GONK
-                    // We use fastSeek() on B2G, and an accurate (but slower)
-                    // seek on other platforms (that are likely to be higher
-                    // perf).
-                    this.video.fastSeek(newPosition);
-#else
-                    this.video.currentTime = newPosition;
-#endif
+                    if (AppConstants.platform == "gonk") {
+                        // We use fastSeek() on B2G, and an accurate (but slower)
+                        // seek on other platforms (that are likely to be higher
+                        // perf).
+                        this.video.fastSeek(newPosition);
+                    } else {
+                        this.video.currentTime = newPosition;
+                    }
                 },
 
                 setVolume : function(newVolume) {
                     this.log("*** setting volume to " + newVolume);
                     this.video.volume = newVolume;
                     this.video.muted = false;
                 },
 
@@ -1247,32 +1249,34 @@
                     s.volume.textContent = volume;
                 },
 
                 keyHandler : function(event) {
                     // Ignore keys when content might be providing its own.
                     if (!this.video.hasAttribute("controls"))
                         return;
 
+                    let { AppConstants } =
+                        Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
                     var keystroke = "";
                     if (event.altKey)
                         keystroke += "alt-";
                     if (event.shiftKey)
                         keystroke += "shift-";
-#ifdef XP_MACOSX
-                    if (event.metaKey)
-                        keystroke += "accel-";
-                    if (event.ctrlKey)
-                        keystroke += "control-";
-#else
-                    if (event.metaKey)
-                        keystroke += "meta-";
-                    if (event.ctrlKey)
-                        keystroke += "accel-";
-#endif
+                    if (AppConstants.platform == "macosx") {
+                        if (event.metaKey)
+                            keystroke += "accel-";
+                        if (event.ctrlKey)
+                            keystroke += "control-";
+                    } else {
+                        if (event.metaKey)
+                            keystroke += "meta-";
+                        if (event.ctrlKey)
+                            keystroke += "accel-";
+                    }
 
                     switch (event.keyCode) {
                         case KeyEvent.DOM_VK_UP:
                             keystroke += "upArrow";
                             break;
                         case KeyEvent.DOM_VK_DOWN:
                             keystroke += "downArrow";
                             break;
--- a/toolkit/content/widgets/wizard.xml
+++ b/toolkit/content/widgets/wizard.xml
@@ -67,33 +67,32 @@
           if (!val)
             return val;
             
           this._currentPage = val;
 
           // Setting this attribute allows wizard's clients to dynamically
           // change the styles of each page based on purpose of the page. 
           this.setAttribute("currentpageid", val.pageid);
-                    
+
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {}); 
+
           if (this.onFirstPage) {
             this.canRewind = false;
             this.setAttribute("firstpage", "true");
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-            this._backButton.setAttribute('hidden', 'true');
-#endif
-#endif
+            if (AppConstants.XP_UNIX && AppConstants.platform != "macosx") {
+              this._backButton.setAttribute('hidden', 'true');
+            }
           } else {
             this.canRewind = true;
             this.setAttribute("firstpage", "false");
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-            this._backButton.setAttribute('hidden', 'false');
-#endif
-#endif
+            if (AppConstants.XP_UNIX && AppConstants.platform != "macosx") {
+              this._backButton.setAttribute('hidden', 'false');
+            }
           }
                     
           if (this.onLastPage) {
             this.canAdvance = true;
             this.setAttribute("lastpage", "true");
           } else {
             this.setAttribute("lastpage", "false");
           }
@@ -385,29 +384,32 @@
            this["_"+aName+"Button"] = btn;
          }
          return btn;
         ]]></body>
       </method>
 
       <method name="_adjustWizardHeader">
         <body><![CDATA[
+          let { AppConstants } =
+              Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
           var label = this.currentPage.getAttribute("label");
-          if (!label && this.onFirstPage && this._bundle)
-#ifdef XP_MACOSX
-            label = this._bundle.GetStringFromName("default-first-title-mac");
-#else
-            label = this._bundle.formatStringFromName("default-first-title", [this.title], 1);
-#endif
-          else if (!label && this.onLastPage && this._bundle)
-#ifdef XP_MACOSX
-            label = this._bundle.GetStringFromName("default-last-title-mac");
-#else
-            label = this._bundle.formatStringFromName("default-last-title", [this.title], 1);
-#endif
+          if (!label && this.onFirstPage && this._bundle) {
+            if (AppConstants.platform == "macosx") {
+              label = this._bundle.GetStringFromName("default-first-title-mac");
+            } else {
+              label = this._bundle.formatStringFromName("default-first-title", [this.title], 1);
+            }
+          } else if (!label && this.onLastPage && this._bundle) {
+            if (AppConstants.platform == "macosx") {
+              label = this._bundle.GetStringFromName("default-last-title-mac");
+            } else {
+              label = this._bundle.formatStringFromName("default-last-title", [this.title], 1);
+            }
+          }
           this._wizardHeader.setAttribute("label", label);
           this._wizardHeader.setAttribute("description", this.currentPage.getAttribute("description"));
         ]]></body>
       </method>
 
       <method name="_hitEnter">
         <parameter name="evt"/>
         <body>
--- a/toolkit/modules/AppConstants.jsm
+++ b/toolkit/modules/AppConstants.jsm
@@ -132,16 +132,23 @@ this.AppConstants = Object.freeze({
 # MOZ_B2G covers both device and desktop b2g
   MOZ_B2G:
 #ifdef MOZ_B2G
   true,
 #else
   false,
 #endif
 
+  XP_UNIX:
+#ifdef XP_UNIX
+  true,
+#else
+  false,
+#endif
+
 # NOTE! XP_LINUX has to go after MOZ_WIDGET_ANDROID otherwise Android
 # builds will be misidentified as linux.
   platform:
 #ifdef MOZ_WIDGET_GTK
   "linux",
 #elif MOZ_WIDGET_QT
   "linux",
 #elif XP_WIN