Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Mon, 12 Mar 2012 12:27:40 -0700
changeset 106019 60fb46e7940cdbf645d2ac84b0ac3b7ec2bc4add
parent 106018 bf6acad353e0265602c9c5ce866cc9bef41a56eb (current diff)
parent 88855 c6f26a8dcd084c38f63c282ba77c713c7573e549 (diff)
child 106020 79b5d9b66d9a68117abbda7f3a8ed87fb99d52ce
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.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
Merge from mozilla-central.
accessible/src/base/AccEvent.cpp
accessible/src/base/AccEvent.h
accessible/src/base/Makefile.in
accessible/src/base/TextAttrs.cpp
accessible/src/base/TextAttrs.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsTextAttrs.cpp
accessible/src/base/nsTextAttrs.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/xpcom/nsAccEvent.cpp
accessible/tests/mochitest/common.js
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/tabbrowser.xml
browser/components/nsBrowserGlue.js
browser/devtools/jar.mn
browser/locales/en-US/chrome/browser/browser.properties
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsDOMFile.h
content/base/public/nsIDOMFileError.idl
content/base/public/nsIDOMFileReader.idl
content/base/public/nsIDocument.h
content/base/public/nsIScriptElement.h
content/base/src/nsAttrValue.cpp
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMFileReader.cpp
content/base/src/nsDOMFileReader.h
content/base/src/nsDocument.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsImageLoadingContent.cpp
content/base/src/nsImageLoadingContent.h
content/base/src/nsScriptLoader.cpp
content/base/src/nsScriptLoader.h
content/base/src/nsStyleLinkElement.cpp
content/base/test/Makefile.in
content/canvas/src/CustomQS_WebGL.h
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/test/test_canvas.html
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLLinkElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLOptGroupElement.cpp
content/html/content/src/nsHTMLOptionElement.h
content/html/content/src/nsHTMLScriptElement.cpp
content/html/content/src/nsHTMLStyleElement.cpp
content/html/document/src/nsHTMLDocument.cpp
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGScriptElement.cpp
content/svg/content/src/nsSVGStyleElement.cpp
content/svg/content/src/nsSVGSwitchElement.cpp
content/svg/content/src/nsSVGSwitchElement.h
content/xbl/src/nsXBLPrototypeHandler.cpp
content/xslt/src/base/txStringUtils.h
content/xslt/src/xpath/txExprParser.cpp
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xpath/txResultRecycler.cpp
content/xslt/src/xpath/txResultRecycler.h
content/xslt/src/xslt/txMozillaXMLOutput.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
docshell/base/nsDefaultURIFixup.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsIScriptContext.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsJSTimeoutHandler.cpp
dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
dom/src/storage/nsDOMStorage.cpp
dom/system/nsDeviceMotion.cpp
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ImageLayers.h
gfx/layers/basic/BasicLayers.cpp
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/thebes/gfxWindowsPlatform.cpp
image/public/imgIContainer.idl
image/src/DiscardTracker.cpp
image/src/RasterImage.cpp
image/src/RasterImage.h
image/src/VectorImage.cpp
image/src/VectorImage.h
image/src/imgFrame.cpp
image/src/imgFrame.h
image/src/imgRequestProxy.cpp
image/test/mochitest/Makefile.in
intl/uconv/ucvcn/nsGBKToUnicode.cpp
js/src/configure.in
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsgc.cpp
js/src/jsgcinlines.h
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobjinlines.h
js/src/jsscope.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/LoopState.cpp
js/src/vm/Debugger.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsBlockReflowState.cpp
layout/generic/nsBlockReflowState.h
layout/generic/nsFrame.cpp
layout/generic/nsLineBox.cpp
layout/generic/nsLineBox.h
layout/generic/nsObjectFrame.cpp
layout/generic/nsSelection.cpp
layout/mathml/mathml.css
layout/svg/base/src/nsISVGChildFrame.h
layout/svg/base/src/nsSVGClipPathFrame.cpp
layout/svg/base/src/nsSVGClipPathFrame.h
layout/svg/base/src/nsSVGContainerFrame.cpp
layout/svg/base/src/nsSVGContainerFrame.h
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.cpp
layout/svg/base/src/nsSVGInnerSVGFrame.cpp
layout/svg/base/src/nsSVGMarkerFrame.cpp
layout/svg/base/src/nsSVGMarkerFrame.h
layout/svg/base/src/nsSVGMaskFrame.cpp
layout/svg/base/src/nsSVGMaskFrame.h
layout/svg/base/src/nsSVGPaintServerFrame.h
layout/svg/base/src/nsSVGPathGeometryFrame.cpp
layout/svg/base/src/nsSVGPatternFrame.cpp
layout/svg/base/src/nsSVGTextFrame.cpp
layout/tools/reftest/reftest.js
layout/xul/base/src/nsBoxFrame.cpp
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable/background.png
modules/freetype2/docs/GPL.TXT
modules/freetype2/docs/PATENTS
modules/freetype2/docs/TRUETYPE
modules/freetype2/docs/UPGRADE.UNIX
modules/freetype2/docs/reference/.gitignore
modules/freetype2/include/freetype/internal/pcftypes.h
modules/freetype2/moz_ft_shim.c
modules/freetype2/src/gzip/ChangeLog.moz
modules/libpref/src/init/all.js
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
security/manager/ssl/src/nsNSSComponent.cpp
services/sync/tests/unit/head_http_server.js
services/sync/tests/unit/test_jpakeclient.js
storage/src/mozStorageAsyncStatementExecution.cpp
testing/xpcshell/xpcshell.ini
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/content/license.html
toolkit/mozapps/update/nsUpdateService.js
widget/cocoa/nsNativeThemeCocoa.mm
xpcom/base/nsStackWalk.cpp
--- a/accessible/public/nsIAccessibleEvent.idl
+++ b/accessible/public/nsIAccessibleEvent.idl
@@ -566,8 +566,31 @@ interface nsIAccessibleTableChangeEvent:
   readonly attribute long rowOrColIndex;
 
   /**
    * Return the number of rows or cols
    */
   readonly attribute long numRowsOrCols;
 };
 
+
+/*
+ * An interface for virtual cursor changed events.
+ * Passes previous cursor position and text offsets.
+ */
+[scriptable, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
+interface nsIAccessibleVirtualCursorChangeEvent : nsISupports
+{
+  /**
+   * Previous object pointed at by virtual cursor. null if none.
+   */
+  readonly attribute nsIAccessible oldAccessible;
+
+  /**
+   * Previous start offset of pivot. -1 if none.
+   */
+  readonly attribute long oldStartOffset;
+
+  /**
+   * Previous end offset of pivot. -1 if none.
+   */
+  readonly attribute long oldEndOffset;
+};
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -375,8 +375,29 @@ AccTableChangeEvent::
 already_AddRefed<nsAccEvent>
 AccTableChangeEvent::CreateXPCOMObject()
 {
   nsAccEvent* event = new nsAccTableChangeEvent(this);
   NS_IF_ADDREF(event);
   return event;
 }
 
+
+////////////////////////////////////////////////////////////////////////////////
+// AccVCChangeEvent
+////////////////////////////////////////////////////////////////////////////////
+
+AccVCChangeEvent::
+  AccVCChangeEvent(nsAccessible* aAccessible,
+                   nsIAccessible* aOldAccessible,
+                   PRInt32 aOldStart, PRInt32 aOldEnd) :
+    AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
+    mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd)
+{
+}
+
+already_AddRefed<nsAccEvent>
+AccVCChangeEvent::CreateXPCOMObject()
+{
+  nsAccEvent* event = new nsAccVirtualCursorChangeEvent(this);
+  NS_ADDREF(event);
+  return event;
+}
--- a/accessible/src/base/AccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -124,17 +124,18 @@ public:
     eGenericEvent,
     eStateChangeEvent,
     eTextChangeEvent,
     eMutationEvent,
     eHideEvent,
     eShowEvent,
     eCaretMoveEvent,
     eSelectionChangeEvent,
-    eTableChangeEvent
+    eTableChangeEvent,
+    eVirtualCursorChangeEvent
   };
 
   static const EventGroup kEventGroup = eGenericEvent;
   virtual unsigned int GetEventGroups() const
   {
     return 1U << eGenericEvent;
   }
 
@@ -394,16 +395,47 @@ public:
   PRUint32 GetIndex() const { return mRowOrColIndex; }
   PRUint32 GetCount() const { return mNumRowsOrCols; }
 
 private:
   PRUint32 mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
   PRUint32 mNumRowsOrCols;   // the number of inserted/deleted rows/columns
 };
 
+/**
+ * Accessible virtual cursor change event.
+ */
+class AccVCChangeEvent : public AccEvent
+{
+public:
+  AccVCChangeEvent(nsAccessible* aAccessible,
+                   nsIAccessible* aOldAccessible,
+                   PRInt32 aOldStart, PRInt32 aOldEnd);
+
+  virtual ~AccVCChangeEvent() { }
+
+  // AccEvent
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
+
+  static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
+  }
+
+  // AccTableChangeEvent
+  nsIAccessible* OldAccessible() const { return mOldAccessible; }
+  PRInt32 OldStartOffset() const { return mOldStart; }
+  PRInt32 OldEndOffset() const { return mOldEnd; }
+
+private:
+  nsRefPtr<nsIAccessible> mOldAccessible;
+  PRInt32 mOldStart;
+  PRInt32 mOldEnd;
+};
 
 /**
  * Downcast the generic accessible event object to derived type.
  */
 class downcast_accEvent
 {
 public:
   downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -70,18 +70,18 @@ CPPSRCS = \
   nsBaseWidgetAccessible.cpp \
   nsEventShell.cpp \
   nsFormControlAccessible.cpp \
   nsRootAccessible.cpp \
   nsApplicationAccessible.cpp \
   nsCaretAccessible.cpp \
   nsTextAccessible.cpp \
   nsTextEquivUtils.cpp \
-  nsTextAttrs.cpp \
   StyleInfo.cpp \
+  TextAttrs.cpp \
   TextUpdater.cpp \
   $(NULL)
 
 EXPORTS = \
   a11yGeneric.h \
   nsAccDocManager.h \
   nsAccessibilityService.h \
   nsAccessible.h \
--- a/accessible/src/base/StyleInfo.cpp
+++ b/accessible/src/base/StyleInfo.cpp
@@ -126,8 +126,17 @@ StyleInfo::FormatColor(const nscolor& aV
 
 void
 StyleInfo::FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue)
 {
   nsCSSKeyword keyword =
     nsCSSProps::ValueToKeywordEnum(aValue, nsCSSProps::kFontStyleKTable);
   AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
 }
+
+void
+StyleInfo::FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue)
+{
+  nsCSSKeyword keyword =
+    nsCSSProps::ValueToKeywordEnum(aValue,
+                                   nsCSSProps::kTextDecorationStyleKTable);
+  AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
+}
--- a/accessible/src/base/StyleInfo.h
+++ b/accessible/src/base/StyleInfo.h
@@ -57,16 +57,17 @@ public:
   void TextIndent(nsAString& aValue);
   void MarginLeft(nsAString& aValue) { Margin(css::eSideLeft, aValue); }
   void MarginRight(nsAString& aValue) { Margin(css::eSideRight, aValue); }
   void MarginTop(nsAString& aValue) { Margin(css::eSideTop, aValue); }
   void MarginBottom(nsAString& aValue) { Margin(css::eSideBottom, aValue); }
 
   static void FormatColor(const nscolor& aValue, nsString& aFormattedValue);
   static void FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue);
+  static void FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue);
 
 private:
   StyleInfo() MOZ_DELETE;
   StyleInfo(const StyleInfo&) MOZ_DELETE;
   StyleInfo& operator = (const StyleInfo&) MOZ_DELETE;
 
   void Margin(css::Side aSide, nsAString& aValue);
 
rename from accessible/src/base/nsTextAttrs.cpp
rename to accessible/src/base/TextAttrs.cpp
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsTextAttrs.h"
+#include "TextAttrs.h"
 
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsHyperTextAccessibleWrap.h"
 #include "StyleInfo.h"
 
 #include "gfxFont.h"
 #include "gfxUserFontSet.h"
@@ -68,52 +68,42 @@ struct nsCSSTextAttrMapItem
 /**
  * The map of CSS properties to text attributes.
  */
 const char* const kAnyValue = nsnull;
 const char* const kCopyValue = nsnull;
 
 static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
 {
-  // CSS name            CSS value        Attribute name                                Attribute value
-  { "text-decoration",   "line-through",  &nsGkAtoms::textLineThroughStyle,  "solid" },
-  { "text-decoration",   "underline",     &nsGkAtoms::textUnderlineStyle,    "solid" },
+  // CSS name            CSS value        Attribute name                     Attribute value
   { "vertical-align",    kAnyValue,       &nsGkAtoms::textPosition,          kCopyValue }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsTextAttrs
+// TextAttrsMgr
+////////////////////////////////////////////////////////////////////////////////
 
-nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                               bool aIncludeDefAttrs,
-                               nsAccessible *aOffsetAcc,
-                               PRInt32 aOffsetAccIdx) :
-  mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
-  mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
-{
-}
-
-nsresult
-nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
-                              PRInt32 *aStartHTOffset,
-                              PRInt32 *aEndHTOffset)
+void
+TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
+                            PRInt32* aStartHTOffset,
+                            PRInt32* aEndHTOffset)
 {
   // 1. Hyper text accessible must be specified always.
   // 2. Offset accessible and result hyper text offsets must be specified in
   // the case of text attributes.
   // 3. Offset accessible and result hyper text offsets must not be specified
   // but include default text attributes flag and attributes list must be
   // specified in the case of default text attributes.
   NS_PRECONDITION(mHyperTextAcc &&
                   ((mOffsetAcc && mOffsetAccIdx != -1 &&
                     aStartHTOffset && aEndHTOffset) ||
                   (!mOffsetAcc && mOffsetAccIdx == -1 &&
                     !aStartHTOffset && !aEndHTOffset &&
                    mIncludeDefAttrs && aAttributes)),
-                  "Wrong usage of nsTextAttrsMgr!");
+                  "Wrong usage of TextAttrsMgr!");
 
   // Embedded objects are combined into own range with empty attributes set.
   if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
     for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
       nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
       if (!nsAccUtils::IsEmbeddedObject(currAcc))
         break;
 
@@ -125,120 +115,107 @@ nsTextAttrsMgr::GetAttributes(nsIPersist
          childIdx++) {
       nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
       if (!nsAccUtils::IsEmbeddedObject(currAcc))
         break;
 
       (*aEndHTOffset)++;
     }
 
-    return NS_OK;
+    return;
   }
 
   // Get the content and frame of the accessible. In the case of document
   // accessible it's role content and root frame.
   nsIContent *hyperTextElm = mHyperTextAcc->GetContent();
   nsIFrame *rootFrame = mHyperTextAcc->GetFrame();
   NS_ASSERTION(rootFrame, "No frame for accessible!");
   if (!rootFrame)
-    return NS_OK;
+    return;
 
   nsIContent *offsetNode = nsnull, *offsetElm = nsnull;
   nsIFrame *frame = nsnull;
   if (mOffsetAcc) {
     offsetNode = mOffsetAcc->GetContent();
     offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
     frame = offsetElm->GetPrimaryFrame();
   }
 
-  nsTArray<nsITextAttr*> textAttrArray(10);
+  nsTArray<TextAttr*> textAttrArray(9);
 
   // "language" text attribute
-  nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
+  LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
   textAttrArray.AppendElement(&langTextAttr);
 
-  // "text-line-through-style" text attribute
-  nsCSSTextAttr lineThroughTextAttr(0, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(&lineThroughTextAttr);
-
-  // "text-underline-style" text attribute
-  nsCSSTextAttr underlineTextAttr(1, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(&underlineTextAttr);
-
   // "text-position" text attribute
-  nsCSSTextAttr posTextAttr(2, hyperTextElm, offsetElm);
+  CSSTextAttr posTextAttr(0, hyperTextElm, offsetElm);
   textAttrArray.AppendElement(&posTextAttr);
 
   // "background-color" text attribute
-  nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
+  BGColorTextAttr bgColorTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&bgColorTextAttr);
 
   // "color" text attribute
   ColorTextAttr colorTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&colorTextAttr);
 
   // "font-family" text attribute
   FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&fontFamilyTextAttr);
 
   // "font-size" text attribute
-  nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
+  FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&fontSizeTextAttr);
 
   // "font-style" text attribute
   FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&fontStyleTextAttr);
 
   // "font-weight" text attribute
-  nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
+  FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
   textAttrArray.AppendElement(&fontWeightTextAttr);
 
+  // "text-underline(line-through)-style(color)" text attributes
+  TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
+  textAttrArray.AppendElement(&textDecorTextAttr);
+
   // Expose text attributes if applicable.
   if (aAttributes) {
     PRUint32 len = textAttrArray.Length();
-    for (PRUint32 idx = 0; idx < len; idx++) {
-      nsITextAttr *textAttr = textAttrArray[idx];
-
-      nsAutoString value;
-      if (textAttr->GetValue(value, mIncludeDefAttrs))
-        nsAccUtils::SetAccAttr(aAttributes, textAttr->GetName(), value);
-    }
+    for (PRUint32 idx = 0; idx < len; idx++)
+      textAttrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
   }
 
-  nsresult rv = NS_OK;
-
   // Expose text attributes range where they are applied if applicable.
   if (mOffsetAcc)
-    rv = GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
-
-  textAttrArray.Clear();
-  return rv;
+    GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
 }
 
-nsresult
-nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
-                         PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset)
+void
+TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
+                       PRInt32* aStartHTOffset, PRInt32* aEndHTOffset)
 {
   PRUint32 attrLen = aTextAttrArray.Length();
 
   // Navigate backward from anchor accessible to find start offset.
   for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
     nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
 
     // Stop on embedded accessible since embedded accessibles are combined into
     // own range.
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
-    nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
-    NS_ENSURE_STATE(currElm);
+    nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
+    if (!currElm)
+      return;
 
     bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
-      nsITextAttr *textAttr = aTextAttrArray[attrIdx];
+      TextAttr* textAttr = aTextAttrArray[attrIdx];
       if (!textAttr->Equal(currElm)) {
         offsetFound = true;
         break;
       }
     }
 
     if (offsetFound)
       break;
@@ -248,99 +225,99 @@ nsTextAttrsMgr::GetRange(const nsTArray<
 
   // Navigate forward from anchor accessible to find end offset.
   PRInt32 childLen = mHyperTextAcc->GetChildCount();
   for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
     nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
-    nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
-    NS_ENSURE_STATE(currElm);
+    nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
+    if (!currElm)
+      return;
 
     bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
-      nsITextAttr *textAttr = aTextAttrArray[attrIdx];
+      TextAttr* textAttr = aTextAttrArray[attrIdx];
 
       // Alter the end offset when text attribute changes its value and stop
       // the search.
       if (!textAttr->Equal(currElm)) {
         offsetFound = true;
         break;
       }
     }
 
     if (offsetFound)
       break;
 
     (*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
   }
+}
 
-  return NS_OK;
-}
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsLangTextAttr
+// LangTextAttr
+////////////////////////////////////////////////////////////////////////////////
 
-nsLangTextAttr::nsLangTextAttr(nsHyperTextAccessible *aRootAcc, 
-                               nsIContent *aRootContent, nsIContent *aContent) :
-  nsTextAttr<nsAutoString>(aContent == nsnull), mRootContent(aRootContent)
+TextAttrsMgr::LangTextAttr::
+  LangTextAttr(nsHyperTextAccessible* aRoot,
+               nsIContent* aRootElm, nsIContent* aElm) :
+  TTextAttr<nsString>(!aElm), mRootContent(aRootElm)
 {
-  aRootAcc->Language(mRootNativeValue);
+  aRoot->Language(mRootNativeValue);
   mIsRootDefined =  !mRootNativeValue.IsEmpty();
 
-  if (aContent)
-    mIsDefined = GetLang(aContent, mNativeValue);
+  if (aElm)
+    mIsDefined = GetLang(aElm, mNativeValue);
 }
 
 bool
-nsLangTextAttr::GetValueFor(nsIContent *aElm, nsAutoString *aValue)
+TextAttrsMgr::LangTextAttr::
+  GetValueFor(nsIContent* aElm, nsString* aValue)
 {
   return GetLang(aElm, *aValue);
 }
 
 void
-nsLangTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::LangTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
-  aFormattedValue = aValue;
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
 }
 
 bool
-nsLangTextAttr::GetLang(nsIContent *aContent, nsAString& aLang)
+TextAttrsMgr::LangTextAttr::
+  GetLang(nsIContent* aElm, nsAString& aLang)
 {
-  nsCoreUtils::GetLanguageFor(aContent, mRootContent, aLang);
+  nsCoreUtils::GetLanguageFor(aElm, mRootContent, aLang);
   return !aLang.IsEmpty();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsCSSTextAttr
+// CSSTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-nsCSSTextAttr::nsCSSTextAttr(PRUint32 aIndex, nsIContent *aRootContent,
-                             nsIContent *aContent) :
-  nsTextAttr<nsAutoString>(aContent == nsnull), mIndex(aIndex)
+TextAttrsMgr::CSSTextAttr::
+  CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm) :
+  TTextAttr<nsString>(!aElm), mIndex(aIndex)
 {
-  mIsRootDefined = GetValueFor(aRootContent, &mRootNativeValue);
+  mIsRootDefined = GetValueFor(aRootElm, &mRootNativeValue);
 
-  if (aContent)
-    mIsDefined = GetValueFor(aContent, &mNativeValue);
-}
-
-nsIAtom*
-nsCSSTextAttr::GetName() const
-{
-  return *gCSSTextAttrsMap[mIndex].mAttrName;
+  if (aElm)
+    mIsDefined = GetValueFor(aElm, &mNativeValue);
 }
 
 bool
-nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
+TextAttrsMgr::CSSTextAttr::
+  GetValueFor(nsIContent* aElm, nsString* aValue)
 {
   nsCOMPtr<nsIDOMCSSStyleDeclaration> currStyleDecl =
-    nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aContent);
+    nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aElm);
   if (!currStyleDecl)
     return false;
 
   NS_ConvertASCIItoUTF16 cssName(gCSSTextAttrsMap[mIndex].mCSSName);
 
   nsresult rv = currStyleDecl->GetPropertyValue(cssName, *aValue);
   if (NS_FAILED(rv))
     return true;
@@ -348,60 +325,69 @@ nsCSSTextAttr::GetValueFor(nsIContent *a
   const char *cssValue = gCSSTextAttrsMap[mIndex].mCSSValue;
   if (cssValue != kAnyValue && !aValue->EqualsASCII(cssValue))
     return false;
 
   return true;
 }
 
 void
-nsCSSTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::CSSTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
-  const char *attrValue = gCSSTextAttrsMap[mIndex].mAttrValue;
-  if (attrValue != kCopyValue)
-    AppendASCIItoUTF16(attrValue, aFormattedValue);
-  else
-    aFormattedValue = aValue;
+  const char* attrValue = gCSSTextAttrsMap[mIndex].mAttrValue;
+  if (attrValue != kCopyValue) {
+    nsAutoString formattedValue;
+    AppendASCIItoUTF16(attrValue, formattedValue);
+    nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
+                           formattedValue);
+    return;
+  }
+
+  nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
+                         aValue);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsBGColorTextAttr
+// BGColorTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
-  nsTextAttr<nscolor>(aFrame == nsnull), mRootFrame(aRootFrame)
+TextAttrsMgr::BGColorTextAttr::
+  BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
 {
   mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
   if (aFrame)
     mIsDefined = GetColor(aFrame, &mNativeValue);
 }
 
 bool
-nsBGColorTextAttr::GetValueFor(nsIContent *aContent, nscolor *aValue)
+TextAttrsMgr::BGColorTextAttr::
+  GetValueFor(nsIContent* aElm, nscolor* aValue)
 {
-  nsIFrame *frame = aContent->GetPrimaryFrame();
-  if (!frame)
-    return false;
-
-  return GetColor(frame, aValue);
+  nsIFrame* frame = aElm->GetPrimaryFrame();
+  return frame ? GetColor(frame, aValue) : false;
 }
 
 void
-nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::BGColorTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
 {
-  nsAutoString value;
-  StyleInfo::FormatColor(aValue, value);
-  aFormattedValue = value;
+  nsAutoString formattedValue;
+  StyleInfo::FormatColor(aValue, formattedValue);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::backgroundColor,
+                         formattedValue);
 }
 
 bool
-nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
+TextAttrsMgr::BGColorTextAttr::
+  GetColor(nsIFrame* aFrame, nscolor* aColor)
 {
-  const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
+  const nsStyleBackground* styleBackground = aFrame->GetStyleBackground();
 
   if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
     *aColor = styleBackground->mBackgroundColor;
     return true;
   }
 
   nsIFrame *parentFrame = aFrame->GetParent();
   if (!parentFrame) {
@@ -418,124 +404,131 @@ nsBGColorTextAttr::GetColor(nsIFrame *aF
   return GetColor(parentFrame, aColor);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // ColorTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
-  nsTextAttr<nscolor>(!aFrame)
+TextAttrsMgr::ColorTextAttr::
+  ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<nscolor>(!aFrame)
 {
   mRootNativeValue = aRootFrame->GetStyleColor()->mColor;
   mIsRootDefined = true;
 
   if (aFrame) {
     mNativeValue = aFrame->GetStyleColor()->mColor;
     mIsDefined = true;
   }
 }
 
 bool
-ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
+TextAttrsMgr::ColorTextAttr::
+  GetValueFor(nsIContent* aElm, nscolor* aValue)
 {
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIFrame* frame = aElm->GetPrimaryFrame();
   if (frame) {
     *aValue = frame->GetStyleColor()->mColor;
     return true;
   }
 
   return false;
 }
 
 void
-ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::ColorTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
 {
-  nsAutoString value;
-  StyleInfo::FormatColor(aValue, value);
-  aFormattedValue = value;
+  nsAutoString formattedValue;
+  StyleInfo::FormatColor(aValue, formattedValue);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::color, formattedValue);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // FontFamilyTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
-  nsTextAttr<nsAutoString>(aFrame == nsnull)
+TextAttrsMgr::FontFamilyTextAttr::
+  FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<nsString>(!aFrame)
 {
   mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
 
   if (aFrame)
     mIsDefined = GetFontFamily(aFrame, mNativeValue);
 }
 
 bool
-FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
+TextAttrsMgr::FontFamilyTextAttr::
+  GetValueFor(nsIContent* aElm, nsString* aValue)
 {
   nsIFrame* frame = aElm->GetPrimaryFrame();
-  if (!frame)
-    return false;
-
-  return GetFontFamily(frame, *aValue);
+  return frame ? GetFontFamily(frame, *aValue) : false;
 }
 
 void
-FontFamilyTextAttr::Format(const nsAutoString& aValue,
-                           nsAString& aFormattedValue)
+TextAttrsMgr::FontFamilyTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
 {
-  aFormattedValue = aValue;
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
 }
 
 bool
-FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
+TextAttrsMgr::FontFamilyTextAttr::
+  GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
 {
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
 
   gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
   gfxFont* font = fontGroup->GetFontAt(0);
   gfxFontEntry* fontEntry = font->GetFontEntry();
   aFamily = fontEntry->FamilyName();
   return true;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsFontSizeTextAttr
+// FontSizeTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-nsFontSizeTextAttr::nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
-  nsTextAttr<nscoord>(aFrame == nsnull)
+TextAttrsMgr::FontSizeTextAttr::
+  FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<nscoord>(!aFrame)
 {
   mDC = aRootFrame->PresContext()->DeviceContext();
 
-  mRootNativeValue = GetFontSize(aRootFrame);
+  mRootNativeValue = aRootFrame->GetStyleFont()->mSize;
   mIsRootDefined = true;
 
   if (aFrame) {
-    mNativeValue = GetFontSize(aFrame);
+    mNativeValue = aFrame->GetStyleFont()->mSize;
     mIsDefined = true;
   }
 }
 
 bool
-nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
+TextAttrsMgr::FontSizeTextAttr::
+  GetValueFor(nsIContent* aElm, nscoord* aValue)
 {
-  nsIFrame *frame = aContent->GetPrimaryFrame();
-  if (!frame)
-    return false;
+  nsIFrame* frame = aElm->GetPrimaryFrame();
+  if (frame) {
+    *aValue = frame->GetStyleFont()->mSize;
+    return true;
+  }
 
-  *aValue = GetFontSize(frame);
-  return true;
+  return false;
 }
 
 void
-nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::FontSizeTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
 {
   // Convert from nscoord to pt.
   //
   // Note: according to IA2, "The conversion doesn't have to be exact.
   // The intent is to give the user a feel for the size of the text."
   //
   // ATK does not specify a unit and will likely follow IA2 here.
   //
@@ -543,99 +536,105 @@ nsFontSizeTextAttr::Format(const nscoord
   float px =
     NSAppUnitsToFloatPixels(aValue, nsDeviceContext::AppUnitsPerCSSPixel());
   // Each pt is 4/3 of a CSS pixel.
   int pts = NS_lround(px*3/4);
 
   nsAutoString value;
   value.AppendInt(pts);
   value.Append(NS_LITERAL_STRING("pt"));
-  aFormattedValue = value;
-}
 
-nscoord
-nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
-{
-  return aFrame->GetStyleFont()->mSize;
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_size, value);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // FontStyleTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
-  nsTextAttr<nscoord>(!aFrame)
+TextAttrsMgr::FontStyleTextAttr::
+  FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<nscoord>(!aFrame)
 {
   mRootNativeValue = aRootFrame->GetStyleFont()->mFont.style;
   mIsRootDefined = true;
 
   if (aFrame) {
     mNativeValue = aFrame->GetStyleFont()->mFont.style;
     mIsDefined = true;
   }
 }
 
 bool
-FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
+TextAttrsMgr::FontStyleTextAttr::
+  GetValueFor(nsIContent* aContent, nscoord* aValue)
 {
   nsIFrame* frame = aContent->GetPrimaryFrame();
   if (frame) {
     *aValue = frame->GetStyleFont()->mFont.style;
     return true;
   }
 
   return false;
 }
 
 void
-FontStyleTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::FontStyleTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
 {
-  StyleInfo::FormatFontStyle(aValue, aFormattedValue);
+  nsAutoString formattedValue;
+  StyleInfo::FormatFontStyle(aValue, formattedValue);
+
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_style, formattedValue);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsFontWeightTextAttr
+// FontWeightTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
-nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
-                                           nsIFrame *aFrame) :
-  nsTextAttr<PRInt32>(aFrame == nsnull)
+TextAttrsMgr::FontWeightTextAttr::
+  FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<PRInt32>(!aFrame)
 {
   mRootNativeValue = GetFontWeight(aRootFrame);
   mIsRootDefined = true;
 
   if (aFrame) {
     mNativeValue = GetFontWeight(aFrame);
     mIsDefined = true;
   }
 }
 
 bool
-nsFontWeightTextAttr::GetValueFor(nsIContent *aContent, PRInt32 *aValue)
+TextAttrsMgr::FontWeightTextAttr::
+  GetValueFor(nsIContent* aElm, PRInt32* aValue)
 {
-  nsIFrame *frame = aContent->GetPrimaryFrame();
-  if (!frame)
-    return false;
+  nsIFrame* frame = aElm->GetPrimaryFrame();
+  if (frame) {
+    *aValue = GetFontWeight(frame);
+    return true;
+  }
 
-  *aValue = GetFontWeight(frame);
-  return true;
+  return false;
 }
 
 void
-nsFontWeightTextAttr::Format(const PRInt32& aValue, nsAString& aFormattedValue)
+TextAttrsMgr::FontWeightTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const PRInt32& aValue)
 {
-  nsAutoString value;
-  value.AppendInt(aValue);
-  aFormattedValue = value;
+  nsAutoString formattedValue;
+  formattedValue.AppendInt(aValue);
+
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::fontWeight, formattedValue);
 }
 
 PRInt32
-nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
+TextAttrsMgr::FontWeightTextAttr::
+  GetFontWeight(nsIFrame* aFrame)
 {
   // nsFont::width isn't suitable here because it's necessary to expose real
   // value of font weight (used font might not have some font weight values).
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
 
   gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
   gfxFont *font = fontGroup->GetFontAt(0);
@@ -659,8 +658,87 @@ nsFontWeightTextAttr::GetFontWeight(nsIF
   // may not be the weight of the font face used to render the characters.
   // On Mac, font->GetStyle()->weight will just give the same number as
   // getComputedStyle(). fontEntry->Weight() will give the weight of the font
   // face used.
   gfxFontEntry *fontEntry = font->GetFontEntry();
   return fontEntry->Weight();
 #endif
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// TextDecorTextAttr
+////////////////////////////////////////////////////////////////////////////////
+
+TextAttrsMgr::TextDecorValue::
+  TextDecorValue(nsIFrame* aFrame)
+{
+  const nsStyleTextReset* textReset = aFrame->GetStyleTextReset();
+  mStyle = textReset->GetDecorationStyle();
+
+  bool isForegroundColor = false;
+  textReset->GetDecorationColor(mColor, isForegroundColor);
+  if (isForegroundColor)
+    mColor = aFrame->GetStyleColor()->mColor;
+
+  mLine = textReset->mTextDecorationLine &
+    (NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
+     NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
+}
+
+TextAttrsMgr::TextDecorTextAttr::
+  TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  TTextAttr<TextDecorValue>(!aFrame)
+{
+  mRootNativeValue = TextDecorValue(aRootFrame);
+  mIsRootDefined = mRootNativeValue.IsDefined();
+
+  if (aFrame) {
+    mNativeValue = TextDecorValue(aFrame);
+    mIsDefined = mNativeValue.IsDefined();
+  }
+}
+
+bool
+TextAttrsMgr::TextDecorTextAttr::
+  GetValueFor(nsIContent* aContent, TextDecorValue* aValue)
+{
+  nsIFrame* frame = aContent->GetPrimaryFrame();
+  if (frame) {
+    *aValue = TextDecorValue(frame);
+    return aValue->IsDefined();
+  }
+
+  return false;
+}
+
+void
+TextAttrsMgr::TextDecorTextAttr::
+  ExposeValue(nsIPersistentProperties* aAttributes, const TextDecorValue& aValue)
+{
+  if (aValue.IsUnderline()) {
+    nsAutoString formattedStyle;
+    StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
+    nsAccUtils::SetAccAttr(aAttributes,
+                           nsGkAtoms::textUnderlineStyle,
+                           formattedStyle);
+
+    nsAutoString formattedColor;
+    StyleInfo::FormatColor(aValue.Color(), formattedColor);
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textUnderlineColor,
+                           formattedColor);
+    return;
+  }
+
+  if (aValue.IsLineThrough()) {
+    nsAutoString formattedStyle;
+    StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
+    nsAccUtils::SetAccAttr(aAttributes,
+                           nsGkAtoms::textLineThroughStyle,
+                           formattedStyle);
+
+    nsAutoString formattedColor;
+    StyleInfo::FormatColor(aValue.Color(), formattedColor);
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textLineThroughColor,
+                           formattedColor);
+  }
+}
rename from accessible/src/base/nsTextAttrs.h
rename to accessible/src/base/TextAttrs.h
--- a/accessible/src/base/nsTextAttrs.h
+++ b/accessible/src/base/TextAttrs.h
@@ -34,393 +34,410 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsTextAttrs_h_
 #define nsTextAttrs_h_
 
-class nsHyperTextAccessible;
-
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsIPersistentProperties2.h"
+#include "nsStyleConsts.h"
 
-class nsITextAttr;
+class nsHyperTextAccessible;
+
+namespace mozilla {
+namespace a11y {
 
 /**
  * Used to expose text attributes for the hyper text accessible (see
- * nsHyperTextAccessible class). It is indended for the work with 'language' and
- * CSS based text attributes.
+ * nsHyperTextAccessible class).
  *
- * @note "invalid: spelling" text attrbiute is implemented entirerly in
+ * @note "invalid: spelling" text attribute is implemented entirely in
  *       nsHyperTextAccessible class.
  */
-class nsTextAttrsMgr
+class TextAttrsMgr
 {
 public:
   /**
-   * Constructor. If instance of the class is intended to expose default text
-   * attributes then 'aIncludeDefAttrs' and 'aOffsetNode' argument must be
-   * skiped.
+   * Constructor. Used to expose default text attributes.
+   */
+  TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc) :
+    mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(true),
+    mOffsetAcc(nsnull), mOffsetAccIdx(-1) { }
+
+  /**
+   * Constructor. Used to expose text attributes at the given offset.
    *
-   * @param aHyperTextAcc    hyper text accessible text attributes are
-   *                         calculated for
-   * @param aHyperTextNode   DOM node of the given hyper text accessbile
+   * @param aHyperTextAcc    [in] hyper text accessible text attributes are
+   *                          calculated for
    * @param aIncludeDefAttrs [optional] indicates whether default text
-   *                         attributes should be included into list of exposed
-   *                         text attributes.
-   * @param oOffsetNode      [optional] DOM node represents hyper text offset
-   *                         inside hyper text accessible
+   *                          attributes should be included into list of exposed
+   *                          text attributes
+   * @param oOffsetAcc       [optional] offset an accessible the text attributes
+   *                          should be calculated for
+   * @param oOffsetAccIdx    [optional] index in parent of offset accessible
    */
-  nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                 bool aIncludeDefAttrs = true,
-                 nsAccessible *aOffsetAcc = nsnull,
-                 PRInt32 aOffsetAccIdx = -1);
+  TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc,
+               bool aIncludeDefAttrs,
+               nsAccessible* aOffsetAcc,
+               PRInt32 aOffsetAccIdx) :
+    mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
+    mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx) { }
 
   /*
    * Return text attributes and hyper text offsets where these attributes are
    * applied. Offsets are calculated in the case of non default attributes.
    *
    * @note In the case of default attributes pointers on hyper text offsets
-   *       must be skiped.
+   *       must be skipped.
    *
    * @param aAttributes    [in, out] text attributes list
    * @param aStartHTOffset [out, optional] start hyper text offset
    * @param aEndHTOffset   [out, optional] end hyper text offset
    */
-  nsresult GetAttributes(nsIPersistentProperties *aAttributes,
-                         PRInt32 *aStartHTOffset = nsnull,
-                         PRInt32 *aEndHTOffset = nsnull);
+  void GetAttributes(nsIPersistentProperties* aAttributes,
+                     PRInt32* aStartHTOffset = nsnull,
+                     PRInt32* aEndHTOffset = nsnull);
 
 protected:
   /**
    * Calculates range (start and end offsets) of text where the text attributes
    * are stretched. New offsets may be smaller if one of text attributes changes
    * its value before or after the given offsets.
    *
    * @param aTextAttrArray  [in] text attributes array
    * @param aStartHTOffset  [in, out] the start offset
    * @param aEndHTOffset    [in, out] the end offset
    */
-   nsresult GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
-                     PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset);
+  class TextAttr;
+  void GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
+                PRInt32* aStartHTOffset, PRInt32* aEndHTOffset);
 
 private:
-  nsRefPtr<nsHyperTextAccessible> mHyperTextAcc;
+  nsHyperTextAccessible* mHyperTextAcc;
 
   bool mIncludeDefAttrs;
 
-  nsRefPtr<nsAccessible> mOffsetAcc;
+  nsAccessible* mOffsetAcc;
   PRInt32 mOffsetAccIdx;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Private implementation details
-
-/**
- * Interface class of text attribute class implementations.
- */
-class nsITextAttr
-{
-public:
-  /**
-   * Return the name of text attribute.
-   */
-  virtual nsIAtom* GetName() const = 0;
-
-  /**
-   * Retrieve the value of text attribute in out param, return true if differs
-   * from the default value of text attribute or if include default attribute
-   * value flag is setted.
-   * 
-   * @param aValue                [in, out] the value of text attribute
-   * @param aIncludeDefAttrValue  [in] include default attribute value flag
-   * @return                      true if text attribute value differs from
-   *                              default or include default attribute value
-   *                              flag is applied
-   */
-  virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue) = 0;
-
-  /**
-   * Return true if the text attribute value on the given element equals with
-   * predefined attribute value.
-   */
-  virtual bool Equal(nsIContent *aContent) = 0;
-};
-
-
-/**
- * Base class to work with text attributes. See derived classes below.
- */
-template<class T>
-class nsTextAttr : public nsITextAttr
-{
-public:
-  nsTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
-
-  // nsITextAttr
-  virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue)
-  {
-    if (mGetRootValue) {
-      Format(mRootNativeValue, aValue);
-      return mIsRootDefined;
-    }
-
-    bool isDefined = mIsDefined;
-    T* nativeValue = &mNativeValue;
-
-    if (!isDefined) {
-      if (aIncludeDefAttrValue) {
-        isDefined = mIsRootDefined;
-        nativeValue = &mRootNativeValue;
-      }
-    } else if (!aIncludeDefAttrValue) {
-      isDefined = mRootNativeValue != mNativeValue;
-    }
-
-    if (!isDefined)
-      return false;
-
-    Format(*nativeValue, aValue);
-    return true;
-  }
-
-  virtual bool Equal(nsIContent *aContent)
-  {
-    T nativeValue;
-    bool isDefined = GetValueFor(aContent, &nativeValue);
-
-    if (!mIsDefined && !isDefined)
-      return true;
-
-    if (mIsDefined && isDefined)
-      return nativeValue == mNativeValue;
-
-    if (mIsDefined)
-      return mNativeValue == mRootNativeValue;
-
-    return nativeValue == mRootNativeValue;
-  }
-
-protected:
-
-  // Return native value for the given DOM element.
-  virtual bool GetValueFor(nsIContent *aContent, T *aValue) = 0;
-
-  // Format native value to text attribute value.
-  virtual void Format(const T& aValue, nsAString& aFormattedValue) = 0;
-
-  // Indicates if root value should be exposed.
-  bool mGetRootValue;
-
-  // Native value and flag indicating if the value is defined (initialized in
-  // derived classes). Note, undefined native value means it is inherited
-  // from root.
-  T mNativeValue;
-  bool mIsDefined;
-
-  // Native root value and flag indicating if the value is defined  (initialized
-  // in derived classes).
-  T mRootNativeValue;
-  bool mIsRootDefined;
-};
-
-
-/**
- * Class is used for the work with 'language' text attribute in nsTextAttrsMgr
- * class.
- */
-class nsLangTextAttr : public nsTextAttr<nsAutoString>
-{
-public:
-  nsLangTextAttr(nsHyperTextAccessible *aRootAcc, nsIContent *aRootContent,
-                 nsIContent *aContent);
-
-  // nsITextAttr
-  virtual nsIAtom *GetName() const { return nsGkAtoms::language; }
 
 protected:
 
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent *aElm, nsAutoString *aValue);
-  virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
-
-private:
-  bool GetLang(nsIContent *aContent, nsAString& aLang);
-  nsCOMPtr<nsIContent> mRootContent;
-};
-
+  /**
+   * Interface class of text attribute class implementations.
+   */
+  class TextAttr
+  {
+  public:
+    /**
+     * Expose the text attribute to the given attribute set.
+     *
+     * @param aAttributes           [in] the given attribute set
+     * @param aIncludeDefAttrValue  [in] if true then attribute is exposed even
+     *                               if its value is the same as default one
+     */
+    virtual void Expose(nsIPersistentProperties* aAttributes,
+                        bool aIncludeDefAttrValue) = 0;
 
-/**
- * Class is used for the work with CSS based text attributes in nsTextAttrsMgr
- * class.
- */
-class nsCSSTextAttr : public nsTextAttr<nsAutoString>
-{
-public:
-  nsCSSTextAttr(PRUint32 aIndex, nsIContent *aRootContent,
-                nsIContent *aContent);
-
-  // nsITextAttr
-  virtual nsIAtom *GetName() const;
-
-protected:
-
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent *aContent, nsAutoString *aValue);
-  virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
-
-private:
-  PRInt32 mIndex;
-};
+    /**
+     * Return true if the text attribute value on the given element equals with
+     * predefined attribute value.
+     */
+    virtual bool Equal(nsIContent* aElm) = 0;
+  };
 
 
-/**
- * Class is used for the work with 'background-color' text attribute in
- * nsTextAttrsMgr class.
- */
-class nsBGColorTextAttr : public nsTextAttr<nscolor>
-{
-public:
-  nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
+  /**
+   * Base class to work with text attributes. See derived classes below.
+   */
+  template<class T>
+  class TTextAttr : public TextAttr
+  {
+  public:
+    TTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
+
+    // ITextAttr
+    virtual void Expose(nsIPersistentProperties* aAttributes,
+                        bool aIncludeDefAttrValue)
+    {
+      if (mGetRootValue) {
+        if (mIsRootDefined)
+          ExposeValue(aAttributes, mRootNativeValue);
+        return;
+      }
+
+      if (mIsDefined) {
+        if (aIncludeDefAttrValue || mRootNativeValue != mNativeValue)
+          ExposeValue(aAttributes, mNativeValue);
+        return;
+      }
+
+      if (aIncludeDefAttrValue && mIsRootDefined)
+        ExposeValue(aAttributes, mRootNativeValue);
+    }
+
+    virtual bool Equal(nsIContent* aElm)
+    {
+      T nativeValue;
+      bool isDefined = GetValueFor(aElm, &nativeValue);
 
-  // nsITextAttr
-  virtual nsIAtom *GetName() const { return nsGkAtoms::backgroundColor; }
+      if (!mIsDefined && !isDefined)
+        return true;
+
+      if (mIsDefined && isDefined)
+        return nativeValue == mNativeValue;
+
+      if (mIsDefined)
+        return mNativeValue == mRootNativeValue;
+
+      return nativeValue == mRootNativeValue;
+    }
+
+  protected:
+
+    // Expose the text attribute with the given value to attribute set.
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const T& aValue) = 0;
 
-protected:
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent *aContent, nscolor *aValue);
-  virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
+    // Return native value for the given DOM element.
+    virtual bool GetValueFor(nsIContent* aElm, T* aValue) = 0;
+
+    // Indicates if root value should be exposed.
+    bool mGetRootValue;
 
-private:
-  bool GetColor(nsIFrame *aFrame, nscolor *aColor);
-  nsIFrame *mRootFrame;
-};
+    // Native value and flag indicating if the value is defined (initialized in
+    // derived classes). Note, undefined native value means it is inherited
+    // from root.
+    T mNativeValue;
+    bool mIsDefined;
+
+    // Native root value and flag indicating if the value is defined  (initialized
+    // in derived classes).
+    T mRootNativeValue;
+    bool mIsRootDefined;
+  };
 
 
-/**
- * Class is used for the work with 'color' text attribute in nsTextAttrsMgr
- * class.
- */
-class ColorTextAttr : public nsTextAttr<nscolor>
-{
-public:
-  ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+  /**
+   * Class is used for the work with 'language' text attribute.
+   */
+  class LangTextAttr : public TTextAttr<nsString>
+  {
+  public:
+    LangTextAttr(nsHyperTextAccessible* aRoot, nsIContent* aRootElm,
+                 nsIContent* aElm);
+    virtual ~LangTextAttr() { }
+
+  protected:
+
+    // TextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nsString& aValue);
 
-  // nsITextAttr
-  virtual nsIAtom* GetName() const { return nsGkAtoms::color; }
+  private:
+    bool GetLang(nsIContent* aElm, nsAString& aLang);
+    nsCOMPtr<nsIContent> mRootContent;
+  };
+
 
-protected:
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent* aContent, nscolor* aValue);
-  virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
-};
+  /**
+   * Class is used for the work with CSS based text attributes.
+   */
+  class CSSTextAttr : public TTextAttr<nsString>
+  {
+  public:
+    CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm);
+    virtual ~CSSTextAttr() { }
+
+  protected:
+
+    // TextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nsString& aValue);
+
+  private:
+    PRInt32 mIndex;
+  };
 
 
-/**
- * Class is used for the work with "font-family" text attribute in
- * nsTextAttrsMgr class.
- */
-class FontFamilyTextAttr : public nsTextAttr<nsAutoString>
-{
-public:
-  FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+  /**
+   * Class is used for the work with 'background-color' text attribute.
+   */
+  class BGColorTextAttr : public TTextAttr<nscolor>
+  {
+  public:
+    BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~BGColorTextAttr() { }
+
+  protected:
+
+    // TextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nscolor& aValue);
 
-  // nsITextAttr
-  virtual nsIAtom* GetName() const { return nsGkAtoms::font_family; }
+  private:
+    bool GetColor(nsIFrame* aFrame, nscolor* aColor);
+    nsIFrame* mRootFrame;
+  };
 
-protected:
 
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent* aContent, nsAutoString* aValue);
-  virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
+  /**
+   * Class is used for the work with 'color' text attribute.
+   */
+  class ColorTextAttr : public TTextAttr<nscolor>
+  {
+  public:
+    ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~ColorTextAttr() { }
 
-private:
+  protected:
 
-  bool GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily);
-};
+    // TTextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nscolor& aValue);
+  };
 
 
-/**
- * Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
- * class.
- */
-class nsFontSizeTextAttr : public nsTextAttr<nscoord>
-{
-public:
-  nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
+  /**
+   * Class is used for the work with "font-family" text attribute.
+   */
+  class FontFamilyTextAttr : public TTextAttr<nsString>
+  {
+  public:
+    FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~FontFamilyTextAttr() { }
+
+  protected:
+
+    // TTextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nsString& aValue);
+
+  private:
+
+    bool GetFontFamily(nsIFrame* aFrame, nsString& aFamily);
+  };
 
-  // nsITextAttr
-  virtual nsIAtom *GetName() const { return nsGkAtoms::font_size; }
 
-protected:
+  /**
+   * Class is used for the work with "font-size" text attribute.
+   */
+  class FontSizeTextAttr : public TTextAttr<nscoord>
+  {
+  public:
+    FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~FontSizeTextAttr() { }
 
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent *aContent, nscoord *aValue);
-  virtual void Format(const nscoord& aValue, nsAString& aFormattedValue);
+  protected:
 
-private:
+    // TTextAttr
+    virtual bool GetValueFor(nsIContent* aElm, nscoord* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nscoord& aValue);
+
+  private:
+    nsDeviceContext* mDC;
+  };
+
 
   /**
-   * Return font size for the given frame.
-   *
-   * @param aFrame      [in] the given frame to query font-size
-   * @return            font size
+   * Class is used for the work with "font-style" text attribute.
    */
-   nscoord GetFontSize(nsIFrame *aFrame);
+  class FontStyleTextAttr : public TTextAttr<nscoord>
+  {
+  public:
+    FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~FontStyleTextAttr() { }
 
-  nsDeviceContext *mDC;
-};
+  protected:
+
+    // TTextAttr
+    virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const nscoord& aValue);
+  };
 
 
-/**
- * Class is used for the work with "font-style" text attribute in nsTextAttrsMgr
- * class.
- */
-class FontStyleTextAttr : public nsTextAttr<nscoord>
-{
-public:
-  FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+  /**
+   * Class is used for the work with "font-weight" text attribute.
+   */
+  class FontWeightTextAttr : public TTextAttr<PRInt32>
+  {
+  public:
+    FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~FontWeightTextAttr() { }
 
-  // nsITextAttr
-  virtual nsIAtom* GetName() const { return nsGkAtoms::font_style; }
-
-protected:
+  protected:
 
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
-  virtual void Format(const nscoord &aValue, nsAString &aFormattedValue);
-};
+    // TTextAttr
+    virtual bool GetValueFor(nsIContent* aElm, PRInt32* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const PRInt32& aValue);
+
+  private:
+    PRInt32 GetFontWeight(nsIFrame* aFrame);
+  };
 
 
-/**
- * Class is used for the work with "font-weight" text attribute in
- * nsTextAttrsMgr class.
- */
-class nsFontWeightTextAttr : public nsTextAttr<PRInt32>
-{
-public:
-  nsFontWeightTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
+  /**
+   * TextDecorTextAttr class is used for the work with
+   * "text-line-through-style", "text-line-through-color",
+   * "text-underline-style" and "text-underline-color" text attributes.
+   */
 
-  // nsITextAttr
-  virtual nsIAtom *GetName() const { return nsGkAtoms::fontWeight; }
+  class TextDecorValue
+  {
+  public:
+    TextDecorValue() { }
+    TextDecorValue(nsIFrame* aFrame);
 
-protected:
+    nscolor Color() const { return mColor; }
+    PRUint8 Style() const { return mStyle; }
+
+    bool IsDefined() const
+      { return IsUnderline() || IsLineThrough(); }
+    bool IsUnderline() const
+      { return mLine & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE; }
+    bool IsLineThrough() const
+      { return mLine & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH; }
 
-  // nsTextAttr
-  virtual bool GetValueFor(nsIContent *aElm, PRInt32 *aValue);
-  virtual void Format(const PRInt32& aValue, nsAString& aFormattedValue);
+    bool operator ==(const TextDecorValue& aValue)
+    {
+      return mColor == aValue.mColor && mLine == aValue.mLine &&
+        mStyle == aValue.mStyle;
+    }
+    bool operator !=(const TextDecorValue& aValue)
+      { return !(*this == aValue); }
 
-private:
+  private:
+    nscolor mColor;
+    PRUint8 mLine;
+    PRUint8 mStyle;
+  };
 
-  /**
-   * Return font weight for the given frame.
-   *
-   * @param aFrame      [in] the given frame to query font weight
-   * @return            font weight
-   */
-  PRInt32 GetFontWeight(nsIFrame *aFrame);
-};
+  class TextDecorTextAttr : public TTextAttr<TextDecorValue>
+  {
+  public:
+    TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+    virtual ~TextDecorTextAttr() { }
+
+  protected:
+
+    // TextAttr
+    virtual bool GetValueFor(nsIContent* aElm, TextDecorValue* aValue);
+    virtual void ExposeValue(nsIPersistentProperties* aAttributes,
+                             const TextDecorValue& aValue);
+  };
+
+}; // TextAttrMgr
+
+} // namespace a11y
+} // namespace mozilla
 
 #endif
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1445,16 +1445,33 @@ nsAccessible::GetAttributesInternal(nsIP
       break;
 
     startContent = parentDoc->FindContentForSubDocument(doc);      
   }
 
   if (!mContent->IsElement())
     return NS_OK;
 
+  // Expose draggable object attribute?
+  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
+  if (htmlElement) {
+    bool draggable = false;
+    htmlElement->GetDraggable(&draggable);
+    if (draggable) {
+      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
+                             NS_LITERAL_STRING("true"));
+    }
+  }
+
+  // Don't calculate CSS-based object attributes when no frame (i.e.
+  // the accessible is not unattached form three) or when the accessible is not
+  // primary for node (like list bullet or XUL tree items).
+  if (!mContent->GetPrimaryFrame() || !IsPrimaryForNode())
+    return NS_OK;
+
   // CSS style based object attributes.
   nsAutoString value;
   StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
 
   // Expose 'display' attribute.
   styleInfo.Display(value);
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
 
@@ -1477,27 +1494,16 @@ nsAccessible::GetAttributesInternal(nsIP
   // Expose 'margin-top' attribute.
   styleInfo.MarginTop(value);
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
 
   // Expose 'margin-bottom' attribute.
   styleInfo.MarginBottom(value);
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
 
-  // Expose draggable object attribute?
-  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
-  if (htmlElement) {
-    bool draggable = false;
-    htmlElement->GetDraggable(&draggable);
-    if (draggable) {
-      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
-                             NS_LITERAL_STRING("true"));
-    }
-  }
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GroupPosition(PRInt32 *aGroupLevel,
                             PRInt32 *aSimilarItemsInGroup,
                             PRInt32 *aPositionInGroup)
 {
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -918,17 +918,18 @@ NS_IMETHODIMP nsDocAccessible::Observe(n
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessiblePivotObserver
 
 NS_IMETHODIMP
 nsDocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
                                 nsIAccessible* aOldAccessible,
                                 PRInt32 aOldStart, PRInt32 aOldEnd)
 {
-  nsRefPtr<AccEvent> event = new AccEvent(nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, this);
+  nsRefPtr<AccEvent> event = new AccVCChangeEvent(this, aOldAccessible,
+                                                  aOldStart, aOldEnd);
   nsEventShell::FireEvent(event);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDocumentObserver
 
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -37,19 +37,19 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHyperTextAccessible.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsDocAccessible.h"
-#include "nsTextAttrs.h"
 #include "Role.h"
 #include "States.h"
+#include "TextAttrs.h"
 
 #include "nsIClipboard.h"
 #include "nsContentUtils.h"
 #include "nsFocusManager.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMXULDocument.h"
@@ -1125,34 +1125,32 @@ nsHyperTextAccessible::GetTextAttributes
   }
 
   nsAccessible* accAtOffset = GetChildAtOffset(aOffset);
   if (!accAtOffset) {
     // Offset 0 is correct offset when accessible has empty text. Include
     // default attributes if they were requested, otherwise return empty set.
     if (aOffset == 0) {
       if (aIncludeDefAttrs) {
-        nsTextAttrsMgr textAttrsMgr(this, true, nsnull, -1);
-        return textAttrsMgr.GetAttributes(*aAttributes);
+        TextAttrsMgr textAttrsMgr(this);
+        textAttrsMgr.GetAttributes(*aAttributes);
       }
       return NS_OK;
     }
     return NS_ERROR_INVALID_ARG;
   }
 
   PRInt32 accAtOffsetIdx = accAtOffset->IndexInParent();
   PRInt32 startOffset = GetChildOffset(accAtOffsetIdx);
   PRInt32 endOffset = GetChildOffset(accAtOffsetIdx + 1);
   PRInt32 offsetInAcc = aOffset - startOffset;
 
-  nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
-                              accAtOffsetIdx);
-  nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
-                                           &endOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  TextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
+                            accAtOffsetIdx);
+  textAttrsMgr.GetAttributes(*aAttributes, &startOffset, &endOffset);
 
   // Compute spelling attributes on text accessible only.
   nsIFrame *offsetFrame = accAtOffset->GetFrame();
   if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) {
     PRInt32 nodeOffset = 0;
     nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
                                           &nodeOffset);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -1181,18 +1179,19 @@ nsHyperTextAccessible::GetDefaultTextAtt
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIPersistentProperties> attributes =
     do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
   NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*aAttributes = attributes);
 
-  nsTextAttrsMgr textAttrsMgr(this, true);
-  return textAttrsMgr.GetAttributes(*aAttributes);
+  TextAttrsMgr textAttrsMgr(this);
+  textAttrsMgr.GetAttributes(*aAttributes);
+  return NS_OK;
 }
 
 PRInt32
 nsHyperTextAccessible::GetLevelInternal()
 {
   nsIAtom *tag = mContent->Tag();
   if (tag == nsGkAtoms::h1)
     return 1;
--- a/accessible/src/xpcom/nsAccEvent.cpp
+++ b/accessible/src/xpcom/nsAccEvent.cpp
@@ -248,8 +248,45 @@ NS_IMETHODIMP
 nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
 {
   NS_ENSURE_ARG_POINTER(aNumRowsOrCols);
 
   *aNumRowsOrCols = static_cast<AccTableChangeEvent*>(mEvent.get())->GetCount();
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccVirtualCursorChangeEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccVirtualCursorChangeEvent, nsAccEvent,
+                             nsIAccessibleVirtualCursorChangeEvent)
+
+NS_IMETHODIMP
+nsAccVirtualCursorChangeEvent::GetOldAccessible(nsIAccessible** aOldAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aOldAccessible);
+
+  *aOldAccessible =
+    static_cast<AccVCChangeEvent*>(mEvent.get())->OldAccessible();
+  NS_IF_ADDREF(*aOldAccessible);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccVirtualCursorChangeEvent::GetOldStartOffset(PRInt32* aOldStartOffset)
+{
+  NS_ENSURE_ARG_POINTER(aOldStartOffset);
+
+  *aOldStartOffset =
+    static_cast<AccVCChangeEvent*>(mEvent.get())->OldStartOffset();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccVirtualCursorChangeEvent::GetOldEndOffset(PRInt32* aOldEndOffset)
+{
+  NS_ENSURE_ARG_POINTER(aOldEndOffset);
+
+  *aOldEndOffset =
+    static_cast<AccVCChangeEvent*>(mEvent.get())->OldEndOffset();
+  return NS_OK;
+}
--- a/accessible/src/xpcom/nsAccEvent.h
+++ b/accessible/src/xpcom/nsAccEvent.h
@@ -159,10 +159,30 @@ public:
   NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
 
 private:
   nsAccTableChangeEvent();
   nsAccTableChangeEvent(const nsAccTableChangeEvent&);
   nsAccTableChangeEvent& operator =(const nsAccTableChangeEvent&);
 };
 
+/**
+ * Accessible virtual cursor change event.
+ */
+class nsAccVirtualCursorChangeEvent : public nsAccEvent,
+                                      public nsIAccessibleVirtualCursorChangeEvent
+{
+public:
+  nsAccVirtualCursorChangeEvent(AccVCChangeEvent* aEvent) :
+    nsAccEvent(aEvent) { }
+  virtual ~nsAccVirtualCursorChangeEvent() { }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIACCESSIBLEVIRTUALCURSORCHANGEEVENT
+
+private:
+  nsAccVirtualCursorChangeEvent() MOZ_DELETE;
+  nsAccVirtualCursorChangeEvent(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
+  nsAccVirtualCursorChangeEvent& operator =(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
+};
+
 #endif
 
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -43,16 +43,33 @@ function testCSSAttrs(aID)
     "margin-right": computedStyle.marginRight,
     "margin-top": computedStyle.marginTop,
     "margin-bottom": computedStyle.marginBottom
   };
   testAttrs(aID, attrs, true);
 }
 
 /**
+ * Test the accessible that it doesn't have CSS-based object attributes.
+ */
+function testAbsentCSSAttrs(aID)
+{
+  var attrs = {
+    "display": "",
+    "text-align": "",
+    "text-indent": "",
+    "margin-left": "",
+    "margin-right": "",
+    "margin-top": "",
+    "margin-bottom": ""
+  };
+  testAbsentAttrs(aID, attrs);
+}
+
+/**
  * Test group object attributes (posinset, setsize and level) and
  * nsIAccessible::groupPosition() method.
  *
  * @param aAccOrElmOrID  [in] the ID, DOM node or accessible
  * @param aPosInSet      [in] the value of 'posinset' attribute
  * @param aSetSize       [in] the value of 'setsize' attribute
  * @param aLevel         [in, optional] the value of 'level' attribute
  */
--- a/accessible/tests/mochitest/attributes/test_obj_css.html
+++ b/accessible/tests/mochitest/attributes/test_obj_css.html
@@ -77,16 +77,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       testCSSAttrs("span");
       testCSSAttrs("div");
       testCSSAttrs("p");
       testCSSAttrs("input");
       testCSSAttrs("table");
       testCSSAttrs("tr");
       testCSSAttrs("td");
 
+      // no CSS-based object attributes
+      testAbsentCSSAttrs(getAccessible("listitem").firstChild);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
@@ -106,16 +109,21 @@ https://bugzilla.mozilla.org/show_bug.cg
      title="Expose IA2 margin- object attributes">
     Mozilla Bug 689540
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=714579"
      title="Don't use GetComputedStyle for object attribute calculation">
     Mozilla Bug 714579
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=729831"
+     title="Don't expose CSS-based object attributes on not in tree accessible and accessible having no DOM element">
+    Mozilla Bug 729831
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="display_block" role="img"
        style="display: block;">display: block</div>
@@ -184,10 +192,14 @@ https://bugzilla.mozilla.org/show_bug.cg
   <div id="div">It's div</div>
   <p id="p">It's paragraph"</p>
   <input id="input"/>
   <table id="table" style="margin: 2px; text-align: center; text-indent: 10%;">
     <tr id="tr" role="group">
       <td id="td">td</td>
     </tr>
   </table>
+
+  <ul>
+    <li id="listitem">item
+  </ul>
 </body>
 </html>
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -264,23 +264,29 @@
       tempElem = tempElem.nextSibling.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
       attrs = { "font-family": kMonospaceFontFamily };
       testTextAttrs(ID, 70, attrs, defAttrs, 69, 83);
 
       attrs = {};
       testTextAttrs(ID, 84, attrs, defAttrs, 83, 91);
 
-      attrs = { "text-underline-style": "solid" };
+      attrs = {
+        "text-underline-style": "solid",
+        "text-underline-color": gComputedStyle.color
+      };
       testTextAttrs(ID, 92, attrs, defAttrs, 91, 101);
 
       attrs = {};
       testTextAttrs(ID, 102, attrs, defAttrs, 101, 109);
 
-      attrs = { "text-line-through-style": "solid" };
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": gComputedStyle.color
+      };
       testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
 
       attrs = {};
       testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
 
       //////////////////////////////////////////////////////////////////////////
       // area10, different single style spans in non-styled paragraph
       ID = "area10";
@@ -318,23 +324,29 @@
       tempElem = tempElem.nextSibling.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
       attrs = { "font-family": kMonospaceFontFamily };
       testTextAttrs(ID, 71, attrs, defAttrs, 70, 84);
 
       attrs = {};
       testTextAttrs(ID, 85, attrs, defAttrs, 84, 92);
 
-      attrs = { "text-underline-style": "solid" };
+      attrs = {
+        "text-underline-style": "solid",
+        "text-underline-color": gComputedStyle.color
+      };
       testTextAttrs(ID, 93, attrs, defAttrs, 92, 102);
 
       attrs = {};
       testTextAttrs(ID, 103, attrs, defAttrs, 102, 110);
 
-      attrs = { "text-line-through-style": "solid" };
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": gComputedStyle.color
+      };
       testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
 
       attrs = {};
       testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
 
       //////////////////////////////////////////////////////////////////////////
       // area11, "font-weight" tests
       ID = "area11";
@@ -432,35 +444,82 @@
       testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);
 
       attrs = { "font-family": kCursiveFontFamily };
       testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
 
       attrs = { };
       testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
 
+      //////////////////////////////////////////////////////////////////////////
+      // area17, "text-decoration" tests
+      ID = "area17";
+      defAttrs = buildDefaultTextAttrs(ID, "12pt");
+      testDefaultTextAttrs(ID, defAttrs);
+
+      attrs = {
+        "text-underline-style": "solid",
+        "text-underline-color": "rgb(0, 0, 0)",
+      };
+      testTextAttrs(ID, 0, attrs, defAttrs, 0, 10);
+
+      attrs = {
+        "text-underline-style": "solid",
+        "text-underline-color": "rgb(0, 0, 255)",
+      };
+      testTextAttrs(ID, 10, attrs, defAttrs, 10, 15);
+
+      attrs = {
+        "text-underline-style": "dotted",
+        "text-underline-color": "rgb(0, 0, 0)",
+      };
+      testTextAttrs(ID, 15, attrs, defAttrs, 15, 22);
+
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": "rgb(0, 0, 0)",
+      };
+      testTextAttrs(ID, 22, attrs, defAttrs, 22, 34);
+
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": "rgb(0, 0, 255)",
+      };
+      testTextAttrs(ID, 34, attrs, defAttrs, 34, 39);
+
+      attrs = {
+        "text-line-through-style": "wavy",
+        "text-line-through-color": "rgb(0, 0, 0)",
+      };
+      testTextAttrs(ID, 39, attrs, defAttrs, 39, 44);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body style="font-size: 12pt">
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
      title="Implement text attributes">
     Mozilla Bug 345759
-  </a><br>
+  </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
      title="font-family text attribute should expose actual font used">
     Mozilla Bug 473576
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=523304"
+     title="expose text-underline-color and text-line-through-color text attributes">
+    Mozilla Bug 523304
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <p id="area1" style="font-size: smaller">Normal <b>Bold</b> Normal</p>
   <p id="area2" style="font-size: 120%">Normal <b>Bold <i>Italic </i>Bold</b> Normal</p>
   <p id="area3" style="background-color: blue;">
@@ -541,10 +600,20 @@
 
   <p id="area16" style="font-family: sans-serif;">
     <span style="font-family: monospace;">text</span>text
     <span style="font-family: serif;">text</span>text
     <span style="font-family: BodoniThatDoesntExist;">text</span>text
     <span style="font-family: Comic Sans MS, cursive;">text</span>text
     <span style="font-family: sans-serif, fantasy;">text</span>text
   </p>
+
+  <p id="area17">
+    <span style="-moz-text-decoration-line: underline;">underline
+    </span><span style="text-decoration: underline; -moz-text-decoration-color: blue;">blue
+    </span><span style="text-decoration: underline; -moz-text-decoration-style: dotted;">dotted
+    </span><span style="-moz-text-decoration-line: line-through;">linethrough
+    </span><span style="text-decoration: line-through; -moz-text-decoration-color: blue;">blue
+    </span><span style="text-decoration: line-through; -moz-text-decoration-style: wavy;">wavy
+    </span>
+  </p>
 </body>
 </html>
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -5,16 +5,18 @@ const nsIAccessibleRetrieval = Component
 
 const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
 const nsIAccessibleStateChangeEvent =
   Components.interfaces.nsIAccessibleStateChangeEvent;
 const nsIAccessibleCaretMoveEvent =
   Components.interfaces.nsIAccessibleCaretMoveEvent;
 const nsIAccessibleTextChangeEvent =
   Components.interfaces.nsIAccessibleTextChangeEvent;
+const nsIAccessibleVirtualCursorChangeEvent =
+  Components.interfaces.nsIAccessibleVirtualCursorChangeEvent;
 
 const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
 const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
 const nsIAccessibleScrollType = Components.interfaces.nsIAccessibleScrollType;
 const nsIAccessibleCoordinateType = Components.interfaces.nsIAccessibleCoordinateType;
 
 const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
 
--- a/accessible/tests/mochitest/pivot.js
+++ b/accessible/tests/mochitest/pivot.js
@@ -69,47 +69,87 @@ var ObjectTraversalRule =
  * A checker for virtual cursor changed events.
  */
 function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
 {
   this.__proto__ = new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc);
 
   this.check = function virtualCursorChangedChecker_check(aEvent)
   {
+    SimpleTest.info("virtualCursorChangedChecker_check");
+
+    var event = null;
+    try {
+      event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
+    } catch (e) {
+      SimpleTest.ok(false, "Does not support correct interface: " + e);
+    }
+
     var position = aDocAcc.virtualCursor.position;
 
     var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
     var nameMatches = position.name == aIdOrNameOrAcc;
     var accMatches = position == aIdOrNameOrAcc;
 
     SimpleTest.ok(idMatches || nameMatches || accMatches, "id or name matches",
                   "expecting " + aIdOrNameOrAcc + ", got '" +
                   prettyName(position));
 
     if (aTextOffsets) {
       SimpleTest.is(aDocAcc.virtualCursor.startOffset, aTextOffsets[0],
                     "wrong start offset");
       SimpleTest.is(aDocAcc.virtualCursor.endOffset, aTextOffsets[1],
                     "wrong end offset");
     }
+
+    var prevPosAndOffset = virtualCursorChangedChecker.
+      getPreviousPosAndOffset(aDocAcc.virtualCursor);
+
+    if (prevPosAndOffset) {
+      SimpleTest.is(event.oldAccessible, prevPosAndOffset.position,
+                    "previous position does not match");
+      SimpleTest.is(event.oldStartOffset, prevPosAndOffset.startOffset,
+                    "previous start offset does not match");
+      SimpleTest.is(event.oldEndOffset, prevPosAndOffset.endOffset,
+                    "previous end offset does not match");
+    }
   };
 }
 
+virtualCursorChangedChecker.prevPosAndOffset = {};
+
+virtualCursorChangedChecker.storePreviousPosAndOffset =
+  function storePreviousPosAndOffset(aPivot)
+{
+  virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
+    {position: aPivot.position,
+     startOffset: aPivot.startOffset,
+     endOffset: aPivot.endOffset};
+};
+
+virtualCursorChangedChecker.getPreviousPosAndOffset =
+  function getPreviousPosAndOffset(aPivot)
+{
+  return virtualCursorChangedChecker.prevPosAndOffset[aPivot];
+};
+
 /**
  * Set a text range in the pivot and wait for virtual cursor change event.
  *
  * @param aDocAcc document that manages the virtual cursor
  * @param aTextAccessible accessible to set to virtual cursor's position
  * @param aTextOffsets start and end offsets of text range to set in virtual
  *   cursor
  */
 function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
 {
   this.invoke = function virtualCursorChangedInvoker_invoke()
   {
+    virtualCursorChangedChecker.
+      storePreviousPosAndOffset(aDocAcc.virtualCursor);
     SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
     aDocAcc.virtualCursor.setTextRange(aTextAccessible,
                                        aTextOffsets[0],
                                        aTextOffsets[1]);
   };
 
   this.getID = function setVirtualCursorRangeInvoker_getID()
   {
@@ -131,16 +171,18 @@ function setVirtualCursorRangeInvoker(aD
  * @param aIdOrNameOrAcc id, accessivle or accessible name to expect virtual
  *   cursor to land on after performing move method.
  */
 function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
                                     aIdOrNameOrAcc)
 {
   this.invoke = function virtualCursorChangedInvoker_invoke()
   {
+    virtualCursorChangedChecker.
+      storePreviousPosAndOffset(aDocAcc.virtualCursor);
     var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
     SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
                   "moved pivot");
   };
 
   this.getID = function setVirtualCursorPosInvoker_getID()
   {
     return "Do " + (aIdOrNameOrAcc ? "" : "no-op ") + aPivotMoveMethod;
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1330367012000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1331241604000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
@@ -14,28 +14,16 @@
                     </versionRange>
                   </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i43" id="supportaccessplugin@gmail.com">
                         </emItem>
-      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
-                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion="3.3.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="5.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i65" id="activity@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i66" id="youtubeer@youtuber.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
@@ -58,54 +46,32 @@
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
                         </emItem>
-      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
-                        <versionRange  minVersion="2.1" maxVersion="3.3">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion=" " maxVersion="6.9.8">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i63" id="youtube@youtuber.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i18" id="msntoolbar@msn.com">
                         <versionRange  minVersion=" " maxVersion="6.*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
                         </emItem>
       <emItem  blockID="i64" id="royal@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
-                        <versionRange  minVersion="1.2" maxVersion="1.2">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i50" id="firebug@software.joehewitt.com">
-                        <versionRange  minVersion="0" maxVersion="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="9.0a1" maxVersion="9.*" />
-                          </targetApplication>
+      <emItem  blockID="i72" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
+                        <versionRange  minVersion="0" maxVersion="3.4.1.194" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
                         <versionRange  minVersion="2.0.3" maxVersion="2.0.3">
@@ -116,60 +82,36 @@
                     </versionRange>
                   </emItem>
       <emItem  blockID="i70" id="psid-vhvxQHMZBOzUZA@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
                         </emItem>
-      <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
-                        <versionRange  minVersion="0.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="9.0a1" maxVersion="9.0" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i67" id="youtube2@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i60" id="youtb3@youtb3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i23" id="firefox@bandoo.com">
-                        <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
+      <emItem  blockID="i56" id="flash@adobe.com">
+                        <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i55" id="youtube@youtube7.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
-                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.5.7" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
                         <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
-                        <versionRange  minVersion="1.0" maxVersion="1.3.1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i44" id="sigma@labs.mozilla">
                         </emItem>
       <emItem  blockID="i5" id="support@daemon-tools.cc">
                         <versionRange  minVersion=" " maxVersion="1.0.0.5">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -198,102 +140,49 @@
       <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
                         <versionRange  minVersion="2.2" maxVersion="2.2">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i56" id="flash@adobe.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
-                        <versionRange  minVersion="0.1" maxVersion="7.6.1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="8.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
                         <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i51" id="admin@youtubeplayer.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i52" id="ff-ext@youtube">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i15" id="personas@christopher.beard">
-                        <versionRange  minVersion="1.6" maxVersion="1.6">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i21" id="support@update-firefox.com">
                         </emItem>
     </emItems>
 
   <pluginItems>
-      <pluginItem  blockID="p26">
-      <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p27">
-      <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
       <pluginItem  blockID="p28">
                   <match name="filename" exp="NPFFAddOn.dll" />              <versionRange >
                   </versionRange>
           </pluginItem>
       <pluginItem  blockID="p31">
                   <match name="filename" exp="NPMySrch.dll" />              <versionRange >
                   </versionRange>
           </pluginItem>
-      <pluginItem  blockID="p32">
-                  <match name="filename" exp="npViewpoint.dll" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
       <pluginItem  blockID="p33">
       <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />              <versionRange  severity="1">
                   </versionRange>
           </pluginItem>
-      <pluginItem  blockID="p34">
-                  <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />              <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.6a1pre" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">
       <os>WINNT 6.1</os>
       <vendor>0x10de</vendor>
               <devices>
                       <device>0x0a6c</device>
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -286,22 +286,22 @@
                               accesskey="&fullZoomToggleCmd.accesskey;"
                               type="checkbox"
                               command="cmd_fullZoomToggle"
                               checked="false"/>
                   </menupopup>
                 </menu>
                 <menu id="pageStyleMenu" label="&pageStyleMenu.label;"
                       accesskey="&pageStyleMenu.accesskey;" observes="isImage">
-                  <menupopup onpopupshowing="stylesheetFillPopup(this);"
-                             oncommand="stylesheetSwitchAll(window.content, event.target.getAttribute('data')); setStyleDisabled(false);">
+                  <menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);"
+                             oncommand="gPageStyleMenu.switchStyleSheet(event.target.getAttribute('data'));">
                     <menuitem id="menu_pageStyleNoStyle"
                               label="&pageStyleNoStyle.label;"
                               accesskey="&pageStyleNoStyle.accesskey;"
-                              oncommand="setStyleDisabled(true); event.stopPropagation();"
+                              oncommand="gPageStyleMenu.disableStyle(); event.stopPropagation();"
                               type="radio"/>
                     <menuitem id="menu_pageStylePersistentOnly"
                               label="&pageStylePersistentOnly.label;"
                               accesskey="&pageStylePersistentOnly.accesskey;"
                               type="radio"
                               checked="true"/>
                     <menuseparator/>
                   </menupopup>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5326,33 +5326,28 @@ function setToolbarVisibility(toolbar, i
 
 #ifdef MENUBAR_CAN_AUTOHIDE
   updateAppButtonDisplay();
 #endif
 }
 
 var TabsOnTop = {
   init: function TabsOnTop_init() {
-    this._initialized = true;
-    this.syncUI();
     Services.prefs.addObserver(this._prefName, this, false);
   },
 
   uninit: function TabsOnTop_uninit() {
     Services.prefs.removeObserver(this._prefName, this);
   },
 
   toggle: function () {
     this.enabled = !Services.prefs.getBoolPref(this._prefName);
   },
 
   syncUI: function () {
-    if (!this._initialized)
-      return;
-
     let userEnabled = Services.prefs.getBoolPref(this._prefName);
     let enabled = userEnabled && gBrowser.tabContainer.visible;
 
     document.getElementById("cmd_ToggleTabsOnTop")
             .setAttribute("checked", userEnabled);
 
     document.documentElement.setAttribute("tabsontop", enabled);
     document.getElementById("navigator-toolbox").setAttribute("tabsontop", enabled);
@@ -6092,33 +6087,33 @@ function charsetLoadListener(event) {
     gPrevCharset = gLastBrowserCharset;
     gLastBrowserCharset = charset;
   }
 }
 
 
 var gPageStyleMenu = {
 
-  getAllStyleSheets: function (frameset) {
+  _getAllStyleSheets: function (frameset) {
     var styleSheetsArray = Array.slice(frameset.document.styleSheets);
     for (let i = 0; i < frameset.frames.length; i++) {
-      let frameSheets = this.getAllStyleSheets(frameset.frames[i]);
+      let frameSheets = this._getAllStyleSheets(frameset.frames[i]);
       styleSheetsArray = styleSheetsArray.concat(frameSheets);
     }
     return styleSheetsArray;
   },
 
-  stylesheetFillPopup: function (menuPopup) {
+  fillPopup: function (menuPopup) {
     var noStyle = menuPopup.firstChild;
     var persistentOnly = noStyle.nextSibling;
     var sep = persistentOnly.nextSibling;
     while (sep.nextSibling)
       menuPopup.removeChild(sep.nextSibling);
 
-    var styleSheets = this.getAllStyleSheets(window.content);
+    var styleSheets = this._getAllStyleSheets(window.content);
     var currentStyleSheets = {};
     var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
     var haveAltSheets = false;
     var altStyleSelected = false;
 
     for (let i = 0; i < styleSheets.length; ++i) {
       let currentStyleSheet = styleSheets[i];
 
@@ -6156,56 +6151,64 @@ var gPageStyleMenu = {
 
     noStyle.setAttribute("checked", styleDisabled);
     persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
     persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
     sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
     return true;
   },
 
-  stylesheetInFrame: function (frame, title) {
+  _stylesheetInFrame: function (frame, title) {
     return Array.some(frame.document.styleSheets,
                       function (stylesheet) stylesheet.title == title);
   },
 
-  stylesheetSwitchFrame: function (frame, title) {
+  _stylesheetSwitchFrame: function (frame, title) {
     var docStyleSheets = frame.document.styleSheets;
 
     for (let i = 0; i < docStyleSheets.length; ++i) {
       let docStyleSheet = docStyleSheets[i];
 
       if (title == "_nostyle")
         docStyleSheet.disabled = true;
       else if (docStyleSheet.title)
         docStyleSheet.disabled = (docStyleSheet.title != title);
       else if (docStyleSheet.disabled)
         docStyleSheet.disabled = false;
     }
   },
 
-  stylesheetSwitchAll: function (frameset, title) {
-    if (!title || title == "_nostyle" || this.stylesheetInFrame(frameset, title))
-      this.stylesheetSwitchFrame(frameset, title);
+  _stylesheetSwitchAll: function (frameset, title) {
+    if (!title || title == "_nostyle" || this._stylesheetInFrame(frameset, title))
+      this._stylesheetSwitchFrame(frameset, title);
 
     for (let i = 0; i < frameset.frames.length; i++)
-      this.stylesheetSwitchAll(frameset.frames[i], title);
-  },
-
-  setStyleDisabled: function (disabled) {
-    getMarkupDocumentViewer().authorStyleDisabled = disabled;
+      this._stylesheetSwitchAll(frameset.frames[i], title);
+  },
+
+  switchStyleSheet: function (title, contentWindow) {
+    getMarkupDocumentViewer().authorStyleDisabled = false;
+    this._stylesheetSwitchAll(contentWindow || content, title);
+  },
+
+  disableStyle: function () {
+    getMarkupDocumentViewer().authorStyleDisabled = true;
   },
 };
 
 /* Legacy global page-style functions */
-var getAllStyleSheets     = gPageStyleMenu.getAllStyleSheets;
-var stylesheetFillPopup   = gPageStyleMenu.stylesheetFillPopup;
-var stylesheetInFrame     = gPageStyleMenu.stylesheetInFrame;
-var stylesheetSwitchFrame = gPageStyleMenu.stylesheetSwitchFrame;
-var stylesheetSwitchAll   = gPageStyleMenu.stylesheetSwitchAll;
-var setStyleDisabled      = gPageStyleMenu.setStyleDisabled;
+var getAllStyleSheets   = gPageStyleMenu._getAllStyleSheets.bind(gPageStyleMenu);
+var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
+function stylesheetSwitchAll(contentWindow, title) {
+  gPageStyleMenu.switchStyleSheet(title, contentWindow);
+}
+function setStyleDisabled(disabled) {
+  if (disabled)
+    gPageStyleMenu.disableStyle();
+}
 
 
 var BrowserOffline = {
   _inited: false,
 
   /////////////////////////////////////////////////////////////////////////////
   // BrowserOffline Public Methods
   init: function ()
old mode 100644
new mode 100755
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2774,19 +2774,17 @@
                            this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle"));
           tab.setAttribute("crop", "end");
           tab.setAttribute("validate", "never");
           tab.setAttribute("onerror", "this.removeAttribute('image');");
           this.adjustTabstrip();
 
           Services.prefs.addObserver("browser.tabs.", this._prefObserver, false);
           window.addEventListener("resize", this, false);
-
-          this.updateVisibility();
-          this._propagateVisibility();
+          window.addEventListener("load", this, false);
         ]]>
       </constructor>
 
       <destructor>
         <![CDATA[
           Services.prefs.removeObserver("browser.tabs.", this._prefObserver);
         ]]>
       </destructor>
@@ -2836,25 +2834,29 @@
 
       <field name="_dragOverDelay">350</field>
       <field name="_dragTime">0</field>
 
       <field name="_container" readonly="true"><![CDATA[
         this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
       ]]></field>
 
+      <field name="_propagatedVisibilityOnce">false</field>
+
       <property name="visible"
                 onget="return !this._container.collapsed;">
         <setter><![CDATA[
-          if (val == this.visible)
+          if (val == this.visible &&
+              this._propagatedVisibilityOnce)
             return val;
 
           this._container.collapsed = !val;
 
           this._propagateVisibility();
+          this._propagatedVisibilityOnce = true;
 
           return val;
         ]]></setter>
       </property>
 
       <method name="_propagateVisibility">
         <body><![CDATA[
           let visible = this.visible;
@@ -3075,16 +3077,19 @@
           this.mTabstrip.ensureElementIsVisible(this.selectedItem, false);
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
+            case "load":
+              this.updateVisibility();
+              break;
             case "resize":
               if (aEvent.target != window)
                 break;
               var width = this.mTabstrip.boxObject.width;
               if (width != this.mTabstripWidth) {
                 this.adjustTabstrip();
                 this._fillTrailingGap();
                 this._handleTabSelect();
--- a/browser/base/content/test/browser_page_style_menu.js
+++ b/browser/base/content/test/browser_page_style_menu.js
@@ -9,17 +9,17 @@ function test() {
   }, true);
   let rootDir = getRootDirectory(gTestPath);
   content.location = rootDir + "page_style_sample.html";
 }
 
 function checkPageStyleMenu() {
   var menupopup = document.getElementById("pageStyleMenu")
                           .getElementsByTagName("menupopup")[0];
-  stylesheetFillPopup(menupopup);
+  gPageStyleMenu.fillPopup(menupopup);
 
   var items = [];
   var current = menupopup.getElementsByTagName("menuseparator")[0];
   while (current.nextSibling) {
     current = current.nextSibling;
     items.push(current);
   }
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -59,16 +59,19 @@ XPCOMUtils.defineLazyGetter(this, "NetUt
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
   Cu.import("resource://gre/modules/PlacesUtils.jsm");
   return PlacesUtils;
 });
 
+XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
+                                  "resource:///modules/KeywordURLResetPrompter.jsm");
+
 const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
 const PREF_PLUGINS_UPDATEURL  = "plugins.update.url";
 
 // We try to backup bookmarks at idle times, to avoid doing that at shutdown.
 // Number of idle seconds before trying to backup bookmarks.  15 minutes.
 const BOOKMARKS_BACKUP_IDLE_TIME = 15 * 60;
 // Minimum interval in milliseconds between backups.
 const BOOKMARKS_BACKUP_INTERVAL = 86400 * 1000;
@@ -272,16 +275,23 @@ BrowserGlue.prototype = {
           this._distributionCustomizer.applyPrefDefaults();
           this._distributionCustomizer.applyCustomizations();
           // To apply distribution bookmarks use "places-init-complete".
         }
         else if (data == "force-places-init") {
           this._initPlaces();
         }
         break;
+      case "defaultURIFixup-using-keyword-pref":
+        if (KeywordURLResetPrompter.shouldPrompt) {
+          let keywordURI = subject.QueryInterface(Ci.nsIURI);
+          KeywordURLResetPrompter.prompt(this.getMostRecentBrowserWindow(),
+                                         keywordURI);
+        }
+        break;
     }
   }, 
 
   // initialization (called on application startup) 
   _init: function BG__init() {
     let os = Services.obs;
     os.addObserver(this, "xpcom-shutdown", false);
     os.addObserver(this, "prefservice:after-app-defaults", false);
@@ -301,16 +311,17 @@ BrowserGlue.prototype = {
     os.addObserver(this, "session-save", false);
     os.addObserver(this, "places-init-complete", false);
     this._isPlacesInitObserver = true;
     os.addObserver(this, "places-database-locked", false);
     this._isPlacesLockedObserver = true;
     os.addObserver(this, "distribution-customization-complete", false);
     os.addObserver(this, "places-shutdown", false);
     this._isPlacesShutdownObserver = true;
+    os.addObserver(this, "defaultURIFixup-using-keyword-pref", false);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function BG__dispose() {
     let os = Services.obs;
     os.removeObserver(this, "xpcom-shutdown");
     os.removeObserver(this, "prefservice:after-app-defaults");
     os.removeObserver(this, "final-ui-startup");
@@ -329,16 +340,17 @@ BrowserGlue.prototype = {
     if (this._isIdleObserver)
       this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
     if (this._isPlacesInitObserver)
       os.removeObserver(this, "places-init-complete");
     if (this._isPlacesLockedObserver)
       os.removeObserver(this, "places-database-locked");
     if (this._isPlacesShutdownObserver)
       os.removeObserver(this, "places-shutdown");
+    os.removeObserver(this, "defaultURIFixup-using-keyword-pref");
   },
 
   _onAppDefaults: function BG__onAppDefaults() {
     // apply distribution customizations (prefs)
     // other customizations are applied in _onProfileStartup()
     this._distributionCustomizer.applyPrefDefaults();
   },
 
--- a/browser/components/sessionstore/test/browser_408470.js
+++ b/browser/components/sessionstore/test/browser_408470.js
@@ -45,18 +45,18 @@ function test() {
   let tab = gBrowser.addTab(testUrl);
   
   tab.linkedBrowser.addEventListener("load", function(aEvent) {
     tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
     // enable all stylesheets and verify that they're correctly persisted
     Array.forEach(tab.linkedBrowser.contentDocument.styleSheets, function(aSS, aIx) {
       pendingCount++;
       let ssTitle = aSS.title;
-      stylesheetSwitchAll(tab.linkedBrowser.contentWindow, ssTitle);
-      
+      gPageStyleMenu.switchStyleSheet(ssTitle, tab.linkedBrowser.contentWindow);
+
       let newTab = gBrowser.duplicateTab(tab);
       newTab.linkedBrowser.addEventListener("load", function(aEvent) {
         newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
         let states = Array.map(newTab.linkedBrowser.contentDocument.styleSheets,
                                function(aSS) !aSS.disabled);
         let correct = states.indexOf(true) == aIx && states.indexOf(true, aIx + 1) == -1;
         
         if (/^fail_/.test(ssTitle))
--- a/browser/devtools/debugger/DebuggerUI.jsm
+++ b/browser/devtools/debugger/DebuggerUI.jsm
@@ -563,16 +563,17 @@ DebuggerUI.prototype = {
    *        The content type of the source script.
    */
   _onSourceLoaded: function DebuggerUI__onSourceLoaded(aSourceUrl,
                                                        aSourceText,
                                                        aContentType) {
     let dbg = this.getDebugger(this.aWindow.gBrowser.selectedTab);
     dbg.debuggerWindow.SourceScripts.setEditorMode(aSourceUrl, aContentType);
     dbg.editor.setText(aSourceText);
+    dbg.editor.resetUndo();
     let doc = dbg.frame.contentDocument;
     let scripts = doc.getElementById("scripts");
     let elt = scripts.getElementsByAttribute("value", aSourceUrl)[0];
     let script = elt.getUserData("sourceScript");
     script.loaded = true;
     script.text = aSourceText;
     script.contentType = aContentType;
     elt.setUserData("sourceScript", script, null);
--- a/browser/devtools/debugger/debugger.js
+++ b/browser/devtools/debugger/debugger.js
@@ -610,16 +610,17 @@ var SourceScripts = {
       var evt = document.createEvent("CustomEvent");
       evt.initCustomEvent("Debugger:LoadSource", true, false, aScript.url);
       document.documentElement.dispatchEvent(evt);
       window.editor.setText(DebuggerView.getStr("loadingText"));
     } else {
       window.editor.setText(aScript.text);
       window.updateEditorBreakpoints();
     }
+    window.editor.resetUndo();
   }
 };
 
 SourceScripts.onPaused = SourceScripts.onPaused.bind(SourceScripts);
 SourceScripts.onScripts = SourceScripts.onScripts.bind(SourceScripts);
 SourceScripts.onNewScript = SourceScripts.onNewScript.bind(SourceScripts);
 SourceScripts.onScriptsCleared = SourceScripts.onScriptsCleared.bind(SourceScripts);
 SourceScripts.onChange = SourceScripts.onChange.bind(SourceScripts);
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -40,20 +40,39 @@
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/orion.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/debugger.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/devtools/debugger.css" type="text/css"?>
 <!DOCTYPE window [
 <!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
  %debuggerDTD;
 ]>
+<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
+<?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
 <xul:window xmlns="http://www.w3.org/1999/xhtml"
             xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+    <xul:script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
     <xul:script type="text/javascript" src="debugger.js"/>
     <xul:script type="text/javascript" src="debugger-view.js"/>
+    <xul:popupset id="debugger-popups">
+      <xul:menupopup id="sourceEditorContextMenu"
+                     onpopupshowing="goUpdateSourceEditorMenuItems()">
+        <xul:menuitem id="se-cMenu-copy"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="se-cMenu-selectAll"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="se-cMenu-find"/>
+        <xul:menuitem id="se-cMenu-findAgain"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="se-cMenu-gotoLine"/>
+      </xul:menupopup>
+    </xul:popupset>
+    <xul:commandset id="editMenuCommands"/>
+    <xul:commandset id="sourceEditorCommands"/>
+    <xul:keyset id="sourceEditorKeys"/>
 
     <div id="body" class="vbox flex">
         <xul:toolbar id="dbg-toolbar">
             <xul:button id="close">&debuggerUI.closeButton;</xul:button>
             <xul:button id="resume"/>
             <xul:menulist id="scripts"/>
         </xul:toolbar>
         <div id="dbg-content" class="hbox flex">
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -69,16 +69,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_dbg_stack-04.js \
 	browser_dbg_location-changes.js \
 	browser_dbg_script-switching.js \
 	browser_dbg_pause-resume.js \
 	browser_dbg_update-editor-mode.js \
 	browser_dbg_select-line.js \
 	browser_dbg_clean-exit.js \
 	browser_dbg_bug723069_editor-breakpoints.js \
+	browser_dbg_bug731394_editor-contextmenu.js \
 	head.js \
 	$(NULL)
 
 _BROWSER_TEST_PAGES = \
 	browser_dbg_tab1.html \
 	browser_dbg_tab2.html \
 	browser_dbg_debuggerstatement.html \
 	browser_dbg_stack.html \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
@@ -0,0 +1,102 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Bug 731394: test the debugger source editor default context menu.
+ */
+
+const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
+
+let gPane = null;
+let gTab = null;
+let gDebuggee = null;
+let gDebugger = null;
+
+function test()
+{
+  let tempScope = {};
+  Cu.import("resource:///modules/source-editor.jsm", tempScope);
+  let SourceEditor = tempScope.SourceEditor;
+
+  let contextMenu = null;
+
+  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.debuggerWindow;
+
+    gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+      Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
+    });
+    gDebuggee.firstCall();
+  });
+
+  function onScriptsAdded()
+  {
+    let scripts = gDebugger.DebuggerView.Scripts._scripts;
+
+    is(gDebugger.StackFrames.activeThread.state, "paused",
+      "Should only be getting stack frames while paused.");
+
+    is(scripts.itemCount, 2, "Found the expected number of scripts.");
+
+    let editor = gDebugger.editor;
+
+    isnot(editor.getText().indexOf("debugger"), -1,
+          "The correct script was loaded initially.");
+
+    contextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
+    ok(contextMenu, "source editor context menupopup");
+    ok(editor.readOnly, "editor is read only");
+
+    editor.focus();
+    editor.setSelection(0, 10);
+
+    contextMenu.addEventListener("popupshown", function onPopupShown() {
+      contextMenu.removeEventListener("popupshown", onPopupShown, false);
+      executeSoon(testContextMenu);
+    }, false);
+    contextMenu.openPopup(editor.editorElement, "overlap", 0, 0, true, false);
+  }
+
+  function testContextMenu()
+  {
+    let document = gDebugger.document;
+
+    ok(document.getElementById("editMenuCommands"),
+       "#editMenuCommands found");
+    ok(!document.getElementById("editMenuKeys"),
+       "#editMenuKeys not found");
+    ok(document.getElementById("sourceEditorCommands"),
+       "#sourceEditorCommands found");
+    ok(document.getElementById("sourceEditorKeys"),
+       "#sourceEditorKeys found");
+
+    // Map command ids to their expected disabled state.
+    let commands = {"se-cmd-undo": true, "se-cmd-redo": true,
+                    "se-cmd-cut": true, "se-cmd-paste": true,
+                    "se-cmd-delete": true, "cmd_findAgain": true,
+                    "cmd_findPrevious": true, "cmd_find": false,
+                    "cmd_gotoLine": false, "cmd_copy": false,
+                    "se-cmd-selectAll": false};
+    for (let id in commands) {
+      let element = document.getElementById(id);
+      is(element.hasAttribute("disabled"), commands[id],
+         id + " hasAttribute('disabled') check");
+    }
+
+    executeSoon(function() {
+      contextMenu.hidePopup();
+      gDebugger.StackFrames.activeThread.resume(finish);
+    });
+  }
+
+  registerCleanupFunction(function() {
+    removeTab(gTab);
+    gPane = null;
+    gTab = null;
+    gDebuggee = null;
+    gDebugger = null;
+  });
+}
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -5,14 +5,14 @@ browser.jar:
     content/browser/scratchpad.js                 (scratchpad/scratchpad.js)
     content/browser/splitview.css                 (shared/splitview.css)
 *   content/browser/styleeditor.xul               (styleeditor/styleeditor.xul)
     content/browser/styleeditor.css               (styleeditor/styleeditor.css)
     content/browser/devtools/csshtmltree.xul      (styleinspector/csshtmltree.xul)
     content/browser/devtools/cssruleview.xul      (styleinspector/cssruleview.xul)
     content/browser/devtools/styleinspector.css   (styleinspector/styleinspector.css)
     content/browser/orion.js                      (sourceeditor/orion/orion.js)
-    content/browser/source-editor-overlay.xul     (sourceeditor/source-editor-overlay.xul)
+*   content/browser/source-editor-overlay.xul     (sourceeditor/source-editor-overlay.xul)
 *   content/browser/debugger.xul                  (debugger/debugger.xul)
     content/browser/debugger.css                  (debugger/debugger.css)
     content/browser/debugger.js                   (debugger/debugger.js)
     content/browser/debugger-view.js              (debugger/debugger-view.js)
 
--- a/browser/devtools/scratchpad/scratchpad.xul
+++ b/browser/devtools/scratchpad/scratchpad.xul
@@ -106,31 +106,16 @@
 
   <!-- TODO: bug 650340 - implement printFile
   <key id="sp-key-printFile"
        key="&printCmd.commandkey;"
        command="sp-cmd-printFile"
        modifiers="accel"/>
   -->
 
-  <key id="key_cut"
-       key="&cutCmd.key;"
-       modifiers="accel"/>
-
-  <key id="key_copy"
-       key="&copyCmd.key;"
-       modifiers="accel"/>
-  <key id="key_paste"
-       key="&pasteCmd.key;"
-       modifiers="accel"/>
-  <key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
-  <key id="key_undo" key="&undoCmd.key;" modifiers="accel"
-       command="se-cmd-undo"/>
-  <key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"
-       command="se-cmd-redo"/>
   <key id="sp-key-run"
        key="&run.key;"
        command="sp-cmd-run"
        modifiers="accel"/>
   <key id="sp-key-inspect"
        key="&inspect.key;"
        command="sp-cmd-inspect"
        modifiers="accel"/>
@@ -141,38 +126,16 @@
   <key id="sp-key-errorConsole"
        key="&errorConsoleCmd.commandkey;"
        command="sp-cmd-errorConsole"
        modifiers="accel,shift"/>
   <key id="sp-key-webConsole"
        key="&webConsoleCmd.commandkey;"
        command="sp-cmd-webConsole"
        modifiers="accel,shift"/>
-  <key id="key_find"
-       key="&findCmd.key;"
-       command="cmd_find"
-       modifiers="accel"/>
-#ifdef XP_MACOSX
-  <key id="key_findAgain"
-       key="&findAgainCmd.key;"
-       command="cmd_findAgain"
-       modifiers="accel"/>
-  <key id="key_findPrevious"
-       key="&findPreviousCmd.key;"
-       command="cmd_findPrevious"
-       modifiers="accel,shift"/>
-#else
-  <key id="key_findAgain"
-       keycode="VK_F3"
-       command="cmd_findAgain"/>
-  <key id="key_findPrevious"
-       keycode="VK_F3"
-       command="cmd_findPrevious"
-       modifiers="shift"/>
-#endif
   <key id="key_openHelp"
        keycode="VK_F1"
        command="sp-cmd-documentationLink"/>
 </keyset>
 
 
 <menubar id="sp-menubar">
   <menu id="sp-file-menu" label="&fileMenu.label;"
@@ -214,66 +177,30 @@
                 accesskey="&closeCmd.accesskey;"
                 command="sp-cmd-close"/>
     </menupopup>
   </menu>
 
   <menu id="sp-edit-menu" label="&editMenu.label;"
         accesskey="&editMenu.accesskey;">
     <menupopup id="sp-menu_editpopup"
-               onpopupshowing="goUpdateGlobalEditMenuItems()">
-      <menuitem id="sp-menu-undo"
-                label="&undoCmd.label;"
-                key="key_undo"
-                accesskey="&undoCmd.accesskey;"
-                command="se-cmd-undo"/>
-      <menuitem id="sp-menu-redo"
-                label="&redoCmd.label;"
-                key="key_redo"
-                accesskey="&redoCmd.accesskey;"
-                command="se-cmd-redo"/>
+               onpopupshowing="goUpdateSourceEditorMenuItems()">
+      <menuitem id="se-menu-undo"/>
+      <menuitem id="se-menu-redo"/>
       <menuseparator/>
-      <menuitem id="sp-menu-cut"
-                label="&cutCmd.label;"
-                key="key_cut"
-                accesskey="&cutCmd.accesskey;"
-                command="cmd_cut"/>
-      <menuitem id="sp-menu-copy"
-                label="&copyCmd.label;"
-                key="key_copy"
-                accesskey="&copyCmd.accesskey;"
-                command="cmd_copy"/>
-      <menuitem id="sp-menu-paste"
-                label="&pasteCmd.label;"
-                key="key_paste"
-                accesskey="&pasteCmd.accesskey;"
-                command="cmd_paste"/>
+      <menuitem id="se-menu-cut"/>
+      <menuitem id="se-menu-copy"/>
+      <menuitem id="se-menu-paste"/>
       <menuseparator/>
-      <menuitem id="sp-menu-selectAll"
-                label="&selectAllCmd.label;"
-                key="key_selectAll"
-                accesskey="&selectAllCmd.accesskey;"
-                command="cmd_selectAll"/>
+      <menuitem id="se-menu-selectAll"/>
       <menuseparator/>
-      <menuitem id="sp-menu-find"
-                label="&findCmd.label;"
-                accesskey="&findCmd.accesskey;"
-                key="key_find"
-                command="cmd_find"/>
-      <menuitem id="sp-menu-findAgain"
-                label="&findAgainCmd.label;"
-                accesskey="&findAgainCmd.accesskey;"
-                key="key_findAgain"
-                command="cmd_findAgain"/>
+      <menuitem id="se-menu-find"/>
+      <menuitem id="se-menu-findAgain"/>
       <menuseparator/>
-      <menuitem id="sp-menu-gotoLine"
-                label="&gotoLineCmd.label;"
-                accesskey="&gotoLineCmd.accesskey;"
-                key="key_gotoLine"
-                command="cmd_gotoLine"/>
+      <menuitem id="se-menu-gotoLine"/>
     </menupopup>
   </menu>
 
   <menu id="sp-execute-menu" label="&executeMenu.label;"
         accesskey="&executeMenu.accesskey;">
     <menupopup id="sp-menu_executepopup">
       <menuitem id="sp-text-run"
                 label="&run.label;"
@@ -333,23 +260,23 @@
                 command="sp-cmd-documentationLink"
                 key="key_openHelp"/>
     </menupopup>
   </menu>
 </menubar>
 
 <popupset id="scratchpad-popups">
   <menupopup id="scratchpad-text-popup"
-             onpopupshowing="goUpdateGlobalEditMenuItems()">
-    <menuitem id="menu_cut"/>
-    <menuitem id="menu_copy"/>
-    <menuitem id="menu_paste"/>
-    <menuitem id="menu_delete"/>
+             onpopupshowing="goUpdateSourceEditorMenuItems()">
+    <menuitem id="se-cMenu-cut"/>
+    <menuitem id="se-cMenu-copy"/>
+    <menuitem id="se-cMenu-paste"/>
+    <menuitem id="se-cMenu-delete"/>
     <menuseparator/>
-    <menuitem id="menu_selectAll"/>
+    <menuitem id="se-cMenu-selectAll"/>
     <menuseparator/>
     <menuitem id="sp-text-run"
               label="&run.label;"
               accesskey="&run.accesskey;"
               key="sp-key-run"
               command="sp-cmd-run"/>
     <menuitem id="sp-text-inspect"
               label="&inspect.label;"
@@ -365,12 +292,12 @@
     <menuitem id="sp-text-resetContext"
               label="&resetContext2.label;"
               accesskey="&resetContext2.accesskey;"
               command="sp-cmd-resetContext"/>
   </menupopup>
 </popupset>
 
 <notificationbox id="scratchpad-notificationbox" flex="1">
-  <hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" />
+  <hbox id="scratchpad-editor" flex="1"/>
 </notificationbox>
 
 </window>
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug_699130_edit_ui_updates.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug_699130_edit_ui_updates.js
@@ -22,17 +22,17 @@ function test()
 }
 
 function runTests()
 {
   let sp = gScratchpadWindow.Scratchpad;
   let doc = gScratchpadWindow.document;
   let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
                  getInterface(Ci.nsIDOMWindowUtils);
-  let OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
+  let OS = Services.appinfo.OS;
 
   info("will test the Edit menu");
 
   let pass = 0;
 
   sp.setText("bug 699130: hello world! (edit menu)");
 
   let editMenu = doc.getElementById("sp-edit-menu");
@@ -46,19 +46,19 @@ function runTests()
       editMenuIndex = i;
       break;
     }
   }
   isnot(editMenuIndex, -1, "Edit menu index is correct");
 
   let menuPopup = editMenu.menupopup;
   ok(menuPopup, "the Edit menupopup");
-  let cutItem = doc.getElementById("sp-menu-cut");
+  let cutItem = doc.getElementById("se-menu-cut");
   ok(cutItem, "the Cut menuitem");
-  let pasteItem = doc.getElementById("sp-menu-paste");
+  let pasteItem = doc.getElementById("se-menu-paste");
   ok(pasteItem, "the Paste menuitem");
 
   let anchor = doc.documentElement;
   let isContextMenu = false;
 
   let openMenu = function(aX, aY, aCallback) {
     if (!editMenu || OS != "Darwin") {
       menuPopup.addEventListener("popupshown", function onPopupShown() {
@@ -169,19 +169,19 @@ function runTests()
   let testContextMenu = function() {
     info("will test the context menu");
 
     editMenu = null;
     isContextMenu = true;
 
     menuPopup = doc.getElementById("scratchpad-text-popup");
     ok(menuPopup, "the context menupopup");
-    cutItem = doc.getElementById("menu_cut");
+    cutItem = doc.getElementById("se-cMenu-cut");
     ok(cutItem, "the Cut menuitem");
-    pasteItem = doc.getElementById("menu_paste");
+    pasteItem = doc.getElementById("se-cMenu-paste");
     ok(pasteItem, "the Paste menuitem");
 
     sp.setText("bug 699130: hello world! (context menu)");
     openMenu(10, 10, firstShow);
   };
 
   openMenu(10, 10, firstShow);
 }
--- a/browser/devtools/sourceeditor/source-editor-orion.jsm
+++ b/browser/devtools/sourceeditor/source-editor-orion.jsm
@@ -19,16 +19,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Mihai Sucan <mihai.sucan@gmail.com> (original author)
  *   Kenny Heaton <kennyheaton@gmail.com>
  *   Spyros Livathinos <livathinos.spyros@gmail.com>
  *   Allen Eubank <adeubank@gmail.com>
+ *   Girish Sharma <scrapmachines@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -59,16 +60,24 @@ const ORION_IFRAME = "data:text/html;cha
   " href='chrome://browser/skin/devtools/orion-container.css'></head>" +
   "<body style='height:100%;margin:0;overflow:hidden'>" +
   "<div id='editor' style='height:100%'></div>" +
   "</body></html>";
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 /**
+ * Maximum allowed vertical offset for the line index when you call
+ * SourceEditor.setCaretPosition().
+ *
+ * @type number
+ */
+const VERTICAL_OFFSET = 3;
+
+/**
  * The primary selection update delay. On Linux, the X11 primary selection is
  * updated to hold the currently selected text.
  *
  * @type number
  */
 const PRIMARY_SELECTION_DELAY = 100;
 
 /**
@@ -105,16 +114,20 @@ const ORION_ANNOTATION_TYPES = {
   currentLine: "orion.annotation.currentLine",
 };
 
 /**
  * Default key bindings in the Orion editor.
  */
 const DEFAULT_KEYBINDINGS = [
   {
+    action: "enter",
+    code: Ci.nsIDOMKeyEvent.DOM_VK_ENTER,
+  },
+  {
     action: "undo",
     code: Ci.nsIDOMKeyEvent.DOM_VK_Z,
     accel: true,
   },
   {
     action: "redo",
     code: Ci.nsIDOMKeyEvent.DOM_VK_Z,
     accel: true,
@@ -460,16 +473,20 @@ SourceEditor.prototype = {
 
   /**
    * The "tab" editor action implementation. This adds support for expanded tabs
    * to spaces, and support for the indentation of multiple lines at once.
    * @private
    */
   _doTab: function SE__doTab()
   {
+    if (this.readOnly) {
+      return false;
+    }
+
     let indent = "\t";
     let selection = this.getSelection();
     let model = this._model;
     let firstLine = model.getLineAtOffset(selection.start);
     let firstLineStart = model.getLineStart(firstLine);
     let lastLineOffset = selection.end > selection.start ?
                          selection.end - 1 : selection.end;
     let lastLine = model.getLineAtOffset(lastLineOffset);
@@ -510,16 +527,20 @@ SourceEditor.prototype = {
 
   /**
    * The "Unindent lines" editor action implementation. This method is invoked
    * when the user presses Shift-Tab.
    * @private
    */
   _doUnindentLines: function SE__doUnindentLines()
   {
+    if (this.readOnly) {
+      return true;
+    }
+
     let indent = "\t";
 
     let selection = this.getSelection();
     let model = this._model;
     let firstLine = model.getLineAtOffset(selection.start);
     let lastLineOffset = selection.end > selection.start ?
                          selection.end - 1 : selection.end;
     let lastLine = model.getLineAtOffset(lastLineOffset);
@@ -564,16 +585,20 @@ SourceEditor.prototype = {
 
   /**
    * The editor Enter action implementation, which adds simple automatic
    * indentation based on the previous line when the user presses the Enter key.
    * @private
    */
   _doEnter: function SE__doEnter()
   {
+    if (this.readOnly) {
+      return false;
+    }
+
     let selection = this.getSelection();
     if (selection.start != selection.end) {
       return false;
     }
 
     let model = this._model;
     let lineIndex = model.getLineAtOffset(selection.start);
     let lineText = model.getLine(lineIndex, true);
@@ -1304,20 +1329,66 @@ SourceEditor.prototype = {
 
   /**
    * Set the caret position: line and column.
    *
    * @param number aLine
    *        The new caret line location. Line numbers start from 0.
    * @param number [aColumn=0]
    *        Optional. The new caret column location. Columns start from 0.
+   * @param number [aAlign=0]
+   *        Optional. Position of the line with respect to viewport.
+   *        Allowed values are:
+   *          SourceEditor.VERTICAL_ALIGN.TOP     target line at top of view.
+   *          SourceEditor.VERTICAL_ALIGN.CENTER  target line at center of view.
+   *          SourceEditor.VERTICAL_ALIGN.BOTTOM  target line at bottom of view.
    */
-  setCaretPosition: function SE_setCaretPosition(aLine, aColumn)
+  setCaretPosition: function SE_setCaretPosition(aLine, aColumn, aAlign)
   {
-    this.setCaretOffset(this._model.getLineStart(aLine) + (aColumn || 0));
+    let editorHeight = this._view.getClientArea().height;
+    let lineHeight = this._view.getLineHeight();
+    let linesVisible = Math.floor(editorHeight/lineHeight);
+    let halfVisible = Math.round(linesVisible/2);
+    let firstVisible = this.getTopIndex();
+    let lastVisible = this._view.getBottomIndex();
+    let caretOffset = this._model.getLineStart(aLine) + (aColumn || 0);
+
+    this._view.setSelection(caretOffset, caretOffset, false);
+
+    // If the target line is in view, skip the vertical alignment part.
+    if (aLine <= lastVisible && aLine >= firstVisible) {
+      this._view.showSelection();
+      return;
+    }
+
+    // Setting the offset so that the line always falls in the upper half
+    // of visible lines (lower half for BOTTOM aligned).
+    // VERTICAL_OFFSET is the maximum allowed value.
+    let offset = Math.min(halfVisible, VERTICAL_OFFSET);
+
+    let topIndex;
+    switch (aAlign) {
+      case this.VERTICAL_ALIGN.CENTER:
+        topIndex = Math.max(aLine - halfVisible, 0);
+        break;
+
+      case this.VERTICAL_ALIGN.BOTTOM:
+        topIndex = Math.max(aLine - linesVisible + offset, 0);
+        break;
+
+      default: // this.VERTICAL_ALIGN.TOP.
+        topIndex = Math.max(aLine - offset, 0);
+        break;
+    }
+    // Bringing down the topIndex to total lines in the editor if exceeding.
+    topIndex = Math.min(topIndex, this.getLineCount());
+    this.setTopIndex(topIndex);
+
+    let location = this._view.getLocationAtOffset(caretOffset);
+    this._view.setHorizontalPixel(location.x);
   },
 
   /**
    * Get the line count.
    *
    * @return number
    *         The number of lines in the document being edited.
    */
--- a/browser/devtools/sourceeditor/source-editor-overlay.xul
+++ b/browser/devtools/sourceeditor/source-editor-overlay.xul
@@ -30,85 +30,208 @@
    - under the terms of either the GPL or the LGPL, and not to allow others to
    - use your version of this file under the terms of the MPL, indicate your
    - decision by deleting the provisions above and replace them with the notice
    - and other provisions required by the GPL or the LGPL. If you do not delete
    - the provisions above, a recipient may use your version of this file under
    - the terms of any one of the MPL, the GPL or the LGPL.
    -
    - ***** END LICENSE BLOCK ***** -->
-<!DOCTYPE overlay SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
+<!DOCTYPE overlay [
+  <!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
+  %editMenuStrings;
+  <!ENTITY % sourceEditorStrings SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
+  %sourceEditorStrings;
+]>
 <overlay id="sourceEditorOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded.
        The globalOverlay.js script is also required in the XUL document where
-       the source-editor-overlay.xul is loaded. -->
+       the source-editor-overlay.xul is loaded. Do not use #editMenuKeys to
+       avoid conflicts! -->
+
+  <script type="application/javascript">
+    function goUpdateSourceEditorMenuItems()
+    {
+      goUpdateGlobalEditMenuItems();
+      let commands = ['se-cmd-undo', 'se-cmd-redo', 'se-cmd-cut', 'se-cmd-paste',
+                      'se-cmd-delete'];
+      commands.forEach(goUpdateCommand);
+    }
+  </script>
 
   <commandset id="sourceEditorCommands">
     <command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
     <command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
     <command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/>
     <command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
+    <command id="se-cmd-selectAll" oncommand="goDoCommand('se-cmd-selectAll')"/>
+    <command id="se-cmd-cut" oncommand="goDoCommand('se-cmd-cut')" disabled="true"/>
+    <command id="se-cmd-paste" oncommand="goDoCommand('se-cmd-paste')" disabled="true"/>
+    <command id="se-cmd-delete" oncommand="goDoCommand('se-cmd-delete')" disabled="true"/>
     <command id="se-cmd-undo" oncommand="goDoCommand('se-cmd-undo')" disabled="true"/>
     <command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/>
   </commandset>
 
   <keyset id="sourceEditorKeys">
+    <!-- Do not use both #sourceEditorKeys and #editMenuKeys in the same
+    	 document to avoid conflicts! -->
+    <key id="key_undo"
+         key="&undoCmd.key;"
+         modifiers="accel"
+         command="se-cmd-undo"/>
+#ifdef XP_UNIX
+    <key id="key_redo"
+         key="&undoCmd.key;"
+         modifiers="accel,shift"
+         command="se-cmd-redo"/>
+#else
+    <key id="key_redo"
+         key="&redoCmd.key;"
+         modifiers="accel"
+         command="se-cmd-redo"/>
+#endif
+    <key id="key_cut"
+         key="&cutCmd.key;"
+         modifiers="accel"
+         command="se-cmd-cut"/>
+    <key id="key_copy"
+         key="&copyCmd.key;"
+         modifiers="accel"
+         command="cmd_copy"/>
+    <key id="key_paste"
+         key="&pasteCmd.key;"
+         modifiers="accel"
+         command="se-cmd-paste"/>
     <key id="key_gotoLine"
          key="&gotoLineCmd.key;"
          command="cmd_gotoLine"
          modifiers="accel"/>
+    <key id="key_delete"
+         keycode="VK_DELETE"
+         command="se-cmd-delete"/>
+    <key id="key_selectAll"
+         key="&selectAllCmd.key;"
+         modifiers="accel"
+         command="se-cmd-selectAll"/>
+    <key id="key_find"
+         key="&findCmd.key;"
+         modifiers="accel"
+         command="cmd_find"/>
+    <key id="key_findAgain"
+         key="&findAgainCmd.key;"
+         modifiers="accel"
+         command="cmd_findAgain"/>
+    <key id="key_findPrevious"
+         key="&findAgainCmd.key;"
+         modifiers="shift,accel"
+         command="cmd_findPrevious"/>
+    <key id="key_findAgain2"
+         keycode="&findAgainCmd.key2;"
+         command="cmd_findAgain"/>
+    <key id="key_findPrevious2"
+         keycode="&findAgainCmd.key2;"
+         modifiers="shift"
+         command="cmd_findPrevious"/>
   </keyset>
 
-  <menupopup id="sourceEditorContextMenu"
-             onpopupshowing="goUpdateGlobalEditMenuItems()">
-    <menuitem id="se-menu-undo"
-              label="&undoCmd.label;"
-              key="key_undo"
-              accesskey="&undoCmd.accesskey;"
-              command="se-cmd-undo"/>
-    <menuseparator/>
-    <menuitem id="se-menu-cut"
-              label="&cutCmd.label;"
-              key="key_cut"
-              accesskey="&cutCmd.accesskey;"
-              command="cmd_cut"/>
-    <menuitem id="se-menu-copy"
-              label="&copyCmd.label;"
-              key="key_copy"
-              accesskey="&copyCmd.accesskey;"
-              command="cmd_copy"/>
-    <menuitem id="se-menu-paste"
-              label="&pasteCmd.label;"
-              key="key_paste"
-              accesskey="&pasteCmd.accesskey;"
-              command="cmd_paste"/>
-    <menuitem id="se-menu-delete"
-              label="&deleteCmd.label;"
-              key="key_delete"
-              accesskey="&deleteCmd.accesskey;"
-              command="cmd_delete"/>
-    <menuseparator/>
-    <menuitem id="se-menu-selectAll"
-              label="&selectAllCmd.label;"
-              key="key_selectAll"
-              accesskey="&selectAllCmd.accesskey;"
-              command="cmd_selectAll"/>
-    <menuseparator/>
-    <menuitem id="se-menu-find"
-              label="&findCmd.label;"
-              accesskey="&findCmd.accesskey;"
-              key="key_find"
-              command="cmd_find"/>
-    <menuitem id="se-menu-findAgain"
-              label="&findAgainCmd.label;"
-              accesskey="&findAgainCmd.accesskey;"
-              key="key_findAgain"
-              command="cmd_findAgain"/>
-    <menuseparator/>
-    <menuitem id="se-menu-gotoLine"
-              label="&gotoLineCmd.label;"
-              accesskey="&gotoLineCmd.accesskey;"
-              key="key_gotoLine"
-              command="cmd_gotoLine"/>
-  </menupopup>
+  <!-- Items for the Edit menu -->
+
+  <menuitem id="se-menu-undo"
+            label="&undoCmd.label;"
+            key="key_undo"
+            accesskey="&undoCmd.accesskey;"
+            command="se-cmd-undo"/>
+  <menuitem id="se-menu-redo"
+            label="&redoCmd.label;"
+            key="key_redo"
+            accesskey="&redoCmd.accesskey;"
+            command="se-cmd-redo"/>
+  <menuitem id="se-menu-cut"
+            label="&cutCmd.label;"
+            key="key_cut"
+            accesskey="&cutCmd.accesskey;"
+            command="se-cmd-cut"/>
+  <menuitem id="se-menu-copy"
+            label="&copyCmd.label;"
+            key="key_copy"
+            accesskey="&copyCmd.accesskey;"
+            command="cmd_copy"/>
+  <menuitem id="se-menu-paste"
+            label="&pasteCmd.label;"
+            key="key_paste"
+            accesskey="&pasteCmd.accesskey;"
+            command="se-cmd-paste"/>
+  <menuitem id="se-menu-delete"
+            label="&deleteCmd.label;"
+            key="key_delete"
+            accesskey="&deleteCmd.accesskey;"
+            command="se-cmd-delete"/>
+  <menuitem id="se-menu-selectAll"
+            label="&selectAllCmd.label;"
+            key="key_selectAll"
+            accesskey="&selectAllCmd.accesskey;"
+            command="se-cmd-selectAll"/>
+  <menuitem id="se-menu-find"
+            label="&findCmd.label;"
+            accesskey="&findCmd.accesskey;"
+            key="key_find"
+            command="cmd_find"/>
+  <menuitem id="se-menu-findAgain"
+            label="&findAgainCmd.label;"
+            accesskey="&findAgainCmd.accesskey;"
+            key="key_findAgain"
+            command="cmd_findAgain"/>
+  <menuitem id="se-menu-gotoLine"
+            label="&gotoLineCmd.label;"
+            accesskey="&gotoLineCmd.accesskey;"
+            key="key_gotoLine"
+            command="cmd_gotoLine"/>
+
+  <!-- Items for context menus -->
+
+  <menuitem id="se-cMenu-undo"
+            label="&undoCmd.label;"
+            key="key_undo"
+            accesskey="&undoCmd.accesskey;"
+            command="se-cmd-undo"/>
+  <menuitem id="se-cMenu-cut"
+            label="&cutCmd.label;"
+            key="key_cut"
+            accesskey="&cutCmd.accesskey;"
+            command="se-cmd-cut"/>
+  <menuitem id="se-cMenu-copy"
+            label="&copyCmd.label;"
+            key="key_copy"
+            accesskey="&copyCmd.accesskey;"
+            command="cmd_copy"/>
+  <menuitem id="se-cMenu-paste"
+            label="&pasteCmd.label;"
+            key="key_paste"
+            accesskey="&pasteCmd.accesskey;"
+            command="se-cmd-paste"/>
+  <menuitem id="se-cMenu-delete"
+            label="&deleteCmd.label;"
+            key="key_delete"
+            accesskey="&deleteCmd.accesskey;"
+            command="se-cmd-delete"/>
+  <menuitem id="se-cMenu-selectAll"
+            label="&selectAllCmd.label;"
+            key="key_selectAll"
+            accesskey="&selectAllCmd.accesskey;"
+            command="se-cmd-selectAll"/>
+  <menuitem id="se-cMenu-find"
+            label="&findCmd.label;"
+            accesskey="&findCmd.accesskey;"
+            key="key_find"
+            command="cmd_find"/>
+  <menuitem id="se-cMenu-findAgain"
+            label="&findAgainCmd.label;"
+            accesskey="&findAgainCmd.accesskey;"
+            key="key_findAgain"
+            command="cmd_findAgain"/>
+  <menuitem id="se-cMenu-gotoLine"
+            label="&gotoLineCmd.label;"
+            accesskey="&gotoLineCmd.accesskey;"
+            key="key_gotoLine"
+            command="cmd_gotoLine"/>
 </overlay>
--- a/browser/devtools/sourceeditor/source-editor-ui.jsm
+++ b/browser/devtools/sourceeditor/source-editor-ui.jsm
@@ -248,16 +248,20 @@ SourceEditorController.prototype = {
 
     switch (aCommand) {
       case "cmd_find":
       case "cmd_findAgain":
       case "cmd_findPrevious":
       case "cmd_gotoLine":
       case "se-cmd-undo":
       case "se-cmd-redo":
+      case "se-cmd-cut":
+      case "se-cmd-paste":
+      case "se-cmd-delete":
+      case "se-cmd-selectAll":
         result = true;
         break;
       default:
         result = false;
         break;
     }
 
     return result;
@@ -273,28 +277,42 @@ SourceEditorController.prototype = {
    */
   isCommandEnabled: function SEC_isCommandEnabled(aCommand)
   {
     let result;
 
     switch (aCommand) {
       case "cmd_find":
       case "cmd_gotoLine":
+      case "se-cmd-selectAll":
         result = true;
         break;
       case "cmd_findAgain":
       case "cmd_findPrevious":
         result = this._editor.lastFind && this._editor.lastFind.lastFound != -1;
         break;
       case "se-cmd-undo":
         result = this._editor.canUndo();
         break;
       case "se-cmd-redo":
         result = this._editor.canRedo();
         break;
+      case "se-cmd-cut":
+      case "se-cmd-delete": {
+        let selection = this._editor.getSelection();
+        result = selection.start != selection.end && !this._editor.readOnly;
+        break;
+      }
+      case "se-cmd-paste": {
+        let window = this._editor._view._frameWindow;
+        let controller = window.controllers.getControllerForCommand("cmd_paste");
+        result = !this._editor.readOnly &&
+                 controller.isCommandEnabled("cmd_paste");
+        break;
+      }
       default:
         result = false;
         break;
     }
 
     return result;
   },
 
@@ -315,19 +333,33 @@ SourceEditorController.prototype = {
         this._editor.ui.findNext();
         break;
       case "cmd_findPrevious":
         this._editor.ui.findPrevious();
         break;
       case "cmd_gotoLine":
         this._editor.ui.gotoLine();
         break;
+      case "se-cmd-selectAll":
+        this._editor._view.invokeAction("selectAll");
+        break;
       case "se-cmd-undo":
         this._editor.undo();
         break;
       case "se-cmd-redo":
         this._editor.redo();
         break;
+      case "se-cmd-cut":
+        this._editor.ui._ownerWindow.goDoCommand("cmd_cut");
+        break;
+      case "se-cmd-paste":
+        this._editor.ui._ownerWindow.goDoCommand("cmd_paste");
+        break;
+      case "se-cmd-delete": {
+        let selection = this._editor.getSelection();
+        this._editor.setText("", selection.start, selection.end);
+        break;
+      }
     }
   },
 
   onEvent: function() { }
 };
--- a/browser/devtools/sourceeditor/source-editor.jsm
+++ b/browser/devtools/sourceeditor/source-editor.jsm
@@ -308,16 +308,26 @@ SourceEditor.EVENTS = {
    * have not been saved yet. Event object properties: oldValue and newValue.
    * Both are booleans telling the old dirty state and the new state,
    * respectively.
    */
   DIRTY_CHANGED: "DirtyChanged",
 };
 
 /**
+ * Allowed vertical alignment options for the line index
+ * when you call SourceEditor.setCaretPosition().
+ */
+SourceEditor.VERTICAL_ALIGN = {
+  TOP: 0,
+  CENTER: 1,
+  BOTTOM: 2,
+};
+
+/**
  * Extend a destination object with properties from a source object.
  *
  * @param object aDestination
  * @param object aSource
  */
 function extend(aDestination, aSource)
 {
   for (let name in aSource) {
@@ -331,16 +341,17 @@ function extend(aDestination, aSource)
  * Add methods common to all components.
  */
 extend(SourceEditor.prototype, {
   // Expose the static constants on the SourceEditor instances.
   EVENTS: SourceEditor.EVENTS,
   MODES: SourceEditor.MODES,
   THEMES: SourceEditor.THEMES,
   DEFAULTS: SourceEditor.DEFAULTS,
+  VERTICAL_ALIGN: SourceEditor.VERTICAL_ALIGN,
 
   _lastFind: null,
 
   /**
    * Find a string in the editor.
    *
    * @param string aString
    *        The string you want to search for. If |aString| is not given the
--- a/browser/devtools/sourceeditor/test/Makefile.in
+++ b/browser/devtools/sourceeditor/test/Makefile.in
@@ -55,12 +55,13 @@ include $(topsrcdir)/config/rules.mk
 		browser_bug687160_line_api.js \
 		browser_bug650345_find.js \
 		browser_bug703692_focus_blur.js \
 		browser_bug725388_mouse_events.js \
 		browser_bug707987_debugger_breakpoints.js \
 		browser_bug712982_line_ruler_click.js \
 		browser_bug725618_moveLines_shortcut.js \
 		browser_bug700893_dirty_state.js \
+		browser_bug729480_line_vertical_align.js \
 		head.js \
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/sourceeditor/test/browser_bug729480_line_vertical_align.js
@@ -0,0 +1,99 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
+
+let testWin;
+let editor;
+const VERTICAL_OFFSET = 3;
+
+function test()
+{
+  waitForExplicitFinish();
+
+  const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
+    "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
+    " title='test for bug 729480 - allow setCaretPosition align the target line" +
+    " vertically in view according to a third argument'" +
+    " width='300' height='300'><box flex='1'/></window>";
+  const windowFeatures = "chrome,titlebar,toolbar,centerscreen,dialog=no";
+
+  testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
+  testWin.addEventListener("load", function onWindowLoad() {
+    testWin.removeEventListener("load", onWindowLoad, false);
+    waitForFocus(initEditor, testWin);
+  }, false);
+}
+
+function initEditor()
+{
+  let box = testWin.document.querySelector("box");
+
+  editor = new SourceEditor();
+  editor.init(box, {showLineNumbers: true}, editorLoaded);
+}
+
+function editorLoaded()
+{
+  editor.focus();
+
+  // setting 3 pages of lines containing the line number.
+  let view = editor._view;
+
+  let lineHeight = view.getLineHeight();
+  let editorHeight = view.getClientArea().height;
+  let linesPerPage = Math.floor(editorHeight / lineHeight);
+  let totalLines = 3 * linesPerPage;
+
+  let text = "";
+  for (let i = 0; i < totalLines; i++) {
+    text += "Line " + i + "\n";
+  }
+
+  editor.setText(text);
+  editor.setCaretOffset(0);
+
+  let offset = Math.min(Math.round(linesPerPage/2), VERTICAL_OFFSET);
+  // Building the iterator array.
+  // [line, alignment, topIndex_check]
+  let iterateOn = [
+    [0, "TOP", 0],
+    [25, "TOP", 25 - offset],
+    // Case when the target line is already in view.
+    [27, "TOP", 25 - offset],
+    [0, "BOTTOM", 0],
+    [5, "BOTTOM", 0],
+    [38, "BOTTOM", 38 - linesPerPage + offset],
+    [0, "CENTER", 0],
+    [4, "CENTER", 0],
+    [34, "CENTER", 34 - Math.round(linesPerPage/2)]
+  ];
+
+  function testEnd() {
+    editor.destroy();
+    testWin.close();
+    testWin = editor = null;
+    waitForFocus(finish, window);
+  }
+
+  function testPosition(pos) {
+    is(editor.getTopIndex(), iterateOn[pos][2], "scroll is correct for test #" + pos);
+    iterator(++pos);
+  }
+
+  function iterator(i) {
+    if (i == iterateOn.length) {
+      testEnd();
+    } else {
+      editor.setCaretPosition(iterateOn[i][0], 0,
+                              editor.VERTICAL_ALIGN[iterateOn[i][1]]);
+      executeSoon(testPosition.bind(this, i));
+    }
+  }
+  iterator(0);
+}
--- a/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
+++ b/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
@@ -196,21 +196,31 @@ function editorLoaded()
 
   editor.readOnly = true;
   EventUtils.synthesizeKey("b", {}, testWin);
   is(editor.getText(), "foofoo", "editor is now read-only (keyboard)");
 
   editor.setText("foobar");
   is(editor.getText(), "foobar", "editor allows programmatic changes (setText)");
 
+  EventUtils.synthesizeKey("VK_RETURN", {}, testWin);
+  is(editor.getText(), "foobar", "Enter key does nothing");
+
+  EventUtils.synthesizeKey("VK_TAB", {}, testWin);
+  is(editor.getText(), "foobar", "Tab does nothing");
+
+  editor.setText("      foobar");
+  EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, testWin);
+  is(editor.getText(), "      foobar", "Shift+Tab does nothing");
+
   editor.readOnly = false;
 
   editor.setCaretOffset(editor.getCharCount());
   EventUtils.synthesizeKey("-", {}, testWin);
-  is(editor.getText(), "foobar-", "editor is now editable again");
+  is(editor.getText(), "      foobar-", "editor is now editable again");
 
   // Test the Selection event.
 
   editor.setText("foobarbaz");
 
   editor.setSelection(1, 4);
 
   let event = null;
--- a/browser/devtools/styleeditor/styleeditor.xul
+++ b/browser/devtools/styleeditor/styleeditor.xul
@@ -52,26 +52,40 @@
         id="style-editor-chrome-window"
         title="&window.title;"
         windowtype="Tools:StyleEditor"
         width="800" height="280"
         persist="screenX screenY width height sizemode">
 <xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
 
 <xul:popupset id="style-editor-popups">
-  <xul:menupopup id="sourceEditorContextMenu"/>
+  <xul:menupopup id="sourceEditorContextMenu"
+                 onpopupshowing="goUpdateSourceEditorMenuItems()">
+    <xul:menuitem id="se-cMenu-undo"/>
+    <xul:menuseparator/>
+    <xul:menuitem id="se-cMenu-cut"/>
+    <xul:menuitem id="se-cMenu-copy"/>
+    <xul:menuitem id="se-cMenu-paste"/>
+    <xul:menuitem id="se-cMenu-delete"/>
+    <xul:menuseparator/>
+    <xul:menuitem id="se-cMenu-selectAll"/>
+    <xul:menuseparator/>
+    <xul:menuitem id="se-cMenu-find"/>
+    <xul:menuitem id="se-cMenu-findAgain"/>
+    <xul:menuseparator/>
+    <xul:menuitem id="se-cMenu-gotoLine"/>
+  </xul:menupopup>
 </xul:popupset>
 
 <xul:commandset id="editMenuCommands"/>
 <xul:commandset id="sourceEditorCommands"/>
 <xul:commandset id="style-editor-commandset">
   <xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
 </xul:commandset>
 
-<xul:keyset id="editMenuKeys"/>
 <xul:keyset id="sourceEditorKeys"/>
 <xul:keyset id="style-editor-keyset">
   <xul:key id="style-editor-key-close"
            key="&closeCmd.key;"
            command="style-editor-cmd-close"
            modifiers="accel"/>
 </xul:keyset>
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -328,12 +328,28 @@ syncPromoNotification.learnMoreLinkText=
 # LOCALIZATION NOTE (telemetryPrompt): %1$S will be replaced by brandFullName,
 # and %2$S by the value of the toolkit.telemetry.server_owner preference.
 telemetryPrompt = Will you help improve %1$S by sending anonymous information about performance, hardware characteristics, feature usage, and browser customizations to %2$S?
 telemetryLinkLabel = Learn More
 telemetryYesButtonLabel2 = Yes, I want to help
 telemetryYesButtonAccessKey = Y
 telemetryNoButtonLabel = No
 telemetryNoButtonAccessKey = N
+
+# Keyword.URL reset prompt
+# LOCALIZATION NOTE (keywordPrompt.message):
+#  - %1$S is brandShortName
+#  - %2$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
+#  - %3$S is the name of the default search engine (e.g. "Google")
+keywordPrompt.message = %1$S is using '%2$S' for searches from the location bar. Would you like to restore the default search (%3$S)?
+
+# LOCALIZATION NOTE (keywordPrompt.yesButton): %1$S is the name of the default search engine
+keywordPrompt.yesButton = Yes, use %1$S
+keywordPrompt.yesButton.accessKey = Y
+
+# LOCALIZATION NOTE (keywordPrompt.noButton): %1$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
+keywordPrompt.noButton = No, continue using '%1$S'
+keywordPrompt.noButton.accessKey  = N
+
 # Telemetry opt-out prompt for Aurora and Nightly
 # LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
 # brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.
 telemetryOptOutPrompt = %1$S sends information about performance, hardware, usage and customizations back to %2$S to help improve %3$S.
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
@@ -38,60 +38,16 @@
 
 <!ENTITY closeCmd.label               "Close">
 <!ENTITY closeCmd.key                 "W">
 <!ENTITY closeCmd.accesskey           "C">
 
 <!ENTITY editMenu.label               "Edit">
 <!ENTITY editMenu.accesskey           "E">
 
-<!ENTITY undoCmd.label                "Undo">
-<!ENTITY undoCmd.key                  "Z">
-<!ENTITY undoCmd.accesskey            "U">
-
-<!ENTITY redoCmd.label                "Redo">
-<!ENTITY redoCmd.key                  "Y">
-<!ENTITY redoCmd.accesskey            "R">
-
-<!ENTITY cutCmd.label                 "Cut">
-<!ENTITY cutCmd.key                   "X">
-<!ENTITY cutCmd.accesskey             "t">
-
-<!ENTITY copyCmd.label                "Copy">
-<!ENTITY copyCmd.key                  "C">
-<!ENTITY copyCmd.accesskey            "C">
-
-<!ENTITY pasteCmd.label               "Paste">
-<!ENTITY pasteCmd.key                 "V">
-<!ENTITY pasteCmd.accesskey           "P">
-
-<!ENTITY selectAllCmd.label           "Select All">
-<!ENTITY selectAllCmd.key             "A">
-<!ENTITY selectAllCmd.accesskey       "A">
-
-<!ENTITY findCmd.label                "Find…">
-<!ENTITY findCmd.key                  "F">
-<!ENTITY findCmd.accesskey            "F">
-
-<!ENTITY findAgainCmd.label           "Find Again…">
-<!-- LOCALIZATION NOTE (findAgainCmd.key): This key is used only on Macs.
-  -  Windows and Linux builds use the F3 key which is not localizable on purpose.
-  -->
-<!ENTITY findAgainCmd.key             "G">
-<!ENTITY findAgainCmd.accesskey       "g">
-<!-- LOCALIZATION NOTE (findPreviousCmd.key): This key is used only on Macs.
-  -  Windows and Linux builds use the Shift-F3 key which is not localizable on
-  -  purpose.
-  -->
-<!ENTITY findPreviousCmd.key          "G">
-
-<!ENTITY gotoLineCmd.label            "Jump to line…">
-<!ENTITY gotoLineCmd.key              "J">
-<!ENTITY gotoLineCmd.accesskey        "J">
-
 <!ENTITY run.label                    "Run">
 <!ENTITY run.accesskey                "R">
 <!ENTITY run.key                      "r">
 
 <!ENTITY inspect.label                "Inspect">
 <!ENTITY inspect.accesskey            "I">
 <!ENTITY inspect.key                  "i">
 
--- a/browser/locales/en-US/chrome/browser/devtools/sourceeditor.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/sourceeditor.dtd
@@ -5,28 +5,11 @@
 <!-- LOCALIZATION NOTE : FILE Do not translate commandkeys -->
 
 <!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
   - keep it in English, or another language commonly spoken among web developers.
   - You want to make that choice consistent across the developer tools.
   - A good criteria is the language in which you'd find the best
   - documentation on web development on the web. -->
 
-<!ENTITY undoCmd.label             "Undo">
-<!ENTITY undoCmd.accesskey         "U">
-<!ENTITY cutCmd.label              "Cut">
-<!ENTITY cutCmd.accesskey          "t">
-<!ENTITY copyCmd.label             "Copy">
-<!ENTITY copyCmd.accesskey         "C">
-<!ENTITY pasteCmd.label            "Paste">
-<!ENTITY pasteCmd.accesskey        "P">
-<!ENTITY deleteCmd.label           "Delete">
-<!ENTITY deleteCmd.accesskey       "D">
-<!ENTITY selectAllCmd.label        "Select All">
-<!ENTITY selectAllCmd.accesskey    "A">
-<!ENTITY findCmd.label             "Find…">
-<!ENTITY findCmd.accesskey         "F">
-<!ENTITY findAgainCmd.label        "Find Again…">
-<!ENTITY findAgainCmd.accesskey    "g">
 <!ENTITY gotoLineCmd.label         "Jump to line…">
 <!ENTITY gotoLineCmd.key           "J">
 <!ENTITY gotoLineCmd.accesskey     "J">
-
new file mode 100644
--- /dev/null
+++ b/browser/modules/KeywordURLResetPrompter.jsm
@@ -0,0 +1,105 @@
+/* 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/. */
+
+let EXPORTED_SYMBOLS = [ "KeywordURLResetPrompter" ];
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const KEYWORD_PROMPT_REV = 1;
+
+let KeywordURLResetPrompter = {
+  get shouldPrompt() {
+    let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
+    let declinedRev;
+    try {
+      declinedRev = Services.prefs.getIntPref("browser.keywordURLPromptDeclined");
+    } catch (ex) {}
+
+    return keywordURLUserSet && declinedRev != KEYWORD_PROMPT_REV;
+  },
+
+  prompt: function KeywordURLResetPrompter_prompt(win, keywordURI) {
+    let tabbrowser = win.gBrowser;
+    let notifyBox = tabbrowser.getNotificationBox();
+
+    let existingNotification = notifyBox.getNotificationWithValue("keywordURL-reset");
+    if (existingNotification)
+      return;
+
+    // Find the name/URI of this build's original default engine.
+    // XXX: Can't use originalDefaultEngine getter here, because that doesn't
+    //      use the default pref branch.
+    let defaultURI;
+    let defaultEngine;
+    try {
+      let defaultPB = Services.prefs.getDefaultBranch(null);
+      let defaultName = defaultPB.getComplexValue("browser.search.defaultenginename",
+                                                  Ci.nsIPrefLocalizedString).data;
+      defaultEngine = Services.search.getEngineByName(defaultName);
+      defaultURI = defaultEngine.getSubmission("foo").uri;
+    } catch (ex) {
+      // Something went horribly wrong! bail out
+      return;
+    }
+
+    // If the user-set value has the same base domain as the default, don't
+    // prompt.
+    let keywordBaseDomain;
+    try {
+      keywordBaseDomain = Services.eTLD.getBaseDomain(keywordURI);
+      if (keywordBaseDomain == Services.eTLD.getBaseDomain(defaultURI))
+        return;
+    } catch (ex) {}
+
+    if (!keywordBaseDomain)
+      return;
+
+    let brandBundle  = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+    let brandShortName = brandBundle.GetStringFromName("brandShortName");
+
+    let browserBundle = win.gNavigatorBundle;
+    let msg = browserBundle.getFormattedString("keywordPrompt.message",
+                                               [brandShortName, keywordBaseDomain,
+                                                defaultEngine.name]);
+    let buttons = [
+      {
+        label: browserBundle.getFormattedString("keywordPrompt.yesButton",
+                                                [defaultEngine.name]),
+        accessKey: browserBundle.getString("keywordPrompt.yesButton.accessKey"),
+        popup:     null,
+        callback: function(aNotificationBar, aButton) {
+          Services.prefs.clearUserPref("keyword.URL");
+          try {
+            // If the currently loaded URI still has the same base domain as the
+            // keyword URI (this is used as a rough approximation of whether the
+            // user is still seeing search results as opposed to having clicked
+            // on a result link), load the default engine's searchForm URL so
+            // that they can re-do their search.
+            let currentBaseDomain = Services.eTLD.getBaseDomain(tabbrowser.currentURI);
+            if (currentBaseDomain == keywordBaseDomain)
+              tabbrowser.loadURI(defaultEngine.searchForm);
+          } catch (ex) {}
+        }
+      },
+      {
+        label: browserBundle.getFormattedString("keywordPrompt.noButton",
+                                                [keywordBaseDomain]),
+        accessKey: browserBundle.getString("keywordPrompt.noButton.accessKey"),
+        popup:     null,
+        callback: function(aNotificationBar, aButton) {
+          Services.prefs.setIntPref("browser.keywordURLPromptDeclined", KEYWORD_PROMPT_REV);
+        }
+      }
+    ];
+    
+    let notification = notifyBox.appendNotification(msg, "keywordURL-reset", null, notifyBox.PRIORITY_WARNING_HIGH, buttons);
+    notification.setAttribute("hideclose", true);
+    // stick around for a few page loads in case there are redirects involved
+    notification.persistence = 3;
+  }
+}
--- a/browser/modules/Makefile.in
+++ b/browser/modules/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/config.mk
 TEST_DIRS += test
 
 EXTRA_JS_MODULES = \
 	openLocationLastURL.jsm \
 	NetworkPrioritizer.jsm \
 	NewTabUtils.jsm \
 	offlineAppCache.jsm \
 	TelemetryTimestamps.jsm \
+	KeywordURLResetPrompter.jsm \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 EXTRA_JS_MODULES += \
 	WindowsPreviewPerTab.jsm \
 	WindowsJumpLists.jsm \
 	$(NULL)
 endif
--- a/browser/themes/gnomestripe/devtools/csshtmltree.css
+++ b/browser/themes/gnomestripe/devtools/csshtmltree.css
@@ -200,17 +200,17 @@
  */
 
 .ruleview {
   background-color: #FFF;
 }
 
 .ruleview-rule-source {
   background-color: -moz-dialog;
-  color: #0091ff;
+  color: -moz-dialogText;
   padding: 2px 5px;
   cursor: pointer;
 }
 
 .ruleview-rule-source:hover {
   text-decoration: underline;
 }
 
index 8ef1ba4a5cd268f4549fa2b511d6d47f8b46333e..9184b95187e8b951069a209a9051a9eceba6e461
GIT binary patch
literal 863
zc$@)W1EBngP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0009fNkl<Zc-pO1
zTS!z<6b(rP5kVx2TOx!RN`X?J5<=il^cO@Q{RGxe^;ut0R9a-Iqo#?^G#}+7(-2A!
z60-**q=Z2bzEYbzPtUyWj5@2e2Z?GXHS}Y#&)#>fIcx88II{zTM|Kjsh{HrKk+%WJ
zAy+h_1$Jx&Vju+r2d|+o^($UzYEvLrG@{)O13Bp3yBM15T3%i8U^5V|Xhgdm29BXy
zQ$a(AVfYZRkHZKquM6RdMzp{GSVdEJERpfQ2J+CUDZ{sjfMpcu*TPsGJ&oW@5B!D!
ze_;6!2v;<s{mVc$VP3;SBA<xa*g%J-eBK54+&Y4j#aQ`xo+b_eJv8zv7k=vmyhiXB
zgiB2{1BpZdQB>a8HC*1%X*M-<b~C20Z=h9EUiUma9uIuhFYx#R@G2XEW4C~I4WXVa
z_$(7r4@0=rL^BXeq{+Ih?rB14ZO6ru+IBPJ5cBkZ8)(*)+x;Eh`H^tfq34GX_;3U6
zB?tTy^}u6JqUUHhS6&0cr6%eTnAmk`UB}>qnzqZukDkOASGSyEG&6t6dVF*Pjha$w
z4ol8O_&?pp%D@Srft$AHvZf<2cqyFw$E)G;_#s?sA`EcsiR|<oH*2_8)oi|7+0=cf
zqA`K-y5y{%iEf}yQ!dvm9Lfi$(*cKT37*fLK!pb5^;NhmGYHk~$4c+<Fh{u5L>Lfo
z+;QwUmYe1mn(EEB%WAJMCNqD_dRue@HJWldXW`VR5bDapYDW$nb{hhH1qfAS!R~S+
z(0^9CCT9l1r6$4v$DhJ8AL7^t*m*oRFS=P$GsGCfyo7Z#zb8i;sM3_(F$24mqkWc!
zP-{AD)*o<>wE!j!j=4#AM~cFC!8P>;!lfp{0B?H|C-9D)4zuF~c7BqZn;BD?UtnD>
zWOn33RH-SeeHs?02Ug20tonR-t?P@he|rzzW@CLG_Gzv;8R1eB@er-u{v@7tqO8RP
zJI`c{;~hw3J(J(#BA?>QeG9Jf)@9u`h0Q>?qS>yecsE)z3Sr{gUaF~0fn3pub~_Bj
p5__Z@8R^D<$K;SJ8qsdmz)uUW$2a}EvC#kk002ovPDHLkV1k%7iwOV#
--- a/browser/themes/pinstripe/devtools/csshtmltree.css
+++ b/browser/themes/pinstripe/devtools/csshtmltree.css
@@ -202,17 +202,17 @@
  */
 
 .ruleview {
   background-color: #FFF;
 }
 
 .ruleview-rule-source {
   background-color: -moz-dialog;
-  color: #0091ff;
+  color: -moz-dialogText;
   padding: 2px 5px;
   cursor: pointer;
 }
 
 .ruleview-rule-source:hover {
   text-decoration: underline;
 }
 
index 8ef1ba4a5cd268f4549fa2b511d6d47f8b46333e..9184b95187e8b951069a209a9051a9eceba6e461
GIT binary patch
literal 863
zc$@)W1EBngP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0009fNkl<Zc-pO1
zTS!z<6b(rP5kVx2TOx!RN`X?J5<=il^cO@Q{RGxe^;ut0R9a-Iqo#?^G#}+7(-2A!
z60-**q=Z2bzEYbzPtUyWj5@2e2Z?GXHS}Y#&)#>fIcx88II{zTM|Kjsh{HrKk+%WJ
zAy+h_1$Jx&Vju+r2d|+o^($UzYEvLrG@{)O13Bp3yBM15T3%i8U^5V|Xhgdm29BXy
zQ$a(AVfYZRkHZKquM6RdMzp{GSVdEJERpfQ2J+CUDZ{sjfMpcu*TPsGJ&oW@5B!D!
ze_;6!2v;<s{mVc$VP3;SBA<xa*g%J-eBK54+&Y4j#aQ`xo+b_eJv8zv7k=vmyhiXB
zgiB2{1BpZdQB>a8HC*1%X*M-<b~C20Z=h9EUiUma9uIuhFYx#R@G2XEW4C~I4WXVa
z_$(7r4@0=rL^BXeq{+Ih?rB14ZO6ru+IBPJ5cBkZ8)(*)+x;Eh`H^tfq34GX_;3U6
zB?tTy^}u6JqUUHhS6&0cr6%eTnAmk`UB}>qnzqZukDkOASGSyEG&6t6dVF*Pjha$w
z4ol8O_&?pp%D@Srft$AHvZf<2cqyFw$E)G;_#s?sA`EcsiR|<oH*2_8)oi|7+0=cf
zqA`K-y5y{%iEf}yQ!dvm9Lfi$(*cKT37*fLK!pb5^;NhmGYHk~$4c+<Fh{u5L>Lfo
z+;QwUmYe1mn(EEB%WAJMCNqD_dRue@HJWldXW`VR5bDapYDW$nb{hhH1qfAS!R~S+
z(0^9CCT9l1r6$4v$DhJ8AL7^t*m*oRFS=P$GsGCfyo7Z#zb8i;sM3_(F$24mqkWc!
zP-{AD)*o<>wE!j!j=4#AM~cFC!8P>;!lfp{0B?H|C-9D)4zuF~c7BqZn;BD?UtnD>
zWOn33RH-SeeHs?02Ug20tonR-t?P@he|rzzW@CLG_Gzv;8R1eB@er-u{v@7tqO8RP
zJI`c{;~hw3J(J(#BA?>QeG9Jf)@9u`h0Q>?qS>yecsE)z3Sr{gUaF~0fn3pub~_Bj
p5__Z@8R^D<$K;SJ8qsdmz)uUW$2a}EvC#kk002ovPDHLkV1k%7iwOV#
--- a/browser/themes/winstripe/devtools/csshtmltree.css
+++ b/browser/themes/winstripe/devtools/csshtmltree.css
@@ -200,17 +200,17 @@
  */
 
 .ruleview {
   background-color: #FFF;
 }
 
 .ruleview-rule-source {
   background-color: -moz-dialog;
-  color: #0091ff;
+  color: -moz-dialogText;
   padding: 2px 5px;
   cursor: pointer;
 }
 
 .ruleview-rule-source:hover {
   text-decoration: underline;
 }
 
index 8ef1ba4a5cd268f4549fa2b511d6d47f8b46333e..9184b95187e8b951069a209a9051a9eceba6e461
GIT binary patch
literal 863
zc$@)W1EBngP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0009fNkl<Zc-pO1
zTS!z<6b(rP5kVx2TOx!RN`X?J5<=il^cO@Q{RGxe^;ut0R9a-Iqo#?^G#}+7(-2A!
z60-**q=Z2bzEYbzPtUyWj5@2e2Z?GXHS}Y#&)#>fIcx88II{zTM|Kjsh{HrKk+%WJ
zAy+h_1$Jx&Vju+r2d|+o^($UzYEvLrG@{)O13Bp3yBM15T3%i8U^5V|Xhgdm29BXy
zQ$a(AVfYZRkHZKquM6RdMzp{GSVdEJERpfQ2J+CUDZ{sjfMpcu*TPsGJ&oW@5B!D!
ze_;6!2v;<s{mVc$VP3;SBA<xa*g%J-eBK54+&Y4j#aQ`xo+b_eJv8zv7k=vmyhiXB
zgiB2{1BpZdQB>a8HC*1%X*M-<b~C20Z=h9EUiUma9uIuhFYx#R@G2XEW4C~I4WXVa
z_$(7r4@0=rL^BXeq{+Ih?rB14ZO6ru+IBPJ5cBkZ8)(*)+x;Eh`H^tfq34GX_;3U6
zB?tTy^}u6JqUUHhS6&0cr6%eTnAmk`UB}>qnzqZukDkOASGSyEG&6t6dVF*Pjha$w
z4ol8O_&?pp%D@Srft$AHvZf<2cqyFw$E)G;_#s?sA`EcsiR|<oH*2_8)oi|7+0=cf
zqA`K-y5y{%iEf}yQ!dvm9Lfi$(*cKT37*fLK!pb5^;NhmGYHk~$4c+<Fh{u5L>Lfo
z+;QwUmYe1mn(EEB%WAJMCNqD_dRue@HJWldXW`VR5bDapYDW$nb{hhH1qfAS!R~S+
z(0^9CCT9l1r6$4v$DhJ8AL7^t*m*oRFS=P$GsGCfyo7Z#zb8i;sM3_(F$24mqkWc!
zP-{AD)*o<>wE!j!j=4#AM~cFC!8P>;!lfp{0B?H|C-9D)4zuF~c7BqZn;BD?UtnD>
zWOn33RH-SeeHs?02Ug20tonR-t?P@he|rzzW@CLG_Gzv;8R1eB@er-u{v@7tqO8RP
zJI`c{;~hw3J(J(#BA?>QeG9Jf)@9u`h0Q>?qS>yecsE)z3Sr{gUaF~0fn3pub~_Bj
p5__Z@8R^D<$K;SJ8qsdmz)uUW$2a}EvC#kk002ovPDHLkV1k%7iwOV#
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -955,20 +955,20 @@ ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(CPP_PROG_LINK),1)
-	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
+	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
 	@$(call CHECK_STDCXX,$@)
 else
-	$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
+	$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
--- a/configure.in
+++ b/configure.in
@@ -4926,16 +4926,20 @@ MOZ_ARG_HEADER(Toolkit Options)
     then
         dnl nglayout only supports building with one toolkit,
         dnl so ignore everything after the first comma (",").
         MOZ_WIDGET_TOOLKIT=`echo "$_DEFAULT_TOOLKIT" | sed -e "s/,.*$//"`
     else
         AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
     fi
 
+MOZ_ARG_WITHOUT_BOOL(x,
+[  --without-x              Build without X11],
+    WITHOUT_X11=1)
+
 dnl ========================================================
 dnl = Enable the toolkit as needed                         =
 dnl ========================================================
 
 case "$MOZ_WIDGET_TOOLKIT" in
 
 cairo-windows)
     MOZ_WIDGET_TOOLKIT=windows
@@ -4960,26 +4964,27 @@ cairo-gtk2|cairo-gtk2-x11)
     AC_DEFINE(MOZ_WIDGET_GTK2)
     MOZ_PDF_PRINTING=1
     MOZ_INSTRUMENT_EVENT_LOOP=1
     ;;
 
 cairo-qt)
     MOZ_WIDGET_TOOLKIT=qt
     MOZ_ENABLE_QT=1
-    MOZ_ENABLE_XREMOTE=1
+    if test -z "$WITHOUT_X11"; then
+      MOZ_ENABLE_XREMOTE=1
+      MOZ_WEBGL_GLX=1
+      MOZ_X11=1
+      AC_DEFINE(MOZ_X11)
+      XT_LIBS=
+    fi
+
     MOZ_WEBGL=1
-    MOZ_WEBGL_GLX=1
     USE_ELF_DYNSTR_GC=
-
-    AC_DEFINE(MOZ_X11)
-    MOZ_X11=1
     USE_FC_FREETYPE=1
-    XT_LIBS=
-
     TK_CFLAGS='$(MOZ_QT_CFLAGS)'
     TK_LIBS='$(MOZ_QT_LIBS)'
     AC_DEFINE(MOZ_WIDGET_QT)
     MOZ_PDF_PRINTING=1
     ;;
 
 cairo-os2)
     MOZ_WIDGET_TOOLKIT=os2
@@ -8838,16 +8843,19 @@ if test "$ac_cv___posix_fallocate" = tru
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
 
 dnl Check for missing components
 if test "$COMPILE_ENVIRONMENT"; then
 if test "$MOZ_X11"; then
+    if test "$WITHOUT_X11"; then
+        AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined])
+    fi
     dnl ====================================================
     dnl = Check if X headers exist
     dnl ====================================================
     _SAVE_CFLAGS=$CFLAGS
     CFLAGS="$CFLAGS $XCFLAGS"
     AC_TRY_COMPILE([
         #include <stdio.h>
         #include <stdlib.h>
new file mode 100644
--- /dev/null
+++ b/content/base/public/CORSMode.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef CORSMode_h_
+#define CORSMode_h_
+
+namespace mozilla {
+
+enum CORSMode {
+  /**
+   * The default of not using CORS to validate cross-origin loads.
+   */
+  CORS_NONE,
+
+  /**
+   * Validate cross-site loads using CORS, but do not send any credentials
+   * (cookies, HTTP auth logins, etc) along with the request.
+   */
+  CORS_ANONYMOUS,
+
+  /**
+   * Validate cross-site loads using CORS, and send credentials such as cookies
+   * and HTTP auth logins along with the request.
+   */
+  CORS_USE_CREDENTIALS
+};
+
+} // namespace mozilla
+
+#endif /* CORSMode_h_ */
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -74,35 +74,38 @@ nsContentCreatorFunctions.h \
 nsDOMFile.h \
 nsLineBreaker.h \
 nsReferencedElement.h \
 nsTreeSanitizer.h \
 nsXMLNameSpaceMap.h \
 nsIXFormsUtilityService.h \
 $(NULL)
 
-EXPORTS_NAMESPACES = mozilla/dom
+EXPORTS_NAMESPACES = mozilla/dom mozilla
 
 EXPORTS_mozilla/dom = \
 		Element.h \
 		FromParser.h \
 		$(NULL)
 
+EXPORTS_mozilla = \
+		CORSMode.h \
+		$(NULL)
+
 SDK_XPIDLSRCS   = \
 		nsISelection.idl  \
 		$(NULL)
 
 XPIDLSRCS	= \
 		nsIContentPolicy.idl        \
 		nsIDocumentEncoder.idl      \
 		nsIDOMFile.idl \
 		nsIDOMFileReader.idl \
 		nsIDOMFileList.idl \
 		nsIDOMFileException.idl \
-		nsIDOMFileError.idl \
 		nsIDOMFormData.idl \
 		nsIDOMParser.idl \
 		nsIDOMSerializer.idl \
 		nsISelectionController.idl  \
 		nsISelectionDisplay.idl  \
 		nsISelectionListener.idl  \
 		nsISelectionPrivate.idl  \
 		nsIScriptLoaderObserver.idl  \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1614,17 +1614,53 @@ public:
 
   static JSContext *GetCurrentJSContext();
 
   /**
    * Case insensitive comparison between two strings. However it only ignores
    * case for ASCII characters a-z.
    */
   static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
-                                      const nsAString& aStr2);
+                                    const nsAString& aStr2);
+
+  /**
+   * Case insensitive comparison between a string and an ASCII literal.
+   * This must ONLY be applied to an actual literal string. Do not attempt
+   * to use it with a regular char* pointer, or with a char array variable.
+   * The template trick to acquire the array length at compile time without
+   * using a macro is due to Corey Kosak, which much thanks.
+   */
+  static bool EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
+                                           const char* aStr2,
+                                           const PRUint32 len);
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+  static inline bool
+  EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
+                               const char* aStr2)
+  {
+    PRUint32 len = strlen(aStr2);
+    return EqualsLiteralIgnoreASCIICase(aStr1, aStr2, len);
+  }
+#else
+  template<int N>
+  static inline bool
+  EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
+                               const char (&aStr2)[N])
+  {
+    return EqualsLiteralIgnoreASCIICase(aStr1, aStr2, N-1);
+  }
+  template<int N>
+  static inline bool
+  EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
+                               char (&aStr2)[N])
+  {
+    const char* s = aStr2;
+    return EqualsLiteralIgnoreASCIICase(aStr1, s, N-1);
+  }
+#endif
 
   /**
    * Convert ASCII A-Z to a-z.
    */
   static void ASCIIToLower(nsAString& aStr);
   static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
 
   /**
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -38,33 +38,33 @@
 
 #ifndef nsDOMFile_h__
 #define nsDOMFile_h__
 
 #include "nsICharsetDetectionObserver.h"
 #include "nsIFile.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMFileList.h"
-#include "nsIDOMFileError.h"
 #include "nsIInputStream.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsIMutable.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIXMLHttpRequest.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
+
+#include "mozilla/GuardObjects.h"
+#include "mozilla/StandardInteger.h"
+#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/indexedDB/FileInfo.h"
 #include "mozilla/dom/indexedDB/FileManager.h"
 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
 
-#include "mozilla/GuardObjects.h"
-#include "mozilla/StandardInteger.h"
-
 class nsIFile;
 class nsIInputStream;
 class nsIClassInfo;
 class nsIBlobBuilder;
 
 nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
 
 class nsDOMFileBase : public nsIDOMFile,
@@ -358,28 +358,16 @@ public:
 
     return static_cast<nsDOMFileList*>(aSupports);
   }
 
 private:
   nsCOMArray<nsIDOMFile> mFiles;
 };
 
-class nsDOMFileError : public nsIDOMFileError
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMFILEERROR
-
-  nsDOMFileError(PRUint16 aErrorCode) : mCode(aErrorCode) {}
-
-private:
-  PRUint16 mCode;
-};
-
 class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
 public:
   nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
   ~nsDOMFileInternalUrlHolder();
   nsAutoString mUrl;
 private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
deleted file mode 100644
--- a/content/base/public/nsIDOMFileError.idl
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-[scriptable, uuid(4BDAFB64-15E2-49C1-A090-4315A7884A56)]
-interface nsIDOMFileError : nsISupports
-{
-  const unsigned short NOT_FOUND_ERR = 1;
-  const unsigned short SECURITY_ERR = 2;
-  const unsigned short ABORT_ERR = 3;
-  const unsigned short NOT_READABLE_ERR = 4;
-  const unsigned short ENCODING_ERR = 5;
-
-  readonly attribute unsigned short code;
-};
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -34,19 +34,19 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
-interface nsIDOMFileError;
+interface nsIDOMDOMError;
 
-[scriptable, builtinclass, uuid(d158de26-904e-4731-b42c-8b3a4d172703)]
+[scriptable, builtinclass, uuid(faed1779-b523-4060-8c3b-7199f347b273)]
 interface nsIDOMFileReader : nsIDOMEventTarget
 {
   [implicit_jscontext]
   void readAsArrayBuffer(in nsIDOMBlob filedata);
   void readAsBinaryString(in nsIDOMBlob filedata);
   void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMBlob file);
 
@@ -54,17 +54,17 @@ interface nsIDOMFileReader : nsIDOMEvent
 
   const unsigned short EMPTY = 0;
   const unsigned short LOADING = 1;
   const unsigned short DONE = 2;
   readonly attribute unsigned short readyState;
 
   [implicit_jscontext]
   readonly attribute jsval result;
-  readonly attribute nsIDOMFileError error;
+  readonly attribute nsIDOMDOMError error;
 
   attribute nsIDOMEventListener onloadstart;
   attribute nsIDOMEventListener onprogress;
   attribute nsIDOMEventListener onload;
   attribute nsIDOMEventListener onabort;
   attribute nsIDOMEventListener onerror;
   attribute nsIDOMEventListener onloadend;
 };
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1419,17 +1419,18 @@ public:
    * If this document is a static clone, this returns the original
    * document.
    */
   nsIDocument* GetOriginalDocument() { return mOriginalDocument; }
 
   /**
    * Called by nsParser to preload images. Can be removed and code moved
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
-   * parser-module is linked with gklayout-module.
+   * parser-module is linked with gklayout-module.  aCrossOriginAttr should
+   * be a void string if the attr is not present.
    */
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString& aCrossOriginAttr) = 0;
 
   /**
    * Called by nsParser to preload style sheets.  Can also be merged into
    * the parser if and when the parser is merged with libgklayout.
    */
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -42,16 +42,17 @@
 #include "nsISupports.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptLoaderObserver.h"
 #include "nsWeakPtr.h"
 #include "nsIParser.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIDOMHTMLScriptElement.h"
+#include "mozilla/CORSMode.h"
 
 #define NS_ISCRIPTELEMENT_IID \
 { 0x24ab3ff2, 0xd75e, 0x4be4, \
   { 0x8d, 0x50, 0xd6, 0x75, 0x31, 0x29, 0xab, 0x65 } }
 
 /**
  * Internal interface implemented by script elements
  */
@@ -253,16 +254,25 @@ public:
     if (!mAlreadyStarted) {
       // Need to lose parser-insertedness here to allow another script to cause
       // execution later.
       LoseParserInsertedness();
     }
     return block;
   }
 
+  /**
+   * Get the CORS mode of the script element
+   */
+  virtual mozilla::CORSMode GetCORSMode() const
+  {
+    /* Default to no CORS */
+    return mozilla::CORS_NONE;
+  }
+
 protected:
   /**
    * Processes the script if it's in the document-tree and links to or
    * contains a script. Once it has been evaluated there is no way to make it
    * reevaluate the script, you'll have to create a new element. This also means
    * that when adding a src attribute to an element that already contains an
    * inline script, the script referenced by the src attribute will not be
    * loaded.
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -114,23 +114,23 @@ FileIOObject::ClearProgressEventTimer()
 }
 
 void
 FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
 {
   // Set the status attribute, and dispatch the error event
   switch (rv) {
   case NS_ERROR_FILE_NOT_FOUND:
-    mError = new nsDOMFileError(nsIDOMFileError::NOT_FOUND_ERR);
+    mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotFoundError"));
     break;
   case NS_ERROR_FILE_ACCESS_DENIED:
-    mError = new nsDOMFileError(nsIDOMFileError::SECURITY_ERR);
+    mError = DOMError::CreateWithName(NS_LITERAL_STRING("SecurityError"));
     break;
   default:
-    mError = new nsDOMFileError(nsIDOMFileError::NOT_READABLE_ERR);
+    mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotReadableError"));
     break;
   }
 
   // Dispatch error event to signify load failure
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
   DispatchProgressEvent(finalEvent);
 }
 
@@ -253,24 +253,27 @@ FileIOObject::OnStopRequest(nsIRequest* 
   DispatchProgressEvent(termEvent);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FileIOObject::Abort()
 {
-  if (mReadyState != 1)
+  if (mReadyState != 1) {
+    // XXX The spec doesn't say this
     return NS_ERROR_DOM_FILE_ABORT_ERR;
+  }
 
   ClearProgressEventTimer();
 
   mReadyState = 2; // There are DONE constants on multiple interfaces,
                    // but they all have value 2.
-  mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
+  // XXX The spec doesn't say this
+  mError = DOMError::CreateWithName(NS_LITERAL_STRING("AbortError"));
 
   nsString finalEvent;
   nsresult rv = DoAbort(finalEvent);
 
   // Dispatch the events
   DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
   DispatchProgressEvent(finalEvent);
 
@@ -280,16 +283,16 @@ FileIOObject::Abort()
 NS_IMETHODIMP
 FileIOObject::GetReadyState(PRUint16 *aReadyState)
 {
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FileIOObject::GetError(nsIDOMFileError** aError)
+FileIOObject::GetError(nsIDOMDOMError** aError)
 {
   NS_IF_ADDREF(*aError = mError);
   return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -40,18 +40,19 @@
 
 #include "nsIDOMEventTarget.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIChannel.h"
 #include "nsIFile.h"
 #include "nsIDOMFile.h"
 #include "nsIStreamListener.h"
 #include "nsITimer.h"
+#include "nsCOMPtr.h"
 
-#include "nsCOMPtr.h"
+#include "mozilla/dom/DOMError.h"
 
 #define NS_PROGRESS_EVENT_INTERVAL 50
 
 namespace mozilla {
 namespace dom {
 
 extern const PRUint64 kUnknownSize;
 
@@ -64,17 +65,17 @@ class FileIOObject : public nsDOMEventTa
 public:
   FileIOObject();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Common methods
   NS_METHOD Abort();
   NS_METHOD GetReadyState(PRUint16* aReadyState);
-  NS_METHOD GetError(nsIDOMFileError** aError);
+  NS_METHOD GetError(nsIDOMDOMError** aError);
 
   NS_DECL_AND_IMPL_EVENT_HANDLER(abort);
   NS_DECL_AND_IMPL_EVENT_HANDLER(error);
   NS_DECL_AND_IMPL_EVENT_HANDLER(progress);
 
   NS_DECL_NSITIMERCALLBACK
 
   NS_DECL_NSISTREAMLISTENER
@@ -103,17 +104,17 @@ protected:
   void ClearProgressEventTimer();
   void DispatchError(nsresult rv, nsAString& finalEvent);
   nsresult DispatchProgressEvent(const nsAString& aType);
 
   nsCOMPtr<nsITimer> mProgressNotifier;
   bool mProgressEventWasDelayed;
   bool mTimerIsActive;
 
-  nsCOMPtr<nsIDOMFileError> mError;
+  nsCOMPtr<nsIDOMDOMError> mError;
   nsCOMPtr<nsIChannel> mChannel;
 
   PRUint16 mReadyState;
 
   PRUint64 mTotal;
   PRUint64 mTransferred;
 };
 
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -709,17 +709,17 @@ nsAttrValue::GetEnumString(nsAString& aR
   PRInt16 val = allEnumBits >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS;
   const EnumTable* table = sEnumTableArray->
     ElementAt(allEnumBits & NS_ATTRVALUE_ENUMTABLEINDEX_MASK);
 
   while (table->tag) {
     if (table->value == val) {
       aResult.AssignASCII(table->tag);
       if (!aRealTag && allEnumBits & NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER) {
-        ToUpperCase(aResult);
+        nsContentUtils::ASCIIToUpper(aResult);
       }
       return;
     }
     table++;
   }
 
   NS_NOTREACHED("couldn't find value in EnumTable");
 }
@@ -1311,17 +1311,17 @@ nsAttrValue::ParseEnumValue(const nsAStr
     if (aCaseSensitive ? aValue.EqualsASCII(tableEntry->tag) :
                          aValue.LowerCaseEqualsASCII(tableEntry->tag)) {
       PRInt32 value = EnumTableEntryToValue(aTable, tableEntry);
 
       bool equals = aCaseSensitive || aValue.EqualsASCII(tableEntry->tag);
       if (!equals) {
         nsAutoString tag;
         tag.AssignASCII(tableEntry->tag);
-        ToUpperCase(tag);
+        nsContentUtils::ASCIIToUpper(tag);
         if ((equals = tag.Equals(aValue))) {
           value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER;
         }
       }
       SetIntValueAndType(value, eEnum, equals ? nsnull : &aValue);
       NS_ASSERTION(GetEnumValue() == tableEntry->value,
                    "failed to store enum properly");
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -612,18 +612,19 @@ nsContentSink::ProcessLinkHeader(nsICont
             if (type.IsEmpty()) {
               type = value;
               type.StripWhitespace();
             }
           } else if (attr.LowerCaseEqualsLiteral("media")) {
             if (media.IsEmpty()) {
               media = value;
 
-              // HTML4.0 spec is inconsistent, make it case INSENSITIVE
-              ToLowerCase(media);
+              // The HTML5 spec is formulated in terms of the CSS3 spec,
+              // which specifies that media queries are case insensitive.
+              nsContentUtils::ASCIIToLower(media);
             }
           } else if (attr.LowerCaseEqualsLiteral("anchor")) {
             if (anchor.IsEmpty()) {
               anchor = value;
               anchor.StripWhitespace();
             }
           }
         }
@@ -752,29 +753,29 @@ nsContentSink::ProcessMETATag(nsIContent
 
   // set any HTTP-EQUIV data into document's header data as well as url
   nsAutoString header;
   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
   if (!header.IsEmpty()) {
     nsAutoString result;
     aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
     if (!result.IsEmpty()) {
-      ToLowerCase(header);
+      nsContentUtils::ASCIIToLower(header);
       nsCOMPtr<nsIAtom> fieldAtom(do_GetAtom(header));
       rv = ProcessHeaderData(fieldAtom, result, aContent); 
     }
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                             nsGkAtoms::handheldFriendly, eIgnoreCase)) {
     nsAutoString result;
     aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
     if (!result.IsEmpty()) {
-      ToLowerCase(result);
+      nsContentUtils::ASCIIToLower(result);
       mDocument->SetHeaderData(nsGkAtoms::handheldFriendly, result);
     }
   }
 
   return rv;
 }
 
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5388,16 +5388,17 @@ nsContentUtils::ASCIIToUpper(const nsASt
       *dest = (c >= 'a' && c <= 'z') ?
          c + ('A' - 'a') : c;
       ++iter;
       ++dest;
     }
   }
 }
 
+/* static */
 bool
 nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
                                       const nsAString& aStr2)
 {
   PRUint32 len = aStr1.Length();
   if (len != aStr2.Length()) {
     return false;
   }
@@ -5410,32 +5411,70 @@ nsContentUtils::EqualsIgnoreASCIICase(co
     PRUnichar c1 = *str1++;
     PRUnichar c2 = *str2++;
 
     // First check if any bits other than the 0x0020 differs
     if ((c1 ^ c2) & 0xffdf) {
       return false;
     }
 
-    // We know they only differ in the 0x0020 bit.
+    // We know they can only differ in the 0x0020 bit.
     // Likely the two chars are the same, so check that first
     if (c1 != c2) {
       // They do differ, but since it's only in the 0x0020 bit, check if it's
       // the same ascii char, but just differing in case
       PRUnichar c1Upper = c1 & 0xffdf;
       if (!('A' <= c1Upper && c1Upper <= 'Z')) {
         return false;
       }
     }
   }
 
   return true;
 }
 
 /* static */
+bool
+nsContentUtils::EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
+                                             const char* aStr2,
+                                             const PRUint32 len)
+{
+  if (aStr1.Length() != len) {
+    return false;
+  }
+  
+  const PRUnichar* str1 = aStr1.BeginReading();
+  const char*      str2 = aStr2;
+  const PRUnichar* end = str1 + len;
+  
+  while (str1 < end) {
+    PRUnichar c1 = *str1++;
+    PRUnichar c2 = *str2++;
+
+    // First check if any bits other than the 0x0020 differs
+    if ((c1 ^ c2) & 0xffdf) {
+      return false;
+    }
+    
+    // We know they can only differ in the 0x0020 bit.
+    // Likely the two chars are the same, so check that first
+    if (c1 != c2) {
+      // They do differ, but since it's only in the 0x0020 bit, check if it's
+      // the same ascii char, but just differing in case
+      PRUnichar c1Upper = c1 & 0xffdf;
+      if (!('A' <= c1Upper && c1Upper <= 'Z')) {
+        return false;
+      }
+    }
+  }
+  
+  return true;
+}
+
+/* static */
 nsIInterfaceRequestor*
 nsContentUtils::GetSameOriginChecker()
 {
   if (!sSameOriginChecker) {
     sSameOriginChecker = new nsSameOriginChecker();
     NS_IF_ADDREF(sSameOriginChecker);
   }
   return sSameOriginChecker;
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -205,21 +205,21 @@ nsDOMAttribute::GetName(nsAString& aName
 already_AddRefed<nsIAtom>
 nsDOMAttribute::GetNameAtom(nsIContent* aContent)
 {
   nsIAtom* result = nsnull;
   if (!mNsAware &&
       mNodeInfo->NamespaceID() == kNameSpaceID_None &&
       aContent->IsInHTMLDocument() &&
       aContent->IsHTML()) {
-    nsAutoString name;
-    mNodeInfo->NameAtom()->ToString(name);
-    nsAutoString lower;
-    ToLowerCase(name, lower);
-    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lower);
+    nsString name;
+    mNodeInfo->GetName(name);
+    nsAutoString lowercaseName;
+    nsContentUtils::ASCIIToLower(name, lowercaseName);
+    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lowercaseName);
     nameAtom.swap(result);
   } else {
     nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
     nameAtom.swap(result);
   }
   return result;
 }
 
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -330,19 +330,17 @@ nsDOMAttributeMap::SetNamedItemInternal(
       ni = mContent->GetExistingAttrNameFromQName(name);
       if (ni) {
         rv = RemoveAttribute(ni, getter_AddRefs(tmpReturn));
         NS_ENSURE_SUCCESS(rv, rv);
       }
       else {
         if (mContent->IsInHTMLDocument() &&
             mContent->IsHTML()) {
-          nsAutoString lower;
-          ToLowerCase(name, lower);
-          name = lower;
+          nsContentUtils::ASCIIToLower(name);
         }
 
         rv = mContent->NodeInfo()->NodeInfoManager()->
           GetNodeInfo(name, nsnull, kNameSpaceID_None,
                       nsIDOMNode::ATTRIBUTE_NODE, getter_AddRefs(ni));
         NS_ENSURE_SUCCESS(rv, rv);
         // value is already empty
       }
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -628,37 +628,16 @@ NS_IMETHODIMP
 nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
 {
   NS_IF_ADDREF(*aFile = GetItemAt(aIndex));
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////
-// nsDOMFileError implementation
-
-DOMCI_DATA(FileError, nsDOMFileError)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMFileError)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileError)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMFileError)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileError)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(nsDOMFileError)
-NS_IMPL_RELEASE(nsDOMFileError)
-
-NS_IMETHODIMP
-nsDOMFileError::GetCode(PRUint16* aCode)
-{
-  *aCode = mCode;
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////
 // nsDOMFileInternalUrlHolder implementation
 
 nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
                                                        nsIPrincipal* aPrincipal
                                                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   aFile->GetInternalUrl(aPrincipal, mUrl);
 }
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -250,17 +250,17 @@ nsDOMFileReader::GetResult(JSContext* aC
   nsString tmpResult = mResult;
   if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::GetError(nsIDOMFileError** aError)
+nsDOMFileReader::GetError(nsIDOMDOMError** aError)
 {
   return FileIOObject::GetError(aError);
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aFile, JSContext* aCx)
 {
   return ReadFileContent(aCx, aFile, EmptyString(), FILE_AS_ARRAYBUFFER);
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -49,17 +49,16 @@
 #include "prtime.h"                
 #include "nsITimer.h"              
 #include "nsICharsetDetector.h"
 #include "nsICharsetDetectionObserver.h"
 
 #include "nsIDOMFile.h"
 #include "nsIDOMFileReader.h"
 #include "nsIDOMFileList.h"
-#include "nsIDOMFileError.h"
 #include "nsIInputStream.h"
 #include "nsCOMPtr.h"
 #include "nsIStreamLoader.h"
 #include "nsIChannel.h"
 #include "prmem.h"
 
 #include "FileIOObject.h"
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3242,24 +3242,37 @@ nsDocument::MaybeRescheduleAnimationFram
 
 void
 nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
 {
   aCallbacks.AppendElements(mFrameRequestCallbacks);
   mFrameRequestCallbacks.Clear();
 }
 
+PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey,
+                                         PRUint32 aData,
+                                         void* userArg)
+{
+  aKey->RequestDiscard();
+  return PL_DHASH_NEXT;
+}
+
 void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
   if (IsEventHandlingEnabled()) {
     RevokeAnimationFrameNotifications();
   }
 
+  // When our shell goes away, request that all our images be immediately
+  // discarded, so we don't carry around decoded image data for a document we
+  // no longer intend to paint.
+  mImageTracker.EnumerateRead(RequestDiscardEnumerator, nsnull);
+
   mPresShell = nsnull;
 }
 
 void
 nsDocument::RevokeAnimationFrameNotifications()
 {
   if (!mFrameRequestCallbacks.IsEmpty()) {
     mPresShell->GetPresContext()->RefreshDriver()->
@@ -4409,17 +4422,17 @@ nsDocument::CreateElement(const nsAStrin
   *aReturn = nsnull;
 
   nsresult rv = nsContentUtils::CheckQName(aTagName, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
   nsAutoString lcTagName;
   if (needsLowercase) {
-    ToLowerCase(aTagName, lcTagName);
+    nsContentUtils::ASCIIToLower(aTagName, lcTagName);
   }
 
   rv = CreateElem(needsLowercase ? lcTagName : aTagName,
                   nsnull, mDefaultElementType, aReturn);
   return rv;
 }
 
 NS_IMETHODIMP
@@ -7719,24 +7732,30 @@ nsDocument::MaybePreLoadImage(nsIURI* ur
   PRInt16 blockingStatus;
   if (nsContentUtils::IsImageInCache(uri) ||
       !nsContentUtils::CanLoadImage(uri, static_cast<nsIDocument *>(this),
                                     this, NodePrincipal(), &blockingStatus)) {
     return;
   }
 
   nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
-  if (aCrossOriginAttr.LowerCaseEqualsLiteral("anonymous")) {
+  switch (nsGenericElement::StringToCORSMode(aCrossOriginAttr)) {
+  case CORS_NONE:
+    // Nothing to do
+    break;
+  case CORS_ANONYMOUS:
     loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
-  } else if (aCrossOriginAttr.LowerCaseEqualsLiteral("use-credentials")) {
+    break;
+  case CORS_USE_CREDENTIALS:
     loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
-  }
-  // else should we err on the side of not doing the preload if
-  // aCrossOriginAttr is nonempty?  Let's err on the side of doing the
-  // preload as CORS_NONE.
+    break;
+  default:
+    /* should never happen */
+    MOZ_NOT_REACHED("Unknown CORS mode!");
+  }
 
   // Image not in cache - trigger preload
   nsCOMPtr<imgIRequest> request;
   nsresult rv =
     nsContentUtils::LoadImage(uri,
                               this,
                               NodePrincipal(),
                               mDocumentURI, // uri of document used as referrer
@@ -8304,36 +8323,42 @@ nsDocument::RemoveImage(imgIRequest* aIm
   NS_ABORT_IF_FALSE(found, "Removing image that wasn't in the tracker!");
   NS_ABORT_IF_FALSE(count > 0, "Entry in the cache tracker with count 0!");
 
   // We're removing, so decrement the count.
   count--;
 
   // If the count is now zero, remove from the tracker.
   // Otherwise, set the new value.
-  if (count == 0) {
-    mImageTracker.Remove(aImage);
-  } else {
+  if (count != 0) {
     mImageTracker.Put(aImage, count);
-  }
+    return NS_OK;
+  }
+
+  mImageTracker.Remove(aImage);
 
   nsresult rv = NS_OK;
 
-  // If we removed the image from the tracker and we're locking images, unlock
-  // this image.
-  if (count == 0 && mLockingImages)
+  // Now that we're no longer tracking this image, unlock it if we'd
+  // previously locked it.
+  if (mLockingImages) {
     rv = aImage->UnlockImage();
-
-  // If we removed the image from the tracker and we're animating images,
-  // remove our request to animate this image.
-  if (count == 0 && mAnimatingImages) {
+  }
+
+  // If we're animating images, remove our request to animate this one.
+  if (mAnimatingImages) {
     nsresult rv2 = aImage->DecrementAnimationConsumers();
     rv = NS_SUCCEEDED(rv) ? rv2 : rv;
   }
 
+  // Request that the image be discarded if nobody else holds a lock on it.
+  // Do this even if !mLockingImages, because even if we didn't just unlock
+  // this image, it might still be a candidate for discarding.
+  aImage->RequestDiscard();
+
   return rv;
 }
 
 PLDHashOperator LockEnumerator(imgIRequest* aKey,
                                PRUint32 aData,
                                void*    userArg)
 {
   aKey->LockImage();
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -154,16 +154,18 @@
 #include "nsSVGFeatures.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollector.h"
 #include "xpcpublic.h"
 #include "xpcprivate.h"
 #include "nsLayoutStatics.h"
 #include "mozilla/Telemetry.h"
 
+#include "mozilla/CORSMode.h"
+
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
 
 PRInt32 nsIContent::sTabFocusModel = eTabFocus_any;
 bool nsIContent::sTabFocusModelAppliesToXUL = false;
 PRUint32 nsMutationGuard::sMutationCount = 0;
@@ -2848,25 +2850,26 @@ nsresult
 nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
                                  const nsAString& aLocalName,
                                  nsAString& aReturn)
 {
   PRInt32 nsid =
     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
 
   if (nsid == kNameSpaceID_Unknown) {
-    // Unknown namespace means no attr...
-
-    aReturn.Truncate();
-
+    // Unknown namespace means no attribute.
+    SetDOMStringToNull(aReturn);
     return NS_OK;
   }
 
   nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
-  GetAttr(nsid, name, aReturn);
+  bool hasAttr = GetAttr(nsid, name, aReturn);
+  if (!hasAttr) {
+    SetDOMStringToNull(aReturn);
+  }
 
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::SetAttributeNS(const nsAString& aNamespaceURI,
                                  const nsAString& aQualifiedName,
                                  const nsAString& aValue)
@@ -6230,16 +6233,58 @@ nsINode::SizeOfExcludingThis(nsMallocSiz
 
 size_t
 nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
 {
   return Element::SizeOfExcludingThis(aMallocSizeOf) +
          mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf);
 }
 
+static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
+  // Order matters here
+  // See ParseCORSValue
+  { "anonymous",       CORS_ANONYMOUS       },
+  { "use-credentials", CORS_USE_CREDENTIALS },
+  { 0 }
+};
+
+/* static */ void
+nsGenericElement::ParseCORSValue(const nsAString& aValue,
+                                 nsAttrValue& aResult)
+{
+  DebugOnly<bool> success =
+    aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
+                           // default value is anonymous if aValue is
+                           // not a value we understand
+                           &kCORSAttributeTable[0]);
+  MOZ_ASSERT(success);
+}
+
+/* static */ CORSMode
+nsGenericElement::StringToCORSMode(const nsAString& aValue)
+{
+  if (aValue.IsVoid()) {
+    return CORS_NONE;
+  }
+
+  nsAttrValue val;
+  nsGenericElement::ParseCORSValue(aValue, val);
+  return CORSMode(val.GetEnumValue());
+}
+
+/* static */ CORSMode
+nsGenericElement::AttrValueToCORSMode(const nsAttrValue* aValue)
+{
+  if (!aValue) {
+    return CORS_NONE;
+  }
+
+  return CORSMode(aValue->GetEnumValue());
+}
+
 #define EVENT(name_, id_, type_, struct_)                                    \
   NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) {            \
     nsEventListenerManager *elm = GetListenerManager(false);              \
     if (elm) {                                                               \
       elm->GetJSEventListener(nsGkAtoms::on##name_, vp);                     \
     } else {                                                                 \
       *vp = JSVAL_NULL;                                                      \
     }                                                                        \
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -60,16 +60,17 @@
 #include "nsIDOMNodeSelector.h"
 #include "nsIDOMXPathNSResolver.h"
 #include "nsPresContext.h"
 #include "nsIDOMDOMStringMap.h"
 #include "nsContentList.h"
 #include "nsDOMClassInfoID.h" // DOMCI_DATA
 #include "nsIDOMTouchEvent.h"
 #include "nsIInlineEventHandlers.h"
+#include "mozilla/CORSMode.h"
 
 #include "nsISMILAttr.h"
 
 class nsIDOMAttr;
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsICSSDeclaration;
@@ -635,16 +636,35 @@ public:
   static bool CanSkipInCC(nsINode* aNode);
   static bool CanSkipThis(nsINode* aNode);
   static void MarkNodeChildren(nsINode* aNode);
   static void InitCCCallbacks();
   static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
                            void *aData);
   static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
                                   void* aData);
+
+  /**
+   * Parse a string into an nsAttrValue for a CORS attribute.  This
+   * never fails.  The resulting value is an enumerated value whose
+   * GetEnumValue() returns one of the above constants.
+   */
+  static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
+
+  /**
+   * Return the CORS mode for a given string
+   */
+  static mozilla::CORSMode StringToCORSMode(const nsAString& aValue);
+  
+  /**
+   * Return the CORS mode for a given nsAttrValue (which may be null,
+   * but if not should have been parsed via ParseCORSValue).
+   */
+  static mozilla::CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
+
 protected:
   /*
    * Named-bools for use with SetAttrAndNotify to make call sites easier to
    * read.
    */
   static const bool kFireMutationEvent           = true;
   static const bool kDontFireMutationEvent       = false;
   static const bool kNotifyDocumentObservers     = true;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1999,18 +1999,20 @@ GK_ATOM(mixed, "mixed")
 GK_ATOM(multiline, "multiline")
 GK_ATOM(password, "password")
 GK_ATOM(posinset, "posinset") 
 GK_ATOM(select1, "select1")
 GK_ATOM(setsize, "setsize")
 GK_ATOM(tableCellIndex, "table-cell-index")
 GK_ATOM(textAlign, "text-align")
 GK_ATOM(textIndent, "text-indent")
+GK_ATOM(textLineThroughColor, "text-line-through-color")
 GK_ATOM(textLineThroughStyle, "text-line-through-style")
 GK_ATOM(textPosition, "text-position")
+GK_ATOM(textUnderlineColor, "text-underline-color")
 GK_ATOM(textUnderlineStyle, "text-underline-style")
 GK_ATOM(toolbarname, "toolbarname")
 GK_ATOM(toolbarseparator, "toolbarseparator")
 GK_ATOM(toolbarspacer, "toolbarspacer")
 GK_ATOM(toolbarspring, "toolbarspring")
 GK_ATOM(_undefined, "undefined")
 GK_ATOM(xmlroles, "xml-roles")
 #endif
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -55,17 +55,17 @@
 #include "nsContentPolicyUtils.h"
 #include "nsIURI.h"
 #include "nsILoadGroup.h"
 #include "imgIContainer.h"
 #include "imgILoader.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsAsyncDOMEvent.h"
-#include "nsGenericHTMLElement.h"
+#include "nsGenericElement.h"
 
 #include "nsIPresShell.h"
 #include "nsEventStates.h"
 #include "nsGUIEvent.h"
 
 #include "nsIChannel.h"
 #include "nsIStreamListener.h"
 
@@ -77,16 +77,18 @@
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsSVGEffects.h"
 
 #include "mozAutoDocUpdate.h"
 #include "mozilla/dom/Element.h"
 
+using namespace mozilla;
+
 #ifdef DEBUG_chb
 static void PrintReqURL(imgIRequest* req) {
   if (!req) {
     printf("(null req)\n");
     return;
   }
 
   nsCOMPtr<nsIURI> uri;
@@ -770,19 +772,19 @@ nsImageLoadingContent::LoadImage(nsIURI*
   if (!NS_CP_ACCEPTED(cpDecision)) {
     FireEvent(NS_LITERAL_STRING("error"));
     SetBlockedRequest(aNewURI, cpDecision);
     return NS_OK;
   }
 
   nsLoadFlags loadFlags = aLoadFlags;
   PRInt32 corsmode = GetCORSMode();
-  if (corsmode == nsGenericHTMLElement::CORS_ANONYMOUS) {
+  if (corsmode == CORS_ANONYMOUS) {
     loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
-  } else if (corsmode == nsGenericHTMLElement::CORS_USE_CREDENTIALS) {
+  } else if (corsmode == CORS_USE_CREDENTIALS) {
     loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
   }
 
   // Not blocked. Do the load.
   nsCOMPtr<imgIRequest>& req = PrepareNextRequest();
   nsresult rv;
   rv = nsContentUtils::LoadImage(aNewURI, aDocument,
                                  aDocument->NodePrincipal(),
@@ -1182,13 +1184,13 @@ nsImageLoadingContent::CreateStaticImage
   aDest->mStateChangerDepth = mStateChangerDepth;
   aDest->mIsImageStateForced = mIsImageStateForced;
   aDest->mLoading = mLoading;
   aDest->mBroken = mBroken;
   aDest->mUserDisabled = mUserDisabled;
   aDest->mSuppressed = mSuppressed;
 }
 
-nsGenericHTMLElement::CORSMode
+CORSMode
 nsImageLoadingContent::GetCORSMode()
 {
-  return nsGenericHTMLElement::CORS_NONE;
+  return CORS_NONE;
 }
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -49,16 +49,17 @@
 #include "nsINode.h"
 #include "imgIRequest.h"
 #include "prtypes.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
 #include "nsString.h"
 #include "nsEventStates.h"
 #include "nsGenericHTMLElement.h"
+#include "mozilla/CORSMode.h"
 
 class nsIURI;
 class nsIDocument;
 class imgILoader;
 class nsIIOService;
 
 class nsImageLoadingContent : public nsIImageLoadingContent
 {
@@ -178,17 +179,17 @@ protected:
   // Sets blocking state only if the desired state is different from the
   // current one. See the comment for mBlockingOnload for more information.
   void SetBlockingOnload(bool aBlocking);
 
   /**
    * Returns the CORS mode that will be used for all future image loads. The
    * default implementation returns CORS_NONE unconditionally.
    */
-  virtual nsGenericHTMLElement::CORSMode GetCORSMode();
+  virtual mozilla::CORSMode GetCORSMode();
 
 private:
   /**
    * Struct used to manage the image observers.
    */
   struct ImageObserver {
     ImageObserver(imgIDecoderObserver* aObserver) :
       mObserver(aObserver),
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -69,37 +69,44 @@
 #include "nsThreadUtils.h"
 #include "nsDocShellCID.h"
 #include "nsIContentSecurityPolicy.h"
 #include "prlog.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "nsCRT.h"
 #include "nsContentCreatorFunctions.h"
+#include "nsGenericElement.h"
+#include "nsCrossSiteListenerProxy.h"
 
 #include "mozilla/FunctionTimer.h"
+#include "mozilla/CORSMode.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gCspPRLog;
 #endif
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 //////////////////////////////////////////////////////////////
 // Per-request data structure
 //////////////////////////////////////////////////////////////
 
 class nsScriptLoadRequest : public nsISupports {
 public:
   nsScriptLoadRequest(nsIScriptElement* aElement,
-                      PRUint32 aVersion)
+                      PRUint32 aVersion,
+                      CORSMode aCORSMode)
     : mElement(aElement),
       mLoading(true),
       mIsInline(true),
-      mJSVersion(aVersion), mLineNo(1)
+      mJSVersion(aVersion),
+      mLineNo(1),
+      mCORSMode(aCORSMode)
   {
   }
 
   NS_DECL_ISUPPORTS
 
   void FireScriptAvailable(nsresult aResult)
   {
     mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
@@ -117,16 +124,17 @@ public:
   nsCOMPtr<nsIScriptElement> mElement;
   bool mLoading;             // Are we still waiting for a load to complete?
   bool mIsInline;            // Is the script inline or loaded?
   nsString mScriptText;              // Holds script for loaded scripts
   PRUint32 mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   PRInt32 mLineNo;
+  const CORSMode mCORSMode;
 };
 
 // The nsScriptLoadRequest is passed as the context to necko, and thus
 // it needs to be threadsafe. Necko won't do anything with this
 // context, but it will AddRef and Release it on other threads.
 NS_IMPL_THREADSAFE_ISUPPORTS0(nsScriptLoadRequest)
 
 //////////////////////////////////////////////////////////////
@@ -288,17 +296,16 @@ nsScriptLoader::StartLoad(nsScriptLoadRe
                          ? static_cast<nsISupports *>(aRequest->mElement.get())
                          : static_cast<nsISupports *>(mDocument);
   nsresult rv = ShouldLoadScript(mDocument, context, aRequest->mURI, aType);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
-  nsCOMPtr<nsIStreamLoader> loader;
 
   nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mDocument->GetScriptGlobalObject()));
   if (!window) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsIDocShell *docshell = window->GetDocShell();
 
@@ -327,20 +334,31 @@ nsScriptLoader::StartLoad(nsScriptLoadRe
   if (httpChannel) {
     // HTTP content negotation has little value in this context.
     httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                   NS_LITERAL_CSTRING("*/*"),
                                   false);
     httpChannel->SetReferrer(mDocument->GetDocumentURI());
   }
 
+  nsCOMPtr<nsIStreamLoader> loader;
   rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = channel->AsyncOpen(loader, aRequest);
+  nsCOMPtr<nsIStreamListener> listener = loader.get();
+
+  if (aRequest->mCORSMode != CORS_NONE) {
+    bool withCredentials = (aRequest->mCORSMode == CORS_USE_CREDENTIALS);
+    listener =
+      new nsCORSListenerProxy(listener, mDocument->NodePrincipal(), channel,
+                              withCredentials, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  rv = channel->AsyncOpen(listener, aRequest);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 bool
 nsScriptLoader::PreloadURIComparator::Equals(const PreloadInfo &aPi,
                                              nsIURI * const &aURI) const
@@ -546,42 +564,44 @@ nsScriptLoader::ProcessScriptElement(nsI
 
   nsRefPtr<nsScriptLoadRequest> request;
   if (aElement->GetScriptExternal()) {
     // external script
     nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
     if (!scriptURI) {
       return false;
     }
+    CORSMode ourCORSMode = aElement->GetCORSMode();
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       // preloaded
       // note that a script-inserted script can steal a preload!
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
       nsString preloadCharset(mPreloads[i].mCharset);
       mPreloads.RemoveElementAt(i);
 
       // Double-check that the charset the preload used is the same as
       // the charset we have now.
       nsAutoString elementCharset;
       aElement->GetScriptCharset(elementCharset);
-      if (elementCharset.Equals(preloadCharset)) {
+      if (elementCharset.Equals(preloadCharset) &&
+          ourCORSMode == request->mCORSMode) {
         rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
         NS_ENSURE_SUCCESS(rv, false);
       } else {
         // Drop the preload
         request = nsnull;
       }
     }
 
     if (!request) {
       // no usable preload
-      request = new nsScriptLoadRequest(aElement, version);
+      request = new nsScriptLoadRequest(aElement, version, ourCORSMode);
       request->mURI = scriptURI;
       request->mIsInline = false;
       request->mLoading = true;
       rv = StartLoad(request, type);
       NS_ENSURE_SUCCESS(rv, false);
     }
 
     request->mJSVersion = version;
@@ -692,17 +712,18 @@ nsScriptLoader::ProcessScriptElement(nsI
       csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
                                NS_ConvertUTF8toUTF16(asciiSpec),
                                scriptText,
                                aElement->GetScriptLineNumber());
       return false;
     }
   }
 
-  request = new nsScriptLoadRequest(aElement, version);
+  // Inline scripts ignore ther CORS mode and are always CORS_NONE
+  request = new nsScriptLoadRequest(aElement, version, CORS_NONE);
   request->mJSVersion = version;
   request->mLoading = false;
   request->mIsInline = true;
   request->mURI = mDocument->GetDocumentURI();
   request->mLineNo = aElement->GetScriptLineNumber();
 
   if (aElement->GetParserCreated() == FROM_PARSER_XSLT &&
       (!ReadyToExecuteScripts() || !mXSLTRequests.IsEmpty())) {
@@ -1223,19 +1244,24 @@ nsScriptLoader::PrepareLoadedRequest(nsS
     bool requestSucceeded;
     rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
     if (NS_SUCCEEDED(rv) && !requestSucceeded) {
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
-  rv = nsContentUtils::GetSecurityManager()->
-    GetChannelPrincipal(channel, getter_AddRefs(aRequest->mOriginPrincipal));
-  NS_ENSURE_SUCCESS(rv, rv);
+  // If this load was subject to a CORS check; don't flag it with a
+  // separate origin principal, so that it will treat our document's
+  // principal as the origin principal
+  if (aRequest->mCORSMode == CORS_NONE) {
+    rv = nsContentUtils::GetSecurityManager()->
+      GetChannelPrincipal(channel, getter_AddRefs(aRequest->mOriginPrincipal));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
 
   if (aStringLen) {
     // Check the charset attribute to determine script charset.
     nsAutoString hintCharset;
     if (!aRequest->IsPreload()) {
       aRequest->mElement->GetScriptCharset(hintCharset);
     } else {
       nsTArray<PreloadInfo>::index_type i =
@@ -1320,24 +1346,27 @@ nsScriptLoader::ParsingComplete(bool aTe
 
   // Have to call this even if aTerminated so we'll correctly unblock
   // onload and all.
   ProcessPendingRequests();
 }
 
 void
 nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
-                           const nsAString &aType)
+                           const nsAString &aType,
+                           const nsAString &aCrossOrigin)
 {
   // Check to see if scripts has been turned off.
   if (!mEnabled || !mDocument->IsScriptEnabled()) {
     return;
   }
 
-  nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
+  nsRefPtr<nsScriptLoadRequest> request =
+    new nsScriptLoadRequest(nsnull, 0,
+                            nsGenericElement::StringToCORSMode(aCrossOrigin));
   request->mURI = aURI;
   request->mIsInline = false;
   request->mLoading = true;
   nsresult rv = StartLoad(request, aType);
   if (NS_FAILED(rv)) {
     return;
   }
 
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -233,19 +233,22 @@ public:
   }
 
   /**
    * Adds aURI to the preload list and starts loading it.
    *
    * @param aURI The URI of the external script.
    * @param aCharset The charset parameter for the script.
    * @param aType The type parameter for the script.
+   * @param aCrossOrigin The crossorigin attribute for the script.
+   *                     Void if not present.
    */
   virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
-                          const nsAString &aType);
+                          const nsAString &aType,
+                          const nsAString &aCrossOrigin);
 
 private:
   /**
    * Unblocks the creator parser of the parser-blocking scripts.
    */
   void UnblockParser(nsScriptLoadRequest* aParserBlockingRequest);
 
   /**
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -180,32 +180,32 @@ PRUint32 nsStyleLinkElement::ParseLinkTy
 
   nsAString::const_iterator current(start);
   bool inString = !nsContentUtils::IsHTMLWhitespace(*current);
   nsAutoString subString;
   
   while (current != done) {
     if (nsContentUtils::IsHTMLWhitespace(*current)) {
       if (inString) {
-        ToLowerCase(Substring(start, current), subString);
+        nsContentUtils::ASCIIToLower(Substring(start, current), subString);
         linkMask |= ToLinkMask(subString);
         inString = false;
       }
     }
     else {
       if (!inString) {
         start = current;
         inString = true;
       }
     }
     ++current;
   }
   if (inString) {
-    ToLowerCase(Substring(start, current), subString);
-     linkMask |= ToLinkMask(subString);
+    nsContentUtils::ASCIIToLower(Substring(start, current), subString);
+    linkMask |= ToLinkMask(subString);
   }
   return linkMask;
 }
 
 NS_IMETHODIMP
 nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
                                      bool* aWillNotify,
                                      bool* aIsAlternate)
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -557,16 +557,21 @@ include $(topsrcdir)/config/rules.mk
 		test_bug717511.html \
 		file_bug717511.html \
 		file_bug717511.html^headers^ \
 		file_bug717511_2.html \
 		file_bug717511_2.html^headers^ \
 		test_bug726364.html \
 		test_bug698381.html \
 		test_bug711047.html \
+		test_bug696301-1.html \
+		test_bug696301-2.html \
+		bug696301-script-1.js \
+		bug696301-script-1.js^headers^ \
+		bug696301-script-2.js \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
copy from content/base/test/bug461735-post-redirect.js
copy to content/base/test/bug696301-script-1.js
--- a/content/base/test/bug461735-post-redirect.js
+++ b/content/base/test/bug696301-script-1.js
@@ -1,3 +1,3 @@
 var a = 0;
-var b = 0;
+var global = "ran";
 c();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/content/base/test/bug696301-script-1.js^headers^
@@ -0,0 +1,1 @@
+Access-Control-Allow-Origin: *
copy from content/base/test/bug461735-post-redirect.js
copy to content/base/test/bug696301-script-2.js
--- a/content/base/test/bug461735-post-redirect.js
+++ b/content/base/test/bug696301-script-2.js
@@ -1,3 +1,3 @@
 var a = 0;
-var b = 0;
+var global = "ran";
 c();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug696301-1.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=696301
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 696301</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+var errorFired = false;
+var global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "Script error.", "Should have empty error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-1.js",
+     "Should have correct script URI");
+  is(line, 0, "Shouldn't have a line here");
+  errorFired = true;
+}
+</script>
+<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
+<script>
+  is(errorFired, true, "Should have error in different origin script");
+  is(global, "ran", "Different origin script should have run");
+</script>
+
+<script type="application/javascript">
+errorFired = false;
+global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "c is not defined", "Should have correct error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-1.js",
+     "Should also have correct script URI");
+  is(line, 3, "Should have a line here");
+  errorFired = true;
+}
+</script>
+<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"
+        crossorigin></script>
+<script>
+  is(errorFired, true, "Should have error in different origin script with CORS");
+  is(global, "ran", "Different origin script with CORS should have run");
+</script>
+
+<script type="application/javascript">
+errorFired = false;
+global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "Error loading script", "Should have correct error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-2.js",
+     "Should still have correct script URI even when failing CORS");
+  is(line, 1, "Load failures seem to count as line 1");
+  errorFired = true;
+}
+</script>
+<script src="http://example.com/tests/content/base/test/bug696301-script-2.js"
+        crossorigin></script>
+<script>
+  is(errorFired, true,
+     "Should have error when different origin script fails CORS check");
+  is(global, "", "Different origin script that fails CORS should not have run");
+</script>
+
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug696301-2.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=696301
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 696301</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<!-- Test SVG script here -->
+<svg>
+<script type="application/javascript">
+var errorFired = false;
+var global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "Script error.", "Should have empty error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-1.js",
+     "Should have correct script URI");
+  is(line, 0, "Shouldn't have a line here");
+  errorFired = true;
+}
+</script>
+<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
+<script>
+  is(errorFired, true, "Should have error in different origin script");
+  is(global, "ran", "Different origin script should have run");
+</script>
+
+<script type="application/javascript">
+errorFired = false;
+global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "c is not defined", "Should have correct error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-1.js",
+     "Should also have correct script URI");
+  is(line, 3, "Should have a line here");
+  errorFired = true;
+}
+</script>
+<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"
+        crossorigin></script>
+<script>
+  is(errorFired, true, "Should have error in different origin script with CORS");
+  is(global, "ran", "Different origin script with CORS should have run");
+</script>
+
+<script type="application/javascript">
+errorFired = false;
+global = "";
+window.onerror = function(message, uri, line) {
+  is(message, "Error loading script", "Should have correct error message");
+  is(uri,
+     "http://example.com/tests/content/base/test/bug696301-script-2.js",
+     "Should still have correct script URI even when failing CORS");
+  is(line, 1, "Load failures seem to count as line 1");
+  errorFired = true;
+}
+</script>
+<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-2.js"
+        crossorigin></script>
+<script>
+  is(errorFired, true,
+     "Should have error when different origin script fails CORS check");
+  is(global, "", "Different origin script that fails CORS should not have run");
+</script>
+</svg>
+</pre>
+</body>
+</html>
--- a/content/canvas/crashtests/crashtests.list
+++ b/content/canvas/crashtests/crashtests.list
@@ -1,6 +1,7 @@
 load 360293-1.html
 load 421715-1.html
 load 553938-1.html
 load 647480.html
 load 0px-size-font-667225.html
+load texImage2D.html
 load 729116.html
new file mode 100644
--- /dev/null
+++ b/content/canvas/crashtests/texImage2D.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<canvas></canvas>
+<script>
+var canvas = document.body.firstChild,
+    gl = canvas.getContext("experimental-webgl");
+gl.texImage2D(0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
+gl.texSubImage2D(0, 0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
+</script>
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -377,16 +377,143 @@ nsIDOMWebGLRenderingContext_ReadPixels(J
     if (NS_FAILED(rv))
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 
+class CallTexImage2D
+{
+private:
+    nsIDOMWebGLRenderingContext* self;
+    WebGLenum target;
+    WebGLint level;
+    WebGLenum internalformat;
+    WebGLenum format;
+    WebGLenum type;
+
+public:
+    explicit CallTexImage2D(nsIDOMWebGLRenderingContext* aSelf,
+                            WebGLenum aTarget,
+                            WebGLint aLevel,
+                            WebGLenum aInternalformat,
+                            WebGLenum aFormat,
+                            WebGLenum aType)
+        : self(aSelf)
+        , target(aTarget)
+        , level(aLevel)
+        , internalformat(aInternalformat)
+        , format(aFormat)
+        , type(aType)
+    {}
+
+    nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
+                                JSObject* pixels)
+    {
+        return self->TexImage2D_imageData(target, level, internalformat, width,
+                                          height, 0, format, type, pixels);
+    }
+    nsresult DoCallForElement(mozilla::dom::Element* elt)
+    {
+        return self->TexImage2D_dom(target, level, internalformat, format, type,
+                                    elt);
+    }
+};
+
+class CallTexSubImage2D
+{
+private:
+    nsIDOMWebGLRenderingContext* self;
+    WebGLenum target;
+    WebGLint level;
+    WebGLint xoffset;
+    WebGLint yoffset;
+    WebGLenum format;
+    WebGLenum type;
+
+public:
+    explicit CallTexSubImage2D(nsIDOMWebGLRenderingContext* aSelf,
+                               WebGLenum aTarget,
+                               WebGLint aLevel,
+                               WebGLint aXoffset,
+                               WebGLint aYoffset,
+                               WebGLenum aFormat,
+                               WebGLenum aType)
+
+        : self(aSelf)
+        , target(aTarget)
+        , level(aLevel)
+        , xoffset(aXoffset)
+        , yoffset(aYoffset)
+        , format(aFormat)
+        , type(aType)
+    {}
+
+    nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
+                                JSObject* pixels)
+    {
+        return self->TexSubImage2D_imageData(target, level, xoffset, yoffset,
+                                             width, height, format, type,
+                                             pixels);
+    }
+    nsresult DoCallForElement(mozilla::dom::Element* elt)
+    {
+        return self->TexSubImage2D_dom(target, level, xoffset, yoffset, format,
+                                       type, elt);
+    }
+};
+
+template<class T>
+static bool
+TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
+{
+    MOZ_ASSERT(object && object->isObject());
+
+    nsGenericElement* elt;
+    xpc_qsSelfRef eltRef;
+    if (NS_SUCCEEDED(xpc_qsUnwrapArg<nsGenericElement>(
+            cx, *object, &elt, &eltRef.ptr, object))) {
+        nsresult rv = self.DoCallForElement(elt);
+        return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
+    }
+
+    // Failed to interpret object as an Element, now try to interpret it as
+    // ImageData.
+    JSObject* imageData = &object->toObject();
+
+    jsval js_width, js_height, js_data;
+    if (!JS_GetProperty(cx, imageData, "width", &js_width) ||
+        !JS_GetProperty(cx, imageData, "height", &js_height) ||
+        !JS_GetProperty(cx, imageData, "data", &js_data)) {
+        return false;
+    }
+    if (js_width  == JSVAL_VOID ||
+        js_height == JSVAL_VOID ||
+        !js_data.isObject())
+    {
+        return xpc_qsThrow(cx, NS_ERROR_FAILURE);
+    }
+    int32_t int_width, int_height;
+    JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
+    if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
+        !JS_ValueToECMAInt32(cx, js_height, &int_height))
+    {
+        return false;
+    }
+    if (!js_IsTypedArray(obj_data))
+    {
+        return xpc_qsThrow(cx, NS_ERROR_FAILURE);
+    }
+
+    nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data);
+    return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
+}
+
 /*
  * TexImage2D takes:
  *    TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
  *    TexImage2D(uint, int, uint, uint, uint, nsIDOMElement)
  *    TexImage2D(uint, int, uint, uint, uint, ImageData)
  */
 static JSBool
 nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
@@ -407,75 +534,31 @@ nsIDOMWebGLRenderingContext_TexImage2D(J
     if (argc < 6 || argc == 7 || argc == 8)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
     // arguments common to all cases
     GET_UINT32_ARG(argv0, 0);
     GET_INT32_ARG(argv1, 1);
+    GET_UINT32_ARG(argv2, 2);
 
-    if (argc > 5 &&
-        !JSVAL_IS_PRIMITIVE(argv[5]))
-    {
+    if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) {
         // implement the variants taking a DOMElement as argv[5]
-        GET_UINT32_ARG(argv2, 2);
         GET_UINT32_ARG(argv3, 3);
         GET_UINT32_ARG(argv4, 4);
 
-        nsIDOMElement *elt;
-        xpc_qsSelfRef eltRef;
-        rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]);
-        if (NS_FAILED(rv)) return JS_FALSE;
-
-        rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt);
-
-        // NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
-        // bail out immediately, don't try to interprete as ImageData
-        if (rv == NS_ERROR_DOM_SECURITY_ERR) {
-            xpc_qsThrowBadArg(cx, rv, vp, 5);
-            return JS_FALSE;
+        CallTexImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4);
+        if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 5)) {
+            return false;
         }
-
-        if (NS_FAILED(rv)) {
-            // failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData
-            JSObject *argv5 = JSVAL_TO_OBJECT(argv[5]);
-
-            jsval js_width, js_height, js_data;
-            JS_GetProperty(cx, argv5, "width", &js_width);
-            JS_GetProperty(cx, argv5, "height", &js_height);
-            JS_GetProperty(cx, argv5, "data", &js_data);
-            if (js_width  == JSVAL_VOID ||
-                js_height == JSVAL_VOID ||
-                !js_data.isObject())
-            {
-                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
-                return JS_FALSE;
-            }
-            int32_t int_width, int_height;
-            JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
-            if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
-                !JS_ValueToECMAInt32(cx, js_height, &int_height))
-            {
-                return JS_FALSE;
-            }
-            if (!js_IsTypedArray(obj_data))
-            {
-                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
-                return JS_FALSE;
-            }
-            rv = self->TexImage2D_imageData(argv0, argv1, argv2,
-                                            int_width, int_height, 0,
-                                            argv3, argv4, js::TypedArray::getTypedArray(obj_data));
-        }
-    } else if (argc > 8 &&
-               JSVAL_IS_OBJECT(argv[8])) // here, we allow null !
-    {
+        rv = NS_OK;
+    } else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
+        // here, we allow null !
         // implement the variants taking a buffer/array as argv[8]
-        GET_UINT32_ARG(argv2, 2);
         GET_INT32_ARG(argv3, 3);
         GET_INT32_ARG(argv4, 4);
         GET_INT32_ARG(argv5, 5);
         GET_UINT32_ARG(argv6, 6);
         GET_UINT32_ARG(argv7, 7);
 
         JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
 
@@ -531,71 +614,27 @@ nsIDOMWebGLRenderingContext_TexSubImage2
     jsval *argv = JS_ARGV(cx, vp);
 
     // arguments common to all cases
     GET_UINT32_ARG(argv0, 0);
     GET_INT32_ARG(argv1, 1);
     GET_INT32_ARG(argv2, 2);
     GET_INT32_ARG(argv3, 3);
 
-    if (argc > 6 &&
-        !JSVAL_IS_PRIMITIVE(argv[6]))
-    {
-        // implement the variants taking a DOMElement as argv[6]
+    if (argc > 6 && !JSVAL_IS_PRIMITIVE(argv[6])) {
+        // implement the variants taking a DOMElement or an ImageData as argv[6]
         GET_UINT32_ARG(argv4, 4);
         GET_UINT32_ARG(argv5, 5);
 
-        nsIDOMElement *elt;
-        xpc_qsSelfRef eltRef;
-        rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[6], &elt, &eltRef.ptr, &argv[6]);
-        if (NS_FAILED(rv)) return JS_FALSE;
-
-        rv = self->TexSubImage2D_dom(argv0, argv1, argv2, argv3, argv4, argv5, elt);
-        
-        // NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
-        // bail out immediately, don't try to interprete as ImageData
-        if (rv == NS_ERROR_DOM_SECURITY_ERR) {
-            xpc_qsThrowBadArg(cx, rv, vp, 6);
-            return JS_FALSE;
+        CallTexSubImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4, argv5);
+        if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 6)) {
+            return false;
         }
-
-        if (NS_FAILED(rv)) {
-            // failed to interprete argv[6] as a DOMElement, now try to interprete it as ImageData
-            JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
-            jsval js_width, js_height, js_data;
-            JS_GetProperty(cx, argv6, "width", &js_width);
-            JS_GetProperty(cx, argv6, "height", &js_height);
-            JS_GetProperty(cx, argv6, "data", &js_data);
-            if (js_width  == JSVAL_VOID ||
-                js_height == JSVAL_VOID ||
-                !js_data.isObject())
-            {
-                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
-                return JS_FALSE;
-            }
-            int32_t int_width, int_height;
-            JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
-            if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
-                !JS_ValueToECMAInt32(cx, js_height, &int_height))
-            {
-                return JS_FALSE;
-            }
-            if (!js_IsTypedArray(obj_data))
-            {
-                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
-                return JS_FALSE;
-            }
-            rv = self->TexSubImage2D_imageData(argv0, argv1, argv2, argv3,
-                                               int_width, int_height,
-                                               argv4, argv5,
-                                               js::TypedArray::getTypedArray(obj_data));
-        }
-    } else if (argc > 8 &&
-               !JSVAL_IS_PRIMITIVE(argv[8]))
-    {
+        rv = NS_OK;
+    } else if (argc > 8 && !JSVAL_IS_PRIMITIVE(argv[8])) {
         // implement the variants taking a buffer/array as argv[8]
         GET_INT32_ARG(argv4, 4);
         GET_INT32_ARG(argv5, 5);
         GET_UINT32_ARG(argv6, 6);
         GET_UINT32_ARG(argv7, 7);
 
         JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
         // try to grab a js::TypedArray
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -810,17 +810,17 @@ protected:
                                WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
 
     void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
                       const PRUint8*src, PRUint8 *dst,
                       int srcFormat, bool srcPremultiplied,
                       int dstFormat, bool dstPremultiplied,
                       size_t dstTexelSize);
 
-    nsresult DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
+    nsresult DOMElementToImageSurface(dom::Element* imageOrCanvas,
                                       gfxImageSurface **imageOut,
                                       int *format);
 
     nsresult CopyTexSubImage2D_base(WebGLenum target,
                                     WebGLint level,
                                     WebGLenum internalformat,
                                     WebGLint xoffset,
                                     WebGLint yoffset,
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -65,16 +65,17 @@
 #include "WebGLValidateStrings.h"
 
 // needed to check if current OS is lower than 10.7
 #if defined(MOZ_WIDGET_COCOA)
 #include "nsCocoaFeatures.h"
 #endif
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
 static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2);
 
 /* Helper macros for when we're just wrapping a gl method, so that
  * we can avoid having to type this 500 times.  Note that these MUST
  * NOT BE USED if we need to check any of the parameters.
  */
@@ -3961,35 +3962,34 @@ WebGLContext::ConvertImage(size_t width,
         HANDLE_FLOAT_SRCFORMAT(A32F,     4, unpackA32FToRGBA32F)
         default:
             NS_ASSERTION(false, "Coding error?! Should never reach this point.");
             return;
     }
 }
 
 nsresult
-WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
+WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
                                        gfxImageSurface **imageOut, int *format)
 {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(imageOrCanvas);
-    if (!content) {
+    if (!imageOrCanvas) {
         return NS_ERROR_FAILURE;
     }        
 
     PRUint32 flags =
         nsLayoutUtils::SFE_WANT_NEW_SURFACE |
         nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
 
     if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
         flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
     if (!mPixelStorePremultiplyAlpha)
         flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
 
     nsLayoutUtils::SurfaceFromElementResult res =
-        nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags);
+        nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
     if (!res.mSurface)
         return NS_ERROR_FAILURE;
     if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) {
         // SurfaceFromElement lied!
         return NS_ERROR_FAILURE;
     }
 
     // We disallow loading cross-domain images and videos that have not been validated
@@ -4011,17 +4011,17 @@ WebGLContext::DOMElementToImageSurface(n
                                 "See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures");
             return NS_ERROR_DOM_SECURITY_ERR;
         }
     }
 
     // part 2: if the DOM element is a canvas, check that it's not write-only.
     // That would indicate a tainted canvas, i.e. a canvas that could contain
     // cross-domain image data.
-    if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) {
+    if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(imageOrCanvas)) {
         if (canvas->IsWriteOnly()) {
             LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
                                 "to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
                                 "when a cross-domain image is drawn on it. "
                                 "See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures");
             return NS_ERROR_DOM_SECURITY_ERR;
         }
     }
@@ -5077,17 +5077,17 @@ WebGLContext::TexImage2D_imageData(WebGL
                            pixels ? JS_GetTypedArrayData(pixels) : 0,
                            pixels ? JS_GetTypedArrayByteLength(pixels) : 0,
                            -1,
                            WebGLTexelFormat::RGBA8, false);
 }
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
-                             WebGLenum format, GLenum type, nsIDOMElement *elt)
+                             WebGLenum format, GLenum type, Element* elt)
 {
     if (!IsContextStable())
         return NS_OK;
 
     nsRefPtr<gfxImageSurface> isurf;
 
     int srcFormat;
     nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf), &srcFormat);
@@ -5267,17 +5267,17 @@ WebGLContext::TexSubImage2D_imageData(We
                               -1,
                               WebGLTexelFormat::RGBA8, false);
 }
 
 NS_IMETHODIMP
 WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
                                 WebGLint xoffset, WebGLint yoffset,
                                 WebGLenum format, WebGLenum type,
-                                nsIDOMElement *elt)
+                                Element *elt)
 {
     if (!IsContextStable())
         return NS_OK;
 
     nsRefPtr<gfxImageSurface> isurf;
 
     int srcFormat;
     nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf), &srcFormat);
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -7586,67 +7586,67 @@ ok(!_thrown_outer, ctx.canvas.id + ' sho
 
 
 }
 </script>
 
 <!-- [[[ test_2d.imageData.create.type.html ]]] -->
 
 <p>Canvas test: 2d.imageData.create.type - bug 433004</p>
-<!-- Testing: createImageData() returns an ImageData object containing a CanvasPixelArray object -->
+<!-- Testing: createImageData() returns an ImageData object containing a Uint8ClampedArray object -->
 <canvas id="c261" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
 function test_2d_imageData_create_type() {
 
 var canvas = document.getElementById('c261');
 var ctx = canvas.getContext('2d');
 
 var _thrown_outer = false;
 try {
 
 todo(window.ImageData !== undefined, "window.ImageData !== undefined");
-todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
+ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
 window.ImageData.prototype.thisImplementsImageData = true;
-window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
+window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
 var imgdata = ctx.createImageData(1, 1);
 ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
-ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
+ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
 
 } catch (e) {
     _thrown_outer = true;
 }
 todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
 
 
 }
 </script>
 
 <!-- [[[ test_2d.imageData.create1.type.html ]]] -->
 
 <p>Canvas test: 2d.imageData.create1.type - bug 630040</p>
-<!-- Testing: createImageData(imgdata) returns an ImageData object containing a CanvasPixelArray object -->
+<!-- Testing: createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object -->
 <canvas id="c261a" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
 function test_2d_imageData_create1_type() {
 
 var canvas = document.getElementById('c261a');
 var ctx = canvas.getContext('2d');
 
 var _thrown_outer = false;
 try {
 
 todo(window.ImageData !== undefined, "window.ImageData !== undefined");
-todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
+ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
 window.ImageData.prototype.thisImplementsImageData = true;
-window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
+window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
 var imgdata = ctx.createImageData(ctx.createImageData(1, 1));
 todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
-todo(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
+ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
 
 } catch (e) {
     _thrown_outer = true;
 }
 todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
 
 
 }
@@ -8224,35 +8224,35 @@ ok(!_thrown_outer, ctx.canvas.id + ' sho
 
 
 }
 </script>
 
 <!-- [[[ test_2d.imageData.get.type.html ]]] -->
 
 <p>Canvas test: 2d.imageData.get.type</p>
-<!-- Testing: getImageData() returns an ImageData object containing a CanvasPixelArray object -->
+<!-- Testing: getImageData() returns an ImageData object containing a Uint8ClampedArray object -->
 <canvas id="c276" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
 function test_2d_imageData_get_type() {
 
 var canvas = document.getElementById('c276');
 var ctx = canvas.getContext('2d');
 
 var _thrown_outer = false;
 try {
 
 todo(window.ImageData !== undefined, "window.ImageData !== undefined");
-todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
+ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
 window.ImageData.prototype.thisImplementsImageData = true;
-window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
+window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
 var imgdata = ctx.getImageData(0, 0, 1, 1);
 ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
-ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
+ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
 
 } catch (e) {
     _thrown_outer = true;
 }
 todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
 
 
 }
--- a/content/events/crashtests/crashtests.list
+++ b/content/events/crashtests/crashtests.list
@@ -1,10 +1,11 @@
 load 104310-1.html
 load 116206-1.html
 load 135345-1.html
 load 422009-1.xhtml
 load 457776-1.html
 load 496308-1.html
 load 682637-1.html
 load eventctor-nulldictionary.html
+load eventctor-nullstorage.html
 load recursive-onload.html
 load recursive-DOMNodeInserted.html
new file mode 100644
--- /dev/null
+++ b/content/events/crashtests/eventctor-nullstorage.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<script>
+new StorageEvent("").storageArea;
+</script>
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -45,16 +45,17 @@
 #include "nsIHttpChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMRange.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsILoadGroup.h"
 #include "nsIObserver.h"
 #include "nsAudioStream.h"
 #include "VideoFrameContainer.h"
+#include "mozilla/CORSMode.h"
 
 // Define to output information on decoding and painting framerate
 /* #define DEBUG_FRAME_RATE 1 */
 
 typedef PRUint16 nsMediaNetworkState;
 typedef PRUint16 nsMediaReadyState;
 
 class nsHTMLMediaElement : public nsGenericHTMLElement,
@@ -66,17 +67,17 @@ public:
   typedef mozilla::VideoFrameContainer VideoFrameContainer;
 
   enum CanPlayStatus {
     CANPLAY_NO,
     CANPLAY_MAYBE,
     CANPLAY_YES
   };
 
-  CORSMode GetCORSMode() {
+  mozilla::CORSMode GetCORSMode() {
     return mCORSMode;
   }
 
   nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLMediaElement();
 
   /**
    * This is used when the browser is constructing a video element to play
@@ -776,12 +777,12 @@ protected:
   // load when the user initiates either playback or an explicit load is
   // stored in mPreloadURI.
   bool mLoadIsSuspended;
 
   // True if a same-origin check has been done for the media element and resource.
   bool mMediaSecurityVerified;
 
   // The CORS mode when loading the media element
-  CORSMode mCORSMode;
+  mozilla::CORSMode mCORSMode;
 };
 
 #endif
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2483,34 +2483,35 @@ nsGenericHTMLElement::GetContentEditable
   }
 
   return NS_OK;
 }
 
 nsresult
 nsGenericHTMLElement::SetContentEditable(const nsAString& aContentEditable)
 {
-  nsString contentEditable;
-  ToLowerCase(aContentEditable, contentEditable);
-
-  if (contentEditable.EqualsLiteral("inherit")) {
+  if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "inherit")) {
     UnsetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, true);
 
     return NS_OK;
   }
 
-  if (!contentEditable.EqualsLiteral("true") &&
-      !contentEditable.EqualsLiteral("false")) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
+  if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "true")) {
+    SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("true"), true);
+    
+    return NS_OK;
   }
-
-  SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, contentEditable,
-          true);
-
-  return NS_OK;
+  
+  if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "false")) {
+    SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("false"), true);
+
+    return NS_OK;
+  }
+
+  return NS_ERROR_DOM_SYNTAX_ERR;
 }
 
 nsresult
 nsGenericHTMLElement::GetIsContentEditable(bool* aContentEditable)
 {
   NS_ENSURE_ARG_POINTER(aContentEditable);
 
   for (nsIContent* node = this; node; node = node->GetParent()) {
@@ -2881,24 +2882,16 @@ nsGenericHTMLFormElement::PreHandleEvent
         break;
       }
     }
   }
 
   return nsGenericHTMLElement::PreHandleEvent(aVisitor);
 }
 
-const nsAttrValue::EnumTable nsGenericHTMLElement::kCORSAttributeTable[] = {
-  // Order matters here
-  // See ParseAttribute in nsHTMLImageElement or nsHTMLMediaElement
-  { "anonymous",       nsGenericHTMLElement::CORS_ANONYMOUS       },
-  { "use-credentials", nsGenericHTMLElement::CORS_USE_CREDENTIALS },
-  { 0 }
-};
-
 /* virtual */
 bool
 nsGenericHTMLFormElement::IsDisabled() const
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
          (mFieldSet && mFieldSet->IsDisabled());
 }
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -525,50 +525,24 @@ public:
    * @param aResult    result value [out]
    */
   NS_HIDDEN_(nsresult) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult);
 
   /**
    * Returns the current disabled state of the element.
    */
   virtual bool IsDisabled() const {
-    return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+    return false;
   }
 
   bool IsHidden() const
   {
     return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
   }
 
-  /**
-   * Shared cross-origin resource sharing attributes so they don't get
-   * duplicated on every CORS-enabled element
-   */
-
-  enum CORSMode {
-    /**
-     * The default of not using CORS to validate cross-origin loads.
-     */
-    CORS_NONE,
-
-    /**
-     * Validate cross-site loads using CORS, but do not send any credentials
-     * (cookies, HTTP auth logins, etc) along with the request.
-     */
-    CORS_ANONYMOUS,
-
-    /**
-     * Validate cross-site loads using CORS, and send credentials such as cookies
-     * and HTTP auth logins along with the request.
-     */
-    CORS_USE_CREDENTIALS
-  };
-
-  const static nsAttrValue::EnumTable kCORSAttributeTable[];
-
 protected:
   /**
    * Add/remove this element to the documents name cache
    */
   void AddToNameTable(nsIAtom* aName) {
     NS_ASSERTION(HasName(), "Node doesn't have name?");
     nsIDocument* doc = GetCurrentDoc();
     if (doc && !IsInAnonymousSubtree()) {
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -358,20 +358,18 @@ nsHTMLImageElement::ParseAttribute(PRInt
                                    const nsAString& aValue,
                                    nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::align) {
       return ParseAlignValue(aValue, aResult);
     }
     if (aAttribute == nsGkAtoms::crossorigin) {
-      return aResult.ParseEnumValue(aValue, nsGenericHTMLElement::kCORSAttributeTable, false,
-                                    // default value is anonymous if aValue is
-                                    // not a value we understand
-                                    &nsGenericHTMLElement::kCORSAttributeTable[0]);
+      ParseCORSValue(aValue, aResult);
+      return true;
     }
     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return true;
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
@@ -657,22 +655,13 @@ nsresult
 nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const
 {
   if (aDest->OwnerDoc()->IsStaticDocument()) {
     CreateStaticImageClone(static_cast<nsHTMLImageElement*>(aDest));
   }
   return nsGenericHTMLElement::CopyInnerTo(aDest);
 }
 
-nsGenericHTMLElement::CORSMode
+CORSMode
 nsHTMLImageElement::GetCORSMode()
 {
-  nsGenericHTMLElement::CORSMode ret = nsGenericHTMLElement::CORS_NONE;
-
-  const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
-  if (value) {
-    NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
-                 "Why is this not an enum value?");
-    ret = nsGenericHTMLElement::CORSMode(value->GetEnumValue());
-  }
-
-  return ret;
+  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 }
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -431,17 +431,19 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsA
     if (aTitle.IsEmpty()) { // alternates must have title
       return;
     } else {
       *aIsAlternate = true;
     }
   }
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
-  ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
+  // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
+  // that media queries should be ASCII lowercased during serialization.
+  nsContentUtils::ASCIIToLower(aMedia);
 
   nsAutoString mimeType;
   nsAutoString notUsed;
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
   nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
   if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
     return;
   }
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -946,24 +946,17 @@ nsresult nsHTMLMediaElement::LoadResourc
   }
 
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
     mChannel = nsnull;
   }
 
   // Set the media element's CORS mode only when loading a resource
-  // By default, it's CORS_NONE
-  mCORSMode = CORS_NONE;
-  const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
-  if (value) {
-    NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
-                 "Why is this not an enum value?");
-    mCORSMode = CORSMode(value->GetEnumValue());
-  }
+  mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
   nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other) {
     // Clone it.
     nsresult rv = InitializeDecoderAsClone(other->mDecoder);
     if (NS_SUCCEEDED(rv))
       return rv;
   }
@@ -1599,20 +1592,18 @@ bool nsHTMLMediaElement::ParseAttribute(
     { 0 }
   };
 
   if (aNamespaceID == kNameSpaceID_None) {
     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return true;
     }
     if (aAttribute == nsGkAtoms::crossorigin) {
-      return aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
-                                    // default value is anonymous if aValue is
-                                    // not a value we understand
-                                    &kCORSAttributeTable[0]);
+      ParseCORSValue(aValue, aResult);
+      return true;
     }
     if (aAttribute == nsGkAtoms::preload) {
       return aResult.ParseEnumValue(aValue, kPreloadTable, false);
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
--- a/content/html/content/src/nsHTMLOptGroupElement.cpp
+++ b/content/html/content/src/nsHTMLOptGroupElement.cpp
@@ -80,16 +80,20 @@ public:
   // nsIContent
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   virtual nsEventStates IntrinsicState() const;
  
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual bool IsDisabled() const {
+    return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+  }
 protected:
 
   /**
    * Get the select content element that contains this option
    * @param aSelectElement the select element [OUT]
    */
   nsIContent* GetSelect();
 };
--- a/content/html/content/src/nsHTMLOptionElement.h
+++ b/content/html/content/src/nsHTMLOptionElement.h
@@ -99,16 +99,20 @@ public:
   // nsIContent
   virtual nsEventStates IntrinsicState() const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   nsresult CopyInnerTo(nsGenericElement* aDest) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual bool IsDisabled() const {
+    return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+  }
 protected:
   /**
    * Get the select content element that contains this option, this
    * intentionally does not return nsresult, all we care about is if
    * there's a select associated with this option or not.
    */
   nsHTMLSelectElement* GetSelect();
 
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -52,16 +52,17 @@
 #include "nsIXPConnect.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMDocument.h"
 #include "nsContentErrors.h"
 #include "nsIArray.h"
 #include "nsTArray.h"
 #include "nsDOMJSUtils.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLScriptElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLScriptElement,
                             public nsScriptElement
 {
 public:
   using nsGenericElement::GetText;
@@ -103,21 +104,26 @@ public:
   // nsIDOMHTMLScriptElement
   NS_DECL_NSIDOMHTMLSCRIPTELEMENT
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual void FreezeUriAsyncDefer();
+  virtual CORSMode GetCORSMode() const;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
+  virtual bool ParseAttribute(PRInt32 aNamespaceID,
+                              nsIAtom* aAttribute,
+                              const nsAString& aValue,
+                              nsAttrValue& aResult);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsGenericElement
   virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify);
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -173,16 +179,32 @@ nsHTMLScriptElement::BindToTree(nsIDocum
 
   if (aDocument) {
     MaybeProcessScript();
   }
 
   return NS_OK;
 }
 
+bool
+nsHTMLScriptElement::ParseAttribute(PRInt32 aNamespaceID,
+                                    nsIAtom* aAttribute,
+                                    const nsAString& aValue,
+                                    nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None &&
+      aAttribute == nsGkAtoms::crossorigin) {
+    ParseCORSValue(aValue, aResult);
+    return true;
+  }
+
+  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
+                                              aResult);
+}
+
 nsresult
 nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsHTMLScriptElement* it =
     new nsHTMLScriptElement(ni.forget(), NOT_FROM_PARSER);
@@ -306,14 +328,20 @@ nsHTMLScriptElement::FreezeUriAsyncDefer
 
     mDefer = !async && defer;
     mAsync = async;
   }
   
   mFrozen = true;
 }
 
+CORSMode
+nsHTMLScriptElement::GetCORSMode() const
+{
+  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
+}
+
 bool
 nsHTMLScriptElement::HasScriptContent()
 {
   return (mFrozen ? mExternal : HasAttr(kNameSpaceID_None, nsGkAtoms::src)) ||
          nsContentUtils::HasNonEmptyTextContent(this);
 }
--- a/content/html/content/src/nsHTMLStyleElement.cpp
+++ b/content/html/content/src/nsHTMLStyleElement.cpp
@@ -335,17 +335,19 @@ nsHTMLStyleElement::GetStyleSheetInfo(ns
   *aIsAlternate = false;
 
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
   aTitle.Assign(title);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
-  ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
+  // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
+  // that media queries should be ASCII lowercased during serialization.
+  nsContentUtils::ASCIIToLower(aMedia);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
 
   nsAutoString mimeType;
   nsAutoString notUsed;
   nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
   if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
     return;
--- a/content/html/content/test/test_bug353415-1.html
+++ b/content/html/content/test/test_bug353415-1.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>Test</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
 </head>
 <body>
-<iframe name="submit_frame" onLoad="doCheck();"></iframe>
+<iframe name="submit_frame"></iframe>
 <form method="get" id="form1" target="submit_frame" action="../../../../../blah">
 <input type="text" name="field1" value="teststring"><br>
 <input type="radio" name="field2" value="0" checked> 0
 <input type="radio" name="field3" value="1"> 1<br>
 <input type="checkbox" name="field4" value="1" checked> 1
 <input type="checkbox" name="field5" value="2"> 2
 <input type="checkbox" name="field6" value="3" checked> 3
 <select name="field7">
@@ -22,18 +22,21 @@
 <input name="field8" value="8">
 <input name="field9" value="9">
 <input type="image" name="field10">
 <label name="field11">
 <input name="field12">
 <input type="button" name="field13" value="button">
 </form>
 <script>
-	document.forms[0].submit();
+  SimpleTest.waitForExplicitFinish();
 
-	SimpleTest.waitForExplicitFinish();
-        function doCheck(){
-		is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=", "Submit string was correct.");
-                SimpleTest.finish();
-	}
+  addLoadEvent(function() {
+    document.getElementsByName('submit_frame')[0].onload = function() {
+      is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=", "Submit string was correct.");
+      SimpleTest.finish();
+    };
+
+    document.forms[0].submit();
+  });
 </script>
 </body>
 </html>
--- a/content/html/content/test/test_bug353415-2.html
+++ b/content/html/content/test/test_bug353415-2.html
@@ -49,17 +49,19 @@
 <input type="button" name="field13-2" value="button">
 <input type="hidden" name="field14-2" value="14">
 </tr>
 </table>
 </form>
 <script>
   SimpleTest.waitForExplicitFinish();
 
-  frames['submit_frame'].onload = function() {
-    is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1-2=teststring&field2-2=0&field4-2=1&field6-2=3&field7-2=2&field8-2=8&field9-2=9&field12-2=&field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=&field14=14&field14-2=14", "Submit string was correct.");
-    SimpleTest.finish();
-  }
+  addLoadEvent(function() {
+    document.getElementsByName('submit_frame')[0].onload = function() {
+      is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1-2=teststring&field2-2=0&field4-2=1&field6-2=3&field7-2=2&field8-2=8&field9-2=9&field12-2=&field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=&field14=14&field14-2=14", "Submit string was correct.");
+      SimpleTest.finish();
+    };
 
-  document.forms[0].submit();
+    document.forms[0].submit();
+  });
 </script>
 </body>
 </html>
--- a/content/html/content/test/test_bug430351.html
+++ b/content/html/content/test/test_bug430351.html
@@ -56,16 +56,17 @@ var focusableElements = [
     "<button type=\"submit\" tabindex=\"0\"></button>",
     "<button type=\"submit\" tabindex=\"1\"></button>",
     "<button type=\"submit\" contenteditable=\"true\"></button>",
 
     "<div tabindex=\"-1\"></div>",
     "<div tabindex=\"0\"></div>",
     "<div tabindex=\"1\"></div>",
     "<div contenteditable=\"true\"></div>",
+    "<div tabindex=\"0\" disabled></div>",
 
     "<embed>",
     "<embed tabindex=\"-1\">",
     "<embed tabindex=\"0\">",
     "<embed tabindex=\"0\" disabled>",
     "<embed tabindex=\"1\">",
     "<embed disabled>",
     "<embed contenteditable=\"true\">",
@@ -160,34 +161,43 @@ var focusableElements = [
     "<object classid=\"java:a\" tabindex=\"1\"></object>",
     "<object classid=\"java:a\" disabled></object>",
     "<object classid=\"java:a\" contenteditable=\"true\"></object>",
 
     "<select></select>",
     "<select tabindex=\"-1\"></select>",
     "<select tabindex=\"0\"></select>",
     "<select tabindex=\"1\"></select>",
-    "<select contenteditable=\"true\"></select>"
+    "<select contenteditable=\"true\"></select>",
+
+    "<option tabindex='-1'></option>",
+    "<option tabindex='0'></option>",
+    "<option tabindex='1'></option>",
+    "<option contenteditable></option>",
+
+    "<optgroup tabindex='-1'></optgroup>",
+    "<optgroup tabindex='0'></optgroup>",
+    "<optgroup tabindex='1'></optgroup>",
+    "<optgroup contenteditable></optgroup>"
 ];
 
 var nonFocusableElements = [
     "<a></a>",
     "<a disabled></a>",
 
     "<button tabindex=\"0\" disabled></button>",
     "<button disabled></button>",
 
     "<button type=\"reset\" tabindex=\"0\" disabled></button>",
     "<button type=\"reset\" disabled></button>",
 
     "<button type=\"submit\" tabindex=\"0\" disabled></button>",
     "<button type=\"submit\" disabled></button>",
 
     "<div></div>",
-    "<div tabindex=\"0\" disabled></div>",
     "<div disabled></div>",
 
     "<img>",
     "<img disabled>",
     "<img contenteditable=\"true\">",
 
     "<img usemap=\"#map\">",
     "<img usemap=\"#map\" tabindex=\"-1\">",
@@ -238,17 +248,23 @@ var nonFocusableElements = [
     "<input type=\"submit\" disabled>",
 
     "<input type=\"text\" tabindex=\"0\" disabled>",
     "<input type=\"text\" disabled>",
 
     "<object></object>",
 
     "<select tabindex=\"0\" disabled></select>",
-    "<select disabled></select>"
+    "<select disabled></select>",
+
+    "<option></option>",
+    "<option tabindex='1' disabled></option>",
+
+    "<optgroup></optgroup>",
+    "<optgroup tabindex='1' disabled></optgroup>"
 ];
 
 var focusableInContentEditable = [
     "<button></button>",
     "<button tabindex=\"-1\"></button>",
     "<button tabindex=\"0\"></button>",
     "<button tabindex=\"1\"></button>",
     "<button contenteditable=\"true\"></button>",
@@ -263,16 +279,17 @@ var focusableInContentEditable = [
     "<button type=\"submit\" tabindex=\"-1\"></button>",
     "<button type=\"submit\" tabindex=\"0\"></button>",
     "<button type=\"submit\" tabindex=\"1\"></button>",
     "<button type=\"submit\" contenteditable=\"true\"></button>",
 
     "<div tabindex=\"-1\"></div>",
     "<div tabindex=\"0\"></div>",
     "<div tabindex=\"1\"></div>",
+    "<div tabindex=\"0\" disabled></div>",
 
     "<embed>",
     "<embed tabindex=\"-1\">",
     "<embed tabindex=\"0\">",
     "<embed tabindex=\"0\" disabled>",
     "<embed tabindex=\"1\">",
     "<embed disabled>",
     "<embed contenteditable=\"true\">",
@@ -360,17 +377,25 @@ var focusableInContentEditable = [
     // Disabled doesn't work for <object>.
     "<object tabindex=\"0\" disabled></object>",
     "<object disabled></object>",
 
     "<select></select>",
     "<select tabindex=\"-1\"></select>",
     "<select tabindex=\"0\"></select>",
     "<select tabindex=\"1\"></select>",
-    "<select contenteditable=\"true\"></select>"
+    "<select contenteditable=\"true\"></select>",
+
+    "<option tabindex='-1'></option>",
+    "<option tabindex='0'></option>",
+    "<option tabindex='1'></option>",
+
+    "<optgroup tabindex='-1'></optgroup>",
+    "<optgroup tabindex='0'></optgroup>",
+    "<optgroup tabindex='1'></optgroup>"
 ];
 
 var focusableInDesignMode = [
     "<embed>",
     "<embed tabindex=\"-1\">",
     "<embed tabindex=\"0\">",
     "<embed tabindex=\"0\" disabled>",
     "<embed tabindex=\"1\">",
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1353,17 +1353,17 @@ nsHTMLDocument::Open(const nsAString& aC
     // No calling document.open() on XHTML
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   nsCAutoString contentType;
   contentType.AssignLiteral("text/html");
   if (aOptionalArgCount > 0) {
     nsAutoString type;
-    ToLowerCase(aContentTypeOrUrl, type);
+    nsContentUtils::ASCIIToLower(aContentTypeOrUrl, type);
     nsCAutoString actualType, dummy;
     NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy);
     if (!actualType.EqualsLiteral("text/html") &&
         !type.EqualsLiteral("replace")) {
       contentType.AssignLiteral("text/plain");
     }
   }
 
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -139,22 +139,22 @@ nsSVGFE::SetupScalingFilter(nsSVGFilterI
   result.mRescaling = aKernelUnitLength->IsExplicitlySet();
   if (!result.mRescaling) {
     result.mSource = aSource->mImage;
     result.mTarget = aTarget->mImage;
     result.mDataRect = aDataRect;
     return result;
   }
 
-  float kernelX = aInstance->GetPrimitiveNumber(nsSVGUtils::X,
-                                                aKernelUnitLength,
-                                                nsSVGNumberPair::eFirst);
-  float kernelY = aInstance->GetPrimitiveNumber(nsSVGUtils::Y,
-                                                aKernelUnitLength,
-                                                nsSVGNumberPair::eSecond);
+  gfxFloat kernelX = aInstance->GetPrimitiveNumber(nsSVGUtils::X,
+                                                   aKernelUnitLength,
+                                                   nsSVGNumberPair::eFirst);
+  gfxFloat kernelY = aInstance->GetPrimitiveNumber(nsSVGUtils::Y,
+                                                   aKernelUnitLength,
+                                                   nsSVGNumberPair::eSecond);
   if (kernelX <= 0 || kernelY <= 0)
     return result;
 
   bool overflow = false;
   gfxIntSize scaledSize =
     nsSVGUtils::ConvertToSurfaceSize(gfxSize(aTarget->mImage->Width() / kernelX,
                                              aTarget->mImage->Height() / kernelY),
                                      &overflow);
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -81,26 +81,31 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsSVGScriptElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGScriptElementBase::)
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual void FreezeUriAsyncDefer();
+  virtual CORSMode GetCORSMode() const;
   
   // nsScriptElement
   virtual bool HasScriptContent();
 
   // nsIContent specializations:
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify);
+  virtual bool ParseAttribute(PRInt32 aNamespaceID,
+                              nsIAtom* aAttribute,
+                              const nsAString& aValue,
+                              nsAttrValue& aResult);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   virtual StringAttributesInfo GetStringInfo();
 
   enum { HREF };
@@ -283,8 +288,31 @@ nsSVGScriptElement::AfterSetAttr(PRInt32
                                  const nsAttrValue* aValue, bool aNotify)
 {
   if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
     MaybeProcessScript();
   }
   return nsSVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
                                               aValue, aNotify);
 }
+
+bool
+nsSVGScriptElement::ParseAttribute(PRInt32 aNamespaceID,
+                                   nsIAtom* aAttribute,
+                                   const nsAString& aValue,
+                                   nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None &&
+      aAttribute == nsGkAtoms::crossorigin) {
+    ParseCORSValue(aValue, aResult);
+    return true;
+  }
+
+  return nsSVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute,
+                                                aValue, aResult);
+}
+
+CORSMode
+nsSVGScriptElement::GetCORSMode() const
+{
+  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
+}
+
--- a/content/svg/content/src/nsSVGStyleElement.cpp
+++ b/content/svg/content/src/nsSVGStyleElement.cpp
@@ -332,19 +332,19 @@ nsSVGStyleElement::GetStyleSheetInfo(nsA
   *aIsAlternate = false;
 
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
   aTitle.Assign(title);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
-  // SVG spec refers to the HTML4.0 spec which is inconsistent, make it
-  // case INSENSITIVE
-  ToLowerCase(aMedia);
+  // The SVG spec is formulated in terms of the CSS2 spec,
+  // which specifies that media queries are case insensitive.
+  nsContentUtils::ASCIIToLower(aMedia);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
   if (aType.IsEmpty()) {
     aType.AssignLiteral("text/css");
   }
 
   return;
 }
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -927,31 +927,28 @@ nsXBLPrototypeHandler::ConstructPrototyp
       if (key.IsEmpty()) 
         aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::charcode, key);
     }
   }
 
   if (!key.IsEmpty()) {
     if (mKeyMask == 0)
       mKeyMask = cAllModifiers;
-    ToLowerCase(key);
+    nsContentUtils::ASCIIToLower(key);
 
     // We have a charcode.
     mMisc = 1;
     mDetail = key[0];
     const PRUint8 GTK2Modifiers = cShift | cControl | cShiftMask | cControlMask;
     if ((mKeyMask & GTK2Modifiers) == GTK2Modifiers &&
-        modifiers.First() != PRUnichar(',') &&
-        (mDetail == 'u' || mDetail == 'U'))
+        modifiers.First() != PRUnichar(',') && mDetail == 'u')
       ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "GTK2Conflict");
     const PRUint8 WinModifiers = cControl | cAlt | cControlMask | cAltMask;
     if ((mKeyMask & WinModifiers) == WinModifiers &&
-        modifiers.First() != PRUnichar(',') &&
-        (('A' <= mDetail && mDetail <= 'Z') ||
-         ('a' <= mDetail && mDetail <= 'z')))
+        modifiers.First() != PRUnichar(',') && ('a' <= mDetail && mDetail <= 'z'))
       ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "WinConflict");
   }
   else {
     key.Assign(aKeyCode);
     if (mType & NS_HANDLER_TYPE_XUL)
       aKeyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, key);
     
     if (!key.IsEmpty()) {
--- a/content/xslt/src/base/txStringUtils.h
+++ b/content/xslt/src/base/txStringUtils.h
@@ -39,31 +39,29 @@
 
 #ifndef txStringUtils_h__
 #define txStringUtils_h__
 
 #include "nsAString.h"
 #include "nsIAtom.h"
 #include "nsUnicharUtils.h"
 
-#define TX_ToLowerCase ToLowerCase
-
 typedef nsCaseInsensitiveStringComparator txCaseInsensitiveStringComparator;
 
 /**
  * Check equality between a string and an atom containing ASCII.
  */
 inline bool
 TX_StringEqualsAtom(const nsASingleFragmentString& aString, nsIAtom* aAtom)
 {
   return aAtom->Equals(aString);
 }
 
 inline already_AddRefed<nsIAtom>
 TX_ToLowerCaseAtom(nsIAtom* aAtom)
 {
   nsAutoString str;
   aAtom->ToString(str);
-  TX_ToLowerCase(str);
+  nsContentUtils::ASCIIToLower(str);
   return do_GetAtom(str);
 }
 
 #endif // txStringUtils_h__
--- a/content/xslt/src/xpath/txExprParser.cpp
+++ b/content/xslt/src/xpath/txExprParser.cpp
@@ -933,17 +933,17 @@ txExprParser::resolveQName(const nsAStri
             return NS_ERROR_OUT_OF_MEMORY;
         }
         return aContext->resolveNamespacePrefix(*aPrefix, aNamespace);
     }
     // the lexer dealt with idx == 0
     *aPrefix = 0;
     if (aIsNameTest && aContext->caseInsensitiveNameTests()) {
         nsAutoString lcname;
-        TX_ToLowerCase(aQName, lcname);
+        nsContentUtils::ASCIIToLower(aQName, lcname);
         *aLocalName = NS_NewAtom(lcname);
     }
     else {
         *aLocalName = NS_NewAtom(aQName);
     }
     if (!*aLocalName) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -448,17 +448,17 @@ txXPathNodeUtils::getLocalName(const txX
     }
 
     aNode.Content()->GetAttrNameAt(aNode.mIndex)->LocalName()->
       ToString(aLocalName);
 
     // Check for html
     if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) &&
         aNode.Content()->IsHTML()) {
-        ToUpperCase(aLocalName);
+        nsContentUtils::ASCIIToUpper(aLocalName);
     }
 }
 
 /* static */
 void
 txXPathNodeUtils::getNodeName(const txXPathNode& aNode, nsAString& aName)
 {
     if (aNode.isDocument()) {
--- a/content/xslt/src/xpath/txResultRecycler.cpp
+++ b/content/xslt/src/xpath/txResultRecycler.cpp
@@ -224,33 +224,16 @@ txResultRecycler::getNodeSet(const txXPa
         *aResult = nodes;
     }
     NS_ADDREF(*aResult);
 
     return NS_OK;
 }
 
 nsresult
-txResultRecycler::getNodeSet(const txXPathNode& aNode, txNodeSet** aResult)
-{
-    if (mNodeSetResults.isEmpty()) {
-        *aResult = new txNodeSet(aNode, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
-        (*aResult)->append(aNode);
-        (*aResult)->mRecycler = this;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
-}
-
-nsresult
 txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult)
 {
     if (mNumberResults.isEmpty()) {
         *aResult = new NumberResult(aValue, this);
         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
     }
     else {
         NumberResult* numRes =
--- a/content/xslt/src/xpath/txResultRecycler.h
+++ b/content/xslt/src/xpath/txResultRecycler.h
@@ -81,17 +81,16 @@ public:
      * Functions to return results that will be fully used by the caller.
      * Returns nsnull on out-of-memory and an inited result otherwise.
      */
     nsresult getStringResult(StringResult** aResult);
     nsresult getStringResult(const nsAString& aValue, txAExprResult** aResult);
     nsresult getNodeSet(txNodeSet** aResult);
     nsresult getNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult);
     nsresult getNodeSet(const txXPathNode& aNode, txAExprResult** aResult);
-    nsresult getNodeSet(const txXPathNode& aNode, txNodeSet** aResult);
     nsresult getNumberResult(double aValue, txAExprResult** aResult);
 
     /**
      * Functions to return a txAExprResult that is shared across several
      * clients and must not be modified. Never returns nsnull.
      */
     void getEmptyStringResult(txAExprResult** aResult);
     void getBoolResult(bool aValue, txAExprResult** aResult);
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -155,17 +155,17 @@ txMozillaXMLOutput::attribute(nsIAtom* a
                               const nsSubstring& aLocalName,
                               const PRInt32 aNsID,
                               const nsString& aValue)
 {
     nsCOMPtr<nsIAtom> lname;
 
     if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
         nsAutoString lnameStr;
-        ToLowerCase(aLocalName, lnameStr);
+        nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
         lname = do_GetAtom(lnameStr);
     }
     else {
         lname = do_GetAtom(aLocalName);
     }
 
     NS_ENSURE_TRUE(lname, NS_ERROR_OUT_OF_MEMORY);
 
@@ -494,17 +494,17 @@ txMozillaXMLOutput::startElement(nsIAtom
 {
     PRInt32 nsId = aNsID;
     nsCOMPtr<nsIAtom> lname;
 
     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
         nsId = kNameSpaceID_XHTML;
 
         nsAutoString lnameStr;
-        ToLowerCase(aLocalName, lnameStr);
+        nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
         lname = do_GetAtom(lnameStr);
     }
     else {
         lname = do_GetAtom(aLocalName);
     }
 
     // No biggie if we lose the prefix due to OOM
     NS_ENSURE_TRUE(lname, NS_ERROR_OUT_OF_MEMORY);
@@ -797,17 +797,17 @@ txMozillaXMLOutput::endHTMLElement(nsICo
     else if (mCreatingNewDocument && atom == nsGkAtoms::meta) {
         // handle HTTP-EQUIV data
         nsAutoString httpEquiv;
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, httpEquiv);
         if (!httpEquiv.IsEmpty()) {
             nsAutoString value;
             aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
             if (!value.IsEmpty()) {
-                ToLowerCase(httpEquiv);
+                nsContentUtils::ASCIIToLower(httpEquiv);
                 nsCOMPtr<nsIAtom> header = do_GetAtom(httpEquiv);
                 processHTTPEquiv(header, value);
             }
         }
     }
     
     return NS_OK;
 }
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -783,21 +783,17 @@ void
 nsXULPDGlobalObject::ClearGlobalObjectOwner()
 {
   NS_ASSERTION(!mCachedPrincipal, "This shouldn't ever be set until now!");
 
   // Cache mGlobalObjectOwner's principal if possible.
   if (this != nsXULPrototypeDocument::gSystemGlobal)
     mCachedPrincipal = mGlobalObjectOwner->DocumentPrincipal();
 
-  if (mContext) {
-    mContext->FinalizeContext();
-    mContext = NULL;
-  }
-
+  mContext = NULL;
   mGlobalObjectOwner = NULL;
 }
 
 
 void
 nsXULPDGlobalObject::OnFinalize(JSObject* aObject)
 {
   mJSObject = NULL;
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -49,16 +49,17 @@
 
 #ifdef MOZ_TOOLKIT_SEARCH
 #include "nsIBrowserSearchService.h"
 #endif
 
 #include "nsIURIFixup.h"
 #include "nsDefaultURIFixup.h"
 #include "mozilla/Preferences.h"
+#include "nsIObserverService.h"
 
 using namespace mozilla;
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup)
 
 nsDefaultURIFixup::nsDefaultURIFixup()
 {
@@ -373,17 +374,27 @@ NS_IMETHODIMP nsDefaultURIFixup::Keyword
         // Escape keyword, then prepend URL
         nsCAutoString spec;
         if (!NS_Escape(keyword, spec, url_XPAlphas)) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
 
         spec.Insert(url, 0);
 
-        return NS_NewURI(aURI, spec);
+        nsresult rv = NS_NewURI(aURI, spec);
+        if (NS_FAILED(rv))
+            return rv;
+
+        nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+        if (obsSvc) {
+            obsSvc->NotifyObservers(*aURI,
+                                    "defaultURIFixup-using-keyword-pref",
+                                    nsnull);
+        }
+        return NS_OK;
     }
 
 #ifdef MOZ_TOOLKIT_SEARCH
     // Try falling back to the search service's default search engine
     nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
     if (searchSvc) {
         nsCOMPtr<nsISearchEngine> defaultEngine;
         searchSvc->GetOriginalDefaultEngine(getter_AddRefs(defaultEngine));
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -447,17 +447,16 @@
 #include "nsIDOMGeoPositionError.h"
 
 // Workers
 #include "mozilla/dom/workers/Workers.h"
 
 #include "nsDOMFile.h"
 #include "nsDOMFileReader.h"
 #include "nsIDOMFileException.h"
-#include "nsIDOMFileError.h"
 #include "nsIDOMFormData.h"
 
 #include "nsIDOMDOMStringMap.h"
 
 #include "nsIDOMDesktopNotification.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "Navigator.h"
@@ -1389,18 +1388,16 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(FileList, nsFileListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(Blob, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(FileError, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(FileReader, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozBlobBuilder, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DOMStringMap, nsDOMStringMapSH,
@@ -3959,20 +3956,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(ClientRectList, nsIDOMClientRectList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientRectList)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(FileList, nsIDOMFileList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileList)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(FileError, nsIDOMFileError)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileError)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(File, nsIDOMFile)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -397,17 +397,16 @@ DOMCI_CLASS(SVGForeignObjectElement)
 DOMCI_CLASS(XULCommandEvent)
 DOMCI_CLASS(CommandEvent)
 DOMCI_CLASS(OfflineResourceList)
 
 DOMCI_CLASS(FileList)
 DOMCI_CLASS(Blob)
 DOMCI_CLASS(File)
 DOMCI_CLASS(FileException)
-DOMCI_CLASS(FileError)
 DOMCI_CLASS(FileReader)
 DOMCI_CLASS(MozURLProperty)
 DOMCI_CLASS(MozBlobBuilder)
 
 DOMCI_CLASS(DOMStringMap)
 
 // DOM modal content window class, almost identical to Window
 DOMCI_CLASS(ModalContentWindow)
--- a/dom/base/nsDOMJSUtils.h
+++ b/dom/base/nsDOMJSUtils.h
@@ -1,15 +1,17 @@
 
 #ifndef nsDOMJSUtils_h__
 #define nsDOMJSUtils_h__
 
 #include "jsapi.h"
 #include "nsIScriptContext.h"
 
+class nsIJSArgArray;
+
 // seems like overkill for just this 1 function - but let's see what else
 // falls out first.
 inline nsIScriptContext *
 GetScriptContextFromJSContext(JSContext *cx)
 {
   if (!(::JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS)) {
     return nsnull;
   }
@@ -45,11 +47,11 @@ GetScriptContextPrincipalFromJSContext(J
 // jsval* and the args are found at:
 //    ((jsval*)aArgv)[0], ..., ((jsval*)aArgv)[aArgc - 1]
 // The resulting object will take a copy of the array, and ensure each
 // element is rooted.
 // Optionally, aArgv may be NULL, in which case the array is allocated and
 // rooted, but all items remain NULL.  This presumably means the caller will
 // then QI us for nsIJSArgArray, and set our array elements.
 nsresult NS_CreateJSArgv(JSContext *aContext, PRUint32 aArgc, void *aArgv,
-                         nsIArray **aArray);
+                         nsIJSArgArray **aArray);
 
 #endif // nsDOMJSUtils_h__
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2397,17 +2397,16 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
       // SetArguments(), drop our reference to the arguments.
       mArguments = nsnull;
       mArgumentsLast = nsnull;
       mArgumentsOrigin = nsnull;
     }
 
     if (mContext) {
       mContext->GC(js::gcreason::SET_DOC_SHELL);
-      mContext->FinalizeContext();
       mContext = nsnull;
     }
 
 #ifdef DEBUG
     nsCycleCollector_DEBUG_shouldBeFreed(mContext);
     nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
 #endif
   }
@@ -5927,17 +5926,17 @@ nsGlobalWindow::OpenDialog(const nsAStri
   jsval *argv = nsnull;
 
   // XXX - need to get this as nsISupports?
   ncc->GetArgc(&argc);
   ncc->GetArgvPtr(&argv);
 
   // Strip the url, name and options from the args seen by scripts.
   PRUint32 argOffset = argc < 3 ? argc : 3;
-  nsCOMPtr<nsIArray> argvArray;
+  nsCOMPtr<nsIJSArgArray> argvArray;
   rv = NS_CreateJSArgv(cx, argc - argOffset, argv + argOffset,
                        getter_AddRefs(argvArray));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return OpenInternal(aUrl, aName, aOptions,
                       true,             // aDialog
                       false,            // aContentModal
                       false,            // aCalledNoScript
@@ -6527,65 +6526,50 @@ nsGlobalWindow::ForceClose()
   DispatchCustomEvent("DOMWindowClose");
 
   return FinalClose();
 }
 
 nsresult
 nsGlobalWindow::FinalClose()
 {
-  nsresult rv;
   // Flag that we were closed.
   mIsClosed = true;
 
   nsCOMPtr<nsIJSContextStack> stack =
     do_GetService(sJSStackContractID);
 
   JSContext *cx = nsnull;
 
   if (stack) {
     stack->Peek(&cx);
   }
 
   if (cx) {
     nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx);
 
     if (currentCX && currentCX == GetContextInternal()) {
-      // We ignore the return value here.  If setting the termination function
-      // fails, it's better to fail to close the window than it is to crash
-      // (which is what would tend to happen if we did this synchronously
-      // here).
-      rv = currentCX->SetTerminationFunction(CloseWindow,
-                                             static_cast<nsIDOMWindow *>
-                                                        (this));
-      if (NS_SUCCEEDED(rv)) {
-        mHavePendingClose = true;
-      }
+      currentCX->SetTerminationFunction(CloseWindow, this);
+      mHavePendingClose = true;
       return NS_OK;
     }
   }
 
-  
   // We may have plugins on the page that have issued this close from their
   // event loop and because we currently destroy the plugin window with
   // frames, we crash. So, if we are called from Javascript, post an event
   // to really close the window.
-  rv = NS_ERROR_FAILURE;
-  if (!nsContentUtils::IsCallerChrome()) {
-    rv = nsCloseEvent::PostCloseEvent(this);
-  }
-  
-  if (NS_FAILED(rv)) {
+  if (nsContentUtils::IsCallerChrome() ||
+      NS_FAILED(nsCloseEvent::PostCloseEvent(this))) {
     ReallyCloseWindow();
-    rv = NS_OK;
   } else {
     mHavePendingClose = true;
   }
-  
-  return rv;
+
+  return NS_OK;
 }
 
 
 void
 nsGlobalWindow::ReallyCloseWindow()
 {
   FORWARD_TO_OUTER_VOID(ReallyCloseWindow, ());
 
@@ -8862,18 +8846,17 @@ nsGlobalWindow::OpenInternal(const nsASt
         // If script in some other window is doing a window.open on us and
         // it's being blocked, then it's OK to close us afterwards, probably.
         // But if we're doing a window.open on ourselves and block the popup,
         // prevent this window from closing until after this script terminates
         // so that whatever popup blocker UI the app has will be visible.
         if (mContext == GetScriptContextFromJSContext(aJSCallerContext)) {
           mBlockScriptedClosingFlag = true;
           mContext->SetTerminationFunction(CloseBlockScriptTerminationFunc,
-                                           static_cast<nsPIDOMWindow*>
-                                                      (this));
+                                           this);
         }
       }
 
       FireAbuseEvents(true, false, aUrl, aName, aOptions);
       return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
     }
   }    
 
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -51,16 +51,17 @@ class nsIScriptSecurityManager;
 class nsIPrincipal;
 class nsIAtom;
 class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 template<class> class nsScriptObjectHolder;
 class nsIScriptObjectPrincipal;
+class nsIDOMWindow;
 
 typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
 
 #define NS_ISCRIPTCONTEXTPRINCIPAL_IID \
   { 0xd012cdb3, 0x8f1e, 0x4440, \
     { 0x8c, 0xbd, 0x32, 0x7f, 0x98, 0x1d, 0x37, 0xb4 } }
 
 class nsIScriptContextPrincipal : public nsISupports
@@ -70,18 +71,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x6d69fbee, 0x0723, 0x48f5, \
- { 0x82, 0x48, 0xcd, 0xcf, 0x88, 0xac, 0x25, 0x74 } }
+{ 0xdfaea249, 0xaaad, 0x48bd, \
+  { 0xb8, 0x04, 0x92, 0xad, 0x30, 0x88, 0xd0, 0xc6 } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -340,21 +341,16 @@ public:
    * reentrancy issues during the initialization process.
    *
    * @return true if initialized, false if not
    *
    */
   virtual bool IsContextInitialized() = 0;
 
   /**
-   * Called as the global object discards its reference to the context.
-   */
-  virtual void FinalizeContext() = 0;
-
-  /**
    * For garbage collected systems, do a synchronous collection pass.
    * May be a no-op on other systems
    *
    * @return NS_OK if the method is successful
    */
   virtual void GC(js::gcreason::Reason aReason) = 0;
 
   /**
@@ -384,28 +380,28 @@ public:
    * than JS (ie, this should be moved to a private interface!)
    * Called to specify a function that should be called when the current
    * script (if there is one) terminates. Generally used if breakdown
    * of script state needs to happen, but should be deferred till
    * the end of script evaluation.
    *
    * @throws NS_ERROR_OUT_OF_MEMORY if that happens
    */
-  virtual nsresult SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                          nsISupports* aRef) = 0;
+  virtual void SetTerminationFunction(nsScriptTerminationFunc aFunc,
+                                      nsIDOMWindow* aRef) = 0;
 
   /**
    * Called to disable/enable script execution in this context.
    */
   virtual bool GetScriptsEnabled() = 0;
   virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts) = 0;
 
   // SetProperty is suspect and jst believes should not be needed.  Currenly
   // used only for "arguments".
-  virtual nsresult SetProperty(void *aTarget, const char *aPropName, nsISupports *aVal) = 0;
+  virtual nsresult SetProperty(JSObject* aTarget, const char* aPropName, nsISupports* aVal) = 0;
   /** 
    * Called to set/get information if the script context is
    * currently processing a script tag
    */
   virtual bool GetProcessingScriptTag() = 0;
   virtual void SetProcessingScriptTag(bool aResult) = 0;
 
   /**
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2288,27 +2288,27 @@ nsJSContext::InitializeExternalClasses()
 {
   nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
   NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
 
   return nameSpaceManager->InitForContext(this);
 }
 
 nsresult
-nsJSContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aArgs)
+nsJSContext::SetProperty(JSObject* aTarget, const char* aPropName, nsISupports* aArgs)
 {
   PRUint32  argc;
   jsval    *argv = nsnull;
 
   JSAutoRequest ar(mContext);
 
   Maybe<nsRootedJSValueArray> tempStorage;
 
-  nsresult rv;
-  rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, &argv, tempStorage);
+  nsresult rv =
+    ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, &argv, tempStorage);
   NS_ENSURE_SUCCESS(rv, rv);
 
   jsval vargs;
 
   // got the arguments, now attach them.
 
   // window.dialogArguments is supposed to be an array if a JS array
   // was passed to showModalDialog(), deal with that here.
@@ -2322,21 +2322,19 @@ nsJSContext::SetProperty(void *aTarget, 
     }
 
     JSObject *args = ::JS_NewArrayObject(mContext, argc, argv);
     vargs = OBJECT_TO_JSVAL(args);
   }
 
   // Make sure to use JS_DefineProperty here so that we can override
   // readonly XPConnect properties here as well (read dialogArguments).
-  rv = ::JS_DefineProperty(mContext, reinterpret_cast<JSObject *>(aTarget),
-                           aPropName, vargs, nsnull, nsnull, 0) ?
-       NS_OK : NS_ERROR_FAILURE;
-
-  return rv;
+  return JS_DefineProperty(mContext, aTarget, aPropName, vargs, NULL, NULL, 0)
+    ? NS_OK
+    : NS_ERROR_FAILURE;
 }
 
 nsresult
 nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
                                      JSObject *aScope,
                                      PRUint32 *aArgc,
                                      jsval **aArgv,
                                      Maybe<nsRootedJSValueArray> &aTempStorage)
@@ -2355,17 +2353,17 @@ nsJSContext::ConvertSupportsTojsvals(nsI
   *aArgv = nsnull;
   *aArgc = 0;
 
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   NS_ENSURE_TRUE(xpc, NS_ERROR_UNEXPECTED);
 
   if (!aArgs)
     return NS_OK;
-  PRUint32 argCtr, argCount;
+  PRUint32 argCount;
   // This general purpose function may need to convert an arg array
   // (window.arguments, event-handler args) and a generic property.
   nsCOMPtr<nsIArray> argsArray(do_QueryInterface(aArgs));
 
   if (argsArray) {
     rv = argsArray->GetLength(&argCount);
     NS_ENSURE_SUCCESS(rv, rv);
     if (argCount == 0)
@@ -2376,17 +2374,17 @@ nsJSContext::ConvertSupportsTojsvals(nsI
 
   // Use the caller's auto guards to release and unroot.
   aTempStorage.construct(mContext);
   bool ok = aTempStorage.ref().SetCapacity(mContext, argCount);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   jsval *argv = aTempStorage.ref().Elements();
 
   if (argsArray) {
-    for (argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) {
+    for (PRUint32 argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) {
       nsCOMPtr<nsISupports> arg;
       jsval *thisval = argv + argCtr;
       argsArray->QueryElementAt(argCtr, NS_GET_IID(nsISupports),
                                 getter_AddRefs(arg));
       if (!arg) {
         *thisval = JSVAL_NULL;
         continue;
       }
@@ -2971,22 +2969,16 @@ nsJSContext::DidInitializeContext()
 
 bool
 nsJSContext::IsContextInitialized()
 {
   return mIsInitialized;
 }
 
 void
-nsJSContext::FinalizeContext()
-{
-  ;
-}
-
-void
 nsJSContext::ScriptEvaluated(bool aTerminated)
 {
   if (aTerminated && mTerminations) {
     // Make sure to null out mTerminations before doing anything that
     // might cause new termination funcs to be added!
     nsJSContext::TerminationFuncClosure* start = mTerminations;
     mTerminations = nsnull;
 
@@ -3001,30 +2993,25 @@ nsJSContext::ScriptEvaluated(bool aTermi
   JS_MaybeGC(mContext);
 
   if (aTerminated) {
     mOperationCallbackTime = 0;
     mModalStateTime = 0;
   }
 }
 
-nsresult
+void
 nsJSContext::SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                    nsISupports* aRef)
+                                    nsIDOMWindow* aRef)
 {
   NS_PRECONDITION(GetExecutingScript(), "should be executing script");
 
   nsJSContext::TerminationFuncClosure* newClosure =
     new nsJSContext::TerminationFuncClosure(aFunc, aRef, mTerminations);
-  if (!newClosure) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
   mTerminations = newClosure;
-  return NS_OK;
 }
 
 bool
 nsJSContext::GetScriptsEnabled()
 {
   return mScriptsEnabled;
 }
 
@@ -3917,17 +3904,17 @@ nsresult NS_CreateJSRuntime(nsIScriptRun
 }
 
 // A fast-array class for JS.  This class supports both nsIJSScriptArray and
 // nsIArray.  If it is JS itself providing and consuming this class, all work
 // can be done via nsIJSScriptArray, and avoid the conversion of elements
 // to/from nsISupports.
 // When consumed by non-JS (eg, another script language), conversion is done
 // on-the-fly.
-class nsJSArgArray : public nsIJSArgArray, public nsIArray {
+class nsJSArgArray : public nsIJSArgArray {
 public:
   nsJSArgArray(JSContext *aContext, PRUint32 argc, jsval *argv, nsresult *prv);
   ~nsJSArgArray();
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSArgArray,
                                                          nsIJSArgArray)
 
@@ -4057,17 +4044,17 @@ NS_IMETHODIMP nsJSArgArray::IndexOf(PRUi
 /* nsISimpleEnumerator enumerate (); */
 NS_IMETHODIMP nsJSArgArray::Enumerate(nsISimpleEnumerator **_retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 // The factory function
 nsresult NS_CreateJSArgv(JSContext *aContext, PRUint32 argc, void *argv,
-                         nsIArray **aArray)
+                         nsIJSArgArray **aArray)
 {
   nsresult rv;
   nsJSArgArray *ret = new nsJSArgArray(aContext, argc,
                                        static_cast<jsval *>(argv), &rv);
   if (ret == nsnull)
     return NS_ERROR_OUT_OF_MEMORY;
   if (NS_FAILED(rv)) {
     delete ret;
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -42,16 +42,17 @@
 #include "nsCOMPtr.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "nsIObserver.h"
 #include "nsIXPCScriptNotify.h"
 #include "prtime.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIXPConnect.h"
+#include "nsIArray.h"
 
 class nsIXPConnectJSObjectHolder;
 class nsRootedJSValueArray;
 class nsScriptNameSpaceManager;
 namespace mozilla {
 template <class> class Maybe;
 }
 
@@ -138,25 +139,24 @@ public:
   virtual nsresult ConnectToInner(nsIScriptGlobalObject *aNewInner,
                                   JSObject *aOuterGlobal);
   virtual nsresult InitContext();
   virtual nsresult CreateOuterObject(nsIScriptGlobalObject *aGlobalObject,
                                      nsIScriptGlobalObject *aCurrentInner);
   virtual nsresult SetOuterObject(JSObject* aOuterObject);
   virtual nsresult InitOuterWindow();
   virtual bool IsContextInitialized();
-  virtual void FinalizeContext();
 
   virtual void ScriptEvaluated(bool aTerminated);
-  virtual nsresult SetTerminationFunction(nsScriptTerminationFunc aFunc,
-                                          nsISupports* aRef);
+  virtual void SetTerminationFunction(nsScriptTerminationFunc aFunc,
+                                      nsIDOMWindow* aRef);
   virtual bool GetScriptsEnabled();
   virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
 
-  virtual nsresult SetProperty(void *aTarget, const char *aPropName, nsISupports *aVal);
+  virtual nsresult SetProperty(JSObject* aTarget, const char* aPropName, nsISupports* aVal);
 
   virtual bool GetProcessingScriptTag();
   virtual void SetProcessingScriptTag(bool aResult);
 
   virtual bool GetExecutingScript();
 
   virtual void SetGCOnDestruction(bool aGCOnDestruction);
 
@@ -343,21 +343,20 @@ public:
   static nsScriptNameSpaceManager* GetNameSpaceManager();
 };
 
 // An interface for fast and native conversion to/from nsIArray. If an object
 // supports this interface, JS can reach directly in for the argv, and avoid
 // nsISupports conversion. If this interface is not supported, the object will
 // be queried for nsIArray, and everything converted via xpcom objects.
 #define NS_IJSARGARRAY_IID \
- { /*{E96FB2AE-CB4F-44a0-81F8-D91C80AFE9A3} */ \
- 0xe96fb2ae, 0xcb4f, 0x44a0, \
- { 0x81, 0xf8, 0xd9, 0x1c, 0x80, 0xaf, 0xe9, 0xa3 } }
+{ 0xb6acdac8, 0xf5c6, 0x432c, \
+  { 0xa8, 0x6e, 0x33, 0xee, 0xb1, 0xb0, 0xcd, 0xdc } }
 
-class nsIJSArgArray: public nsISupports
+class nsIJSArgArray : public nsIArray
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSARGARRAY_IID)
   // Bug 312003 describes why this must be "void **", but after calling argv
   // may be cast to jsval* and the args found at:
   //    ((jsval*)argv)[0], ..., ((jsval*)argv)[argc - 1]
   virtual nsresult GetArgs(PRUint32 *argc, void **argv) = 0;
 };
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -96,17 +96,17 @@ private:
 
   nsCOMPtr<nsIScriptContext> mContext;
 
   // filename, line number and JS language version string of the
   // caller of setTimeout()
   nsCString mFileName;
   PRUint32 mLineNo;
   PRUint32 mVersion;
-  nsCOMPtr<nsIArray> mArgv;
+  nsCOMPtr<nsIJSArgArray> mArgv;
 
   // The JS expression to evaluate or function to call, if !mExpr
   JSFlatString *mExpr;
   JSObject *mFunObj;
 };
 
 
 // nsJSScriptTimeoutHandler
@@ -321,28 +321,27 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
     NS_ENSURE_SUCCESS(rv, rv);
 
     mFunObj = funobj;
 
     // Create our arg array.  argc is the number of arguments passed
     // to setTimeout or setInterval; the first two are our callback
     // and the delay, so only arguments after that need to go in our
     // array.
-    nsCOMPtr<nsIArray> array;
+    nsCOMPtr<nsIJSArgArray> array;
     // NS_MAX(argc - 2, 0) wouldn't work right because argc is unsigned.
     rv = NS_CreateJSArgv(cx, NS_MAX(argc, 2u) - 2, nsnull,
                          getter_AddRefs(array));
     if (NS_FAILED(rv)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     PRUint32 dummy;
     jsval *jsargv = nsnull;
-    nsCOMPtr<nsIJSArgArray> jsarray(do_QueryInterface(array));
-    jsarray->GetArgs(&dummy, reinterpret_cast<void **>(&jsargv));
+    array->GetArgs(&dummy, reinterpret_cast<void **>(&jsargv));
 
     // jsargv might be null if we have argc <= 2
     if (jsargv) {
       for (PRInt32 i = 2; (PRUint32)i < argc; ++i) {
         jsargv[i - 2] = argv[i];
       }
     } else {
       NS_ASSERTION(argc <= 2, "Why do we have no jsargv when we have arguments?");
--- a/dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
+++ b/dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
@@ -54,26 +54,28 @@ typedef long           WebGLsizeiptr;
 typedef unsigned long  WebGLuint;
 typedef float          WebGLfloat;
 typedef float          WebGLclampf;
 
 %{C++
 // for jsval
 #include "jsapi.h"
 
-namespace js {
-struct ArrayBuffer;
-struct TypedArray;
-}
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
 
 /* Avoid conflict with WinAPI */
 #undef NO_ERROR
 %}
 
 [ptr] native WebGLJSObjectPtr (JSObject);
+[ptr] native Element (mozilla::dom::Element);
 
 //
 // OpenGL object wrappers
 //
 
 [scriptable, builtinclass, uuid(0df9f4ed-f5ff-4e51-a6ff-2bd9785a7639)]
 interface nsIWebGLTexture : nsISupports
 {
@@ -170,17 +172,17 @@ interface nsIWebGLExtensionLoseContext :
 
 [scriptable, uuid(73bfb64d-94bd-4a7a-9eab-6b6d32e57aa0)]
 interface nsIWebGLExtensionTextureFilterAnisotropic : nsIWebGLExtension
 {
   const WebGLenum TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
   const WebGLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
 };
 
-[scriptable, builtinclass, uuid(f000afac-11b3-4c06-a35f-8db411f1cf54)]
+[scriptable, builtinclass, uuid(020474b1-2d3f-403b-b85d-11d9082ccd92)]
 interface nsIDOMWebGLRenderingContext : nsISupports
 {
   //
   //  CONSTANTS
   //
 
   /* ClearBufferMask */
   const unsigned long DEPTH_BUFFER_BIT               = 0x00000100;
@@ -781,29 +783,29 @@ interface nsIDOMWebGLRenderingContext : 
                                    in WebGLsizei width, in WebGLsizei height,
                                    in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
   [noscript] void texImage2D_imageData(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
                                    in WebGLsizei width, in WebGLsizei height,
                                    in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
 
   // HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
   [noscript] void texImage2D_dom(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
-                                 in WebGLenum format, in WebGLenum type, in nsIDOMElement element);
+                                 in WebGLenum format, in WebGLenum type, in Element element);
 
   void texSubImage2D([optional] in long dummy);
   [noscript] void texSubImage2D_array(in WebGLenum target, in WebGLint level,