Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Mon, 12 Mar 2012 12:27:40 -0700
changeset 109568 60fb46e7940cdbf645d2ac84b0ac3b7ec2bc4add
parent 109567 bf6acad353e0265602c9c5ce866cc9bef41a56eb (current diff)
parent 90282 c6f26a8dcd084c38f63c282ba77c713c7573e549 (diff)
child 109569 79b5d9b66d9a68117abbda7f3a8ed87fb99d52ce
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
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,
                                       in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
                                       in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
   [noscript] void texSubImage2D_imageData(in WebGLenum target, in WebGLint level,
                                       in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
                                       in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
   // HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
   [noscript] void texSubImage2D_dom(in WebGLenum target, in WebGLint level,
                                     in WebGLint xoffset, in WebGLint yoffset, in WebGLenum format, in WebGLenum type,
-                                    in nsIDOMElement element);
+                                    in Element element);
 
   // Modified: This replaces glTexParameterf, glTexParameterfv, glTexParameteri and glTexParameteriv
   void texParameterf(in WebGLenum target, in WebGLenum pname, in WebGLfloat param);
   void texParameteri(in WebGLenum target, in WebGLenum pname, in WebGLint param);
   //void glTexParameter(in WebGLenum target, in WebGLenum pname, in nsIWebGLArray params);
 
   // Modified: All the glUniform*v forms below are modified by replacing 'count' and 'v' with a nsIWebGLArray
   void uniform1f (in nsIWebGLUniformLocation location, in WebGLfloat x);
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -2358,17 +2358,17 @@ NS_IMETHODIMP nsDOMStorageEvent::GetUrl(
   return NS_OK;
 }
 
 /* readonly attribute nsIDOMStorage storageArea; */
 NS_IMETHODIMP nsDOMStorageEvent::GetStorageArea(nsIDOMStorage * *aStorageArea)
 {
   NS_ENSURE_ARG_POINTER(aStorageArea);
 
-  NS_ADDREF(*aStorageArea = mStorageArea);
+  NS_IF_ADDREF(*aStorageArea = mStorageArea);
   return NS_OK;
 }
 
 /* void initStorageEvent (in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in DOMString oldValueArg, in DOMString newValueArg, in DOMString urlArg, in nsIDOMStorage storageAreaArg); */
 NS_IMETHODIMP nsDOMStorageEvent::InitStorageEvent(const nsAString & typeArg,
                                                   bool canBubbleArg,
                                                   bool cancelableArg,
                                                   const nsAString & keyArg,
--- a/dom/system/nsDeviceMotion.cpp
+++ b/dom/system/nsDeviceMotion.cpp
@@ -194,22 +194,25 @@ NS_IMETHODIMP nsDeviceMotion::RemoveList
 
   mListeners.RemoveObject(aListener);
   StartDisconnectTimer();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDeviceMotion::AddWindowListener(nsIDOMWindow *aWindow)
 {
+  if (mWindowListeners.IndexOf(aWindow) != NoIndex)
+      return NS_OK;
+
   if (mStarted == false) {
     mStarted = true;
     Startup();
   }
-  if (mWindowListeners.IndexOf(aWindow) == NoIndex)
-    mWindowListeners.AppendElement(aWindow);
+
+  mWindowListeners.AppendElement(aWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDeviceMotion::RemoveWindowListener(nsIDOMWindow *aWindow)
 {
   if (mWindowListeners.IndexOf(aWindow) == NoIndex)
     return NS_OK;
 
@@ -219,38 +222,44 @@ NS_IMETHODIMP nsDeviceMotion::RemoveWind
 }
 
 NS_IMETHODIMP
 nsDeviceMotion::DeviceMotionChanged(PRUint32 type, double x, double y, double z)
 {
   if (!mEnabled)
     return NS_ERROR_NOT_INITIALIZED;
 
-  for (PRUint32 i = mListeners.Count(); i > 0 ; ) {
+  nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
+  for (PRUint32 i = listeners.Count(); i > 0 ; ) {
     --i;
     nsRefPtr<nsDeviceMotionData> a = new nsDeviceMotionData(type, x, y, z);
-    mListeners[i]->OnMotionChange(a);
+    listeners[i]->OnMotionChange(a);
   }
 
-  fo