Bug 1151940 part 3. Make some writable cssom-view attributes that we only allow setting from chrome act the way readonly replaceables would when called from content. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 08 Apr 2015 22:50:45 -0400
changeset 238260 7a3a671dedd592560892f6af6cb622903110fa27
parent 238259 ab636388d337132c08add96ad722d77f02d78ec9
child 238261 50cb8f889d230e7cb75ac283fd7e5c69489d9f84
push id58167
push userbzbarsky@mozilla.com
push dateThu, 09 Apr 2015 02:51:03 +0000
treeherdermozilla-inbound@6607b7fca4f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1151940
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1151940 part 3. Make some writable cssom-view attributes that we only allow setting from chrome act the way readonly replaceables would when called from content. r=smaug
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/test/test_innersize_scrollport.html
dom/base/test/test_writable-replaceable.html
dom/tests/mochitest/bugs/test_bug400204.html
dom/tests/mochitest/bugs/test_resize_move_windows.html
dom/webidl/Window.webidl
testing/web-platform/meta/html/browsers/the-window-object/window-properties.html.ini
testing/web-platform/meta/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html.ini
testing/web-platform/tests/html/browsers/the-window-object/window-properties.html
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -210,16 +210,17 @@
 #include "mozilla/dom/cache/CacheStorage.h"
 #include "mozilla/dom/Console.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/HashChangeEvent.h"
 #include "mozilla/dom/MozSelfSupportBinding.h"
 #include "mozilla/dom/PopStateEvent.h"
 #include "mozilla/dom/PopupBlockedEvent.h"
+#include "mozilla/dom/PrimitiveConversions.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "nsITabChild.h"
 #include "mozilla/dom/MediaQueryList.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/NavigatorBinding.h"
 #ifdef HAVE_SIDEBAR
 #include "mozilla/dom/ExternalBinding.h"
 #endif
@@ -4788,16 +4789,25 @@ nsGlobalWindow::GetInnerWidth(ErrorResul
 {
   FORWARD_TO_OUTER_OR_THROW(GetInnerWidth, (aError), aError, 0);
 
   CSSIntSize size;
   aError = GetInnerSize(size);
   return size.width;
 }
 
+void
+nsGlobalWindow::GetInnerWidth(JSContext* aCx,
+                              JS::MutableHandle<JS::Value> aValue,
+                              ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetInnerWidth, aValue,
+                            aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::GetInnerWidth(int32_t* aInnerWidth)
 {
   ErrorResult rv;
   *aInnerWidth = GetInnerWidth(rv);
 
   return rv.ErrorCode();
 }
@@ -4807,24 +4817,16 @@ nsGlobalWindow::SetInnerWidth(int32_t aI
 {
   FORWARD_TO_OUTER_OR_THROW(SetInnerWidth, (aInnerWidth, aError), aError, );
 
   if (!mDocShell) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
 
-  /*
-   * If caller is not chrome and the user has not explicitly exempted the site,
-   * prevent setting window.innerWidth by exiting early
-   */
-  if (!CanMoveResizeWindows() || IsFrame()) {
-    return;
-  }
-
   CheckSecurityWidthAndHeight(&aInnerWidth, nullptr);
 
   nsRefPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
 
   if (presShell && presShell->GetIsViewportOverridden())
   {
     nscoord height = 0;
 
@@ -4841,35 +4843,56 @@ nsGlobalWindow::SetInnerWidth(int32_t aI
   int32_t height = 0;
   int32_t unused  = 0;
 
   nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
   docShellAsWin->GetSize(&unused, &height);
   aError = SetDocShellWidthAndHeight(CSSToDevIntPixels(aInnerWidth), height);
 }
 
+void
+nsGlobalWindow::SetInnerWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                              ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetInnerWidth,
+                            aValue, "innerWidth", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetInnerWidth(int32_t aInnerWidth)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetInnerWidth(aInnerWidth, rv);
 
   return rv.ErrorCode();
 }
 
 int32_t
 nsGlobalWindow::GetInnerHeight(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetInnerHeight, (aError), aError, 0);
 
   CSSIntSize size;
   aError = GetInnerSize(size);
   return size.height;
 }
 
+void
+nsGlobalWindow::GetInnerHeight(JSContext* aCx,
+                              JS::MutableHandle<JS::Value> aValue,
+                              ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetInnerHeight, aValue,
+                            aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::GetInnerHeight(int32_t* aInnerHeight)
 {
   ErrorResult rv;
   *aInnerHeight = GetInnerHeight(rv);
 
   return rv.ErrorCode();
 }
@@ -4879,24 +4902,16 @@ nsGlobalWindow::SetInnerHeight(int32_t a
 {
   FORWARD_TO_OUTER_OR_THROW(SetInnerHeight, (aInnerHeight, aError), aError, );
 
   if (!mDocShell) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
 
-  /*
-   * If caller is not chrome and the user has not explicitly exempted the site,
-   * prevent setting window.innerHeight by exiting early
-   */
-  if (!CanMoveResizeWindows() || IsFrame()) {
-    return;
-  }
-
   nsRefPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
 
   if (presShell && presShell->GetIsViewportOverridden())
   {
     nsRefPtr<nsPresContext> presContext;
     presContext = presShell->GetPresContext();
 
     nsRect shellArea = presContext->GetVisibleArea();
@@ -4912,19 +4927,31 @@ nsGlobalWindow::SetInnerHeight(int32_t a
   int32_t width  = 0;
 
   nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
   docShellAsWin->GetSize(&width, &height);
   CheckSecurityWidthAndHeight(nullptr, &aInnerHeight);
   aError = SetDocShellWidthAndHeight(width, CSSToDevIntPixels(aInnerHeight));
 }
 
+void
+nsGlobalWindow::SetInnerHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                               ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetInnerHeight,
+                            aValue, "innerHeight", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetInnerHeight(int32_t aInnerHeight)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetInnerHeight(aInnerHeight, rv);
 
   return rv.ErrorCode();
 }
 
 nsIntSize
 nsGlobalWindow::GetOuterSize(ErrorResult& aError)
@@ -4954,56 +4981,65 @@ nsGlobalWindow::GetOuterSize(ErrorResult
 
 int32_t
 nsGlobalWindow::GetOuterWidth(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetOuterWidth, (aError), aError, 0);
   return GetOuterSize(aError).width;
 }
 
+void
+nsGlobalWindow::GetOuterWidth(JSContext* aCx,
+                              JS::MutableHandle<JS::Value> aValue,
+                              ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetOuterWidth, aValue,
+                            aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::GetOuterWidth(int32_t* aOuterWidth)
 {
   ErrorResult rv;
   *aOuterWidth = GetOuterWidth(rv);
 
   return rv.ErrorCode();
 }
 
 int32_t
 nsGlobalWindow::GetOuterHeight(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetOuterHeight, (aError), aError, 0);
   return GetOuterSize(aError).height;
 }
 
+void
+nsGlobalWindow::GetOuterHeight(JSContext* aCx,
+                               JS::MutableHandle<JS::Value> aValue,
+                               ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetOuterHeight, aValue,
+                            aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::GetOuterHeight(int32_t* aOuterHeight)
 {
   ErrorResult rv;
   *aOuterHeight = GetOuterHeight(rv);
 
   return rv.ErrorCode();
 }
 
 void
 nsGlobalWindow::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
                              ErrorResult& aError)
 {
   MOZ_ASSERT(IsOuterWindow());
 
-  /*
-   * If caller is not chrome and the user has not explicitly exempted the site,
-   * prevent setting window.outerWidth by exiting early
-   */
-
-  if (!CanMoveResizeWindows() || IsFrame()) {
-    return;
-  }
-
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (!treeOwnerAsWin) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   CheckSecurityWidthAndHeight(aIsWidth ? &aLengthCSSPixels : nullptr,
                               aIsWidth ? nullptr : &aLengthCSSPixels);
@@ -5026,36 +5062,60 @@ nsGlobalWindow::SetOuterSize(int32_t aLe
 void
 nsGlobalWindow::SetOuterWidth(int32_t aOuterWidth, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(SetOuterWidth, (aOuterWidth, aError), aError, );
 
   SetOuterSize(aOuterWidth, true, aError);
 }
 
+void
+nsGlobalWindow::SetOuterWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                              ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetOuterWidth,
+                            aValue, "outerWidth", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetOuterWidth(int32_t aOuterWidth)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetOuterWidth(aOuterWidth, rv);
 
   return rv.ErrorCode();
 }
 
 void
 nsGlobalWindow::SetOuterHeight(int32_t aOuterHeight, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(SetOuterHeight, (aOuterHeight, aError), aError, );
 
   SetOuterSize(aOuterHeight, false, aError);
 }
 
+void
+nsGlobalWindow::SetOuterHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                               ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetOuterHeight,
+                            aValue, "outerHeight", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetOuterHeight(int32_t aOuterHeight)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetOuterHeight(aOuterHeight, rv);
 
   return rv.ErrorCode();
 }
 
 nsIntPoint
 nsGlobalWindow::GetScreenXY(ErrorResult& aError)
@@ -5076,16 +5136,25 @@ nsGlobalWindow::GetScreenXY(ErrorResult&
 int32_t
 nsGlobalWindow::GetScreenX(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetScreenX, (aError), aError, 0);
 
   return DevToCSSIntPixels(GetScreenXY(aError).x);
 }
 
+void
+nsGlobalWindow::GetScreenX(JSContext* aCx,
+                           JS::MutableHandle<JS::Value> aValue,
+                           ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetScreenX, aValue,
+                            aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::GetScreenX(int32_t* aScreenX)
 {
   ErrorResult rv;
   *aScreenX = GetScreenX(rv);
 
   return rv.ErrorCode();
 }
@@ -5368,25 +5437,16 @@ nsGlobalWindow::MatchMedia(const nsAStri
   return rv.ErrorCode();
 }
 
 void
 nsGlobalWindow::SetScreenX(int32_t aScreenX, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(SetScreenX, (aScreenX, aError), aError, );
 
-  /*
-   * If caller is not chrome and the user has not explicitly exempted the site,
-   * prevent setting window.screenX by exiting early
-   */
-
-  if (!CanMoveResizeWindows() || IsFrame()) {
-    return;
-  }
-
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (!treeOwnerAsWin) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   int32_t x, y;
   aError = treeOwnerAsWin->GetPosition(&x, &y);
@@ -5395,19 +5455,31 @@ nsGlobalWindow::SetScreenX(int32_t aScre
   }
 
   CheckSecurityLeftAndTop(&aScreenX, nullptr);
   x = CSSToDevIntPixels(aScreenX);
 
   aError = treeOwnerAsWin->SetPosition(x, y);
 }
 
+void
+nsGlobalWindow::SetScreenX(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                           ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetScreenX,
+                            aValue, "screenX", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetScreenX(int32_t aScreenX)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetScreenX(aScreenX, rv);
 
   return rv.ErrorCode();
 }
 
 int32_t
 nsGlobalWindow::GetScreenY(ErrorResult& aError)
@@ -5422,29 +5494,29 @@ nsGlobalWindow::GetScreenY(int32_t* aScr
 {
   ErrorResult rv;
   *aScreenY = GetScreenY(rv);
 
   return rv.ErrorCode();
 }
 
 void
+nsGlobalWindow::GetScreenY(JSContext* aCx,
+                           JS::MutableHandle<JS::Value> aValue,
+                           ErrorResult& aError)
+{
+  GetReplaceableWindowCoord(aCx, &nsGlobalWindow::GetScreenY, aValue,
+                            aError);
+}
+
+void
 nsGlobalWindow::SetScreenY(int32_t aScreenY, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(SetScreenY, (aScreenY, aError), aError, );
 
-  /*
-   * If caller is not chrome and the user has not explicitly exempted the site,
-   * prevent setting window.screenY by exiting early
-   */
-
-  if (!CanMoveResizeWindows() || IsFrame()) {
-    return;
-  }
-
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (!treeOwnerAsWin) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   int32_t x, y;
   aError = treeOwnerAsWin->GetPosition(&x, &y);
@@ -5453,19 +5525,31 @@ nsGlobalWindow::SetScreenY(int32_t aScre
   }
 
   CheckSecurityLeftAndTop(nullptr, &aScreenY);
   y = CSSToDevIntPixels(aScreenY);
 
   aError = treeOwnerAsWin->SetPosition(x, y);
 }
 
+void
+nsGlobalWindow::SetScreenY(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                           ErrorResult& aError)
+{
+  SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetScreenY,
+                            aValue, "screenY", aError);
+}
+
 NS_IMETHODIMP
 nsGlobalWindow::SetScreenY(int32_t aScreenY)
 {
+  if (IsFrame()) {
+    return NS_OK;
+  }
+
   ErrorResult rv;
   SetScreenY(aScreenY, rv);
 
   return rv.ErrorCode();
 }
 
 // NOTE: Arguments to this function should have values scaled to
 // CSS pixels, not device pixels.
@@ -14138,11 +14222,50 @@ nsGlobalWindow::RedefineProperty(JSConte
 
   if (!JS_WrapObject(aCx, &thisObj) ||
       !JS_DefineProperty(aCx, thisObj, aPropName, aValue, JSPROP_ENUMERATE,
                          JS_STUBGETTER, JS_STUBSETTER)) {
     aError.Throw(NS_ERROR_FAILURE);
   }
 }
 
+void
+nsGlobalWindow::GetReplaceableWindowCoord(JSContext* aCx,
+                                          nsGlobalWindow::WindowCoordGetter aGetter,
+                                          JS::MutableHandle<JS::Value> aRetval,
+                                          ErrorResult& aError)
+{
+  int32_t coord = (this->*aGetter)(aError);
+  if (!aError.Failed() &&
+      !ToJSValue(aCx, coord, aRetval)) {
+    aError.Throw(NS_ERROR_FAILURE);
+  }
+}
+
+void
+nsGlobalWindow::SetReplaceableWindowCoord(JSContext* aCx,
+                                          nsGlobalWindow::WindowCoordSetter aSetter,
+                                          JS::Handle<JS::Value> aValue,
+                                          const char* aPropName,
+                                          ErrorResult& aError)
+{
+  /*
+   * If caller is not chrome and the user has not explicitly exempted the site,
+   * just treat this the way we would an IDL replaceable property.
+   */
+  nsGlobalWindow* outer = GetOuterWindowInternal();
+  if (!outer || !outer->CanMoveResizeWindows() || outer->IsFrame()) {
+    RedefineProperty(aCx, aPropName, aValue, aError);
+    return;
+  }
+
+  int32_t value;
+  if (!ValueToPrimitive<int32_t, eDefault>(aCx, aValue, &value)) {
+    aError.Throw(NS_ERROR_UNEXPECTED);
+    return;
+  }
+
+  (this->*aSetter)(value, aError);
+}
+
 #ifdef _WINDOWS_
 #error "Never include windows.h in this file!"
 #endif
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -961,39 +961,51 @@ public:
   void ScrollTo(const mozilla::dom::ScrollToOptions& aOptions);
   void ScrollBy(double aXScrollDif, double aYScrollDif);
   void ScrollBy(const mozilla::dom::ScrollToOptions& aOptions);
   void ScrollByLines(int32_t numLines,
                      const mozilla::dom::ScrollOptions& aOptions);
   void ScrollByPages(int32_t numPages,
                      const mozilla::dom::ScrollOptions& aOptions);
   void MozScrollSnap();
-  int32_t GetInnerWidth(mozilla::ErrorResult& aError);
-  void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError);
-  int32_t GetInnerHeight(mozilla::ErrorResult& aError);
-  void SetInnerHeight(int32_t aInnerHeight, mozilla::ErrorResult& aError);
+  void GetInnerWidth(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                     mozilla::ErrorResult& aError);
+  void SetInnerWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                     mozilla::ErrorResult& aError);
+  void GetInnerHeight(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                     mozilla::ErrorResult& aError);
+  void SetInnerHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                      mozilla::ErrorResult& aError);
   int32_t GetScrollX(mozilla::ErrorResult& aError);
   int32_t GetPageXOffset(mozilla::ErrorResult& aError)
   {
     return GetScrollX(aError);
   }
   int32_t GetScrollY(mozilla::ErrorResult& aError);
   int32_t GetPageYOffset(mozilla::ErrorResult& aError)
   {
     return GetScrollY(aError);
   }
   void MozRequestOverfill(mozilla::dom::OverfillCallback& aCallback, mozilla::ErrorResult& aError);
-  int32_t GetScreenX(mozilla::ErrorResult& aError);
-  void SetScreenX(int32_t aScreenX, mozilla::ErrorResult& aError);
-  int32_t GetScreenY(mozilla::ErrorResult& aError);
-  void SetScreenY(int32_t aScreenY, mozilla::ErrorResult& aError);
-  int32_t GetOuterWidth(mozilla::ErrorResult& aError);
-  void SetOuterWidth(int32_t aOuterWidth, mozilla::ErrorResult& aError);
-  int32_t GetOuterHeight(mozilla::ErrorResult& aError);
-  void SetOuterHeight(int32_t aOuterHeight, mozilla::ErrorResult& aError);
+  void GetScreenX(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                  mozilla::ErrorResult& aError);
+  void SetScreenX(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                  mozilla::ErrorResult& aError);
+  void GetScreenY(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                  mozilla::ErrorResult& aError);
+  void SetScreenY(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                  mozilla::ErrorResult& aError);
+  void GetOuterWidth(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                     mozilla::ErrorResult& aError);
+  void SetOuterWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                     mozilla::ErrorResult& aError);
+  void GetOuterHeight(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
+                      mozilla::ErrorResult& aError);
+  void SetOuterHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                      mozilla::ErrorResult& aError);
   int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
                                 mozilla::ErrorResult& aError);
   void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
   nsPerformance* GetPerformance();
 #ifdef MOZ_WEBSPEECH
   mozilla::dom::SpeechSynthesis*
     GetSpeechSynthesis(mozilla::ErrorResult& aError);
 #endif
@@ -1091,16 +1103,42 @@ protected:
 
   // Redefine the property called aPropName on this window object to be a value
   // property with the value aValue, much like we would do for a [Replaceable]
   // property in IDL.
   void RedefineProperty(JSContext* aCx, const char* aPropName,
                         JS::Handle<JS::Value> aValue,
                         mozilla::ErrorResult& aError);
 
+  // Implementation guts for our writable IDL attributes that are really
+  // supposed to be readonly replaceable.
+  typedef int32_t (nsGlobalWindow::*WindowCoordGetter)(mozilla::ErrorResult&);
+  typedef void (nsGlobalWindow::*WindowCoordSetter)(int32_t,
+                                                    mozilla::ErrorResult&);
+  void GetReplaceableWindowCoord(JSContext* aCx, WindowCoordGetter aGetter,
+                                 JS::MutableHandle<JS::Value> aRetval,
+                                 mozilla::ErrorResult& aError);
+  void SetReplaceableWindowCoord(JSContext* aCx, WindowCoordSetter aSetter,
+                                 JS::Handle<JS::Value> aValue,
+                                 const char* aPropName,
+                                 mozilla::ErrorResult& aError);
+  // And the implementations of WindowCoordGetter/WindowCoordSetter.
+  int32_t GetInnerWidth(mozilla::ErrorResult& aError);
+  void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError);
+  int32_t GetInnerHeight(mozilla::ErrorResult& aError);
+  void SetInnerHeight(int32_t aInnerHeight, mozilla::ErrorResult& aError);
+  int32_t GetScreenX(mozilla::ErrorResult& aError);
+  void SetScreenX(int32_t aScreenX, mozilla::ErrorResult& aError);
+  int32_t GetScreenY(mozilla::ErrorResult& aError);
+  void SetScreenY(int32_t aScreenY, mozilla::ErrorResult& aError);
+  int32_t GetOuterWidth(mozilla::ErrorResult& aError);
+  void SetOuterWidth(int32_t aOuterWidth, mozilla::ErrorResult& aError);
+  int32_t GetOuterHeight(mozilla::ErrorResult& aError);
+  void SetOuterHeight(int32_t aOuterHeight, mozilla::ErrorResult& aError);
+
   // Array of idle observers that are notified of idle events.
   nsTObserverArray<IdleObserverHolder> mIdleObservers;
 
   // Idle timer used for function callbacks to notify idle observers.
   nsCOMPtr<nsITimer> mIdleTimer;
 
   // Idle fuzz time added to idle timer callbacks.
   uint32_t mIdleFuzzFactor;
--- a/dom/base/test/test_innersize_scrollport.html
+++ b/dom/base/test/test_innersize_scrollport.html
@@ -22,20 +22,25 @@ function run()
   var newWidth = oldWidth / 2;
   var newHeight = oldHeight / 2;
 
   var utils = SpecialPowers.getDOMWindowUtils(window);
   utils.setScrollPositionClampingScrollPortSize(newWidth, newHeight);
   is(window.innerWidth, newWidth, "innerWidth not updated to scroll port width");
   is(window.innerHeight, newHeight, "innerHeight not updated to scroll port height");
 
+  var innerWidthGetter = Object.getOwnPropertyDescriptor(window, "innerWidth").get;
+  var innerHeightGetter = Object.getOwnPropertyDescriptor(window, "innerHeight").get;
+
   window.innerWidth = oldWidth;
   window.innerHeight = oldHeight;
-  is(window.innerWidth, newWidth, "innerWidth clobbered by direct set");
-  is(window.innerHeight, newHeight, "innerHeight clobbered by direct set");
+  is(window.innerWidth, oldWidth, "Should have redefined innerWidth");
+  is(window.innerHeight, oldHeight, "Should have redefined innerWidth");
+  is(innerWidthGetter.call(window), newWidth, "innerWidth clobbered by direct set");
+  is(innerHeightGetter.call(window), newHeight, "innerHeight clobbered by direct set");
 
   SimpleTest.finish();
 }
 
 window.addEventListener("load", run, false);
 
 </script>
 </pre>
--- a/dom/base/test/test_writable-replaceable.html
+++ b/dom/base/test/test_writable-replaceable.html
@@ -9,39 +9,40 @@
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823283">Mozilla Bug 823283</a>
 <p id="display"></p>
 <div id="content" style="display: none"></div>
 <pre id="test">
 <script type="application/javascript">
 /** Test for Bug 823283 **/
 
-function createTest(prop, typeStr, valCode)
+function createTest(prop, typeStr, valCode, replaceable)
 {
+  var newType = replaceable ? typeof(valCode) : typeStr;
   var code =
     'is(typeof ' + prop + ', "' + typeStr + '", "' + prop + ': bad unqualified before-state");\n' +
     'is(typeof window.' + prop + ', "' + typeStr + '", "' + prop + ': bad qualified before-state");\n' +
     '\n' +
     prop + ' = ' + valCode + ';\n' +
     '\n' +
-    'is(typeof ' + prop + ', "' + typeStr + '", "' + prop + ': bad unqualified after-state");\n' +
-    'is(typeof window.' + prop + ', "' + typeStr + '", "' + prop + ': bad qualified after-state");';
+    'is(typeof ' + prop + ', "' + newType + '", "' + prop + ': bad unqualified after-state");\n' +
+    'is(typeof window.' + prop + ', "' + newType + '", "' + prop + ': bad qualified after-state");';
 
   return Function(code);
 }
 
 [
-  ["innerHeight", "number", '"123"'],
-  ["innerWidth", "number", '"456"'],
-  ["outerHeight", "number", '"654"'],
-  ["outerWidth", "number", '"321"'],
-  ["screenX", "number", '"17"'],
-  ["screenY", "number", '"42"'],
-  ["status", "string", '{}'],
-  ["name", "string", '{}'],
+  ["innerHeight", "number", '"123"', true],
+  ["innerWidth", "number", '"456"', true],
+  ["outerHeight", "number", '"654"', true],
+  ["outerWidth", "number", '"321"', true],
+  ["screenX", "number", '"17"', true],
+  ["screenY", "number", '"42"', true],
+  ["status", "string", '{}', false],
+  ["name", "string", '{}', false],
 ].forEach(function(args)
 {
   createTest.apply(null, args)();
 });
 
 </script>
 </pre>
 </body>
--- a/dom/tests/mochitest/bugs/test_bug400204.html
+++ b/dom/tests/mochitest/bugs/test_bug400204.html
@@ -20,33 +20,45 @@ https://bugzilla.mozilla.org/show_bug.cg
   try { success = (c.contentWindow.innerWidth == 0); } catch(ex) { success = false; }
   ok(success, "can't access hidden iframe innerWidth, or it's not 0");
 
   // try to access innerHeight
   success = false;
   try { success = (c.contentWindow.innerHeight == 0); } catch(ex) { success = false; }
   ok(success, "can't access hidden iframe innerHeight, or it's not 0");
 
+  // Snag the canonical getter and setter
+  var innerWidthGetter = Object.getOwnPropertyDescriptor(c.contentWindow, "innerWidth").get;
+  var innerHeightGetter = Object.getOwnPropertyDescriptor(c.contentWindow, "innerHeight").get;
+
   // try to set innerWidth
   success = false;
   try { c.contentWindow.innerWidth = 100; success = true; } catch(ex) { success = false; }
   ok(success, "can't set hidden iframe innerWidth");
 
   // try to set innerHeight
   success = false;
   try { c.contentWindow.innerHeight = 100; success = true; } catch(ex) { success = false; }
   ok(success, "can't set hidden iframe innerHeight");
 
   // now try these again for good measure, and to ensure the values
-  // haven't changed
+  // haven't changed except via getting replaced
   // try to access innerWidth
   success = false;
-  try { success = (c.contentWindow.innerWidth == 0); } catch(ex) { success = false; }
+  try { success = (c.contentWindow.innerWidth == 100); } catch(ex) { success = false; }
+  ok(success, "can't access hidden iframe innerWidth, or it's not 100");
+
+  success = false;
+  try { success = (innerWidthGetter.call(c.contentWindow) == 0); } catch(ex) { success = false; }
   ok(success, "can't access hidden iframe innerWidth, or it's not 0");
 
   // try to access innerHeight
   success = false;
-  try { success = (c.contentWindow.innerHeight == 0); } catch(ex) { success = false; }
+  try { success = (c.contentWindow.innerHeight == 100); } catch(ex) { success = false; }
+  ok(success, "can't access hidden iframe innerHeight, or it's not 100");
+
+  success = false;
+  try { success = (innerHeightGetter.call(c.contentWindow) == 0); } catch(ex) { success = false; }
   ok(success, "can't access hidden iframe innerHeight, or it's not 0");
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/bugs/test_resize_move_windows.html
+++ b/dom/tests/mochitest/bugs/test_resize_move_windows.html
@@ -18,16 +18,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 565541 **/
 
 SimpleTest.waitForExplicitFinish();
 
 var previousX, previousY, previousWidth, previousHeight;
 
+["innerWidth", "innerHeight", "screenX", "screenY", "outerWidth",
+ "outerHeight"].map(function(name) {
+  window[name+"Getter"] = Object.getOwnPropertyDescriptor(window, name).get;
+});
 
 function backValues()
 {
   previousX = window.screenX;
   previousY = window.screenY;
   previousWidth = window.innerWidth;
   previousHeight = window.innerHeight;
 }
@@ -81,39 +85,49 @@ function hitEventLoop(condition, test, t
 }
 
 function checkChangeIsDisabled(aWindow, aNext)
 {
   // We want to check that nothing has changed. Having a high value would take
   // too much time. Worse thing that could happen is random green.
   var hits = 5;
 
-  var originalWidth = aWindow.innerWidth;
-  var originalHeight = aWindow.innerHeight;
+  function getProp(propName) {
+    return window[propName + "Getter"].call(aWindow);
+  }
 
-  var originalX = aWindow.screenX;
-  var originalY = aWindow.screenY;
+  var originalWidth = getProp("innerWidth");
+  var originalHeight = getProp("innerHeight");
 
-  var oWidth = aWindow.outerWidth;
-  var oHeight = aWindow.outerHeight;
+  var originalX = getProp("screenX");
+  var originalY = getProp("screenY");
+
+  var oWidth = getProp("outerWidth");
+  var oHeight = getProp("outerHeight");
 
   function changeCondition() {
     return aWindow.innerWidth != originalWidth ||
            aWindow.innerHeight != originalHeight ||
            aWindow.screenX != originalX || aWindow.screenY != originalY ||
            aWindow.outerWidth != oWidth || aWindow.outerHeight != oHeight;
   }
 
   function changeTest() {
-    is(aWindow.innerWidth, originalWidth, "Window width shouldn't have changed");
-    is(aWindow.innerHeight, originalHeight, "Window height shouldn't have changed");
-    is(aWindow.screenX, originalX, "Window x position shouldn't have changed");
-    is(aWindow.screenY, originalY, "Window y position shouldn't have changed");
-    is(aWindow.outerWidth, oWidth, "Window outerWidth shouldn't have changed");
-    is(aWindow.outerHeight, oHeight, "Window outerHeight shouldn't have changed");
+    ise(getProp("innerWidth"), originalWidth,
+        "Window width shouldn't have changed");
+    ise(getProp("innerHeight"), originalHeight,
+        "Window height shouldn't have changed");
+    ise(getProp("screenX"), originalX,
+        "Window x position shouldn't have changed");
+    ise(getProp("screenY"), originalY,
+        "Window y position shouldn't have changed");
+    ise(getProp("outerWidth"), oWidth,
+        "Window outerWidth shouldn't have changed");
+    ise(getProp("outerHeight"), oHeight,
+        "Window outerHeight shouldn't have changed");
   }
 
   /**
    * Size changes.
    */
   var newWidth = getNewWidth(aWindow);
   var newHeight = getNewHeight(aWindow);
 
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -171,20 +171,23 @@ partial interface Window {
   //[Throws] void resizeTo(double x, double y);
   //[Throws] void resizeBy(double x, double y);
   [Throws, UnsafeInPrerendering] void moveTo(long x, long y);
   [Throws, UnsafeInPrerendering] void moveBy(long x, long y);
   [Throws, UnsafeInPrerendering] void resizeTo(long x, long y);
   [Throws, UnsafeInPrerendering] void resizeBy(long x, long y);
 
   // viewport
-  //[Throws] readonly attribute double innerWidth;
-  //[Throws] readonly attribute double innerHeight;
-  [Throws] attribute long innerWidth;
-  [Throws] attribute long innerHeight;
+  // These are writable because we allow chrome to write them.  And they need
+  // to use 'any' as the type, because non-chrome writing them needs to act
+  // like a [Replaceable] attribute would, which needs the original JS value.
+  //[Replaceable, Throws] readonly attribute double innerWidth;
+  //[Replaceable, Throws] readonly attribute double innerHeight;
+  [Throws] attribute any innerWidth;
+  [Throws] attribute any innerHeight;
 
   // viewport scrolling
   void scroll(unrestricted double x, unrestricted double y);
   void scroll(optional ScrollToOptions options);
   void scrollTo(unrestricted double x, unrestricted double y);
   void scrollTo(optional ScrollToOptions options);
   void scrollBy(unrestricted double x, unrestricted double y);
   void scrollBy(optional ScrollToOptions options);
@@ -200,24 +203,27 @@ partial interface Window {
   //[Replaceable, Throws] readonly attribute double scrollY;
   //[Replaceable, Throws] readonly attribute double pageYOffset;
   [Replaceable, Throws] readonly attribute long scrollX;
   [Replaceable, Throws] readonly attribute long pageXOffset;
   [Replaceable, Throws] readonly attribute long scrollY;
   [Replaceable, Throws] readonly attribute long pageYOffset;
 
   // client
-  //[Throws] readonly attribute double screenX;
-  //[Throws] readonly attribute double screenY;
-  //[Throws] readonly attribute double outerWidth;
-  //[Throws] readonly attribute double outerHeight;
-  [Throws] attribute long screenX;
-  [Throws] attribute long screenY;
-  [Throws] attribute long outerWidth;
-  [Throws] attribute long outerHeight;
+  // These are writable because we allow chrome to write them.  And they need
+  // to use 'any' as the type, because non-chrome writing them needs to act
+  // like a [Replaceable] attribute would, which needs the original JS value.
+  //[Replaceable, Throws] readonly attribute double screenX;
+  //[Replaceable, Throws] readonly attribute double screenY;
+  //[Replaceable, Throws] readonly attribute double outerWidth;
+  //[Replaceable, Throws] readonly attribute double outerHeight;
+  [Throws] attribute any screenX;
+  [Throws] attribute any screenY;
+  [Throws] attribute any outerWidth;
+  [Throws] attribute any outerHeight;
 };
 
 /**
  * Special function that gets the fill ratio from the compositor used for testing
  * and is an indicator that we're layerizing correctly.
  * This function will call the given callback current fill ratio for a
  * composited frame. We don't guarantee which frame fill ratios will be returned.
  */
--- a/testing/web-platform/meta/html/browsers/the-window-object/window-properties.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/window-properties.html.ini
@@ -1,34 +1,10 @@
 [window-properties.html]
   type: testharness
-  [Window readonly attribute: innerWidth]
-    expected: FAIL
-
-  [Window readonly attribute: innerHeight]
-    expected: FAIL
-
-  [Window readonly attribute: scrollX]
-    expected: FAIL
-
-  [Window readonly attribute: scrollY]
-    expected: FAIL
-
-  [Window readonly attribute: screenX]
-    expected: FAIL
-
-  [Window readonly attribute: screenY]
-    expected: FAIL
-
-  [Window readonly attribute: outerWidth]
-    expected: FAIL
-
-  [Window readonly attribute: outerHeight]
-    expected: FAIL
-
   [Window attribute: oncancel]
     expected: FAIL
 
   [Window attribute: onclose]
     expected: FAIL
 
   [Window attribute: oncuechange]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html.ini
+++ /dev/null
@@ -1,449 +0,0 @@
-[svg-inline.html]
-  type: testharness
-  [svgViewBoxAttr: '0 0 100 200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '200', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '200', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '100px', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
-  [containerHeightStyle: '400px', svgViewBoxAttr: '0 0 100 200', svgWidthStyle: '50%', svgHeightStyle: '50%', svgWidthAttr: '25%', svgHeightAttr: '25%', ]
-    expected: FAIL
-
--- a/testing/web-platform/tests/html/browsers/the-window-object/window-properties.html
+++ b/testing/web-platform/tests/html/browsers/the-window-object/window-properties.html
@@ -56,16 +56,22 @@ var replaceableAttributes = [
   "length",
 
   // CSSOM-View
   "screen",
   "scrollX",
   "scrollY",
   "pageXOffset",
   "pageYOffset",
+  "innerWidth",
+  "innerHeight",
+  "screenX",
+  "screenY",
+  "outerWidth",
+  "outerHeight",
 ];
 
 var methods = [
   "close",
   "stop",
   "focus",
   "blur",
   "open",
@@ -111,24 +117,16 @@ var readonlyAttributes = [
   "navigator",
   "applicationCache",
 
   // WindowSessionStorage
   "sessionStorage",
 
   // WindowLocalStorage
   "localStorage",
-
-  // CSSOM-View
-  "innerWidth",
-  "innerHeight",
-  "screenX",
-  "screenY",
-  "outerWidth",
-  "outerHeight"
 ];
 
 var writableAttributes = [
   "name",
   "status",
   "opener",
   "onabort",
   "onafterprint",