<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[166422] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/166422">166422</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2014-03-28 12:57:34 -0700 (Fri, 28 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support form controls that may need incremental redraw
https://bugs.webkit.org/show_bug.cgi?id=130736

Reviewed by Beth Dakin.

There are some form controls that change appearance
over time. Expand the ControlStates so that it can
hold a little more information, including a reference
to the native form control. This way the Theme implementation
can repaint the existing native control if necessary. At
least ThemeMac was reusing a single control for painting
all instances before this change.

Since ControlStates is now a class, pass it around by
reference.

The other major change is keeping a timer to trigger a
repaint in RenderBox, which happens if Theme/RenderTheme
update the ControlState to request one.

* WebCore.xcodeproj/project.pbxproj: Add ControlStates.h.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* dom/Element.cpp:
(WebCore::Element::setActive): States now within ControlStates.
(WebCore::Element::setHovered): Ditto.
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::focusedOrActiveStateChanged): Ditto.
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::disabledStateChanged): Ditto.
(WebCore::HTMLFormControlElement::readOnlyAttributeChanged): Ditto.
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked): Ditto.
(WebCore::HTMLInputElement::setIndeterminate): Ditto.
* html/HTMLOptionElement.cpp:
(WebCore::HTMLOptionElement::parseAttribute): Ditto.
* platform/ControlStates.h: New file. Copied the old ControlStates enum,
and added accessors to hold whether or not the state is dirty, and
a reference to a platform control if necessary.
* platform/Theme.h:
(WebCore::Theme::selectionColor): Pass ControlStates pointer.
(WebCore::Theme::paint): Ditto.
(WebCore::Theme::inflateControlPaintRect): Ditto.
* platform/ThemeTypes.h: Remove ControlStates enum.
* platform/efl/RenderThemeEfl.cpp:
(WebCore::RenderThemeEfl::applyEdjeStateFromForm): Pass ControlStates pointer.
(WebCore::RenderThemeEfl::paintThemePart): Ditto.
* platform/efl/RenderThemeEfl.h: Ditto.
* platform/mac/ThemeMac.h: Ditto.
* platform/mac/ThemeMac.mm:
(-[WebCoreThemeView addSubview:]): New method to make sure we don't add CALayer backed
views to the NSView we're using for rendering.
(WebCore::updateStates): Use the private animated setters if necessary.
(WebCore::convertControlStatesToThemeDrawState): Namespacing.
(WebCore::configureCheckbox): Pass ControlStates pointer.
(WebCore::createCheckboxCell): New helper since we're creating non-static cells.
(WebCore::sharedCheckboxCell): The old static provider, renamed.
(WebCore::paintCheckbox): Check if this paint was triggered by a state change
or an animation. Update the ControlStates if we need to be repainted.
(WebCore::radio): Parameter is now ControlStates*.
(WebCore::paintRadio): Ditto.
(WebCore::setUpButtonCell): Ditto.
(WebCore::button): Ditto.
(WebCore::paintButton): Ditto.
(WebCore::paintStepper): Ditto.
(WebCore::ThemeMac::ensuredView): Ditto.
(WebCore::ThemeMac::inflateControlPaintRect): Ditto.
(WebCore::ThemeMac::paint): Ditto.
(WebCore::checkbox): Deleted.
* rendering/RenderBox.cpp:
(WebCore::RenderBox::RenderBox): Initialize timer.
(WebCore::RenderBox::~RenderBox): Stop any pending timers and delete the ControlState if necessary.
(WebCore::RenderBox::paintBoxDecorations): Create a ControlStates if needed. Paint, and start the repaint
timer if the ControlStates say we should.
(WebCore::RenderBox::repaintTimerFired): Call repaint when the timer fires.
* rendering/RenderBox.h: Add a timer for repainting.
* rendering/RenderElement.cpp:
(WebCore::controlStatesRendererMap): A static HashMap that associates renderers with ControlStates.
(WebCore::RenderElement::hasControlStatesForRenderer):
(WebCore::RenderElement::controlStatesForRenderer):
(WebCore::RenderElement::removeControlStatesForRenderer):
(WebCore::RenderElement::addControlStatesForRenderer):
* rendering/RenderElement.h:
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::paint): Use a pointer to ControlStates.
(WebCore::RenderTheme::adjustRepaintRect): Ditto.
(WebCore::RenderTheme::stateChanged): Ditto.
(WebCore::RenderTheme::updateControlStatesForRenderer): New method that just updates the states part of ControlStates.
(WebCore::RenderTheme::extractControlStatesForRenderer): New method that calculates the state.
(WebCore::RenderTheme::controlStatesForRenderer): Deleted.
* rendering/RenderTheme.h:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::documentViewFor): Use a ControlStates pointer.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingFrameSelectioncpp">trunk/Source/WebCore/editing/FrameSelection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlElementcpp">trunk/Source/WebCore/html/HTMLFormControlElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLInputElementcpp">trunk/Source/WebCore/html/HTMLInputElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLOptionElementcpp">trunk/Source/WebCore/html/HTMLOptionElement.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformThemeh">trunk/Source/WebCore/platform/Theme.h</a></li>
<li><a href="#trunkSourceWebCoreplatformThemeTypesh">trunk/Source/WebCore/platform/ThemeTypes.h</a></li>
<li><a href="#trunkSourceWebCoreplatformeflRenderThemeEflcpp">trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformeflRenderThemeEflh">trunk/Source/WebCore/platform/efl/RenderThemeEfl.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacThemeMach">trunk/Source/WebCore/platform/mac/ThemeMac.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacThemeMacmm">trunk/Source/WebCore/platform/mac/ThemeMac.mm</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxcpp">trunk/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxh">trunk/Source/WebCore/rendering/RenderBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementcpp">trunk/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementh">trunk/Source/WebCore/rendering/RenderElement.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemecpp">trunk/Source/WebCore/rendering/RenderTheme.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeh">trunk/Source/WebCore/rendering/RenderTheme.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeMacmm">trunk/Source/WebCore/rendering/RenderThemeMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformControlStatesh">trunk/Source/WebCore/platform/ControlStates.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/ChangeLog        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -1,3 +1,99 @@
</span><ins>+2014-03-27  Dean Jackson  &lt;dino@apple.com&gt;
+
+        Support form controls that may need incremental redraw
+        https://bugs.webkit.org/show_bug.cgi?id=130736
+
+        Reviewed by Beth Dakin.
+
+        There are some form controls that change appearance
+        over time. Expand the ControlStates so that it can
+        hold a little more information, including a reference
+        to the native form control. This way the Theme implementation
+        can repaint the existing native control if necessary. At
+        least ThemeMac was reusing a single control for painting
+        all instances before this change.
+
+        Since ControlStates is now a class, pass it around by
+        reference.
+
+        The other major change is keeping a timer to trigger a
+        repaint in RenderBox, which happens if Theme/RenderTheme
+        update the ControlState to request one.
+
+        * WebCore.xcodeproj/project.pbxproj: Add ControlStates.h.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * dom/Element.cpp:
+        (WebCore::Element::setActive): States now within ControlStates.
+        (WebCore::Element::setHovered): Ditto.
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::focusedOrActiveStateChanged): Ditto.
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::disabledStateChanged): Ditto.
+        (WebCore::HTMLFormControlElement::readOnlyAttributeChanged): Ditto.
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::setChecked): Ditto.
+        (WebCore::HTMLInputElement::setIndeterminate): Ditto.
+        * html/HTMLOptionElement.cpp:
+        (WebCore::HTMLOptionElement::parseAttribute): Ditto.
+        * platform/ControlStates.h: New file. Copied the old ControlStates enum,
+        and added accessors to hold whether or not the state is dirty, and
+        a reference to a platform control if necessary.
+        * platform/Theme.h:
+        (WebCore::Theme::selectionColor): Pass ControlStates pointer.
+        (WebCore::Theme::paint): Ditto.
+        (WebCore::Theme::inflateControlPaintRect): Ditto.
+        * platform/ThemeTypes.h: Remove ControlStates enum.
+        * platform/efl/RenderThemeEfl.cpp:
+        (WebCore::RenderThemeEfl::applyEdjeStateFromForm): Pass ControlStates pointer.
+        (WebCore::RenderThemeEfl::paintThemePart): Ditto.
+        * platform/efl/RenderThemeEfl.h: Ditto.
+        * platform/mac/ThemeMac.h: Ditto.
+        * platform/mac/ThemeMac.mm:
+        (-[WebCoreThemeView addSubview:]): New method to make sure we don't add CALayer backed
+        views to the NSView we're using for rendering.
+        (WebCore::updateStates): Use the private animated setters if necessary.
+        (WebCore::convertControlStatesToThemeDrawState): Namespacing.
+        (WebCore::configureCheckbox): Pass ControlStates pointer.
+        (WebCore::createCheckboxCell): New helper since we're creating non-static cells.
+        (WebCore::sharedCheckboxCell): The old static provider, renamed.
+        (WebCore::paintCheckbox): Check if this paint was triggered by a state change
+        or an animation. Update the ControlStates if we need to be repainted.
+        (WebCore::radio): Parameter is now ControlStates*.
+        (WebCore::paintRadio): Ditto.
+        (WebCore::setUpButtonCell): Ditto.
+        (WebCore::button): Ditto.
+        (WebCore::paintButton): Ditto.
+        (WebCore::paintStepper): Ditto.
+        (WebCore::ThemeMac::ensuredView): Ditto.
+        (WebCore::ThemeMac::inflateControlPaintRect): Ditto.
+        (WebCore::ThemeMac::paint): Ditto.
+        (WebCore::checkbox): Deleted.
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::RenderBox): Initialize timer.
+        (WebCore::RenderBox::~RenderBox): Stop any pending timers and delete the ControlState if necessary.
+        (WebCore::RenderBox::paintBoxDecorations): Create a ControlStates if needed. Paint, and start the repaint
+        timer if the ControlStates say we should.
+        (WebCore::RenderBox::repaintTimerFired): Call repaint when the timer fires.
+        * rendering/RenderBox.h: Add a timer for repainting.
+        * rendering/RenderElement.cpp:
+        (WebCore::controlStatesRendererMap): A static HashMap that associates renderers with ControlStates.
+        (WebCore::RenderElement::hasControlStatesForRenderer):
+        (WebCore::RenderElement::controlStatesForRenderer):
+        (WebCore::RenderElement::removeControlStatesForRenderer):
+        (WebCore::RenderElement::addControlStatesForRenderer):
+        * rendering/RenderElement.h:
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::paint): Use a pointer to ControlStates.
+        (WebCore::RenderTheme::adjustRepaintRect): Ditto.
+        (WebCore::RenderTheme::stateChanged): Ditto.
+        (WebCore::RenderTheme::updateControlStatesForRenderer): New method that just updates the states part of ControlStates.
+        (WebCore::RenderTheme::extractControlStatesForRenderer): New method that calculates the state.
+        (WebCore::RenderTheme::controlStatesForRenderer): Deleted.
+        * rendering/RenderTheme.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::documentViewFor): Use a ControlStates pointer.
+
</ins><span class="cx"> 2014-03-28  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clear SVGInlineTextBox fragments when the text changes.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -19084,6 +19084,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\ContentType.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\ContextMenu.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\ContextMenuItem.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\platform\ControlStates.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\platform\CookiesStrategy.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\CrossThreadCopier.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\Cursor.h&quot; /&gt;
</span><span class="lines">@@ -21130,4 +21131,4 @@
</span><span class="cx">   &lt;ImportGroup Label=&quot;ExtensionTargets&quot;&gt;
</span><span class="cx">     &lt;Import Project=&quot;$(VCTargetsPath)\BuildCustomizations\masm.targets&quot; /&gt;
</span><span class="cx">   &lt;/ImportGroup&gt;
</span><del>-&lt;/Project&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/Project&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -7969,6 +7969,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\ContextMenuItem.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\platform\ControlStates.h&quot;&gt;
+      &lt;Filter&gt;platform&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\platform\CookiesStrategy.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="lines">@@ -15147,4 +15150,4 @@
</span><span class="cx">       &lt;Filter&gt;platform\win&lt;/Filter&gt;
</span><span class="cx">     &lt;/MASM&gt;
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><del>-&lt;/Project&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/Project&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -8034,6 +8034,7 @@
</span><span class="cx">                 31078CC41880A6A6008099DC /* OESTextureHalfFloatLinear.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = OESTextureHalfFloatLinear.idl; path = canvas/OESTextureHalfFloatLinear.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 31078CC51880AAAA008099DC /* JSOESTextureHalfFloatLinear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSOESTextureHalfFloatLinear.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 31078CC61880AAAA008099DC /* JSOESTextureHalfFloatLinear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSOESTextureHalfFloatLinear.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                311C08BC18E35D6800B65615 /* ControlStates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlStates.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframeRule.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSKeyframeRule.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframesRule.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -20878,6 +20879,7 @@
</span><span class="cx">                 BCF1A5BA097832090061A123 /* platform */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                311C08BC18E35D6800B65615 /* ControlStates.h */,
</ins><span class="cx">                                 49E912A40EFAC8E6009D0CAF /* animation */,
</span><span class="cx">                                 FD31604012B026A300C1A359 /* audio */,
</span><span class="cx">                                 1AE42F670AA4B8CB00C8612D /* cf */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/dom/Element.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -487,7 +487,7 @@
</span><span class="cx">     if (reactsToPress)
</span><span class="cx">         setNeedsStyleRecalc();
</span><span class="cx"> 
</span><del>-    if (renderer()-&gt;style().hasAppearance() &amp;&amp; renderer()-&gt;theme().stateChanged(renderer(), PressedState))
</del><ins>+    if (renderer()-&gt;style().hasAppearance() &amp;&amp; renderer()-&gt;theme().stateChanged(renderer(), ControlStates::PressedState))
</ins><span class="cx">         reactsToPress = true;
</span><span class="cx"> 
</span><span class="cx">     // The rest of this function implements a feature that only works if the
</span><span class="lines">@@ -553,7 +553,7 @@
</span><span class="cx">         setNeedsStyleRecalc();
</span><span class="cx"> 
</span><span class="cx">     if (renderer()-&gt;style().hasAppearance())
</span><del>-        renderer()-&gt;theme().stateChanged(renderer(), HoverState);
</del><ins>+        renderer()-&gt;theme().stateChanged(renderer(), ControlStates::HoverState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Element::scrollIntoView(bool alignToTop) 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingFrameSelectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/FrameSelection.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -1745,7 +1745,7 @@
</span><span class="cx">         element-&gt;setNeedsStyleRecalc();
</span><span class="cx">         if (RenderObject* renderer = element-&gt;renderer())
</span><span class="cx">             if (renderer &amp;&amp; renderer-&gt;style().hasAppearance())
</span><del>-                renderer-&gt;theme().stateChanged(renderer, FocusState);
</del><ins>+                renderer-&gt;theme().stateChanged(renderer, ControlStates::FocusState);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;HTMLFormControlElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Attribute.h&quot;
</span><ins>+#include &quot;ControlStates.h&quot;
</ins><span class="cx"> #include &quot;Event.h&quot;
</span><span class="cx"> #include &quot;EventHandler.h&quot;
</span><span class="cx"> #include &quot;EventNames.h&quot;
</span><span class="lines">@@ -154,7 +155,7 @@
</span><span class="cx">     setNeedsWillValidateCheck();
</span><span class="cx">     didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
</span><span class="cx">     if (renderer() &amp;&amp; renderer()-&gt;style().hasAppearance())
</span><del>-        renderer()-&gt;theme().stateChanged(renderer(), EnabledState);
</del><ins>+        renderer()-&gt;theme().stateChanged(renderer(), ControlStates::EnabledState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLFormControlElement::readOnlyAttributeChanged()
</span><span class="lines">@@ -162,7 +163,7 @@
</span><span class="cx">     setNeedsWillValidateCheck();
</span><span class="cx">     setNeedsStyleRecalc();
</span><span class="cx">     if (renderer() &amp;&amp; renderer()-&gt;style().hasAppearance())
</span><del>-        renderer()-&gt;theme().stateChanged(renderer(), ReadOnlyState);
</del><ins>+        renderer()-&gt;theme().stateChanged(renderer(), ControlStates::ReadOnlyState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLFormControlElement::requiredAttributeChanged()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLInputElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLInputElement.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -859,7 +859,7 @@
</span><span class="cx">     if (CheckedRadioButtons* buttons = checkedRadioButtons())
</span><span class="cx">             buttons-&gt;updateCheckedState(this);
</span><span class="cx">     if (renderer() &amp;&amp; renderer()-&gt;style().hasAppearance())
</span><del>-        renderer()-&gt;theme().stateChanged(renderer(), CheckedState);
</del><ins>+        renderer()-&gt;theme().stateChanged(renderer(), ControlStates::CheckedState);
</ins><span class="cx">     setNeedsValidityCheck();
</span><span class="cx"> 
</span><span class="cx">     // Ideally we'd do this from the render tree (matching
</span><span class="lines">@@ -893,7 +893,7 @@
</span><span class="cx">     didAffectSelector(AffectedSelectorIndeterminate);
</span><span class="cx"> 
</span><span class="cx">     if (renderer() &amp;&amp; renderer()-&gt;style().hasAppearance())
</span><del>-        renderer()-&gt;theme().stateChanged(renderer(), CheckedState);
</del><ins>+        renderer()-&gt;theme().stateChanged(renderer(), ControlStates::CheckedState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int HTMLInputElement::size() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLOptionElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLOptionElement.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLOptionElement.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/html/HTMLOptionElement.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -195,7 +195,7 @@
</span><span class="cx">         if (oldDisabled != m_disabled) {
</span><span class="cx">             didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
</span><span class="cx">             if (renderer() &amp;&amp; renderer()-&gt;style().hasAppearance())
</span><del>-                renderer()-&gt;theme().stateChanged(renderer(), EnabledState);
</del><ins>+                renderer()-&gt;theme().stateChanged(renderer(), ControlStates::EnabledState);
</ins><span class="cx">         }
</span><span class="cx">     } else if (name == selectedAttr) {
</span><span class="cx">         // FIXME: This doesn't match what the HTML specification says.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformControlStatesh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/ControlStates.h (0 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ControlStates.h                                (rev 0)
+++ trunk/Source/WebCore/platform/ControlStates.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ControlStates_h
+#define ControlStates_h
+
+#include &lt;wtf/RetainPtr.h&gt;
+
+namespace WebCore {
+
+#if PLATFORM(COCOA)
+#ifndef __OBJC__
+typedef struct objc_object *id;
+#endif
+typedef id PlatformControlInstance;
+#endif
+
+class ControlStates {
+public:
+    enum {
+        HoverState = 1,
+        PressedState = 1 &lt;&lt; 1,
+        FocusState = 1 &lt;&lt; 2,
+        EnabledState = 1 &lt;&lt; 3,
+        CheckedState = 1 &lt;&lt; 4,
+        ReadOnlyState = 1 &lt;&lt; 5,
+        DefaultState = 1 &lt;&lt; 6,
+        WindowInactiveState = 1 &lt;&lt; 7,
+        IndeterminateState = 1 &lt;&lt; 8,
+        SpinUpState = 1 &lt;&lt; 9, // Sub-state for HoverState and PressedState.
+        AllStates = 0xffffffff
+    };
+
+    typedef unsigned States;
+
+    ControlStates(States states)
+        : m_states(states)
+        , m_initialized(false)
+        , m_needsRepaint(false)
+        , m_isDirty(false)
+#if PLATFORM(COCOA)
+        , m_controlInstance(nullptr)
+#endif
+    {
+    }
+
+    ControlStates()
+        : ControlStates(0)
+    {
+    }
+
+    ~ControlStates()
+    {
+    }
+
+    States states() const { return m_states; }
+    void setStates(States newStates)
+    {
+        if (newStates == m_states)
+            return;
+        m_states = newStates;
+        m_isDirty = m_initialized;
+        m_initialized = true;
+    }
+
+    bool needsRepaint() const { return m_needsRepaint; }
+    void setNeedsRepaint(bool r) { m_needsRepaint = r; }
+
+    bool isDirty() const { return m_isDirty; }
+    void setDirty(bool d) { m_isDirty = d; }
+
+#if PLATFORM(COCOA)
+    PlatformControlInstance platformControl() const { return m_controlInstance.get(); }
+    void setPlatformControl(PlatformControlInstance instance) { m_controlInstance = instance; }
+#endif
+
+private:
+    States m_states;
+    bool m_initialized;
+    bool m_needsRepaint;
+    bool m_isDirty;
+#if PLATFORM(COCOA)
+    RetainPtr&lt;PlatformControlInstance&gt; m_controlInstance;
+#endif
+};
+
+}
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/WebCore/platform/ControlStates.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCoreplatformThemeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Theme.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Theme.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/Theme.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define Theme_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Color.h&quot;
</span><ins>+#include &quot;ControlStates.h&quot;
</ins><span class="cx"> #include &quot;Font.h&quot;
</span><span class="cx"> #include &quot;IntRect.h&quot;
</span><span class="cx"> #include &quot;LengthBox.h&quot;
</span><span class="lines">@@ -65,7 +66,7 @@
</span><span class="cx">     virtual bool controlDrawsFocusOutline(ControlPart) const { return true; }
</span><span class="cx"> 
</span><span class="cx">     // Methods for obtaining platform-specific colors.
</span><del>-    virtual Color selectionColor(ControlPart, ControlState, SelectionPart) const { return Color(); }
</del><ins>+    virtual Color selectionColor(ControlPart, const ControlStates*, SelectionPart) const { return Color(); }
</ins><span class="cx">     virtual Color textSearchHighlightColor() const { return Color(); }
</span><span class="cx">     
</span><span class="cx">     // CSS system colors and fonts
</span><span class="lines">@@ -97,13 +98,13 @@
</span><span class="cx">     virtual bool controlRequiresPreWhiteSpace(ControlPart) const { return false; }
</span><span class="cx"> 
</span><span class="cx">     // Method for painting a control. The rect is in zoomed coordinates.
</span><del>-    virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&amp; /*zoomedRect*/, float /*zoomFactor*/, ScrollView*) const { }
</del><ins>+    virtual void paint(ControlPart, ControlStates*, GraphicsContext*, const IntRect&amp; /*zoomedRect*/, float /*zoomFactor*/, ScrollView*) { }
</ins><span class="cx"> 
</span><span class="cx">     // Some controls may spill out of their containers (e.g., the check on an OS X checkbox).  When these controls repaint,
</span><span class="cx">     // the theme needs to communicate this inflated rect to the engine so that it can invalidate the whole control.
</span><span class="cx">     // The rect passed in is in zoomed coordinates, so the inflation should take that into account and make sure the inflation
</span><span class="cx">     // amount is also scaled by the zoomFactor.
</span><del>-    virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&amp; /*zoomedRect*/, float /*zoomFactor*/) const { }
</del><ins>+    virtual void inflateControlPaintRect(ControlPart, const ControlStates*, IntRect&amp; /*zoomedRect*/, float /*zoomFactor*/) const { }
</ins><span class="cx">     
</span><span class="cx">     // This method is called once, from RenderTheme::adjustDefaultStyleSheet(), to let each platform adjust
</span><span class="cx">     // the default CSS rules in html.css.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformThemeTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ThemeTypes.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ThemeTypes.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/ThemeTypes.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -28,22 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-enum ControlState {
-    HoverState = 1,
-    PressedState = 1 &lt;&lt; 1,
-    FocusState = 1 &lt;&lt; 2,
-    EnabledState = 1 &lt;&lt; 3,
-    CheckedState = 1 &lt;&lt; 4,
-    ReadOnlyState = 1 &lt;&lt; 5,
-    DefaultState = 1 &lt;&lt; 6,
-    WindowInactiveState = 1 &lt;&lt; 7,
-    IndeterminateState = 1 &lt;&lt; 8,
-    SpinUpState = 1 &lt;&lt; 9, // Sub-state for HoverState and PressedState.
-    AllStates = 0xffffffff
-};
-
-typedef unsigned ControlStates;
-
</del><span class="cx"> // Must follow CSSValueKeywords.in order
</span><span class="cx"> enum ControlPart {
</span><span class="cx">     NoControlPart, CheckboxPart, RadioPart, PushButtonPart, SquareButtonPart, ButtonPart,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformeflRenderThemeEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -296,7 +296,7 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates states, bool haveBackground)
</del><ins>+void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, const ControlStates* states, bool haveBackground)
</ins><span class="cx"> {
</span><span class="cx">     const char *signals[] = { // keep in sync with WebCore/platform/ThemeTypes.h
</span><span class="cx">         &quot;hovered&quot;,
</span><span class="lines">@@ -314,7 +314,7 @@
</span><span class="cx">     edje_object_signal_emit(object, &quot;reset&quot;, &quot;&quot;);
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; WTF_ARRAY_LENGTH(signals); ++i) {
</span><del>-        if (states &amp; (1 &lt;&lt; i))
</del><ins>+        if (states-&gt;states() &amp; (1 &lt;&lt; i))
</ins><span class="cx">             edje_object_signal_emit(object, signals[i], &quot;&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -383,7 +383,8 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     bool haveBackgroundColor = isControlStyled(&amp;object-&gt;style(), object-&gt;style().border(), *object-&gt;style().backgroundLayers(), Color::white);
</span><del>-    applyEdjeStateFromForm(entry-&gt;edje(), controlStatesForRenderer(object), haveBackgroundColor);
</del><ins>+    ControlStates states(extractControlStatesForRenderer(object));
+    applyEdjeStateFromForm(entry-&gt;edje(), &amp;states, haveBackgroundColor);
</ins><span class="cx"> 
</span><span class="cx">     applyEdjeRTLState(entry-&gt;edje(), object, type, rect);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformeflRenderThemeEflh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/efl/RenderThemeEfl.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/efl/RenderThemeEfl.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/efl/RenderThemeEfl.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -229,7 +229,7 @@
</span><span class="cx"> 
</span><span class="cx">     void applyPartDescriptionsFrom(const String&amp; themePath);
</span><span class="cx"> 
</span><del>-    void applyEdjeStateFromForm(Evas_Object*, ControlStates, bool);
</del><ins>+    void applyEdjeStateFromForm(Evas_Object*, const ControlStates*, bool);
</ins><span class="cx">     void applyEdjeRTLState(Evas_Object*, RenderObject*, FormType, const IntRect&amp;);
</span><span class="cx">     bool paintThemePart(RenderObject*, FormType, const PaintInfo&amp;, const IntRect&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacThemeMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/ThemeMac.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/ThemeMac.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/mac/ThemeMac.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -51,11 +51,11 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; }
</span><span class="cx"> 
</span><del>-    virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&amp;, float zoomFactor, ScrollView*) const;
-    virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&amp;, float zoomFactor) const;
</del><ins>+    virtual void paint(ControlPart, ControlStates*, GraphicsContext*, const IntRect&amp;, float zoomFactor, ScrollView*) override;
+    virtual void inflateControlPaintRect(ControlPart, const ControlStates*, IntRect&amp;, float zoomFactor) const;
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: Once RenderThemeMac is converted over to use Theme then this can be internal to ThemeMac.
</span><del>-    static NSView* ensuredView(ScrollView*, ControlStates);
</del><ins>+    static NSView* ensuredView(ScrollView*, const ControlStates*);
</ins><span class="cx">     static void setFocusRingClipRect(const FloatRect&amp;);
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacThemeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/ThemeMac.mm (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/ThemeMac.mm        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/platform/mac/ThemeMac.mm        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -35,6 +35,15 @@
</span><span class="cx"> #import &lt;Carbon/Carbon.h&gt;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+@interface NSButtonCell(Details)
+- (void)_setState:(NSInteger)value animated:(BOOL)animated;
+- (void)_setHighlighted:(BOOL)flag animated:(BOOL)animated;
+- (void)_renderCurrentAnimationFrameInContext:(CGContextRef)ctxt atLocation:(NSPoint)where;
+- (BOOL)_stateAnimationRunning;
+@end
+#endif
+
</ins><span class="cx"> static NSRect focusRingClipRect;
</span><span class="cx"> static BOOL themeWindowHasKeyAppearance;
</span><span class="cx"> 
</span><span class="lines">@@ -97,6 +106,12 @@
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)addSubview:(NSView*)subview
+{
+    // By doing nothing in this method we forbid controls from adding subviews.
+    // This tells AppKit to not use Layer-backed animation for control rendering.
+    UNUSED_PARAM(subview);
+}
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @implementation NSFont (WebCoreTheme)
</span><span class="lines">@@ -176,45 +191,56 @@
</span><span class="cx">         [cell setControlSize:(NSControlSize)size];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void updateStates(NSCell* cell, ControlStates states)
</del><ins>+static void updateStates(NSCell* cell, const ControlStates* controlStates, bool useAnimation = false)
</ins><span class="cx"> {
</span><ins>+    ControlStates::States states = controlStates-&gt;states();
+
</ins><span class="cx">     // Hover state is not supported by Aqua.
</span><span class="cx">     
</span><span class="cx">     // Pressed state
</span><span class="cx">     bool oldPressed = [cell isHighlighted];
</span><del>-    bool pressed = states &amp; PressedState;
</del><ins>+    bool pressed = states &amp; ControlStates::PressedState;
</ins><span class="cx">     if (pressed != oldPressed)
</span><span class="cx">         [cell setHighlighted:pressed];
</span><span class="cx">     
</span><span class="cx">     // Enabled state
</span><span class="cx">     bool oldEnabled = [cell isEnabled];
</span><del>-    bool enabled = states &amp; EnabledState;
</del><ins>+    bool enabled = states &amp; ControlStates::EnabledState;
</ins><span class="cx">     if (enabled != oldEnabled)
</span><span class="cx">         [cell setEnabled:enabled];
</span><span class="cx"> 
</span><span class="cx">     // Checked and Indeterminate
</span><span class="cx">     bool oldIndeterminate = [cell state] == NSMixedState;
</span><del>-    bool indeterminate = (states &amp; IndeterminateState);
-    bool checked = states &amp; CheckedState;
</del><ins>+    bool indeterminate = (states &amp; ControlStates::IndeterminateState);
+    bool checked = states &amp; ControlStates::CheckedState;
</ins><span class="cx">     bool oldChecked = [cell state] == NSOnState;
</span><del>-    if (oldIndeterminate != indeterminate || checked != oldChecked)
-        [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
-        
</del><ins>+    if (oldIndeterminate != indeterminate || checked != oldChecked) {
+        NSCellStateValue newState = indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+        [(NSButtonCell*)cell _setState:newState animated:useAnimation];
+#else
+        UNUSED_PARAM(useAnimation);
+        [cell setState:newState];
+#endif
+    }
+
</ins><span class="cx">     // Window inactive state does not need to be checked explicitly, since we paint parented to 
</span><span class="cx">     // a view in a window whose key state can be detected.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states)
</del><ins>+static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, const ControlStates* controlStates)
</ins><span class="cx"> {
</span><del>-    if (states &amp; ReadOnlyState)
</del><ins>+    ControlStates::States states = controlStates-&gt;states();
+
+    if (states &amp; ControlStates::ReadOnlyState)
</ins><span class="cx">         return kThemeStateUnavailableInactive;
</span><del>-    if (!(states &amp; EnabledState))
</del><ins>+    if (!(states &amp; ControlStates::EnabledState))
</ins><span class="cx">         return kThemeStateUnavailableInactive;
</span><span class="cx"> 
</span><span class="cx">     // Do not process PressedState if !EnabledState or ReadOnlyState.
</span><del>-    if (states &amp; PressedState) {
</del><ins>+    if (states &amp; ControlStates::PressedState) {
</ins><span class="cx">         if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini)
</span><del>-            return states &amp; SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown;
</del><ins>+            return states &amp; ControlStates::SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown;
</ins><span class="cx">         return kThemeStatePressed;
</span><span class="cx">     }
</span><span class="cx">     return kThemeStateActive;
</span><span class="lines">@@ -266,34 +292,54 @@
</span><span class="cx">     // Use the font size to determine the intrinsic width of the control.
</span><span class="cx">     return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes());
</span><span class="cx"> }
</span><del>-
-static NSButtonCell *checkbox(ControlStates states, const IntRect&amp; zoomedRect, float zoomFactor)
</del><ins>+    
+static void configureCheckbox(NSCell* cell, const ControlStates* states, const IntRect&amp; zoomedRect, float zoomFactor, bool isStateChange)
</ins><span class="cx"> {
</span><del>-    static NSButtonCell *checkboxCell;
-    if (!checkboxCell) {
-        checkboxCell = [[NSButtonCell alloc] init];
-        [checkboxCell setButtonType:NSSwitchButton];
-        [checkboxCell setTitle:nil];
-        [checkboxCell setAllowsMixedState:YES];
-        [checkboxCell setFocusRingType:NSFocusRingTypeExterior];
-    }
-    
</del><span class="cx">     // Set the control size based off the rectangle we're painting into.
</span><del>-    setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor);
</del><ins>+    setControlSize(cell, checkboxSizes(), zoomedRect.size(), zoomFactor);
</ins><span class="cx"> 
</span><span class="cx">     // Update the various states we respond to.
</span><del>-    updateStates(checkboxCell, states);
</del><ins>+    updateStates(cell, states, isStateChange);
+}
</ins><span class="cx">     
</span><ins>+static NSButtonCell *createCheckboxCell()
+{
+    NSButtonCell *checkboxCell = [[NSButtonCell alloc] init];
+    [checkboxCell setButtonType:NSSwitchButton];
+    [checkboxCell setTitle:nil];
+    [checkboxCell setAllowsMixedState:YES];
+    [checkboxCell setFocusRingType:NSFocusRingTypeExterior];
</ins><span class="cx">     return checkboxCell;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static NSButtonCell *sharedCheckboxCell(const ControlStates* states, const IntRect&amp; zoomedRect, float zoomFactor)
+{
+    static NSButtonCell *checkboxCell;
+    if (!checkboxCell)
+        checkboxCell = createCheckboxCell();
+
+    configureCheckbox(checkboxCell, states, zoomedRect, zoomFactor, false);
+    return checkboxCell;
+}
+    
</ins><span class="cx"> // FIXME: Share more code with radio buttons.
</span><del>-static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</del><ins>+static void paintCheckbox(ControlStates* controlStates, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</ins><span class="cx"> {
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS
</span><span class="cx"> 
</span><del>-    // Determine the width and height needed for the control and prepare the cell for painting.
-    NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor);
</del><ins>+    NSButtonCell *checkboxCell = static_cast&lt;NSButtonCell*&gt;(controlStates-&gt;platformControl());
+
+    if (controlStates-&gt;isDirty()) {
+        if (!checkboxCell)
+            checkboxCell = createCheckboxCell();
+        configureCheckbox(checkboxCell, controlStates, zoomedRect, zoomFactor, true);
+    } else {
+        if (!checkboxCell)
+            checkboxCell = sharedCheckboxCell(controlStates, zoomedRect, zoomFactor);
+        configureCheckbox(checkboxCell, controlStates, zoomedRect, zoomFactor, false);
+    }
+    controlStates-&gt;setDirty(false);
+
</ins><span class="cx">     GraphicsContextStateSaver stateSaver(*context);
</span><span class="cx"> 
</span><span class="cx">     NSControlSize controlSize = [checkboxCell controlSize];
</span><span class="lines">@@ -311,12 +357,34 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     LocalCurrentGraphicsContext localContext(context);
</span><del>-    NSView *view = ThemeMac::ensuredView(scrollView, states);
-    [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view];
-    if (states &amp; FocusState)
</del><ins>+    NSView *view = ThemeMac::ensuredView(scrollView, controlStates);
+    bool drawStatically = true;
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+    drawStatically = ![checkboxCell _stateAnimationRunning];
+#endif
+    if (drawStatically)
+        [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view];
+    else {
+        // FIXME: This isn't quite correct at the moment due to the way the tick mark extends out of the control.
+        context-&gt;translate(inflatedRect.x(), inflatedRect.y());
+        context-&gt;scale(FloatSize(1, -1));
+        context-&gt;translate(0, -inflatedRect.height());
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+        [checkboxCell _renderCurrentAnimationFrameInContext:context-&gt;platformContext() atLocation:NSMakePoint(0, 0)];
+#endif
+    }
+    if (controlStates-&gt;states() &amp; ControlStates::FocusState)
</ins><span class="cx">         [checkboxCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
</span><span class="cx">     [checkboxCell setControlView:nil];
</span><span class="cx">     
</span><ins>+    bool needsRepaint = false;
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+    needsRepaint = [checkboxCell _stateAnimationRunning];
+#endif
+    controlStates-&gt;setNeedsRepaint(needsRepaint);
+    if (needsRepaint)
+        controlStates-&gt;setPlatformControl(checkboxCell);
+
</ins><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -349,7 +417,7 @@
</span><span class="cx">     return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static NSButtonCell *radio(ControlStates states, const IntRect&amp; zoomedRect, float zoomFactor)
</del><ins>+static NSButtonCell *radio(const ControlStates* states, const IntRect&amp; zoomedRect, float zoomFactor)
</ins><span class="cx"> {
</span><span class="cx">     static NSButtonCell *radioCell;
</span><span class="cx">     if (!radioCell) {
</span><span class="lines">@@ -368,10 +436,10 @@
</span><span class="cx">     return radioCell;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</del><ins>+static void paintRadio(ControlStates* controlStates, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</ins><span class="cx"> {
</span><span class="cx">     // Determine the width and height needed for the control and prepare the cell for painting.
</span><del>-    NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor);
</del><ins>+    NSButtonCell *radioCell = radio(controlStates, zoomedRect, zoomFactor);
</ins><span class="cx">     GraphicsContextStateSaver stateSaver(*context);
</span><span class="cx"> 
</span><span class="cx">     NSControlSize controlSize = [radioCell controlSize];
</span><span class="lines">@@ -390,9 +458,9 @@
</span><span class="cx"> 
</span><span class="cx">     LocalCurrentGraphicsContext localContext(context);
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS
</span><del>-    NSView *view = ThemeMac::ensuredView(scrollView, states);
</del><ins>+    NSView *view = ThemeMac::ensuredView(scrollView, controlStates);
</ins><span class="cx">     [radioCell drawWithFrame:NSRect(inflatedRect) inView:view];
</span><del>-    if (states &amp; FocusState)
</del><ins>+    if (controlStates-&gt;states() &amp; ControlStates::FocusState)
</ins><span class="cx">         [radioCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
</span><span class="cx">     [radioCell setControlView:nil];
</span><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS
</span><span class="lines">@@ -430,7 +498,7 @@
</span><span class="cx">     return cell;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void setUpButtonCell(NSButtonCell *cell, ControlPart part, ControlStates states, const IntRect&amp; zoomedRect, float zoomFactor)
</del><ins>+static void setUpButtonCell(NSButtonCell *cell, ControlPart part, const ControlStates* states, const IntRect&amp; zoomedRect, float zoomFactor)
</ins><span class="cx"> {
</span><span class="cx">     // Set the control size based off the rectangle we're painting into.
</span><span class="cx">     const IntSize* sizes = buttonSizes();
</span><span class="lines">@@ -447,26 +515,28 @@
</span><span class="cx">     updateStates(cell, states);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static NSButtonCell *button(ControlPart part, ControlStates states, const IntRect&amp; zoomedRect, float zoomFactor)
</del><ins>+static NSButtonCell *button(ControlPart part, const ControlStates* controlStates, const IntRect&amp; zoomedRect, float zoomFactor)
</ins><span class="cx"> {
</span><ins>+    ControlStates::States states = controlStates-&gt;states();
</ins><span class="cx">     NSButtonCell *cell;
</span><del>-    if (states &amp; DefaultState) {
</del><ins>+    if (states &amp; ControlStates::DefaultState) {
</ins><span class="cx">         static NSButtonCell *defaultCell = leakButtonCell(DefaultButtonCell);
</span><span class="cx">         cell = defaultCell;
</span><span class="cx">     } else {
</span><span class="cx">         static NSButtonCell *normalCell = leakButtonCell(NormalButtonCell);
</span><span class="cx">         cell = normalCell;
</span><span class="cx">     }
</span><del>-    setUpButtonCell(cell, part, states, zoomedRect, zoomFactor);    
</del><ins>+    setUpButtonCell(cell, part, controlStates, zoomedRect, zoomFactor);
</ins><span class="cx">     return cell;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</del><ins>+static void paintButton(ControlPart part, ControlStates* controlStates, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</ins><span class="cx"> {
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="cx">     // Determine the width and height needed for the control and prepare the cell for painting.
</span><del>-    NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor);
</del><ins>+    ControlStates::States states = controlStates-&gt;states();
+    NSButtonCell *buttonCell = button(part, controlStates, zoomedRect, zoomFactor);
</ins><span class="cx">     GraphicsContextStateSaver stateSaver(*context);
</span><span class="cx"> 
</span><span class="cx">     NSControlSize controlSize = [buttonCell controlSize];
</span><span class="lines">@@ -494,18 +564,18 @@
</span><span class="cx">     } 
</span><span class="cx"> 
</span><span class="cx">     LocalCurrentGraphicsContext localContext(context);
</span><del>-    NSView *view = ThemeMac::ensuredView(scrollView, states);
</del><ins>+    NSView *view = ThemeMac::ensuredView(scrollView, controlStates);
</ins><span class="cx">     NSWindow *window = [view window];
</span><span class="cx">     NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell];
</span><span class="cx"> 
</span><del>-    if (states &amp; DefaultState) {
</del><ins>+    if (states &amp; ControlStates::DefaultState) {
</ins><span class="cx">         [window setDefaultButtonCell:buttonCell];
</span><span class="cx">         wkAdvanceDefaultButtonPulseAnimation(buttonCell);
</span><span class="cx">     } else if ([previousDefaultButtonCell isEqual:buttonCell])
</span><span class="cx">         [window setDefaultButtonCell:nil];
</span><span class="cx"> 
</span><span class="cx">     [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view];
</span><del>-    if (states &amp; FocusState)
</del><ins>+    if (states &amp; ControlStates::FocusState)
</ins><span class="cx">         [buttonCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
</span><span class="cx">     [buttonCell setControlView:nil];
</span><span class="cx"> 
</span><span class="lines">@@ -535,7 +605,7 @@
</span><span class="cx">     return NSMiniControlSize;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView*)
</del><ins>+static void paintStepper(ControlStates* states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView*)
</ins><span class="cx"> {
</span><span class="cx">     // We don't use NSStepperCell because there are no ways to draw an
</span><span class="cx">     // NSStepperCell with the up button highlighted.
</span><span class="lines">@@ -577,7 +647,7 @@
</span><span class="cx"> 
</span><span class="cx"> // This will ensure that we always return a valid NSView, even if ScrollView doesn't have an associated document NSView.
</span><span class="cx"> // If the ScrollView doesn't have an NSView, we will return a fake NSView set up in the way AppKit expects.
</span><del>-NSView *ThemeMac::ensuredView(ScrollView* scrollView, ControlStates states)
</del><ins>+NSView *ThemeMac::ensuredView(ScrollView* scrollView, const ControlStates* controlStates)
</ins><span class="cx"> {
</span><span class="cx">     if (NSView *documentView = scrollView-&gt;documentView())
</span><span class="cx">         return documentView;
</span><span class="lines">@@ -586,7 +656,7 @@
</span><span class="cx">     static WebCoreThemeView *themeView = [[WebCoreThemeView alloc] init];
</span><span class="cx">     [themeView setFrameSize:NSSizeFromCGSize(scrollView-&gt;totalContentsSize())];
</span><span class="cx"> 
</span><del>-    themeWindowHasKeyAppearance = !(states &amp; WindowInactiveState);
</del><ins>+    themeWindowHasKeyAppearance = !(controlStates-&gt;states() &amp; ControlStates::WindowInactiveState);
</ins><span class="cx"> 
</span><span class="cx">     return themeView;
</span><span class="cx"> }
</span><span class="lines">@@ -689,14 +759,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect&amp; zoomedRect, float zoomFactor) const
</del><ins>+void ThemeMac::inflateControlPaintRect(ControlPart part, const ControlStates* states, IntRect&amp; zoomedRect, float zoomFactor) const
</ins><span class="cx"> {
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS
</span><span class="cx">     switch (part) {
</span><span class="cx">         case CheckboxPart: {
</span><span class="cx">             // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
</span><span class="cx">             // shadow&quot; and the check.  We don't consider this part of the bounds of the control in WebKit.
</span><del>-            NSCell *cell = checkbox(states, zoomedRect, zoomFactor);
</del><ins>+            NSCell *cell = sharedCheckboxCell(states, zoomedRect, zoomFactor);
</ins><span class="cx">             NSControlSize controlSize = [cell controlSize];
</span><span class="cx">             IntSize zoomedSize = checkboxSizes()[controlSize];
</span><span class="cx">             zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
</span><span class="lines">@@ -745,7 +815,7 @@
</span><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView) const
</del><ins>+void ThemeMac::paint(ControlPart part, ControlStates* states, GraphicsContext* context, const IntRect&amp; zoomedRect, float zoomFactor, ScrollView* scrollView)
</ins><span class="cx"> {
</span><span class="cx">     switch (part) {
</span><span class="cx">         case CheckboxPart:
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx">     , m_minPreferredLogicalWidth(-1)
</span><span class="cx">     , m_maxPreferredLogicalWidth(-1)
</span><span class="cx">     , m_inlineBoxWrapper(0)
</span><ins>+    , m_repaintTimer(this, &amp;RenderBox::repaintTimerFired)
</ins><span class="cx"> {
</span><span class="cx">     setIsBox();
</span><span class="cx"> }
</span><span class="lines">@@ -111,12 +112,16 @@
</span><span class="cx">     , m_minPreferredLogicalWidth(-1)
</span><span class="cx">     , m_maxPreferredLogicalWidth(-1)
</span><span class="cx">     , m_inlineBoxWrapper(0)
</span><ins>+    , m_repaintTimer(this, &amp;RenderBox::repaintTimerFired)
</ins><span class="cx"> {
</span><span class="cx">     setIsBox();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RenderBox::~RenderBox()
</span><span class="cx"> {
</span><ins>+    m_repaintTimer.stop();
+    if (hasControlStatesForRenderer(this))
+        removeControlStatesForRenderer(this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RenderRegion* RenderBox::clampToStartAndEndRegions(RenderRegion* region) const
</span><span class="lines">@@ -1221,7 +1226,22 @@
</span><span class="cx">     // If we have a native theme appearance, paint that before painting our background.
</span><span class="cx">     // The theme will tell us whether or not we should also paint the CSS background.
</span><span class="cx">     IntRect snappedPaintRect(pixelSnappedIntRect(paintRect));
</span><del>-    bool themePainted = style().hasAppearance() &amp;&amp; !theme().paint(this, paintInfo, snappedPaintRect);
</del><ins>+
+    ControlStates* controlStates = nullptr;
+    if (style().hasAppearance()) {
+        if (hasControlStatesForRenderer(this))
+            controlStates = controlStatesForRenderer(this);
+        else {
+            controlStates = new ControlStates();
+            addControlStatesForRenderer(this, controlStates);
+        }
+    }
+
+    bool themePainted = style().hasAppearance() &amp;&amp; !theme().paint(this, controlStates, paintInfo, snappedPaintRect);
+
+    if (controlStates &amp;&amp; controlStates-&gt;needsRepaint())
+        m_repaintTimer.startOneShot(0);
+
</ins><span class="cx">     if (!themePainted) {
</span><span class="cx">         if (bleedAvoidance == BackgroundBleedBackgroundOverBorder)
</span><span class="cx">             paintBorder(paintInfo, paintRect, style(), bleedAvoidance);
</span><span class="lines">@@ -4729,4 +4749,10 @@
</span><span class="cx">     return containerBlock-&gt;offsetFromLogicalTopOfFirstPage() + logicalTop();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RenderBox::repaintTimerFired(Timer&lt;RenderBox&gt;&amp;)
+{
+    if (!document().inPageCache())
+        this-&gt;repaint();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderBox.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -721,8 +721,12 @@
</span><span class="cx">     RefPtr&lt;RenderOverflow&gt; m_overflow;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    void repaintTimerFired(Timer&lt;RenderBox&gt;&amp;);
+
</ins><span class="cx">     // Used to store state between styleWillChange and styleDidChange
</span><span class="cx">     static bool s_hadOverflowClip;
</span><ins>+
+    Timer&lt;RenderBox&gt; m_repaintTimer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> RENDER_OBJECT_TYPE_CASTS(RenderBox, isBox())
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include &quot;AXObjectCache.h&quot;
</span><span class="cx"> #include &quot;AnimationController.h&quot;
</span><span class="cx"> #include &quot;ContentData.h&quot;
</span><ins>+#include &quot;ControlStates.h&quot;
</ins><span class="cx"> #include &quot;CursorList.h&quot;
</span><span class="cx"> #include &quot;EventHandler.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="lines">@@ -66,7 +67,13 @@
</span><span class="cx"> 
</span><span class="cx"> bool RenderElement::s_affectsParentBlock = false;
</span><span class="cx"> bool RenderElement::s_noLongerAffectsParentBlock = false;
</span><del>-
</del><ins>+    
+static HashMap&lt;const RenderObject*, ControlStates*&gt;&amp; controlStatesRendererMap()
+{
+    static NeverDestroyed&lt;HashMap&lt;const RenderObject*, ControlStates*&gt;&gt; map;
+    return map;
+}
+    
</ins><span class="cx"> RenderElement::RenderElement(Element&amp; element, PassRef&lt;RenderStyle&gt; style, unsigned baseTypeFlags)
</span><span class="cx">     : RenderObject(element)
</span><span class="cx">     , m_baseTypeFlags(baseTypeFlags)
</span><span class="lines">@@ -1338,4 +1345,28 @@
</span><span class="cx">     return renderer &amp;&amp; renderer-&gt;isRenderNamedFlowThread() ? toRenderNamedFlowThread(renderer) : nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool RenderElement::hasControlStatesForRenderer(const RenderObject* o)
+{
+    return controlStatesRendererMap().contains(o);
</ins><span class="cx"> }
</span><ins>+
+ControlStates* RenderElement::controlStatesForRenderer(const RenderObject* o)
+{
+    return controlStatesRendererMap().get(o);
+}
+
+void RenderElement::removeControlStatesForRenderer(const RenderObject* o)
+{
+    ControlStates* states = controlStatesRendererMap().get(o);
+    if (states) {
+        controlStatesRendererMap().remove(o);
+        delete states;
+    }
+}
+
+void RenderElement::addControlStatesForRenderer(const RenderObject* o, ControlStates* states)
+{
+    controlStatesRendererMap().add(o, states);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderElement.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class ControlStates;
+
</ins><span class="cx"> class RenderElement : public RenderObject {
</span><span class="cx"> public:
</span><span class="cx">     virtual ~RenderElement();
</span><span class="lines">@@ -182,6 +184,11 @@
</span><span class="cx">     void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; }
</span><span class="cx">     bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; }
</span><span class="cx"> 
</span><ins>+    static bool hasControlStatesForRenderer(const RenderObject*);
+    static ControlStates* controlStatesForRenderer(const RenderObject*);
+    static void removeControlStatesForRenderer(const RenderObject*);
+    static void addControlStatesForRenderer(const RenderObject*, ControlStates*);
+
</ins><span class="cx"> private:
</span><span class="cx">     void node() const = delete;
</span><span class="cx">     void nonPseudoNode() const = delete;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTheme.cpp (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTheme.cpp        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderTheme.cpp        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> #include &quot;RenderTheme.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSValueKeywords.h&quot;
</span><ins>+#include &quot;ControlStates.h&quot;
</ins><span class="cx"> #include &quot;Document.h&quot;
</span><span class="cx"> #include &quot;FileList.h&quot;
</span><span class="cx"> #include &quot;FileSystem.h&quot;
</span><span class="lines">@@ -262,7 +263,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RenderTheme::paint(RenderObject* o, const PaintInfo&amp; paintInfo, const IntRect&amp; r)
</del><ins>+bool RenderTheme::paint(RenderObject* o, ControlStates* controlStates, const PaintInfo&amp; paintInfo, const IntRect&amp; r)
</ins><span class="cx"> {
</span><span class="cx">     // If painting is disabled, but we aren't updating control tints, then just bail.
</span><span class="cx">     // If we are updating control tints, just schedule a repaint if the theme supports tinting
</span><span class="lines">@@ -286,7 +287,8 @@
</span><span class="cx">     case DefaultButtonPart:
</span><span class="cx">     case ButtonPart:
</span><span class="cx">     case InnerSpinButtonPart:
</span><del>-        m_theme-&gt;paint(part, controlStatesForRenderer(o), const_cast&lt;GraphicsContext*&gt;(paintInfo.context), r, o-&gt;style().effectiveZoom(), &amp;o-&gt;view().frameView());
</del><ins>+        updateControlStatesForRenderer(o, controlStates);
+        m_theme-&gt;paint(part, controlStates, const_cast&lt;GraphicsContext*&gt;(paintInfo.context), r, o-&gt;style().effectiveZoom(), &amp;o-&gt;view().frameView());
</ins><span class="cx">         return false;
</span><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="lines">@@ -713,7 +715,8 @@
</span><span class="cx"> void RenderTheme::adjustRepaintRect(const RenderObject* o, IntRect&amp; r)
</span><span class="cx"> {
</span><span class="cx"> #if USE(NEW_THEME)
</span><del>-    m_theme-&gt;inflateControlPaintRect(o-&gt;style().appearance(), controlStatesForRenderer(o), r, o-&gt;style().effectiveZoom());
</del><ins>+    ControlStates states(extractControlStatesForRenderer(o));
+    m_theme-&gt;inflateControlPaintRect(o-&gt;style().appearance(), &amp;states, r, o-&gt;style().effectiveZoom());
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(o);
</span><span class="cx">     UNUSED_PARAM(r);
</span><span class="lines">@@ -725,14 +728,14 @@
</span><span class="cx">     return (style-&gt;hasAppearance() &amp;&amp; style-&gt;appearance() != TextFieldPart &amp;&amp; style-&gt;appearance() != TextAreaPart &amp;&amp; style-&gt;appearance() != MenulistButtonPart &amp;&amp; style-&gt;appearance() != ListboxPart);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
</del><ins>+bool RenderTheme::stateChanged(RenderObject* o, ControlStates::States state) const
</ins><span class="cx"> {
</span><span class="cx">     // Default implementation assumes the controls don't respond to changes in :hover state
</span><del>-    if (state == HoverState &amp;&amp; !supportsHover(&amp;o-&gt;style()))
</del><ins>+    if (state == ControlStates::HoverState &amp;&amp; !supportsHover(&amp;o-&gt;style()))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Assume pressed state is only responded to if the control is enabled.
</span><del>-    if (state == PressedState &amp;&amp; !isEnabled(o))
</del><ins>+    if (state == ControlStates::PressedState &amp;&amp; !isEnabled(o))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Repaint the control.
</span><span class="lines">@@ -740,34 +743,40 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
</del><ins>+void RenderTheme::updateControlStatesForRenderer(const RenderObject* o, ControlStates* controlStates) const
</ins><span class="cx"> {
</span><del>-    ControlStates result = 0;
</del><ins>+    ControlStates newStates = extractControlStatesForRenderer(o);
+    controlStates-&gt;setStates(newStates.states());
+}
+
+ControlStates::States RenderTheme::extractControlStatesForRenderer(const RenderObject* o) const
+{
+    ControlStates::States states = 0;
</ins><span class="cx">     if (isHovered(o)) {
</span><del>-        result |= HoverState;
</del><ins>+        states |= ControlStates::HoverState;
</ins><span class="cx">         if (isSpinUpButtonPartHovered(o))
</span><del>-            result |= SpinUpState;
</del><ins>+            states |= ControlStates::SpinUpState;
</ins><span class="cx">     }
</span><span class="cx">     if (isPressed(o)) {
</span><del>-        result |= PressedState;
</del><ins>+        states |= ControlStates::PressedState;
</ins><span class="cx">         if (isSpinUpButtonPartPressed(o))
</span><del>-            result |= SpinUpState;
</del><ins>+            states |= ControlStates::SpinUpState;
</ins><span class="cx">     }
</span><span class="cx">     if (isFocused(o) &amp;&amp; o-&gt;style().outlineStyleIsAuto())
</span><del>-        result |= FocusState;
</del><ins>+        states |= ControlStates::FocusState;
</ins><span class="cx">     if (isEnabled(o))
</span><del>-        result |= EnabledState;
</del><ins>+        states |= ControlStates::EnabledState;
</ins><span class="cx">     if (isChecked(o))
</span><del>-        result |= CheckedState;
</del><ins>+        states |= ControlStates::CheckedState;
</ins><span class="cx">     if (isReadOnlyControl(o))
</span><del>-        result |= ReadOnlyState;
</del><ins>+        states |= ControlStates::ReadOnlyState;
</ins><span class="cx">     if (isDefault(o))
</span><del>-        result |= DefaultState;
</del><ins>+        states |= ControlStates::DefaultState;
</ins><span class="cx">     if (!isActive(o))
</span><del>-        result |= WindowInactiveState;
</del><ins>+        states |= ControlStates::WindowInactiveState;
</ins><span class="cx">     if (isIndeterminate(o))
</span><del>-        result |= IndeterminateState;
-    return result;
</del><ins>+        states |= ControlStates::IndeterminateState;
+    return states;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderTheme::isActive(const RenderObject* o) const
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTheme.h (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTheme.h        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderTheme.h        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> #ifndef RenderTheme_h
</span><span class="cx"> #define RenderTheme_h
</span><span class="cx"> 
</span><ins>+#include &quot;ControlStates.h&quot;
</ins><span class="cx"> #if USE(NEW_THEME)
</span><span class="cx"> #include &quot;Theme.h&quot;
</span><span class="cx"> #else
</span><span class="lines">@@ -78,7 +79,7 @@
</span><span class="cx">     // This method is called to paint the widget as a background of the RenderObject.  A widget's foreground, e.g., the
</span><span class="cx">     // text of a button, is always rendered by the engine itself.  The boolean return value indicates
</span><span class="cx">     // whether the CSS border/background should also be painted.
</span><del>-    bool paint(RenderObject*, const PaintInfo&amp;, const IntRect&amp;);
</del><ins>+    bool paint(RenderObject*, ControlStates*, const PaintInfo&amp;, const IntRect&amp;);
</ins><span class="cx">     bool paintBorderOnly(RenderObject*, const PaintInfo&amp;, const IntRect&amp;);
</span><span class="cx">     bool paintDecorations(RenderObject*, const PaintInfo&amp;, const IntRect&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -126,7 +127,7 @@
</span><span class="cx"> 
</span><span class="cx">     // This method is called whenever a relevant state changes on a particular themed object, e.g., the mouse becomes pressed
</span><span class="cx">     // or a control becomes disabled.
</span><del>-    virtual bool stateChanged(RenderObject*, ControlState) const;
</del><ins>+    virtual bool stateChanged(RenderObject*, ControlStates::States) const;
</ins><span class="cx"> 
</span><span class="cx">     // This method is called whenever the theme changes on the system in order to flush cached resources from the
</span><span class="cx">     // old theme.
</span><span class="lines">@@ -369,8 +370,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    // Methods for state querying
-    ControlStates controlStatesForRenderer(const RenderObject* o) const;
</del><ins>+    void updateControlStatesForRenderer(const RenderObject*, ControlStates*) const;
+    ControlStates::States extractControlStatesForRenderer(const RenderObject*) const;
</ins><span class="cx">     bool isActive(const RenderObject*) const;
</span><span class="cx">     bool isChecked(const RenderObject*) const;
</span><span class="cx">     bool isIndeterminate(const RenderObject*) const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeMac.mm (166421 => 166422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeMac.mm        2014-03-28 19:11:18 UTC (rev 166421)
+++ trunk/Source/WebCore/rendering/RenderThemeMac.mm        2014-03-28 19:57:34 UTC (rev 166422)
</span><span class="lines">@@ -212,7 +212,8 @@
</span><span class="cx"> 
</span><span class="cx"> NSView* RenderThemeMac::documentViewFor(RenderObject* o) const
</span><span class="cx"> {
</span><del>-    return ThemeMac::ensuredView(&amp;o-&gt;view().frameView(), controlStatesForRenderer(o));
</del><ins>+    ControlStates states(extractControlStatesForRenderer(o));
+    return ThemeMac::ensuredView(&amp;o-&gt;view().frameView(), &amp;states);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO)
</span></span></pre>
</div>
</div>

</body>
</html>