<!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>[160236] 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/160236">160236</a></dd>
<dt>Author</dt> <dd>dbates@webkit.org</dd>
<dt>Date</dt> <dd>2013-12-06 11:59:38 -0800 (Fri, 06 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>[iOS] Upstream WebCore/rendering changes
https://bugs.webkit.org/show_bug.cgi?id=125239
Reviewed by Simon Fraser.
* WebCore.xcodeproj/project.pbxproj:
* rendering/InlineBox.cpp:
(WebCore::InlineBox::previousOnLineExists): Added.
* rendering/InlineBox.h:
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintCompositionBackground): Modified to query RenderStyle
on iOS for the composition fill color. Added FIXME to make this platform-independent.
(WebCore::InlineTextBox::paintDecoration): Added iOS-specific decoration code.
(WebCore::lineStyleForMarkerType):
(WebCore::InlineTextBox::paintDocumentMarkers): Added iOS-specific code. Also, added
FIXME to make this code platform-independent.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paint): Ditto.
(WebCore::positionForPointRespectingEditingBoundaries): Added iOS-specific code.
* rendering/RenderBlock.h: Changed access control of logical{Left, Right}SelectionOffset()
from private to protected so that these methods can be used from RenderImage::collectSelectionRects().
* rendering/RenderBox.cpp:
(WebCore::RenderBox::borderRadii): Added.
(WebCore::RenderBox::paintBoxDecorations): Added iOS-specific workaround. See <rdar://problem/6209763>
for more details.
(WebCore::RenderBox::computeRectForRepaint): Added iOS-specific code.
(WebCore::customContainingBlockWidth): Added; guarded by PLATFORM(IOS).
(WebCore::customContainingBlockHeight): Added; guarded by PLATFORM(IOS).
(WebCore::customContainingBlockLogicalWidth): Added; guarded by PLATFORM(IOS).
(WebCore::customContainingBlockLogicalHeight): Added; guarded by PLATFORM(IOS).
(WebCore::customContainingBlockAvailableLogicalHeight): Added; guarded by PLATFORM(IOS).
(WebCore::RenderBox::availableLogicalHeightUsing): Added iOS-specific code; calls customContainingBlockAvailableLogicalHeight().
(WebCore::RenderBox::containingBlockLogicalWidthForPositioned): Added iOS-specific code; calls customContainingBlockLogicalWidth().
(WebCore::RenderBox::containingBlockLogicalHeightForPositioned): Added iOS-specific code; calls customContainingBlockLogicalHeight().
(WebCore::RenderBox::layoutOverflowRectForPropagation): Added iOS-specific code.
* rendering/RenderBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::stickyPositionOffset): Use FrameView::customFixedPositionLayoutRect()
instead of FrameView::viewportConstrainedVisibleContentRect().
* rendering/RenderButton.cpp:
(WebCore::RenderButton::layout): Added; iOS-specific. Includes FIXME comment.
See <rdar://problem/7675493> for more details.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::styleWillChange): Added iOS-specific code.
(WebCore::RenderElement::styleDidChange): Modified to only call areCursorsEqual() and
EventHandler::scheduleCursorUpdate() on a non-iOS port.
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::allowsAcceleratedCompositing): Added iOS-specific code.
(WebCore::RenderEmbeddedObject::setPluginUnavailabilityReason): This method has an empty implementation for iOS.
(WebCore::RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription): Ditto.
* rendering/RenderFileUploadControl.cpp:
(WebCore::nodeHeight):
(WebCore::RenderFileUploadControl::maxFilenameWidth): Added iOS-specific code.
(WebCore::RenderFileUploadControl::paintObject): Ditto.
(WebCore::RenderFileUploadControl::fileTextValue): Ditto.
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::positionFrames): Ditto; Also added FIXME comment as this code may not
be specific to iOS.
* rendering/RenderIFrame.h: Added iOS-specific workaround to RenderObject::renderName(). Added
FIXME comment to determine whether this workaround is still applicable.
* rendering/RenderImage.cpp:
(WebCore::RenderImage::collectSelectionRects): Added; guarded by PLATFORM(IOS).
(WebCore::RenderImage::paintAreaElementFocusRing): This method has an empty implementation for iOS.
* rendering/RenderImage.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::absoluteQuadsForSelection): Added; guarded by PLATFORM(IOS).
* rendering/RenderInline.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer): Added iOS-specific member initialization.
(WebCore::RenderLayer::~RenderLayer): Added iOS-specific code.
(WebCore::RenderLayer::willBeDestroyed): Added; iOS-specific.
(WebCore::RenderLayer::hasAcceleratedTouchScrolling): Ditto.
(WebCore::RenderLayer::handleTouchEvent): Ditto.
(WebCore::RenderLayer::registerAsTouchEventListenerForScrolling): Ditto.
(WebCore::RenderLayer::unregisterAsTouchEventListenerForScrolling): Ditto.
(WebCore::RenderLayer::updateNeedsCompositedScrolling): Added iOS-specific code as we use UIKit
to composite our scroll bars.
(WebCore::RenderLayer::scrollTo): Added iOS-specific code.
(WebCore::RenderLayer::scrollRectToVisible): Ditto.
(WebCore::RenderLayer::styleChanged): Modified to make use of the passed StyleDifference on iOS.
(WebCore::RenderLayer::visibleContentRect): Added; iOS-specific.
(WebCore::RenderLayer::didStartScroll): Ditto.
(WebCore::RenderLayer::didEndScroll): Ditto.
(WebCore::RenderLayer::didUpdateScroll): Ditto.
(WebCore::RenderLayer::invalidateScrollbarRect): Added iOS-specific code.
(WebCore::RenderLayer::invalidateScrollCornerRect): Ditto.
(WebCore::RenderLayer::verticalScrollbarWidth): Ditto.
(WebCore::RenderLayer::horizontalScrollbarHeight): Ditto.
(WebCore::RenderLayer::updateScrollableAreaSet): Ditto.
(WebCore::RenderLayer::updateScrollInfoAfterLayout): Add iOS-specific workaround with FIXME. See
<rdar://problem/15579797> for more details.
(WebCore::RenderLayer::paintOverflowControls): Added iOS-specific code.
(WebCore::RenderLayer::calculateClipRects): Ditto.
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::createPrimaryGraphicsLayer): Modified to not apply page scale on iOS
as we apply a page scale at a different time in the code.
(WebCore::RenderLayerBacking::layerWillBeDestroyed): Added; guarded by PLATFORM(IOS).
(WebCore::layerOrAncestorIsTransformedOrScrolling): Added iOS-specific variant with FIXME comment.
(WebCore::RenderLayerBacking::shouldClipCompositedBounds): Added iOS-specific code.
(WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Ditto.
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Ditto.
(WebCore::RenderLayerBacking::registerScrollingLayers): Ditto.
(WebCore::RenderLayerBacking::updateScrollingLayers): Ditto.
(WebCore::RenderLayerBacking::containsPaintedContent): Call RenderLayer::hasBoxDecorationsOrBackground()
when building on iOS Simulator.
(WebCore::RenderLayerBacking::parentForSublayers): Added iOS-specific code and FIXME comment.
(WebCore::RenderLayerBacking::paintsIntoWindow): Opt-into coordinated graphics code path.
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect): Added iOS-specific code.
(WebCore::RenderLayerBacking::paintIntoLayer): Compile-out ASSERT_NOT_REACHED for iOS and added FIXME comment.
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::scheduleLayerFlush): Added iOS-specific code.
(WebCore::RenderLayerCompositor::chromeClient): Added; guarded by PLATFORM(IOS).
(WebCore::RenderLayerCompositor::flushPendingLayerChanges): Added iOS-specific code.
(WebCore::scrollbarHasDisplayNone): Added; iOS-specific.
(WebCore::updateScrollingLayerWithClient): Ditto.
(WebCore::RenderLayerCompositor::updateCustomLayersAfterFlush): Ditto.
(WebCore::RenderLayerCompositor::didFlushChangesForLayer): Added iOS-specific code.
(WebCore::RenderLayerCompositor::didChangeVisibleRect): Ditto.
(WebCore::RenderLayerCompositor::addToOverlapMap): Don't apply page scale factor on iOS. We apply
the page scale factor at a different time in the code. Also, added FIXME comment.
(WebCore::RenderLayerCompositor::computeCompositingRequirements): Added iOS-specific workaround.
See <rdar://problem/8348337> for more details.
(WebCore::RenderLayerCompositor::setIsInWindow): Use non-Mac code path for iOS.
(WebCore::RenderLayerCompositor::allowsIndependentlyCompositedFrames): Added iOS-specific code.
(WebCore::RenderLayerCompositor::requiresCompositingLayer): Ditto.
(WebCore::RenderLayerCompositor::requiresOwnBackingStore): Ditto.
(WebCore::RenderLayerCompositor::reasonsForCompositing): Ditto.
(WebCore::RenderLayerCompositor::requiresCompositingForAnimation): Opt-into calling
AnimationController::isRunningAnimationOnRenderer() on iOS.
(WebCore::RenderLayerCompositor::requiresCompositingForScrolling): Added; guarded by PLATFORM(IOS).
(WebCore::isStickyInAcceleratedScrollingLayerOrViewport): Added iOS-specific code.
(WebCore::isViewportConstrainedFixedOrStickyLayer): Ditto.
(WebCore::RenderLayerCompositor::requiresCompositingForPosition): Use FrameView::customFixedPositionLayoutRect()
instead of FrameView::viewportConstrainedVisibleContentRect().
(WebCore::RenderLayerCompositor::contentsScaleMultiplierForNewTiles): Ditto.
(WebCore::RenderLayerCompositor::ensureRootLayer): Ditto.
(WebCore::RenderLayerCompositor::computeFixedViewportConstraints): Use FrameView::customFixedPositionLayoutRect()
instead of FrameView::viewportConstrainedVisibleContentRect().
(WebCore::RenderLayerCompositor::computeStickyViewportConstraints): Ditto.
(WebCore::RenderLayerCompositor::registerOrUpdateViewportConstrainedLayer): This method has an empty implementation for iOS
as we batch update viewport-constrained layers in the iOS-specific method, RenderLayerCompositor::updateCustomLayersAfterFlush().
(WebCore::RenderLayerCompositor::unregisterViewportConstrainedLayer): Ditto.
(WebCore::RenderLayerCompositor::registerAllViewportConstrainedLayers): Added; guarded by PLATFORM(IOS).
(WebCore::RenderLayerCompositor::unregisterAllViewportConstrainedLayers): Ditto.
(WebCore::RenderLayerCompositor::registerAllScrollingLayers): Ditto.
(WebCore::RenderLayerCompositor::unregisterAllScrollingLayers): Ditto.
(WebCore::RenderLayerCompositor::scrollingLayerAddedOrUpdated): Ditto.
(WebCore::RenderLayerCompositor::scrollingLayerRemoved): Ditto.
(WebCore::RenderLayerCompositor::startInitialLayerFlushTimerIfNeeded): Ditto.
* rendering/RenderLayerCompositor.h:
* rendering/RenderLayerFilterInfo.h: Added iOS-specific Clang workaround to ignore
an unused private field.
* rendering/RenderMenuList.cpp:
(WebCore::selectedOptionCount): Added; guarded by PLATFORM(IOS).
(WebCore::RenderMenuList::RenderMenuList): On iOS we don't make use of RenderMenuList::m_popupIsVisible.
(WebCore::RenderMenuList::~RenderMenuList): On iOS we don't make use of RenderMenuList::m_popup.
(WebCore::RenderMenuList::adjustInnerStyle): Add iOS-specific code.
(RenderMenuList::updateFromElement): On iOS we don't make use of RenderMenuList::m_popup.
(RenderMenuList::setTextFromOption): Add iOS-specific code.
(RenderMenuList::showPopup): Define RenderMenuList::showPopup() to ASSERT_NOT_REACHED() on iOS as
we don't make use of RenderMenuList::m_popup.
(RenderMenuList::hidePopup): This method has an empty implementation for iOS as we don't make use
of RenderMenuList::m_popup.
(RenderMenuList::popupDidHide): This method has an empty implementation for iOS as we don't make use
of RenderMenuList::m_popupIsVisible.
* rendering/RenderMenuList.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::columnNumberForOffset): Added; guarded by PLATFORM(IOS). Also, added a FIXME comment to
make this function return an unsigned integer instead of a signed integer.
(WebCore::RenderObject::collectSelectionRects): Added; guarded by PLATFORM(IOS).
(WebCore::RenderObject::destroy): Added iOS-specific code.
(WebCore::RenderObject::innerLineHeight): Added.
(WebCore::RenderObject::willRenderImage): Added iOS-specific code.
* rendering/RenderObject.h: Change the access control of RenderObject::drawLineForBoxSide() from protected to
public so that it can be used from RenderThemeIOS::adjustMenuListButtonStyle().
(WebCore::RenderObject::absoluteQuadsForSelection):
* rendering/RenderScrollbar.h: Change the access control of RenderScrollbar::getScrollbarPseudoStyle() from
private to public so that it can be used from the iOS-specific static function, scrollbarHasDisplayNone,
defined in RenderLayerCompositor.cpp.
* rendering/RenderSearchField.cpp:
(WebCore::RenderSearchField::itemText): Added iOS-specific code.
* rendering/RenderText.cpp:
(WebCore::RenderText::collectSelectionRects): Added; guarded by PLATFORM(IOS).
(WebCore::RenderText::setTextInternal): Added iOS-specific code.
* rendering/RenderText.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::adjustInnerTextStyle): Ditto.
(WebCore::RenderTextControl::canScroll): Added; guarded by PLATFORM(IOS).
(WebCore::RenderTextControl::innerLineHeight): Ditto.
* rendering/RenderTextControl.h:
* rendering/RenderTextControlMultiLine.cpp:
(WebCore::RenderTextControlMultiLine::getAvgCharWidth): Compile-out code when building for iOS.
(WebCore::RenderTextControlMultiLine::createInnerTextStyle): Added iOS-specific code.
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::layout): Ditto.
(WebCore::RenderTextControlSingleLine::getAvgCharWidth): Compile-out code when building for iOS.
(WebCore::RenderTextControlSingleLine::preferredContentLogicalWidth): Ditto.
* rendering/RenderTextLineBoxes.cpp:
(WebCore::lineDirectionPointFitsInBox): Ditto.
(WebCore::RenderTextLineBoxes::positionForPoint): Added iOS-specific code.
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::paintBorderOnly): Ditto.
(WebCore::RenderTheme::paintDecorations): Modified to call the control-specific paint*Decorations().
* rendering/RenderTheme.h:
(WebCore::RenderTheme::paintCheckboxDecorations): Added.
(WebCore::RenderTheme::paintRadioDecorations): Added.
(WebCore::RenderTheme::paintButtonDecorations): Added.
(WebCore::RenderTheme::paintTextFieldDecorations): Added.
(WebCore::RenderTheme::paintTextAreaDecorations): Added.
(WebCore::RenderTheme::paintMenuListDecorations): Added.
(WebCore::RenderTheme::paintPushButtonDecorations): Added.
(WebCore::RenderTheme::paintSquareButtonDecorations): Added.
(WebCore::RenderTheme::paintFileUploadIconDecorations): Added.
(WebCore::RenderTheme::paintSliderThumbDecorations): Added.
(WebCore::RenderTheme::paintSearchFieldDecorations): Added.
* rendering/RenderThemeIOS.h: Added.
* rendering/RenderThemeIOS.mm: Added.
* rendering/RenderThemeMac.h: Don't compile the contents of this file when building for iOS.
* rendering/RenderThemeMac.mm: Ditto.
* rendering/RenderVideo.cpp:
(WebCore::RenderVideo::calculateIntrinsicSize): Compile-out code when building for iOS.
* rendering/RenderView.cpp:
(WebCore::RenderView::availableLogicalHeight): Add iOS-specific workaround. See <rdar://problem/7166808>.
(WebCore::fixedPositionOffset): Added; used in iOS-specific code (e.g. RenderView::mapLocalToContainer()).
(WebCore::RenderView::mapLocalToContainer): Use WebCore::fixedPositionOffset() instead of
FrameView::scrollOffsetForFixedPosition().
(WebCore::RenderView::pushMappingToContainer): Ditto.
(WebCore::RenderView::mapAbsoluteToLocalPoint): Ditto.
(WebCore::RenderView::repaintViewRectangle): Ditto.
(WebCore::RenderView::computeRectForRepaint): Ditto.
(WebCore::isFixedPositionInViewport): Added; used in RenderView::hasCustomFixedPosition().
(WebCore::RenderView::hasCustomFixedPosition): Added; guarded by PLATFORM(IOS).
* rendering/RenderView.h:
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::willBeDestroyed): Added iOS-specific code.
* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::ascentAndDescentForBox): Ditto.
* rendering/break_lines.cpp: Only include header <CoreServices/CoreServices.h> when building for Mac.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineBoxcpp">trunk/Source/WebCore/rendering/InlineBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineBoxh">trunk/Source/WebCore/rendering/InlineBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineTextBoxcpp">trunk/Source/WebCore/rendering/InlineTextBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockcpp">trunk/Source/WebCore/rendering/RenderBlock.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockh">trunk/Source/WebCore/rendering/RenderBlock.h</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="#trunkSourceWebCorerenderingRenderBoxModelObjectcpp">trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderButtoncpp">trunk/Source/WebCore/rendering/RenderButton.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementcpp">trunk/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderEmbeddedObjectcpp">trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderFileUploadControlcpp">trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderFrameSetcpp">trunk/Source/WebCore/rendering/RenderFrameSet.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderIFrameh">trunk/Source/WebCore/rendering/RenderIFrame.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderImagecpp">trunk/Source/WebCore/rendering/RenderImage.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderImageh">trunk/Source/WebCore/rendering/RenderImage.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderInlinecpp">trunk/Source/WebCore/rendering/RenderInline.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderInlineh">trunk/Source/WebCore/rendering/RenderInline.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerh">trunk/Source/WebCore/rendering/RenderLayer.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingh">trunk/Source/WebCore/rendering/RenderLayerBacking.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorcpp">trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorh">trunk/Source/WebCore/rendering/RenderLayerCompositor.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerFilterInfoh">trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMenuListcpp">trunk/Source/WebCore/rendering/RenderMenuList.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMenuListh">trunk/Source/WebCore/rendering/RenderMenuList.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjectcpp">trunk/Source/WebCore/rendering/RenderObject.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjecth">trunk/Source/WebCore/rendering/RenderObject.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderScrollbarh">trunk/Source/WebCore/rendering/RenderScrollbar.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderSearchFieldcpp">trunk/Source/WebCore/rendering/RenderSearchField.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextcpp">trunk/Source/WebCore/rendering/RenderText.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTexth">trunk/Source/WebCore/rendering/RenderText.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextControlcpp">trunk/Source/WebCore/rendering/RenderTextControl.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextControlh">trunk/Source/WebCore/rendering/RenderTextControl.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextControlMultiLinecpp">trunk/Source/WebCore/rendering/RenderTextControlMultiLine.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextControlSingleLinecpp">trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextLineBoxescpp">trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp</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="#trunkSourceWebCorerenderingRenderThemeMach">trunk/Source/WebCore/rendering/RenderThemeMac.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeMacmm">trunk/Source/WebCore/rendering/RenderThemeMac.mm</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderVideocpp">trunk/Source/WebCore/rendering/RenderVideo.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderViewcpp">trunk/Source/WebCore/rendering/RenderView.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderViewh">trunk/Source/WebCore/rendering/RenderView.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderWidgetcpp">trunk/Source/WebCore/rendering/RenderWidget.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRootInlineBoxcpp">trunk/Source/WebCore/rendering/RootInlineBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingbreak_linescpp">trunk/Source/WebCore/rendering/break_lines.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSh">trunk/Source/WebCore/rendering/RenderThemeIOS.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSmm">trunk/Source/WebCore/rendering/RenderThemeIOS.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/ChangeLog        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -1,3 +1,246 @@
</span><ins>+2013-12-06 Daniel Bates <dabates@apple.com>
+
+ [iOS] Upstream WebCore/rendering changes
+ https://bugs.webkit.org/show_bug.cgi?id=125239
+
+ Reviewed by Simon Fraser.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/InlineBox.cpp:
+ (WebCore::InlineBox::previousOnLineExists): Added.
+ * rendering/InlineBox.h:
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintCompositionBackground): Modified to query RenderStyle
+ on iOS for the composition fill color. Added FIXME to make this platform-independent.
+ (WebCore::InlineTextBox::paintDecoration): Added iOS-specific decoration code.
+ (WebCore::lineStyleForMarkerType):
+ (WebCore::InlineTextBox::paintDocumentMarkers): Added iOS-specific code. Also, added
+ FIXME to make this code platform-independent.
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paint): Ditto.
+ (WebCore::positionForPointRespectingEditingBoundaries): Added iOS-specific code.
+ * rendering/RenderBlock.h: Changed access control of logical{Left, Right}SelectionOffset()
+ from private to protected so that these methods can be used from RenderImage::collectSelectionRects().
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::borderRadii): Added.
+ (WebCore::RenderBox::paintBoxDecorations): Added iOS-specific workaround. See <rdar://problem/6209763>
+ for more details.
+ (WebCore::RenderBox::computeRectForRepaint): Added iOS-specific code.
+ (WebCore::customContainingBlockWidth): Added; guarded by PLATFORM(IOS).
+ (WebCore::customContainingBlockHeight): Added; guarded by PLATFORM(IOS).
+ (WebCore::customContainingBlockLogicalWidth): Added; guarded by PLATFORM(IOS).
+ (WebCore::customContainingBlockLogicalHeight): Added; guarded by PLATFORM(IOS).
+ (WebCore::customContainingBlockAvailableLogicalHeight): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderBox::availableLogicalHeightUsing): Added iOS-specific code; calls customContainingBlockAvailableLogicalHeight().
+ (WebCore::RenderBox::containingBlockLogicalWidthForPositioned): Added iOS-specific code; calls customContainingBlockLogicalWidth().
+ (WebCore::RenderBox::containingBlockLogicalHeightForPositioned): Added iOS-specific code; calls customContainingBlockLogicalHeight().
+ (WebCore::RenderBox::layoutOverflowRectForPropagation): Added iOS-specific code.
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::stickyPositionOffset): Use FrameView::customFixedPositionLayoutRect()
+ instead of FrameView::viewportConstrainedVisibleContentRect().
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::layout): Added; iOS-specific. Includes FIXME comment.
+ See <rdar://problem/7675493> for more details.
+ * rendering/RenderElement.cpp:
+ (WebCore::RenderElement::styleWillChange): Added iOS-specific code.
+ (WebCore::RenderElement::styleDidChange): Modified to only call areCursorsEqual() and
+ EventHandler::scheduleCursorUpdate() on a non-iOS port.
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::allowsAcceleratedCompositing): Added iOS-specific code.
+ (WebCore::RenderEmbeddedObject::setPluginUnavailabilityReason): This method has an empty implementation for iOS.
+ (WebCore::RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription): Ditto.
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::nodeHeight):
+ (WebCore::RenderFileUploadControl::maxFilenameWidth): Added iOS-specific code.
+ (WebCore::RenderFileUploadControl::paintObject): Ditto.
+ (WebCore::RenderFileUploadControl::fileTextValue): Ditto.
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::positionFrames): Ditto; Also added FIXME comment as this code may not
+ be specific to iOS.
+ * rendering/RenderIFrame.h: Added iOS-specific workaround to RenderObject::renderName(). Added
+ FIXME comment to determine whether this workaround is still applicable.
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::collectSelectionRects): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderImage::paintAreaElementFocusRing): This method has an empty implementation for iOS.
+ * rendering/RenderImage.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::absoluteQuadsForSelection): Added; guarded by PLATFORM(IOS).
+ * rendering/RenderInline.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer): Added iOS-specific member initialization.
+ (WebCore::RenderLayer::~RenderLayer): Added iOS-specific code.
+ (WebCore::RenderLayer::willBeDestroyed): Added; iOS-specific.
+ (WebCore::RenderLayer::hasAcceleratedTouchScrolling): Ditto.
+ (WebCore::RenderLayer::handleTouchEvent): Ditto.
+ (WebCore::RenderLayer::registerAsTouchEventListenerForScrolling): Ditto.
+ (WebCore::RenderLayer::unregisterAsTouchEventListenerForScrolling): Ditto.
+ (WebCore::RenderLayer::updateNeedsCompositedScrolling): Added iOS-specific code as we use UIKit
+ to composite our scroll bars.
+ (WebCore::RenderLayer::scrollTo): Added iOS-specific code.
+ (WebCore::RenderLayer::scrollRectToVisible): Ditto.
+ (WebCore::RenderLayer::styleChanged): Modified to make use of the passed StyleDifference on iOS.
+ (WebCore::RenderLayer::visibleContentRect): Added; iOS-specific.
+ (WebCore::RenderLayer::didStartScroll): Ditto.
+ (WebCore::RenderLayer::didEndScroll): Ditto.
+ (WebCore::RenderLayer::didUpdateScroll): Ditto.
+ (WebCore::RenderLayer::invalidateScrollbarRect): Added iOS-specific code.
+ (WebCore::RenderLayer::invalidateScrollCornerRect): Ditto.
+ (WebCore::RenderLayer::verticalScrollbarWidth): Ditto.
+ (WebCore::RenderLayer::horizontalScrollbarHeight): Ditto.
+ (WebCore::RenderLayer::updateScrollableAreaSet): Ditto.
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout): Add iOS-specific workaround with FIXME. See
+ <rdar://problem/15579797> for more details.
+ (WebCore::RenderLayer::paintOverflowControls): Added iOS-specific code.
+ (WebCore::RenderLayer::calculateClipRects): Ditto.
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::createPrimaryGraphicsLayer): Modified to not apply page scale on iOS
+ as we apply a page scale at a different time in the code.
+ (WebCore::RenderLayerBacking::layerWillBeDestroyed): Added; guarded by PLATFORM(IOS).
+ (WebCore::layerOrAncestorIsTransformedOrScrolling): Added iOS-specific variant with FIXME comment.
+ (WebCore::RenderLayerBacking::shouldClipCompositedBounds): Added iOS-specific code.
+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Ditto.
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Ditto.
+ (WebCore::RenderLayerBacking::registerScrollingLayers): Ditto.
+ (WebCore::RenderLayerBacking::updateScrollingLayers): Ditto.
+ (WebCore::RenderLayerBacking::containsPaintedContent): Call RenderLayer::hasBoxDecorationsOrBackground()
+ when building on iOS Simulator.
+ (WebCore::RenderLayerBacking::parentForSublayers): Added iOS-specific code and FIXME comment.
+ (WebCore::RenderLayerBacking::paintsIntoWindow): Opt-into coordinated graphics code path.
+ (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect): Added iOS-specific code.
+ (WebCore::RenderLayerBacking::paintIntoLayer): Compile-out ASSERT_NOT_REACHED for iOS and added FIXME comment.
+ * rendering/RenderLayerBacking.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::scheduleLayerFlush): Added iOS-specific code.
+ (WebCore::RenderLayerCompositor::chromeClient): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderLayerCompositor::flushPendingLayerChanges): Added iOS-specific code.
+ (WebCore::scrollbarHasDisplayNone): Added; iOS-specific.
+ (WebCore::updateScrollingLayerWithClient): Ditto.
+ (WebCore::RenderLayerCompositor::updateCustomLayersAfterFlush): Ditto.
+ (WebCore::RenderLayerCompositor::didFlushChangesForLayer): Added iOS-specific code.
+ (WebCore::RenderLayerCompositor::didChangeVisibleRect): Ditto.
+ (WebCore::RenderLayerCompositor::addToOverlapMap): Don't apply page scale factor on iOS. We apply
+ the page scale factor at a different time in the code. Also, added FIXME comment.
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements): Added iOS-specific workaround.
+ See <rdar://problem/8348337> for more details.
+ (WebCore::RenderLayerCompositor::setIsInWindow): Use non-Mac code path for iOS.
+ (WebCore::RenderLayerCompositor::allowsIndependentlyCompositedFrames): Added iOS-specific code.
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer): Ditto.
+ (WebCore::RenderLayerCompositor::requiresOwnBackingStore): Ditto.
+ (WebCore::RenderLayerCompositor::reasonsForCompositing): Ditto.
+ (WebCore::RenderLayerCompositor::requiresCompositingForAnimation): Opt-into calling
+ AnimationController::isRunningAnimationOnRenderer() on iOS.
+ (WebCore::RenderLayerCompositor::requiresCompositingForScrolling): Added; guarded by PLATFORM(IOS).
+ (WebCore::isStickyInAcceleratedScrollingLayerOrViewport): Added iOS-specific code.
+ (WebCore::isViewportConstrainedFixedOrStickyLayer): Ditto.
+ (WebCore::RenderLayerCompositor::requiresCompositingForPosition): Use FrameView::customFixedPositionLayoutRect()
+ instead of FrameView::viewportConstrainedVisibleContentRect().
+ (WebCore::RenderLayerCompositor::contentsScaleMultiplierForNewTiles): Ditto.
+ (WebCore::RenderLayerCompositor::ensureRootLayer): Ditto.
+ (WebCore::RenderLayerCompositor::computeFixedViewportConstraints): Use FrameView::customFixedPositionLayoutRect()
+ instead of FrameView::viewportConstrainedVisibleContentRect().
+ (WebCore::RenderLayerCompositor::computeStickyViewportConstraints): Ditto.
+ (WebCore::RenderLayerCompositor::registerOrUpdateViewportConstrainedLayer): This method has an empty implementation for iOS
+ as we batch update viewport-constrained layers in the iOS-specific method, RenderLayerCompositor::updateCustomLayersAfterFlush().
+ (WebCore::RenderLayerCompositor::unregisterViewportConstrainedLayer): Ditto.
+ (WebCore::RenderLayerCompositor::registerAllViewportConstrainedLayers): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderLayerCompositor::unregisterAllViewportConstrainedLayers): Ditto.
+ (WebCore::RenderLayerCompositor::registerAllScrollingLayers): Ditto.
+ (WebCore::RenderLayerCompositor::unregisterAllScrollingLayers): Ditto.
+ (WebCore::RenderLayerCompositor::scrollingLayerAddedOrUpdated): Ditto.
+ (WebCore::RenderLayerCompositor::scrollingLayerRemoved): Ditto.
+ (WebCore::RenderLayerCompositor::startInitialLayerFlushTimerIfNeeded): Ditto.
+ * rendering/RenderLayerCompositor.h:
+ * rendering/RenderLayerFilterInfo.h: Added iOS-specific Clang workaround to ignore
+ an unused private field.
+ * rendering/RenderMenuList.cpp:
+ (WebCore::selectedOptionCount): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderMenuList::RenderMenuList): On iOS we don't make use of RenderMenuList::m_popupIsVisible.
+ (WebCore::RenderMenuList::~RenderMenuList): On iOS we don't make use of RenderMenuList::m_popup.
+ (WebCore::RenderMenuList::adjustInnerStyle): Add iOS-specific code.
+ (RenderMenuList::updateFromElement): On iOS we don't make use of RenderMenuList::m_popup.
+ (RenderMenuList::setTextFromOption): Add iOS-specific code.
+ (RenderMenuList::showPopup): Define RenderMenuList::showPopup() to ASSERT_NOT_REACHED() on iOS as
+ we don't make use of RenderMenuList::m_popup.
+ (RenderMenuList::hidePopup): This method has an empty implementation for iOS as we don't make use
+ of RenderMenuList::m_popup.
+ (RenderMenuList::popupDidHide): This method has an empty implementation for iOS as we don't make use
+ of RenderMenuList::m_popupIsVisible.
+ * rendering/RenderMenuList.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::columnNumberForOffset): Added; guarded by PLATFORM(IOS). Also, added a FIXME comment to
+ make this function return an unsigned integer instead of a signed integer.
+ (WebCore::RenderObject::collectSelectionRects): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderObject::destroy): Added iOS-specific code.
+ (WebCore::RenderObject::innerLineHeight): Added.
+ (WebCore::RenderObject::willRenderImage): Added iOS-specific code.
+ * rendering/RenderObject.h: Change the access control of RenderObject::drawLineForBoxSide() from protected to
+ public so that it can be used from RenderThemeIOS::adjustMenuListButtonStyle().
+ (WebCore::RenderObject::absoluteQuadsForSelection):
+ * rendering/RenderScrollbar.h: Change the access control of RenderScrollbar::getScrollbarPseudoStyle() from
+ private to public so that it can be used from the iOS-specific static function, scrollbarHasDisplayNone,
+ defined in RenderLayerCompositor.cpp.
+ * rendering/RenderSearchField.cpp:
+ (WebCore::RenderSearchField::itemText): Added iOS-specific code.
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::collectSelectionRects): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderText::setTextInternal): Added iOS-specific code.
+ * rendering/RenderText.h:
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::adjustInnerTextStyle): Ditto.
+ (WebCore::RenderTextControl::canScroll): Added; guarded by PLATFORM(IOS).
+ (WebCore::RenderTextControl::innerLineHeight): Ditto.
+ * rendering/RenderTextControl.h:
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::getAvgCharWidth): Compile-out code when building for iOS.
+ (WebCore::RenderTextControlMultiLine::createInnerTextStyle): Added iOS-specific code.
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::layout): Ditto.
+ (WebCore::RenderTextControlSingleLine::getAvgCharWidth): Compile-out code when building for iOS.
+ (WebCore::RenderTextControlSingleLine::preferredContentLogicalWidth): Ditto.
+ * rendering/RenderTextLineBoxes.cpp:
+ (WebCore::lineDirectionPointFitsInBox): Ditto.
+ (WebCore::RenderTextLineBoxes::positionForPoint): Added iOS-specific code.
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::paintBorderOnly): Ditto.
+ (WebCore::RenderTheme::paintDecorations): Modified to call the control-specific paint*Decorations().
+ * rendering/RenderTheme.h:
+ (WebCore::RenderTheme::paintCheckboxDecorations): Added.
+ (WebCore::RenderTheme::paintRadioDecorations): Added.
+ (WebCore::RenderTheme::paintButtonDecorations): Added.
+ (WebCore::RenderTheme::paintTextFieldDecorations): Added.
+ (WebCore::RenderTheme::paintTextAreaDecorations): Added.
+ (WebCore::RenderTheme::paintMenuListDecorations): Added.
+ (WebCore::RenderTheme::paintPushButtonDecorations): Added.
+ (WebCore::RenderTheme::paintSquareButtonDecorations): Added.
+ (WebCore::RenderTheme::paintFileUploadIconDecorations): Added.
+ (WebCore::RenderTheme::paintSliderThumbDecorations): Added.
+ (WebCore::RenderTheme::paintSearchFieldDecorations): Added.
+ * rendering/RenderThemeIOS.h: Added.
+ * rendering/RenderThemeIOS.mm: Added.
+ * rendering/RenderThemeMac.h: Don't compile the contents of this file when building for iOS.
+ * rendering/RenderThemeMac.mm: Ditto.
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::calculateIntrinsicSize): Compile-out code when building for iOS.
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::availableLogicalHeight): Add iOS-specific workaround. See <rdar://problem/7166808>.
+ (WebCore::fixedPositionOffset): Added; used in iOS-specific code (e.g. RenderView::mapLocalToContainer()).
+ (WebCore::RenderView::mapLocalToContainer): Use WebCore::fixedPositionOffset() instead of
+ FrameView::scrollOffsetForFixedPosition().
+ (WebCore::RenderView::pushMappingToContainer): Ditto.
+ (WebCore::RenderView::mapAbsoluteToLocalPoint): Ditto.
+ (WebCore::RenderView::repaintViewRectangle): Ditto.
+ (WebCore::RenderView::computeRectForRepaint): Ditto.
+ (WebCore::isFixedPositionInViewport): Added; used in RenderView::hasCustomFixedPosition().
+ (WebCore::RenderView::hasCustomFixedPosition): Added; guarded by PLATFORM(IOS).
+ * rendering/RenderView.h:
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::willBeDestroyed): Added iOS-specific code.
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::ascentAndDescentForBox): Ditto.
+ * rendering/break_lines.cpp: Only include header <CoreServices/CoreServices.h> when building for Mac.
+
</ins><span class="cx"> 2013-12-06 Zoltan Horvath <zoltan@webkit.org>
</span><span class="cx">
</span><span class="cx"> Clean up the includes of RenderBlock.h
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -5439,6 +5439,8 @@
</span><span class="cx">                 CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CE7B2DB61586ABAD0098B3FA /* TextAlternativeWithRange.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */; };
</span><span class="cx">                 CE95208A1811B475007A5392 /* WebSafeIncrementalSweeperIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C4CB1D161A131200D214DA /* WebSafeIncrementalSweeperIOS.h */; };
</span><ins>+                FED13D520CEA949700D89466 /* RenderThemeIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = FED13D500CEA949700D89466 /* RenderThemeIOS.h */; };
+                C55C7BA11718AFBA001327E4 /* RenderThemeIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = C55C7BA01718AFBA001327E4 /* RenderThemeIOS.mm */; };
</ins><span class="cx">                 CECADFC6153778FF00E37068 /* DictationAlternative.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CECADFC2153778FF00E37068 /* DictationAlternative.cpp */; };
</span><span class="cx">                 CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC3153778FF00E37068 /* DictationAlternative.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CECADFC8153778FF00E37068 /* DictationCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CECADFC4153778FF00E37068 /* DictationCommand.cpp */; };
</span><span class="lines">@@ -12558,6 +12560,8 @@
</span><span class="cx">                 CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AlternativeTextUIController.mm; path = mac/AlternativeTextUIController.mm; sourceTree = "<group>"; };
</span><span class="cx">                 CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextAlternativeWithRange.h; path = mac/TextAlternativeWithRange.h; sourceTree = "<group>"; };
</span><span class="cx">                 CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TextAlternativeWithRange.mm; path = mac/TextAlternativeWithRange.mm; sourceTree = "<group>"; };
</span><ins>+                FED13D500CEA949700D89466 /* RenderThemeIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderThemeIOS.h; sourceTree = "<group>"; };
+                C55C7BA01718AFBA001327E4 /* RenderThemeIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderThemeIOS.mm; sourceTree = "<group>"; };
</ins><span class="cx">                 CECADFC2153778FF00E37068 /* DictationAlternative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationAlternative.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 CECADFC3153778FF00E37068 /* DictationAlternative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictationAlternative.h; sourceTree = "<group>"; };
</span><span class="cx">                 CECADFC4153778FF00E37068 /* DictationCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationCommand.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -21240,6 +21244,8 @@
</span><span class="cx">                                 86FF885F15DE3B8200BD6B28 /* RenderTextTrackCue.h */,
</span><span class="cx">                                 BCEA484A097D93020094C9E4 /* RenderTheme.cpp */,
</span><span class="cx">                                 BCEA484B097D93020094C9E4 /* RenderTheme.h */,
</span><ins>+                                FED13D500CEA949700D89466 /* RenderThemeIOS.h */,
+                                C55C7BA01718AFBA001327E4 /* RenderThemeIOS.mm */,
</ins><span class="cx">                                 BCEA4848097D93020094C9E4 /* RenderThemeMac.h */,
</span><span class="cx">                                 BCEA4849097D93020094C9E4 /* RenderThemeMac.mm */,
</span><span class="cx">                                 93955A4203D72932008635CE /* RenderTreeAsText.cpp */,
</span><span class="lines">@@ -24361,6 +24367,7 @@
</span><span class="cx">                                 439046DE12DA25E800AF80A2 /* RenderMathMLMath.h in Headers */,
</span><span class="cx">                                 439046E012DA25E800AF80A2 /* RenderMathMLOperator.h in Headers */,
</span><span class="cx">                                 439046E212DA25E800AF80A2 /* RenderMathMLRoot.h in Headers */,
</span><ins>+                                FED13D520CEA949700D89466 /* RenderThemeIOS.h in Headers */,
</ins><span class="cx">                                 439046E412DA25E800AF80A2 /* RenderMathMLRow.h in Headers */,
</span><span class="cx">                                 439046E612DA25E800AF80A2 /* RenderMathMLSquareRoot.h in Headers */,
</span><span class="cx">                                 0783228518013ED800999E0C /* MediaStreamAudioSource.h in Headers */,
</span><span class="lines">@@ -28303,6 +28310,7 @@
</span><span class="cx">                                 976D6C7B122B8A3D001FD1F7 /* WebKitBlobBuilder.cpp in Sources */,
</span><span class="cx">                                 150B923915F08DC400E10986 /* WebKitCSSArrayFunctionValue.cpp in Sources */,
</span><span class="cx">                                 A2E8AE3016A48E1C006BB3AA /* WebKitCSSFilterRule.cpp in Sources */,
</span><ins>+                                C55C7BA11718AFBA001327E4 /* RenderThemeIOS.mm in Sources */,
</ins><span class="cx">                                 3106036F14327D2E00ABF4BA /* WebKitCSSFilterValue.cpp in Sources */,
</span><span class="cx">                                 31288E720E3005D6003619AE /* WebKitCSSKeyframeRule.cpp in Sources */,
</span><span class="cx">                                 31288E740E3005D6003619AE /* WebKitCSSKeyframesRule.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineBox.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineBox.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/InlineBox.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -193,6 +193,15 @@
</span><span class="cx"> return m_bitfields.nextOnLineExists();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool InlineBox::previousOnLineExists() const
+{
+ if (!parent())
+ return false;
+ if (prevOnLine())
+ return true;
+ return parent()->previousOnLineExists();
+}
+
</ins><span class="cx"> InlineBox* InlineBox::nextLeafChild() const
</span><span class="cx"> {
</span><span class="cx"> InlineBox* leaf = 0;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineBox.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineBox.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/InlineBox.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -131,6 +131,7 @@
</span><span class="cx"> m_prev = prev;
</span><span class="cx"> }
</span><span class="cx"> bool nextOnLineExists() const;
</span><ins>+ bool previousOnLineExists() const;
</ins><span class="cx">
</span><span class="cx"> virtual bool isLeaf() const { return true; }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineTextBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineTextBox.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -716,7 +716,13 @@
</span><span class="cx">
</span><span class="cx"> GraphicsContextStateSaver stateSaver(*context);
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
+ // FIXME: Is this color still applicable as of Mavericks? for non-Mac ports? We should
+ // be able to move this color information to RenderStyle.
</ins><span class="cx"> Color c = Color(225, 221, 85);
</span><ins>+#else
+ Color c = style.compositionFillColor();
+#endif
</ins><span class="cx">
</span><span class="cx"> updateGraphicsContext(*context, TextPaintStyle(c, style.colorSpace())); // Don't draw text at all!
</span><span class="cx">
</span><span class="lines">@@ -1001,8 +1007,24 @@
</span><span class="cx">
</span><span class="cx"> // Use a special function for underlines to get the positioning exactly right.
</span><span class="cx"> bool isPrinting = renderer().document().printing();
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> context.setStrokeThickness(textDecorationThickness);
</span><ins>+#else
+ // On iOS we want to draw crisp decorations. The function drawLineForText takes the context's
+ // strokeThickness and renders that at device pixel scale (i.e. a strokeThickness of 1 will
+ // produce a 1 device pixel line, so thinner on retina than non-retina). We will also scale
+ // our thickness based on the size of the font. Since our default size is 16px we'll use that
+ // as a scale reference.
+ float pageScale = 1;
+ if (Page* page = renderer().frame().page())
+ pageScale = page->pageScaleFactor();
</ins><span class="cx">
</span><ins>+ const float textDecorationBaseFontSize = 16;
+ float fontSizeScaling = renderer().style().fontSize() / textDecorationBaseFontSize;
+ float strokeThickness = roundf(textDecorationThickness * fontSizeScaling * pageScale);
+ context.setStrokeThickness(strokeThickness);
+#endif
+
</ins><span class="cx"> bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
</span><span class="cx">
</span><span class="cx"> const RenderStyle& lineStyle = this->lineStyle();
</span><span class="lines">@@ -1164,6 +1186,11 @@
</span><span class="cx"> return GraphicsContext::DocumentMarkerAutocorrectionReplacementLineStyle;
</span><span class="cx"> case DocumentMarker::DictationAlternatives:
</span><span class="cx"> return GraphicsContext::DocumentMarkerDictationAlternativesLineStyle;
</span><ins>+#if PLATFORM(IOS)
+ case DocumentMarker::DictationPhraseWithAlternatives:
+ // FIXME: Rename TextCheckingDictationPhraseWithAlternativesLineStyle and remove the PLATFORM(IOS)-guard.
+ return GraphicsContext::TextCheckingDictationPhraseWithAlternativesLineStyle;
+#endif
</ins><span class="cx"> default:
</span><span class="cx"> ASSERT_NOT_REACHED();
</span><span class="cx"> return GraphicsContext::DocumentMarkerSpellingLineStyle;
</span><span class="lines">@@ -1304,6 +1331,10 @@
</span><span class="cx"> case DocumentMarker::CorrectionIndicator:
</span><span class="cx"> case DocumentMarker::Replacement:
</span><span class="cx"> case DocumentMarker::DictationAlternatives:
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: Remove the PLATFORM(IOS)-guard.
+ case DocumentMarker::DictationPhraseWithAlternatives:
+#endif
</ins><span class="cx"> if (background)
</span><span class="cx"> continue;
</span><span class="cx"> break;
</span><span class="lines">@@ -1334,6 +1365,12 @@
</span><span class="cx"> case DocumentMarker::Grammar:
</span><span class="cx"> paintDocumentMarker(pt, boxOrigin, marker, style, font, true);
</span><span class="cx"> break;
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS)-guard.
+ case DocumentMarker::DictationPhraseWithAlternatives:
+ paintDocumentMarker(pt, boxOrigin, marker, style, font, true);
+ break;
+#endif
</ins><span class="cx"> case DocumentMarker::TextMatch:
</span><span class="cx"> paintTextMatchMarker(pt, boxOrigin, marker, style, font);
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlock.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -2210,7 +2210,12 @@
</span><span class="cx"> flipForWritingMode(overflowBox);
</span><span class="cx"> overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
</span><span class="cx"> overflowBox.moveBy(adjustedPaintOffset);
</span><del>- if (!overflowBox.intersects(paintInfo.rect))
</del><ins>+ if (!overflowBox.intersects(paintInfo.rect)
+#if PLATFORM(IOS)
+ // FIXME: This may be applicable to non-iOS ports.
+ && (!hasLayer() || !layer()->isComposited())
+#endif
+ )
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -3559,6 +3564,15 @@
</span><span class="cx"> // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
</span><span class="cx"> if (isEditingBoundary(ancestor, child))
</span><span class="cx"> return child.positionForPoint(pointInChildCoordinates);
</span><ins>+
+#if PLATFORM(IOS)
+ // On iOS we want to constrain VisiblePositions to the editable region closest to the input position, so
+ // we will allow descent from non-edtiable to editable content.
+ // FIXME: This constraining must be done at a higher level once we implement contentEditable. For now, if something
+ // is editable, the whole document will be.
+ if (childElement->isContentEditable() && !ancestor->element()->isContentEditable())
+ return child.positionForPoint(pointInChildCoordinates);
+#endif
</ins><span class="cx">
</span><span class="cx"> // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
</span><span class="cx"> LayoutUnit childMiddle = parent.logicalWidthForChild(child) / 2;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlock.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlock.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderBlock.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -437,6 +437,9 @@
</span><span class="cx">
</span><span class="cx"> void setDesiredColumnCountAndWidth(int, LayoutUnit);
</span><span class="cx">
</span><ins>+ LayoutUnit logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
+ LayoutUnit logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
+
</ins><span class="cx"> public:
</span><span class="cx"> virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
</span><span class="cx"> void clearLayoutOverflow();
</span><span class="lines">@@ -557,9 +560,7 @@
</span><span class="cx"> LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
</span><span class="cx"> LayoutRect blockSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
</span><span class="cx"> LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches&, const PaintInfo*);
</span><del>- LayoutUnit logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
- LayoutUnit logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
-
</del><ins>+
</ins><span class="cx"> // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
</span><span class="cx"> virtual void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) { };
</span><span class="cx"> friend class LogicalSelectionOffsetCaches;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -62,6 +62,10 @@
</span><span class="cx"> #include "RenderLayerCompositor.h"
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "Settings.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="lines">@@ -596,6 +600,18 @@
</span><span class="cx"> return std::max(logicalHeight, computeContentLogicalHeight(styleToUse.logicalMinHeight()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RoundedRect::Radii RenderBox::borderRadii() const
+{
+ RenderStyle& style = this->style();
+ LayoutRect bounds = frameRect();
+
+ unsigned borderLeft = style.borderLeftWidth();
+ unsigned borderTop = style.borderTopWidth();
+ bounds.moveBy(LayoutPoint(borderLeft, borderTop));
+ bounds.contract(borderLeft + style.borderRightWidth(), borderTop + style.borderBottomWidth());
+ return style.getRoundedBorderFor(bounds).radii();
+}
+
</ins><span class="cx"> IntRect RenderBox::absoluteContentBox() const
</span><span class="cx"> {
</span><span class="cx"> // This is wrong with transforms and flipped writing modes.
</span><span class="lines">@@ -1159,6 +1175,14 @@
</span><span class="cx"> LayoutRect paintRect = borderBoxRectInRegion(paintInfo.renderRegion);
</span><span class="cx"> paintRect.moveBy(paintOffset);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // Workaround for <rdar://problem/6209763>. Force the painting bounds of checkboxes and radio controls to be square.
+ if (style().appearance() == CheckboxPart || style().appearance() == RadioPart) {
+ int width = std::min(paintRect.width(), paintRect.height());
+ int height = width;
+ paintRect = IntRect(paintRect.x(), paintRect.y() + (this->height() - height) / 2, width, height); // Vertically center the checkbox, like on desktop
+ }
+#endif
</ins><span class="cx"> BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context);
</span><span class="cx">
</span><span class="cx"> // FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have
</span><span class="lines">@@ -2109,9 +2133,15 @@
</span><span class="cx"> rect.setLocation(topLeft);
</span><span class="cx"> if (o->hasOverflowClip()) {
</span><span class="cx"> RenderBox* containerBox = toRenderBox(o);
</span><ins>+#if PLATFORM(IOS)
+ if (!containerBox->layer() || !containerBox->layer()->hasAcceleratedTouchScrolling()) {
+#endif
</ins><span class="cx"> containerBox->applyCachedClipAndScrollOffsetForRepaint(rect);
</span><span class="cx"> if (rect.isEmpty())
</span><span class="cx"> return;
</span><ins>+#if PLATFORM(IOS)
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (containerSkipped) {
</span><span class="lines">@@ -2902,6 +2932,33 @@
</span><span class="cx"> return constrainLogicalHeightByMinMax(availableLogicalHeightUsing(style().logicalHeight(), heightType));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static inline int customContainingBlockWidth(const RenderView& view, const RenderBox& containingBlockBox)
+{
+ return view.frameView().customFixedPositionLayoutRect().width() - containingBlockBox.borderLeft() - containingBlockBox.borderRight() - containingBlockBox.verticalScrollbarWidth();
+}
+
+static inline int customContainingBlockHeight(const RenderView& view, const RenderBox& containingBlockBox)
+{
+ return view.frameView().customFixedPositionLayoutRect().height() - containingBlockBox.borderTop() - containingBlockBox.borderBottom() - containingBlockBox.horizontalScrollbarHeight();
+}
+
+static int customContainingBlockLogicalWidth(const RenderStyle& style, const RenderView& view, const RenderBox& containingBlockBox)
+{
+ return style.isHorizontalWritingMode() ? customContainingBlockWidth(view, containingBlockBox) : customContainingBlockHeight(view, containingBlockBox);
+}
+
+static int customContainingBlockLogicalHeight(const RenderStyle& style, const RenderView& view, const RenderBox& containingBlockBox)
+{
+ return style.isHorizontalWritingMode() ? customContainingBlockHeight(view, containingBlockBox) : customContainingBlockWidth(view, containingBlockBox);
+}
+
+static inline int customContainingBlockAvailableLogicalHeight(const RenderStyle& style, const RenderView& view)
+{
+ return style.isHorizontalWritingMode() ? view.frameView().customFixedPositionLayoutRect().height() : view.frameView().customFixedPositionLayoutRect().width();
+}
+#endif
+
</ins><span class="cx"> LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h, AvailableLogicalHeightType heightType) const
</span><span class="cx"> {
</span><span class="cx"> // We need to stop here, since we don't want to increase the height of the table
</span><span class="lines">@@ -2914,9 +2971,21 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (h.isPercent() && isOutOfFlowPositioned() && !isRenderFlowThread()) {
</span><ins>+#if PLATFORM(IOS)
+ RenderBlock* containingBlock = this->containingBlock();
+ // If we're fixed, and our container is the RenderView, use the custom fixed position rect for sizing.
+ if (containingBlock->isRenderView()) {
+ RenderView& view = toRenderView(*containingBlock);
+ if (view.hasCustomFixedPosition(*this))
+ return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(h, customContainingBlockAvailableLogicalHeight(containingBlock->style(), view)));
+ }
+
+ return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(h, containingBlock->availableLogicalHeight(heightType)));
+#else
</ins><span class="cx"> // FIXME: This is wrong if the containingBlock has a perpendicular writing mode.
</span><span class="cx"> LayoutUnit availableHeight = containingBlockLogicalHeightForPositioned(containingBlock());
</span><span class="cx"> return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(h, availableHeight));
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> LayoutUnit heightIncludingScrollbar = computeContentAndScrollbarLogicalHeightUsing(h);
</span><span class="lines">@@ -2981,8 +3050,15 @@
</span><span class="cx">
</span><span class="cx"> if (containingBlock->isBox()) {
</span><span class="cx"> RenderFlowThread* flowThread = flowThreadContainingBlock();
</span><del>- if (!flowThread)
</del><ins>+ if (!flowThread) {
+#if PLATFORM(IOS)
+ if (view().hasCustomFixedPosition(*this)) {
+ const RenderBox& containingBlockBox = toRenderBox(*containingBlock);
+ return customContainingBlockLogicalWidth(containingBlockBox.style(), &view(), containingBlockBox);
+ }
+#endif
</ins><span class="cx"> return toRenderBox(containingBlock)->clientLogicalWidth();
</span><ins>+ }
</ins><span class="cx">
</span><span class="cx"> if (containingBlock->isRenderNamedFlowThread() && style().position() == FixedPosition)
</span><span class="cx"> return containingBlock->view().clientLogicalWidth();
</span><span class="lines">@@ -3038,6 +3114,10 @@
</span><span class="cx"> return containingBlockLogicalWidthForPositioned(containingBlock, 0, false);
</span><span class="cx">
</span><span class="cx"> if (containingBlock->isBox()) {
</span><ins>+#if PLATFORM(IOS)
+ if (view().hasCustomFixedPosition(*this))
+ return customContainingBlockLogicalHeight(style(), view(), toRenderBox(*containingBlock));
+#endif
</ins><span class="cx"> const RenderBlock* cb = toRenderBlock(containingBlock);
</span><span class="cx"> LayoutUnit result = cb->clientLogicalHeight();
</span><span class="cx"> RenderFlowThread* flowThread = flowThreadContainingBlock();
</span><span class="lines">@@ -4460,7 +4540,11 @@
</span><span class="cx"> rect.unite(layoutOverflowRect());
</span><span class="cx">
</span><span class="cx"> bool hasTransform = hasLayer() && layer()->transform();
</span><ins>+#if PLATFORM(IOS)
+ if (isInFlowPositioned() || (hasTransform && document().settings()->shouldTransformsAffectOverflow())) {
+#else
</ins><span class="cx"> if (isInFlowPositioned() || hasTransform) {
</span><ins>+#endif
</ins><span class="cx"> // If we are relatively positioned or if we have a transform, then we have to convert
</span><span class="cx"> // this rectangle into physical coordinates, apply relative positioning and transforms
</span><span class="cx"> // to it, and then convert it back.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderBox.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -157,6 +157,8 @@
</span><span class="cx"> IntRect pixelSnappedBorderBoxRect() const { return IntRect(IntPoint(), m_frameRect.pixelSnappedSize()); }
</span><span class="cx"> virtual IntRect borderBoundingBox() const OVERRIDE FINAL { return pixelSnappedBorderBoxRect(); }
</span><span class="cx">
</span><ins>+ RoundedRect::Radii borderRadii() const;
+
</ins><span class="cx"> // The content area of the box (excludes padding - and intrinsic padding for table cells, etc... - and border).
</span><span class="cx"> LayoutRect contentBoxRect() const { return LayoutRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); }
</span><span class="cx"> // The content box in absolute coords. Ignores transforms.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxModelObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -432,7 +432,11 @@
</span><span class="cx"> FloatPoint scrollOffset = FloatPoint() + enclosingClippingLayer->scrollOffset();
</span><span class="cx"> constrainingRect.setLocation(scrollOffset);
</span><span class="cx"> } else {
</span><ins>+#if PLATFORM(IOS)
+ LayoutRect viewportRect = view().frameView().customFixedPositionLayoutRect();
+#else
</ins><span class="cx"> LayoutRect viewportRect = view().frameView().viewportConstrainedVisibleContentRect();
</span><ins>+#endif
</ins><span class="cx"> float scale = view().frameView().frame().frameScaleFactor();
</span><span class="cx"> viewportRect.scale(1 / scale);
</span><span class="cx"> constrainingRect = viewportRect;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderButtoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderButton.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderButton.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderButton.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -29,6 +29,10 @@
</span><span class="cx"> #include "RenderTheme.h"
</span><span class="cx"> #include "StyleInheritedData.h"
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "RenderThemeIOS.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="lines">@@ -192,4 +196,14 @@
</span><span class="cx"> repaint();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderButton::layout()
+{
+ RenderFlexibleBox::layout();
+
+ // FIXME: We should not be adjusting styles during layout. See <rdar://problem/7675493>.
+ RenderThemeIOS::adjustRoundBorderRadius(style(), this);
+}
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -846,6 +846,10 @@
</span><span class="cx"> if (visibilityChanged)
</span><span class="cx"> document().setAnnotatedRegionsDirty(true);
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+ if (visibilityChanged)
+ document().dirtyTouchEventRects();
+#endif
</ins><span class="cx"> if (visibilityChanged) {
</span><span class="cx"> if (AXObjectCache* cache = document().existingAXObjectCache())
</span><span class="cx"> cache->childrenChanged(parent());
</span><span class="lines">@@ -923,6 +927,7 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(a->cursors() != b->cursors());
</span><span class="lines">@@ -933,6 +938,7 @@
</span><span class="cx"> {
</span><span class="cx"> return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> void RenderElement::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
</span><span class="cx"> {
</span><span class="lines">@@ -972,8 +978,10 @@
</span><span class="cx"> // Don't check for repaint here; we need to wait until the layer has been
</span><span class="cx"> // updated by subclasses before we know if we have to repaint (in setStyle()).
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (oldStyle && !areCursorsEqual(oldStyle, &style()))
</span><span class="cx"> frame().eventHandler().scheduleCursorUpdate();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderElement::insertedIntoTree()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderEmbeddedObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -134,10 +134,16 @@
</span><span class="cx">
</span><span class="cx"> bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ // The timing of layer creation is different on the phone, since the plugin can only be manipulated from the main thread.
+ return widget() && widget()->isPluginViewBase() && toPluginViewBase(widget())->willProvidePluginLayer();
+#else
</ins><span class="cx"> return widget() && widget()->isPluginViewBase() && toPluginViewBase(widget())->platformLayer();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> static String unavailablePluginReplacementText(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
</span><span class="cx"> {
</span><span class="cx"> switch (pluginUnavailabilityReason) {
</span><span class="lines">@@ -154,6 +160,7 @@
</span><span class="cx"> ASSERT_NOT_REACHED();
</span><span class="cx"> return String();
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> static bool shouldUnavailablePluginMessageBeButton(Document& document, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
</span><span class="cx"> {
</span><span class="lines">@@ -163,11 +170,19 @@
</span><span class="cx">
</span><span class="cx"> void RenderEmbeddedObject::setPluginUnavailabilityReason(PluginUnavailabilityReason pluginUnavailabilityReason)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(pluginUnavailabilityReason);
+#else
</ins><span class="cx"> setPluginUnavailabilityReasonWithDescription(pluginUnavailabilityReason, unavailablePluginReplacementText(pluginUnavailabilityReason));
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription(PluginUnavailabilityReason pluginUnavailabilityReason, const String& description)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(pluginUnavailabilityReason);
+ UNUSED_PARAM(description);
+#else
</ins><span class="cx"> ASSERT(!m_isPluginUnavailable);
</span><span class="cx"> m_isPluginUnavailable = true;
</span><span class="cx"> m_pluginUnavailabilityReason = pluginUnavailabilityReason;
</span><span class="lines">@@ -176,6 +191,7 @@
</span><span class="cx"> m_unavailablePluginReplacementText = unavailablePluginReplacementText(pluginUnavailabilityReason);
</span><span class="cx"> else
</span><span class="cx"> m_unavailablePluginReplacementText = description;
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderEmbeddedObject::setUnavailablePluginIndicatorIsPressed(bool pressed)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderFileUploadControlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -37,15 +37,25 @@
</span><span class="cx"> #include "VisiblePosition.h"
</span><span class="cx"> #include <math.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "StringTruncator.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx">
</span><span class="cx"> const int afterButtonSpacing = 4;
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> const int iconHeight = 16;
</span><span class="cx"> const int iconWidth = 16;
</span><span class="cx"> const int iconFilenameSpacing = 2;
</span><span class="cx"> const int defaultWidthNumChars = 34;
</span><ins>+#else
+// On iOS the icon height matches the button height, to maximize the icon size.
+const int iconFilenameSpacing = afterButtonSpacing;
+const int defaultWidthNumChars = 38;
+#endif
</ins><span class="cx"> const int buttonShadowHeight = 2;
</span><span class="cx">
</span><span class="cx"> RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement& input, PassRef<RenderStyle> style)
</span><span class="lines">@@ -93,8 +103,18 @@
</span><span class="cx"> return (node && node->renderBox()) ? node->renderBox()->pixelSnappedWidth() : 0;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static int nodeHeight(Node* node)
+{
+ return (node && node->renderBox()) ? node->renderBox()->pixelSnappedHeight() : 0;
+}
+#endif
+
</ins><span class="cx"> int RenderFileUploadControl::maxFilenameWidth() const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ int iconWidth = nodeHeight(uploadButton());
+#endif
</ins><span class="cx"> return std::max(0, contentBoxRect().pixelSnappedWidth() - nodeWidth(uploadButton()) - afterButtonSpacing
</span><span class="cx"> - (inputElement().icon() ? iconWidth + iconFilenameSpacing : 0));
</span><span class="cx"> }
</span><span class="lines">@@ -121,6 +141,10 @@
</span><span class="cx"> TextRun textRun = constructTextRun(this, font, displayedFilename, style(), TextRun::AllowTrailingExpansion, RespectDirection | RespectDirectionOverride);
</span><span class="cx"> textRun.disableRoundingHacks();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ int iconHeight = nodeHeight(uploadButton());
+ int iconWidth = iconHeight;
+#endif
</ins><span class="cx"> // Determine where the filename should be placed
</span><span class="cx"> LayoutUnit contentLeft = paintOffset.x() + borderLeft() + paddingLeft();
</span><span class="cx"> HTMLInputElement* button = uploadButton();
</span><span class="lines">@@ -158,8 +182,17 @@
</span><span class="cx"> else
</span><span class="cx"> iconX = contentLeft + contentWidth() - buttonWidth - afterButtonSpacing - iconWidth;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (RenderButton* buttonRenderer = toRenderButton(button->renderer())) {
+ // Draw the file icon and decorations.
+ IntRect iconRect(iconX, iconY, iconWidth, iconHeight);
+ RenderTheme::FileUploadDecorations decorationsType = inputElement().files()->length() == 1 ? RenderTheme::SingleFile : RenderTheme::MultipleFiles;
+ theme()->paintFileUploadIconDecorations(this, buttonRenderer, paintInfo, iconRect, inputElement().icon(), decorationsType);
+ }
+#else
</ins><span class="cx"> // Draw the file icon
</span><span class="cx"> inputElement().icon()->paint(paintInfo.context, IntRect(roundToInt(iconX), roundToInt(iconY), iconWidth, iconHeight));
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -241,6 +274,10 @@
</span><span class="cx"> String RenderFileUploadControl::fileTextValue() const
</span><span class="cx"> {
</span><span class="cx"> ASSERT(inputElement().files());
</span><ins>+#if PLATFORM(IOS)
+ if (inputElement().files()->length())
+ return StringTruncator::rightTruncate(inputElement().displayString(), maxFilenameWidth(), style().font(), StringTruncator::EnableRoundingHacks);
+#endif
</ins><span class="cx"> return theme()->fileListNameForWidth(inputElement().files(), style().font(), maxFilenameWidth(), inputElement().multiple());
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderFrameSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderFrameSet.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderFrameSet.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderFrameSet.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -514,7 +514,12 @@
</span><span class="cx"> if (width != child->width() || height != child->height()) {
</span><span class="cx"> child->setWidth(width);
</span><span class="cx"> child->setHeight(height);
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: Is this iOS-specific?
+ child->setNeedsLayout(MarkOnlyThis);
+#else
</ins><span class="cx"> child->setNeedsLayout();
</span><ins>+#endif
</ins><span class="cx"> child->layout();
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderIFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderIFrame.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderIFrame.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderIFrame.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -54,7 +54,12 @@
</span><span class="cx">
</span><span class="cx"> virtual bool isRenderIFrame() const OVERRIDE { return true; }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: Do we still need this workaround to avoid breaking layout tests?
+ virtual const char* renderName() const OVERRIDE { return "RenderPartObject"; }
+#else
</ins><span class="cx"> virtual const char* renderName() const OVERRIDE { return "RenderIFrame"; }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> virtual bool requiresLayer() const OVERRIDE;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderImage.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -47,8 +47,71 @@
</span><span class="cx"> #include "SVGImage.h"
</span><span class="cx"> #include <wtf/StackStats.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "LogicalSelectionOffsetCaches.h"
+#include "SelectionRect.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+// FIXME: This doesn't behave correctly for floating or positioned images, but WebCore doesn't handle those well
+// during selection creation yet anyway.
+// FIXME: We can't tell whether or not we contain the start or end of the selected Range using only the offsets
+// of the start and end, we need to know the whole Position.
+void RenderImage::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned)
+{
+ RenderBlock* containingBlock = this->containingBlock();
+
+ IntRect imageRect;
+ // FIXME: It doesn't make sense to package line bounds into SelectionRects. We should find
+ // the right and left extent of the selection once for the entire selected Range, perhaps
+ // using the Range's common ancestor.
+ IntRect lineExtentRect;
+ bool isFirstOnLine = false;
+ bool isLastOnLine = false;
+
+ InlineBox* inlineBox = inlineBoxWrapper();
+ if (!inlineBox) {
+ // This is a block image.
+ imageRect = IntRect(0, 0, width(), height());
+ isFirstOnLine = true;
+ isLastOnLine = true;
+ lineExtentRect = imageRect;
+ if (containingBlock->isHorizontalWritingMode()) {
+ lineExtentRect.setX(containingBlock->x());
+ lineExtentRect.setWidth(containingBlock->width());
+ } else {
+ lineExtentRect.setY(containingBlock->y());
+ lineExtentRect.setHeight(containingBlock->height());
+ }
+ } else {
+ LayoutUnit selectionTop = !containingBlock->style().isFlippedBlocksWritingMode() ? inlineBox->root().selectionTop() - logicalTop() : logicalBottom() - inlineBox->root().selectionBottom();
+ imageRect = IntRect(0, selectionTop, logicalWidth(), inlineBox->root().selectionHeight());
+ isFirstOnLine = !inlineBox->previousOnLineExists();
+ isLastOnLine = !inlineBox->nextOnLineExists();
+ LogicalSelectionOffsetCaches cache(*containingBlock);
+ LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache);
+ LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache);
+ lineExtentRect = IntRect(leftOffset - logicalLeft(), imageRect.y(), rightOffset - leftOffset, imageRect.height());
+ if (!inlineBox->isHorizontal()) {
+ imageRect = imageRect.transposedRect();
+ lineExtentRect = lineExtentRect.transposedRect();
+ }
+ }
+
+ bool isFixed = false;
+ IntRect absoluteBounds = localToAbsoluteQuad(FloatRect(imageRect), false, &isFixed).enclosingBoundingBox();
+ IntRect lineExtentBounds = localToAbsoluteQuad(FloatRect(lineExtentRect)).enclosingBoundingBox();
+ if (!containingBlock->isHorizontalWritingMode())
+ lineExtentBounds = lineExtentBounds.transposedRect();
+
+ // FIXME: We should consider either making SelectionRect a struct or better organize its optional fields into
+ // an auxiliary struct to simplify its initialization.
+ rects.append(SelectionRect(absoluteBounds, containingBlock->style().direction(), lineExtentBounds.x(), lineExtentBounds.maxX(), lineExtentBounds.maxY(), 0, false /* line break */, isFirstOnLine, isLastOnLine, false /* contains start */, false /* contains end */, containingBlock->style().isHorizontalWritingMode(), isFixed, false /* ruby text */, columnNumberForOffset(absoluteBounds.x())));
+}
+#endif
+
</ins><span class="cx"> using namespace HTMLNames;
</span><span class="cx">
</span><span class="cx"> RenderImage::RenderImage(Element& element, PassRef<RenderStyle> style)
</span><span class="lines">@@ -462,6 +525,9 @@
</span><span class="cx">
</span><span class="cx"> void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(paintInfo);
+#else
</ins><span class="cx"> if (document().printing() || !frame().selection().isFocusedAndActive())
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -493,6 +559,7 @@
</span><span class="cx"> paintInfo.context->drawFocusRing(path, outlineWidth,
</span><span class="cx"> areaElementStyle->outlineOffset(),
</span><span class="cx"> areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderImage::areaElementFocusChanged(HTMLAreaElement* element)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderImage.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderImage.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderImage.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -56,6 +56,10 @@
</span><span class="cx"> void areaElementFocusChanged(HTMLAreaElement*);
</span><span class="cx">
</span><span class="cx"> void highQualityRepaintTimerFired(Timer<RenderImage>*);
</span><ins>+
+#if PLATFORM(IOS)
+ virtual void collectSelectionRects(Vector<SelectionRect>&, unsigned, unsigned) OVERRIDE;
+#endif
</ins><span class="cx">
</span><span class="cx"> void setIsGeneratedContent(bool generated = true) { m_isGeneratedContent = generated; }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderInlinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderInline.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -697,6 +697,14 @@
</span><span class="cx"> continuation->absoluteQuads(quads, wasFixed);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderInline::absoluteQuadsForSelection(Vector<FloatQuad>& quads) const
+{
+ AbsoluteQuadsGeneratorContext context(this, quads);
+ generateLineBoxRects(context);
+}
+#endif
+
</ins><span class="cx"> LayoutUnit RenderInline::offsetLeft() const
</span><span class="cx"> {
</span><span class="cx"> LayoutPoint topLeft;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderInlineh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderInline.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderInline.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderInline.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -68,6 +68,10 @@
</span><span class="cx"> InlineBox* firstLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? firstLineBox() : culledInlineFirstLineBox(); }
</span><span class="cx"> InlineBox* lastLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? lastLineBox() : culledInlineLastLineBox(); }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ virtual void absoluteQuadsForSelection(Vector<FloatQuad>& quads) const OVERRIDE;
+#endif
+
</ins><span class="cx"> virtual RenderBoxModelObject* virtualContinuation() const OVERRIDE FINAL { return continuation(); }
</span><span class="cx"> RenderInline* inlineElementContinuation() const;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -182,6 +182,12 @@
</span><span class="cx"> , m_indirectCompositingReason(NoIndirectCompositingReason)
</span><span class="cx"> , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS)
+ , m_adjustForIOSCaretWhenScrolling(false)
+ , m_registeredAsTouchEventListenerForScrolling(false)
+ , m_inUserScroll(false)
+ , m_requiresScrollBoundsOriginUpdate(false)
+#endif
</ins><span class="cx"> , m_containsDirtyOverlayScrollbars(false)
</span><span class="cx"> , m_updatingMarqueePosition(false)
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="lines">@@ -237,6 +243,9 @@
</span><span class="cx"> renderer().view().frameView().removeScrollableArea(this);
</span><span class="cx">
</span><span class="cx"> if (!renderer().documentBeingDestroyed()) {
</span><ins>+#if PLATFORM(IOS)
+ unregisterAsTouchEventListenerForScrolling();
+#endif
</ins><span class="cx"> if (Element* element = renderer().element())
</span><span class="cx"> element->setSavedLayerScrollOffset(m_scrollOffset);
</span><span class="cx"> }
</span><span class="lines">@@ -1767,6 +1776,14 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderLayer::willBeDestroyed()
+{
+ if (RenderLayerBacking* layerBacking = backing())
+ layerBacking->layerWillBeDestroyed();
+}
+#endif
+
</ins><span class="cx"> void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
</span><span class="cx"> {
</span><span class="cx"> RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
</span><span class="lines">@@ -2084,6 +2101,55 @@
</span><span class="cx"> rect.move(-delta.x(), -delta.y());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+bool RenderLayer::hasAcceleratedTouchScrolling() const
+{
+#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
+ if (!scrollsOverflow())
+ return false;
+
+ Settings* settings = renderer().document().settings();
+
+ // FIXME: settings should not be null at this point. If you find a reliable way to hit this assertion, please file a bug.
+ // See <rdar://problem/10266101>.
+ ASSERT(settings);
+
+ return renderer().style().useTouchOverflowScrolling() || (settings && settings->alwaysUseAcceleratedOverflowScroll());
+#else
+ return false;
+#endif
+}
+
+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
+{
+ // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
+ if (hasAcceleratedTouchScrolling())
+ return false;
+
+ return ScrollableArea::handleTouchEvent(touchEvent);
+}
+#endif
+
+void RenderLayer::registerAsTouchEventListenerForScrolling()
+{
+ if (!renderer().element() || m_registeredAsTouchEventListenerForScrolling)
+ return;
+
+ renderer().document().addTouchEventListener(renderer().element());
+ m_registeredAsTouchEventListenerForScrolling = true;
+}
+
+void RenderLayer::unregisterAsTouchEventListenerForScrolling()
+{
+ if (!renderer().element() || !m_registeredAsTouchEventListenerForScrolling)
+ return;
+
+ renderer().document().removeTouchEventListener(renderer().element());
+ m_registeredAsTouchEventListenerForScrolling = false;
+}
+#endif // PLATFORM(IOS)
+
</ins><span class="cx"> #if USE(ACCELERATED_COMPOSITING)
</span><span class="cx">
</span><span class="cx"> bool RenderLayer::usesCompositedScrolling() const
</span><span class="lines">@@ -2107,9 +2173,11 @@
</span><span class="cx"> && canBeStackingContainer()
</span><span class="cx"> && !hasOutOfFlowPositionedDescendant();
</span><span class="cx">
</span><del>-#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
</del><ins>+#if !PLATFORM(IOS) && ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
</ins><span class="cx"> m_needsCompositedScrolling = forceUseCompositedScrolling || renderer().style().useTouchOverflowScrolling();
</span><span class="cx"> #else
</span><ins>+ // On iOS we don't want to opt into accelerated composited scrolling, which creates scroll bar
+ // layers in WebCore, because we use UIKit to composite our scroll bars.
</ins><span class="cx"> m_needsCompositedScrolling = forceUseCompositedScrolling;
</span><span class="cx"> #endif
</span><span class="cx"> // We gather a boolean value for use with Google UMA histograms to
</span><span class="lines">@@ -2241,6 +2309,17 @@
</span><span class="cx"> // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
</span><span class="cx"> if (m_scrollDimensionsDirty)
</span><span class="cx"> computeScrollDimensions();
</span><ins>+#if PLATFORM(IOS)
+ if (adjustForIOSCaretWhenScrolling()) {
+ int maxX = scrollWidth() - box->clientWidth();
+ if (x > maxX - caretWidth) {
+ x += caretWidth;
+ if (x <= caretWidth)
+ x = 0;
+ } else if (x < m_scrollOffset.width() - caretWidth)
+ x -= caretWidth;
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // FIXME: Eventually, we will want to perform a blit. For now never
</span><span class="lines">@@ -2249,8 +2328,13 @@
</span><span class="cx"> // is either occluded by another layer or clipped by an enclosing
</span><span class="cx"> // layer or contains fixed backgrounds, etc.).
</span><span class="cx"> IntSize newScrollOffset = IntSize(x - scrollOrigin().x(), y - scrollOrigin().y());
</span><del>- if (m_scrollOffset == newScrollOffset)
</del><ins>+ if (m_scrollOffset == newScrollOffset) {
+#if PLATFORM(IOS)
+ if (m_requiresScrollBoundsOriginUpdate)
+ updateCompositingLayersAfterScroll();
+#endif
</ins><span class="cx"> return;
</span><ins>+}
</ins><span class="cx"> m_scrollOffset = newScrollOffset;
</span><span class="cx">
</span><span class="cx"> InspectorInstrumentation::willScrollLayer(&renderer().frame());
</span><span class="lines">@@ -2276,6 +2360,10 @@
</span><span class="cx"> // when that completes.
</span><span class="cx"> updateCompositingLayersAfterScroll();
</span><span class="cx"> }
</span><ins>+
+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+ renderer().document().dirtyTouchEventRects();
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Frame& frame = renderer().frame();
</span><span class="lines">@@ -2296,7 +2384,11 @@
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> // Just schedule a full repaint of our object.
</span><ins>+#if PLATFORM(IOS)
+ if (!hasAcceleratedTouchScrolling())
+#else
</ins><span class="cx"> if (requiresRepaint)
</span><ins>+#endif
</ins><span class="cx"> renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect));
</span><span class="cx">
</span><span class="cx"> // Schedule the scroll DOM event.
</span><span class="lines">@@ -2386,10 +2478,15 @@
</span><span class="cx"> parentLayer = 0;
</span><span class="cx"> }
</span><span class="cx"> } else {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> LayoutRect viewRect = frameView.visibleContentRect();
</span><span class="cx"> LayoutRect visibleRectRelativeToDocument = viewRect;
</span><span class="cx"> IntSize scrollOffsetRelativeToDocument = frameView.scrollOffsetRelativeToDocument();
</span><span class="cx"> visibleRectRelativeToDocument.setLocation(IntPoint(scrollOffsetRelativeToDocument.width(), scrollOffsetRelativeToDocument.height()));
</span><ins>+#else
+ LayoutRect viewRect = frameView.actualVisibleContentRect();
+ LayoutRect visibleRectRelativeToDocument = viewRect;
+#endif
</ins><span class="cx">
</span><span class="cx"> LayoutRect r = getRectToExpose(viewRect, visibleRectRelativeToDocument, rect, alignX, alignY);
</span><span class="cx">
</span><span class="lines">@@ -2624,6 +2721,13 @@
</span><span class="cx"> if (scrollbarInclusion == IncludeScrollbars) {
</span><span class="cx"> verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
</span><span class="cx"> horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
</span><ins>+
+#if PLATFORM(IOS)
+ if (hasAcceleratedTouchScrolling()) {
+ verticalScrollbarWidth = 0;
+ horizontalScrollbarHeight = 0;
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
</span><span class="lines">@@ -2761,6 +2865,27 @@
</span><span class="cx"> return renderer().view().frameView().shouldSuspendScrollAnimations();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderLayer::didStartScroll()
+{
+ if (Page* page = renderer().frame().page())
+ page->chrome().client().didStartOverflowScroll();
+}
+
+void RenderLayer::didEndScroll()
+{
+ if (Page* page = renderer().frame().page())
+ page->chrome().client().didEndOverflowScroll();
+}
+
+void RenderLayer::didUpdateScroll()
+{
+ // Send this notification when we scroll, since this is how we keep selection updated.
+ if (Page* page = renderer().frame().page())
+ page->chrome().client().didLayout(ChromeClient::Scroll);
+}
+#endif
+
</ins><span class="cx"> IntPoint RenderLayer::lastKnownMousePosition() const
</span><span class="cx"> {
</span><span class="cx"> return renderer().frame().eventHandler().lastKnownMousePosition();
</span><span class="lines">@@ -2832,6 +2957,12 @@
</span><span class="cx">
</span><span class="cx"> void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ // No need to invalidate scrollbars if we're using accelerated scrolling.
+ if (hasAcceleratedTouchScrolling())
+ return;
+#endif
+
</ins><span class="cx"> #if USE(ACCELERATED_COMPOSITING)
</span><span class="cx"> if (scrollbar == m_vBar.get()) {
</span><span class="cx"> if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
</span><span class="lines">@@ -2863,6 +2994,12 @@
</span><span class="cx">
</span><span class="cx"> void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ // No need to invalidate the scroll corner if we're using accelerated scrolling.
+ if (hasAcceleratedTouchScrolling())
+ return;
+#endif
+
</ins><span class="cx"> #if USE(ACCELERATED_COMPOSITING)
</span><span class="cx"> if (GraphicsLayer* layer = layerForScrollCorner()) {
</span><span class="cx"> layer->setNeedsDisplayInRect(rect);
</span><span class="lines">@@ -2984,6 +3121,12 @@
</span><span class="cx"> {
</span><span class="cx"> if (!m_vBar || (m_vBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_vBar->shouldParticipateInHitTesting())))
</span><span class="cx"> return 0;
</span><ins>+
+#if PLATFORM(IOS)
+ if (hasAcceleratedTouchScrolling())
+ return 0;
+#endif
+
</ins><span class="cx"> return m_vBar->width();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2991,6 +3134,12 @@
</span><span class="cx"> {
</span><span class="cx"> if (!m_hBar || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_hBar->shouldParticipateInHitTesting())))
</span><span class="cx"> return 0;
</span><ins>+
+#if PLATFORM(IOS)
+ if (hasAcceleratedTouchScrolling())
+ return 0;
+#endif
+
</ins><span class="cx"> return m_hBar->height();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -3219,8 +3368,18 @@
</span><span class="cx"> // Layout may cause us to be at an invalid scroll position. In this case we need
</span><span class="cx"> // to pull our scroll offsets back to the max (or push them up to the min).
</span><span class="cx"> IntSize clampedScrollOffset = clampScrollOffset(scrollOffset());
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: This looks wrong. The caret adjust mode should only be enabled on editing related entry points.
+ // This code was added to fix an issue where the text insertion point would always be drawn on the right edge
+ // of a text field whose content overflowed its bounds. See <rdar://problem/15579797> for more details.
+ setAdjustForIOSCaretWhenScrolling(true);
+#endif
</ins><span class="cx"> if (clampedScrollOffset != scrollOffset())
</span><span class="cx"> scrollToOffset(clampedScrollOffset);
</span><ins>+
+#if PLATFORM(IOS)
+ setAdjustForIOSCaretWhenScrolling(false);
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> updateScrollbarsAfterLayout();
</span><span class="lines">@@ -3260,6 +3419,12 @@
</span><span class="cx"> if (!renderer().hasOverflowClip())
</span><span class="cx"> return;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // Don't render (custom) scrollbars if we have accelerated scrolling.
+ if (hasAcceleratedTouchScrolling())
+ return;
+#endif
+
</ins><span class="cx"> // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
</span><span class="cx"> // on top of everything else. If this is the normal painting pass, paintingOverlayControls
</span><span class="cx"> // will be false, and we should just tell the root layer that there are overlay scrollbars
</span><span class="lines">@@ -5243,7 +5408,11 @@
</span><span class="cx"> clipRects.setOverflowClipRect(clipRects.posClipRect());
</span><span class="cx">
</span><span class="cx"> // Update the clip rects that will be passed to child layers.
</span><ins>+#if PLATFORM(IOS)
+ if (renderer().hasClipOrOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || this != clipRectsContext.rootLayer)) {
+#else
</ins><span class="cx"> if ((renderer().hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || this != clipRectsContext.rootLayer)) || renderer().hasClip()) {
</span><ins>+#endif
</ins><span class="cx"> // This layer establishes a clip of some kind.
</span><span class="cx">
</span><span class="cx"> // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across
</span><span class="lines">@@ -6183,6 +6352,9 @@
</span><span class="cx"> #if ENABLE(CSS_FILTERS)
</span><span class="cx"> && !renderer().hasFilter()
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS)
+ && !hasAcceleratedTouchScrolling()
+#endif
</ins><span class="cx"> #if ENABLE(CSS_COMPOSITING)
</span><span class="cx"> && !renderer().hasBlendMode()
</span><span class="cx"> #endif
</span><span class="lines">@@ -6397,7 +6569,7 @@
</span><span class="cx">
</span><span class="cx"> #endif // USE(ACCELERATED_COMPOSITING)
</span><span class="cx">
</span><del>-void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
</del><ins>+void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
</ins><span class="cx"> {
</span><span class="cx"> bool isNormalFlowOnly = shouldBeNormalFlowOnly();
</span><span class="cx"> if (isNormalFlowOnly != m_isNormalFlowOnly) {
</span><span class="lines">@@ -6477,6 +6649,13 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+ if (diff == StyleDifferenceRecompositeLayer || diff >= StyleDifferenceLayoutPositionedMovementOnly)
+ renderer().document().dirtyTouchEventRects();
+#else
+ UNUSED_PARAM(diff);
+#endif
+
</ins><span class="cx"> #if ENABLE(CSS_FILTERS)
</span><span class="cx"> updateOrRemoveFilterEffectRenderer();
</span><span class="cx"> #if USE(ACCELERATED_COMPOSITING)
</span><span class="lines">@@ -6510,6 +6689,18 @@
</span><span class="cx"> updateNeedsCompositedScrolling();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><ins>+
+#if PLATFORM(IOS)
+ if (addedOrRemoved) {
+ if (isScrollable && !hasAcceleratedTouchScrolling())
+ registerAsTouchEventListenerForScrolling();
+ else {
+ // We only need the touch listener for unaccelerated overflow scrolling, so if we became
+ // accelerated, remove ourselves as a touch event listener.
+ unregisterAsTouchEventListenerForScrolling();
+ }
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderLayer::updateScrollCornerStyle()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayer.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -320,6 +320,10 @@
</span><span class="cx"> explicit RenderLayer(RenderLayerModelObject&);
</span><span class="cx"> virtual ~RenderLayer();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // Called before the renderer's widget (if any) has been nulled out.
+ void willBeDestroyed();
+#endif
</ins><span class="cx"> String name() const;
</span><span class="cx">
</span><span class="cx"> RenderLayerModelObject& renderer() const { return m_renderer; }
</span><span class="lines">@@ -420,6 +424,27 @@
</span><span class="cx"> virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); }
</span><span class="cx"> virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#if ENABLE(TOUCH_EVENTS)
+ virtual bool handleTouchEvent(const PlatformTouchEvent&) OVERRIDE;
+ virtual bool isTouchScrollable() const OVERRIDE { return true; }
+#endif
+ virtual bool isOverflowScroll() const OVERRIDE { return true; }
+
+ virtual void didStartScroll() OVERRIDE;
+ virtual void didEndScroll() OVERRIDE;
+ virtual void didUpdateScroll() OVERRIDE;
+ virtual void setIsUserScroll(bool isUserScroll) OVERRIDE { m_inUserScroll = isUserScroll; }
+
+ bool isInUserScroll() const { return m_inUserScroll; }
+
+ bool requiresScrollBoundsOriginUpdate() const { return m_requiresScrollBoundsOriginUpdate; }
+ void setRequiresScrollBoundsOriginUpdate(bool requiresUpdate = true) { m_requiresScrollBoundsOriginUpdate = requiresUpdate; }
+
+ bool hasAcceleratedTouchScrolling() const;
+
+#endif
+
</ins><span class="cx"> int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
</span><span class="cx"> int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
</span><span class="cx">
</span><span class="lines">@@ -728,6 +753,11 @@
</span><span class="cx"> void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; }
</span><span class="cx"> void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ bool adjustForIOSCaretWhenScrolling() const { return m_adjustForIOSCaretWhenScrolling; }
+ void setAdjustForIOSCaretWhenScrolling(bool adjustForIOSCaretWhenScrolling) { m_adjustForIOSCaretWhenScrolling = adjustForIOSCaretWhenScrolling; }
+#endif
+
</ins><span class="cx"> bool hasTransform() const { return renderer().hasTransform(); }
</span><span class="cx"> // Note that this transform has the transform-origin baked in.
</span><span class="cx"> TransformationMatrix* transform() const { return m_transform.get(); }
</span><span class="lines">@@ -1044,6 +1074,11 @@
</span><span class="cx"> virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
</span><span class="cx"> virtual bool updatesScrollLayerPositionOnMainThread() const OVERRIDE { return true; }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ void registerAsTouchEventListenerForScrolling();
+ void unregisterAsTouchEventListenerForScrolling();
+#endif
+
</ins><span class="cx"> // Rectangle encompassing the scroll corner and resizer rect.
</span><span class="cx"> IntRect scrollCornerAndResizerRect() const;
</span><span class="cx">
</span><span class="lines">@@ -1204,6 +1239,13 @@
</span><span class="cx"> unsigned m_viewportConstrainedNotCompositedReason : 2;
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ bool m_adjustForIOSCaretWhenScrolling : 1;
+ bool m_registeredAsTouchEventListenerForScrolling : 1;
+ bool m_inUserScroll : 1;
+ bool m_requiresScrollBoundsOriginUpdate : 1;
+#endif
+
</ins><span class="cx"> bool m_containsDirtyOverlayScrollbars : 1;
</span><span class="cx"> bool m_updatingMarqueePosition : 1;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -312,8 +312,11 @@
</span><span class="cx"> m_childContainmentLayer = createGraphicsLayer("TiledBacking Flattening Layer");
</span><span class="cx">
</span><span class="cx"> if (m_isMainFrameRenderViewLayer) {
</span><ins>+#if !PLATFORM(IOS)
+ // Page scale is applied above the RenderView on iOS.
</ins><span class="cx"> m_graphicsLayer->setContentsOpaque(true);
</span><span class="cx"> m_graphicsLayer->setAppliesPageScale();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(MAC) && USE(CA)
</span><span class="lines">@@ -334,6 +337,18 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderLayerBacking::layerWillBeDestroyed()
+{
+ RenderObject& renderer = this->renderer();
+ if (renderer.isEmbeddedObject() && toRenderEmbeddedObject(renderer).allowsAcceleratedCompositing()) {
+ PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(renderer).widget());
+ if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
+ pluginViewBase->detachPluginLayer();
+ }
+}
+#endif
+
</ins><span class="cx"> void RenderLayerBacking::destroyGraphicsLayers()
</span><span class="cx"> {
</span><span class="cx"> if (m_graphicsLayer) {
</span><span class="lines">@@ -395,27 +410,48 @@
</span><span class="cx"> || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+// FIXME: We should merge the concept of RenderLayer::{hasAcceleratedTouchScrolling, needsCompositedScrolling}()
+// so that we can remove this iOS-specific variant.
+static bool layerOrAncestorIsTransformedOrScrolling(RenderLayer& layer)
+{
+ for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
+ if (curr->hasTransform() || curr->hasAcceleratedTouchScrolling())
+ return true;
+ }
+
+ return false;
+}
+#else
</ins><span class="cx"> static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer& layer)
</span><span class="cx"> {
</span><span class="cx"> for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
</span><span class="cx"> if (curr->hasTransform() || curr->needsCompositedScrolling())
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><del>-
</del><ins>+#endif
+
</ins><span class="cx"> bool RenderLayerBacking::shouldClipCompositedBounds() const
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // Scrollbar layers use this layer for relative positioning, so don't clip.
</span><span class="cx"> if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
</span><span class="cx"> return false;
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (m_usingTiledCacheLayer)
</span><span class="cx"> return false;
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
</span><span class="cx"> return false;
</span><ins>+#else
+ if (layerOrAncestorIsTransformedOrScrolling(m_owningLayer))
+ return false;
+#endif
</ins><span class="cx">
</span><span class="cx"> if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions())
</span><span class="cx"> return false;
</span><span class="lines">@@ -516,9 +552,15 @@
</span><span class="cx">
</span><span class="cx"> bool needsDescendentsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx"> // Our scrolling layer will clip.
</span><ins>+ if (m_owningLayer.hasAcceleratedTouchScrolling())
+ needsDescendentsClippingLayer = false;
+#else
+ // Our scrolling layer will clip.
</ins><span class="cx"> if (m_owningLayer.needsCompositedScrolling())
</span><span class="cx"> needsDescendentsClippingLayer = false;
</span><ins>+#endif // PLATFORM(IOS)
</ins><span class="cx">
</span><span class="cx"> if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
</span><span class="cx"> layerConfigChanged = true;
</span><span class="lines">@@ -529,8 +571,13 @@
</span><span class="cx"> if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
</span><span class="cx"> layerConfigChanged = true;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (updateScrollingLayers(m_owningLayer.hasAcceleratedTouchScrolling()))
+ layerConfigChanged = true;
+#else
</ins><span class="cx"> if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling()))
</span><span class="cx"> layerConfigChanged = true;
</span><ins>+#endif // PLATFORM(IOS)
</ins><span class="cx">
</span><span class="cx"> if (layerConfigChanged)
</span><span class="cx"> updateInternalHierarchy();
</span><span class="lines">@@ -562,8 +609,15 @@
</span><span class="cx">
</span><span class="cx"> if (renderer().isEmbeddedObject() && toRenderEmbeddedObject(&renderer())->allowsAcceleratedCompositing()) {
</span><span class="cx"> PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(&renderer())->widget());
</span><ins>+#if PLATFORM(IOS)
+ if (pluginViewBase && !m_graphicsLayer->contentsLayerForMedia()) {
+ pluginViewBase->detachPluginLayer();
+ pluginViewBase->attachPluginLayer();
+ }
+#else
</ins><span class="cx"> if (!pluginViewBase->shouldNotAddLayer())
</span><span class="cx"> m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> #if ENABLE(VIDEO)
</span><span class="cx"> else if (renderer().isVideo()) {
</span><span class="lines">@@ -669,6 +723,18 @@
</span><span class="cx"> else
</span><span class="cx"> graphicsLayerParentLocation = renderer().view().documentRect().location();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (compAncestor && compAncestor->hasAcceleratedTouchScrolling()) {
+ RenderBox* renderBox = toRenderBox(&compAncestor->renderer());
+ IntRect paddingBox(renderBox->borderLeft(), renderBox->borderTop(),
+ renderBox->width() - renderBox->borderLeft() - renderBox->borderRight(),
+ renderBox->height() - renderBox->borderTop() - renderBox->borderBottom());
+
+ IntSize scrollOffset = compAncestor->scrolledContentOffset();
+ graphicsLayerParentLocation = paddingBox.location() - scrollOffset;
+ }
+#endif
+
</ins><span class="cx"> if (compAncestor && compAncestor->needsCompositedScrolling()) {
</span><span class="cx"> RenderBox& renderBox = toRenderBox(compAncestor->renderer());
</span><span class="cx"> IntSize scrollOffset = compAncestor->scrolledContentOffset();
</span><span class="lines">@@ -822,6 +888,35 @@
</span><span class="cx"> m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
</span><span class="cx">
</span><span class="cx"> m_scrollingLayer->setSize(paddingBox.size());
</span><ins>+#if PLATFORM(IOS)
+ IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
+ m_scrollingLayer->setOffsetFromRenderer(IntPoint() - paddingBox.location());
+ bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
+
+ if (m_owningLayer.isInUserScroll()) {
+ // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause
+ // jitter. Set a flag to ensure that we sync up later.
+ m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
+ } else {
+ // Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
+ m_scrollingLayer->setBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
+ m_owningLayer.setRequiresScrollBoundsOriginUpdate(false);
+ }
+
+ IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
+
+ m_scrollingContentsLayer->setPosition(FloatPoint());
+
+ if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
+ m_scrollingContentsLayer->setNeedsDisplay();
+
+ m_scrollingContentsLayer->setSize(scrollSize);
+ // Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
+ // FIXME: The paint offset and the scroll offset should really be separate concepts.
+ m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - IntPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
+
+ compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
+#else
</ins><span class="cx"> m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
</span><span class="cx">
</span><span class="cx"> IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
</span><span class="lines">@@ -840,6 +935,7 @@
</span><span class="cx"> m_scrollingContentsLayer->setSize(scrollSize);
</span><span class="cx"> // FIXME: The paint offset and the scroll offset should really be separate concepts.
</span><span class="cx"> m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (m_foregroundLayer) {
</span><span class="cx"> m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
</span><span class="lines">@@ -909,6 +1005,9 @@
</span><span class="cx">
</span><span class="cx"> void RenderLayerBacking::registerScrollingLayers()
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ compositor().updateViewportConstraintStatus(m_owningLayer);
+#else
</ins><span class="cx"> // Register fixed position layers and their containers with the scrolling coordinator.
</span><span class="cx"> ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
</span><span class="cx"> if (!scrollingCoordinator)
</span><span class="lines">@@ -924,6 +1023,7 @@
</span><span class="cx"> // layer as a container.
</span><span class="cx"> bool isContainer = m_owningLayer.hasTransform() && !m_owningLayer.isRootLayer();
</span><span class="cx"> scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderLayerBacking::updateInternalHierarchy()
</span><span class="lines">@@ -1320,8 +1420,16 @@
</span><span class="cx"> layerChanged = true;
</span><span class="cx"> if (scrollingCoordinator)
</span><span class="cx"> scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
</span><ins>+#if PLATFORM(IOS)
+ if (m_owningLayer.parent())
+ compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> } else if (m_scrollingLayer) {
</span><ins>+#if PLATFORM(IOS)
+ if (!renderer().documentBeingDestroyed())
+ compositor().scrollingLayerRemoved(&m_owningLayer, m_scrollingLayer->platformLayer(), m_scrollingContentsLayer->platformLayer());
+#endif
</ins><span class="cx"> willDestroyLayer(m_scrollingLayer.get());
</span><span class="cx"> willDestroyLayer(m_scrollingContentsLayer.get());
</span><span class="cx"> m_scrollingLayer = nullptr;
</span><span class="lines">@@ -1334,8 +1442,10 @@
</span><span class="cx"> if (layerChanged) {
</span><span class="cx"> updateInternalHierarchy();
</span><span class="cx"> m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> m_graphicsLayer->setNeedsDisplay();
</span><span class="cx"> compositor().scrollingLayerDidChange(m_owningLayer);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return layerChanged;
</span><span class="lines">@@ -1725,8 +1835,8 @@
</span><span class="cx"> if (renderer().isVideo() && toRenderVideo(renderer()).shouldDisplayVideo())
</span><span class="cx"> return m_owningLayer.hasBoxDecorationsOrBackground();
</span><span class="cx"> #endif
</span><del>-#if PLATFORM(MAC) && USE(CA)
-#elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
</del><ins>+#if PLATFORM(MAC) && !PLATFORM(IOS) && USE(CA)
+#elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS) || PLATFORM(IOS_SIMULATOR)
</ins><span class="cx"> if (isAcceleratedCanvas(&renderer()))
</span><span class="cx"> return m_owningLayer.hasBoxDecorationsOrBackground();
</span><span class="cx"> #endif
</span><span class="lines">@@ -1903,7 +2013,14 @@
</span><span class="cx"> if (m_scrollingContentsLayer)
</span><span class="cx"> return m_scrollingContentsLayer.get();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // FIXME: Can we remove this iOS-specific code path?
+ if (GraphicsLayer* clippingLayer = this->clippingLayer())
+ return clippingLayer;
+ return m_graphicsLayer.get();
+#else
</ins><span class="cx"> return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
</span><span class="lines">@@ -1923,7 +2040,7 @@
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> if (m_owningLayer.isRootLayer()) {
</span><del>-#if PLATFORM(BLACKBERRY) || USE(COORDINATED_GRAPHICS)
</del><ins>+#if PLATFORM(BLACKBERRY) || PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
</ins><span class="cx"> if (compositor().inForcedCompositingMode())
</span><span class="cx"> return false;
</span><span class="cx"> #endif
</span><span class="lines">@@ -2016,6 +2133,10 @@
</span><span class="cx"> if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
</span><span class="cx"> IntRect layerDirtyRect = r;
</span><span class="cx"> layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
</span><ins>+#if PLATFORM(IOS)
+ // Account for the fact that RenderLayerBacking::updateGraphicsLayerGeometry() bakes scrollOffset into offsetFromRenderer on iOS.
+ layerDirtyRect.move(-m_owningLayer.scrollOffset());
+#endif
</ins><span class="cx"> m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -2025,7 +2146,12 @@
</span><span class="cx"> PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
</span><span class="cx"> {
</span><span class="cx"> if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
</span><ins>+#if !PLATFORM(IOS)
+ // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
+ // when pages are restored from the PageCache.
+ // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
</ins><span class="cx"> ASSERT_NOT_REACHED();
</span><ins>+#endif
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -60,6 +60,10 @@
</span><span class="cx"> explicit RenderLayerBacking(RenderLayer&);
</span><span class="cx"> ~RenderLayerBacking();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ void layerWillBeDestroyed();
+#endif
+
</ins><span class="cx"> RenderLayer& owningLayer() const { return m_owningLayer; }
</span><span class="cx">
</span><span class="cx"> enum UpdateAfterLayoutFlag {
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -66,6 +66,12 @@
</span><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx"> #include <wtf/text/StringBuilder.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "Region.h"
+#include "RenderScrollbar.h"
+#include "TileCache.h"
+#endif
+
</ins><span class="cx"> #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
</span><span class="cx"> #include "HTMLAudioElement.h"
</span><span class="cx"> #include "HTMLMediaElement.h"
</span><span class="lines">@@ -88,7 +94,12 @@
</span><span class="cx">
</span><span class="cx"> static const int canvasAreaThresholdRequiringCompositing = 50 * 100;
</span><span class="cx"> // During page loading delay layer flushes up to this many seconds to allow them coalesce, reducing workload.
</span><ins>+#if PLATFORM(IOS)
+static const double throttledLayerFlushInitialDelay = .5;
+static const double throttledLayerFlushDelay = 1.5;
+#else
</ins><span class="cx"> static const double throttledLayerFlushDelay = .5;
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx">
</span><span class="lines">@@ -360,6 +371,11 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!m_flushingLayers);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (canThrottle)
+ startInitialLayerFlushTimerIfNeeded();
+#endif
+
</ins><span class="cx"> if (canThrottle && isThrottlingLayerFlushes()) {
</span><span class="cx"> m_hasPendingLayerFlush = true;
</span><span class="cx"> return;
</span><span class="lines">@@ -367,6 +383,16 @@
</span><span class="cx"> scheduleLayerFlushNow();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ChromeClient* RenderLayerCompositor::chromeClient() const
+{
+ Page* page = m_renderView.frameView().frame().page();
+ if (!page)
+ return 0;
+ return &page->chrome().client();
+}
+#endif
+
</ins><span class="cx"> void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
</span><span class="cx"> {
</span><span class="cx"> // FrameView::flushCompositingStateIncludingSubframes() flushes each subframe,
</span><span class="lines">@@ -377,6 +403,9 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> if (rootLayerAttachment() == RootLayerUnattached) {
</span><ins>+#if PLATFORM(IOS)
+ startLayerFlushTimerIfNeeded();
+#endif
</ins><span class="cx"> m_shouldFlushOnReattach = true;
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -388,26 +417,82 @@
</span><span class="cx"> m_flushingLayers = true;
</span><span class="cx">
</span><span class="cx"> if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
</span><ins>+#if PLATFORM(IOS)
+ rootLayer->flushCompositingState(frameView.visibleExtentContentRect());
+#else
</ins><span class="cx"> // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
</span><span class="cx"> IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.contentsSize()) : frameView.visibleContentRect();
</span><span class="cx"> rootLayer->flushCompositingState(visibleRect);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ASSERT(m_flushingLayers);
</span><span class="cx"> m_flushingLayers = false;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ updateCustomLayersAfterFlush();
+
+ ChromeClient* client = this->chromeClient();
+ if (client && isFlushRoot)
+ client->didFlushCompositingLayers();
+#else
</ins><span class="cx"> for (auto it = m_viewportConstrainedLayersNeedingUpdate.begin(), end = m_viewportConstrainedLayersNeedingUpdate.end(); it != end; ++it)
</span><span class="cx"> registerOrUpdateViewportConstrainedLayer(**it);
</span><span class="cx"> m_viewportConstrainedLayersNeedingUpdate.clear();
</span><del>-
</del><ins>+#endif
</ins><span class="cx"> startLayerFlushTimerIfNeeded();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static bool scrollbarHasDisplayNone(Scrollbar* scrollbar)
+{
+ if (!scrollbar || !scrollbar->isCustomScrollbar())
+ return false;
+
+ RefPtr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, SCROLLBAR);
+ return scrollbarStyle && scrollbarStyle->display() == NONE;
+}
+
+// FIXME: Can we make |layer| const RenderLayer&?
+static void updateScrollingLayerWithClient(RenderLayer& layer, ChromeClient* client)
+{
+ if (!client)
+ return;
+
+ RenderLayerBacking* backing = layer->backing();
+ ASSERT(backing);
+
+ bool allowHorizontalScrollbar = !scrollbarHasDisplayNone(layer->horizontalScrollbar());
+ bool allowVerticalScrollbar = !scrollbarHasDisplayNone(layer->verticalScrollbar());
+ client->addOrUpdateScrollingLayer(layer->renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer(),
+ IntSize(layer->scrollWidth(), layer->scrollHeight()), allowHorizontalScrollbar, allowVerticalScrollbar);
+}
+
+void RenderLayerCompositor::updateCustomLayersAfterFlush()
+{
+ registerAllViewportConstrainedLayers();
+
+ if (!m_scrollingLayersNeedingUpdate.isEmpty()) {
+ ChromeClient* chromeClient = this->chromeClient();
+
+ for (auto it = m_scrollingLayersNeedingUpdate.begin(), end = m_scrollingLayersNeedingUpdate.end(); it != end; ++it)
+ updateScrollingLayerWithClient(**it, chromeClient);
+ m_scrollingLayersNeedingUpdate.clear();
+ }
+ m_scrollingLayersNeedingUpdate.clear();
+}
+#endif
+
</ins><span class="cx"> void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer& layer, const GraphicsLayer* graphicsLayer)
</span><span class="cx"> {
</span><span class="cx"> if (m_viewportConstrainedLayers.contains(&layer))
</span><span class="cx"> m_viewportConstrainedLayersNeedingUpdate.add(&layer);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (m_scrollingLayers.contains(&layer))
+ m_scrollingLayersNeedingUpdate.add(&layer);
+#endif
+
</ins><span class="cx"> RenderLayerBacking* backing = layer.backing();
</span><span class="cx"> if (backing->backgroundLayerPaintsFixedRootBackground() && graphicsLayer == backing->backgroundLayer())
</span><span class="cx"> fixedRootBackgroundLayerChanged();
</span><span class="lines">@@ -428,7 +513,12 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> const FrameView& frameView = m_renderView.frameView();
</span><ins>+
+#if PLATFORM(IOS)
+ IntRect visibleRect = frameView.visibleExtentContentRect();
+#else
</ins><span class="cx"> IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.contentsSize()) : frameView.visibleContentRect();
</span><ins>+#endif
</ins><span class="cx"> if (!rootLayer->visibleRectChangeRequiresFlush(visibleRect))
</span><span class="cx"> return;
</span><span class="cx"> scheduleLayerFlushNow();
</span><span class="lines">@@ -877,9 +967,14 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> IntRect clipRect = pixelSnappedIntRect(layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
</span><ins>+
+ // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
+ // FIXME: Set Settings::delegatesPageScaling to true for iOS.
+#if !PLATFORM(IOS)
</ins><span class="cx"> const Settings& settings = m_renderView.frameView().frame().settings();
</span><span class="cx"> if (!settings.delegatesPageScaling())
</span><span class="cx"> clipRect.scale(pageScaleFactor());
</span><ins>+#endif
</ins><span class="cx"> clipRect.intersect(layerBounds);
</span><span class="cx"> overlapMap.add(&layer, clipRect);
</span><span class="cx"> }
</span><span class="lines">@@ -1119,8 +1214,11 @@
</span><span class="cx"> // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
</span><span class="cx"> // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
</span><span class="cx"> if (layer.isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
</span><ins>+ // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>.
+#if !PLATFORM(IOS)
</ins><span class="cx"> enableCompositingMode(false);
</span><span class="cx"> willBeComposited = false;
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // If the layer is going into compositing mode, repaint its old location.
</span><span class="lines">@@ -1699,11 +1797,19 @@
</span><span class="cx">
</span><span class="cx"> RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
</span><span class="cx"> attachRootLayer(attachment);
</span><ins>+#if PLATFORM(IOS)
+ registerAllViewportConstrainedLayers();
+ registerAllScrollingLayers();
+#endif
</ins><span class="cx"> } else {
</span><span class="cx"> if (m_rootLayerAttachment == RootLayerUnattached)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> detachRootLayer();
</span><ins>+#if PLATFORM(IOS)
+ unregisterAllViewportConstrainedLayers();
+ unregisterAllScrollingLayers();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1758,7 +1864,7 @@
</span><span class="cx">
</span><span class="cx"> bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
</span><span class="cx"> {
</span><del>-#if PLATFORM(MAC)
</del><ins>+#if PLATFORM(MAC) && !PLATFORM(IOS)
</ins><span class="cx"> // frames are only independently composited in Mac pre-WebKit2.
</span><span class="cx"> return view->platformWidget();
</span><span class="cx"> #else
</span><span class="lines">@@ -1832,6 +1938,9 @@
</span><span class="cx"> || requiresCompositingForAnimation(*renderer)
</span><span class="cx"> || requiresCompositingForFilters(*renderer)
</span><span class="cx"> || requiresCompositingForPosition(*renderer, *renderer->layer(), viewportConstrainedNotCompositedReason)
</span><ins>+#if PLATFORM(IOS)
+ || requiresCompositingForScrolling(*renderer)
+#endif
</ins><span class="cx"> || requiresCompositingForOverflowScrolling(*renderer->layer())
</span><span class="cx"> || requiresCompositingForBlending(*renderer);
</span><span class="cx"> }
</span><span class="lines">@@ -1878,7 +1987,11 @@
</span><span class="cx"> || renderer.isTransparent()
</span><span class="cx"> || renderer.hasMask()
</span><span class="cx"> || renderer.hasReflection()
</span><del>- || renderer.hasFilter())
</del><ins>+ || renderer.hasFilter()
+#if PLATFORM(IOS)
+ || requiresCompositingForScrolling(renderer)
+#endif
+ )
</ins><span class="cx"> return true;
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -1935,6 +2048,11 @@
</span><span class="cx"> if (requiresCompositingForPosition(*renderer, *renderer->layer()))
</span><span class="cx"> reasons |= renderer->style().position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (requiresCompositingForScrolling(*renderer))
+ reasons |= CompositingReasonOverflowScrollingTouch;
+#endif
+
</ins><span class="cx"> if (requiresCompositingForOverflowScrolling(*renderer->layer()))
</span><span class="cx"> reasons |= CompositingReasonOverflowScrollingTouch;
</span><span class="cx">
</span><span class="lines">@@ -2217,10 +2335,10 @@
</span><span class="cx"> return (animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyOpacity)
</span><span class="cx"> && (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
</span><span class="cx"> #if ENABLE(CSS_FILTERS)
</span><del>-#if !PLATFORM(MAC) || (!PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
</del><ins>+#if PLATFORM(IOS) || !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
</ins><span class="cx"> // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
</span><span class="cx"> || animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyWebkitFilter)
</span><del>-#endif // !PLATFORM(MAC) || (!PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
</del><ins>+#endif // PLATFORM(IOS) || !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
</ins><span class="cx"> #endif // CSS_FILTERS
</span><span class="cx"> || animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyWebkitTransform);
</span><span class="cx"> }
</span><span class="lines">@@ -2254,6 +2372,13 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+bool RenderLayerCompositor::requiresCompositingForScrolling(RenderLayerModelObject& renderer) const
+{
+ return renderer.hasLayer() && toRenderBoxModelObject(renderer).layer()->hasAcceleratedTouchScrolling();
+}
+#endif
+
</ins><span class="cx"> bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(CSS_FILTERS)
</span><span class="lines">@@ -2277,10 +2402,31 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static bool isStickyInAcceleratedScrollingLayerOrViewport(const RenderLayer& layer, const RenderLayer** enclosingAcceleratedOverflowLayer = 0)
+{
+ ASSERT(layer.renderer().isStickyPositioned());
+
+ RenderLayer* enclosingOverflowLayer = layer.enclosingOverflowClipLayer(ExcludeSelf);
+ if (enclosingOverflowLayer && enclosingOverflowLayer->hasAcceleratedTouchScrolling()) {
+ if (enclosingAcceleratedOverflowLayer)
+ *enclosingAcceleratedOverflowLayer = enclosingOverflowLayer;
+ return true;
+ }
+
+ return !enclosingOverflowLayer;
+}
+#endif
+
</ins><span class="cx"> static bool isViewportConstrainedFixedOrStickyLayer(const RenderLayer& layer)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx"> if (layer.renderer().isStickyPositioned())
</span><ins>+ return isStickyInAcceleratedScrollingLayerOrViewport(layer);
+#else
+ if (layer.renderer().isStickyPositioned())
</ins><span class="cx"> return !layer.enclosingOverflowClipLayer(ExcludeSelf);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (layer.renderer().style().position() != FixedPosition)
</span><span class="cx"> return false;
</span><span class="lines">@@ -2295,9 +2441,24 @@
</span><span class="cx">
</span><span class="cx"> bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ if (renderer.isStickyPositioned())
+ return true;
+
</ins><span class="cx"> // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
</span><span class="cx"> // opacity, transform) can get their own composited layer. A stacking context is required otherwise
</span><span class="cx"> // z-index and clipping will be broken.
</span><ins>+ if (!(renderer.isOutOfFlowPositioned() && renderer.style().position() == FixedPosition))
+ return false;
+
+ if (!m_renderView.hasCustomFixedPosition(renderer, RenderView::CheckContainingBlock)) {
+ m_reevaluateCompositingAfterLayout = true;
+ return false;
+ }
+#else
+ // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
+ // opacity, transform) can get their own composited layer. A stacking context is required otherwise
+ // z-index and clipping will be broken.
</ins><span class="cx"> if (!renderer.isPositioned())
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -2317,6 +2478,7 @@
</span><span class="cx">
</span><span class="cx"> if (isSticky)
</span><span class="cx"> return hasCoordinatedScrolling() && isViewportConstrainedFixedOrStickyLayer(layer);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> auto container = renderer.container();
</span><span class="cx"> // If the renderer is not hooked up yet then we have to wait until it is.
</span><span class="lines">@@ -2347,7 +2509,11 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Fixed position elements that are invisible in the current view don't get their own layer.
</span><ins>+#if PLATFORM(IOS)
+ LayoutRect viewBounds = m_renderView.frameView().customFixedPositionLayoutRect();
+#else
</ins><span class="cx"> LayoutRect viewBounds = m_renderView.frameView().viewportConstrainedVisibleContentRect();
</span><ins>+#endif
</ins><span class="cx"> LayoutRect layerBounds = layer.calculateLayerBounds(&layer, 0, RenderLayer::UseLocalClipRectIfPossible | RenderLayer::IncludeLayerFilterOutsets | RenderLayer::UseFragmentBoxes
</span><span class="cx"> | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask | RenderLayer::IncludeCompositedDescendants);
</span><span class="cx"> // Map to m_renderView to ignore page scale.
</span><span class="lines">@@ -2495,6 +2661,16 @@
</span><span class="cx">
</span><span class="cx"> float RenderLayerCompositor::contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ TileCache* tileCache = nullptr;
+ if (Page* page = this->page())
+ tileCache = page->mainFrame().view().tileCache();
+
+ if (!tileCache)
+ return 1;
+
+ return tileCache->tilingMode() == TileCache::Zooming ? 0.125 : 1;
+#endif
</ins><span class="cx"> return 1;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2869,6 +3045,14 @@
</span><span class="cx"> m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
</span><span class="cx"> m_rootContentLayer->setPosition(FloatPoint());
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ // Page scale is applied above this on iOS, so we'll just say that our root layer applies it.
+ Frame& frame = m_renderView.frameView().frame();
+ Page* page = frame.page();
+ if (page && &page->mainFrame() == &frame)
+ m_rootContentLayer->setAppliesPageScale();
+#endif
+
</ins><span class="cx"> // Need to clip to prevent transformed content showing outside this frame
</span><span class="cx"> m_rootContentLayer->setMasksToBounds(true);
</span><span class="cx"> }
</span><span class="lines">@@ -3149,7 +3333,11 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(layer.isComposited());
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ LayoutRect viewportRect = m_renderView.frameView().customFixedPositionLayoutRect();
+#else
</ins><span class="cx"> LayoutRect viewportRect = m_renderView.frameView().viewportConstrainedVisibleContentRect();
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> FixedPositionViewportConstraints constraints;
</span><span class="cx">
</span><span class="lines">@@ -3185,10 +3373,17 @@
</span><span class="cx"> StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer& layer) const
</span><span class="cx"> {
</span><span class="cx"> ASSERT(layer.isComposited());
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // We should never get here for stickies constrained by an enclosing clipping layer.
</span><ins>+ // FIXME: Why does this assertion fail on iOS?
</ins><span class="cx"> ASSERT(!layer.enclosingOverflowClipLayer(ExcludeSelf));
</span><ins>+#endif
</ins><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ LayoutRect viewportRect = m_renderView.frameView().customFixedPositionLayoutRect();
+#else
</ins><span class="cx"> LayoutRect viewportRect = m_renderView.frameView().viewportConstrainedVisibleContentRect();
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> RenderBoxModelObject& renderer = toRenderBoxModelObject(layer.renderer());
</span><span class="cx">
</span><span class="lines">@@ -3203,6 +3398,7 @@
</span><span class="cx"> return constraints;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> static RenderLayerBacking* nearestScrollingCoordinatorAncestor(RenderLayer& layer)
</span><span class="cx"> {
</span><span class="cx"> RenderLayer* ancestor = layer.parent();
</span><span class="lines">@@ -3216,9 +3412,14 @@
</span><span class="cx">
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> void RenderLayerCompositor::registerOrUpdateViewportConstrainedLayer(RenderLayer& layer)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(layer);
+ // On iOS, we batch-update viewport-constrained layers in updateCustomLayersAfterFlush().
+#else
</ins><span class="cx"> // FIXME: We should support sticky position here! And we should eventuall support fixed/sticky elements
</span><span class="cx"> // that are inside non-main frames once we get non-main frames scrolling with the ScrollingCoordinator.
</span><span class="cx"> if (m_renderView.document().ownerElement())
</span><span class="lines">@@ -3252,16 +3453,113 @@
</span><span class="cx"> scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeStickyViewportConstraints(layer), backing->graphicsLayer());
</span><span class="cx"> else
</span><span class="cx"> scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeFixedViewportConstraints(layer), backing->graphicsLayer());
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderLayerCompositor::unregisterViewportConstrainedLayer(RenderLayer& layer)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(m_viewportConstrainedLayers.contains(&layer));
</span><del>-
</del><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(layer);
+ // On iOS, we batch-update viewport-constrained layers in updateCustomLayersAfterFlush().
+#else
</ins><span class="cx"> if (RenderLayerBacking* backing = layer.backing())
</span><span class="cx"> backing->detachFromScrollingCoordinator();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+typedef HashMap<PlatformLayer*, std::unique_ptr<ViewportConstraints>> LayerMap;
+typedef HashMap<PlatformLayer*, PlatformLayer*> StickyContainerMap;
+
+void RenderLayerCompositor::registerAllViewportConstrainedLayers()
+{
+ // Only the main frame should register fixed/sticky layers.
+ if (m_renderView.document().ownerElement())
+ return;
+
+ LayerMap layerMap;
+ StickyContainerMap stickyContainerMap;
+
+ for (auto it = m_viewportConstrainedLayers.begin(), end = m_viewportConstrainedLayers.end(); it != end; ++it) {
+ RenderLayer& layer = **it;
+ ASSERT(layer.isComposited());
+
+ std::unique_ptr<ViewportConstraints> constraints;
+ if (layer.renderer().isStickyPositioned()) {
+ constraints = std::make_unique<ViewportConstraints>(new StickyPositionViewportConstraints(computeStickyViewportConstraints(layer)));
+ const RenderLayer* enclosingTouchScrollableLayer = nullptr;
+ if (isStickyInAcceleratedScrollingLayerOrViewport(layer, &enclosingTouchScrollableLayer) && enclosingTouchScrollableLayer) {
+ ASSERT(enclosingTouchScrollableLayer->isComposited());
+ stickyContainerMap.add(layer.backing()->graphicsLayer()->platformLayer(), enclosingTouchScrollableLayer->backing()->scrollingLayer()->platformLayer());
+ }
+ } else
+ constraints = std::make_unique<ViewportConstraints>(new FixedPositionViewportConstraints(computeFixedViewportConstraints(layer)));
+
+ layerMap.add(layer.backing()->graphicsLayer()->platformLayer(), constraints.release());
+ }
+
+ if (ChromeClient* client = this->chromeClient())
+ client->updateViewportConstrainedLayers(layerMap, stickyContainerMap);
+}
+
+void RenderLayerCompositor::unregisterAllViewportConstrainedLayers()
+{
+ // Only the main frame should register fixed/sticky layers.
+ if (m_renderView.document().ownerElement())
+ return;
+
+ if (ChromeClient* client = this->chromeClient()) {
+ LayerMap layerMap;
+ StickyContainerMap stickyContainerMap;
+ client->updateViewportConstrainedLayers(layerMap, stickyContainerMap);
+ }
+}
+
+void RenderLayerCompositor::registerAllScrollingLayers()
+{
+ ChromeClient* client = this->chromeClient();
+ if (!client)
+ return;
+
+ for (auto it = m_scrollingLayers.begin(), end = m_scrollingLayers.end(); it != end; ++it)
+ updateScrollingLayerWithClient(**it, client);
+}
+
+void RenderLayerCompositor::unregisterAllScrollingLayers()
+{
+ ChromeClient* client = this->chromeClient();
+ if (!client)
+ return;
+
+ for (auto it = m_scrollingLayers.begin(), end = m_scrollingLayers.end(); it != end; ++it) {
+ RenderLayer& layer = **it;
+ RenderLayerBacking* backing = layer.backing();
+ ASSERT(backing);
+ client->removeScrollingLayer(layer.renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer());
+ }
+}
+
+// Called when the size of the contentsLayer changes, and when the contentsLayer is replaced by another layer.
+void RenderLayerCompositor::scrollingLayerAddedOrUpdated(RenderLayer* layer)
+{
+ ASSERT(!m_renderView.document().inPageCache());
+ m_scrollingLayers.add(layer);
+}
+
+void RenderLayerCompositor::scrollingLayerRemoved(RenderLayer* layer, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer)
+{
+ m_scrollingLayersNeedingUpdate.remove(layer);
+ m_scrollingLayers.remove(layer);
+
+ if (m_renderView.document().inPageCache())
+ return;
+
+ if (ChromeClient* client = this->chromeClient())
+ client->removeScrollingLayer(layer->renderer().element(), scrollingLayer, contentsLayer);
+}
+#endif
+
</ins><span class="cx"> void RenderLayerCompositor::windowScreenDidChange(PlatformDisplayID displayID)
</span><span class="cx"> {
</span><span class="cx"> if (m_layerUpdater)
</span><span class="lines">@@ -3327,6 +3625,17 @@
</span><span class="cx"> m_layerFlushTimer.startOneShot(throttledLayerFlushDelay);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+void RenderLayerCompositor::startInitialLayerFlushTimerIfNeeded()
+{
+ if (!m_layerFlushThrottlingEnabled)
+ return;
+ if (m_layerFlushTimer.isActive())
+ return;
+ m_layerFlushTimer.startOneShot(throttledLayerFlushInitialDelay);
+}
+#endif
+
</ins><span class="cx"> void RenderLayerCompositor::layerFlushTimerFired(Timer<RenderLayerCompositor>*)
</span><span class="cx"> {
</span><span class="cx"> if (!m_hasPendingLayerFlush)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -273,6 +273,16 @@
</span><span class="cx"> void updateViewportConstraintStatus(RenderLayer&);
</span><span class="cx"> void removeViewportConstrainedLayer(RenderLayer&);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ void registerAllViewportConstrainedLayers();
+ void unregisterAllViewportConstrainedLayers();
+
+ void scrollingLayerAddedOrUpdated(RenderLayer*);
+ void scrollingLayerRemoved(RenderLayer*, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer);
+
+ void registerAllScrollingLayers();
+ void unregisterAllScrollingLayers();
+#endif
</ins><span class="cx"> void resetTrackedRepaintRects();
</span><span class="cx"> void setTracksRepaints(bool);
</span><span class="cx">
</span><span class="lines">@@ -383,6 +393,16 @@
</span><span class="cx"> bool requiresCompositingForOverflowScrolling(const RenderLayer&) const;
</span><span class="cx"> bool requiresCompositingForIndirectReason(RenderLayerModelObject&, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ bool requiresCompositingForScrolling(RenderLayerModelObject&) const;
+
+ void updateCustomLayersAfterFlush();
+
+ ChromeClient* chromeClient() const;
+
+ void startInitialLayerFlushTimerIfNeeded();
+#endif
+
</ins><span class="cx"> void addViewportConstrainedLayer(RenderLayer&);
</span><span class="cx"> void registerOrUpdateViewportConstrainedLayer(RenderLayer&);
</span><span class="cx"> void unregisterViewportConstrainedLayer(RenderLayer&);
</span><span class="lines">@@ -450,6 +470,10 @@
</span><span class="cx"> std::unique_ptr<GraphicsLayer> m_clipLayer;
</span><span class="cx"> std::unique_ptr<GraphicsLayer> m_scrollLayer;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ HashSet<RenderLayer*> m_scrollingLayers;
+ HashSet<RenderLayer*> m_scrollingLayersNeedingUpdate;
+#endif
</ins><span class="cx"> HashSet<RenderLayer*> m_viewportConstrainedLayers;
</span><span class="cx"> HashSet<RenderLayer*> m_viewportConstrainedLayersNeedingUpdate;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerFilterInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderLayerFilterInfo.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -89,7 +89,16 @@
</span><span class="cx">
</span><span class="cx"> static HashMap<const RenderLayer*, OwnPtr<FilterInfo>>& map();
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#pragma clang diagnostic push
+#if defined(__has_warning) && __has_warning("-Wunused-private-field")
+#pragma clang diagnostic ignored "-Wunused-private-field"
+#endif
+#endif
</ins><span class="cx"> RenderLayer& m_layer;
</span><ins>+#if PLATFORM(IOS)
+#pragma clang diagnostic pop
+#endif
</ins><span class="cx">
</span><span class="cx"> RefPtr<FilterEffectRenderer> m_renderer;
</span><span class="cx"> LayoutRect m_dirtySourceRect;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMenuListcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMenuList.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMenuList.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderMenuList.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -48,10 +48,29 @@
</span><span class="cx"> #include "TextRun.h"
</span><span class="cx"> #include <math.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "LocalizedStrings.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static size_t selectedOptionCount(const RenderMenuList& renderMenuList)
+{
+ const Vector<HTMLElement*>& listItems = renderMenuList.selectElement().listItems();
+ size_t numberOfItems = listItems.size();
+
+ size_t count = 0;
+ for (size_t i = 0; i < numberOfItems; ++i) {
+ if (listItems[i]->hasTagName(optionTag) && toHTMLOptionElement(listItems[i])->selected())
+ ++count;
+ }
+ return count;
+}
+#endif
+
</ins><span class="cx"> RenderMenuList::RenderMenuList(HTMLSelectElement& element, PassRef<RenderStyle> style)
</span><span class="cx"> : RenderFlexibleBox(element, std::move(style))
</span><span class="cx"> , m_buttonText(nullptr)
</span><span class="lines">@@ -59,15 +78,19 @@
</span><span class="cx"> , m_needsOptionsWidthUpdate(true)
</span><span class="cx"> , m_optionsWidth(0)
</span><span class="cx"> , m_lastActiveIndex(-1)
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> , m_popupIsVisible(false)
</span><ins>+#endif
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RenderMenuList::~RenderMenuList()
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (m_popup)
</span><span class="cx"> m_popup->disconnectClient();
</span><span class="cx"> m_popup = 0;
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool RenderMenuList::canBeReplacedWithInlineRunIn() const
</span><span class="lines">@@ -118,6 +141,26 @@
</span><span class="cx"> innerStyle.setTextAlign(LEFT);
</span><span class="cx"> TextDirection direction = (m_buttonText && m_buttonText->text()->defaultWritingDirection() == U_RIGHT_TO_LEFT) ? RTL : LTR;
</span><span class="cx"> innerStyle.setDirection(direction);
</span><ins>+#if PLATFORM(IOS)
+ } else if (document().page()->chrome().selectItemAlignmentFollowsMenuWritingDirection()) {
+ innerStyle.setTextAlign(style().direction() == LTR ? LEFT : RIGHT);
+ TextDirection direction;
+ EUnicodeBidi unicodeBidi;
+ if (multiple() && selectedOptionCount(*this) != 1) {
+ direction = (m_buttonText && m_buttonText->text()->defaultWritingDirection() == U_RIGHT_TO_LEFT) ? RTL : LTR;
+ unicodeBidi = UBNormal;
+ } else if (m_optionStyle) {
+ direction = m_optionStyle->direction();
+ unicodeBidi = m_optionStyle->unicodeBidi();
+ } else {
+ direction = style().direction();
+ unicodeBidi = style().unicodeBidi();
+ }
+
+ innerStyle.setDirection(direction);
+ innerStyle.setUnicodeBidi(unicodeBidi);
+ }
+#else
</ins><span class="cx"> } else if (m_optionStyle && document().page()->chrome().selectItemAlignmentFollowsMenuWritingDirection()) {
</span><span class="cx"> if ((m_optionStyle->direction() != innerStyle.direction() || m_optionStyle->unicodeBidi() != innerStyle.unicodeBidi()))
</span><span class="cx"> m_innerBlock->setNeedsLayoutAndPrefWidthsRecalc();
</span><span class="lines">@@ -125,6 +168,7 @@
</span><span class="cx"> innerStyle.setDirection(m_optionStyle->direction());
</span><span class="cx"> innerStyle.setUnicodeBidi(m_optionStyle->unicodeBidi());
</span><span class="cx"> }
</span><ins>+#endif // !PLATFORM(IOS)
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> HTMLSelectElement& RenderMenuList::selectElement() const
</span><span class="lines">@@ -207,9 +251,11 @@
</span><span class="cx"> m_needsOptionsWidthUpdate = false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (m_popupIsVisible)
</span><span class="cx"> m_popup->updateFromElement();
</span><span class="cx"> else
</span><ins>+#endif
</ins><span class="cx"> setTextFromOption(selectElement().selectedIndex());
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -228,6 +274,14 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (multiple()) {
+ size_t count = selectedOptionCount(*this);
+ if (count != 1)
+ text = htmlSelectMultipleItems(count);
+ }
+#endif
+
</ins><span class="cx"> setText(text.stripWhiteSpace());
</span><span class="cx"> didUpdateActiveOption(optionIndex);
</span><span class="cx"> }
</span><span class="lines">@@ -302,8 +356,15 @@
</span><span class="cx"> setPreferredLogicalWidthsDirty(false);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+NO_RETURN_DUE_TO_ASSERT
</ins><span class="cx"> void RenderMenuList::showPopup()
</span><span class="cx"> {
</span><ins>+ ASSERT_NOT_REACHED();
+}
+#else
+void RenderMenuList::showPopup()
+{
</ins><span class="cx"> if (m_popupIsVisible)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -325,11 +386,14 @@
</span><span class="cx"> absBounds.setLocation(roundedIntPoint(absTopLeft));
</span><span class="cx"> m_popup->show(absBounds, &view().frameView(), selectElement().optionToListIndex(selectElement().selectedIndex()));
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> void RenderMenuList::hidePopup()
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (m_popup)
</span><span class="cx"> m_popup->hide();
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange)
</span><span class="lines">@@ -564,7 +628,9 @@
</span><span class="cx">
</span><span class="cx"> void RenderMenuList::popupDidHide()
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> m_popupIsVisible = false;
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMenuListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMenuList.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMenuList.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderMenuList.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -48,7 +48,9 @@
</span><span class="cx">
</span><span class="cx"> HTMLSelectElement& selectElement() const;
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> bool popupIsVisible() const { return m_popupIsVisible; }
</span><ins>+#endif
</ins><span class="cx"> void showPopup();
</span><span class="cx"> void hidePopup();
</span><span class="cx">
</span><span class="lines">@@ -145,8 +147,10 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<RenderStyle> m_optionStyle;
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> RefPtr<PopupMenu> m_popup;
</span><span class="cx"> bool m_popupIsVisible;
</span><ins>+#endif
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> template<> inline bool isRendererOfType<const RenderMenuList>(const RenderObject& renderer) { return renderer.isMenuList(); }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -67,6 +67,10 @@
</span><span class="cx"> #include "SVGRenderSupport.h"
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "SelectionRect.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="lines">@@ -1127,6 +1131,57 @@
</span><span class="cx"> graphicsContext->endTransparencyLayer();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+// FIXME: Make this return an unsigned integer?
+int RenderObject::columnNumberForOffset(int offset)
+{
+ int columnNumber = 0;
+ RenderBlock* containingBlock = this->containingBlock();
+ RenderView& view = containingBlock->view();
+ const Pagination& pagination = view.frameView().frame().page()->pagination();
+ if (pagination.mode == Pagination::Unpaginated)
+ return columnNumber;
+
+ ColumnInfo* columnInfo = view.columnInfo();
+ if (columnInfo && columnInfo->progressionAxis() == ColumnInfo::BlockAxis) {
+ if (!columnInfo->progressionIsReversed())
+ columnNumber = (pagination.pageLength + pagination.gap - offset) / (pagination.pageLength + pagination.gap);
+ else
+ columnNumber = offset / (pagination.pageLength + pagination.gap);
+ }
+ return columnNumber;
+}
+
+#if PLATFORM(IOS)
+// This function is similar in spirit to RenderText::absoluteRectsForRange, but returns rectangles
+// which are annotated with additional state which helps iOS draw selections in its unique way.
+// No annotations are added in this class.
+// FIXME: Move to RenderText with absoluteRectsForRange()?
+void RenderObject::collectSelectionRects(Vector<SelectionRect>& rects, unsigned start, unsigned end)
+{
+ Vector<FloatQuad> quads;
+
+ if (!firstChildSlow()) {
+ // FIXME: WebKit's position for an empty span after a BR is incorrect, so we can't trust
+ // quads for them. We don't need selection rects for those anyway though, since they
+ // are just empty containers. See <https://bugs.webkit.org/show_bug.cgi?id=49358>.
+ RenderObject* previous = previousSibling();
+ Node* node = this->node();
+ if (!previous || !previous->isBR() || !node || !node->isContainerNode() || !isInline()) {
+ // For inline elements we don't use absoluteQuads, since it takes into account continuations and leads to wrong results.
+ absoluteQuadsForSelection(quads);
+ }
+ } else {
+ unsigned offset = start;
+ for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset)
+ child->absoluteQuads(quads);
+ }
+
+ unsigned numberOfQuads = quads.size();
+ for (unsigned i = 0; i < numberOfQuads; ++i)
+ rects.append(SelectionRect(quads[i].enclosingBoundingBox(), isHorizontalWritingMode(), columnNumberForOffset(quads[i].enclosingBoundingBox().x())));
+}
+#endif
+
</ins><span class="cx"> IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
</span><span class="cx"> {
</span><span class="cx"> if (useTransforms) {
</span><span class="lines">@@ -2093,6 +2148,11 @@
</span><span class="cx">
</span><span class="cx"> void RenderObject::destroy()
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ if (hasLayer())
+ toRenderBoxModelObject(this)->layer()->willBeDestroyed();
+#endif
+
</ins><span class="cx"> willBeDestroyed();
</span><span class="cx"> delete this;
</span><span class="cx"> }
</span><span class="lines">@@ -2167,6 +2227,11 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+int RenderObject::innerLineHeight() const
+{
+ return style().computedLineHeight();
+}
+
</ins><span class="cx"> RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
</span><span class="cx"> {
</span><span class="cx"> if (pseudo < FIRST_INTERNAL_PSEUDOID && !style().hasPseudoStyle(pseudo))
</span><span class="lines">@@ -2343,9 +2408,14 @@
</span><span class="cx"> if (style().visibility() != VISIBLE)
</span><span class="cx"> return false;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ if (document().frame()->timersPaused())
+ return false;
+#else
</ins><span class="cx"> // We will not render a new image when Active DOM is suspended
</span><span class="cx"> if (document().activeDOMObjectsAreSuspended())
</span><span class="cx"> return false;
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // If we're not in a window (i.e., we're dormant from being put in the b/f cache or in a background tab)
</span><span class="cx"> // then we don't want to render either.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderObject.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -65,6 +65,9 @@
</span><span class="cx"> #if ENABLE(SVG)
</span><span class="cx"> class RenderSVGResourceContainer;
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS)
+class SelectionRect;
+#endif
</ins><span class="cx">
</span><span class="cx"> struct PaintInfo;
</span><span class="cx">
</span><span class="lines">@@ -108,7 +111,11 @@
</span><span class="cx"> };
</span><span class="cx"> typedef unsigned MapCoordinatesFlags;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+const int caretWidth = 2; // This value should be kept in sync with UIKit. See <rdar://problem/15580601>.
+#else
</ins><span class="cx"> const int caretWidth = 1;
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
</span><span class="cx"> struct AnnotatedRegionValue {
</span><span class="lines">@@ -653,7 +660,11 @@
</span><span class="cx"> void setHasLayer(bool b = true) { m_bitfields.setHasLayer(b); }
</span><span class="cx"> void setHasTransform(bool b = true) { m_bitfields.setHasTransform(b); }
</span><span class="cx"> void setHasReflection(bool b = true) { m_bitfields.setHasReflection(b); }
</span><del>-
</del><ins>+
+ // Hook so that RenderTextControl can return the line height of its inner renderer.
+ // For other renderers, the value is the same as lineHeight(false).
+ virtual int innerLineHeight() const;
+
</ins><span class="cx"> // used for element state updates that cannot be fixed with a
</span><span class="cx"> // repaint and do not need a relayout
</span><span class="cx"> virtual void updateFromElement() { }
</span><span class="lines">@@ -707,7 +718,12 @@
</span><span class="cx"> virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
</span><span class="cx"> // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
</span><span class="cx"> LayoutSize offsetFromAncestorContainer(RenderObject*) const;
</span><del>-
</del><ins>+
+#if PLATFORM(IOS)
+ virtual void collectSelectionRects(Vector<SelectionRect>&, unsigned startOffset = 0, unsigned endOffset = std::numeric_limits<unsigned>::max());
+ virtual void absoluteQuadsForSelection(Vector<FloatQuad>& quads) const { absoluteQuads(quads); }
+#endif
+
</ins><span class="cx"> virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { }
</span><span class="cx">
</span><span class="cx"> // FIXME: useTransforms should go away eventually
</span><span class="lines">@@ -905,9 +921,10 @@
</span><span class="cx">
</span><span class="cx"> RespectImageOrientationEnum shouldRespectImageOrientation() const;
</span><span class="cx">
</span><del>-protected:
</del><span class="cx"> void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
</span><span class="cx"> Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
</span><ins>+protected:
+ int columnNumberForOffset(int offset);
</ins><span class="cx">
</span><span class="cx"> void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*);
</span><span class="cx"> void paintOutline(PaintInfo&, const LayoutRect&);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderScrollbarh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderScrollbar.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderScrollbar.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderScrollbar.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -58,6 +58,8 @@
</span><span class="cx">
</span><span class="cx"> float opacity();
</span><span class="cx">
</span><ins>+ PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId);
+
</ins><span class="cx"> private:
</span><span class="cx"> RenderScrollbar(ScrollableArea*, ScrollbarOrientation, Element*, Frame*);
</span><span class="cx">
</span><span class="lines">@@ -75,7 +77,6 @@
</span><span class="cx">
</span><span class="cx"> void updateScrollbarParts(bool destroy = false);
</span><span class="cx">
</span><del>- PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId);
</del><span class="cx"> void updateScrollbarPart(ScrollbarPart, bool destroy = false);
</span><span class="cx">
</span><span class="cx"> // This Scrollbar(Widget) may outlive the DOM which created it (during tear down),
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderSearchFieldcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderSearchField.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderSearchField.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderSearchField.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -218,6 +218,7 @@
</span><span class="cx">
</span><span class="cx"> String RenderSearchField::itemText(unsigned listIndex) const
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> int size = listSize();
</span><span class="cx"> if (size == 1) {
</span><span class="cx"> ASSERT(!listIndex);
</span><span class="lines">@@ -225,10 +226,13 @@
</span><span class="cx"> }
</span><span class="cx"> if (!listIndex)
</span><span class="cx"> return searchMenuRecentSearchesText();
</span><ins>+#endif
</ins><span class="cx"> if (itemIsSeparator(listIndex))
</span><span class="cx"> return String();
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> if (static_cast<int>(listIndex) == (size - 1))
</span><span class="cx"> return searchMenuClearRecentSearchesText();
</span><ins>+#endif
</ins><span class="cx"> return m_recentSearches[listIndex - 1];
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderText.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -47,6 +47,14 @@
</span><span class="cx"> #include <wtf/text/StringBuffer.h>
</span><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "Document.h"
+#include "EditorClient.h"
+#include "LogicalSelectionOffsetCaches.h"
+#include "Page.h"
+#include "SelectionRect.h"
+#endif
+
</ins><span class="cx"> using namespace WTF;
</span><span class="cx"> using namespace Unicode;
</span><span class="cx">
</span><span class="lines">@@ -300,6 +308,83 @@
</span><span class="cx"> return m_lineBoxes.absoluteRectsForRange(*this, start, end, useSelectionHeight, wasFixed);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+// This function is similar in spirit to addLineBoxRects, but returns rectangles
+// which are annotated with additional state which helps the iPhone draw selections in its unique way.
+// Full annotations are added in this class.
+void RenderText::collectSelectionRects(Vector<SelectionRect>& rects, unsigned start, unsigned end)
+{
+ // FIXME: Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
+ // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
+ // function to take ints causes various internal mismatches. But selectionRect takes ints, and
+ // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
+ // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
+ ASSERT(end == std::numeric_limits<unsigned>::max() || end <= std::numeric_limits<int>::max());
+ ASSERT(start <= std::numeric_limits<int>::max());
+ start = std::min(start, static_cast<unsigned>(std::numeric_limits<int>::max()));
+ end = std::min(end, static_cast<unsigned>(std::numeric_limits<int>::max()));
+
+ for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
+ LayoutRect rect;
+ // Note, box->end() returns the index of the last character, not the index past it.
+ if (start <= box->start() && box->end() < end)
+ rect = box->localSelectionRect(start, end);
+ else {
+ unsigned realEnd = std::min(box->end() + 1, end);
+ rect = box->localSelectionRect(start, realEnd);
+ if (rect.isEmpty())
+ continue;
+ }
+
+ if (box->root().isFirstAfterPageBreak()) {
+ if (box->isHorizontal())
+ rect.shiftYEdgeTo(box->root().lineTopWithLeading());
+ else
+ rect.shiftXEdgeTo(box->root().lineTopWithLeading());
+ }
+
+ RenderBlock* containingBlock = this->containingBlock();
+ // Map rect, extended left to leftOffset, and right to rightOffset, through transforms to get minX and maxX.
+ LogicalSelectionOffsetCaches cache(*containingBlock);
+ LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, box->logicalTop(), cache);
+ LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, box->logicalTop(), cache);
+ LayoutRect extentsRect = rect;
+ if (box->isHorizontal()) {
+ extentsRect.setX(leftOffset);
+ extentsRect.setWidth(rightOffset - leftOffset);
+ } else {
+ extentsRect.setY(leftOffset);
+ extentsRect.setHeight(rightOffset - leftOffset);
+ }
+ extentsRect = localToAbsoluteQuad(FloatRect(extentsRect)).enclosingBoundingBox();
+ if (!box->isHorizontal())
+ extentsRect = extentsRect.transposedRect();
+ bool isFirstOnLine = !box->previousOnLineExists();
+ bool isLastOnLine = !box->nextOnLineExists();
+ if (containingBlock->isRubyBase() || containingBlock->isRubyText())
+ isLastOnLine = !containingBlock->containingBlock()->inlineBoxWrapper()->nextOnLineExists();
+
+ bool containsStart = box->start() <= start && box->end() + 1 >= start;
+ bool containsEnd = box->start() <= end && box->end() + 1 >= end;
+
+ bool isFixed = false;
+ IntRect absRect = localToAbsoluteQuad(FloatRect(rect), false, &isFixed).enclosingBoundingBox();
+ bool boxIsHorizontal = !box->isSVGInlineTextBox() ? box->isHorizontal() : !style().svgStyle().isVerticalWritingMode();
+ // If the containing block is an inline element, we want to check the inlineBoxWrapper orientation
+ // to determine the orientation of the block. In this case we also use the inlineBoxWrapper to
+ // determine if the element is the last on the line.
+ if (containingBlock->inlineBoxWrapper()) {
+ if (containingBlock->inlineBoxWrapper()->isHorizontal() != boxIsHorizontal) {
+ boxIsHorizontal = containingBlock->inlineBoxWrapper()->isHorizontal();
+ isLastOnLine = !containingBlock->inlineBoxWrapper()->nextOnLineExists();
+ }
+ }
+
+ rects.append(SelectionRect(absRect, box->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, box->isLineBreak(), isFirstOnLine, isLastOnLine, containsStart, containsEnd, boxIsHorizontal, isFixed, containingBlock->isRubyText(), columnNumberForOffset(absRect.x())));
+ }
+}
+#endif
+
</ins><span class="cx"> Vector<FloatQuad> RenderText::absoluteQuadsClippedToEllipsis() const
</span><span class="cx"> {
</span><span class="cx"> if (auto layout = simpleLineLayout()) {
</span><span class="lines">@@ -953,13 +1038,25 @@
</span><span class="cx"> case TSNONE:
</span><span class="cx"> break;
</span><span class="cx"> case TSCIRCLE:
</span><ins>+#if PLATFORM(IOS)
+ secureText(blackCircle);
+#else
</ins><span class="cx"> secureText(whiteBullet);
</span><ins>+#endif
</ins><span class="cx"> break;
</span><span class="cx"> case TSDISC:
</span><ins>+#if PLATFORM(IOS)
+ secureText(blackCircle);
+#else
</ins><span class="cx"> secureText(bullet);
</span><ins>+#endif
</ins><span class="cx"> break;
</span><span class="cx"> case TSSQUARE:
</span><ins>+#if PLATFORM(IOS)
+ secureText(blackCircle);
+#else
</ins><span class="cx"> secureText(blackSquare);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ASSERT(!m_text.isNull());
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderText.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -64,6 +64,9 @@
</span><span class="cx">
</span><span class="cx"> virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE FINAL;
</span><span class="cx"> Vector<IntRect> absoluteRectsForRange(unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false, bool* wasFixed = nullptr) const;
</span><ins>+#if PLATFORM(IOS)
+ virtual void collectSelectionRects(Vector<SelectionRect>&, unsigned startOffset = 0, unsigned endOffset = std::numeric_limits<unsigned>::max()) OVERRIDE;
+#endif
</ins><span class="cx">
</span><span class="cx"> virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE FINAL;
</span><span class="cx"> Vector<FloatQuad> absoluteQuadsForRange(unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false, bool* wasFixed = nullptr) const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextControlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTextControl.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTextControl.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTextControl.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -92,6 +92,31 @@
</span><span class="cx"> bool disabled = updateUserModifyProperty(textFormControlElement(), textBlockStyle);
</span><span class="cx"> if (disabled)
</span><span class="cx"> textBlockStyle->setColor(theme()->disabledTextColor(textBlockStyle->visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
</span><ins>+#if PLATFORM(IOS)
+ if (textBlockStyle->textSecurity() != TSNONE && !textBlockStyle->isLeftToRightDirection()) {
+ // Preserve the alignment but force the direction to LTR so that the last-typed, unmasked character
+ // (which cannot have RTL directionality) will appear to the right of the masked characters. See <rdar://problem/7024375>.
+
+ switch (textBlockStyle->textAlign()) {
+ case TASTART:
+ case JUSTIFY:
+ textBlockStyle->setTextAlign(RIGHT);
+ break;
+ case TAEND:
+ textBlockStyle->setTextAlign(LEFT);
+ break;
+ case LEFT:
+ case RIGHT:
+ case CENTER:
+ case WEBKIT_LEFT:
+ case WEBKIT_RIGHT:
+ case WEBKIT_CENTER:
+ break;
+ }
+
+ textBlockStyle->setDirection(LTR);
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> int RenderTextControl::textBlockLogicalHeight() const
</span><span class="lines">@@ -303,6 +328,22 @@
</span><span class="cx"> return placeholderRenderer;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+bool RenderTextControl::canScroll() const
+{
+ Element* innerText = innerTextElement();
+ return innerText && innerText->renderer() && innerText->renderer()->hasOverflowClip();
+}
+
+int RenderTextControl::innerLineHeight() const
+{
+ Element* innerText = innerTextElement();
+ if (innerText && innerText->renderer())
+ return innerText->renderer()->style().computedLineHeight();
+ return style().computedLineHeight();
+}
+#endif
+
</ins><span class="cx"> bool RenderTextControl::canBeReplacedWithInlineRunIn() const
</span><span class="cx"> {
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextControlh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTextControl.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTextControl.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTextControl.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -37,6 +37,13 @@
</span><span class="cx"> HTMLTextFormControlElement& textFormControlElement() const;
</span><span class="cx"> virtual PassRef<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const = 0;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ bool canScroll() const;
+
+ // Returns the line height of the inner renderer.
+ virtual int innerLineHeight() const OVERRIDE;
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx"> RenderTextControl(HTMLTextFormControlElement&, PassRef<RenderStyle>);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextControlMultiLinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTextControlMultiLine.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTextControlMultiLine.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTextControlMultiLine.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -61,11 +61,13 @@
</span><span class="cx">
</span><span class="cx"> float RenderTextControlMultiLine::getAvgCharWidth(AtomicString family)
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // Since Lucida Grande is the default font, we want this to match the width
</span><span class="cx"> // of Courier New, the default font for textareas in IE, Firefox and Safari Win.
</span><span class="cx"> // 1229 is the avgCharWidth value in the OS/2 table for Courier New.
</span><span class="cx"> if (family == "Lucida Grande")
</span><span class="cx"> return scaleEmToUnits(1229);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> return RenderTextControl::getAvgCharWidth(family);
</span><span class="cx"> }
</span><span class="lines">@@ -91,6 +93,13 @@
</span><span class="cx"> textBlockStyle.get().inheritFrom(startStyle);
</span><span class="cx"> adjustInnerTextStyle(startStyle, &textBlockStyle.get());
</span><span class="cx"> textBlockStyle.get().setDisplay(BLOCK);
</span><ins>+
+#if PLATFORM(IOS)
+ // We're adding three extra pixels of padding to line textareas up with text fields.
+ textBlockStyle.get().setPaddingLeft(Length(3, Fixed));
+ textBlockStyle.get().setPaddingRight(Length(3, Fixed));
+#endif
+
</ins><span class="cx"> return textBlockStyle;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextControlSingleLinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -45,6 +45,10 @@
</span><span class="cx"> #include "TextControlInnerElements.h"
</span><span class="cx"> #include <wtf/StackStats.h>
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+#include "RenderThemeIOS.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> using namespace HTMLNames;
</span><span class="lines">@@ -211,6 +215,12 @@
</span><span class="cx"> if (neededLayout)
</span><span class="cx"> computeOverflow(clientLogicalBottom());
</span><span class="cx"> }
</span><ins>+
+#if PLATFORM(IOS)
+ // FIXME: We should not be adjusting styles during layout. <rdar://problem/7675493>
+ if (inputElement().isSearchField())
+ RenderThemeIOS::adjustRoundBorderRadius(style(), this);
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
</span><span class="lines">@@ -298,12 +308,14 @@
</span><span class="cx">
</span><span class="cx"> float RenderTextControlSingleLine::getAvgCharWidth(AtomicString family)
</span><span class="cx"> {
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // Since Lucida Grande is the default font, we want this to match the width
</span><span class="cx"> // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
</span><span class="cx"> // IE for some encodings (in IE, the default font is encoding specific).
</span><span class="cx"> // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
</span><span class="cx"> if (family == "Lucida Grande")
</span><span class="cx"> return scaleEmToUnits(901);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> return RenderTextControl::getAvgCharWidth(family);
</span><span class="cx"> }
</span><span class="lines">@@ -318,6 +330,8 @@
</span><span class="cx"> LayoutUnit result = static_cast<LayoutUnit>(ceiledLayoutUnit(charWidth * factor));
</span><span class="cx">
</span><span class="cx"> float maxCharWidth = 0.f;
</span><ins>+
+#if !PLATFORM(IOS)
</ins><span class="cx"> const AtomicString& family = style().font().firstFamily();
</span><span class="cx"> // Since Lucida Grande is the default font, we want this to match the width
</span><span class="cx"> // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
</span><span class="lines">@@ -327,6 +341,7 @@
</span><span class="cx"> maxCharWidth = scaleEmToUnits(4027);
</span><span class="cx"> else if (hasValidAvgCharWidth(family))
</span><span class="cx"> maxCharWidth = roundf(style().font().primaryFont()->maxCharWidth());
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // For text inputs, IE adds some extra width.
</span><span class="cx"> if (maxCharWidth > 0.f)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextLineBoxescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -271,12 +271,14 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // and the x coordinate is to the left of the right edge of this box
</span><span class="cx"> // check to see if position goes in this box
</span><span class="cx"> if (pointLineDirection < box.logicalRight()) {
</span><span class="cx"> shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // box is first on line
</span><span class="cx"> // and the x coordinate is to the left of the first text box left edge
</span><span class="lines">@@ -406,6 +408,13 @@
</span><span class="cx">
</span><span class="cx"> if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
</span><span class="cx"> ShouldAffinityBeDownstream shouldAffinityBeDownstream;
</span><ins>+#if PLATFORM(IOS)
+ if (pointLineDirection != box->logicalLeft() && point.x() < box->x() + box->logicalWidth()) {
+ int half = box->x() + box->logicalWidth() / 2;
+ EAffinity affinity = point.x() < half ? DOWNSTREAM : VP_UPSTREAM_IF_POSSIBLE;
+ return renderer.createVisiblePosition(box->offsetForPosition(pointLineDirection) + box->start(), affinity);
+ }
+#endif
</ins><span class="cx"> if (lineDirectionPointFitsInBox(pointLineDirection, *box, shouldAffinityBeDownstream))
</span><span class="cx"> return createVisiblePositionAfterAdjustingOffsetForBiDi(*box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTheme.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTheme.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTheme.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -397,6 +397,10 @@
</span><span class="cx"> if (paintInfo.context->paintingDisabled())
</span><span class="cx"> return false;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ UNUSED_PARAM(r);
+ return o->style().appearance() != NoControlPart;
+#else
</ins><span class="cx"> // Call the appropriate paint method based off the appearance value.
</span><span class="cx"> switch (o->style().appearance()) {
</span><span class="cx"> case TextFieldPart:
</span><span class="lines">@@ -440,6 +444,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return false;
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool RenderTheme::paintDecorations(RenderObject* renderer, const PaintInfo& paintInfo, const IntRect& rect)
</span><span class="lines">@@ -452,15 +457,26 @@
</span><span class="cx"> case MenulistButtonPart:
</span><span class="cx"> return paintMenuListButtonDecorations(renderer, paintInfo, rect);
</span><span class="cx"> case TextFieldPart:
</span><ins>+ return paintTextFieldDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case TextAreaPart:
</span><del>- case ListboxPart:
</del><ins>+ return paintTextAreaDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case CheckboxPart:
</span><ins>+ return paintCheckboxDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case RadioPart:
</span><ins>+ return paintRadioDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case PushButtonPart:
</span><ins>+ return paintPushButtonDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case SquareButtonPart:
</span><del>- case DefaultButtonPart:
</del><ins>+ return paintSquareButtonDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case ButtonPart:
</span><ins>+ return paintButtonDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> case MenulistPart:
</span><ins>+ return paintMenuListDecorations(renderer, paintInfo, rect);
+ case SliderThumbHorizontalPart:
+ case SliderThumbVerticalPart:
+ return paintSliderThumbDecorations(renderer, paintInfo, rect);
+ case SearchFieldPart:
+ return paintSearchFieldDecorations(renderer, paintInfo, rect);
</ins><span class="cx"> #if ENABLE(METER_ELEMENT)
</span><span class="cx"> case MeterPart:
</span><span class="cx"> case RelevancyLevelIndicatorPart:
</span><span class="lines">@@ -473,9 +489,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> case SliderHorizontalPart:
</span><span class="cx"> case SliderVerticalPart:
</span><del>- case SliderThumbHorizontalPart:
- case SliderThumbVerticalPart:
- case SearchFieldPart:
</del><ins>+ case ListboxPart:
+ case DefaultButtonPart:
</ins><span class="cx"> case SearchFieldCancelButtonPart:
</span><span class="cx"> case SearchFieldDecorationPart:
</span><span class="cx"> case SearchFieldResultsDecorationPart:
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTheme.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTheme.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderTheme.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> class Element;
</span><span class="cx"> class FileList;
</span><span class="cx"> class HTMLInputElement;
</span><ins>+class Icon;
</ins><span class="cx"> class PopupMenu;
</span><span class="cx"> class RenderMenuList;
</span><span class="cx"> #if ENABLE(METER_ELEMENT)
</span><span class="lines">@@ -271,18 +272,31 @@
</span><span class="cx"> virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ virtual bool paintCheckboxDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+ virtual bool paintRadioDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+ virtual bool paintButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+
</ins><span class="cx"> virtual void adjustTextFieldStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><ins>+ virtual bool paintTextFieldDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</ins><span class="cx">
</span><span class="cx"> virtual void adjustTextAreaStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><ins>+ virtual bool paintTextAreaDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</ins><span class="cx">
</span><span class="cx"> virtual void adjustMenuListStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><ins>+ virtual bool paintMenuListDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</ins><span class="cx">
</span><span class="cx"> virtual void adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintMenuListButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><span class="cx">
</span><ins>+ virtual bool paintPushButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+ virtual bool paintSquareButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
+
+ enum FileUploadDecorations { SingleFile, MultipleFiles };
+ virtual bool paintFileUploadIconDecorations(RenderObject* /*inputRenderer*/, RenderObject* /*buttonRenderer*/, const PaintInfo&, const IntRect&, Icon*, FileUploadDecorations) { return true; }
+
</ins><span class="cx"> #if ENABLE(METER_ELEMENT)
</span><span class="cx"> virtual void adjustMeterStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintMeter(RenderObject*, const PaintInfo&, const IntRect&);
</span><span class="lines">@@ -303,9 +317,11 @@
</span><span class="cx">
</span><span class="cx"> virtual void adjustSliderThumbStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><ins>+ virtual bool paintSliderThumbDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</ins><span class="cx">
</span><span class="cx"> virtual void adjustSearchFieldStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span><ins>+ virtual bool paintSearchFieldDecorations(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</ins><span class="cx">
</span><span class="cx"> virtual void adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
</span><span class="cx"> virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/rendering/RenderThemeIOS.h (0 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.h         (rev 0)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -0,0 +1,124 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 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. AND ITS CONTRIBUTORS ``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 ITS 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 RenderThemeIOS_h
+#define RenderThemeIOS_h
+
+#if PLATFORM(IOS)
+
+#include "RenderTheme.h"
+
+namespace WebCore {
+
+class RenderStyle;
+class GraphicsContext;
+
+class RenderThemeIOS : public RenderTheme {
+public:
+ static PassRefPtr<RenderTheme> create();
+
+ virtual int popupInternalPaddingRight(RenderStyle*) const OVERRIDE;
+
+ static void adjustRoundBorderRadius(RenderStyle&, RenderBox*);
+
+ virtual void systemFont(CSSValueID, FontDescription&) const OVERRIDE;
+
+ static CFStringRef contentSizeCategory();
+
+protected:
+ virtual int baselinePosition(const RenderObject*) const OVERRIDE;
+
+ virtual bool isControlStyled(const RenderStyle*, const BorderData&, const FillLayer& background, const Color& backgroundColor) const OVERRIDE;
+
+ // Methods for each appearance value.
+ virtual void adjustCheckboxStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintCheckboxDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual void adjustRadioStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintRadioDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual void adjustButtonStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintPushButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void setButtonSize(RenderStyle*) const OVERRIDE;
+
+ virtual bool paintFileUploadIconDecorations(RenderObject* inputRenderer, RenderObject* buttonRenderer, const PaintInfo&, const IntRect&, Icon*, FileUploadDecorations) OVERRIDE;
+
+ virtual bool paintTextFieldDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintTextAreaDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual void adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintMenuListButtonDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual void adjustSliderTrackStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSliderThumbDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+#if ENABLE(PROGRESS_ELEMENT)
+ // Returns the repeat interval of the animation for the progress bar.
+ virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const OVERRIDE;
+ // Returns the duration of the animation for the progress bar.
+ virtual double animationDurationForProgressBar(RenderProgress*) const OVERRIDE;
+
+ virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+#endif
+
+#if ENABLE(DATALIST_ELEMENT)
+ virtual IntSize sliderTickSize() const OVERRIDE;
+ virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
+
+ virtual void adjustSearchFieldStyle(StyleResolver*, RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldDecorations(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+
+ virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformInactiveSelectionBackgroundColor() const OVERRIDE;
+
+#if ENABLE(TOUCH_EVENTS)
+ virtual Color platformTapHighlightColor() const OVERRIDE { return 0x4D1A1A1A; }
+#endif
+
+ virtual bool shouldShowPlaceholderWhenFocused() const OVERRIDE;
+ virtual bool shouldHaveSpinButton(HTMLInputElement*) const OVERRIDE;
+
+#if ENABLE(VIDEO)
+ virtual String mediaControlsStyleSheet() OVERRIDE;
+ virtual String mediaControlsScript() OVERRIDE;
+#endif
+
+private:
+ RenderThemeIOS();
+ virtual ~RenderThemeIOS() { }
+
+ const Color& shadowColor() const;
+ FloatRect addRoundedBorderClip(RenderObject* box, GraphicsContext*, const IntRect&);
+};
+
+}
+
+#endif // PLATFORM(IOS)
+#endif // RenderThemeIOS_h
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (0 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm         (rev 0)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -0,0 +1,1217 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#import "config.h"
+
+#if PLATFORM(IOS)
+
+#import "CSSPrimitiveValue.h"
+#import "CSSValueKeywords.h"
+#import "DateComponents.h"
+#import "Document.h"
+#import "Font.h"
+#import "FontCache.h"
+#import "Frame.h"
+#import "FrameView.h"
+#import "Gradient.h"
+#import "GraphicsContext.h"
+#import "GraphicsContextCG.h"
+#import "HTMLInputElement.h"
+#import "HTMLNames.h"
+#import "HTMLSelectElement.h"
+#import "Icon.h"
+#import "NodeRenderStyle.h"
+#import "Page.h"
+#import "PlatformLocale.h"
+#import "PaintInfo.h"
+#import "RenderObject.h"
+#import "RenderStyle.h"
+#import "RenderThemeIOS.h"
+#import "RenderView.h"
+#import "SoftLinking.h"
+#import "UserAgentScripts.h"
+#import "UserAgentStyleSheets.h"
+#import "WebCoreThreadRun.h"
+#import <CoreGraphics/CGPathPrivate.h>
+#import <CoreText/CTFontDescriptorPriv.h>
+#import <objc/runtime.h>
+#import <wtf/NeverDestroyed.h>
+#import <wtf/RefPtr.h>
+#import <wtf/StdLibExtras.h>
+
+#if ENABLE(PROGRESS_ELEMENT)
+#import "RenderProgress.h"
+#endif
+
+@interface UIApplication
++ (UIApplication *)sharedApplication;
+@property(nonatomic,copy) NSString *preferredContentSizeCategory;
+@end
+
+SOFT_LINK_FRAMEWORK(UIKit)
+SOFT_LINK_CLASS(UIKit, UIApplication)
+SOFT_LINK_CONSTANT(UIKit, UIContentSizeCategoryDidChangeNotification, CFStringRef)
+#define UIContentSizeCategoryDidChangeNotification getUIContentSizeCategoryDidChangeNotification()
+
+namespace WebCore {
+
+const float ControlBaseHeight = 20;
+const float ControlBaseFontSize = 11;
+
+struct IOSGradient {
+ float* start; // points to static float[4]
+ float* end; // points to static float[4]
+ IOSGradient(float start[4], float end[4])
+ : start(start)
+ , end(end)
+ {
+ }
+};
+
+typedef IOSGradient* IOSGradientRef;
+
+enum Interpolation
+{
+ LinearInterpolation,
+ ExponentialInterpolation
+};
+
+static void interpolateLinearGradient(void *info, const CGFloat *inData, CGFloat *outData)
+{
+ IOSGradientRef gradient = static_cast<IOSGradientRef>(info);
+ float alpha = inData[0];
+ float inverse = 1.0f - alpha;
+
+ outData[0] = inverse * gradient->start[0] + alpha * gradient->end[0];
+ outData[1] = inverse * gradient->start[1] + alpha * gradient->end[1];
+ outData[2] = inverse * gradient->start[2] + alpha * gradient->end[2];
+ outData[3] = inverse * gradient->start[3] + alpha * gradient->end[3];
+}
+
+static void interpolateExponentialGradient(void *info, const CGFloat *inData, CGFloat *outData)
+{
+ IOSGradientRef gradient = static_cast<IOSGradientRef>(info);
+ float a = inData[0];
+ for (int paintInfo = 0; paintInfo < 4; ++paintInfo) {
+ float end = logf(std::max(gradient->end[paintInfo], 0.01f));
+ float start = logf(std::max(gradient->start[paintInfo], 0.01f));
+ outData[paintInfo] = expf(start - (end + start) * a);
+ }
+}
+
+static CGFunctionRef getSharedFunctionRef(IOSGradientRef gradient, Interpolation interpolation)
+{
+ CGFunctionRef function = nullptr;
+
+ static HashMap<IOSGradientRef, CGFunctionRef>* linearFunctionRefs;
+ static HashMap<IOSGradientRef, CGFunctionRef>* exponentialFunctionRefs;;
+
+ if (interpolation == LinearInterpolation) {
+ if (!linearFunctionRefs)
+ linearFunctionRefs = new HashMap<IOSGradientRef, CGFunctionRef>;
+ else
+ function = linearFunctionRefs->get(gradient);
+
+ if (!function) {
+ static struct CGFunctionCallbacks linearFunctionCallbacks = { 0, interpolateLinearGradient, 0 };
+ linearFunctionRefs->set(gradient, function = CGFunctionCreate(gradient, 1, nullptr, 4, nullptr, &linearFunctionCallbacks));
+ }
+
+ return function;
+ }
+
+ if (!exponentialFunctionRefs)
+ exponentialFunctionRefs = new HashMap<IOSGradientRef, CGFunctionRef>;
+ else
+ function = exponentialFunctionRefs->get(gradient);
+
+ if (!function) {
+ static struct CGFunctionCallbacks exponentialFunctionCallbacks = { 0, interpolateExponentialGradient, 0 };
+ exponentialFunctionRefs->set(gradient, function = CGFunctionCreate(gradient, 1, 0, 4, 0, &exponentialFunctionCallbacks));
+ }
+
+ return function;
+}
+
+static void drawAxialGradient(CGContextRef context, IOSGradientRef gradient, const FloatPoint& startPoint, const FloatPoint& stopPoint, Interpolation interpolation)
+{
+ RetainPtr<CGShadingRef> shading = adoptCF(CGShadingCreateAxial(deviceRGBColorSpaceRef(), startPoint, stopPoint, getSharedFunctionRef(gradient, interpolation), false, false));
+ CGContextDrawShading(context, shading.get());
+}
+
+static void drawRadialGradient(CGContextRef context, IOSGradientRef gradient, const FloatPoint& startPoint, float startRadius, const FloatPoint& stopPoint, float stopRadius, Interpolation interpolation)
+{
+ RetainPtr<CGShadingRef> shading = adoptCF(CGShadingCreateRadial(deviceRGBColorSpaceRef(), startPoint, startRadius, stopPoint, stopRadius, getSharedFunctionRef(gradient, interpolation), false, false));
+ CGContextDrawShading(context, shading.get());
+}
+
+enum IOSGradientType {
+ InsetGradient,
+ ShineGradient,
+ ShadeGradient,
+ ConvexGradient,
+ ConcaveGradient,
+ SliderTrackGradient,
+ ReadonlySliderTrackGradient,
+ SliderThumbOpaquePressedGradient,
+};
+
+static IOSGradientRef getInsetGradient()
+{
+ static float end[4] = { 0 / 255.0, 0 / 255.0, 0 / 255.0, 0 };
+ static float start[4] = { 0 / 255.0, 0 / 255.0, 0 / 255.0, 0.2 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getShineGradient()
+{
+ static float end[4] = { 1, 1, 1, 0.8 };
+ static float start[4] = { 1, 1, 1, 0 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getShadeGradient()
+{
+ static float end[4] = { 178 / 255.0, 178 / 255.0, 178 / 255.0, 0.65 };
+ static float start[4] = { 252 / 255.0, 252 / 255.0, 252 / 255.0, 0.65 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getConvexGradient()
+{
+ static float end[4] = { 255 / 255.0, 255 / 255.0, 255 / 255.0, 0.05 };
+ static float start[4] = { 255 / 255.0, 255 / 255.0, 255 / 255.0, 0.43 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getConcaveGradient()
+{
+ static float end[4] = { 255 / 255.0, 255 / 255.0, 255 / 255.0, 0.46 };
+ static float start[4] = { 255 / 255.0, 255 / 255.0, 255 / 255.0, 0 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getSliderTrackGradient()
+{
+ static float end[4] = { 132 / 255.0, 132 / 255.0, 132 / 255.0, 1 };
+ static float start[4] = { 74 / 255.0, 77 / 255.0, 80 / 255.0, 1 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getReadonlySliderTrackGradient()
+{
+ static float end[4] = { 132 / 255.0, 132 / 255.0, 132 / 255.0, 0.4 };
+ static float start[4] = { 74 / 255.0, 77 / 255.0, 80 /255.0, 0.4 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef getSliderThumbOpaquePressedGradient()
+{
+ static float end[4] = { 144 / 255.0, 144 / 255.0, 144 / 255.0, 1};
+ static float start[4] = { 55 / 255.0, 55 / 255.0, 55 / 255.0, 1 };
+ static NeverDestroyed<IOSGradient> gradient(start, end);
+ return &gradient.get();
+}
+
+static IOSGradientRef gradientWithName(IOSGradientType gradientType)
+{
+ switch (gradientType) {
+ case InsetGradient:
+ return getInsetGradient();
+ case ShineGradient:
+ return getShineGradient();
+ case ShadeGradient:
+ return getShadeGradient();
+ case ConvexGradient:
+ return getConvexGradient();
+ case ConcaveGradient:
+ return getConcaveGradient();
+ case SliderTrackGradient:
+ return getSliderTrackGradient();
+ case ReadonlySliderTrackGradient:
+ return getReadonlySliderTrackGradient();
+ case SliderThumbOpaquePressedGradient:
+ return getSliderThumbOpaquePressedGradient();
+ }
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+static void contentSizeCategoryDidChange(CFNotificationCenterRef, void*, CFStringRef name, const void*, CFDictionaryRef)
+{
+ ASSERT_UNUSED(name, CFEqual(name, UIContentSizeCategoryDidChangeNotification));
+ WebThreadRun(^{
+ Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
+ });
+}
+
+RenderThemeIOS::RenderThemeIOS()
+{
+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, contentSizeCategoryDidChange, UIContentSizeCategoryDidChangeNotification, 0, CFNotificationSuspensionBehaviorDeliverImmediately);
+}
+
+PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*)
+{
+ static RenderTheme* renderTheme = RenderThemeIOS::create().leakRef();
+ return renderTheme;
+}
+
+PassRefPtr<RenderTheme> RenderThemeIOS::create()
+{
+ return adoptRef(new RenderThemeIOS);
+}
+
+CFStringRef RenderThemeIOS::contentSizeCategory()
+{
+ return (CFStringRef)[[getUIApplicationClass() sharedApplication] preferredContentSizeCategory];
+}
+
+const Color& RenderThemeIOS::shadowColor() const
+{
+ static Color color(0.0f, 0.0f, 0.0f, 0.7f);
+ return color;
+}
+
+FloatRect RenderThemeIOS::addRoundedBorderClip(RenderObject* box, GraphicsContext* context, const IntRect& rect)
+{
+ // To fix inner border bleeding issues <rdar://problem/9812507>, we clip to the outer border and assert that
+ // the border is opaque or transparent, unless we're checked because checked radio/checkboxes show no bleeding.
+ RenderStyle& style = box->style();
+ RoundedRect border = isChecked(box) ? style.getRoundedInnerBorderFor(rect) : style.getRoundedBorderFor(rect);
+
+ if (border.isRounded())
+ context->clipRoundedRect(border);
+ else
+ context->clip(border.rect());
+
+ if (isChecked(box)) {
+ ASSERT(style.visitedDependentColor(CSSPropertyBorderTopColor).alpha() % 255 == 0);
+ ASSERT(style.visitedDependentColor(CSSPropertyBorderRightColor).alpha() % 255 == 0);
+ ASSERT(style.visitedDependentColor(CSSPropertyBorderBottomColor).alpha() % 255 == 0);
+ ASSERT(style.visitedDependentColor(CSSPropertyBorderLeftColor).alpha() % 255 == 0);
+ }
+
+ return border.rect();
+}
+
+void RenderThemeIOS::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ Length length = Length(static_cast<int>(ceilf(std::max(style->fontSize(), 10))), Fixed);
+
+ style->setWidth(length);
+ style->setHeight(length);
+}
+
+static CGPoint shortened(CGPoint start, CGPoint end, float width)
+{
+ float x = end.x - start.x;
+ float y = end.y - start.y;
+ float ratio = width / sqrtf(x * x + y * y);
+ return CGPointMake(start.x + x * ratio, start.y + y * ratio);
+}
+
+bool RenderThemeIOS::paintCheckboxDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ FloatRect clip = addRoundedBorderClip(box, paintInfo.context, rect);
+
+ float width = clip.width();
+ float height = clip.height();
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ if (isChecked(box)) {
+ drawAxialGradient(cgContext, gradientWithName(ConcaveGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+
+ static float thicknessRatio = 2 / 14.0;
+ static CGSize size = { 14.0f, 14.0f };
+ static CGPoint pathRatios[3] = {
+ { 2.5f / size.width, 7.5f / size.height },
+ { 5.5f / size.width, 10.5f / size.height },
+ { 11.5f / size.width, 2.5f / size.height }
+ };
+
+ float lineWidth = std::min(width, height) * 2.0f * thicknessRatio;
+
+ CGPoint line[3] = {
+ CGPointMake(clip.x() + width * pathRatios[0].x, clip.y() + height * pathRatios[0].y),
+ CGPointMake(clip.x() + width * pathRatios[1].x, clip.y() + height * pathRatios[1].y),
+ CGPointMake(clip.x() + width * pathRatios[2].x, clip.y() + height * pathRatios[2].y)
+ };
+ CGPoint shadow[3] = {
+ shortened(line[0], line[1], lineWidth / 4.0f),
+ line[1],
+ shortened(line[2], line[1], lineWidth / 4.0f)
+ };
+
+ paintInfo.context->setStrokeThickness(lineWidth);
+ paintInfo.context->setStrokeColor(Color(0.0f, 0.0f, 0.0f, 0.7f), ColorSpaceDeviceRGB);
+
+ paintInfo.context->drawJoinedLines(shadow, 3, true, kCGLineCapSquare);
+
+ paintInfo.context->setStrokeThickness(std::min(clip.width(), clip.height()) * thicknessRatio);
+ paintInfo.context->setStrokeColor(Color(1.0f, 1.0f, 1.0f, 240 / 255.0f), ColorSpaceDeviceRGB);
+
+ paintInfo.context->drawJoinedLines(line, 3, true);
+ } else {
+ FloatPoint bottomCenter(clip.x() + clip.width() / 2.0f, clip.maxY());
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ drawRadialGradient(cgContext, gradientWithName(ShineGradient), bottomCenter, 0, bottomCenter, sqrtf((width * width) / 4.0f + height * height), ExponentialInterpolation);
+ }
+
+ return false;
+}
+
+int RenderThemeIOS::baselinePosition(const RenderObject* renderer) const
+{
+ if (!renderer->isBox())
+ return 0;
+
+ const RenderBox* box = toRenderBox(renderer);
+
+ if (box->style().appearance() == CheckboxPart || box->style().appearance() == RadioPart)
+ return box->marginTop() + box->height() - 2; // The baseline is 2px up from the bottom of the checkbox/radio in AppKit.
+ if (box->style().appearance() == MenulistPart)
+ return box->marginTop() + box->height() - 5; // This is to match AppKit. There might be a better way to calculate this though.
+ return RenderTheme::baselinePosition(box);
+}
+
+bool RenderThemeIOS::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const
+{
+ // Buttons and MenulistButtons are styled if they contain a background image.
+ if (style->appearance() == PushButtonPart || style->appearance() == MenulistButtonPart)
+ return !style->visitedDependentColor(CSSPropertyBackgroundColor).alpha() || style->backgroundLayers()->hasImage();
+
+ if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart)
+ return *style->backgroundLayers() != background;
+
+ return RenderTheme::isControlStyled(style, border, background, backgroundColor);
+}
+
+void RenderThemeIOS::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ Length length = Length(static_cast<int>(ceilf(std::max(style->fontSize(), 10))), Fixed);
+ style->setWidth(length);
+ style->setHeight(length);
+ style->setBorderRadius(IntSize(length.value() / 2.0f, length.value() / 2.0f));
+}
+
+bool RenderThemeIOS::paintRadioDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ FloatRect clip = addRoundedBorderClip(box, paintInfo.context, rect);
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ if (isChecked(box)) {
+ drawAxialGradient(cgContext, gradientWithName(ConcaveGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+
+ // The inner circle is 6 / 14 the size of the surrounding circle,
+ // leaving 8 / 14 around it. (8 / 14) / 2 = 2 / 7.
+
+ static float InnerInverseRatio = 2 / 7.0;
+
+ clip.inflateX(-clip.width() * InnerInverseRatio);
+ clip.inflateY(-clip.height() * InnerInverseRatio);
+
+ paintInfo.context->drawRaisedEllipse(clip, Color::white, ColorSpaceDeviceRGB, shadowColor(), ColorSpaceDeviceRGB);
+
+ FloatSize radius(clip.width() / 2.0f, clip.height() / 2.0f);
+ paintInfo.context->clipRoundedRect(clip, radius, radius, radius, radius);
+ }
+ FloatPoint bottomCenter(clip.x() + clip.width() / 2.0, clip.maxY());
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ drawRadialGradient(cgContext, gradientWithName(ShineGradient), bottomCenter, 0, bottomCenter, std::max(clip.width(), clip.height()), ExponentialInterpolation);
+ return false;
+}
+
+bool RenderThemeIOS::paintTextFieldDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ RenderStyle& style = box->style();
+ IntPoint point(rect.x() + style.borderLeftWidth(), rect.y() + style.borderTopWidth());
+
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ paintInfo.context->clipRoundedRect(style.getRoundedBorderFor(r));
+
+ // This gradient gets drawn black when printing.
+ // Do not draw the gradient if there is no visible top border.
+ bool topBorderIsInvisible = !style.hasBorder() || !style.borderTopWidth() || style.borderTopIsTransparent();
+ if (!box->view().printing() && !topBorderIsInvisible)
+ drawAxialGradient(paintInfo.context->platformContext(), gradientWithName(InsetGradient), point, FloatPoint(CGPointMake(point.x(), point.y() + 3.0f)), LinearInterpolation);
+ return false;
+}
+
+bool RenderThemeIOS::paintTextAreaDecorations(RenderObject* renderer, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return paintTextFieldDecorations(renderer, paintInfo, rect);
+}
+
+const int MenuListMinHeight = 15;
+
+const float MenuListBaseHeight = 20;
+const float MenuListBaseFontSize = 11;
+
+const float MenuListArrowWidth = 7;
+const float MenuListArrowHeight = 6;
+const float MenuListButtonPaddingRight = 19;
+
+int RenderThemeIOS::popupInternalPaddingRight(RenderStyle* style) const
+{
+ if (style->appearance() == MenulistButtonPart)
+ return MenuListButtonPaddingRight + style->borderTopWidth();
+ return 0;
+}
+
+void RenderThemeIOS::adjustRoundBorderRadius(RenderStyle& style, RenderBox* box)
+{
+ if (style.appearance() == NoControlPart || style.backgroundLayers()->hasImage())
+ return;
+
+ // FIXME: We should not be relying on border radius for the appearance of our controls <rdar://problem/7675493>
+ Length radiusWidth(static_cast<int>(std::min(box->width(), box->height()) / 2.0), Fixed);
+ Length radiusHeight(static_cast<int>(box->height() / 2.0), Fixed);
+ style.setBorderRadius(LengthSize(radiusWidth, radiusHeight));
+}
+
+static void applyCommonButtonPaddingToStyle(RenderStyle* style, Element* element)
+{
+ Document& document = element->document();
+ RefPtr<CSSPrimitiveValue> emSize = CSSPrimitiveValue::create(0.5, CSSPrimitiveValue::CSS_EMS);
+ int pixels = emSize->computeLength<int>(style, document.renderStyle(), document.frame()->pageZoomFactor());
+ style->setPaddingBox(LengthBox(0, pixels, 0, pixels));
+}
+
+static void adjustSelectListButtonStyle(RenderStyle* style, Element* element)
+{
+ // Enforce "padding: 0 0.5em".
+ applyCommonButtonPaddingToStyle(style, element);
+
+ // Enforce "line-height: normal".
+ style->setLineHeight(Length(-100.0, Percent));
+}
+
+static void adjustInputElementButtonStyle(RenderStyle* style, HTMLInputElement* inputElement)
+{
+ // Always Enforce "padding: 0 0.5em".
+ applyCommonButtonPaddingToStyle(style, inputElement);
+
+ // Don't adjust the style if the width is specified.
+ if (style->width().isFixed() && style->width().value() > 0)
+ return;
+
+ // Don't adjust for unsupported date input types.
+ DateComponents::Type dateType = inputElement->dateType();
+ if (dateType == DateComponents::Invalid || dateType == DateComponents::Week)
+ return;
+
+ // Enforce the width and set the box-sizing to content-box to not conflict with the padding.
+ Font font = style->font();
+ float maximumWidth = inputElement->locale().maximumWidthForDateType(dateType, font);
+ if (maximumWidth > 0) {
+ int width = static_cast<int>(maximumWidth + MenuListButtonPaddingRight);
+ style->setWidth(Length(width, Fixed));
+ style->setBoxSizing(CONTENT_BOX);
+ }
+}
+
+void RenderThemeIOS::adjustMenuListButtonStyle(StyleResolver*, RenderStyle* style, Element* element) const
+{
+ // Set the min-height to be at least MenuListMinHeight.
+ if (style->height().isAuto())
+ style->setMinHeight(Length(std::max(MenuListMinHeight, static_cast<int>(MenuListBaseHeight / MenuListBaseFontSize * style->fontDescription().computedSize())), Fixed));
+ else
+ style->setMinHeight(Length(MenuListMinHeight, Fixed));
+
+ // Enforce some default styles in the case that this is a non-multiple <select> element,
+ // or a date input. We don't force these if this is just an element with
+ // "-webkit-appearance: menulist-button".
+ if (element->hasTagName(HTMLNames::selectTag) && !element->hasAttribute(HTMLNames::multipleAttr))
+ adjustSelectListButtonStyle(style, element);
+ else if (element->hasTagName(HTMLNames::inputTag)) {
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
+ adjustInputElementButtonStyle(style, inputElement);
+ }
+}
+
+bool RenderThemeIOS::paintMenuListButtonDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ RenderStyle& style = box->style();
+ float borderTopWidth = style.borderTopWidth();
+ FloatRect clip(rect.x() + style.borderLeftWidth(), rect.y() + style.borderTopWidth(), rect.width() - style.borderLeftWidth() - style.borderRightWidth(), rect.height() - style.borderTopWidth() - style.borderBottomWidth());
+ CGContextRef cgContext = paintInfo.context->platformContext();
+
+ float adjustLeft = 0.5;
+ float adjustRight = 0.5;
+ float adjustTop = 0.5;
+ float adjustBottom = 0.5;
+
+ // Paint left-hand title portion.
+ {
+ FloatRect titleClip(clip.x() - adjustLeft, clip.y() - adjustTop, clip.width() - MenuListButtonPaddingRight + adjustLeft, clip.height() + adjustTop + adjustBottom);
+
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ paintInfo.context->clipRoundedRect(titleClip,
+ FloatSize(valueForLength(style.borderTopLeftRadius().width(), rect.width()) - style.borderLeftWidth(), valueForLength(style.borderTopLeftRadius().height(), rect.height()) - style.borderTopWidth()), FloatSize(0, 0),
+ FloatSize(valueForLength(style.borderBottomLeftRadius().width(), rect.width()) - style.borderLeftWidth(), valueForLength(style.borderBottomLeftRadius().height(), rect.height()) - style.borderBottomWidth()), FloatSize(0, 0));
+
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), titleClip.location(), FloatPoint(titleClip.x(), titleClip.maxY()), LinearInterpolation);
+ drawAxialGradient(cgContext, gradientWithName(ShineGradient), FloatPoint(titleClip.x(), titleClip.maxY()), titleClip.location(), ExponentialInterpolation);
+ }
+
+ // Draw the separator after the initial padding.
+
+ float separator = clip.maxX() - MenuListButtonPaddingRight;
+
+ box->drawLineForBoxSide(paintInfo.context, separator - borderTopWidth, clip.y(), separator, clip.maxY(), BSRight, style.visitedDependentColor(CSSPropertyBorderTopColor), style.borderTopStyle(), 0, 0);
+
+ FloatRect buttonClip(separator - adjustTop, clip.y() - adjustTop, MenuListButtonPaddingRight + adjustTop + adjustRight, clip.height() + adjustTop + adjustBottom);
+
+ // Now paint the button portion.
+ {
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ paintInfo.context->clipRoundedRect(buttonClip,
+ FloatSize(0, 0), FloatSize(valueForLength(style.borderTopRightRadius().width(), rect.width()) - style.borderRightWidth(), valueForLength(style.borderTopRightRadius().height(), rect.height()) - style.borderTopWidth()),
+ FloatSize(0, 0), FloatSize(valueForLength(style.borderBottomRightRadius().width(), rect.width()) - style.borderRightWidth(), valueForLength(style.borderBottomRightRadius().height(), rect.height()) - style.borderBottomWidth()));
+
+ paintInfo.context->fillRect(buttonClip, style.visitedDependentColor(CSSPropertyBorderTopColor), style.colorSpace());
+
+ drawAxialGradient(cgContext, gradientWithName(isFocused(box) && !isReadOnlyControl(box) ? ConcaveGradient : ConvexGradient), buttonClip.location(), FloatPoint(buttonClip.x(), buttonClip.maxY()), LinearInterpolation);
+ }
+
+ // Paint Indicators.
+
+ if (box->isMenuList() && toHTMLSelectElement(box->node())->multiple()) {
+ int size = 2;
+ int count = 3;
+ int padding = 3;
+
+ IntRect ellipse(buttonClip.x() + (buttonClip.width() - count * (size + padding) + padding) / 2.0, buttonClip.maxY() - 10.0, size, size);
+
+ for (int i = 0; i < count; ++i) {
+ paintInfo.context->drawRaisedEllipse(ellipse, Color::white, ColorSpaceDeviceRGB, Color(0.0f, 0.0f, 0.0f, 0.5f), ColorSpaceDeviceRGB);
+ ellipse.move(size + padding, 0);
+ }
+ } else {
+ float centerX = floorf(buttonClip.x() + buttonClip.width() / 2.0) - 0.5;
+ float centerY = floorf(buttonClip.y() + buttonClip.height() * 3.0 / 8.0);
+
+ FloatPoint arrow[3];
+ FloatPoint shadow[3];
+
+ arrow[0] = FloatPoint(centerX - MenuListArrowWidth / 2.0, centerY);
+ arrow[1] = FloatPoint(centerX + MenuListArrowWidth / 2.0, centerY);
+ arrow[2] = FloatPoint(centerX, centerY + MenuListArrowHeight);
+
+ shadow[0] = FloatPoint(arrow[0].x(), arrow[0].y() + 1.0f);
+ shadow[1] = FloatPoint(arrow[1].x(), arrow[1].y() + 1.0f);
+ shadow[2] = FloatPoint(arrow[2].x(), arrow[2].y() + 1.0f);
+
+ float opacity = isReadOnlyControl(box) ? 0.2 : 0.5;
+ paintInfo.context->setStrokeColor(Color(0.0f, 0.0f, 0.0f, opacity), ColorSpaceDeviceRGB);
+ paintInfo.context->setFillColor(Color(0.0f, 0.0f, 0.0f, opacity), ColorSpaceDeviceRGB);
+ paintInfo.context->drawConvexPolygon(3, shadow, true);
+
+ paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
+ paintInfo.context->setFillColor(Color::white, ColorSpaceDeviceRGB);
+ paintInfo.context->drawConvexPolygon(3, arrow, true);
+ }
+
+ return false;
+}
+
+const CGFloat kTrackThickness = 4.0;
+const CGFloat kTrackRadius = kTrackThickness / 2.0;
+const int kDefaultSliderThumbSize = 16;
+
+void RenderThemeIOS::adjustSliderTrackStyle(StyleResolver* selector, RenderStyle* style, Element* element) const
+{
+ RenderTheme::adjustSliderTrackStyle(selector, style, element);
+
+ // FIXME: We should not be relying on border radius for the appearance of our controls <rdar://problem/7675493>
+ Length radiusWidth(static_cast<int>(kTrackRadius), Fixed);
+ Length radiusHeight(static_cast<int>(kTrackRadius), Fixed);
+ style->setBorderRadius(LengthSize(radiusWidth, radiusHeight));
+}
+
+bool RenderThemeIOS::paintSliderTrack(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ IntRect trackClip = rect;
+ RenderStyle& style = box->style();
+
+ bool isHorizontal = true;
+ switch (style.appearance()) {
+ case SliderHorizontalPart:
+ isHorizontal = true;
+ // Inset slightly so the thumb covers the edge.
+ if (trackClip.width() > 2) {
+ trackClip.setWidth(trackClip.width() - 2);
+ trackClip.setX(trackClip.x() + 1);
+ }
+ trackClip.setHeight(static_cast<int>(kTrackThickness));
+ trackClip.setY(rect.y() + rect.height() / 2 - kTrackThickness / 2);
+ break;
+ case SliderVerticalPart:
+ isHorizontal = false;
+ // Inset slightly so the thumb covers the edge.
+ if (trackClip.height() > 2) {
+ trackClip.setHeight(trackClip.height() - 2);
+ trackClip.setY(trackClip.y() + 1);
+ }
+ trackClip.setWidth(kTrackThickness);
+ trackClip.setX(rect.x() + rect.width() / 2 - kTrackThickness / 2);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ASSERT(trackClip.width() >= 0);
+ ASSERT(trackClip.height() >= 0);
+ CGFloat cornerWidth = trackClip.width() < kTrackThickness ? trackClip.width() / 2.0f : kTrackRadius;
+ CGFloat cornerHeight = trackClip.height() < kTrackThickness ? trackClip.height() / 2.0f : kTrackRadius;
+
+ bool readonly = isReadOnlyControl(box);
+
+#if ENABLE(DATALIST_ELEMENT)
+ paintSliderTicks(box, paintInfo, trackClip);
+#endif
+
+ // Draw the track gradient.
+ {
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ IntSize cornerSize(cornerWidth, cornerHeight);
+ RoundedRect innerBorder(trackClip, cornerSize, cornerSize, cornerSize, cornerSize);
+ paintInfo.context->clipRoundedRect(innerBorder);
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ IOSGradientRef gradient = readonly ? gradientWithName(ReadonlySliderTrackGradient) : gradientWithName(SliderTrackGradient);
+ if (isHorizontal)
+ drawAxialGradient(cgContext, gradient, trackClip.location(), FloatPoint(trackClip.x(), trackClip.maxY()), LinearInterpolation);
+ else
+ drawAxialGradient(cgContext, gradient, trackClip.location(), FloatPoint(trackClip.maxX(), trackClip.y()), LinearInterpolation);
+ }
+
+ // Draw the track border.
+ {
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ if (readonly)
+ paintInfo.context->setStrokeColor(Color(178, 178, 178), ColorSpaceDeviceRGB);
+ else
+ paintInfo.context->setStrokeColor(Color(76, 76, 76), ColorSpaceDeviceRGB);
+
+ RetainPtr<CGMutablePathRef> roundedRectPath = adoptCF(CGPathCreateMutable());
+ CGPathAddRoundedRect(roundedRectPath.get(), 0, trackClip, cornerWidth, cornerHeight);
+ CGContextAddPath(cgContext, roundedRectPath.get());
+ CGContextSetLineWidth(cgContext, 1);
+ CGContextStrokePath(cgContext);
+ }
+
+ return false;
+}
+
+void RenderThemeIOS::adjustSliderThumbSize(RenderStyle* style, Element*) const
+{
+ if (style->appearance() != SliderThumbHorizontalPart && style->appearance() != SliderThumbVerticalPart)
+ return;
+
+ // Enforce "border-radius: 50%".
+ Length length(50.0f, Percent);
+ style->setBorderRadius(LengthSize(length, length));
+
+ // Enforce a 16x16 size if no size is provided.
+ if (style->width().isIntrinsicOrAuto() || style->height().isAuto()) {
+ Length length = Length(kDefaultSliderThumbSize, Fixed);
+ style->setWidth(length);
+ style->setHeight(length);
+ }
+}
+
+bool RenderThemeIOS::paintSliderThumbDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ FloatRect clip = addRoundedBorderClip(box, paintInfo.context, rect);
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ FloatPoint bottomCenter(clip.x() + clip.width() / 2.0f, clip.maxY());
+ if (isPressed(box))
+ drawAxialGradient(cgContext, gradientWithName(SliderThumbOpaquePressedGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ else {
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ drawRadialGradient(cgContext, gradientWithName(ShineGradient), bottomCenter, 0.0f, bottomCenter, std::max(clip.width(), clip.height()), ExponentialInterpolation);
+ }
+
+ return false;
+}
+
+#if ENABLE(PROGRESS_ELEMENT)
+double RenderThemeIOS::animationRepeatIntervalForProgressBar(RenderProgress*) const
+{
+ return 0;
+}
+
+double RenderThemeIOS::animationDurationForProgressBar(RenderProgress*) const
+{
+ return 0;
+}
+
+bool RenderThemeIOS::paintProgressBar(RenderObject* renderer, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ if (!renderer->isProgress())
+ return true;
+
+ const int progressBarHeight = 9;
+ const float verticalOffset = (rect.height() - progressBarHeight) / 2.0;
+
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ if (rect.width() < 10 || rect.height() < 9) {
+ // The rect is smaller than the standard progress bar. We clip to the element's rect to avoid
+ // leaking pixels outside the repaint rect.
+ paintInfo.context->clip(rect);
+ }
+
+ // 1) Draw the progress bar track.
+ // 1.1) Draw the white background with grey gradient border.
+ GraphicsContext* context = paintInfo.context;
+ context->setStrokeThickness(0.68);
+ context->setStrokeStyle(SolidStroke);
+
+ const float verticalRenderingPosition = rect.y() + verticalOffset;
+ RefPtr<Gradient> strokeGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ strokeGradient->addColorStop(0.0, Color(0x8d, 0x8d, 0x8d));
+ strokeGradient->addColorStop(0.45, Color(0xee, 0xee, 0xee));
+ strokeGradient->addColorStop(0.55, Color(0xee, 0xee, 0xee));
+ strokeGradient->addColorStop(1.0, Color(0x8d, 0x8d, 0x8d));
+ context->setStrokeGradient(strokeGradient.release());
+
+ ColorSpace colorSpace = renderer->style().colorSpace();
+ context->setFillColor(Color(255, 255, 255), colorSpace);
+
+ Path trackPath;
+ FloatRect trackRect(rect.x() + 0.25, verticalRenderingPosition + 0.25, rect.width() - 0.5, progressBarHeight - 0.5);
+ FloatSize roundedCornerRadius(5, 4);
+ trackPath.addRoundedRect(trackRect, roundedCornerRadius);
+ context->drawPath(trackPath);
+
+ // 1.2) Draw top gradient on the upper half. It is supposed to overlay the fill from the background and darker the stroked path.
+ FloatRect border(rect.x(), rect.y() + verticalOffset, rect.width(), progressBarHeight);
+ paintInfo.context->clipRoundedRect(border, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius);
+
+ float upperGradientHeight = progressBarHeight / 2.;
+ RefPtr<Gradient> upperGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5));
+ upperGradient->addColorStop(0.0, Color(133, 133, 133, 188));
+ upperGradient->addColorStop(1.0, Color(18, 18, 18, 51));
+ context->setFillGradient(upperGradient.release());
+
+ context->fillRect(FloatRect(rect.x(), verticalRenderingPosition, rect.width(), upperGradientHeight));
+
+ RenderProgress* renderProgress = toRenderProgress(renderer);
+ if (renderProgress->isDeterminate()) {
+ // 2) Draw the progress bar.
+ double position = clampTo(renderProgress->position(), 0.0, 1.0);
+ double barWidth = position * rect.width();
+ RefPtr<Gradient> barGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ barGradient->addColorStop(0.0, Color(195, 217, 247));
+ barGradient->addColorStop(0.45, Color(118, 164, 228));
+ barGradient->addColorStop(0.49, Color(118, 164, 228));
+ barGradient->addColorStop(0.51, Color(36, 114, 210));
+ barGradient->addColorStop(0.55, Color(36, 114, 210));
+ barGradient->addColorStop(1.0, Color(57, 142, 244));
+ context->setFillGradient(barGradient.release());
+
+ RefPtr<Gradient> barStrokeGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ barStrokeGradient->addColorStop(0.0, Color(95, 107, 183));
+ barStrokeGradient->addColorStop(0.5, Color(66, 106, 174, 240));
+ barStrokeGradient->addColorStop(1.0, Color(38, 104, 166));
+ context->setStrokeGradient(barStrokeGradient.release());
+
+ Path barPath;
+ int left = rect.x();
+ if (!renderProgress->style().isLeftToRightDirection())
+ left = rect.maxX() - barWidth;
+ FloatRect barRect(left + 0.25, verticalRenderingPosition + 0.25, std::max(barWidth - 0.5, 0.0), progressBarHeight - 0.5);
+ barPath.addRoundedRect(barRect, roundedCornerRadius);
+ context->drawPath(barPath);
+ }
+
+ return false;
+}
+#endif // ENABLE(PROGRESS_ELEMENT)
+
+#if ENABLE(DATALIST_ELEMENT)
+IntSize RenderThemeIOS::sliderTickSize() const
+{
+ // FIXME: <rdar://problem/12271791> MERGEBOT: Correct values for slider tick of <input type="range"> elements (requires ENABLE_DATALIST_ELEMENT)
+ return IntSize(1, 3);
+}
+
+int RenderThemeIOS::sliderTickOffsetFromTrackCenter() const
+{
+ // FIXME: <rdar://problem/12271791> MERGEBOT: Correct values for slider tick of <input type="range"> elements (requires ENABLE_DATALIST_ELEMENT)
+ return -9;
+}
+#endif
+
+void RenderThemeIOS::adjustSearchFieldStyle(StyleResolver* selector, RenderStyle* style, Element* element) const
+{
+ RenderTheme::adjustSearchFieldStyle(selector, style, element);
+
+ if (!element)
+ return;
+
+ if (!style->hasBorder())
+ return;
+
+ RenderBox* box = element->renderBox();
+ if (!box)
+ return;
+
+ adjustRoundBorderRadius(*style, box);
+}
+
+bool RenderThemeIOS::paintSearchFieldDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return paintTextFieldDecorations(box, paintInfo, rect);
+}
+
+void RenderThemeIOS::adjustButtonStyle(StyleResolver* selector, RenderStyle* style, Element* element) const
+{
+ RenderTheme::adjustButtonStyle(selector, style, element);
+
+ // Set padding: 0 1.0em; on buttons.
+ // CSSPrimitiveValue::computeLengthInt only needs the element's style to calculate em lengths.
+ // Since the element might not be in a document, just pass nullptr for the root element style.
+ RefPtr<CSSPrimitiveValue> emSize = CSSPrimitiveValue::create(1.0, CSSPrimitiveValue::CSS_EMS);
+ int pixels = emSize->computeLength<int>(style, nullptr);
+ style->setPaddingBox(LengthBox(0, pixels, 0, pixels));
+
+ if (!element)
+ return;
+
+ RenderBox* box = element->renderBox();
+ if (!box)
+ return;
+
+ adjustRoundBorderRadius(*style, box);
+}
+
+bool RenderThemeIOS::paintButtonDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return paintPushButtonDecorations(box, paintInfo, rect);
+}
+
+bool RenderThemeIOS::paintPushButtonDecorations(RenderObject* box, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ FloatRect clip = addRoundedBorderClip(box, paintInfo.context, rect);
+
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ if (box->style().visitedDependentColor(CSSPropertyBackgroundColor).isDark())
+ drawAxialGradient(cgContext, gradientWithName(ConvexGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ else {
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), clip.location(), FloatPoint(clip.x(), clip.maxY()), LinearInterpolation);
+ drawAxialGradient(cgContext, gradientWithName(ShineGradient), FloatPoint(clip.x(), clip.maxY()), clip.location(), ExponentialInterpolation);
+ }
+ return false;
+}
+
+void RenderThemeIOS::setButtonSize(RenderStyle* style) const
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ // Use the font size to determine the intrinsic width of the control.
+ style->setHeight(Length(static_cast<int>(ControlBaseHeight / ControlBaseFontSize * style->fontDescription().computedSize()), Fixed));
+}
+
+const int kThumbnailBorderStrokeWidth = 1;
+const int kThumbnailBorderCornerRadius = 1;
+const int kVisibleBackgroundImageWidth = 1;
+const int kMultipleThumbnailShrinkSize = 2;
+
+bool RenderThemeIOS::paintFileUploadIconDecorations(RenderObject*, RenderObject* buttonRenderer, const PaintInfo& paintInfo, const IntRect& rect, Icon* icon, FileUploadDecorations fileUploadDecorations)
+{
+ GraphicsContextStateSaver stateSaver(*paintInfo.context);
+
+ IntSize cornerSize(kThumbnailBorderCornerRadius, kThumbnailBorderCornerRadius);
+ Color pictureFrameColor = buttonRenderer ? buttonRenderer->style().visitedDependentColor(CSSPropertyBorderTopColor) : Color(76.0f, 76.0f, 76.0f);
+
+ IntRect thumbnailPictureFrameRect = rect;
+ IntRect thumbnailRect = rect;
+ thumbnailRect.contract(2 * kThumbnailBorderStrokeWidth, 2 * kThumbnailBorderStrokeWidth);
+ thumbnailRect.move(kThumbnailBorderStrokeWidth, kThumbnailBorderStrokeWidth);
+
+ if (fileUploadDecorations == MultipleFiles) {
+ // Smaller thumbnails for multiple selection appearance.
+ thumbnailPictureFrameRect.contract(kMultipleThumbnailShrinkSize, kMultipleThumbnailShrinkSize);
+ thumbnailRect.contract(kMultipleThumbnailShrinkSize, kMultipleThumbnailShrinkSize);
+
+ // Background picture frame and simple background icon with a gradient matching the button.
+ Color backgroundImageColor = buttonRenderer ? Color(buttonRenderer->style().visitedDependentColor(CSSPropertyBackgroundColor).rgb()) : Color(206.0f, 206.0f, 206.0f);
+ paintInfo.context->fillRoundedRect(thumbnailPictureFrameRect, cornerSize, cornerSize, cornerSize, cornerSize, pictureFrameColor, ColorSpaceDeviceRGB);
+ paintInfo.context->fillRect(thumbnailRect, backgroundImageColor, ColorSpaceDeviceRGB);
+ {
+ GraphicsContextStateSaver stateSaver2(*paintInfo.context);
+ CGContextRef cgContext = paintInfo.context->platformContext();
+ paintInfo.context->clip(thumbnailRect);
+ if (backgroundImageColor.isDark())
+ drawAxialGradient(cgContext, gradientWithName(ConvexGradient), thumbnailRect.location(), FloatPoint(thumbnailRect.x(), thumbnailRect.maxY()), LinearInterpolation);
+ else {
+ drawAxialGradient(cgContext, gradientWithName(ShadeGradient), thumbnailRect.location(), FloatPoint(thumbnailRect.x(), thumbnailRect.maxY()), LinearInterpolation);
+ drawAxialGradient(cgContext, gradientWithName(ShineGradient), FloatPoint(thumbnailRect.x(), thumbnailRect.maxY()), thumbnailRect.location(), ExponentialInterpolation);
+ }
+ }
+
+ // Move the rects for the Foreground picture frame and icon.
+ int inset = kVisibleBackgroundImageWidth + kThumbnailBorderStrokeWidth;
+ thumbnailPictureFrameRect.move(inset, inset);
+ thumbnailRect.move(inset, inset);
+ }
+
+ // Foreground picture frame and icon.
+ paintInfo.context->fillRoundedRect(thumbnailPictureFrameRect, cornerSize, cornerSize, cornerSize, cornerSize, pictureFrameColor, ColorSpaceDeviceRGB);
+ icon->paint(paintInfo.context, thumbnailRect);
+
+ return false;
+}
+
+Color RenderThemeIOS::platformActiveSelectionBackgroundColor() const
+{
+ return Color::transparent;
+}
+
+Color RenderThemeIOS::platformInactiveSelectionBackgroundColor() const
+{
+ return Color::transparent;
+}
+
+bool RenderThemeIOS::shouldShowPlaceholderWhenFocused() const
+{
+ return true;
+}
+
+bool RenderThemeIOS::shouldHaveSpinButton(HTMLInputElement*) const
+{
+ return false;
+}
+
+static FontWeight fromCTFontWeight(float fontWeight)
+{
+ if (fontWeight <= -0.8)
+ return FontWeight100;
+ else if (fontWeight <= -0.4)
+ return FontWeight200;
+ else if (fontWeight <= -0.2)
+ return FontWeight300;
+ else if (fontWeight <= 0.0)
+ return FontWeight400;
+ else if (fontWeight <= 0.2)
+ return FontWeight500;
+ else if (fontWeight <= 0.3)
+ return FontWeight600;
+ else if (fontWeight <= 0.4)
+ return FontWeight700;
+ else if (fontWeight <= 0.6)
+ return FontWeight800;
+ else if (fontWeight <= 0.8)
+ return FontWeight900;
+
+ return FontWeightNormal;
+}
+
+void RenderThemeIOS::systemFont(CSSValueID valueID, FontDescription& fontDescription) const
+{
+ static NeverDestroyed<FontDescription> systemFont;
+ static NeverDestroyed<FontDescription> headlineFont;
+ static NeverDestroyed<FontDescription> bodyFont;
+ static NeverDestroyed<FontDescription> subheadlineFont;
+ static NeverDestroyed<FontDescription> footnoteFont;
+ static NeverDestroyed<FontDescription> caption1Font;
+ static NeverDestroyed<FontDescription> caption2Font;
+ static NeverDestroyed<FontDescription> shortHeadlineFont;
+ static NeverDestroyed<FontDescription> shortBodyFont;
+ static NeverDestroyed<FontDescription> shortSubheadlineFont;
+ static NeverDestroyed<FontDescription> shortFootnoteFont;
+ static NeverDestroyed<FontDescription> shortCaption1Font;
+ static NeverDestroyed<FontDescription> tallBodyFont;
+
+ static CFStringRef userTextSize = contentSizeCategory();
+
+ if (userTextSize != contentSizeCategory()) {
+ userTextSize = contentSizeCategory();
+
+ headlineFont.setIsAbsoluteSize(false);
+ bodyFont.setIsAbsoluteSize(false);
+ subheadlineFont.setIsAbsoluteSize(false);
+ footnoteFont.setIsAbsoluteSize(false);
+ caption1Font.setIsAbsoluteSize(false);
+ caption2Font.setIsAbsoluteSize(false);
+ shortHeadlineFont.setIsAbsoluteSize(false);
+ shortBodyFont.setIsAbsoluteSize(false);
+ shortSubheadlineFont.setIsAbsoluteSize(false);
+ shortFootnoteFont.setIsAbsoluteSize(false);
+ shortCaption1Font.setIsAbsoluteSize(false);
+ tallBodyFont.setIsAbsoluteSize(false);
+ }
+
+ FontDescription* cachedDesc;
+ RetainPtr<CTFontDescriptorRef> fontDescriptor;
+ CFStringRef textStyle;
+ switch (valueID) {
+ case CSSValueAppleSystemHeadline:
+ cachedDesc = &headlineFont;
+ textStyle = kCTUIFontTextStyleHeadline;
+ if (!headlineFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemBody:
+ cachedDesc = &bodyFont;
+ textStyle = kCTUIFontTextStyleBody;
+ if (!bodyFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemSubheadline:
+ cachedDesc = &subheadlineFont;
+ textStyle = kCTUIFontTextStyleSubhead;
+ if (!subheadlineFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemFootnote:
+ cachedDesc = &footnoteFont;
+ textStyle = kCTUIFontTextStyleFootnote;
+ if (!footnoteFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemCaption1:
+ cachedDesc = &caption1Font;
+ textStyle = kCTUIFontTextStyleCaption1;
+ if (!caption1Font.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemCaption2:
+ cachedDesc = &caption2Font;
+ textStyle = kCTUIFontTextStyleCaption2;
+ if (!caption2Font.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+
+ // Short version.
+ case CSSValueAppleSystemShortHeadline:
+ cachedDesc = &shortHeadlineFont;
+ textStyle = kCTUIFontTextStyleShortHeadline;
+ if (!shortHeadlineFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemShortBody:
+ cachedDesc = &shortBodyFont;
+ textStyle = kCTUIFontTextStyleShortBody;
+ if (!shortBodyFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemShortSubheadline:
+ cachedDesc = &shortSubheadlineFont;
+ textStyle = kCTUIFontTextStyleShortSubhead;
+ if (!shortSubheadlineFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemShortFootnote:
+ cachedDesc = &shortFootnoteFont;
+ textStyle = kCTUIFontTextStyleShortFootnote;
+ if (!shortFootnoteFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+ case CSSValueAppleSystemShortCaption1:
+ cachedDesc = &shortCaption1Font;
+ textStyle = kCTUIFontTextStyleShortCaption1;
+ if (!shortCaption1Font.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+
+ // Tall version.
+ case CSSValueAppleSystemTallBody:
+ cachedDesc = &tallBodyFont;
+ textStyle = kCTUIFontTextStyleTallBody;
+ if (!tallBodyFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(textStyle, userTextSize, 0));
+ break;
+
+ default:
+ textStyle = kCTFontDescriptorTextStyleEmphasized;
+ cachedDesc = &systemFont;
+ if (!systemFont.isAbsoluteSize())
+ fontDescriptor = adoptCF(CTFontDescriptorCreateForUIType(kCTFontSystemFontType, 0, nullptr));
+ }
+
+ if (fontDescriptor) {
+ RetainPtr<CTFontRef> font = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), 0, nullptr));
+ cachedDesc->setIsAbsoluteSize(true);
+ cachedDesc->setGenericFamily(FontDescription::NoFamily);
+ cachedDesc->setOneFamily(textStyle);
+ cachedDesc->setSpecifiedSize(CTFontGetSize(font.get()));
+ cachedDesc->setWeight(fromCTFontWeight(FontCache::weightOfCTFont(font.get())));
+ cachedDesc->setItalic(0);
+ }
+ fontDescription = *cachedDesc;
+}
+
+#if ENABLE(VIDEO)
+String RenderThemeIOS::mediaControlsStyleSheet()
+{
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+ return String(mediaControlsiOSUserAgentStyleSheet, sizeof(mediaControlsiOSUserAgentStyleSheet));
+#else
+ return emptyString();
+#endif
+}
+
+String RenderThemeIOS::mediaControlsScript()
+{
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+ return String(mediaControlsAppleJavaScript, sizeof(mediaControlsAppleJavaScript));
+#else
+ return emptyString();
+#endif
+}
+#endif // ENABLE(VIDEO)
+
+}
+
+#endif //PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeMac.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeMac.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderThemeMac.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -19,6 +19,7 @@
</span><span class="cx"> * Boston, MA 02110-1301, USA.
</span><span class="cx"> *
</span><span class="cx"> */
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx">
</span><span class="cx"> #ifndef RenderThemeMac_h
</span><span class="cx"> #define RenderThemeMac_h
</span><span class="lines">@@ -235,3 +236,5 @@
</span><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // RenderThemeMac_h
</span><ins>+
+#endif // !PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeMac.mm (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeMac.mm        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderThemeMac.mm        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -16,6 +16,7 @@
</span><span class="cx"> * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
</span><span class="cx"> * Boston, MA 02110-1301, USA.
</span><span class="cx"> */
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx">
</span><span class="cx"> #import "config.h"
</span><span class="cx"> #import "RenderThemeMac.h"
</span><span class="lines">@@ -1933,3 +1934,5 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span><ins>+
+#endif // !PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderVideocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderVideo.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderVideo.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderVideo.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -116,11 +116,13 @@
</span><span class="cx"> if (videoElement().shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !imageResource()->errorOccurred())
</span><span class="cx"> return m_cachedImageSize;
</span><span class="cx">
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> // When the natural size of the video is unavailable, we use the provided
</span><span class="cx"> // width and height attributes of the video element as the intrinsic size until
</span><span class="cx"> // better values become available.
</span><span class="cx"> if (videoElement().hasAttribute(widthAttr) && videoElement().hasAttribute(heightAttr))
</span><span class="cx"> return LayoutSize(videoElement().width(), videoElement().height());
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // <video> in standalone media documents should not use the default 300x150
</span><span class="cx"> // size since they also have audio-only files. By setting the intrinsic
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderView.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderView.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderView.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -137,6 +137,11 @@
</span><span class="cx"> // If we have columns, then the available logical height is reduced to the column height.
</span><span class="cx"> if (hasColumns())
</span><span class="cx"> return columnInfo()->columnHeight();
</span><ins>+#if PLATFORM(IOS)
+ // Workaround for <rdar://problem/7166808>.
+ if (document().isPluginDocument() && frameView().useFixedLayout())
+ return frameView().fixedLayoutSize().height();
+#endif
</ins><span class="cx"> return isHorizontalWritingMode() ? frameView().visibleHeight() : frameView().visibleWidth();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -363,6 +368,13 @@
</span><span class="cx"> return viewLogicalHeight();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static inline LayoutSize fixedPositionOffset(const FrameView& frameView)
+{
+ return frameView.useCustomFixedPositionLayoutRect() ? (frameView.customFixedPositionLayoutRect().location() - LayoutPoint()) : frameView->scrollOffset();
+}
+#endif
+
</ins><span class="cx"> void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
</span><span class="cx"> {
</span><span class="cx"> // If a container was specified, and was not 0 or the RenderView,
</span><span class="lines">@@ -377,7 +389,11 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (mode & IsFixed)
</span><ins>+#if PLATFORM(IOS)
+ transformState.move(fixedPositionOffset(m_frameView));
+#else
</ins><span class="cx"> transformState.move(frameView().scrollOffsetForFixedPosition());
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
</span><span class="lines">@@ -386,7 +402,11 @@
</span><span class="cx"> // then we should have found it by now.
</span><span class="cx"> ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this);
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ LayoutSize scrollOffset = fixedPositionOffset(frameView());
+#else
</ins><span class="cx"> LayoutSize scrollOffset = frameView().scrollOffsetForFixedPosition();
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (!ancestorToStopAt && shouldUseTransformFromContainer(0)) {
</span><span class="cx"> TransformationMatrix t;
</span><span class="lines">@@ -401,7 +421,11 @@
</span><span class="cx"> void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
</span><span class="cx"> {
</span><span class="cx"> if (mode & IsFixed)
</span><ins>+#if PLATFORM(IOS)
+ transformState.move(fixedPositionOffset(frameView()));
+#else
</ins><span class="cx"> transformState.move(frameView().scrollOffsetForFixedPosition());
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (mode & UseTransforms && shouldUseTransformFromContainer(0)) {
</span><span class="cx"> TransformationMatrix t;
</span><span class="lines">@@ -572,7 +596,12 @@
</span><span class="cx"> frameView().repaintContentRectangle(pixelSnappedIntRect(ur), immediate);
</span><span class="cx"> else if (RenderBox* obj = elt->renderBox()) {
</span><span class="cx"> LayoutRect vr = viewRect();
</span><ins>+#if PLATFORM(IOS)
+ // Don't clip using the visible rect since clipping is handled at a higher level on iPhone.
+ LayoutRect r = ur;
+#else
</ins><span class="cx"> LayoutRect r = intersection(ur, vr);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
</span><span class="cx"> // rectangle.
</span><span class="lines">@@ -636,8 +665,13 @@
</span><span class="cx"> rect.setX(viewWidth() - rect.maxX());
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (fixed)
</del><ins>+ if (fixed) {
+#if PLATFORM(IOS)
+ rect.move(fixedPositionOffset(frameView()));
+#else
</ins><span class="cx"> rect.move(frameView().scrollOffsetForFixedPosition());
</span><ins>+#endif
+ }
</ins><span class="cx">
</span><span class="cx"> // Apply our transform if we have one (because of full page zooming).
</span><span class="cx"> if (!repaintContainer && layer() && layer()->transform())
</span><span class="lines">@@ -1156,6 +1190,24 @@
</span><span class="cx"> return *m_flowThreadController;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+static bool isFixedPositionInViewport(const RenderObject& renderer, const RenderObject* container)
+{
+ return (renderer.style().position() == FixedPosition) && renderer.container() == container;
+}
+
+bool RenderView::hasCustomFixedPosition(const RenderObject& renderer, ContainingBlockCheck checkContainer) const
+{
+ if (!frameView().useCustomFixedPositionLayoutRect())
+ return false;
+
+ if (checkContainer == CheckContainingBlock)
+ return isFixedPositionInViewport(renderer, this);
+
+ return renderer.style().position() == FixedPosition;
+}
+#endif
+
</ins><span class="cx"> void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject& object)
</span><span class="cx"> {
</span><span class="cx"> if (!m_flowThreadController)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderView.h (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderView.h        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderView.h        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -204,6 +204,11 @@
</span><span class="cx">
</span><span class="cx"> virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
</span><span class="cx">
</span><ins>+#if PLATFORM(IOS)
+ enum ContainingBlockCheck { CheckContainingBlock, DontCheckContainingBlock };
+ bool hasCustomFixedPosition(const RenderObject&, ContainingBlockCheck = CheckContainingBlock) const;
+#endif
+
</ins><span class="cx"> IntervalArena* intervalArena();
</span><span class="cx">
</span><span class="cx"> IntSize viewportSize() const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderWidgetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderWidget.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderWidget.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RenderWidget.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -91,6 +91,11 @@
</span><span class="cx">
</span><span class="cx"> void RenderWidget::willBeDestroyed()
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+ if (hasLayer())
+ layer()->willBeDestroyed();
+#endif
+
</ins><span class="cx"> if (AXObjectCache* cache = document().existingAXObjectCache()) {
</span><span class="cx"> cache->childrenChanged(this->parent());
</span><span class="cx"> cache->remove(this);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRootInlineBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RootInlineBox.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -846,7 +846,11 @@
</span><span class="cx"> bool setUsedFontWithLeading = false;
</span><span class="cx">
</span><span class="cx"> const RenderStyle& boxLineStyle = box->lineStyle();
</span><ins>+#if PLATFORM(IOS)
+ if (usedFonts && !usedFonts->isEmpty() && (includeFont || (boxLineStyle.lineHeight().isNegative() && includeLeading)) && !box->renderer().document().settings()->alwaysUseBaselineOfPrimaryFont()) {
+#else
</ins><span class="cx"> if (usedFonts && !usedFonts->isEmpty() && (includeFont || (boxLineStyle.lineHeight().isNegative() && includeLeading))) {
</span><ins>+#endif
</ins><span class="cx"> usedFonts->append(boxLineStyle.font().primaryFont());
</span><span class="cx"> for (size_t i = 0; i < usedFonts->size(); ++i) {
</span><span class="cx"> const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingbreak_linescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/break_lines.cpp (160235 => 160236)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/break_lines.cpp        2013-12-06 19:31:50 UTC (rev 160235)
+++ trunk/Source/WebCore/rendering/break_lines.cpp        2013-12-06 19:59:38 UTC (rev 160236)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> #include <wtf/StdLibExtras.h>
</span><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</span><span class="cx">
</span><del>-#if PLATFORM(MAC)
</del><ins>+#if PLATFORM(MAC) && !PLATFORM(IOS)
</ins><span class="cx"> #include <CoreServices/CoreServices.h>
</span><span class="cx"> #endif
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>