https://bugs.webkit.org/show_bug.cgi?id=45020
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 21:37:06 +0000 (21:37 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 21:37:06 +0000 (21:37 +0000)
Support "block-flow" and "writing-mode": interpret properties into RenderStyle

Patch by takano takumi <takano1@asia.apple.com> on 2010-09-16
Reviewed by Dave Hyatt.

Added code that interprets "block-flow" property and "writing-mode" property settings
into a RenderStyle object.

WebCore:

Test: fast/text/international/block-flow-parser-test.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue):
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator EBlockFlowDirection):
* css/CSSPropertyNames.in:
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::applyProperty):
* css/CSSValueKeywords.in:
* css/SVGCSSValueKeywords.in:
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::diff):
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::setBitDefaults):
(WebCore::InheritedFlags::blockFlow):
(WebCore::InheritedFlags::setBlockFlow):
(WebCore::InheritedFlags::initialBlockFlow):
* rendering/style/RenderStyleConstants.h:

LayoutTests:

* fast/css/getComputedStyle/computed-style-expected.txt:
* fast/css/getComputedStyle/computed-style-without-renderer-expected.txt:
* fast/text/international/block-flow-parser-test-expected.txt: Added.
* fast/text/international/block-flow-parser-test.html: Added.
* svg/css/getComputedStyle-basic-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@67667 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt
LayoutTests/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt
LayoutTests/fast/text/international/block-flow-parser-test-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/international/block-flow-parser-test.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/css/getComputedStyle/computed-style-expected.txt
LayoutTests/platform/mac/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt
LayoutTests/svg/css/getComputedStyle-basic-expected.txt
WebCore/ChangeLog
WebCore/css/CSSComputedStyleDeclaration.cpp
WebCore/css/CSSParser.cpp
WebCore/css/CSSPrimitiveValueMappings.h
WebCore/css/CSSPropertyNames.in
WebCore/css/CSSStyleSelector.cpp
WebCore/css/CSSValueKeywords.in
WebCore/css/SVGCSSValueKeywords.in
WebCore/rendering/style/RenderStyle.cpp
WebCore/rendering/style/RenderStyle.h
WebCore/rendering/style/RenderStyleConstants.h

index b83d83dd4b2a2d0d8808ec5a3c1088d8a264e5f7..fa1182289d0f4bf4d342277b256fcc23ff9bfb27 100644 (file)
@@ -1,3 +1,19 @@
+2010-09-16  takano takumi  <takano1@asia.apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45020
+        Support "block-flow" and "writing-mode": interpret properties into RenderStyle
+        Added code that interprets "block-flow" property and "writing-mode" property settings
+        into a RenderStyle object.
+
+        * fast/css/getComputedStyle/computed-style-expected.txt:
+        * fast/css/getComputedStyle/computed-style-without-renderer-expected.txt:
+        * fast/text/international/block-flow-parser-test-expected.txt: Added.
+        * fast/text/international/block-flow-parser-test.html: Added.
+        * svg/css/getComputedStyle-basic-expected.txt:
+
 2010-09-15  David Hyatt  <hyatt@apple.com>
 
         Reviewed by Darin Adler.
index 392391c64f3d9560dd6b7ed6ac204bb95e4b89ac..9d8a85e8d86530136ce3caeb36b1273120556f93 100644 (file)
@@ -96,6 +96,7 @@ zoom: 1;
 -webkit-background-composite: source-over;
 -webkit-background-origin: padding-box;
 -webkit-background-size: auto auto;
+-webkit-block-flow: tb;
 -webkit-border-fit: border;
 -webkit-border-image: none;
 -webkit-border-horizontal-spacing: 0px;
index e6487fb6510c6f6475410f4bb71e547c8cce3b16..311409b2b02f72f72ecef8178e267f01f4c4f4cc 100644 (file)
@@ -95,6 +95,7 @@ Computed style of an element whose parent's 'display' value is 'none':
     -webkit-background-composite: source-over
     -webkit-background-origin: padding-box
     -webkit-background-size: auto auto
+    -webkit-block-flow: tb
     -webkit-border-fit: border
     -webkit-border-image: none
     -webkit-border-horizontal-spacing: 0px
diff --git a/LayoutTests/fast/text/international/block-flow-parser-test-expected.txt b/LayoutTests/fast/text/international/block-flow-parser-test-expected.txt
new file mode 100644 (file)
index 0000000..bf86a0e
--- /dev/null
@@ -0,0 +1,13 @@
+block-flow parser test
+
+-webkit-block-flow:tb
+-webkit-block-flow:rl
+-webkit-block-flow:lr
+-webkit-block-flow:bt
+Okay if -webkit-block-flow values above and below are the same.
+
+-webkit-block-flow:tb
+-webkit-block-flow:rl
+-webkit-block-flow:lr
+-webkit-block-flow:bt
+
diff --git a/LayoutTests/fast/text/international/block-flow-parser-test.html b/LayoutTests/fast/text/international/block-flow-parser-test.html
new file mode 100644 (file)
index 0000000..d4dc09a
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>block-flow parser test</title>
+<script>
+function print(message)
+{
+    var paragraph = document.createElement("li");
+    paragraph.appendChild(document.createTextNode(message));
+    document.getElementById("console").appendChild(paragraph);
+}
+function test()
+{
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+       var blockFlowValues = ["tb", "rl", "lr", "bt"];
+       var pElems = document.getElementsByTagName("div");
+       for ( i = 0 ; i < pElems.length ; ++i )
+       {
+               var elem = pElems[i];
+               elem.style.webkitBlockFlow = blockFlowValues[i];
+               print("-webkit-block-flow:" + elem.style.webkitBlockFlow);
+       }
+}
+</script>
+</head>
+<body onload="test()">
+<p>block-flow parser test</p>
+<div>-webkit-block-flow:tb</div>
+<div>-webkit-block-flow:rl</div>
+<div>-webkit-block-flow:lr</div>
+<div>-webkit-block-flow:bt</div>
+<p>Okay if -webkit-block-flow values above and below are the same.</p>
+<hr>
+<p><ol id=console></ol></p>
+</body>
+</html>
index ff242ef56d2487d02c0fe5b63769c358b6231aad..c642012623da4212d163507ecc8292ec01b9f616 100644 (file)
@@ -107,6 +107,7 @@ zoom: 1;
 -webkit-background-composite: source-over;
 -webkit-background-origin: padding-box;
 -webkit-background-size: auto auto;
+-webkit-block-flow: tb;
 -webkit-border-fit: border;
 -webkit-border-horizontal-spacing: 0px;
 -webkit-border-image: none;
index 21baf09efc83e57b4df0e378cdb8ab43597fa27b..1f742b823e04df7d3df8482f80becbfa01fab5f4 100644 (file)
@@ -106,6 +106,7 @@ Computed style of an element whose parent's 'display' value is 'none':
     -webkit-background-composite: source-over
     -webkit-background-origin: padding-box
     -webkit-background-size: auto auto
+    -webkit-block-flow: tb
     -webkit-border-fit: border
     -webkit-border-horizontal-spacing: 0px
     -webkit-border-image: none
index 9de0e2a002ffc3e1a90c3de6944a741dc2fc9b73..757db218d89dfda0cdfd2c6a569366edef38cb85 100644 (file)
@@ -212,6 +212,8 @@ rect: style.getPropertyValue(-webkit-background-origin) : padding-box
 rect: style.getPropertyCSSValue(-webkit-background-origin) : [object CSSPrimitiveValue]
 rect: style.getPropertyValue(-webkit-background-size) : auto auto
 rect: style.getPropertyCSSValue(-webkit-background-size) : [object CSSValueList]
+rect: style.getPropertyValue(-webkit-block-flow) : tb
+rect: style.getPropertyCSSValue(-webkit-block-flow) : [object CSSPrimitiveValue]
 rect: style.getPropertyValue(-webkit-border-fit) : border
 rect: style.getPropertyCSSValue(-webkit-border-fit) : [object CSSPrimitiveValue]
 rect: style.getPropertyValue(-webkit-border-horizontal-spacing) : 0px
@@ -632,6 +634,8 @@ g: style.getPropertyValue(-webkit-background-origin) : padding-box
 g: style.getPropertyCSSValue(-webkit-background-origin) : [object CSSPrimitiveValue]
 g: style.getPropertyValue(-webkit-background-size) : auto auto
 g: style.getPropertyCSSValue(-webkit-background-size) : [object CSSValueList]
+g: style.getPropertyValue(-webkit-block-flow) : tb
+g: style.getPropertyCSSValue(-webkit-block-flow) : [object CSSPrimitiveValue]
 g: style.getPropertyValue(-webkit-border-fit) : border
 g: style.getPropertyCSSValue(-webkit-border-fit) : [object CSSPrimitiveValue]
 g: style.getPropertyValue(-webkit-border-horizontal-spacing) : 0px
index 506d0e1e82d1005986c3888d8e69c219cf4274fa..d6f8b8a3503cb26b24ad05d3edbcf1e2a84d9b35 100644 (file)
@@ -1,3 +1,36 @@
+2010-09-16  takano takumi  <takano1@asia.apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45020
+        Support "block-flow" and "writing-mode": interpret properties into RenderStyle
+        Added code that interprets "block-flow" property and "writing-mode" property settings
+        into a RenderStyle object.
+
+        Test: fast/text/international/block-flow-parser-test.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue):
+        * css/CSSPrimitiveValueMappings.h:
+        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+        (WebCore::CSSPrimitiveValue::operator EBlockFlowDirection):
+        * css/CSSPropertyNames.in:
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::applyProperty):
+        * css/CSSValueKeywords.in:
+        * css/SVGCSSValueKeywords.in:
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::diff):
+        * rendering/style/RenderStyle.h:
+        (WebCore::InheritedFlags::setBitDefaults):
+        (WebCore::InheritedFlags::blockFlow):
+        (WebCore::InheritedFlags::setBlockFlow):
+        (WebCore::InheritedFlags::initialBlockFlow):
+        * rendering/style/RenderStyleConstants.h:
+
 2010-09-16  Martin Robinson  <mrobinson@igalia.com>
 
         Reviewed by Xan Lopez.
index ab96347d162fa651eee2b6a3df85366686b0906e..e4a41861ef3835f9d4049b35d889381e6822c434 100644 (file)
@@ -158,6 +158,7 @@ static const int computedProperties[] = {
     CSSPropertyWebkitBackgroundComposite,
     CSSPropertyWebkitBackgroundOrigin,
     CSSPropertyWebkitBackgroundSize,
+    CSSPropertyWebkitBlockFlow,
     CSSPropertyWebkitBorderFit,
     CSSPropertyWebkitBorderHorizontalSpacing,
     CSSPropertyWebkitBorderImage,
@@ -1352,6 +1353,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             return CSSPrimitiveValue::create(style->appearance());
         case CSSPropertyWebkitBackfaceVisibility:
             return CSSPrimitiveValue::createIdentifier((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
+        case CSSPropertyWebkitBlockFlow:
+            return CSSPrimitiveValue::create(style->blockFlow());
         case CSSPropertyWebkitBorderImage:
             return valueForNinePieceImage(style->borderImage());
         case CSSPropertyWebkitMaskBoxImage:
@@ -1471,6 +1474,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyListStyle:
         case CSSPropertyMargin:
         case CSSPropertyPadding:
+        case CSSPropertyWebkitWritingMode:
             break;
 
         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
index 7c35739e9f4b681a750cecf01f758955aaaab24a..c3c31494bc69f9dcc694049b5a8fba8304b6c428 100644 (file)
@@ -1720,6 +1720,19 @@ bool CSSParser::parseValue(int propId, bool important)
         break;
 #endif
 
+    // CSS Text Layout Module Level 3: Vertical writing support
+    case CSSPropertyWebkitBlockFlow:
+        // [ "tb" | "rl" | "lr" | "bt" ]
+        if (id == CSSValueTb || id == CSSValueRl || id == CSSValueLr || id == CSSValueBt)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitWritingMode:
+        // [ "lr-tb" | "rl-tb" | "tb-rl" | "bt-rl" | "tb-lr" | "bt-lr" ]
+        if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueBtRl || id == CSSValueTbLr || id == CSSValueBtLr)
+            validPrimitive = true;
+        break;
+
 #if ENABLE(SVG)
     default:
         return parseSVGValue(propId, important);
index 3da5cf66bc4aeb3c21df58dea1a77004d819a1d1..2183c3cec585e5a402775db65551f4fc53fd2611 100644 (file)
@@ -2003,6 +2003,43 @@ template<> inline CSSPrimitiveValue::operator TextDirection() const
     }
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBlockFlowDirection e)
+    : m_type(CSS_IDENT)
+    , m_hasCachedCSSText(false)
+{
+    switch (e) {
+    case TopToBottomBlockFlow:
+        m_value.ident = CSSValueTb;
+        break;
+    case RightToLeftBlockFlow:
+        m_value.ident = CSSValueRl;
+        break;
+    case LeftToRightBlockFlow:
+        m_value.ident = CSSValueLr;
+        break;
+    case BottomToTopBlockFlow:
+        m_value.ident = CSSValueBt;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator EBlockFlowDirection() const
+{
+    switch (m_value.ident) {
+    case CSSValueTb:
+        return TopToBottomBlockFlow;
+    case CSSValueRl:
+        return RightToLeftBlockFlow;
+    case CSSValueLr:
+        return LeftToRightBlockFlow;
+    case CSSValueBt:
+        return BottomToTopBlockFlow;
+    default:
+        ASSERT_NOT_REACHED();
+        return TopToBottomBlockFlow;
+    }
+}
+
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPointerEvents e)
     : m_type(CSS_IDENT)
     , m_hasCachedCSSText(false)
index a3063db6a46ccda91cddc89bbd80fed863b92f7f..9079ea122fd36fa5c0bdd5deb35bc2c1993dc78c 100644 (file)
@@ -173,6 +173,8 @@ z-index
 # a single value: -webkit-background-size: l; is equivalent to background-size: l l;
 # whereas background-size: l; is equivalent to background-size: l auto;
 -webkit-background-size
+# CSS Text Layout Module Level 3: Vertical writing support
+-webkit-block-flow
 -webkit-border-end
 -webkit-border-end-color
 -webkit-border-end-style
@@ -275,3 +277,5 @@ z-index
 -webkit-user-modify
 -webkit-user-select
 -webkit-variable-declaration-block
+# CSS Text Layout Module Level 3: Vertical writing support
+-webkit-writing-mode
index b22ba8faa76ceea0fca983135df80f10730b93e5..3f0029e3af54cb355cd19585dd69d827d30a1d27 100644 (file)
@@ -5521,6 +5521,53 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         return;
 #endif 
 
+    // CSS Text Layout Module Level 3: Vertical writing support
+    case CSSPropertyWebkitBlockFlow:
+        HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(blockFlow, BlockFlow)
+        return;
+
+    case CSSPropertyWebkitWritingMode:
+        // The 'writing-mode' property is a shorthand property for the 'direction' property and the 'block-flow' property. 
+        if (isInherit) {
+            m_style->setDirection(m_parentStyle->direction());
+            m_style->setBlockFlow(m_parentStyle->blockFlow());
+        } else if (isInitial) {
+            m_style->setDirection(m_style->initialDirection());
+            m_style->setBlockFlow(m_style->initialBlockFlow());
+        } else {
+            if (!primitiveValue)
+                return;
+            switch (primitiveValue->getIdent()) {
+            case CSSValueLrTb:
+                m_style->setDirection(LTR);
+                m_style->setBlockFlow(TopToBottomBlockFlow);
+                break;
+            case CSSValueRlTb:
+                m_style->setDirection(RTL);
+                m_style->setBlockFlow(TopToBottomBlockFlow);
+                break;
+            case CSSValueTbRl:
+                m_style->setDirection(LTR);
+                m_style->setBlockFlow(RightToLeftBlockFlow);
+                break;
+            case CSSValueBtRl:
+                m_style->setDirection(RTL);
+                m_style->setBlockFlow(RightToLeftBlockFlow);
+                break;
+            case CSSValueTbLr:
+                m_style->setDirection(LTR);
+                m_style->setBlockFlow(LeftToRightBlockFlow);
+                break;
+            case CSSValueBtLr:
+                m_style->setDirection(RTL);
+                m_style->setBlockFlow(LeftToRightBlockFlow);
+                break;
+            default:
+                break;
+            }
+        }
+        return;
+
 #if ENABLE(SVG)
     default:
         // Try the SVG properties
index 1e7c2b5b76366840e21aa4a423e9bf448b79f13d..990bb36f872349de9b52b12fd56262aab346c144 100644 (file)
@@ -742,3 +742,17 @@ windowed
 # none
 manual
 # auto
+
+# -webkit-block-flow
+tb
+rl
+lr
+bt
+
+# -webkit-writing-mode
+lr-tb
+rl-tb
+tb-rl
+bt-rl
+tb-lr
+bt-lr
index 420fbd8180b4f9d7ac1071a3948738bd82143141..a2c9f83773a4d6742412160f6199db907967c5c4 100644 (file)
@@ -276,12 +276,3 @@ reset-size
 # CSS_PROP_VECTOR_EFFECT
 # none
 non-scaling-stroke
-
-
-# CSS_PROP_WRITING_MODE
-lr-tb
-rl-tb
-tb-rl
-lr
-rl
-tb
index 93cd8deb16d731fe57d9860b8074709a358fd961..4930a1343b46732d7089d1dbb8ff8fcbe1e6fb45 100644 (file)
@@ -441,6 +441,10 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
         noninherited_flags._clear != other->noninherited_flags._clear)
         return StyleDifferenceLayout;
 
+    // Check block flow direction.
+    if (inherited_flags._blockFlow != other->inherited_flags._blockFlow)
+        return StyleDifferenceLayout;
+
     // Overflow returns a layout hint.
     if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
         noninherited_flags._overflowY != other->noninherited_flags._overflowY)
index 9ede4e64cb27d98704217ca081d5faeb3bd5fc66..cf344dcf25195741265e511e997797e6aab7f103 100644 (file)
@@ -178,7 +178,8 @@ protected:
                    (_visuallyOrdered == other._visuallyOrdered) &&
                    (_force_backgrounds_to_white == other._force_backgrounds_to_white) &&
                    (_pointerEvents == other._pointerEvents) &&
-                   (_insideLink == other._insideLink);
+                   (_insideLink == other._insideLink) &&
+                   (_blockFlow == other._blockFlow);
         }
 
         bool operator!=(const InheritedFlags& other) const { return !(*this == other); }
@@ -204,6 +205,10 @@ protected:
         unsigned _pointerEvents : 4; // EPointerEvents
         unsigned _insideLink : 2; // EInsideLink
         // 43 bits
+
+        // CSS Text Layout Module Level 3: Vertical writing support
+        unsigned _blockFlow : 2; // EBlockFlowDirection
+        // 45 bits
     } inherited_flags;
 
 // don't inherit
@@ -279,6 +284,7 @@ protected:
         inherited_flags._force_backgrounds_to_white = false;
         inherited_flags._pointerEvents = initialPointerEvents();
         inherited_flags._insideLink = NotInsideLink;
+        inherited_flags._blockFlow = initialBlockFlow();
 
         noninherited_flags._effectiveDisplay = noninherited_flags._originalDisplay = initialDisplay();
         noninherited_flags._overflowX = initialOverflowX();
@@ -712,6 +718,8 @@ public:
     bool textSizeAdjust() const { return rareInheritedData->textSizeAdjust; }
     ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); }
 
+    EBlockFlowDirection blockFlow() const { return static_cast<EBlockFlowDirection>(inherited_flags._blockFlow); }
+
 // attribute setter methods
 
     void setDisplay(EDisplay v) { noninherited_flags._effectiveDisplay = v; }
@@ -1087,6 +1095,8 @@ public:
                originalDisplay() == INLINE_BOX || originalDisplay() == INLINE_TABLE;
     }
 
+    void setBlockFlow(EBlockFlowDirection v) { inherited_flags._blockFlow = v; }
+
     // To tell if this style matched attribute selectors. This makes it impossible to share.
     bool affectedByAttributeSelectors() const { return m_affectedByAttributeSelectors; }
     void setAffectedByAttributeSelectors() { m_affectedByAttributeSelectors = true; }
@@ -1126,6 +1136,7 @@ public:
     static ECaptionSide initialCaptionSide() { return CAPTOP; }
     static EClear initialClear() { return CNONE; }
     static TextDirection initialDirection() { return LTR; }
+    static EBlockFlowDirection initialBlockFlow() { return TopToBottomBlockFlow; }
     static EDisplay initialDisplay() { return INLINE; }
     static EEmptyCell initialEmptyCells() { return SHOW; }
     static EFloat initialFloating() { return FNONE; }
index a78321f84157563821de7728c506cf657ba13bad..94d30d50daedde2dee4f72c6900f46d13daa7989 100644 (file)
@@ -128,6 +128,11 @@ enum EUnicodeBidi {
     UBNormal, Embed, Override
 };
 
+// CSS Text Layout Module Level 3: Vertical writing support
+enum EBlockFlowDirection {
+    TopToBottomBlockFlow, RightToLeftBlockFlow, LeftToRightBlockFlow, BottomToTopBlockFlow
+};
+
 enum EFillAttachment {
     ScrollBackgroundAttachment, LocalBackgroundAttachment, FixedBackgroundAttachment
 };