Bug 714579 - Don't use GetComputedStyle for object attribute calculation, r=tbsaunde, marcoz, f=bz
authorAlexander Surkov <surkov.alexander@gmail.com>
Tue, 21 Feb 2012 00:45:29 +0900
changeset 90109 6a43d088a2b44458360c328e2159344722b5a352
parent 90108 a4aa5506b2c670a241f9f06646004782793e3e75
child 90110 a76bb7843e733d67788f0d942cb6101d9de4209e
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde, marcoz
bugs714579
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 714579 - Don't use GetComputedStyle for object attribute calculation, r=tbsaunde, marcoz, f=bz
accessible/src/base/Makefile.in
accessible/src/base/StyleInfo.cpp
accessible/src/base/StyleInfo.h
accessible/src/base/nsAccessible.cpp
accessible/tests/mochitest/attributes.js
accessible/tests/mochitest/attributes/Makefile.in
accessible/tests/mochitest/attributes/test_obj_css.html
accessible/tests/mochitest/attributes/test_obj_css.xul
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -71,16 +71,17 @@ CPPSRCS = \
   nsEventShell.cpp \
   nsFormControlAccessible.cpp \
   nsRootAccessible.cpp \
   nsApplicationAccessible.cpp \
   nsCaretAccessible.cpp \
   nsTextAccessible.cpp \
   nsTextEquivUtils.cpp \
   nsTextAttrs.cpp \
+  StyleInfo.cpp \
   TextUpdater.cpp \
   $(NULL)
 
 EXPORTS = \
   a11yGeneric.h \
   nsAccDocManager.h \
   nsAccessibilityService.h \
   nsAccessible.h \
@@ -102,16 +103,17 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xul \
   -I$(srcdir)/../../../layout/generic \
+  -I$(srcdir)/../../../layout/style \
   -I$(srcdir)/../../../layout/xul/base/src \
   -I$(srcdir)/../xforms \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/StyleInfo.cpp
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=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 Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 "StyleInfo.h"
+
+#include "mozilla/dom/Element.h"
+#include "nsComputedDOMStyle.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+StyleInfo::StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell) :
+  mElement(aElement)
+{
+  mStyleContext =
+    nsComputedDOMStyle::GetStyleContextForElementNoFlush(aElement,
+                                                         nsnull,
+                                                         aPresShell);
+}
+
+void
+StyleInfo::Display(nsAString& aValue)
+{
+  aValue.Truncate();
+  AppendASCIItoUTF16(
+    nsCSSProps::ValueToKeyword(mStyleContext->GetStyleDisplay()->mDisplay,
+                               nsCSSProps::kDisplayKTable), aValue);
+}
+
+void
+StyleInfo::TextAlign(nsAString& aValue)
+{
+  aValue.Truncate();
+  AppendASCIItoUTF16(
+    nsCSSProps::ValueToKeyword(mStyleContext->GetStyleText()->mTextAlign,
+                               nsCSSProps::kTextAlignKTable), aValue);
+}
+
+void
+StyleInfo::TextIndent(nsAString& aValue)
+{
+  aValue.Truncate();
+
+  const nsStyleCoord& styleCoord =
+    mStyleContext->GetStyleText()->mTextIndent;
+
+  nscoord coordVal;
+  switch (styleCoord.GetUnit()) {
+    case eStyleUnit_Coord:
+      coordVal = styleCoord.GetCoordValue();
+      break;
+
+    case eStyleUnit_Percent:
+    {
+      nsIFrame* frame = mElement->GetPrimaryFrame();
+      nsIFrame* containerFrame = frame->GetContainingBlock();
+      nscoord percentageBase = containerFrame->GetContentRect().width;
+      coordVal = NSCoordSaturatingMultiply(percentageBase,
+                                           styleCoord.GetPercentValue());
+      break;
+    }
+  }
+
+  aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
+  aValue.AppendLiteral("px");
+}
+
+void
+StyleInfo::Margin(css::Side aSide, nsAString& aValue)
+{
+  aValue.Truncate();
+
+  nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide);
+  aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
+  aValue.AppendLiteral("px");
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/StyleInfo.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=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 Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#ifndef _mozilla_a11y_style_h_
+#define _mozilla_a11y_style_h_
+
+#include "mozilla/gfx/Types.h"
+#include "nsStyleContext.h"
+
+namespace mozilla {
+namespace a11y {
+
+class StyleInfo
+{
+public:
+  StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell);
+  ~StyleInfo() { };
+
+  void Display(nsAString& aValue);
+  void TextAlign(nsAString& aValue);
+  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); }
+
+private:
+  StyleInfo() MOZ_DELETE;
+  StyleInfo(const StyleInfo&) MOZ_DELETE;
+  StyleInfo& operator = (const StyleInfo&) MOZ_DELETE;
+
+  void Margin(css::Side aSide, nsAString& aValue);
+
+  dom::Element* mElement;
+  nsRefPtr<nsStyleContext> mStyleContext;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -39,29 +39,28 @@
 
 #include "nsAccessible.h"
 
 #include "nsIXBLAccessible.h"
 
 #include "AccGroupInfo.h"
 #include "AccIterator.h"
 #include "nsAccUtils.h"
-#include "nsDocAccessible.h"
-#include "nsEventShell.h"
-
 #include "nsAccEvent.h"
 #include "nsAccessibleRelation.h"
 #include "nsAccessibilityService.h"
 #include "nsAccTreeWalker.h"
 #include "nsIAccessibleRelation.h"
+#include "nsEventShell.h"
 #include "nsRootAccessible.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
+#include "StyleInfo.h"
 
 #include "nsIDOMCSSValue.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLFormElement.h"
@@ -1437,59 +1436,50 @@ nsAccessible::GetAttributesInternal(nsIP
 
     nsIDocument *parentDoc = doc->GetParentDocument();
     if (!parentDoc)
       break;
 
     startContent = parentDoc->FindContentForSubDocument(doc);      
   }
 
-  // Expose 'display' attribute.
+  if (!mContent->IsElement())
+    return NS_OK;
+
+  // CSS style based object attributes.
   nsAutoString value;
-  nsresult rv = GetComputedStyleValue(EmptyString(),
-                                      NS_LITERAL_STRING("display"),
-                                      value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
+  StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
+
+  // Expose 'display' attribute.
+  styleInfo.Display(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
 
   // Expose 'text-align' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-align"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
+  styleInfo.TextAlign(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
 
   // Expose 'text-indent' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
+  styleInfo.TextIndent(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
 
   // Expose 'margin-left' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-left"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
+  styleInfo.MarginLeft(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
 
   // Expose 'margin-right' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-right"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
+  styleInfo.MarginRight(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
 
   // Expose 'margin-top' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-top"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
+  styleInfo.MarginTop(value);
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
 
   // Expose 'margin-bottom' attribute.
-  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-bottom"),
-                             value);
-  if (NS_SUCCEEDED(rv))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
+  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,
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -23,16 +23,36 @@ function testAttrs(aAccOrElmOrID, aAttrs
  *                              present (name/value pairs)
  */
 function testAbsentAttrs(aAccOrElmOrID, aAbsentAttrs)
 {
   testAttrsInternal(aAccOrElmOrID, {}, true, aAbsentAttrs);
 }
 
 /**
+ * Test CSS based object attributes.
+ */
+function testCSSAttrs(aID)
+{
+  var node = document.getElementById(aID);
+  var computedStyle = document.defaultView.getComputedStyle(node, "");
+
+  var attrs = {
+    "display": computedStyle.display,
+    "text-align": computedStyle.textAlign,
+    "text-indent": computedStyle.textIndent,
+    "margin-left": computedStyle.marginLeft,
+    "margin-right": computedStyle.marginRight,
+    "margin-top": computedStyle.marginTop,
+    "margin-bottom": computedStyle.marginBottom
+  };
+  testAttrs(aID, attrs, true);
+}
+
+/**
  * 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/Makefile.in
+++ b/accessible/tests/mochitest/attributes/Makefile.in
@@ -43,16 +43,17 @@ VPATH		= @srcdir@
 relativesrcdir  = accessible/attributes
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		test_obj.html \
 		test_obj_css.html \
+		test_obj_css.xul \
 		test_obj_group.html \
 		test_obj_group.xul \
 		test_obj_group_tree.xul \
 		test_text.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/attributes/test_obj_css.html
+++ b/accessible/tests/mochitest/attributes/test_obj_css.html
@@ -13,46 +13,75 @@ https://bugzilla.mozilla.org/show_bug.cg
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../attributes.js"></script>
 
   <script type="application/javascript">
-    function testCSSAttrs(aID)
-    {
-      var node = document.getElementById(aID);
-      var computedStyle = document.defaultView.getComputedStyle(node, "");
-
-      var attrs = {
-        "display": computedStyle.display,
-        "text-align": computedStyle.textAlign,
-        "text-indent": computedStyle.textIndent,
-        "margin-left": computedStyle.marginLeft,
-        "margin-right": computedStyle.marginRight,
-        "margin-top": computedStyle.marginTop,
-        "margin-bottom": computedStyle.marginBottom
-      };
-      testAttrs(aID, attrs, true);
-    }
-
     function doTest()
     {
+      // CSS display
+      testCSSAttrs("display_block");
+      testCSSAttrs("display_inline");
+      testCSSAttrs("display_inline-block");
+      testCSSAttrs("display_list-item");
+      testCSSAttrs("display_table");
+      testCSSAttrs("display_inline-table");
+      testCSSAttrs("display_table-row-group");
+      testCSSAttrs("display_table-column");
+      testCSSAttrs("display_table-column-group");
+      testCSSAttrs("display_table-header-group");
+      testCSSAttrs("display_table-footer-group");
+      testCSSAttrs("display_table-row");
+      testCSSAttrs("display_table-cell");
+      testCSSAttrs("display_table-caption");
+
+      // CSS text-align
+      testCSSAttrs("text-align_left");
+      testCSSAttrs("text-align_right");
+      testCSSAttrs("text-align_center");
+      testCSSAttrs("text-align_justify");
+      testCSSAttrs("text-align_inherit");
+
+      // CSS text-indent
+      testCSSAttrs("text-indent_em");
+      testCSSAttrs("text-indent_ex");
+      testCSSAttrs("text-indent_in");
+      testCSSAttrs("text-indent_cm");
+      testCSSAttrs("text-indent_mm");
+      testCSSAttrs("text-indent_pt");
+      testCSSAttrs("text-indent_pc");
+      testCSSAttrs("text-indent_px");
+      testCSSAttrs("text-indent_percent");
+      testCSSAttrs("text-indent_inherit");
+
+      // CSS margin
+      testCSSAttrs("margin_em");
+      testCSSAttrs("margin_ex");
+      testCSSAttrs("margin_in");
+      testCSSAttrs("margin_cm");
+      testCSSAttrs("margin_mm");
+      testCSSAttrs("margin_pt");
+      testCSSAttrs("margin_pc");
+      testCSSAttrs("margin_px");
+      testCSSAttrs("margin_percent");
+      testCSSAttrs("margin_auto");
+      testCSSAttrs("margin_inherit");
+
+      testCSSAttrs("margin-left");
+      testCSSAttrs("margin-right");
+      testCSSAttrs("margin-top");
+      testCSSAttrs("margin-bottom");
+
+      // Elements
       testCSSAttrs("span");
       testCSSAttrs("div");
-
       testCSSAttrs("p");
-      testCSSAttrs("p2");
-
-      testCSSAttrs("pml");
-      testCSSAttrs("pmr");
-      testCSSAttrs("pmt");
-      testCSSAttrs("pmb");
-
       testCSSAttrs("input");
       testCSSAttrs("table");
       testCSSAttrs("tr");
       testCSSAttrs("td");
 
       SimpleTest.finish();
     }
 
@@ -72,33 +101,93 @@ https://bugzilla.mozilla.org/show_bug.cg
      title="text-indent and text-align should really be object attribute">
     Mozilla Bug 460932
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=689540"
      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>
 
   <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>
+  <div id="display_inline" role="img"
+       style="display: inline;">display: inline</div>
+  <div id="display_inline-block" role="img"
+       style="display: inline-block;">display: inline-block</div>
+  <div id="display_list-item" role="img"
+       style="display: list-item;">display: list-item</div>
+  <div id="display_table" role="img"
+       style="display: table;">display: table</div>
+  <div id="display_inline-table" role="img"
+       style="display: inline-table;">display: inline-table</div>
+  <div id="display_table-row-group" role="img"
+       style="display: table-row-group;">display: table-row-group</div>
+  <div id="display_table-column" role="img"
+       style="display: table-column;">display: table-column</div>
+  <div id="display_table-column-group" role="img"
+       style="display: table-column-group;">display: table-column-group</div>
+  <div id="display_table-header-group" role="img"
+       style="display: table-header-group;">display: table-header-group</div>
+  <div id="display_table-footer-group" role="img"
+       style="display: table-footer-group;">display: table-footer-group</div>
+  <div id="display_table-row" role="img"
+       style="display: table-row;">display: table-row</div>
+  <div id="display_table-cell" role="img"
+       style="display: table-cell;">display: table-cell</div>
+  <div id="display_table-caption" role="img"
+       style="display: table-caption;">display: table-caption</div>
+
+  <p id="text-align_left" style="text-align: left;">text-align: left</p>
+  <p id="text-align_right" style="text-align: right;">text-align: right</p>
+  <p id="text-align_center" style="text-align: center;">text-align: center</p>
+  <p id="text-align_justify" style="text-align: justify;">text-align: justify</p>
+  <p id="text-align_inherit" style="text-align: inherit;">text-align: inherit</p>
+
+  <p id="text-indent_em" style="text-indent: 0.5em;">text-indent: 0.5em</p>
+  <p id="text-indent_ex" style="text-indent: 1ex;">text-indent: 1ex</p>
+  <p id="text-indent_in" style="text-indent: 0.5in;">text-indent: 0.5in</p>
+  <p id="text-indent_cm" style="text-indent: 2cm;">text-indent: 2cm</p>
+  <p id="text-indent_mm" style="text-indent: 10mm;">text-indent: 10mm</p>
+  <p id="text-indent_pt" style="text-indent: 30pt;">text-indent: 30pt</p>
+  <p id="text-indent_pc" style="text-indent: 2pc;">text-indent: 2pc</p>
+  <p id="text-indent_px" style="text-indent: 5px;">text-indent: 5px</p>
+  <p id="text-indent_percent" style="text-indent: 10%;">text-indent: 10%</p>
+  <p id="text-indent_inherit" style="text-indent: inherit;">text-indent: inherit</p>
+
+  <p id="margin_em" style="margin: 0.5em;">margin: 0.5em</p>
+  <p id="margin_ex" style="margin: 1ex;">margin: 1ex</p>
+  <p id="margin_in" style="margin: 0.5in;">margin: 0.5in</p>
+  <p id="margin_cm" style="margin: 2cm;">margin: 2cm</p>
+  <p id="margin_mm" style="margin: 10mm;">margin: 10mm</p>
+  <p id="margin_pt" style="margin: 30pt;">margin: 30pt</p>
+  <p id="margin_pc" style="margin: 2pc;">margin: 2pc</p>
+  <p id="margin_px" style="margin: 5px;">margin: 5px</p>
+  <p id="margin_percent" style="margin: 10%;">margin: 10%</p>
+  <p id="margin_auto" style="margin: auto;">margin: auto</p>
+  <p id="margin_inherit" style="margin: inherit;">margin: inherit</p>
+
+  <p id="margin-left" style="margin-left: 11px;">margin-left: 11px</p>
+  <p id="margin-right" style="margin-right: 21px;">margin-right</p>
+  <p id="margin-top" style="margin-top: 31px;">margin-top: 31px</p>
+  <p id="margin-bottom" style="margin-bottom: 41px;">margin-bottom: 41px</p>
+
   <span id="span" role="group">It's span</span>
   <div id="div">It's div</div>
-
   <p id="p">It's paragraph"</p>
-  <p id="p2"  style="text-indent: 5px">It's another paragraph</p>
-
-  <p id="pml" style="margin-left : 11px;">It's a paragraph with left margin</p>
-  <p id="pmr" style="margin-right : 21px;">It's a paragraph with right margin</p>
-  <p id="pmt" style="margin-top : 31px;">It's a paragraph with top margin</p>
-  <p id="pmb" style="margin-bottom : 41px;">It's a paragraph with bottom margin</p>
-
   <input id="input"/>
-  <table id="table">
+  <table id="table" style="margin: 2px; text-align: center; text-indent: 10%;">
     <tr id="tr" role="group">
       <td id="td">td</td>
     </tr>
   </table>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/attributes/test_obj_css.xul
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessibility CSS-based Object Attributes Test.">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="../common.js" />
+  <script type="application/javascript"
+          src="../events.js" />
+  <script type="application/javascript"
+          src="../attributes.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    function doTest()
+    {
+      // CSS display
+      testCSSAttrs("display_mozbox");
+      testCSSAttrs("display_mozinlinebox");
+      testCSSAttrs("display_mozgrid");
+      testCSSAttrs("display_mozinlinegrid");
+      testCSSAttrs("display_mozgridgroup");
+      testCSSAttrs("display_mozgridline");
+      testCSSAttrs("display_mozstack");
+      testCSSAttrs("display_mozinlinestack");
+      testCSSAttrs("display_mozdeck");
+      testCSSAttrs("display_mozpopup");
+      testCSSAttrs("display_mozgroupbox");
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <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><br/>
+
+    <p id="display"></p>
+    <div id="content" style="display: none">
+    </div>
+    <pre id="test">
+    </pre>
+  </body>
+
+  <vbox id="display_mozbox" style="display: -moz-box;" role="img"/>
+  <vbox id="display_mozinlinebox" style="display: -moz-inline-box;" role="img"/>
+  <vbox id="display_mozgrid" style="display: -moz-grid;" role="img"/>
+  <vbox id="display_mozinlinegrid" style="display: -moz-inline-grid;" role="img"/>
+  <vbox id="display_mozgridgroup" style="display: -moz-grid-group;" role="img"/>
+  <vbox id="display_mozgridline" style="display: -moz-grid-line;" role="img"/>
+  <vbox id="display_mozstack" style="display: -moz-stack;" role="img"/>
+  <vbox id="display_mozinlinestack" style="display: -moz-inline-stack;" role="img"/>
+  <vbox id="display_mozdeck" style="display: -moz-deck;" role="img"/>
+  <vbox id="display_mozpopup" style="display: -moz-popup;" role="img"/>
+  <vbox id="display_mozgroupbox" style="display: -moz-groupbox;" role="img"/>
+
+  </hbox>
+</window>
+