WebCore:

2008-10-09  David Hyatt  <hyatt@apple.com>

        Add support for pseudo classes on scrollbar pseudo elements.  As an initial proof of concept only
        :enabled/:disabled are supported.  More pseudo classes will follow quickly now that this works.

        Reviewed by Tim Hatcher

        Added scrollbars/disabled-scrollbar.html

        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
        (WebCore::CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass):
        * css/CSSStyleSelector.h:
        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::getPseudoStyle):
        * rendering/RenderObject.h:
        * rendering/RenderScrollbar.cpp:
        (WebCore::RenderScrollbar::setEnabled):
        (WebCore::RenderScrollbar::scrollbarForStyleResolve):
        (WebCore::RenderScrollbar::getScrollbarPseudoStyle):
        (WebCore::RenderScrollbar::paintPart):
        * rendering/RenderScrollbar.h:

LayoutTests:

2008-10-09  David Hyatt  <hyatt@apple.com>

        Add test case for disabled scrollbars.

        Reviewed by Tim Hatcher

        * platform/mac/scrollbars/disabled-scrollbar-expected.checksum: Added.
        * platform/mac/scrollbars/disabled-scrollbar-expected.png: Added.
        * platform/mac/scrollbars/disabled-scrollbar-expected.txt: Added.
        * scrollbars/disabled-scrollbar.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c0a47ff..faf73b2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,5 +1,16 @@
 2008-10-09  David Hyatt  <hyatt@apple.com>
 
+        Add test case for disabled scrollbars.
+
+        Reviewed by Tim Hatcher
+
+        * platform/mac/scrollbars/disabled-scrollbar-expected.checksum: Added.
+        * platform/mac/scrollbars/disabled-scrollbar-expected.png: Added.
+        * platform/mac/scrollbars/disabled-scrollbar-expected.txt: Added.
+        * scrollbars/disabled-scrollbar.html: Added.
+
+2008-10-09  David Hyatt  <hyatt@apple.com>
+
         Land layout test for CSS scrollbars.
 
         Reviewed by Oliver Hunt
diff --git a/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.checksum b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.checksum
new file mode 100644
index 0000000..8008ecb
--- /dev/null
+++ b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.checksum
@@ -0,0 +1 @@
+37e066c25f0be1dd8b36c2ccc0b53c05
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.png b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.png
new file mode 100644
index 0000000..d18bd740
--- /dev/null
+++ b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.txt b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.txt
new file mode 100644
index 0000000..c384510
--- /dev/null
+++ b/LayoutTests/platform/mac/scrollbars/disabled-scrollbar-expected.txt
@@ -0,0 +1,154 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+layer at (8,8) size 200x200 clip at (8,8) size 183x183 scrollHeight 882
+  RenderBlock {DIV} at (0,0) size 200x200
+    RenderText {#text} at (0,0) size 35x18
+      text run at (0,0) width 35: "Hello"
+    RenderBR {BR} at (35,14) size 0x0
+    RenderText {#text} at (0,18) size 35x18
+      text run at (0,18) width 35: "Hello"
+    RenderBR {BR} at (35,32) size 0x0
+    RenderText {#text} at (0,36) size 35x18
+      text run at (0,36) width 35: "Hello"
+    RenderBR {BR} at (35,50) size 0x0
+    RenderText {#text} at (0,54) size 35x18
+      text run at (0,54) width 35: "Hello"
+    RenderBR {BR} at (35,68) size 0x0
+    RenderText {#text} at (0,72) size 35x18
+      text run at (0,72) width 35: "Hello"
+    RenderBR {BR} at (35,86) size 0x0
+    RenderText {#text} at (0,90) size 35x18
+      text run at (0,90) width 35: "Hello"
+    RenderBR {BR} at (35,104) size 0x0
+    RenderText {#text} at (0,108) size 35x18
+      text run at (0,108) width 35: "Hello"
+    RenderBR {BR} at (35,122) size 0x0
+    RenderText {#text} at (0,126) size 35x18
+      text run at (0,126) width 35: "Hello"
+    RenderBR {BR} at (35,140) size 0x0
+    RenderText {#text} at (0,144) size 35x18
+      text run at (0,144) width 35: "Hello"
+    RenderBR {BR} at (35,158) size 0x0
+    RenderText {#text} at (0,162) size 35x18
+      text run at (0,162) width 35: "Hello"
+    RenderBR {BR} at (35,176) size 0x0
+    RenderText {#text} at (0,180) size 35x18
+      text run at (0,180) width 35: "Hello"
+    RenderBR {BR} at (35,194) size 0x0
+    RenderText {#text} at (0,198) size 35x18
+      text run at (0,198) width 35: "Hello"
+    RenderBR {BR} at (35,212) size 0x0
+    RenderText {#text} at (0,216) size 35x18
+      text run at (0,216) width 35: "Hello"
+    RenderBR {BR} at (35,230) size 0x0
+    RenderText {#text} at (0,234) size 35x18
+      text run at (0,234) width 35: "Hello"
+    RenderBR {BR} at (35,248) size 0x0
+    RenderText {#text} at (0,252) size 35x18
+      text run at (0,252) width 35: "Hello"
+    RenderBR {BR} at (35,266) size 0x0
+    RenderText {#text} at (0,270) size 35x18
+      text run at (0,270) width 35: "Hello"
+    RenderBR {BR} at (35,284) size 0x0
+    RenderText {#text} at (0,288) size 35x18
+      text run at (0,288) width 35: "Hello"
+    RenderBR {BR} at (35,302) size 0x0
+    RenderText {#text} at (0,306) size 35x18
+      text run at (0,306) width 35: "Hello"
+    RenderBR {BR} at (35,320) size 0x0
+    RenderText {#text} at (0,324) size 35x18
+      text run at (0,324) width 35: "Hello"
+    RenderBR {BR} at (35,338) size 0x0
+    RenderText {#text} at (0,342) size 35x18
+      text run at (0,342) width 35: "Hello"
+    RenderBR {BR} at (35,356) size 0x0
+    RenderText {#text} at (0,360) size 35x18
+      text run at (0,360) width 35: "Hello"
+    RenderBR {BR} at (35,374) size 0x0
+    RenderText {#text} at (0,378) size 35x18
+      text run at (0,378) width 35: "Hello"
+    RenderBR {BR} at (35,392) size 0x0
+    RenderText {#text} at (0,396) size 35x18
+      text run at (0,396) width 35: "Hello"
+    RenderBR {BR} at (35,410) size 0x0
+    RenderText {#text} at (0,414) size 35x18
+      text run at (0,414) width 35: "Hello"
+    RenderBR {BR} at (35,428) size 0x0
+    RenderText {#text} at (0,432) size 35x18
+      text run at (0,432) width 35: "Hello"
+    RenderBR {BR} at (35,446) size 0x0
+    RenderText {#text} at (0,450) size 35x18
+      text run at (0,450) width 35: "Hello"
+    RenderBR {BR} at (35,464) size 0x0
+    RenderText {#text} at (0,468) size 35x18
+      text run at (0,468) width 35: "Hello"
+    RenderBR {BR} at (35,482) size 0x0
+    RenderText {#text} at (0,486) size 35x18
+      text run at (0,486) width 35: "Hello"
+    RenderBR {BR} at (35,500) size 0x0
+    RenderText {#text} at (0,504) size 35x18
+      text run at (0,504) width 35: "Hello"
+    RenderBR {BR} at (35,518) size 0x0
+    RenderText {#text} at (0,522) size 35x18
+      text run at (0,522) width 35: "Hello"
+    RenderBR {BR} at (35,536) size 0x0
+    RenderText {#text} at (0,540) size 35x18
+      text run at (0,540) width 35: "Hello"
+    RenderBR {BR} at (35,554) size 0x0
+    RenderText {#text} at (0,558) size 35x18
+      text run at (0,558) width 35: "Hello"
+    RenderBR {BR} at (35,572) size 0x0
+    RenderText {#text} at (0,576) size 35x18
+      text run at (0,576) width 35: "Hello"
+    RenderBR {BR} at (35,590) size 0x0
+    RenderText {#text} at (0,594) size 35x18
+      text run at (0,594) width 35: "Hello"
+    RenderBR {BR} at (35,608) size 0x0
+    RenderText {#text} at (0,612) size 35x18
+      text run at (0,612) width 35: "Hello"
+    RenderBR {BR} at (35,626) size 0x0
+    RenderText {#text} at (0,630) size 35x18
+      text run at (0,630) width 35: "Hello"
+    RenderBR {BR} at (35,644) size 0x0
+    RenderText {#text} at (0,648) size 35x18
+      text run at (0,648) width 35: "Hello"
+    RenderBR {BR} at (35,662) size 0x0
+    RenderText {#text} at (0,666) size 35x18
+      text run at (0,666) width 35: "Hello"
+    RenderBR {BR} at (35,680) size 0x0
+    RenderText {#text} at (0,684) size 35x18
+      text run at (0,684) width 35: "Hello"
+    RenderBR {BR} at (35,698) size 0x0
+    RenderText {#text} at (0,702) size 35x18
+      text run at (0,702) width 35: "Hello"
+    RenderBR {BR} at (35,716) size 0x0
+    RenderText {#text} at (0,720) size 35x18
+      text run at (0,720) width 35: "Hello"
+    RenderBR {BR} at (35,734) size 0x0
+    RenderText {#text} at (0,738) size 35x18
+      text run at (0,738) width 35: "Hello"
+    RenderBR {BR} at (35,752) size 0x0
+    RenderText {#text} at (0,756) size 35x18
+      text run at (0,756) width 35: "Hello"
+    RenderBR {BR} at (35,770) size 0x0
+    RenderText {#text} at (0,774) size 35x18
+      text run at (0,774) width 35: "Hello"
+    RenderBR {BR} at (35,788) size 0x0
+    RenderText {#text} at (0,792) size 35x18
+      text run at (0,792) width 35: "Hello"
+    RenderBR {BR} at (35,806) size 0x0
+    RenderText {#text} at (0,810) size 35x18
+      text run at (0,810) width 35: "Hello"
+    RenderBR {BR} at (35,824) size 0x0
+    RenderText {#text} at (0,828) size 35x18
+      text run at (0,828) width 35: "Hello"
+    RenderBR {BR} at (35,842) size 0x0
+    RenderText {#text} at (0,846) size 35x18
+      text run at (0,846) width 35: "Hello"
+    RenderBR {BR} at (35,860) size 0x0
+    RenderText {#text} at (0,864) size 35x18
+      text run at (0,864) width 35: "Hello"
+    RenderBR {BR} at (35,878) size 0x0
diff --git a/LayoutTests/scrollbars/disabled-scrollbar.html b/LayoutTests/scrollbars/disabled-scrollbar.html
new file mode 100644
index 0000000..b68864f8
--- /dev/null
+++ b/LayoutTests/scrollbars/disabled-scrollbar.html
@@ -0,0 +1,50 @@
+<head>
+<style>
+div::-webkit-scrollbar {
+  width:17px;
+  height:17px;
+}
+
+div::-webkit-scrollbar-button {
+  width: 17px;
+  height: 17px;
+  background-color:lightblue;
+  border:2px solid black;
+}
+
+div::-webkit-scrollbar-thumb {
+  min-width:20px;
+  min-height:20px;
+  background-color: navy;
+  border:2px solid #cccccc;
+}
+
+div::-webkit-scrollbar-button:disabled {
+  display:none
+}
+
+div::-webkit-scrollbar-track {
+  background-color: maroon;
+}
+
+div::-webkit-scrollbar-track:disabled {
+  background-color: grey;
+}
+
+</style>
+</head>
+<body>
+<div style="width:200px; height:200px; overflow-y:auto; overflow-x:scroll">
+Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>Hello<br>
+Hello<br>Hello<br>Hello<br>
+</div>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index df6b259..a554c65 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,27 @@
+2008-10-09  David Hyatt  <hyatt@apple.com>
+
+        Add support for pseudo classes on scrollbar pseudo elements.  As an initial proof of concept only
+        :enabled/:disabled are supported.  More pseudo classes will follow quickly now that this works.
+
+        Reviewed by Tim Hatcher
+
+        Added scrollbars/disabled-scrollbar.html
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
+        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+        (WebCore::CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass):
+        * css/CSSStyleSelector.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::getPseudoStyle):
+        * rendering/RenderObject.h:
+        * rendering/RenderScrollbar.cpp:
+        (WebCore::RenderScrollbar::setEnabled):
+        (WebCore::RenderScrollbar::scrollbarForStyleResolve):
+        (WebCore::RenderScrollbar::getScrollbarPseudoStyle):
+        (WebCore::RenderScrollbar::paintPart):
+        * rendering/RenderScrollbar.h:
+
 2008-10-09  Eric Carlson  <eric.carlson@apple.com>
 
         Media controls should not show when element is not visible
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index 87a8ecc..d43ed75 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -67,6 +67,7 @@
 #include "PageGroup.h"
 #include "Pair.h"
 #include "Rect.h"
+#include "RenderScrollbar.h"
 #include "RenderTheme.h"
 #include "RotateTransformOperation.h"
 #include "ScaleTransformOperation.h"
@@ -1670,7 +1671,9 @@
             break;
         case CSSSelector::SubSelector:
             // a selector is invalid if something follows a pseudo-element
-            if (elementStyle && dynamicPseudo != RenderStyle::NOPSEUDO)
+            // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
+            // to follow the pseudo elements.
+            if (elementStyle && dynamicPseudo != RenderStyle::NOPSEUDO && !(RenderScrollbar::scrollbarForStyleResolve() && sel->m_match == CSSSelector::PseudoClass))
                 return SelectorFailsCompletely;
             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle);
     }
@@ -1834,6 +1837,13 @@
         }
     }
     if (sel->m_match == CSSSelector::PseudoClass) {
+        
+        // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
+        // (since there are no elements involved).
+        if (RenderScrollbar::scrollbarForStyleResolve() && dynamicPseudo != RenderStyle::NOPSEUDO)
+            return checkScrollbarPseudoClass(sel, dynamicPseudo);
+        
+        // Normal element pseudo class checking.
         switch (sel->pseudoType()) {
             // Pseudo classes:
             case CSSSelector::PseudoEmpty: {
@@ -2369,6 +2379,20 @@
     return true;
 }
 
+bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, RenderStyle::PseudoId& dynamicPseudo) const
+{
+    RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve();
+    ASSERT(sel->m_match == CSSSelector::PseudoClass && scrollbar);
+    switch (sel->pseudoType()) {
+        case CSSSelector::PseudoEnabled:
+            return scrollbar->enabled();
+        case CSSSelector::PseudoDisabled:
+            return !scrollbar->enabled();
+        default:
+            return false;
+    }
+}
+
 void CSSStyleSelector::addVariables(CSSVariablesRule* variables)
 {
     CSSVariablesDeclaration* decl = variables->variables();
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index 11f61cd..05bc264 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -186,6 +186,7 @@
             SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
             bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
             PseudoState checkPseudoState(Element*, bool checkVisited = true) const;
+            bool checkScrollbarPseudoClass(CSSSelector*, RenderStyle::PseudoId& dynamicPseudo) const;
 
             void allVisitedStateChanged();
             void visitedStateChanged(unsigned visitedHash);
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 86a56e1..5e04be0 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -2822,7 +2822,7 @@
     return s;
 }
 
-RenderStyle* RenderObject::getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle) const
+RenderStyle* RenderObject::getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle, bool useCachedStyle) const
 {
     if (pseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
         return 0;
@@ -2830,7 +2830,7 @@
     if (!parentStyle)
         parentStyle = style();
 
-    RenderStyle* result = style()->getPseudoStyle(pseudo);
+    RenderStyle* result = useCachedStyle ? style()->getPseudoStyle(pseudo) : 0;
     if (result)
         return result;
 
@@ -2845,7 +2845,7 @@
         result->setStyleType(RenderStyle::FIRST_LINE_INHERITED);
     } else
         result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<Element*>(node), parentStyle);
-    if (result) {
+    if (result && useCachedStyle) {
         style()->addPseudoStyle(result);
         result->deref(document()->renderArena());
     }
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 9d4a092..d455275 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -376,7 +376,7 @@
     bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); }
 
 public:
-    RenderStyle* getPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const;
+    RenderStyle* getPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0, bool useCachedStyle = true) const;
 
     void updateDragState(bool dragOn);
 
diff --git a/WebCore/rendering/RenderScrollbar.cpp b/WebCore/rendering/RenderScrollbar.cpp
index a424cea..96b9083 100644
--- a/WebCore/rendering/RenderScrollbar.cpp
+++ b/WebCore/rendering/RenderScrollbar.cpp
@@ -56,16 +56,29 @@
     }
 }
 
-static ScrollbarPart gStyleResolvePart;
-static RenderScrollbar* gStyleResolveScrollbar;
+void RenderScrollbar::setEnabled(bool e)
+{
+    bool wasEnabled = enabled();
+    Scrollbar::setEnabled(e);
+    if (wasEnabled != e)
+        updateScrollbarParts();
+}
+
+static ScrollbarPart s_styleResolvePart;
+static RenderScrollbar* s_styleResolveScrollbar;
+
+RenderScrollbar* RenderScrollbar::scrollbarForStyleResolve()
+{
+    return s_styleResolveScrollbar;
+}
 
 RenderStyle* RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, RenderStyle::PseudoId pseudoId)
 {
-    gStyleResolvePart = partType;
-    gStyleResolveScrollbar = this;
-    RenderStyle* result = m_owner->getPseudoStyle(pseudoId, m_owner->style());
-    gStyleResolvePart = NoPart;
-    gStyleResolveScrollbar = 0;
+    s_styleResolvePart = partType;
+    s_styleResolveScrollbar = this;
+    RenderStyle* result = m_owner->getPseudoStyle(pseudoId, m_owner->style(), false);
+    s_styleResolvePart = NoPart;
+    s_styleResolveScrollbar = 0;
     return result;
 }
 
@@ -131,6 +144,8 @@
     partRenderer->setPos(rect.x() - x(), rect.y() - y());
     partRenderer->setWidth(rect.width());
     partRenderer->setHeight(rect.height());
+    partRenderer->setOverflowWidth(max(rect.width(), partRenderer->overflowWidth()));
+    partRenderer->setOverflowHeight(max(rect.height(), partRenderer->overflowHeight()));
 
     // Now do the paint.
     RenderObject::PaintInfo paintInfo(graphicsContext, rect, PaintPhaseBlockBackground, false, 0, 0);
diff --git a/WebCore/rendering/RenderScrollbar.h b/WebCore/rendering/RenderScrollbar.h
index 306e6ec..268e422 100644
--- a/WebCore/rendering/RenderScrollbar.h
+++ b/WebCore/rendering/RenderScrollbar.h
@@ -46,6 +46,7 @@
     virtual ~RenderScrollbar();
 
     virtual void setParent(ScrollView*);
+    virtual void setEnabled(bool);
 
     void updateScrollbarParts(RenderStyle* = 0, bool destroy = false);