diff -r caf81a228fff browser/app/profile/firefox.js
--- a/browser/app/profile/firefox.js	Mon Jun 06 11:22:45 2011 +1000
+++ b/browser/app/profile/firefox.js	Wed Jun 22 16:29:45 2011 +0200
@@ -204,6 +204,7 @@
 pref("extensions.dss.enabled", false);          // Dynamic Skin Switching                                               
 pref("extensions.dss.switchPending", false);    // Non-dynamic switch pending after next
                                                 // restart.
+pref("extensions.closeOnEscape", false); // allow the escape key to close the add-ons manager if it is standalone
 
 pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name", "chrome://browser/locale/browser.properties");
 pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description", "chrome://browser/locale/browser.properties");
diff -r caf81a228fff caps/src/nsScriptSecurityManager.cpp
--- a/caps/src/nsScriptSecurityManager.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/caps/src/nsScriptSecurityManager.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -1545,6 +1545,7 @@
                              &hasFlags);
     NS_ENSURE_SUCCESS(rv, rv);
     if (hasFlags) {
+        return NS_OK;
         // resource: and chrome: are equivalent, securitywise
         // That's bogus!!  Fix this.  But watch out for
         // the view-source stylesheet?
diff -r caf81a228fff content/base/public/nsIDocumentEncoder.idl
--- a/content/base/public/nsIDocumentEncoder.idl	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/public/nsIDocumentEncoder.idl	Wed Jun 22 16:29:45 2011 +0200
@@ -237,6 +237,11 @@
   const unsigned long OutputFormatDelSp  = (1 << 20);
  
   /**
+   * Output all non-ascii characters as numeric entities
+   */
+  const unsigned long OutputEncodeCharacterEntities = (1 << 21);
+
+  /**
    * Initialize with a pointer to the document and the mime type.
    * @param aDocument Document to encode.
    * @param aMimeType MimeType to use. May also be set by SetMimeType.
diff -r caf81a228fff content/base/src/nsCopySupport.cpp
--- a/content/base/src/nsCopySupport.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/src/nsCopySupport.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -436,7 +436,7 @@
   // copy it properly (all the copy code for non-plaintext assumes using HTML
   // serializers and parsers is OK, and those mess up XHTML).
   nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aDoc);
-  if (!(htmlDoc && aDoc->IsHTML()))
+  if (!htmlDoc)
     *aIsPlainTextContext = PR_TRUE;
 
   return NS_OK;
diff -r caf81a228fff content/base/src/nsDocumentEncoder.cpp
--- a/content/base/src/nsDocumentEncoder.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/src/nsDocumentEncoder.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -1333,7 +1333,7 @@
   
   // also consider ourselves in a text widget if we can't find an html document
   nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
-  if (!(htmlDoc && mDocument->IsHTML()))
+  if (!htmlDoc)
     mIsTextWidget = PR_TRUE;
   
   // normalize selection if we are not in a widget
diff -r caf81a228fff content/base/src/nsHTMLContentSerializer.cpp
--- a/content/base/src/nsHTMLContentSerializer.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/src/nsHTMLContentSerializer.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -270,14 +270,15 @@
 
   PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(ns, name);
 
-  if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) {
+  if (((mDoFormat || forceFormat) && !mPreLevel) || mDoRaw) {
     if (mColPos && lineBreakBeforeOpen) {
       AppendNewLineToString(aStr);
+      mMayIgnoreLineBreakSequence = PR_FALSE;
     }
     else {
       MaybeAddNewlineForRootNode(aStr);
     }
-    if (!mColPos) {
+    if (!mColPos && !mDoRaw) {
       AppendIndentation(aStr);
     }
     else if (mAddSpace) {
@@ -545,7 +546,8 @@
   PRBool nonBasicEntities =
     !!(mFlags & (nsIDocumentEncoder::OutputEncodeLatin1Entities |
                  nsIDocumentEncoder::OutputEncodeHTMLEntities   |
-                 nsIDocumentEncoder::OutputEncodeW3CEntities));
+                 nsIDocumentEncoder::OutputEncodeW3CEntities    |
+                 nsIDocumentEncoder::OutputEncodeCharacterEntities));
 
   if (!nonBasicEntities &&
       (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities))) {
@@ -601,7 +603,13 @@
       // needs to be replaced
       for (; c < fragmentEnd; c++, advanceLength++) {
         PRUnichar val = *c;
-        if (val <= kValNBSP && entityTable[val]) {
+        if ((val == kValNBSP || val > 127) &&
+            (mFlags & nsIDocumentEncoder::OutputEncodeCharacterEntities)) {
+          nsAutoString entityValue(PRUnichar('#'));
+          entityValue.AppendInt(val);
+          entityText = ToNewCString(entityValue);
+		break;
+        } else if (val <= kValNBSP && entityTable[val]) {
           fullConstEntityText = entityTable[val];
           break;
         } else if (val > 127 &&
diff -r caf81a228fff content/base/src/nsXHTMLContentSerializer.cpp
--- a/content/base/src/nsXHTMLContentSerializer.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/src/nsXHTMLContentSerializer.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -761,14 +761,23 @@
     return mAddSpace;
   }
 
-  if (aName == nsGkAtoms::title ||
+  if (// aName == nsGkAtoms::title ||
       aName == nsGkAtoms::meta  ||
-      aName == nsGkAtoms::link  ||
-      aName == nsGkAtoms::style ||
+      //aName == nsGkAtoms::link  ||
+      //aName == nsGkAtoms::style ||
       aName == nsGkAtoms::select ||
       aName == nsGkAtoms::option ||
       aName == nsGkAtoms::script ||
-      aName == nsGkAtoms::html) {
+      aName == nsGkAtoms::html ||
+      aName == nsGkAtoms::head ||
+      //aName == nsGkAtoms::body ||
+      aName == nsGkAtoms::table ||
+      aName == nsGkAtoms::caption ||
+      aName == nsGkAtoms::tbody ||
+      aName == nsGkAtoms::thead ||
+      aName == nsGkAtoms::tfoot ||
+      aName == nsGkAtoms::tr ||
+      aName == nsGkAtoms::td) {
     return PR_TRUE;
   }
   else {
@@ -795,7 +804,7 @@
 
   if ((aName == nsGkAtoms::html) ||
       (aName == nsGkAtoms::head) ||
-      (aName == nsGkAtoms::body) ||
+      //(aName == nsGkAtoms::body) ||
       (aName == nsGkAtoms::ul) ||
       (aName == nsGkAtoms::ol) ||
       (aName == nsGkAtoms::dl) ||
@@ -832,7 +841,10 @@
       (aName == nsGkAtoms::dl) ||
       (aName == nsGkAtoms::select) ||
       (aName == nsGkAtoms::table) ||
-      (aName == nsGkAtoms::tbody)) {
+      (aName == nsGkAtoms::tbody) ||
+      (aName == nsGkAtoms::thead) ||
+      (aName == nsGkAtoms::tfoot) ||
+      (aName == nsGkAtoms::tr)) {
     return PR_TRUE;
   }
   return PR_FALSE;
@@ -897,6 +909,8 @@
       name == nsGkAtoms::noframes
       ) {
     mPreLevel++;
+    if (name != nsGkAtoms::pre)
+      ++mDisableEntityEncoding;
   }
 }
 
@@ -915,6 +929,8 @@
       name == nsGkAtoms::noframes
     ) {
     --mPreLevel;
+    if (name != nsGkAtoms::pre)
+      --mDisableEntityEncoding;
   }
 }
 
@@ -1034,3 +1050,4 @@
 
   return PR_TRUE;
 }
+
diff -r caf81a228fff content/base/src/nsXMLContentSerializer.cpp
--- a/content/base/src/nsXMLContentSerializer.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/content/base/src/nsXMLContentSerializer.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -61,6 +61,7 @@
 #include "prprf.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
+#include "nsIParserService.h"
 #include "nsContentUtils.h"
 #include "nsAttrName.h"
 #include "nsILineBreaker.h"
@@ -652,7 +653,25 @@
   PRBool rawAppend = mDoRaw && aDoEscapeEntities;
   nsAString& attrString = (rawAppend) ? aStr : attrString_;
 
-  attrString.Append(PRUnichar(' '));
+  if (mColPos + 1 >= mMaxColumn) {
+    if (mPreLevel > 0 || mDoRaw) {
+      AppendToStringConvertLF(mLineBreak, aStr);
+    }
+    else if (mDoFormat) {
+      AppendToStringFormatedWrapped(mLineBreak, aStr);
+      AppendIndentation(aStr);
+    }
+    else if (mDoWrap) {
+      AppendToStringWrapped(mLineBreak, aStr);
+      AppendIndentation(aStr);
+    }
+    else {
+      AppendToStringConvertLF(mLineBreak, aStr);
+    }
+  }
+  else
+    attrString.Append(PRUnichar(' '));
+
   if (!aPrefix.IsEmpty()) {
     attrString.Append(aPrefix);
     attrString.Append(PRUnichar(':'));
@@ -726,6 +745,8 @@
     attrString.Append(sValue);
     attrString.Append(cDelimiter);
   }
+  AppendToStringConvertLF(attrString, aStr);
+  /* XXX
   if (mPreLevel > 0 || mDoRaw) {
     AppendToStringConvertLF(attrString, aStr);
   }
@@ -738,6 +759,7 @@
   else {
     AppendToStringConvertLF(attrString, aStr);
   }
+  */
 }
 
 PRUint32 
@@ -942,7 +964,7 @@
   nsIAtom *name = content->Tag();
   PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name);
 
-  if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) {
+  if (((mDoFormat || forceFormat) && !mPreLevel) || mDoRaw) {
     if (mColPos && lineBreakBeforeOpen) {
       AppendNewLineToString(aStr);
     }
@@ -1189,6 +1211,21 @@
     return;
   }
   mColPos += aStr.Length();
+  nsASingleFragmentString::const_char_iterator pos, end, sequenceStart;
+
+  aStr.BeginReading(pos);
+  aStr.EndReading(end);
+  PRBool foundOtherThanCR = PR_FALSE;
+  while (!foundOtherThanCR && pos < end) {
+    if (*pos != '\n' && *pos != '\r') {
+      foundOtherThanCR = PR_TRUE;
+    }
+    pos++;
+  }
+
+  if (!foundOtherThanCR) {
+    mMayIgnoreLineBreakSequence = PR_TRUE;
+  }
   aOutputStr.Append(aStr);
 }
 
@@ -1299,6 +1336,10 @@
 void
 nsXMLContentSerializer::AppendNewLineToString(nsAString& aStr)
 {
+  if (!mPreLevel && mMayIgnoreLineBreakSequence) {
+    mMayIgnoreLineBreakSequence = PR_FALSE;
+    return;
+  }
   AppendToString(mLineBreak, aStr);
   mMayIgnoreLineBreakSequence = PR_TRUE;
   mColPos = 0;
@@ -1340,7 +1381,39 @@
 PRBool
 nsXMLContentSerializer::LineBreakBeforeOpen(PRInt32 aNamespaceID, nsIAtom* aName)
 {
-  return mAddSpace;
+    if (aNamespaceID != kNameSpaceID_XHTML) {
+      return mAddSpace;
+    }
+
+    if (aName == nsGkAtoms::title ||
+        aName == nsGkAtoms::meta  ||
+        aName == nsGkAtoms::link  ||
+        aName == nsGkAtoms::style ||
+        aName == nsGkAtoms::select ||
+        aName == nsGkAtoms::option ||
+        aName == nsGkAtoms::script ||
+        aName == nsGkAtoms::html ||
+        aName == nsGkAtoms::table ||
+        aName == nsGkAtoms::caption ||
+        aName == nsGkAtoms::tbody ||
+        aName == nsGkAtoms::thead ||
+        aName == nsGkAtoms::tfoot ||
+        aName == nsGkAtoms::tr ||
+        aName == nsGkAtoms::td) {
+      return PR_TRUE;
+    }
+    else {
+      nsIParserService* parserService = nsContentUtils::GetParserService();
+
+      if (parserService) {
+        PRBool res;
+        parserService->
+          IsBlock(parserService->HTMLCaseSensitiveAtomTagToId(aName), res);
+        return res;
+      }
+    }
+
+    return mAddSpace;
 }
 
 PRBool 
@@ -1352,7 +1425,39 @@
 PRBool 
 nsXMLContentSerializer::LineBreakBeforeClose(PRInt32 aNamespaceID, nsIAtom* aName)
 {
-  return mAddSpace;
+    if (aNamespaceID != kNameSpaceID_XHTML) {
+      return mAddSpace;
+    }
+
+    if (aName == nsGkAtoms::title ||
+        aName == nsGkAtoms::meta  ||
+        aName == nsGkAtoms::link  ||
+        aName == nsGkAtoms::style ||
+        aName == nsGkAtoms::select ||
+        aName == nsGkAtoms::option ||
+        aName == nsGkAtoms::script ||
+        aName == nsGkAtoms::html ||
+        aName == nsGkAtoms::table ||
+        aName == nsGkAtoms::caption ||
+        aName == nsGkAtoms::tbody ||
+        aName == nsGkAtoms::thead ||
+        aName == nsGkAtoms::tfoot ||
+        aName == nsGkAtoms::tr ||
+        aName == nsGkAtoms::td) {
+      return PR_TRUE;
+    }
+    else {
+      nsIParserService* parserService = nsContentUtils::GetParserService();
+
+      if (parserService) {
+        PRBool res;
+        parserService->
+          IsBlock(parserService->HTMLCaseSensitiveAtomTagToId(aName), res);
+        return res;
+      }
+    }
+
+    return mAddSpace;
 }
 
 PRBool 
@@ -1468,6 +1573,7 @@
       // Since we only saw linebreaks, but no spaces or tabs,
       // let's write a linebreak now.
       AppendNewLineToString(aOutputStr);
+      mMayIgnoreLineBreakSequence = PR_TRUE;
     }
   }
 }
diff -r caf81a228fff editor/libeditor/html/nsHTMLDataTransfer.cpp
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -1390,13 +1390,43 @@
         textDataObj->GetData(text);
         NS_ASSERTION(text.Length() <= (len/2), "Invalid length!");
         stuffToPaste.Assign(text.get(), len / 2);
+
+        // Find where the <body> tag starts.
+        nsReadingIterator<PRUnichar> beginbody;
+        nsReadingIterator<PRUnichar> endbody;
+        stuffToPaste.BeginReading(beginbody);
+        stuffToPaste.EndReading(endbody);
+        PRBool foundbody = CaseInsensitiveFindInReadable(NS_LITERAL_STRING("<body"),
+                                                         beginbody, endbody);
+        nsAutoString realStuffToPaste;
+        if (foundbody) {
+          nsReadingIterator<PRUnichar> endstartbody;
+          stuffToPaste.EndReading(endstartbody);
+          PRBool foundstartbody = CaseInsensitiveFindInReadable(NS_LITERAL_STRING(">"),
+                                                                endbody, endstartbody);
+          if (!foundstartbody)
+            return NS_ERROR_FAILURE;
+
+          nsReadingIterator<PRUnichar> beginclosebody;
+          nsReadingIterator<PRUnichar> endclosebody;
+          stuffToPaste.BeginReading(beginclosebody);
+          stuffToPaste.EndReading(endclosebody);
+
+          // Find the index before "</body>"
+          PRBool foundclosehead = CaseInsensitiveFindInReadable(
+                   NS_LITERAL_STRING("</body>"), beginclosebody, endclosebody);
+          realStuffToPaste.Assign(Substring(endstartbody, beginclosebody));
+        }
+        else
+          realStuffToPaste.Assign(stuffToPaste);
         nsAutoEditBatch beginBatching(this);
-        rv = DoInsertHTMLWithContext(stuffToPaste,
+        rv = DoInsertHTMLWithContext(realStuffToPaste,
                                      aContextStr, aInfoStr, flavor,
                                      aSourceDoc,
                                      aDestinationNode, aDestOffset,
                                      aDoDeleteSelection,
-                                     isSafe);
+                                     //isSafe);
+                                     true);
       }
     }
     else if (0 == nsCRT::strcmp(bestFlavor, kUnicodeMime) ||
diff -r caf81a228fff editor/libeditor/html/nsHTMLEditRules.cpp
--- a/editor/libeditor/html/nsHTMLEditRules.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -1428,39 +1428,8 @@
     // it is to search for both tabs and newlines.
     if (isPRE || IsPlaintextEditor())
     {
-      while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
-      {
-        PRInt32 oldPos = pos;
-        PRInt32 subStrLen;
-        pos = tString.FindChar(nsCRT::LF, oldPos);
-
-        if (pos != -1) 
-        {
-          subStrLen = pos - oldPos;
-          // if first char is newline, then use just it
-          if (subStrLen == 0)
-            subStrLen = 1;
-        }
-        else
-        {
-          subStrLen = tString.Length() - oldPos;
-          pos = tString.Length();
-        }
-
-        nsDependentSubstring subStr(tString, oldPos, subStrLen);
-        
-        // is it a return?
-        if (subStr.Equals(newlineStr))
-        {
-          res = mHTMLEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
-          pos++;
-        }
-        else
-        {
-          res = mHTMLEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
-        }
-        NS_ENSURE_SUCCESS(res, res);
-      }
+      res = mHTMLEditor->InsertTextImpl(tString, address_of(curNode), &curOffset, doc);
+      NS_ENSURE_SUCCESS(res, res);
     }
     else
     {
diff -r caf81a228fff editor/libeditor/html/nsHTMLEditor.cpp
--- a/editor/libeditor/html/nsHTMLEditor.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/editor/libeditor/html/nsHTMLEditor.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -322,7 +322,8 @@
 
     if (!IsInteractionAllowed()) {
       // ignore any errors from this in case the file is missing
-      AddOverrideStyleSheet(NS_LITERAL_STRING("resource://gre/res/EditorOverride.css"));
+      // BlueGriffon uses its own EditorOverride.css
+      //AddOverrideStyleSheet(NS_LITERAL_STRING("resource://gre/res/EditorOverride.css"));
     }
 
     nsCOMPtr<nsISelection>selection;
diff -r caf81a228fff toolkit/mozapps/extensions/content/extensions.js
--- a/toolkit/mozapps/extensions/content/extensions.js	Mon Jun 06 11:22:45 2011 +1000
+++ b/toolkit/mozapps/extensions/content/extensions.js	Wed Jun 22 16:29:45 2011 +0200
@@ -57,6 +57,7 @@
 const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled";
 const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden";
 const PREF_UI_LASTCATEGORY = "extensions.ui.lastCategory";
+const PREF_CLOSE_ADDONS_MANAGER_ON_ESCAPE = "extensions.closeOnEscape";
 
 const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
 
@@ -115,6 +116,18 @@
 
 function initialize() {
   document.removeEventListener("load", initialize, true);
+
+ // should we allow the window to close when the user hits the ESC key?
+ let closeOnEscape = false; // default for Firefox 4+
+ try {
+   closeOnEscape = Services.prefs.getBoolPref(PREF_CLOSE_ADDONS_MANAGER_ON_ESCAPE);
+ } catch(e) { }
+ if (!closeOnEscape) {
+   let escapeKeyElt = document.getElementById("escapeKey");
+   if (escapeKeyElt)
+     escapeKeyElt.setAttribute("disabled", "true");
+ }
+
   gViewController.initialize();
   gCategories.initialize();
   gHeader.initialize();
@@ -2451,7 +2464,7 @@
 
     for (let i = 0; i < this._listBox.itemCount; i++) {
       let item = this._listBox.childNodes[i];
-      if (item[prop] == aObj) {
+      if (prop in item && item[prop] == aObj) {
         this._listBox.removeChild(item);
         this.showEmptyNotice(this._listBox.itemCount == 0);
         return;
diff -r caf81a228fff toolkit/mozapps/extensions/content/extensions.xul
--- a/toolkit/mozapps/extensions/content/extensions.xul	Mon Jun 06 11:22:45 2011 +1000
+++ b/toolkit/mozapps/extensions/content/extensions.xul	Wed Jun 22 16:29:45 2011 +0200
@@ -65,6 +65,10 @@
   <script type="application/javascript"
           src="chrome://global/content/contentAreaUtils.js"/>
 
+  <keyset>
+    <key id="escapeKey" keycode="VK_ESCAPE" oncommand="window.close()"/>
+  </keyset>
+
   <popupset>
     <!-- menu for an addon item -->
     <menupopup id="addonitem-popup">
diff -r caf81a228fff widget/src/cocoa/nsMenuItemX.mm
--- a/widget/src/cocoa/nsMenuItemX.mm	Mon Jun 06 11:22:45 2011 +1000
+++ b/widget/src/cocoa/nsMenuItemX.mm	Wed Jun 22 16:29:45 2011 +0200
@@ -284,8 +284,31 @@
       nsAutoString modifiersStr;
       keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::modifiers, modifiersStr);
       PRUint8 modifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
+      unsigned int macModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(modifiers);
 
-      unsigned int macModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(modifiers);
+      // If we're empty, try the keyCode instead.
+      if (keyChar.Equals(NS_LITERAL_STRING(" ")) || keyChar.IsEmpty()) {
+
+        keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::keycode, keyChar);
+
+        if (keyChar.Equals(NS_LITERAL_STRING("VK_F2"))) {
+          unichar ch[1];
+          ch[0] = NSF2FunctionKey;
+          macModifiers |= NSFunctionKeyMask;
+          [mNativeMenuItem setKeyEquivalentModifierMask:macModifiers];
+          [mNativeMenuItem setKeyEquivalent:[NSString stringWithCharacters:ch length:1]];
+          return;
+        }
+        else if (keyChar.Equals(NS_LITERAL_STRING("VK_F4"))) {
+          unichar ch[1];
+          ch[0] = NSF4FunctionKey;
+          macModifiers |= NSFunctionKeyMask;
+          [mNativeMenuItem setKeyEquivalentModifierMask:macModifiers];
+          [mNativeMenuItem setKeyEquivalent:[NSString stringWithCharacters:ch length:1]];
+          return;
+        }
+      }
+
       [mNativeMenuItem setKeyEquivalentModifierMask:macModifiers];
 
       NSString *keyEquivalent = [[NSString stringWithCharacters:(unichar*)keyChar.get()
diff -r caf81a228fff widget/src/gtk2/nsWindow.cpp
--- a/widget/src/gtk2/nsWindow.cpp	Mon Jun 06 11:22:45 2011 +1000
+++ b/widget/src/gtk2/nsWindow.cpp	Wed Jun 22 16:29:45 2011 +0200
@@ -3986,6 +3986,8 @@
                 gdk_window_add_filter(mShell->window,
                                       popup_take_focus_filter, NULL); 
 #endif
+                // XXX BlueGriffon ugly hack to work around bug 662770
+                gtk_window_set_modal(GTK_WINDOW(mShell), TRUE);
             }
 
             GdkWindowTypeHint gtkTypeHint;
diff -r caf81a228fff widget/src/xpwidgets/nsWidgetAtomList.h
--- a/widget/src/xpwidgets/nsWidgetAtomList.h	Mon Jun 06 11:22:45 2011 +1000
+++ b/widget/src/xpwidgets/nsWidgetAtomList.h	Wed Jun 22 16:29:45 2011 +0200
@@ -85,6 +85,7 @@
 WIDGET_ATOM(input, "input")
 WIDGET_ATOM(indeterminate, "indeterminate")
 WIDGET_ATOM(key, "key") // The key element / attribute
+WIDGET_ATOM(keycode, "keycode")
 WIDGET_ATOM(label, "label")
 WIDGET_ATOM(max, "max")
 WIDGET_ATOM(maxpos, "maxpos")
