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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutInline.cpp

Issue 2394263004: Reformat comments in core/layout up until LayoutMultiColumnFlowThread (Closed)
Patch Set: Created 4 years, 2 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 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc.
5 * All rights reserved.
5 * 6 *
6 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
10 * 11 *
11 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details. 15 * Library General Public License for more details.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 }; 51 };
51 52
52 static_assert(sizeof(LayoutInline) == sizeof(SameSizeAsLayoutInline), 53 static_assert(sizeof(LayoutInline) == sizeof(SameSizeAsLayoutInline),
53 "LayoutInline should stay small"); 54 "LayoutInline should stay small");
54 55
55 LayoutInline::LayoutInline(Element* element) : LayoutBoxModelObject(element) { 56 LayoutInline::LayoutInline(Element* element) : LayoutBoxModelObject(element) {
56 setChildrenInline(true); 57 setChildrenInline(true);
57 } 58 }
58 59
59 void LayoutInline::willBeDestroyed() { 60 void LayoutInline::willBeDestroyed() {
60 // Make sure to destroy anonymous children first while they are still connecte d to the rest of the tree, so that they will 61 // Make sure to destroy anonymous children first while they are still
61 // properly dirty line boxes that they are removed from. Effects that do :bef ore/:after only on hover could crash otherwise. 62 // connected to the rest of the tree, so that they will properly dirty line
63 // boxes that they are removed from. Effects that do :before/:after only on
64 // hover could crash otherwise.
62 children()->destroyLeftoverChildren(); 65 children()->destroyLeftoverChildren();
63 66
64 // Destroy our continuation before anything other than anonymous children. 67 // Destroy our continuation before anything other than anonymous children.
65 // The reason we don't destroy it before anonymous children is that they may 68 // The reason we don't destroy it before anonymous children is that they may
66 // have continuations of their own that are anonymous children of our continua tion. 69 // have continuations of their own that are anonymous children of our
70 // continuation.
67 LayoutBoxModelObject* continuation = this->continuation(); 71 LayoutBoxModelObject* continuation = this->continuation();
68 if (continuation) { 72 if (continuation) {
69 continuation->destroy(); 73 continuation->destroy();
70 setContinuation(nullptr); 74 setContinuation(nullptr);
71 } 75 }
72 76
73 if (!documentBeingDestroyed()) { 77 if (!documentBeingDestroyed()) {
74 if (firstLineBox()) { 78 if (firstLineBox()) {
75 // We can't wait for LayoutBoxModelObject::destroy to clear the selection, 79 // We can't wait for LayoutBoxModelObject::destroy to clear the selection,
76 // because by then we will have nuked the line boxes. 80 // because by then we will have nuked the line boxes.
(...skipping 24 matching lines...) Expand all
101 LayoutInline* LayoutInline::inlineElementContinuation() const { 105 LayoutInline* LayoutInline::inlineElementContinuation() const {
102 LayoutBoxModelObject* continuation = this->continuation(); 106 LayoutBoxModelObject* continuation = this->continuation();
103 if (!continuation || continuation->isInline()) 107 if (!continuation || continuation->isInline())
104 return toLayoutInline(continuation); 108 return toLayoutInline(continuation);
105 return toLayoutBlockFlow(continuation)->inlineElementContinuation(); 109 return toLayoutBlockFlow(continuation)->inlineElementContinuation();
106 } 110 }
107 111
108 void LayoutInline::updateFromStyle() { 112 void LayoutInline::updateFromStyle() {
109 LayoutBoxModelObject::updateFromStyle(); 113 LayoutBoxModelObject::updateFromStyle();
110 114
111 // FIXME: Is this still needed. Was needed for run-ins, since run-in is consid ered a block display type. 115 // FIXME: Is this still needed. Was needed for run-ins, since run-in is
116 // considered a block display type.
112 setInline(true); 117 setInline(true);
113 118
114 // FIXME: Support transforms and reflections on inline flows someday. 119 // FIXME: Support transforms and reflections on inline flows someday.
115 setHasTransformRelatedProperty(false); 120 setHasTransformRelatedProperty(false);
116 setHasReflection(false); 121 setHasReflection(false);
117 } 122 }
118 123
119 static LayoutObject* inFlowPositionedInlineAncestor(LayoutObject* p) { 124 static LayoutObject* inFlowPositionedInlineAncestor(LayoutObject* p) {
120 while (p && p->isLayoutInline()) { 125 while (p && p->isLayoutInline()) {
121 if (p->isInFlowPositioned()) 126 if (p->isInFlowPositioned())
122 return p; 127 return p;
123 p = p->parent(); 128 p = p->parent();
124 } 129 }
125 return nullptr; 130 return nullptr;
126 } 131 }
127 132
128 static void updateInFlowPositionOfAnonymousBlockContinuations( 133 static void updateInFlowPositionOfAnonymousBlockContinuations(
129 LayoutObject* block, 134 LayoutObject* block,
130 const ComputedStyle& newStyle, 135 const ComputedStyle& newStyle,
131 const ComputedStyle& oldStyle, 136 const ComputedStyle& oldStyle,
132 LayoutObject* containingBlockOfEndOfContinuation) { 137 LayoutObject* containingBlockOfEndOfContinuation) {
133 for (; block && block != containingBlockOfEndOfContinuation && 138 for (; block && block != containingBlockOfEndOfContinuation &&
134 block->isAnonymousBlock(); 139 block->isAnonymousBlock();
135 block = block->nextSibling()) { 140 block = block->nextSibling()) {
136 LayoutBlockFlow* blockFlow = toLayoutBlockFlow(block); 141 LayoutBlockFlow* blockFlow = toLayoutBlockFlow(block);
137 if (!blockFlow->isAnonymousBlockContinuation()) 142 if (!blockFlow->isAnonymousBlockContinuation())
138 continue; 143 continue;
139 144
140 // If we are no longer in-flow positioned but our descendant block(s) still have an in-flow positioned ancestor then 145 // If we are no longer in-flow positioned but our descendant block(s) still
141 // their containing anonymous block should keep its in-flow positioning. 146 // have an in-flow positioned ancestor then their containing anonymous block
147 // should keep its in-flow positioning.
142 if (oldStyle.hasInFlowPosition() && 148 if (oldStyle.hasInFlowPosition() &&
143 inFlowPositionedInlineAncestor(blockFlow->inlineElementContinuation())) 149 inFlowPositionedInlineAncestor(blockFlow->inlineElementContinuation()))
144 continue; 150 continue;
145 151
146 RefPtr<ComputedStyle> newBlockStyle = 152 RefPtr<ComputedStyle> newBlockStyle =
147 ComputedStyle::clone(block->styleRef()); 153 ComputedStyle::clone(block->styleRef());
148 newBlockStyle->setPosition(newStyle.position()); 154 newBlockStyle->setPosition(newStyle.position());
149 block->setStyle(newBlockStyle); 155 block->setStyle(newBlockStyle);
150 } 156 }
151 } 157 }
152 158
153 void LayoutInline::styleDidChange(StyleDifference diff, 159 void LayoutInline::styleDidChange(StyleDifference diff,
154 const ComputedStyle* oldStyle) { 160 const ComputedStyle* oldStyle) {
155 LayoutBoxModelObject::styleDidChange(diff, oldStyle); 161 LayoutBoxModelObject::styleDidChange(diff, oldStyle);
156 162
157 // Ensure that all of the split inlines pick up the new style. We 163 // Ensure that all of the split inlines pick up the new style. We only do this
158 // only do this if we're an inline, since we don't want to propagate 164 // if we're an inline, since we don't want to propagate a block's style to the
159 // a block's style to the other inlines. 165 // other inlines. e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines
160 // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before 166 // before and after the block share the same style, but the block doesn't need
161 // and after the block share the same style, but the block doesn't 167 // to pass its style on to anyone else.
162 // need to pass its style on to anyone else.
163 const ComputedStyle& newStyle = styleRef(); 168 const ComputedStyle& newStyle = styleRef();
164 LayoutInline* continuation = inlineElementContinuation(); 169 LayoutInline* continuation = inlineElementContinuation();
165 LayoutInline* endOfContinuation = nullptr; 170 LayoutInline* endOfContinuation = nullptr;
166 for (LayoutInline* currCont = continuation; currCont; 171 for (LayoutInline* currCont = continuation; currCont;
167 currCont = currCont->inlineElementContinuation()) { 172 currCont = currCont->inlineElementContinuation()) {
168 LayoutBoxModelObject* nextCont = currCont->continuation(); 173 LayoutBoxModelObject* nextCont = currCont->continuation();
169 currCont->setContinuation(nullptr); 174 currCont->setContinuation(nullptr);
170 currCont->setStyle(mutableStyle()); 175 currCont->setStyle(mutableStyle());
171 currCont->setContinuation(nextCont); 176 currCont->setContinuation(nextCont);
172 endOfContinuation = currCont; 177 endOfContinuation = currCont;
173 } 178 }
174 179
175 if (continuation && oldStyle) { 180 if (continuation && oldStyle) {
176 ASSERT(endOfContinuation); 181 ASSERT(endOfContinuation);
177 LayoutObject* block = containingBlock()->nextSibling(); 182 LayoutObject* block = containingBlock()->nextSibling();
178 // If an inline's in-flow positioning has changed then any descendant blocks will need to change their styles accordingly. 183 // If an inline's in-flow positioning has changed then any descendant blocks
184 // will need to change their styles accordingly.
179 if (block && block->isAnonymousBlock() && 185 if (block && block->isAnonymousBlock() &&
180 newStyle.position() != oldStyle->position() && 186 newStyle.position() != oldStyle->position() &&
181 (newStyle.hasInFlowPosition() || oldStyle->hasInFlowPosition())) 187 (newStyle.hasInFlowPosition() || oldStyle->hasInFlowPosition()))
182 updateInFlowPositionOfAnonymousBlockContinuations( 188 updateInFlowPositionOfAnonymousBlockContinuations(
183 block, newStyle, *oldStyle, endOfContinuation->containingBlock()); 189 block, newStyle, *oldStyle, endOfContinuation->containingBlock());
184 } 190 }
185 191
186 if (!alwaysCreateLineBoxes()) { 192 if (!alwaysCreateLineBoxes()) {
187 bool alwaysCreateLineBoxesNew = 193 bool alwaysCreateLineBoxesNew =
188 hasSelfPaintingLayer() || hasBoxDecorationBackground() || 194 hasSelfPaintingLayer() || hasBoxDecorationBackground() ||
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const SimpleFontData* font = style.font().primaryFont(); 227 const SimpleFontData* font = style.font().primaryFont();
222 const SimpleFontData* parentFont = parentStyle.font().primaryFont(); 228 const SimpleFontData* parentFont = parentStyle.font().primaryFont();
223 229
224 return (font && parentFont && 230 return (font && parentFont &&
225 !font->getFontMetrics().hasIdenticalAscentDescentAndLineGap( 231 !font->getFontMetrics().hasIdenticalAscentDescentAndLineGap(
226 parentFont->getFontMetrics())) || 232 parentFont->getFontMetrics())) ||
227 parentStyle.lineHeight() != style.lineHeight(); 233 parentStyle.lineHeight() != style.lineHeight();
228 } 234 }
229 235
230 void LayoutInline::updateAlwaysCreateLineBoxes(bool fullLayout) { 236 void LayoutInline::updateAlwaysCreateLineBoxes(bool fullLayout) {
231 // Once we have been tainted once, just assume it will happen again. This way effects like hover highlighting that change the 237 // Once we have been tainted once, just assume it will happen again. This way
232 // background color will only cause a layout on the first rollover. 238 // effects like hover highlighting that change the background color will only
239 // cause a layout on the first rollover.
233 if (alwaysCreateLineBoxes()) 240 if (alwaysCreateLineBoxes())
234 return; 241 return;
235 242
236 const ComputedStyle& parentStyle = parent()->styleRef(); 243 const ComputedStyle& parentStyle = parent()->styleRef();
237 LayoutInline* parentLayoutInline = 244 LayoutInline* parentLayoutInline =
238 parent()->isLayoutInline() ? toLayoutInline(parent()) : 0; 245 parent()->isLayoutInline() ? toLayoutInline(parent()) : 0;
239 bool checkFonts = document().inNoQuirksMode(); 246 bool checkFonts = document().inNoQuirksMode();
240 bool alwaysCreateLineBoxesNew = 247 bool alwaysCreateLineBoxesNew =
241 (parentLayoutInline && parentLayoutInline->alwaysCreateLineBoxes()) || 248 (parentLayoutInline && parentLayoutInline->alwaysCreateLineBoxes()) ||
242 (parentLayoutInline && 249 (parentLayoutInline &&
(...skipping 22 matching lines...) Expand all
265 setAlwaysCreateLineBoxes(); 272 setAlwaysCreateLineBoxes();
266 } 273 }
267 } 274 }
268 275
269 LayoutRect LayoutInline::localCaretRect(InlineBox* inlineBox, 276 LayoutRect LayoutInline::localCaretRect(InlineBox* inlineBox,
270 int, 277 int,
271 LayoutUnit* extraWidthToEndOfLine) { 278 LayoutUnit* extraWidthToEndOfLine) {
272 if (firstChild()) { 279 if (firstChild()) {
273 // This condition is possible if the LayoutInline is at an editing boundary, 280 // This condition is possible if the LayoutInline is at an editing boundary,
274 // i.e. the VisiblePosition is: 281 // i.e. the VisiblePosition is:
275 // <LayoutInline editingBoundary=true>|<LayoutText> </LayoutText></LayoutI nline> 282 // <LayoutInline editingBoundary=true>|<LayoutText>
283 // </LayoutText></LayoutInline>
276 // FIXME: need to figure out how to make this return a valid rect, note that 284 // FIXME: need to figure out how to make this return a valid rect, note that
277 // there are no line boxes created in the above case. 285 // there are no line boxes created in the above case.
278 return LayoutRect(); 286 return LayoutRect();
279 } 287 }
280 288
281 DCHECK(!inlineBox); 289 DCHECK(!inlineBox);
282 290
283 if (extraWidthToEndOfLine) 291 if (extraWidthToEndOfLine)
284 *extraWidthToEndOfLine = LayoutUnit(); 292 *extraWidthToEndOfLine = LayoutUnit();
285 293
286 LayoutRect caretRect = 294 LayoutRect caretRect =
287 localCaretRectForEmptyElement(borderAndPaddingWidth(), LayoutUnit()); 295 localCaretRectForEmptyElement(borderAndPaddingWidth(), LayoutUnit());
288 296
289 if (InlineBox* firstBox = firstLineBox()) { 297 if (InlineBox* firstBox = firstLineBox()) {
290 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once 298 // FIXME: the call to roundedLayoutPoint() below is temporary and should be
pdr. 2016/10/07 02:49:40 I think this comment can be removed now.
eae 2016/10/07 16:38:13 Yay!
291 // the transition to LayoutUnit-based types is complete (crbug.com/321237) 299 // removed once the transition to LayoutUnit-based types is complete
300 // (crbug.com/321237).
292 caretRect.moveBy(firstBox->topLeft()); 301 caretRect.moveBy(firstBox->topLeft());
293 } 302 }
294 303
295 return caretRect; 304 return caretRect;
296 } 305 }
297 306
298 void LayoutInline::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { 307 void LayoutInline::addChild(LayoutObject* newChild, LayoutObject* beforeChild) {
299 // Any table-part dom child of an inline element has anonymous wrappers in the layout tree 308 // Any table-part dom child of an inline element has anonymous wrappers in the
300 // so we need to climb up to the enclosing anonymous table wrapper and add the new child before that. 309 // layout tree so we need to climb up to the enclosing anonymous table wrapper
301 // TODO(rhogan): If newChild is a table part we want to insert it into the sam e table as beforeChild. 310 // and add the new child before that.
311 // TODO(rhogan): If newChild is a table part we want to insert it into the
312 // same table as beforeChild.
302 while (beforeChild && beforeChild->isTablePart()) 313 while (beforeChild && beforeChild->isTablePart())
303 beforeChild = beforeChild->parent(); 314 beforeChild = beforeChild->parent();
304 if (continuation()) 315 if (continuation())
305 return addChildToContinuation(newChild, beforeChild); 316 return addChildToContinuation(newChild, beforeChild);
306 return addChildIgnoringContinuation(newChild, beforeChild); 317 return addChildIgnoringContinuation(newChild, beforeChild);
307 } 318 }
308 319
309 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject) { 320 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject) {
310 if (layoutObject->isInline() && !layoutObject->isAtomicInlineLevel()) 321 if (layoutObject->isInline() && !layoutObject->isAtomicInlineLevel())
311 return toLayoutInline(layoutObject)->continuation(); 322 return toLayoutInline(layoutObject)->continuation();
(...skipping 20 matching lines...) Expand all
332 curr = nextContinuation(curr); 343 curr = nextContinuation(curr);
333 } 344 }
334 345
335 if (!beforeChild && !last->slowFirstChild()) 346 if (!beforeChild && !last->slowFirstChild())
336 return nextToLast; 347 return nextToLast;
337 return last; 348 return last;
338 } 349 }
339 350
340 void LayoutInline::addChildIgnoringContinuation(LayoutObject* newChild, 351 void LayoutInline::addChildIgnoringContinuation(LayoutObject* newChild,
341 LayoutObject* beforeChild) { 352 LayoutObject* beforeChild) {
342 // Make sure we don't append things after :after-generated content if we have it. 353 // Make sure we don't append things after :after-generated content if we have
354 // it.
343 if (!beforeChild && isAfterContent(lastChild())) 355 if (!beforeChild && isAfterContent(lastChild()))
344 beforeChild = lastChild(); 356 beforeChild = lastChild();
345 357
346 if (!newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned() && 358 if (!newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned() &&
347 !newChild->isTablePart()) { 359 !newChild->isTablePart()) {
348 // We are placing a block inside an inline. We have to perform a split of th is 360 // We are placing a block inside an inline. We have to perform a split of
349 // inline into continuations. This involves creating an anonymous block box to hold 361 // this inline into continuations. This involves creating an anonymous
350 // |newChild|. We then make that block box a continuation of this inline. We take all of 362 // block box to hold |newChild|. We then make that block box a continuation
351 // the children after |beforeChild| and put them in a clone of this object. 363 // of this inline. We take all of the children after |beforeChild| and put
364 // them in a clone of this object.
352 RefPtr<ComputedStyle> newStyle = 365 RefPtr<ComputedStyle> newStyle =
353 ComputedStyle::createAnonymousStyleWithDisplay( 366 ComputedStyle::createAnonymousStyleWithDisplay(
354 containingBlock()->styleRef(), EDisplay::Block); 367 containingBlock()->styleRef(), EDisplay::Block);
355 368
356 // If inside an inline affected by in-flow positioning the block needs to be affected by it too. 369 // If inside an inline affected by in-flow positioning the block needs to be
357 // Giving the block a layer like this allows it to collect the x/y offsets f rom inline parents later. 370 // affected by it too. Giving the block a layer like this allows it to
371 // collect the x/y offsets from inline parents later.
358 if (LayoutObject* positionedAncestor = inFlowPositionedInlineAncestor(this)) 372 if (LayoutObject* positionedAncestor = inFlowPositionedInlineAncestor(this))
359 newStyle->setPosition(positionedAncestor->style()->position()); 373 newStyle->setPosition(positionedAncestor->style()->position());
360 374
361 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&document()); 375 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&document());
362 newBox->setStyle(newStyle.release()); 376 newBox->setStyle(newStyle.release());
363 LayoutBoxModelObject* oldContinuation = continuation(); 377 LayoutBoxModelObject* oldContinuation = continuation();
364 setContinuation(newBox); 378 setContinuation(newBox);
365 379
366 splitFlow(beforeChild, newBox, newChild, oldContinuation); 380 splitFlow(beforeChild, newBox, newChild, oldContinuation);
367 return; 381 return;
(...skipping 25 matching lines...) Expand all
393 } 407 }
394 408
395 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock, 409 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock,
396 LayoutBlockFlow* toBlock, 410 LayoutBlockFlow* toBlock,
397 LayoutBlockFlow* middleBlock, 411 LayoutBlockFlow* middleBlock,
398 LayoutObject* beforeChild, 412 LayoutObject* beforeChild,
399 LayoutBoxModelObject* oldCont) { 413 LayoutBoxModelObject* oldCont) {
400 ASSERT(isDescendantOf(fromBlock)); 414 ASSERT(isDescendantOf(fromBlock));
401 415
402 // If we're splitting the inline containing the fullscreened element, 416 // If we're splitting the inline containing the fullscreened element,
403 // |beforeChild| may be the layoutObject for the fullscreened element. However , 417 // |beforeChild| may be the layoutObject for the fullscreened element.
404 // that layoutObject is wrapped in a LayoutFullScreen, so |this| is not its 418 // However, that layoutObject is wrapped in a LayoutFullScreen, so |this| is
405 // parent. Since the splitting logic expects |this| to be the parent, set 419 // not its parent. Since the splitting logic expects |this| to be the parent,
406 // |beforeChild| to be the LayoutFullScreen. 420 // set |beforeChild| to be the LayoutFullScreen.
407 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) { 421 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) {
408 const Element* fullScreenElement = fullscreen->currentFullScreenElement(); 422 const Element* fullScreenElement = fullscreen->currentFullScreenElement();
409 if (fullScreenElement && beforeChild && 423 if (fullScreenElement && beforeChild &&
410 beforeChild->node() == fullScreenElement) 424 beforeChild->node() == fullScreenElement)
411 beforeChild = fullscreen->fullScreenLayoutObject(); 425 beforeChild = fullscreen->fullScreenLayoutObject();
412 } 426 }
413 427
414 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone. 428 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the
415 // There will eventually be a better approach to this problem that will let us nest to a much 429 // depth at which we're willing to clone.
416 // greater depth (see bugzilla bug 13430) but for now we have a limit. This * will* result in 430 // There will eventually be a better approach to this problem that will let us
417 // incorrect rendering, but the alternative is to hang forever. 431 // nest to a much greater depth (see bugzilla bug 13430) but for now we have a
432 // limit. This *will* result in incorrect rendering, but the alternative is to
433 // hang forever.
418 const unsigned cMaxSplitDepth = 200; 434 const unsigned cMaxSplitDepth = 200;
419 Vector<LayoutInline*> inlinesToClone; 435 Vector<LayoutInline*> inlinesToClone;
420 LayoutInline* topMostInline = this; 436 LayoutInline* topMostInline = this;
421 for (LayoutObject* o = this; o != fromBlock; o = o->parent()) { 437 for (LayoutObject* o = this; o != fromBlock; o = o->parent()) {
422 topMostInline = toLayoutInline(o); 438 topMostInline = toLayoutInline(o);
423 if (inlinesToClone.size() < cMaxSplitDepth) 439 if (inlinesToClone.size() < cMaxSplitDepth)
424 inlinesToClone.append(topMostInline); 440 inlinesToClone.append(topMostInline);
425 // Keep walking up the chain to ensure |topMostInline| is a child of |fromBl ock|, 441 // Keep walking up the chain to ensure |topMostInline| is a child of
426 // to avoid assertion failure when |fromBlock|'s children are moved to |toBl ock| below. 442 // |fromBlock|, to avoid assertion failure when |fromBlock|'s children are
443 // moved to |toBlock| below.
427 } 444 }
428 445
429 // Create a new clone of the top-most inline in |inlinesToClone|. 446 // Create a new clone of the top-most inline in |inlinesToClone|.
430 LayoutInline* topMostInlineToClone = inlinesToClone.last(); 447 LayoutInline* topMostInlineToClone = inlinesToClone.last();
431 LayoutInline* cloneInline = topMostInlineToClone->clone(); 448 LayoutInline* cloneInline = topMostInlineToClone->clone();
432 449
433 // Now we are at the block level. We need to put the clone into the |toBlock|. 450 // Now we are at the block level. We need to put the clone into the |toBlock|.
434 toBlock->children()->appendChildNode(toBlock, cloneInline); 451 toBlock->children()->appendChildNode(toBlock, cloneInline);
435 452
436 // Now take all the children after |topMostInline| and remove them from the |f romBlock| 453 // Now take all the children after |topMostInline| and remove them from the
437 // and put them into the toBlock. 454 // |fromBlock| and put them into the toBlock.
438 fromBlock->moveChildrenTo(toBlock, topMostInline->nextSibling(), nullptr, 455 fromBlock->moveChildrenTo(toBlock, topMostInline->nextSibling(), nullptr,
439 true); 456 true);
440 457
441 LayoutInline* currentParent = topMostInlineToClone; 458 LayoutInline* currentParent = topMostInlineToClone;
442 LayoutInline* cloneInlineParent = cloneInline; 459 LayoutInline* cloneInlineParent = cloneInline;
443 460
444 // Clone the inlines from top to down to ensure any new object will be added i nto a rooted tree. 461 // Clone the inlines from top to down to ensure any new object will be added
445 // Note that we have already cloned the top-most one, so the loop begins from size - 2 (except if 462 // into a rooted tree.
446 // we have reached |cMaxDepth| in which case we sacrifice correct rendering fo r performance). 463 // Note that we have already cloned the top-most one, so the loop begins from
464 // size - 2 (except if we have reached |cMaxDepth| in which case we sacrifice
465 // correct rendering for performance).
447 for (int i = static_cast<int>(inlinesToClone.size()) - 2; i >= 0; --i) { 466 for (int i = static_cast<int>(inlinesToClone.size()) - 2; i >= 0; --i) {
448 // Hook the clone up as a continuation of |currentInline|. 467 // Hook the clone up as a continuation of |currentInline|.
449 LayoutBoxModelObject* oldCont = currentParent->continuation(); 468 LayoutBoxModelObject* oldCont = currentParent->continuation();
450 currentParent->setContinuation(cloneInline); 469 currentParent->setContinuation(cloneInline);
451 cloneInline->setContinuation(oldCont); 470 cloneInline->setContinuation(oldCont);
452 471
453 // Create a new clone. 472 // Create a new clone.
454 LayoutInline* current = inlinesToClone[i]; 473 LayoutInline* current = inlinesToClone[i];
455 cloneInline = current->clone(); 474 cloneInline = current->clone();
456 475
457 // Insert our |cloneInline| as the first child of |cloneInlineParent|. 476 // Insert our |cloneInline| as the first child of |cloneInlineParent|.
458 cloneInlineParent->addChildIgnoringContinuation(cloneInline, nullptr); 477 cloneInlineParent->addChildIgnoringContinuation(cloneInline, nullptr);
459 478
460 // Now we need to take all of the children starting from the first child 479 // Now we need to take all of the children starting from the first child
461 // *after* |current| and append them all to the |cloneInlineParent|. 480 // *after* |current| and append them all to the |cloneInlineParent|.
462 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent, 481 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent,
463 current->nextSibling()); 482 current->nextSibling());
464 483
465 currentParent = current; 484 currentParent = current;
466 cloneInlineParent = cloneInline; 485 cloneInlineParent = cloneInline;
467 } 486 }
468 487
469 // The last inline to clone is |this|, and the current |cloneInline| is cloned from |this|. 488 // The last inline to clone is |this|, and the current |cloneInline| is cloned
489 // from |this|.
470 ASSERT(this == inlinesToClone.first()); 490 ASSERT(this == inlinesToClone.first());
471 491
472 // Hook |cloneInline| up as the continuation of the middle block. 492 // Hook |cloneInline| up as the continuation of the middle block.
473 cloneInline->setContinuation(oldCont); 493 cloneInline->setContinuation(oldCont);
474 middleBlock->setContinuation(cloneInline); 494 middleBlock->setContinuation(cloneInline);
475 495
476 // Now take all of the children from |beforeChild| to the end and remove 496 // Now take all of the children from |beforeChild| to the end and remove
477 // them from |this| and place them in the clone. 497 // them from |this| and place them in the clone.
478 moveChildrenToIgnoringContinuation(cloneInline, beforeChild); 498 moveChildrenToIgnoringContinuation(cloneInline, beforeChild);
479 } 499 }
480 500
481 void LayoutInline::splitFlow(LayoutObject* beforeChild, 501 void LayoutInline::splitFlow(LayoutObject* beforeChild,
482 LayoutBlockFlow* newBlockBox, 502 LayoutBlockFlow* newBlockBox,
483 LayoutObject* newChild, 503 LayoutObject* newChild,
484 LayoutBoxModelObject* oldCont) { 504 LayoutBoxModelObject* oldCont) {
485 LayoutBlockFlow* block = toLayoutBlockFlow(containingBlock()); 505 LayoutBlockFlow* block = toLayoutBlockFlow(containingBlock());
486 LayoutBlockFlow* pre = nullptr; 506 LayoutBlockFlow* pre = nullptr;
487 507
488 // Delete our line boxes before we do the inline split into continuations. 508 // Delete our line boxes before we do the inline split into continuations.
489 block->deleteLineBoxTree(); 509 block->deleteLineBoxTree();
490 510
491 bool reusedAnonymousBlock = false; 511 bool reusedAnonymousBlock = false;
492 if (block->isAnonymousBlock()) { 512 if (block->isAnonymousBlock()) {
493 LayoutBlock* outerContainingBlock = block->containingBlock(); 513 LayoutBlock* outerContainingBlock = block->containingBlock();
494 if (outerContainingBlock && outerContainingBlock->isLayoutBlockFlow() && 514 if (outerContainingBlock && outerContainingBlock->isLayoutBlockFlow() &&
495 !outerContainingBlock->createsAnonymousWrapper()) { 515 !outerContainingBlock->createsAnonymousWrapper()) {
496 // We can reuse this block and make it the preBlock of the next continuati on. 516 // We can reuse this block and make it the preBlock of the next
517 // continuation.
497 block->removePositionedObjects(nullptr); 518 block->removePositionedObjects(nullptr);
498 block->removeFloatingObjects(); 519 block->removeFloatingObjects();
499 pre = block; 520 pre = block;
500 block = toLayoutBlockFlow(outerContainingBlock); 521 block = toLayoutBlockFlow(outerContainingBlock);
501 reusedAnonymousBlock = true; 522 reusedAnonymousBlock = true;
502 } 523 }
503 } 524 }
525
526 // No anonymous block available for use. Make one.
504 if (!reusedAnonymousBlock) 527 if (!reusedAnonymousBlock)
505 pre = toLayoutBlockFlow( 528 pre = toLayoutBlockFlow(block->createAnonymousBlock());
506 block
507 ->createAnonymousBlock()); // No anonymous block available for use. Make one.
508 529
509 LayoutBlockFlow* post = toLayoutBlockFlow(pre->createAnonymousBlock()); 530 LayoutBlockFlow* post = toLayoutBlockFlow(pre->createAnonymousBlock());
510 531
511 LayoutObject* boxFirst = 532 LayoutObject* boxFirst =
512 !reusedAnonymousBlock ? block->firstChild() : pre->nextSibling(); 533 !reusedAnonymousBlock ? block->firstChild() : pre->nextSibling();
513 if (!reusedAnonymousBlock) 534 if (!reusedAnonymousBlock)
514 block->children()->insertChildNode(block, pre, boxFirst); 535 block->children()->insertChildNode(block, pre, boxFirst);
515 block->children()->insertChildNode(block, newBlockBox, boxFirst); 536 block->children()->insertChildNode(block, newBlockBox, boxFirst);
516 block->children()->insertChildNode(block, post, boxFirst); 537 block->children()->insertChildNode(block, post, boxFirst);
517 block->setChildrenInline(false); 538 block->setChildrenInline(false);
518 539
519 if (!reusedAnonymousBlock) { 540 if (!reusedAnonymousBlock) {
520 LayoutObject* o = boxFirst; 541 LayoutObject* o = boxFirst;
521 while (o) { 542 while (o) {
522 LayoutObject* no = o; 543 LayoutObject* no = o;
523 o = no->nextSibling(); 544 o = no->nextSibling();
524 pre->children()->appendChildNode( 545 pre->children()->appendChildNode(
525 pre, block->children()->removeChildNode(block, no)); 546 pre, block->children()->removeChildNode(block, no));
526 no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 547 no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
527 LayoutInvalidationReason::AnonymousBlockChange); 548 LayoutInvalidationReason::AnonymousBlockChange);
528 } 549 }
529 } 550 }
530 551
531 splitInlines(pre, post, newBlockBox, beforeChild, oldCont); 552 splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
532 553
533 // We already know the newBlockBox isn't going to contain inline kids, so avoi d wasting 554 // We already know the newBlockBox isn't going to contain inline kids, so
534 // time in makeChildrenNonInline by just setting this explicitly up front. 555 // avoid wasting time in makeChildrenNonInline by just setting this explicitly
556 // up front.
535 newBlockBox->setChildrenInline(false); 557 newBlockBox->setChildrenInline(false);
536 558
537 newBlockBox->addChild(newChild); 559 newBlockBox->addChild(newChild);
538 560
539 // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) 561 // Always just do a full layout in order to ensure that line boxes (especially
540 // get deleted properly. Because objects moves from the pre block into the po st block, we want to 562 // wrappers for images) get deleted properly. Because objects moves from the
541 // make new line boxes instead of leaving the old line boxes around. 563 // pre block into the post block, we want to make new line boxes instead of
564 // leaving the old line boxes around.
542 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 565 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
543 LayoutInvalidationReason::AnonymousBlockChange); 566 LayoutInvalidationReason::AnonymousBlockChange);
544 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 567 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
545 LayoutInvalidationReason::AnonymousBlockChange); 568 LayoutInvalidationReason::AnonymousBlockChange);
546 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 569 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
547 LayoutInvalidationReason::AnonymousBlockChange); 570 LayoutInvalidationReason::AnonymousBlockChange);
548 } 571 }
549 572
550 void LayoutInline::addChildToContinuation(LayoutObject* newChild, 573 void LayoutInline::addChildToContinuation(LayoutObject* newChild,
551 LayoutObject* beforeChild) { 574 LayoutObject* beforeChild) {
552 // A continuation always consists of two potential candidates: an inline or an anonymous 575 // A continuation always consists of two potential candidates: an inline or an
553 // block box holding block children. 576 // anonymous block box holding block children.
554 LayoutBoxModelObject* flow = continuationBefore(beforeChild); 577 LayoutBoxModelObject* flow = continuationBefore(beforeChild);
555 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousBlock() || 578 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousBlock() ||
556 beforeChild->parent()->isLayoutInline()); 579 beforeChild->parent()->isLayoutInline());
557 LayoutBoxModelObject* beforeChildParent = nullptr; 580 LayoutBoxModelObject* beforeChildParent = nullptr;
558 if (beforeChild) { 581 if (beforeChild) {
559 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent()); 582 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent());
560 } else { 583 } else {
561 LayoutBoxModelObject* cont = nextContinuation(flow); 584 LayoutBoxModelObject* cont = nextContinuation(flow);
562 if (cont) 585 if (cont)
563 beforeChildParent = cont; 586 beforeChildParent = cont;
564 else 587 else
565 beforeChildParent = flow; 588 beforeChildParent = flow;
566 } 589 }
567 590
568 // TODO(rhogan): Should we treat out-of-flows and floats as through they're in line below? 591 // TODO(rhogan): Should we treat out-of-flows and floats as through they're
592 // inline below?
569 if (newChild->isFloatingOrOutOfFlowPositioned()) 593 if (newChild->isFloatingOrOutOfFlowPositioned())
570 return beforeChildParent->addChildIgnoringContinuation(newChild, 594 return beforeChildParent->addChildIgnoringContinuation(newChild,
571 beforeChild); 595 beforeChild);
572 596
573 // A table part will be wrapped by an inline anonymous table when it is added to the layout 597 // A table part will be wrapped by an inline anonymous table when it is added
574 // tree, so treat it as inline when deciding where to add it. 598 // to the layout tree, so treat it as inline when deciding where to add it.
575 bool childInline = newChild->isInline() || newChild->isTablePart(); 599 bool childInline = newChild->isInline() || newChild->isTablePart();
576 bool bcpInline = beforeChildParent->isInline(); 600 bool bcpInline = beforeChildParent->isInline();
577 bool flowInline = flow->isInline(); 601 bool flowInline = flow->isInline();
578 602
579 if (flow == beforeChildParent) 603 if (flow == beforeChildParent)
580 return flow->addChildIgnoringContinuation(newChild, beforeChild); 604 return flow->addChildIgnoringContinuation(newChild, beforeChild);
581 605
582 // The goal here is to match up if we can, so that we can coalesce and create the 606 // The goal here is to match up if we can, so that we can coalesce and create
583 // minimal # of continuations needed for the inline. 607 // the minimal # of continuations needed for the inline.
584 if (childInline == bcpInline || (beforeChild && beforeChild->isInline())) 608 if (childInline == bcpInline || (beforeChild && beforeChild->isInline()))
585 return beforeChildParent->addChildIgnoringContinuation(newChild, 609 return beforeChildParent->addChildIgnoringContinuation(newChild,
586 beforeChild); 610 beforeChild);
587 if (flowInline == childInline) 611 if (flowInline == childInline) {
588 return flow->addChildIgnoringContinuation(newChild, 612 // Just treat like an append.
589 0); // Just treat like an append. 613 return flow->addChildIgnoringContinuation(newChild, 0);
614 }
590 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 615 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
591 } 616 }
592 617
593 void LayoutInline::paint(const PaintInfo& paintInfo, 618 void LayoutInline::paint(const PaintInfo& paintInfo,
594 const LayoutPoint& paintOffset) const { 619 const LayoutPoint& paintOffset) const {
595 InlinePainter(*this).paint(paintInfo, paintOffset); 620 InlinePainter(*this).paint(paintInfo, paintOffset);
596 } 621 }
597 622
598 template <typename GeneratorContext> 623 template <typename GeneratorContext>
599 void LayoutInline::generateLineBoxRects(GeneratorContext& yield) const { 624 void LayoutInline::generateLineBoxRects(GeneratorContext& yield) const {
(...skipping 11 matching lines...) Expand all
611 const LayoutInline* container) const { 636 const LayoutInline* container) const {
612 if (!culledInlineFirstLineBox()) 637 if (!culledInlineFirstLineBox())
613 return; 638 return;
614 639
615 bool isHorizontal = style()->isHorizontalWritingMode(); 640 bool isHorizontal = style()->isHorizontalWritingMode();
616 641
617 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 642 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
618 if (curr->isFloatingOrOutOfFlowPositioned()) 643 if (curr->isFloatingOrOutOfFlowPositioned())
619 continue; 644 continue;
620 645
621 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 646 // We want to get the margin box in the inline direction, and then use our
622 // direction (aligned to the root box's baseline). 647 // font ascent/descent in the block direction (aligned to the root box's
648 // baseline).
623 if (curr->isBox()) { 649 if (curr->isBox()) {
624 LayoutBox* currBox = toLayoutBox(curr); 650 LayoutBox* currBox = toLayoutBox(curr);
625 if (currBox->inlineBoxWrapper()) { 651 if (currBox->inlineBoxWrapper()) {
626 RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root(); 652 RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
627 LayoutUnit logicalTop = 653 LayoutUnit logicalTop =
628 rootBox.logicalTop() + (rootBox.getLineLayoutItem() 654 rootBox.logicalTop() + (rootBox.getLineLayoutItem()
629 .style(rootBox.isFirstLineStyle()) 655 .style(rootBox.isFirstLineStyle())
630 ->font() 656 ->font()
631 .getFontMetrics() 657 .getFontMetrics()
632 .ascent() - 658 .ascent() -
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 // If there are continuations, test them first because our containing block 966 // If there are continuations, test them first because our containing block
941 // will not check them. 967 // will not check them.
942 LayoutBoxModelObject* continuation = this->continuation(); 968 LayoutBoxModelObject* continuation = this->continuation();
943 while (continuation) { 969 while (continuation) {
944 if (continuation->isInline() || continuation->slowFirstChild()) 970 if (continuation->isInline() || continuation->slowFirstChild())
945 return continuation->positionForPoint(point); 971 return continuation->positionForPoint(point);
946 continuation = toLayoutBlockFlow(continuation)->inlineElementContinuation(); 972 continuation = toLayoutBlockFlow(continuation)->inlineElementContinuation();
947 } 973 }
948 974
949 if (firstLineBoxIncludingCulling()) { 975 if (firstLineBoxIncludingCulling()) {
950 // This inline actually has a line box. We must have clicked in the border/ padding of one of these boxes. We 976 // This inline actually has a line box. We must have clicked in the
977 // border/padding of one of these boxes. We
951 // should try to find a result by asking our containing block. 978 // should try to find a result by asking our containing block.
952 return containingBlock()->positionForPoint(point); 979 return containingBlock()->positionForPoint(point);
953 } 980 }
954 981
955 return LayoutBoxModelObject::positionForPoint(point); 982 return LayoutBoxModelObject::positionForPoint(point);
956 } 983 }
957 984
958 namespace { 985 namespace {
959 986
960 class LinesBoundingBoxGeneratorContext { 987 class LinesBoundingBoxGeneratorContext {
(...skipping 12 matching lines...) Expand all
973 if (!alwaysCreateLineBoxes()) { 1000 if (!alwaysCreateLineBoxes()) {
974 ASSERT(!firstLineBox()); 1001 ASSERT(!firstLineBox());
975 FloatRect floatResult; 1002 FloatRect floatResult;
976 LinesBoundingBoxGeneratorContext context(floatResult); 1003 LinesBoundingBoxGeneratorContext context(floatResult);
977 generateCulledLineBoxRects(context, this); 1004 generateCulledLineBoxRects(context, this);
978 return enclosingLayoutRect(floatResult); 1005 return enclosingLayoutRect(floatResult);
979 } 1006 }
980 1007
981 LayoutRect result; 1008 LayoutRect result;
982 1009
983 // See <rdar://problem/5289721>, for an unknown reason the linked list here is sometimes inconsistent, first is non-zero and last is zero. We have been 1010 // See <rdar://problem/5289721>, for an unknown reason the linked list here is
984 // unable to reproduce this at all (and consequently unable to figure ot why t his is happening). The assert will hopefully catch the problem in debug 1011 // sometimes inconsistent, first is non-zero and last is zero. We have been
985 // builds and help us someday figure out why. We also put in a redundant chec k of lastLineBox() to avoid the crash for now. 1012 // unable to reproduce this at all (and consequently unable to figure ot why
1013 // this is happening). The assert will hopefully catch the problem in debug
1014 // builds and help us someday figure out why. We also put in a redundant
1015 // check of lastLineBox() to avoid the crash for now.
986 ASSERT(!firstLineBox() == 1016 ASSERT(!firstLineBox() ==
987 !lastLineBox()); // Either both are null or both exist. 1017 !lastLineBox()); // Either both are null or both exist.
988 if (firstLineBox() && lastLineBox()) { 1018 if (firstLineBox() && lastLineBox()) {
989 // Return the width of the minimal left side and the maximal right side. 1019 // Return the width of the minimal left side and the maximal right side.
990 LayoutUnit logicalLeftSide; 1020 LayoutUnit logicalLeftSide;
991 LayoutUnit logicalRightSide; 1021 LayoutUnit logicalRightSide;
992 for (InlineFlowBox* curr = firstLineBox(); curr; 1022 for (InlineFlowBox* curr = firstLineBox(); curr;
993 curr = curr->nextLineBox()) { 1023 curr = curr->nextLineBox()) {
994 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide) 1024 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
995 logicalLeftSide = curr->logicalLeft(); 1025 logicalLeftSide = curr->logicalLeft();
(...skipping 13 matching lines...) Expand all
1009 } 1039 }
1010 1040
1011 return result; 1041 return result;
1012 } 1042 }
1013 1043
1014 InlineBox* LayoutInline::culledInlineFirstLineBox() const { 1044 InlineBox* LayoutInline::culledInlineFirstLineBox() const {
1015 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 1045 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
1016 if (curr->isFloatingOrOutOfFlowPositioned()) 1046 if (curr->isFloatingOrOutOfFlowPositioned())
1017 continue; 1047 continue;
1018 1048
1019 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 1049 // We want to get the margin box in the inline direction, and then use our
1020 // direction (aligned to the root box's baseline). 1050 // font ascent/descent in the block direction (aligned to the root box's
1051 // baseline).
1021 if (curr->isBox()) 1052 if (curr->isBox())
1022 return toLayoutBox(curr)->inlineBoxWrapper(); 1053 return toLayoutBox(curr)->inlineBoxWrapper();
1023 if (curr->isLayoutInline()) { 1054 if (curr->isLayoutInline()) {
1024 LayoutInline* currInline = toLayoutInline(curr); 1055 LayoutInline* currInline = toLayoutInline(curr);
1025 InlineBox* result = currInline->firstLineBoxIncludingCulling(); 1056 InlineBox* result = currInline->firstLineBoxIncludingCulling();
1026 if (result) 1057 if (result)
1027 return result; 1058 return result;
1028 } else if (curr->isText()) { 1059 } else if (curr->isText()) {
1029 LayoutText* currText = toLayoutText(curr); 1060 LayoutText* currText = toLayoutText(curr);
1030 if (currText->firstTextBox()) 1061 if (currText->firstTextBox())
1031 return currText->firstTextBox(); 1062 return currText->firstTextBox();
1032 } 1063 }
1033 } 1064 }
1034 return nullptr; 1065 return nullptr;
1035 } 1066 }
1036 1067
1037 InlineBox* LayoutInline::culledInlineLastLineBox() const { 1068 InlineBox* LayoutInline::culledInlineLastLineBox() const {
1038 for (LayoutObject* curr = lastChild(); curr; curr = curr->previousSibling()) { 1069 for (LayoutObject* curr = lastChild(); curr; curr = curr->previousSibling()) {
1039 if (curr->isFloatingOrOutOfFlowPositioned()) 1070 if (curr->isFloatingOrOutOfFlowPositioned())
1040 continue; 1071 continue;
1041 1072
1042 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 1073 // We want to get the margin box in the inline direction, and then use our
1043 // direction (aligned to the root box's baseline). 1074 // font ascent/descent in the block direction (aligned to the root box's
1075 // baseline).
1044 if (curr->isBox()) 1076 if (curr->isBox())
1045 return toLayoutBox(curr)->inlineBoxWrapper(); 1077 return toLayoutBox(curr)->inlineBoxWrapper();
1046 if (curr->isLayoutInline()) { 1078 if (curr->isLayoutInline()) {
1047 LayoutInline* currInline = toLayoutInline(curr); 1079 LayoutInline* currInline = toLayoutInline(curr);
1048 InlineBox* result = currInline->lastLineBoxIncludingCulling(); 1080 InlineBox* result = currInline->lastLineBoxIncludingCulling();
1049 if (result) 1081 if (result)
1050 return result; 1082 return result;
1051 } else if (curr->isText()) { 1083 } else if (curr->isText()) {
1052 LayoutText* currText = toLayoutText(curr); 1084 LayoutText* currText = toLayoutText(curr);
1053 if (currText->lastTextBox()) 1085 if (currText->lastTextBox())
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 1204
1173 return visualOverflowRect(); 1205 return visualOverflowRect();
1174 } 1206 }
1175 1207
1176 LayoutRect LayoutInline::visualOverflowRect() const { 1208 LayoutRect LayoutInline::visualOverflowRect() const {
1177 LayoutRect overflowRect = linesVisualOverflowBoundingBox(); 1209 LayoutRect overflowRect = linesVisualOverflowBoundingBox();
1178 LayoutUnit outlineOutset(style()->outlineOutsetExtent()); 1210 LayoutUnit outlineOutset(style()->outlineOutsetExtent());
1179 if (outlineOutset) { 1211 if (outlineOutset) {
1180 Vector<LayoutRect> rects; 1212 Vector<LayoutRect> rects;
1181 if (document().inNoQuirksMode()) { 1213 if (document().inNoQuirksMode()) {
1182 // We have already included outline extents of line boxes in linesVisualOv erflowBoundingBox(), 1214 // We have already included outline extents of line boxes in
1183 // so the following just add outline rects for children and continuations. 1215 // linesVisualOverflowBoundingBox(), so the following just add outline
1216 // rects for children and continuations.
1184 addOutlineRectsForChildrenAndContinuations( 1217 addOutlineRectsForChildrenAndContinuations(
1185 rects, LayoutPoint(), outlineRectsShouldIncludeBlockVisualOverflow()); 1218 rects, LayoutPoint(), outlineRectsShouldIncludeBlockVisualOverflow());
1186 } else { 1219 } else {
1187 // In non-standard mode, because the difference in LayoutBlock::minLineHei ghtForReplacedObject(), 1220 // In non-standard mode, because the difference in
1188 // linesVisualOverflowBoundingBox() may not cover outline rects of lines c ontaining replaced objects. 1221 // LayoutBlock::minLineHeightForReplacedObject(),
1222 // linesVisualOverflowBoundingBox() may not cover outline rects of lines
1223 // containing replaced objects.
1189 addOutlineRects(rects, LayoutPoint(), 1224 addOutlineRects(rects, LayoutPoint(),
1190 outlineRectsShouldIncludeBlockVisualOverflow()); 1225 outlineRectsShouldIncludeBlockVisualOverflow());
1191 } 1226 }
1192 if (!rects.isEmpty()) { 1227 if (!rects.isEmpty()) {
1193 LayoutRect outlineRect = unionRectEvenIfEmpty(rects); 1228 LayoutRect outlineRect = unionRectEvenIfEmpty(rects);
1194 outlineRect.inflate(outlineOutset); 1229 outlineRect.inflate(outlineOutset);
1195 overflowRect.unite(outlineRect); 1230 overflowRect.unite(outlineRect);
1196 } 1231 }
1197 } 1232 }
1198 return overflowRect; 1233 return overflowRect;
1199 } 1234 }
1200 1235
1201 bool LayoutInline::mapToVisualRectInAncestorSpace( 1236 bool LayoutInline::mapToVisualRectInAncestorSpace(
1202 const LayoutBoxModelObject* ancestor, 1237 const LayoutBoxModelObject* ancestor,
1203 LayoutRect& rect, 1238 LayoutRect& rect,
1204 VisualRectFlags visualRectFlags) const { 1239 VisualRectFlags visualRectFlags) const {
1205 if (ancestor == this) 1240 if (ancestor == this)
1206 return true; 1241 return true;
1207 1242
1208 LayoutObject* container = this->container(); 1243 LayoutObject* container = this->container();
1209 ASSERT(container == parent()); 1244 ASSERT(container == parent());
1210 if (!container) 1245 if (!container)
1211 return true; 1246 return true;
1212 1247
1213 if (style()->hasInFlowPosition() && layer()) { 1248 if (style()->hasInFlowPosition() && layer()) {
1214 // Apply the in-flow position offset when invalidating a rectangle. The laye r 1249 // Apply the in-flow position offset when invalidating a rectangle. The
1215 // is translated, but the layout box isn't, so we need to do this to get the 1250 // layer is translated, but the layout box isn't, so we need to do this to
1216 // right dirty rect. Since this is called from LayoutObject::setStyle, the r elative position 1251 // get the right dirty rect. Since this is called from LayoutObject::
1217 // flag on the LayoutObject has been cleared, so use the one on the style(). 1252 // setStyle, the relative position flag on the LayoutObject has been
1253 // cleared, so use the one on the style().
1218 rect.move(layer()->offsetForInFlowPosition()); 1254 rect.move(layer()->offsetForInFlowPosition());
1219 } 1255 }
1220 1256
1221 LayoutBox* containerBox = 1257 LayoutBox* containerBox =
1222 container->isBox() ? toLayoutBox(container) : nullptr; 1258 container->isBox() ? toLayoutBox(container) : nullptr;
1223 if (containerBox && 1259 if (containerBox &&
1224 !containerBox->mapScrollingContentsRectToBoxSpace( 1260 !containerBox->mapScrollingContentsRectToBoxSpace(
1225 rect, container == ancestor ? ApplyNonScrollOverflowClip 1261 rect, container == ancestor ? ApplyNonScrollOverflowClip
1226 : ApplyOverflowClip, 1262 : ApplyOverflowClip,
1227 visualRectFlags)) 1263 visualRectFlags))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 1305
1270 void LayoutInline::updateHitTestResult(HitTestResult& result, 1306 void LayoutInline::updateHitTestResult(HitTestResult& result,
1271 const LayoutPoint& point) { 1307 const LayoutPoint& point) {
1272 if (result.innerNode()) 1308 if (result.innerNode())
1273 return; 1309 return;
1274 1310
1275 Node* n = node(); 1311 Node* n = node();
1276 LayoutPoint localPoint(point); 1312 LayoutPoint localPoint(point);
1277 if (n) { 1313 if (n) {
1278 if (isInlineElementContinuation()) { 1314 if (isInlineElementContinuation()) {
1279 // We're in the continuation of a split inline. Adjust our local point to be in the coordinate space 1315 // We're in the continuation of a split inline. Adjust our local point to
1280 // of the principal layoutObject's containing block. This will end up bei ng the innerNode. 1316 // be in the coordinate space of the principal layoutObject's containing
1317 // block. This will end up being the innerNode.
1281 LayoutBlock* firstBlock = n->layoutObject()->containingBlock(); 1318 LayoutBlock* firstBlock = n->layoutObject()->containingBlock();
1282 1319
1283 // Get our containing block. 1320 // Get our containing block.
1284 LayoutBox* block = containingBlock(); 1321 LayoutBox* block = containingBlock();
1285 localPoint.moveBy(block->location() - firstBlock->locationOffset()); 1322 localPoint.moveBy(block->location() - firstBlock->locationOffset());
1286 } 1323 }
1287 1324
1288 result.setNodeAndPosition(n, localPoint); 1325 result.setNodeAndPosition(n, localPoint);
1289 } 1326 }
1290 } 1327 }
1291 1328
1292 void LayoutInline::dirtyLineBoxes(bool fullLayout) { 1329 void LayoutInline::dirtyLineBoxes(bool fullLayout) {
1293 if (fullLayout) { 1330 if (fullLayout) {
1294 m_lineBoxes.deleteLineBoxes(); 1331 m_lineBoxes.deleteLineBoxes();
1295 return; 1332 return;
1296 } 1333 }
1297 1334
1298 if (!alwaysCreateLineBoxes()) { 1335 if (!alwaysCreateLineBoxes()) {
1299 // We have to grovel into our children in order to dirty the appropriate lin es. 1336 // We have to grovel into our children in order to dirty the appropriate
1337 // lines.
1300 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 1338 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
1301 if (curr->isFloatingOrOutOfFlowPositioned()) 1339 if (curr->isFloatingOrOutOfFlowPositioned())
1302 continue; 1340 continue;
1303 if (curr->isBox() && !curr->needsLayout()) { 1341 if (curr->isBox() && !curr->needsLayout()) {
1304 LayoutBox* currBox = toLayoutBox(curr); 1342 LayoutBox* currBox = toLayoutBox(curr);
1305 if (currBox->inlineBoxWrapper()) 1343 if (currBox->inlineBoxWrapper())
1306 currBox->inlineBoxWrapper()->root().markDirty(); 1344 currBox->inlineBoxWrapper()->root().markDirty();
1307 } else if (!curr->selfNeedsLayout()) { 1345 } else if (!curr->selfNeedsLayout()) {
1308 if (curr->isLayoutInline()) { 1346 if (curr->isLayoutInline()) {
1309 LayoutInline* currInline = toLayoutInline(curr); 1347 LayoutInline* currInline = toLayoutInline(curr);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 } 1399 }
1362 1400
1363 LayoutSize LayoutInline::offsetForInFlowPositionedInline( 1401 LayoutSize LayoutInline::offsetForInFlowPositionedInline(
1364 const LayoutBox& child) const { 1402 const LayoutBox& child) const {
1365 // FIXME: This function isn't right with mixed writing modes. 1403 // FIXME: This function isn't right with mixed writing modes.
1366 1404
1367 ASSERT(isInFlowPositioned()); 1405 ASSERT(isInFlowPositioned());
1368 if (!isInFlowPositioned()) 1406 if (!isInFlowPositioned())
1369 return LayoutSize(); 1407 return LayoutSize();
1370 1408
1371 // When we have an enclosing relpositioned inline, we need to add in the offse t of the first line 1409 // When we have an enclosing relpositioned inline, we need to add in the
1372 // box from the rest of the content, but only in the cases where we know we're positioned 1410 // offset of the first line box from the rest of the content, but only in the
1373 // relative to the inline itself. 1411 // cases where we know we're positioned relative to the inline itself.
1374 1412
1375 LayoutSize logicalOffset; 1413 LayoutSize logicalOffset;
1376 LayoutUnit inlinePosition; 1414 LayoutUnit inlinePosition;
1377 LayoutUnit blockPosition; 1415 LayoutUnit blockPosition;
1378 if (firstLineBox()) { 1416 if (firstLineBox()) {
1379 inlinePosition = firstLineBox()->logicalLeft(); 1417 inlinePosition = firstLineBox()->logicalLeft();
1380 blockPosition = firstLineBox()->logicalTop(); 1418 blockPosition = firstLineBox()->logicalTop();
1381 } else { 1419 } else {
1382 inlinePosition = layer()->staticInlinePosition(); 1420 inlinePosition = layer()->staticInlinePosition();
1383 blockPosition = layer()->staticBlockPosition(); 1421 blockPosition = layer()->staticBlockPosition();
1384 } 1422 }
1385 1423
1386 // Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an absolu te positioned box 1424 // Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an
1387 // with a static position should locate itself as though it is a normal flow b ox in relation to 1425 // absolute positioned box with a static position should locate itself as
1388 // its containing block. If this relative-positioned inline has a negative off set we need to 1426 // though it is a normal flow box in relation to its containing block. If this
1389 // compensate for it so that we align the positioned object with the edge of i ts containing block. 1427 // relative-positioned inline has a negative offset we need to compensate for
1428 // it so that we align the positioned object with the edge of its containing
1429 // block.
1390 if (child.style()->hasStaticInlinePosition( 1430 if (child.style()->hasStaticInlinePosition(
1391 style()->isHorizontalWritingMode())) 1431 style()->isHorizontalWritingMode()))
1392 logicalOffset.setWidth( 1432 logicalOffset.setWidth(
1393 std::max(LayoutUnit(), -offsetForInFlowPosition().width())); 1433 std::max(LayoutUnit(), -offsetForInFlowPosition().width()));
1394 else 1434 else
1395 logicalOffset.setWidth(inlinePosition); 1435 logicalOffset.setWidth(inlinePosition);
1396 1436
1397 if (!child.style()->hasStaticBlockPosition( 1437 if (!child.style()->hasStaticBlockPosition(
1398 style()->isHorizontalWritingMode())) 1438 style()->isHorizontalWritingMode()))
1399 logicalOffset.setHeight(blockPosition); 1439 logicalOffset.setHeight(blockPosition);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason); 1556 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason);
1517 } 1557 }
1518 1558
1519 // TODO(lunalu): Not to just dump 0, 0 as the x and y here 1559 // TODO(lunalu): Not to just dump 0, 0 as the x and y here
1520 LayoutRect LayoutInline::debugRect() const { 1560 LayoutRect LayoutInline::debugRect() const {
1521 IntRect linesBox = enclosingIntRect(linesBoundingBox()); 1561 IntRect linesBox = enclosingIntRect(linesBoundingBox());
1522 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height())); 1562 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height()));
1523 } 1563 }
1524 1564
1525 } // namespace blink 1565 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698