mozilla-kde.patch
branchfirefox69
changeset 1106 6c6375987b6c
parent 1099 8a3c73e74e65
child 1112 8a4f5aea2475
equal deleted inserted replaced
1105:611baabe5b83 1106:6c6375987b6c
     1 # HG changeset patch
     1 # HG changeset patch
     2 # User msirringhaus@suse.de
     2 # User msirringhaus@suse.de
     3 # Date 1559294891 -7200
     3 # Date 1559294891 -7200
     4 #      Fri May 31 11:28:11 2019 +0200
     4 #      Fri May 31 11:28:11 2019 +0200
     5 # Node ID c2aa7198fb925e7fde96abf65b6f68b9b755f112
     5 # Node ID c2aa7198fb925e7fde96abf65b6f68b9b755f112
     6 # Parent  93495ad6fa0fe292eadcbfef14e0e27273528497
     6 # Parent  85e4798b74da9c377f84cf8f5dd59a7f952d92eb
     7 Description: Add KDE integration to Firefox (toolkit parts)
     7 Description: Add KDE integration to Firefox (toolkit parts)
     8 Author: Wolfgang Rosenauer <wolfgang@rosenauer.org>
     8 Author: Wolfgang Rosenauer <wolfgang@rosenauer.org>
     9 Author: Lubos Lunak <lunak@suse.com>
     9 Author: Lubos Lunak <lunak@suse.com>
    10 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751
    10 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751
    11      https://bugzilla.novell.com/show_bug.cgi?id=170055
    11      https://bugzilla.novell.com/show_bug.cgi?id=170055
    12 
    12 
    13 diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
    13 diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
    14 --- a/modules/libpref/Preferences.cpp
    14 --- a/modules/libpref/Preferences.cpp
    15 +++ b/modules/libpref/Preferences.cpp
    15 +++ b/modules/libpref/Preferences.cpp
    16 @@ -81,16 +81,17 @@
    16 @@ -83,16 +83,17 @@
    17  #include "nsXPCOMCID.h"
       
    18  #include "nsXPCOM.h"
    17  #include "nsXPCOM.h"
    19  #include "nsXULAppAPI.h"
    18  #include "nsXULAppAPI.h"
    20  #include "nsZipArchive.h"
    19  #include "nsZipArchive.h"
    21  #include "plbase64.h"
    20  #include "plbase64.h"
    22  #include "PLDHashTable.h"
    21  #include "PLDHashTable.h"
    23  #include "plstr.h"
    22  #include "plstr.h"
    24  #include "prlink.h"
    23  #include "prlink.h"
       
    24  #include "xpcpublic.h"
    25 +#include "nsKDEUtils.h"
    25 +#include "nsKDEUtils.h"
       
    26  
       
    27  #ifdef DEBUG
       
    28  #  include <map>
       
    29  #endif
    26  
    30  
    27  #ifdef MOZ_MEMORY
    31  #ifdef MOZ_MEMORY
    28  #  include "mozmemory.h"
    32  #  include "mozmemory.h"
    29  #endif
    33  #endif
    30  
    34 @@ -4623,25 +4624,37 @@ Result<Ok, const char*> Preferences::Ini
    31  #ifdef XP_WIN
       
    32  #  include "windows.h"
       
    33  #endif
       
    34 @@ -4507,25 +4508,37 @@ static nsresult pref_ReadDefaultPrefs(co
       
    35    // application pref files for backwards compatibility.
    35    // application pref files for backwards compatibility.
    36    static const char* specialFiles[] = {
    36    static const char* specialFiles[] = {
    37  #if defined(XP_MACOSX)
    37  #if defined(XP_MACOSX)
    38      "macprefs.js"
    38      "macprefs.js"
    39  #elif defined(XP_WIN)
    39  #elif defined(XP_WIN)
    67      NS_WARNING("Error parsing application default preferences.");
    67      NS_WARNING("Error parsing application default preferences.");
    68    }
    68    }
    69  
    69  
    70    // Load jar:$app/omni.jar!/defaults/preferences/*.js
    70    // Load jar:$app/omni.jar!/defaults/preferences/*.js
    71    // or jar:$gre/omni.jar!/defaults/preferences/*.js.
    71    // or jar:$gre/omni.jar!/defaults/preferences/*.js.
    72 @@ -4573,17 +4586,17 @@ static nsresult pref_ReadDefaultPrefs(co
    72 @@ -4688,17 +4701,17 @@ Result<Ok, const char*> Preferences::Ini
    73        }
    73        }
    74  
    74  
    75        nsCOMPtr<nsIFile> path = do_QueryInterface(elem);
    75        nsCOMPtr<nsIFile> path = do_QueryInterface(elem);
    76        if (!path) {
    76        if (!path) {
    77          continue;
    77          continue;
   113  FINAL_LIBRARY = 'xul'
   113  FINAL_LIBRARY = 'xul'
   114  
   114  
   115 diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py
   115 diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py
   116 --- a/python/mozbuild/mozpack/chrome/flags.py
   116 --- a/python/mozbuild/mozpack/chrome/flags.py
   117 +++ b/python/mozbuild/mozpack/chrome/flags.py
   117 +++ b/python/mozbuild/mozpack/chrome/flags.py
   118 @@ -223,16 +223,17 @@ class Flags(OrderedDict):
   118 @@ -227,16 +227,17 @@ class Flags(OrderedDict):
   119          'contentaccessible': Flag,
   119          'contentaccessible': Flag,
   120          'os': StringFlag,
   120          'os': StringFlag,
   121          'osversion': VersionFlag,
   121          'osversion': VersionFlag,
   122          'abi': StringFlag,
   122          'abi': StringFlag,
   123          'platform': Flag,
   123          'platform': Flag,
   134             flags = Flags('contentaccessible=yes', 'appversion>=3.5')
   134             flags = Flags('contentaccessible=yes', 'appversion>=3.5')
   135          '''
   135          '''
   136 diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py
   136 diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py
   137 --- a/python/mozbuild/mozpack/chrome/manifest.py
   137 --- a/python/mozbuild/mozpack/chrome/manifest.py
   138 +++ b/python/mozbuild/mozpack/chrome/manifest.py
   138 +++ b/python/mozbuild/mozpack/chrome/manifest.py
   139 @@ -39,16 +39,17 @@ class ManifestEntry(object):
   139 @@ -36,16 +36,17 @@ class ManifestEntry(object):
   140          'platformversion',
   140          'platformversion',
   141          'os',
   141          'os',
   142          'osversion',
   142          'osversion',
   143          'abi',
   143          'abi',
   144          'xpcnativewrappers',
   144          'xpcnativewrappers',
   170 +    '/toolkit/xre'
   170 +    '/toolkit/xre'
   171 +]
   171 +]
   172 +
   172 +
   173  with Files('**'):
   173  with Files('**'):
   174      BUG_COMPONENT = ('Toolkit', 'Downloads API')
   174      BUG_COMPONENT = ('Toolkit', 'Downloads API')
   175 diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn
       
   176 --- a/toolkit/content/jar.mn
       
   177 +++ b/toolkit/content/jar.mn
       
   178 @@ -63,16 +63,18 @@ toolkit.jar:
       
   179     content/global/widgets.css
       
   180     content/global/bindings/autocomplete.xml    (widgets/autocomplete.xml)
       
   181     content/global/bindings/button.xml          (widgets/button.xml)
       
   182     content/global/bindings/calendar.js         (widgets/calendar.js)
       
   183     content/global/bindings/datekeeper.js       (widgets/datekeeper.js)
       
   184     content/global/bindings/datepicker.js       (widgets/datepicker.js)
       
   185     content/global/bindings/datetimebox.css     (widgets/datetimebox.css)
       
   186  *  content/global/bindings/dialog.xml          (widgets/dialog.xml)
       
   187 +*  content/global/bindings/dialog-kde.xml      (widgets/dialog-kde.xml)
       
   188 +% override chrome://global/content/bindings/dialog.xml chrome://global/content/bindings/dialog-kde.xml desktop=kde
       
   189     content/global/bindings/general.xml         (widgets/general.xml)
       
   190     content/global/bindings/popup.xml           (widgets/popup.xml)
       
   191     content/global/bindings/richlistbox.xml     (widgets/richlistbox.xml)
       
   192     content/global/bindings/scrollbox.xml       (widgets/scrollbox.xml)
       
   193     content/global/bindings/spinner.js          (widgets/spinner.js)
       
   194     content/global/bindings/tabbox.xml          (widgets/tabbox.xml)
       
   195  *  content/global/bindings/textbox.xml         (widgets/textbox.xml)
       
   196     content/global/bindings/timekeeper.js       (widgets/timekeeper.js)
       
   197 diff --git a/toolkit/content/widgets/dialog-kde.xml b/toolkit/content/widgets/dialog-kde.xml
       
   198 new file mode 100644
       
   199 --- /dev/null
       
   200 +++ b/toolkit/content/widgets/dialog-kde.xml
       
   201 @@ -0,0 +1,499 @@
       
   202 +<?xml version="1.0"?>
       
   203 +<!-- This Source Code Form is subject to the terms of the Mozilla Public
       
   204 +   - License, v. 2.0. If a copy of the MPL was not distributed with this
       
   205 +   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
       
   206 +
       
   207 +<!DOCTYPE bindings [
       
   208 +  <!ENTITY % globalKeysDTD SYSTEM "chrome://global/locale/globalKeys.dtd">
       
   209 +  %globalKeysDTD;
       
   210 +]>
       
   211 +
       
   212 +<bindings id="dialogBindings"
       
   213 +          xmlns="http://www.mozilla.org/xbl"
       
   214 +          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
       
   215 +          xmlns:xbl="http://www.mozilla.org/xbl">
       
   216 +
       
   217 +  <binding id="dialog">
       
   218 +    <content>
       
   219 +      <xul:vbox class="box-inherit dialog-content-box" flex="1">
       
   220 +        <children/>
       
   221 +      </xul:vbox>
       
   222 +
       
   223 +      <xul:hbox class="dialog-button-box" anonid="buttons"
       
   224 +                xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
       
   225 +#ifdef XP_UNIX_GNOME
       
   226 +                >
       
   227 +        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
       
   228 +        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
       
   229 +        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
       
   230 +        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
       
   231 +        <xul:spacer anonid="spacer" flex="1"/>
       
   232 +        <xul:button dlgtype="cancel" class="dialog-button"/>
       
   233 +        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
       
   234 +#elif XP_UNIX
       
   235 +                >
       
   236 +        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
       
   237 +        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
       
   238 +        <xul:spacer anonid="spacer" flex="1"/>
       
   239 +        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
       
   240 +        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
       
   241 +        <xul:button dlgtype="cancel" class="dialog-button"/>
       
   242 +        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
       
   243 +#else
       
   244 +                pack="end">
       
   245 +        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
       
   246 +        <xul:spacer anonid="spacer" flex="1" hidden="true"/>
       
   247 +        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
       
   248 +        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
       
   249 +        <xul:button dlgtype="cancel" class="dialog-button"/>
       
   250 +        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
       
   251 +        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
       
   252 +#endif
       
   253 +      </xul:hbox>
       
   254 +
       
   255 +    <xul:keyset>
       
   256 +      <xul:key phase="capturing" oncommand="document.documentElement.openHelp(event)"
       
   257 +#ifdef XP_MACOSX
       
   258 +           key="&openHelpMac.commandkey;" modifiers="accel"/>
       
   259 +#else
       
   260 +           keycode="&openHelp.commandkey;"/>
       
   261 +#endif
       
   262 +    </xul:keyset>
       
   263 +
       
   264 +    </content>
       
   265 +
       
   266 +    <implementation>
       
   267 +      <field name="_mStrBundle">null</field>
       
   268 +      <field name="_closeHandler">(function(event) {
       
   269 +        if (!document.documentElement.cancelDialog())
       
   270 +          event.preventDefault();
       
   271 +      })</field>
       
   272 +
       
   273 +      <!-- Gets populated by elements that are passed to document.l10n.setAttributes
       
   274 +           to localize the dialog buttons. Needed to properly size the dialog after
       
   275 +           the asynchronous translation. -->
       
   276 +      <field name="_l10nButtons">[]</field>
       
   277 +
       
   278 +      <property name="buttons"
       
   279 +                onget="return this.getAttribute('buttons');"
       
   280 +                onset="this._configureButtons(val); return val;"/>
       
   281 +
       
   282 +      <property name="defaultButton">
       
   283 +        <getter>
       
   284 +        <![CDATA[
       
   285 +          if (this.hasAttribute("defaultButton"))
       
   286 +            return this.getAttribute("defaultButton");
       
   287 +          return "accept"; // default to the accept button
       
   288 +        ]]>
       
   289 +        </getter>
       
   290 +        <setter>
       
   291 +        <![CDATA[
       
   292 +          this._setDefaultButton(val);
       
   293 +          return val;
       
   294 +        ]]>
       
   295 +        </setter>
       
   296 +      </property>
       
   297 +
       
   298 +      <method name="acceptDialog">
       
   299 +        <body>
       
   300 +        <![CDATA[
       
   301 +          return this._doButtonCommand("accept");
       
   302 +        ]]>
       
   303 +        </body>
       
   304 +      </method>
       
   305 +
       
   306 +      <method name="cancelDialog">
       
   307 +        <body>
       
   308 +        <![CDATA[
       
   309 +          return this._doButtonCommand("cancel");
       
   310 +        ]]>
       
   311 +        </body>
       
   312 +      </method>
       
   313 +
       
   314 +      <method name="getButton">
       
   315 +        <parameter name="aDlgType"/>
       
   316 +        <body>
       
   317 +        <![CDATA[
       
   318 +          return this._buttons[aDlgType];
       
   319 +        ]]>
       
   320 +        </body>
       
   321 +      </method>
       
   322 +
       
   323 +      <method name="moveToAlertPosition">
       
   324 +        <body>
       
   325 +        <![CDATA[
       
   326 +          // hack. we need this so the window has something like its final size
       
   327 +          if (window.outerWidth == 1) {
       
   328 +            dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n");
       
   329 +            sizeToContent();
       
   330 +          }
       
   331 +
       
   332 +          if (opener) {
       
   333 +            var xOffset = (opener.outerWidth - window.outerWidth) / 2;
       
   334 +            var yOffset = opener.outerHeight / 5;
       
   335 +
       
   336 +            var newX = opener.screenX + xOffset;
       
   337 +            var newY = opener.screenY + yOffset;
       
   338 +          } else {
       
   339 +            newX = (screen.availWidth - window.outerWidth) / 2;
       
   340 +            newY = (screen.availHeight - window.outerHeight) / 2;
       
   341 +          }
       
   342 +
       
   343 +          // ensure the window is fully onscreen (if smaller than the screen)
       
   344 +          if (newX < screen.availLeft)
       
   345 +            newX = screen.availLeft + 20;
       
   346 +          if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth))
       
   347 +            newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20;
       
   348 +
       
   349 +          if (newY < screen.availTop)
       
   350 +            newY = screen.availTop + 20;
       
   351 +          if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight))
       
   352 +            newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60;
       
   353 +
       
   354 +          window.moveTo( newX, newY );
       
   355 +        ]]>
       
   356 +        </body>
       
   357 +      </method>
       
   358 +
       
   359 +      <method name="centerWindowOnScreen">
       
   360 +        <body>
       
   361 +        <![CDATA[
       
   362 +          var xOffset = screen.availWidth / 2 - window.outerWidth / 2;
       
   363 +          var yOffset = screen.availHeight / 2 - window.outerHeight / 2;
       
   364 +
       
   365 +          xOffset = xOffset > 0 ? xOffset : 0;
       
   366 +          yOffset = yOffset > 0 ? yOffset : 0;
       
   367 +          window.moveTo(xOffset, yOffset);
       
   368 +        ]]>
       
   369 +        </body>
       
   370 +      </method>
       
   371 +
       
   372 +      <constructor>
       
   373 +      <![CDATA[
       
   374 +        this._configureButtons(this.buttons);
       
   375 +
       
   376 +        // listen for when window is closed via native close buttons
       
   377 +        window.addEventListener("close", this);
       
   378 +
       
   379 +        // for things that we need to initialize after onload fires
       
   380 +        window.addEventListener("load", this);
       
   381 +
       
   382 +        window.moveToAlertPosition = this.moveToAlertPosition;
       
   383 +        window.centerWindowOnScreen = this.centerWindowOnScreen;
       
   384 +      ]]>
       
   385 +      </constructor>
       
   386 +
       
   387 +      <method name="handleEvent">
       
   388 +        <parameter name="aEvent"/>
       
   389 +        <body><![CDATA[
       
   390 +          switch (aEvent.type) {
       
   391 +            case "close": {
       
   392 +              this._closeHandler(aEvent);
       
   393 +              break;
       
   394 +            }
       
   395 +            case "load": {
       
   396 +              this.postLoadInit(aEvent);
       
   397 +              break;
       
   398 +            }
       
   399 +          }
       
   400 +        ]]></body>
       
   401 +      </method>
       
   402 +
       
   403 +      <method name="postLoadInit">
       
   404 +        <parameter name="aEvent"/>
       
   405 +        <body>
       
   406 +        <![CDATA[
       
   407 +          function focusInit() {
       
   408 +            const dialog = document.documentElement;
       
   409 +            const defaultButton = dialog.getButton(dialog.defaultButton);
       
   410 +            // give focus to the first focusable element in the dialog
       
   411 +            if (!document.commandDispatcher.focusedElement) {
       
   412 +              document.commandDispatcher.advanceFocusIntoSubtree(dialog);
       
   413 +
       
   414 +              var focusedElt = document.commandDispatcher.focusedElement;
       
   415 +              if (focusedElt) {
       
   416 +                var initialFocusedElt = focusedElt;
       
   417 +                while (focusedElt.localName == "tab" ||
       
   418 +                       focusedElt.getAttribute("noinitialfocus") == "true") {
       
   419 +                  document.commandDispatcher.advanceFocusIntoSubtree(focusedElt);
       
   420 +                  focusedElt = document.commandDispatcher.focusedElement;
       
   421 +                  if (focusedElt == initialFocusedElt) {
       
   422 +                    if (focusedElt.getAttribute("noinitialfocus") == "true") {
       
   423 +                      focusedElt.blur();
       
   424 +                    }
       
   425 +                    break;
       
   426 +                  }
       
   427 +                }
       
   428 +
       
   429 +                if (initialFocusedElt.localName == "tab") {
       
   430 +                  if (focusedElt.hasAttribute("dlgtype")) {
       
   431 +                    // We don't want to focus on anonymous OK, Cancel, etc. buttons,
       
   432 +                    // so return focus to the tab itself
       
   433 +                    initialFocusedElt.focus();
       
   434 +                  }
       
   435 +                } else if (!/Mac/.test(navigator.platform) &&
       
   436 +                           focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
       
   437 +                  defaultButton.focus();
       
   438 +                }
       
   439 +              }
       
   440 +            }
       
   441 +
       
   442 +            try {
       
   443 +              if (defaultButton)
       
   444 +                window.notifyDefaultButtonLoaded(defaultButton);
       
   445 +            } catch (e) { }
       
   446 +          }
       
   447 +
       
   448 +          // Give focus after onload completes, see bug 103197.
       
   449 +          setTimeout(focusInit, 0);
       
   450 +
       
   451 +          if (this._l10nButtons.length) {
       
   452 +            document.l10n.translateElements(this._l10nButtons).then(() => {
       
   453 +              window.sizeToContent();
       
   454 +            });
       
   455 +          }
       
   456 +        ]]>
       
   457 +        </body>
       
   458 +      </method>
       
   459 +
       
   460 +      <method name="openHelp">
       
   461 +        <parameter name="event"/>
       
   462 +        <body>
       
   463 +        <![CDATA[
       
   464 +          var helpButton = document.documentElement.getButton("help");
       
   465 +          if (helpButton.disabled || helpButton.hidden)
       
   466 +            return;
       
   467 +          this._fireButtonEvent("help");
       
   468 +          event.stopPropagation();
       
   469 +          event.preventDefault();
       
   470 +        ]]>
       
   471 +        </body>
       
   472 +      </method>
       
   473 +
       
   474 +      <property name="mStrBundle">
       
   475 +        <getter>
       
   476 +        <![CDATA[
       
   477 +          if (!this._mStrBundle) {
       
   478 +            // need to create string bundle manually instead of using <xul:stringbundle/>
       
   479 +            // see bug 63370 for details
       
   480 +            this._mStrBundle = Cc["@mozilla.org/intl/stringbundle;1"]
       
   481 +                                 .getService(Ci.nsIStringBundleService)
       
   482 +                                 .createBundle("chrome://global/locale/dialog.properties");
       
   483 +          }
       
   484 +          return this._mStrBundle;
       
   485 +        ]]></getter>
       
   486 +      </property>
       
   487 +
       
   488 +      <method name="_configureButtons">
       
   489 +        <parameter name="aButtons"/>
       
   490 +        <body>
       
   491 +        <![CDATA[
       
   492 +          // by default, get all the anonymous button elements
       
   493 +          var buttons = {};
       
   494 +          this._buttons = buttons;
       
   495 +          buttons.accept = document.getAnonymousElementByAttribute(this, "dlgtype", "accept");
       
   496 +          buttons.cancel = document.getAnonymousElementByAttribute(this, "dlgtype", "cancel");
       
   497 +          buttons.extra1 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra1");
       
   498 +          buttons.extra2 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra2");
       
   499 +          buttons.help = document.getAnonymousElementByAttribute(this, "dlgtype", "help");
       
   500 +          buttons.disclosure = document.getAnonymousElementByAttribute(this, "dlgtype", "disclosure");
       
   501 +
       
   502 +          for (let button in buttons) {
       
   503 +            customElements.upgrade(buttons[button]);
       
   504 +          }
       
   505 +
       
   506 +          // look for any overriding explicit button elements
       
   507 +          var exBtns = this.getElementsByAttribute("dlgtype", "*");
       
   508 +          var dlgtype;
       
   509 +          var i;
       
   510 +          for (i = 0; i < exBtns.length; ++i) {
       
   511 +            dlgtype = exBtns[i].getAttribute("dlgtype");
       
   512 +            buttons[dlgtype].hidden = true; // hide the anonymous button
       
   513 +            buttons[dlgtype] = exBtns[i];
       
   514 +          }
       
   515 +
       
   516 +          // add the label and oncommand handler to each button
       
   517 +          for (dlgtype in buttons) {
       
   518 +            var button = buttons[dlgtype];
       
   519 +            button.addEventListener("command", this._handleButtonCommand, true);
       
   520 +
       
   521 +            // don't override custom labels with pre-defined labels on explicit buttons
       
   522 +            if (!button.hasAttribute("label")) {
       
   523 +              // dialog attributes override the default labels in dialog.properties
       
   524 +              if (this.hasAttribute("buttonlabel" + dlgtype)) {
       
   525 +                button.setAttribute("label", this.getAttribute("buttonlabel" + dlgtype));
       
   526 +                if (this.hasAttribute("buttonaccesskey" + dlgtype))
       
   527 +                  button.setAttribute("accesskey", this.getAttribute("buttonaccesskey" + dlgtype));
       
   528 +              } else if (this.hasAttribute("buttonid" + dlgtype)) {
       
   529 +                document.l10n.setAttributes(button, this.getAttribute("buttonid" + dlgtype));
       
   530 +                this._l10nButtons.push(button);
       
   531 +              } else if (dlgtype != "extra1" && dlgtype != "extra2") {
       
   532 +                button.setAttribute("label", this.mStrBundle.GetStringFromName("button-" + dlgtype));
       
   533 +                var accessKey = this.mStrBundle.GetStringFromName("accesskey-" + dlgtype);
       
   534 +                if (accessKey)
       
   535 +                  button.setAttribute("accesskey", accessKey);
       
   536 +              }
       
   537 +            }
       
   538 +            // allow specifying alternate icons in the dialog header
       
   539 +            if (!button.hasAttribute("icon")) {
       
   540 +              // if there's an icon specified, use that
       
   541 +              if (this.hasAttribute("buttonicon" + dlgtype))
       
   542 +                button.setAttribute("icon", this.getAttribute("buttonicon" + dlgtype));
       
   543 +              // otherwise set defaults
       
   544 +              else
       
   545 +                switch (dlgtype) {
       
   546 +                  case "accept":
       
   547 +                    button.setAttribute("icon", "accept");
       
   548 +                    break;
       
   549 +                  case "cancel":
       
   550 +                    button.setAttribute("icon", "cancel");
       
   551 +                    break;
       
   552 +                  case "disclosure":
       
   553 +                    button.setAttribute("icon", "properties");
       
   554 +                    break;
       
   555 +                  case "help":
       
   556 +                    button.setAttribute("icon", "help");
       
   557 +                    break;
       
   558 +                  default:
       
   559 +                    break;
       
   560 +                }
       
   561 +            }
       
   562 +          }
       
   563 +
       
   564 +          // ensure that hitting enter triggers the default button command
       
   565 +          this.defaultButton = this.defaultButton;
       
   566 +
       
   567 +          // if there is a special button configuration, use it
       
   568 +          if (aButtons) {
       
   569 +            // expect a comma delimited list of dlgtype values
       
   570 +            var list = aButtons.split(",");
       
   571 +
       
   572 +            // mark shown dlgtypes as true
       
   573 +            var shown = { accept: false, cancel: false, help: false,
       
   574 +                          disclosure: false, extra1: false, extra2: false };
       
   575 +            for (i = 0; i < list.length; ++i)
       
   576 +              shown[list[i].replace(/ /g, "")] = true;
       
   577 +
       
   578 +            // hide/show the buttons we want
       
   579 +            for (dlgtype in buttons)
       
   580 +              buttons[dlgtype].hidden = !shown[dlgtype];
       
   581 +
       
   582 +            // show the spacer on Windows only when the extra2 button is present
       
   583 +            if (/Win/.test(navigator.platform)) {
       
   584 +              var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
       
   585 +              spacer.removeAttribute("hidden");
       
   586 +              spacer.setAttribute("flex", shown.extra2 ? "1" : "0");
       
   587 +            }
       
   588 +          }
       
   589 +        ]]>
       
   590 +        </body>
       
   591 +      </method>
       
   592 +
       
   593 +      <method name="_setDefaultButton">
       
   594 +        <parameter name="aNewDefault"/>
       
   595 +        <body>
       
   596 +        <![CDATA[
       
   597 +          // remove the default attribute from the previous default button, if any
       
   598 +          var oldDefaultButton = this.getButton(this.defaultButton);
       
   599 +          if (oldDefaultButton)
       
   600 +            oldDefaultButton.removeAttribute("default");
       
   601 +
       
   602 +          var newDefaultButton = this.getButton(aNewDefault);
       
   603 +          if (newDefaultButton) {
       
   604 +            this.setAttribute("defaultButton", aNewDefault);
       
   605 +            newDefaultButton.setAttribute("default", "true");
       
   606 +          } else {
       
   607 +            this.setAttribute("defaultButton", "none");
       
   608 +            if (aNewDefault != "none")
       
   609 +              dump("invalid new default button: " + aNewDefault + ", assuming: none\n");
       
   610 +          }
       
   611 +        ]]>
       
   612 +        </body>
       
   613 +      </method>
       
   614 +
       
   615 +      <method name="_handleButtonCommand">
       
   616 +        <parameter name="aEvent"/>
       
   617 +        <body>
       
   618 +        <![CDATA[
       
   619 +          return document.documentElement._doButtonCommand(
       
   620 +                                        aEvent.target.getAttribute("dlgtype"));
       
   621 +        ]]>
       
   622 +        </body>
       
   623 +      </method>
       
   624 +
       
   625 +      <method name="_doButtonCommand">
       
   626 +        <parameter name="aDlgType"/>
       
   627 +        <body>
       
   628 +        <![CDATA[
       
   629 +          var button = this.getButton(aDlgType);
       
   630 +          if (!button.disabled) {
       
   631 +            var noCancel = this._fireButtonEvent(aDlgType);
       
   632 +            if (noCancel) {
       
   633 +              if (aDlgType == "accept" || aDlgType == "cancel") {
       
   634 +                var closingEvent = new CustomEvent("dialogclosing", {
       
   635 +                  bubbles: true,
       
   636 +                  detail: { button: aDlgType },
       
   637 +                });
       
   638 +                this.dispatchEvent(closingEvent);
       
   639 +                window.close();
       
   640 +              }
       
   641 +            }
       
   642 +            return noCancel;
       
   643 +          }
       
   644 +          return true;
       
   645 +        ]]>
       
   646 +        </body>
       
   647 +      </method>
       
   648 +
       
   649 +      <method name="_fireButtonEvent">
       
   650 +        <parameter name="aDlgType"/>
       
   651 +        <body>
       
   652 +        <![CDATA[
       
   653 +          var event = document.createEvent("Events");
       
   654 +          event.initEvent("dialog" + aDlgType, true, true);
       
   655 +
       
   656 +          // handle dom event handlers
       
   657 +          return this.dispatchEvent(event);
       
   658 +        ]]>
       
   659 +        </body>
       
   660 +      </method>
       
   661 +
       
   662 +      <method name="_hitEnter">
       
   663 +        <parameter name="evt"/>
       
   664 +        <body>
       
   665 +        <![CDATA[
       
   666 +          if (evt.defaultPrevented)
       
   667 +            return;
       
   668 +
       
   669 +          var btn = this.getButton(this.defaultButton);
       
   670 +          if (btn)
       
   671 +            this._doButtonCommand(this.defaultButton);
       
   672 +        ]]>
       
   673 +        </body>
       
   674 +      </method>
       
   675 +
       
   676 +    </implementation>
       
   677 +
       
   678 +    <handlers>
       
   679 +      <handler event="keypress" keycode="VK_RETURN"
       
   680 +               group="system" action="this._hitEnter(event);"/>
       
   681 +      <handler event="keypress" keycode="VK_ESCAPE" group="system">
       
   682 +        if (!event.defaultPrevented)
       
   683 +          this.cancelDialog();
       
   684 +      </handler>
       
   685 +#ifdef XP_MACOSX
       
   686 +      <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/>
       
   687 +#else
       
   688 +      <handler event="focus" phase="capturing">
       
   689 +        var btn = this.getButton(this.defaultButton);
       
   690 +        if (btn)
       
   691 +          btn.setAttribute("default", event.originalTarget == btn ||
       
   692 +                           !(event.originalTarget.localName == "button" ||
       
   693 +                             event.originalTarget.localName == "toolbarbutton"));
       
   694 +      </handler>
       
   695 +#endif
       
   696 +    </handlers>
       
   697 +
       
   698 +  </binding>
       
   699 +
       
   700 +</bindings>
       
   701 diff --git a/toolkit/mozapps/downloads/HelperAppDlg.jsm b/toolkit/mozapps/downloads/HelperAppDlg.jsm
   175 diff --git a/toolkit/mozapps/downloads/HelperAppDlg.jsm b/toolkit/mozapps/downloads/HelperAppDlg.jsm
   702 --- a/toolkit/mozapps/downloads/HelperAppDlg.jsm
   176 --- a/toolkit/mozapps/downloads/HelperAppDlg.jsm
   703 +++ b/toolkit/mozapps/downloads/HelperAppDlg.jsm
   177 +++ b/toolkit/mozapps/downloads/HelperAppDlg.jsm
   704 @@ -1204,36 +1204,66 @@ nsUnknownContentTypeDialog.prototype = {
   178 @@ -1204,36 +1204,66 @@ nsUnknownContentTypeDialog.prototype = {
   705          params.handlerApp &&
   179          params.handlerApp &&
  1819        NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?");
  1293        NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?");
  1820        gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions));
  1294        gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions));
  1821 diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
  1295 diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
  1822 --- a/widget/gtk/moz.build
  1296 --- a/widget/gtk/moz.build
  1823 +++ b/widget/gtk/moz.build
  1297 +++ b/widget/gtk/moz.build
  1824 @@ -124,16 +124,17 @@ include('/ipc/chromium/chromium-config.m
  1298 @@ -126,16 +126,17 @@ include('/ipc/chromium/chromium-config.m
  1825  
  1299  
  1826  FINAL_LIBRARY = 'xul'
  1300  FINAL_LIBRARY = 'xul'
  1827  
  1301  
  1828  LOCAL_INCLUDES += [
  1302  LOCAL_INCLUDES += [
  1829      '/layout/base',
  1303      '/layout/base',
  1840          '/widget/x11',
  1314          '/widget/x11',
  1841      ]
  1315      ]
  1842 diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
  1316 diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
  1843 --- a/widget/gtk/nsFilePicker.cpp
  1317 --- a/widget/gtk/nsFilePicker.cpp
  1844 +++ b/widget/gtk/nsFilePicker.cpp
  1318 +++ b/widget/gtk/nsFilePicker.cpp
  1845 @@ -4,32 +4,34 @@
  1319 @@ -4,16 +4,17 @@
  1846   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  1320   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  1847  
  1321  
  1848  #include "mozilla/Types.h"
  1322  #include "mozilla/Types.h"
  1849  #include <sys/types.h>
  1323  #include <sys/types.h>
  1850  #include <sys/stat.h>
  1324  #include <sys/stat.h>
  1853  #include <gtk/gtk.h>
  1327  #include <gtk/gtk.h>
  1854 +#include <gdk/gdkx.h>
  1328 +#include <gdk/gdkx.h>
  1855  
  1329  
  1856  #include "nsGtkUtils.h"
  1330  #include "nsGtkUtils.h"
  1857  #include "nsIFileURL.h"
  1331  #include "nsIFileURL.h"
       
  1332  #include "nsIGIOService.h"
  1858  #include "nsIURI.h"
  1333  #include "nsIURI.h"
  1859  #include "nsIWidget.h"
  1334  #include "nsIWidget.h"
  1860  #include "nsIFile.h"
  1335  #include "nsIFile.h"
  1861  #include "nsIStringBundle.h"
  1336  #include "nsIStringBundle.h"
  1862  
  1337 @@ -21,16 +22,17 @@
  1863  #include "nsArrayEnumerator.h"
  1338  #include "nsArrayEnumerator.h"
  1864  #include "nsMemory.h"
  1339  #include "nsMemory.h"
  1865  #include "nsEnumeratorUtils.h"
  1340  #include "nsEnumeratorUtils.h"
  1866  #include "nsNetUtil.h"
  1341  #include "nsNetUtil.h"
  1867  #include "nsReadableUtils.h"
  1342  #include "nsReadableUtils.h"
  1875  #define MAX_PREVIEW_SIZE 180
  1350  #define MAX_PREVIEW_SIZE 180
  1876  // bug 1184009
  1351  // bug 1184009
  1877  #define MAX_PREVIEW_SOURCE_SIZE 4096
  1352  #define MAX_PREVIEW_SOURCE_SIZE 4096
  1878  
  1353  
  1879  nsIFile* nsFilePicker::mPrevDisplayDirectory = nullptr;
  1354  nsIFile* nsFilePicker::mPrevDisplayDirectory = nullptr;
  1880 @@ -227,17 +229,19 @@ nsFilePicker::AppendFilters(int32_t aFil
  1355 @@ -228,17 +230,19 @@ nsFilePicker::AppendFilters(int32_t aFil
  1881    mAllowURLs = !!(aFilterMask & filterAllowURLs);
  1356    mAllowURLs = !!(aFilterMask & filterAllowURLs);
  1882    return nsBaseFilePicker::AppendFilters(aFilterMask);
  1357    return nsBaseFilePicker::AppendFilters(aFilterMask);
  1883  }
  1358  }
  1884  
  1359  
  1885  NS_IMETHODIMP
  1360  NS_IMETHODIMP
  1896    CopyUTF16toUTF8(aFilter, filter);
  1371    CopyUTF16toUTF8(aFilter, filter);
  1897    CopyUTF16toUTF8(aTitle, name);
  1372    CopyUTF16toUTF8(aTitle, name);
  1898  
  1373  
  1899    mFilters.AppendElement(filter);
  1374    mFilters.AppendElement(filter);
  1900    mFilterNames.AppendElement(name);
  1375    mFilterNames.AppendElement(name);
  1901 @@ -337,16 +341,39 @@ nsresult nsFilePicker::Show(int16_t* aRe
  1376 @@ -338,16 +342,39 @@ nsresult nsFilePicker::Show(int16_t* aRe
  1902    return NS_OK;
  1377    return NS_OK;
  1903  }
  1378  }
  1904  
  1379  
  1905  NS_IMETHODIMP
  1380  NS_IMETHODIMP
  1906  nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
  1381  nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
  1936    GtkWindow* parent_widget =
  1411    GtkWindow* parent_widget =
  1937        GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
  1412        GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
  1938  
  1413  
  1939    GtkFileChooserAction action = GetGtkFileChooserAction(mMode);
  1414    GtkFileChooserAction action = GetGtkFileChooserAction(mMode);
  1940  
  1415  
  1941 @@ -572,16 +599,240 @@ void nsFilePicker::Done(void* file_choos
  1416 @@ -573,16 +600,240 @@ void nsFilePicker::Done(void* file_choos
  1942      mCallback->Done(result);
  1417      mCallback->Done(result);
  1943      mCallback = nullptr;
  1418      mCallback = nullptr;
  1944    } else {
  1419    } else {
  1945      mResult = result;
  1420      mResult = result;
  1946    }
  1421    }