Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: Source/core/dom/NodeRenderingContext.cpp

Issue 15027005: [CSS Regions] Elements in a region should be assignable to a named flow (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Integrates all feedback. One of the tests causes an ASSERT in ContentShell because of Region Ranges. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
7 * Copyright (C) 2011 Google Inc. All rights reserved. 7 * Copyright (C) 2011 Google Inc. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 182
183 bool NodeRenderingContext::shouldCreateRenderer() const 183 bool NodeRenderingContext::shouldCreateRenderer() const
184 { 184 {
185 if (!m_node->document()->shouldCreateRenderers()) 185 if (!m_node->document()->shouldCreateRenderers())
186 return false; 186 return false;
187 if (!m_renderingParent) 187 if (!m_renderingParent)
188 return false; 188 return false;
189 RenderObject* parentRenderer = this->parentRenderer(); 189 RenderObject* parentRenderer = this->parentRenderer();
190 if (!parentRenderer) 190 if (!parentRenderer)
191 return false; 191 return false;
192 if (!parentRenderer->canHaveChildren()) 192 if (!parentRenderer->canHaveChildren()) {
193 return false; 193 if (parentRenderer->canDOMChildrenHaveRenderParent()) {
194 if (!shouldMoveToFlowThread())
195 return false;
196 } else {
197 return false;
198 }
199 }
194 if (!m_renderingParent->childShouldCreateRenderer(*this)) 200 if (!m_renderingParent->childShouldCreateRenderer(*this))
195 return false; 201 return false;
196 return true; 202 return true;
197 } 203 }
198 204
199 void NodeRenderingContext::moveToFlowThreadIfNeeded() 205 bool NodeRenderingContext::shouldMoveToFlowThread() const
200 { 206 {
201 ASSERT(m_node->isElementNode()); 207 if (!m_node->isElementNode())
202 ASSERT(m_style); 208 return false;
209 Element* element = toElement(m_node);
210
203 if (!RuntimeEnabledFeatures::cssRegionsEnabled()) 211 if (!RuntimeEnabledFeatures::cssRegionsEnabled())
204 return; 212 return false;
205 213
206 if (m_style->flowThread().isEmpty()) 214 if (element && FullscreenController::isActiveFullScreenElement(element))
207 return; 215 return false;
216
217 if (m_node->isInShadowTree())
218 return false;
208 219
209 // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements s uch as ::first-line, ::first-letter, ::before or ::after 220 // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements s uch as ::first-line, ::first-letter, ::before or ::after
210 // cannot be directly collected into a named flow. 221 // cannot be directly collected into a named flow.
211 if (m_node->isPseudoElement()) 222 if (m_node->isPseudoElement())
212 return; 223 return false;
213
214 // FIXME: Do not collect elements if they are in shadow tree.
215 if (m_node->isInShadowTree())
216 return;
217
218 if (m_node->isElementNode() && FullscreenController::isActiveFullScreenEleme nt(toElement(m_node)))
219 return;
220 224
221 // Allow only svg root elements to be directly collected by a render flow th read. 225 // Allow only svg root elements to be directly collected by a render flow th read.
222 if (m_node->isSVGElement() 226 if (m_node->isSVGElement()
223 && (!(m_node->hasTagName(SVGNames::svgTag) && m_node->parentNode() && !m _node->parentNode()->isSVGElement()))) 227 && (!(m_node->hasTagName(SVGNames::svgTag) && m_node->parentNode() && !m _node->parentNode()->isSVGElement())))
228 return false;
229
230 if (!m_style)
231 m_style = element->styleForRenderer();
232 if (!m_style)
233 return false;
234
235 if (m_style->flowThread().isEmpty())
236 return false;
237
238 if (m_node->document()->renderView()->flowThreadController()->isContentNodeR egisteredWithAnyNamedFlow(m_node))
239 return false;
240
241 return true;
242 }
243
244 void NodeRenderingContext::moveToFlowThreadIfNeeded()
245 {
246 if (!shouldMoveToFlowThread())
224 return; 247 return;
225 248
226 m_flowThread = m_style->flowThread(); 249 moveToFlowThread();
250 }
251
252 void NodeRenderingContext::moveToFlowThread()
253 {
254 ASSERT(m_node->isElementNode());
255 ASSERT(shouldMoveToFlowThread());
256
227 ASSERT(m_node->document()->renderView()); 257 ASSERT(m_node->document()->renderView());
228 FlowThreadController* flowThreadController = m_node->document()->renderView( )->flowThreadController(); 258 FlowThreadController* flowThreadController = m_node->document()->renderView( )->flowThreadController();
229 m_parentFlowRenderer = flowThreadController->ensureRenderFlowThreadWithName( m_flowThread); 259 m_parentFlowRenderer = flowThreadController->ensureRenderFlowThreadWithName( getStyleForRenderer()->flowThread());
230 flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRende rer); 260 flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRende rer);
231 } 261 }
232 262
263 PassRefPtr<RenderStyle> NodeRenderingContext::getStyleForRenderer() const
264 {
265 ASSERT(m_node->isElementNode());
266 if (!m_style)
267 m_style = toElement(m_node)->styleForRenderer();
268 ASSERT(m_style);
269 return m_style;
270 }
271
233 bool NodeRenderingContext::isOnEncapsulationBoundary() const 272 bool NodeRenderingContext::isOnEncapsulationBoundary() const
234 { 273 {
235 return isOnUpperEncapsulationBoundary() || isLowerEncapsulationBoundary(m_pa rentDetails.insertionPoint()) || isLowerEncapsulationBoundary(m_node->parentNode ()); 274 return isOnUpperEncapsulationBoundary() || isLowerEncapsulationBoundary(m_pa rentDetails.insertionPoint()) || isLowerEncapsulationBoundary(m_node->parentNode ());
236 } 275 }
237 276
238 bool NodeRenderingContext::isOnUpperEncapsulationBoundary() const 277 bool NodeRenderingContext::isOnUpperEncapsulationBoundary() const
239 { 278 {
240 return m_node->parentNode() && m_node->parentNode()->isShadowRoot(); 279 return m_node->parentNode() && m_node->parentNode()->isShadowRoot();
241 } 280 }
242 281
243 void NodeRenderingContext::createRendererForElementIfNeeded() 282 void NodeRenderingContext::createRendererForElementIfNeeded()
244 { 283 {
245 ASSERT(!m_node->renderer()); 284 ASSERT(!m_node->renderer());
246 285
286 ASSERT(m_node->isElementNode());
247 Element* element = toElement(m_node); 287 Element* element = toElement(m_node);
248 288
289 // Look for nodes inside a region that are flowed into a 2nd region.
290 // This avoids doing a style resolution for all nodes.
291 bool haveTestedForMoveToFlowThread = false;
292 for (const Element* parentElement = m_node->parentElement(); parentElement; parentElement = parentElement->parentElement()) {
esprehn 2013/06/17 21:41:02 Woah, this isn't right. This is going to cause per
293 if (const RenderObject* rendererParentElement = parentElement->renderer( )) {
294 if (!rendererParentElement->canHaveChildren() && rendererParentEleme nt->canDOMChildrenHaveRenderParent()) {
295 moveToFlowThreadIfNeeded();
296 haveTestedForMoveToFlowThread = true;
297 break;
298 }
299 }
300 }
301
249 if (!shouldCreateRenderer()) 302 if (!shouldCreateRenderer())
250 return; 303 return;
251 m_style = element->styleForRenderer();
252 ASSERT(m_style);
253 304
254 moveToFlowThreadIfNeeded(); 305 // The usual case when elements collected in a flow are not children of a re gion.
306 if (!haveTestedForMoveToFlowThread)
307 moveToFlowThreadIfNeeded();
255 308
309 getStyleForRenderer(); // rendererIsNeeded will call NodeRenderingContext::s tyle()
esprehn 2013/06/17 21:41:02 Calling a method with a return value and ignoring
maerean 2013/06/17 21:58:45 I have tried using getStyleForRenderer in Element:
256 if (!element->rendererIsNeeded(*this)) 310 if (!element->rendererIsNeeded(*this))
257 return; 311 return;
258 312
259 RenderObject* parentRenderer = this->parentRenderer(); 313 RenderObject* parentRenderer = this->parentRenderer();
260 RenderObject* nextRenderer = this->nextRenderer(); 314 RenderObject* nextRenderer = this->nextRenderer();
261 315
262 Document* document = element->document(); 316 Document* document = element->document();
263 RenderObject* newRenderer = element->createRenderer(document->renderArena(), m_style.get()); 317 RenderObject* newRenderer = element->createRenderer(document->renderArena(), getStyleForRenderer().get());
264 if (!newRenderer) 318 if (!newRenderer)
265 return; 319 return;
266 320
267 if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) { 321 if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
268 newRenderer->destroy(); 322 newRenderer->destroy();
269 return; 323 return;
270 } 324 }
271 325
272 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style 326 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style
273 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail. 327 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); 373 newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
320 374
321 RenderObject* nextRenderer = this->nextRenderer(); 375 RenderObject* nextRenderer = this->nextRenderer();
322 textNode->setRenderer(newRenderer); 376 textNode->setRenderer(newRenderer);
323 // Parent takes care of the animations, no need to call setAnimatableStyle. 377 // Parent takes care of the animations, no need to call setAnimatableStyle.
324 newRenderer->setStyle(m_style.release()); 378 newRenderer->setStyle(m_style.release());
325 parentRenderer->addChild(newRenderer, nextRenderer); 379 parentRenderer->addChild(newRenderer, nextRenderer);
326 } 380 }
327 381
328 } 382 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698