Index: Source/core/dom/Document.cpp |
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp |
index 3f9fe5d48f1c414e4c990c06de69b89036359ead..04ffab170ce6b2e808c7d0fdeb11a71001916c8c 100644 |
--- a/Source/core/dom/Document.cpp |
+++ b/Source/core/dom/Document.cpp |
@@ -342,6 +342,29 @@ static void printNavigationErrorMessage(const Frame& frame, const KURL& activeUR |
frame.domWindow()->printErrorMessage(message); |
} |
+// Decide which element that is to define the viewport's overflow policy. Any parameter may be |
+// 0. Avoid calling Element::renderStyle() here; require style as separate parameters instead. The |
+// reason for this is that style may not have been associated with the elements yet - in which case |
+// it may have been calculated on the fly (without associating it with the actual element) |
+// somewhere. This isn't very pretty, but if we want to avoid duplicating the code that chooses |
+// between root and body for overflow propagation, this is about as pretty as it gets. |
rune
2014/02/07 16:44:27
You could consolidate this code with the viewportD
mstensho (USE GERRIT)
2014/02/11 10:44:14
Done.
|
+// The |bodyElement| passed must either be 0 or set to the document's primary body element. |
+static Element* pickViewportDefiningElement(Element* rootElement, RenderStyle* rootStyle, Element* bodyElement, RenderStyle* bodyStyle) |
ojan
2014/02/08 01:40:19
Do we need to pass the RenderStyles? Can't we just
mstensho (USE GERRIT)
2014/02/11 10:44:14
That's not always going to work. The comment tries
|
+{ |
+ // If a BODY element sets non-visible overflow, it is to be propagated to the viewport, as long |
+ // as the following conditions are all met: |
+ // (1) The root element is HTML. |
+ // (2) It is the primary BODY element (we only assert for this, expecting callers to behave). |
+ // (3) The root element has visible overflow. |
+ // Otherwise it's the root element's properties that are to be propagated. |
+ if (!rootElement || !rootStyle) |
+ return 0; |
+ ASSERT(!bodyElement || bodyElement == bodyElement->document().body()); |
+ if (bodyElement && bodyStyle && rootStyle->isOverflowVisible() && rootElement->hasTagName(htmlTag)) |
+ return bodyElement; |
+ return rootElement; |
+} |
+ |
uint64_t Document::s_globalTreeVersion = 0; |
// This class doesn't work with non-Document ExecutionContext. |
@@ -1607,14 +1630,6 @@ void Document::updateDistributionForNodeIfNeeded(Node* node) |
void Document::setStyleDependentState(RenderStyle* documentStyle) |
ojan
2014/02/08 01:40:19
Nit: maybe rename this method to setupFontBuilder
mstensho (USE GERRIT)
2014/02/11 10:44:14
Done.
|
{ |
- const Pagination& pagination = view()->pagination(); |
- if (pagination.mode != Pagination::Unpaginated) { |
- Pagination::setStylesForPaginationMode(pagination.mode, documentStyle); |
- documentStyle->setColumnGap(pagination.gap); |
- if (renderView()->hasColumns()) |
- renderView()->updateColumnInfoFromStyle(documentStyle); |
- } |
- |
FontBuilder fontBuilder; |
fontBuilder.initForStyleResolve(*this, documentStyle, isSVGDocument()); |
RefPtr<CSSFontSelector> selector = m_styleEngine->fontSelector(); |
@@ -1632,10 +1647,11 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change) |
WritingMode rootWritingMode = documentElementStyle->writingMode(); |
TextDirection rootDirection = documentElementStyle->direction(); |
- HTMLElement* body = this->body(); |
+ HTMLElement* body = this->body(); |
+ RefPtr<RenderStyle> bodyStyle; |
if (body) { |
- RefPtr<RenderStyle> bodyStyle = body->renderStyle(); |
+ bodyStyle = body->renderStyle(); |
if (!bodyStyle || body->needsStyleRecalc() || documentElement()->needsStyleRecalc() || change == Force) |
bodyStyle = ensureStyleResolver().styleForElement(body, documentElementStyle.get()); |
if (!writingModeSetOnDocumentElement()) |
@@ -1644,6 +1660,16 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change) |
rootDirection = bodyStyle->direction(); |
} |
+ RefPtr<RenderStyle> overflowStyle; |
+ if (Element* element = pickViewportDefiningElement(documentElement(), documentElementStyle.get(), body, bodyStyle.get())) { |
+ if (element == body) { |
+ overflowStyle = bodyStyle; |
+ } else { |
+ ASSERT(element == documentElement()); |
+ overflowStyle = documentElementStyle; |
+ } |
+ } |
+ |
// Resolved rem units are stored in the matched properties cache so we need to make sure to |
// invalidate the cache if the documentElement needed to reattach or the font size changed |
// and then trigger a full document recalc. We also need to clear it here since the |
@@ -1657,10 +1683,29 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change) |
} |
RefPtr<RenderStyle> documentStyle = renderView()->style(); |
- if (documentStyle->writingMode() != rootWritingMode || documentStyle->direction() != rootDirection) { |
+ if (documentStyle->writingMode() != rootWritingMode |
+ || documentStyle->direction() != rootDirection |
+ || (overflowStyle && (documentStyle->overflowX() != overflowStyle->overflowX() || documentStyle->overflowY() != overflowStyle->overflowY()))) { |
RefPtr<RenderStyle> newStyle = RenderStyle::clone(documentStyle.get()); |
newStyle->setWritingMode(rootWritingMode); |
newStyle->setDirection(rootDirection); |
+ EOverflow overflowX = OAUTO; |
+ EOverflow overflowY = OAUTO; |
+ if (overflowStyle) { |
+ overflowX = overflowStyle->overflowX(); |
+ overflowY = overflowStyle->overflowY(); |
+ // Visible overflow on the viewport is meaningless. |
+ if (overflowX == OVISIBLE) |
+ overflowX = OAUTO; |
ojan
2014/02/08 01:40:19
We need to do this because pagination doesn't work
mstensho (USE GERRIT)
2014/02/11 10:44:14
overflow:visible is meaningless on the viewport, r
|
+ if (overflowY == OVISIBLE) |
+ overflowY = OAUTO; |
+ |
+ // Column-gap is (ab)used by the current paged overflow implementation (in lack of other |
+ // ways to specify gaps between pages), so we have to propagate it too. |
+ newStyle->setColumnGap(overflowStyle->columnGap()); |
+ } |
+ newStyle->setOverflowX(overflowX); |
+ newStyle->setOverflowY(overflowY); |
renderView()->setStyle(newStyle); |
setStyleDependentState(newStyle.get()); |
} |
@@ -2340,6 +2385,15 @@ HTMLHeadElement* Document::head() |
return 0; |
} |
+Element* Document::viewportDefiningElement() const |
+{ |
+ Element* rootElement = documentElement(); |
+ Element* bodyElement = body(); |
+ return pickViewportDefiningElement( |
+ rootElement, rootElement ? rootElement->renderStyle() : 0, |
+ bodyElement, bodyElement ? bodyElement->renderStyle() : 0); |
+} |
+ |
void Document::close() |
{ |
// FIXME: We should follow the specification more closely: |