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

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: Rebase w/HEAD 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
291 // the transition to LayoutUnit-based types is complete (crbug.com/321237)
292 caretRect.moveBy(firstBox->topLeft()); 298 caretRect.moveBy(firstBox->topLeft());
293 }
294 299
295 return caretRect; 300 return caretRect;
296 } 301 }
297 302
298 void LayoutInline::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { 303 void LayoutInline::addChild(LayoutObject* newChild, LayoutObject* beforeChild) {
299 // Any table-part dom child of an inline element has anonymous wrappers in the layout tree 304 // 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. 305 // 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. 306 // and add the new child before that.
307 // TODO(rhogan): If newChild is a table part we want to insert it into the
308 // same table as beforeChild.
302 while (beforeChild && beforeChild->isTablePart()) 309 while (beforeChild && beforeChild->isTablePart())
303 beforeChild = beforeChild->parent(); 310 beforeChild = beforeChild->parent();
304 if (continuation()) 311 if (continuation())
305 return addChildToContinuation(newChild, beforeChild); 312 return addChildToContinuation(newChild, beforeChild);
306 return addChildIgnoringContinuation(newChild, beforeChild); 313 return addChildIgnoringContinuation(newChild, beforeChild);
307 } 314 }
308 315
309 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject) { 316 static LayoutBoxModelObject* nextContinuation(LayoutObject* layoutObject) {
310 if (layoutObject->isInline() && !layoutObject->isAtomicInlineLevel()) 317 if (layoutObject->isInline() && !layoutObject->isAtomicInlineLevel())
311 return toLayoutInline(layoutObject)->continuation(); 318 return toLayoutInline(layoutObject)->continuation();
(...skipping 20 matching lines...) Expand all
332 curr = nextContinuation(curr); 339 curr = nextContinuation(curr);
333 } 340 }
334 341
335 if (!beforeChild && !last->slowFirstChild()) 342 if (!beforeChild && !last->slowFirstChild())
336 return nextToLast; 343 return nextToLast;
337 return last; 344 return last;
338 } 345 }
339 346
340 void LayoutInline::addChildIgnoringContinuation(LayoutObject* newChild, 347 void LayoutInline::addChildIgnoringContinuation(LayoutObject* newChild,
341 LayoutObject* beforeChild) { 348 LayoutObject* beforeChild) {
342 // Make sure we don't append things after :after-generated content if we have it. 349 // Make sure we don't append things after :after-generated content if we have
350 // it.
343 if (!beforeChild && isAfterContent(lastChild())) 351 if (!beforeChild && isAfterContent(lastChild()))
344 beforeChild = lastChild(); 352 beforeChild = lastChild();
345 353
346 if (!newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned() && 354 if (!newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned() &&
347 !newChild->isTablePart()) { 355 !newChild->isTablePart()) {
348 // We are placing a block inside an inline. We have to perform a split of th is 356 // 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 357 // 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 358 // 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. 359 // of this inline. We take all of the children after |beforeChild| and put
360 // them in a clone of this object.
352 RefPtr<ComputedStyle> newStyle = 361 RefPtr<ComputedStyle> newStyle =
353 ComputedStyle::createAnonymousStyleWithDisplay( 362 ComputedStyle::createAnonymousStyleWithDisplay(
354 containingBlock()->styleRef(), EDisplay::Block); 363 containingBlock()->styleRef(), EDisplay::Block);
355 364
356 // If inside an inline affected by in-flow positioning the block needs to be affected by it too. 365 // 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. 366 // affected by it too. Giving the block a layer like this allows it to
367 // collect the x/y offsets from inline parents later.
358 if (LayoutObject* positionedAncestor = inFlowPositionedInlineAncestor(this)) 368 if (LayoutObject* positionedAncestor = inFlowPositionedInlineAncestor(this))
359 newStyle->setPosition(positionedAncestor->style()->position()); 369 newStyle->setPosition(positionedAncestor->style()->position());
360 370
361 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&document()); 371 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&document());
362 newBox->setStyle(newStyle.release()); 372 newBox->setStyle(newStyle.release());
363 LayoutBoxModelObject* oldContinuation = continuation(); 373 LayoutBoxModelObject* oldContinuation = continuation();
364 setContinuation(newBox); 374 setContinuation(newBox);
365 375
366 splitFlow(beforeChild, newBox, newChild, oldContinuation); 376 splitFlow(beforeChild, newBox, newChild, oldContinuation);
367 return; 377 return;
(...skipping 25 matching lines...) Expand all
393 } 403 }
394 404
395 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock, 405 void LayoutInline::splitInlines(LayoutBlockFlow* fromBlock,
396 LayoutBlockFlow* toBlock, 406 LayoutBlockFlow* toBlock,
397 LayoutBlockFlow* middleBlock, 407 LayoutBlockFlow* middleBlock,
398 LayoutObject* beforeChild, 408 LayoutObject* beforeChild,
399 LayoutBoxModelObject* oldCont) { 409 LayoutBoxModelObject* oldCont) {
400 ASSERT(isDescendantOf(fromBlock)); 410 ASSERT(isDescendantOf(fromBlock));
401 411
402 // If we're splitting the inline containing the fullscreened element, 412 // If we're splitting the inline containing the fullscreened element,
403 // |beforeChild| may be the layoutObject for the fullscreened element. However , 413 // |beforeChild| may be the layoutObject for the fullscreened element.
404 // that layoutObject is wrapped in a LayoutFullScreen, so |this| is not its 414 // However, that layoutObject is wrapped in a LayoutFullScreen, so |this| is
405 // parent. Since the splitting logic expects |this| to be the parent, set 415 // not its parent. Since the splitting logic expects |this| to be the parent,
406 // |beforeChild| to be the LayoutFullScreen. 416 // set |beforeChild| to be the LayoutFullScreen.
407 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) { 417 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) {
408 const Element* fullScreenElement = fullscreen->currentFullScreenElement(); 418 const Element* fullScreenElement = fullscreen->currentFullScreenElement();
409 if (fullScreenElement && beforeChild && 419 if (fullScreenElement && beforeChild &&
410 beforeChild->node() == fullScreenElement) 420 beforeChild->node() == fullScreenElement)
411 beforeChild = fullscreen->fullScreenLayoutObject(); 421 beforeChild = fullscreen->fullScreenLayoutObject();
412 } 422 }
413 423
414 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone. 424 // 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 425 // 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 426 // There will eventually be a better approach to this problem that will let us
417 // incorrect rendering, but the alternative is to hang forever. 427 // nest to a much greater depth (see bugzilla bug 13430) but for now we have a
428 // limit. This *will* result in incorrect rendering, but the alternative is to
429 // hang forever.
418 const unsigned cMaxSplitDepth = 200; 430 const unsigned cMaxSplitDepth = 200;
419 Vector<LayoutInline*> inlinesToClone; 431 Vector<LayoutInline*> inlinesToClone;
420 LayoutInline* topMostInline = this; 432 LayoutInline* topMostInline = this;
421 for (LayoutObject* o = this; o != fromBlock; o = o->parent()) { 433 for (LayoutObject* o = this; o != fromBlock; o = o->parent()) {
422 topMostInline = toLayoutInline(o); 434 topMostInline = toLayoutInline(o);
423 if (inlinesToClone.size() < cMaxSplitDepth) 435 if (inlinesToClone.size() < cMaxSplitDepth)
424 inlinesToClone.append(topMostInline); 436 inlinesToClone.append(topMostInline);
425 // Keep walking up the chain to ensure |topMostInline| is a child of |fromBl ock|, 437 // 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. 438 // |fromBlock|, to avoid assertion failure when |fromBlock|'s children are
439 // moved to |toBlock| below.
427 } 440 }
428 441
429 // Create a new clone of the top-most inline in |inlinesToClone|. 442 // Create a new clone of the top-most inline in |inlinesToClone|.
430 LayoutInline* topMostInlineToClone = inlinesToClone.last(); 443 LayoutInline* topMostInlineToClone = inlinesToClone.last();
431 LayoutInline* cloneInline = topMostInlineToClone->clone(); 444 LayoutInline* cloneInline = topMostInlineToClone->clone();
432 445
433 // Now we are at the block level. We need to put the clone into the |toBlock|. 446 // Now we are at the block level. We need to put the clone into the |toBlock|.
434 toBlock->children()->appendChildNode(toBlock, cloneInline); 447 toBlock->children()->appendChildNode(toBlock, cloneInline);
435 448
436 // Now take all the children after |topMostInline| and remove them from the |f romBlock| 449 // Now take all the children after |topMostInline| and remove them from the
437 // and put them into the toBlock. 450 // |fromBlock| and put them into the toBlock.
438 fromBlock->moveChildrenTo(toBlock, topMostInline->nextSibling(), nullptr, 451 fromBlock->moveChildrenTo(toBlock, topMostInline->nextSibling(), nullptr,
439 true); 452 true);
440 453
441 LayoutInline* currentParent = topMostInlineToClone; 454 LayoutInline* currentParent = topMostInlineToClone;
442 LayoutInline* cloneInlineParent = cloneInline; 455 LayoutInline* cloneInlineParent = cloneInline;
443 456
444 // Clone the inlines from top to down to ensure any new object will be added i nto a rooted tree. 457 // 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 458 // into a rooted tree.
446 // we have reached |cMaxDepth| in which case we sacrifice correct rendering fo r performance). 459 // Note that we have already cloned the top-most one, so the loop begins from
460 // size - 2 (except if we have reached |cMaxDepth| in which case we sacrifice
461 // correct rendering for performance).
447 for (int i = static_cast<int>(inlinesToClone.size()) - 2; i >= 0; --i) { 462 for (int i = static_cast<int>(inlinesToClone.size()) - 2; i >= 0; --i) {
448 // Hook the clone up as a continuation of |currentInline|. 463 // Hook the clone up as a continuation of |currentInline|.
449 LayoutBoxModelObject* oldCont = currentParent->continuation(); 464 LayoutBoxModelObject* oldCont = currentParent->continuation();
450 currentParent->setContinuation(cloneInline); 465 currentParent->setContinuation(cloneInline);
451 cloneInline->setContinuation(oldCont); 466 cloneInline->setContinuation(oldCont);
452 467
453 // Create a new clone. 468 // Create a new clone.
454 LayoutInline* current = inlinesToClone[i]; 469 LayoutInline* current = inlinesToClone[i];
455 cloneInline = current->clone(); 470 cloneInline = current->clone();
456 471
457 // Insert our |cloneInline| as the first child of |cloneInlineParent|. 472 // Insert our |cloneInline| as the first child of |cloneInlineParent|.
458 cloneInlineParent->addChildIgnoringContinuation(cloneInline, nullptr); 473 cloneInlineParent->addChildIgnoringContinuation(cloneInline, nullptr);
459 474
460 // Now we need to take all of the children starting from the first child 475 // Now we need to take all of the children starting from the first child
461 // *after* |current| and append them all to the |cloneInlineParent|. 476 // *after* |current| and append them all to the |cloneInlineParent|.
462 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent, 477 currentParent->moveChildrenToIgnoringContinuation(cloneInlineParent,
463 current->nextSibling()); 478 current->nextSibling());
464 479
465 currentParent = current; 480 currentParent = current;
466 cloneInlineParent = cloneInline; 481 cloneInlineParent = cloneInline;
467 } 482 }
468 483
469 // The last inline to clone is |this|, and the current |cloneInline| is cloned from |this|. 484 // The last inline to clone is |this|, and the current |cloneInline| is cloned
485 // from |this|.
470 ASSERT(this == inlinesToClone.first()); 486 ASSERT(this == inlinesToClone.first());
471 487
472 // Hook |cloneInline| up as the continuation of the middle block. 488 // Hook |cloneInline| up as the continuation of the middle block.
473 cloneInline->setContinuation(oldCont); 489 cloneInline->setContinuation(oldCont);
474 middleBlock->setContinuation(cloneInline); 490 middleBlock->setContinuation(cloneInline);
475 491
476 // Now take all of the children from |beforeChild| to the end and remove 492 // Now take all of the children from |beforeChild| to the end and remove
477 // them from |this| and place them in the clone. 493 // them from |this| and place them in the clone.
478 moveChildrenToIgnoringContinuation(cloneInline, beforeChild); 494 moveChildrenToIgnoringContinuation(cloneInline, beforeChild);
479 } 495 }
480 496
481 void LayoutInline::splitFlow(LayoutObject* beforeChild, 497 void LayoutInline::splitFlow(LayoutObject* beforeChild,
482 LayoutBlockFlow* newBlockBox, 498 LayoutBlockFlow* newBlockBox,
483 LayoutObject* newChild, 499 LayoutObject* newChild,
484 LayoutBoxModelObject* oldCont) { 500 LayoutBoxModelObject* oldCont) {
485 LayoutBlockFlow* block = toLayoutBlockFlow(containingBlock()); 501 LayoutBlockFlow* block = toLayoutBlockFlow(containingBlock());
486 LayoutBlockFlow* pre = nullptr; 502 LayoutBlockFlow* pre = nullptr;
487 503
488 // Delete our line boxes before we do the inline split into continuations. 504 // Delete our line boxes before we do the inline split into continuations.
489 block->deleteLineBoxTree(); 505 block->deleteLineBoxTree();
490 506
491 bool reusedAnonymousBlock = false; 507 bool reusedAnonymousBlock = false;
492 if (block->isAnonymousBlock()) { 508 if (block->isAnonymousBlock()) {
493 LayoutBlock* outerContainingBlock = block->containingBlock(); 509 LayoutBlock* outerContainingBlock = block->containingBlock();
494 if (outerContainingBlock && outerContainingBlock->isLayoutBlockFlow() && 510 if (outerContainingBlock && outerContainingBlock->isLayoutBlockFlow() &&
495 !outerContainingBlock->createsAnonymousWrapper()) { 511 !outerContainingBlock->createsAnonymousWrapper()) {
496 // We can reuse this block and make it the preBlock of the next continuati on. 512 // We can reuse this block and make it the preBlock of the next
513 // continuation.
497 block->removePositionedObjects(nullptr); 514 block->removePositionedObjects(nullptr);
498 block->removeFloatingObjects(); 515 block->removeFloatingObjects();
499 pre = block; 516 pre = block;
500 block = toLayoutBlockFlow(outerContainingBlock); 517 block = toLayoutBlockFlow(outerContainingBlock);
501 reusedAnonymousBlock = true; 518 reusedAnonymousBlock = true;
502 } 519 }
503 } 520 }
521
522 // No anonymous block available for use. Make one.
504 if (!reusedAnonymousBlock) 523 if (!reusedAnonymousBlock)
505 pre = toLayoutBlockFlow( 524 pre = toLayoutBlockFlow(block->createAnonymousBlock());
506 block
507 ->createAnonymousBlock()); // No anonymous block available for use. Make one.
508 525
509 LayoutBlockFlow* post = toLayoutBlockFlow(pre->createAnonymousBlock()); 526 LayoutBlockFlow* post = toLayoutBlockFlow(pre->createAnonymousBlock());
510 527
511 LayoutObject* boxFirst = 528 LayoutObject* boxFirst =
512 !reusedAnonymousBlock ? block->firstChild() : pre->nextSibling(); 529 !reusedAnonymousBlock ? block->firstChild() : pre->nextSibling();
513 if (!reusedAnonymousBlock) 530 if (!reusedAnonymousBlock)
514 block->children()->insertChildNode(block, pre, boxFirst); 531 block->children()->insertChildNode(block, pre, boxFirst);
515 block->children()->insertChildNode(block, newBlockBox, boxFirst); 532 block->children()->insertChildNode(block, newBlockBox, boxFirst);
516 block->children()->insertChildNode(block, post, boxFirst); 533 block->children()->insertChildNode(block, post, boxFirst);
517 block->setChildrenInline(false); 534 block->setChildrenInline(false);
518 535
519 if (!reusedAnonymousBlock) { 536 if (!reusedAnonymousBlock) {
520 LayoutObject* o = boxFirst; 537 LayoutObject* o = boxFirst;
521 while (o) { 538 while (o) {
522 LayoutObject* no = o; 539 LayoutObject* no = o;
523 o = no->nextSibling(); 540 o = no->nextSibling();
524 pre->children()->appendChildNode( 541 pre->children()->appendChildNode(
525 pre, block->children()->removeChildNode(block, no)); 542 pre, block->children()->removeChildNode(block, no));
526 no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 543 no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
527 LayoutInvalidationReason::AnonymousBlockChange); 544 LayoutInvalidationReason::AnonymousBlockChange);
528 } 545 }
529 } 546 }
530 547
531 splitInlines(pre, post, newBlockBox, beforeChild, oldCont); 548 splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
532 549
533 // We already know the newBlockBox isn't going to contain inline kids, so avoi d wasting 550 // We already know the newBlockBox isn't going to contain inline kids, so
534 // time in makeChildrenNonInline by just setting this explicitly up front. 551 // avoid wasting time in makeChildrenNonInline by just setting this explicitly
552 // up front.
535 newBlockBox->setChildrenInline(false); 553 newBlockBox->setChildrenInline(false);
536 554
537 newBlockBox->addChild(newChild); 555 newBlockBox->addChild(newChild);
538 556
539 // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) 557 // 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 558 // wrappers for images) get deleted properly. Because objects moves from the
541 // make new line boxes instead of leaving the old line boxes around. 559 // pre block into the post block, we want to make new line boxes instead of
560 // leaving the old line boxes around.
542 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 561 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
543 LayoutInvalidationReason::AnonymousBlockChange); 562 LayoutInvalidationReason::AnonymousBlockChange);
544 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 563 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
545 LayoutInvalidationReason::AnonymousBlockChange); 564 LayoutInvalidationReason::AnonymousBlockChange);
546 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 565 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
547 LayoutInvalidationReason::AnonymousBlockChange); 566 LayoutInvalidationReason::AnonymousBlockChange);
548 } 567 }
549 568
550 void LayoutInline::addChildToContinuation(LayoutObject* newChild, 569 void LayoutInline::addChildToContinuation(LayoutObject* newChild,
551 LayoutObject* beforeChild) { 570 LayoutObject* beforeChild) {
552 // A continuation always consists of two potential candidates: an inline or an anonymous 571 // A continuation always consists of two potential candidates: an inline or an
553 // block box holding block children. 572 // anonymous block box holding block children.
554 LayoutBoxModelObject* flow = continuationBefore(beforeChild); 573 LayoutBoxModelObject* flow = continuationBefore(beforeChild);
555 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousBlock() || 574 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousBlock() ||
556 beforeChild->parent()->isLayoutInline()); 575 beforeChild->parent()->isLayoutInline());
557 LayoutBoxModelObject* beforeChildParent = nullptr; 576 LayoutBoxModelObject* beforeChildParent = nullptr;
558 if (beforeChild) { 577 if (beforeChild) {
559 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent()); 578 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent());
560 } else { 579 } else {
561 LayoutBoxModelObject* cont = nextContinuation(flow); 580 LayoutBoxModelObject* cont = nextContinuation(flow);
562 if (cont) 581 if (cont)
563 beforeChildParent = cont; 582 beforeChildParent = cont;
564 else 583 else
565 beforeChildParent = flow; 584 beforeChildParent = flow;
566 } 585 }
567 586
568 // TODO(rhogan): Should we treat out-of-flows and floats as through they're in line below? 587 // TODO(rhogan): Should we treat out-of-flows and floats as through they're
588 // inline below?
569 if (newChild->isFloatingOrOutOfFlowPositioned()) 589 if (newChild->isFloatingOrOutOfFlowPositioned())
570 return beforeChildParent->addChildIgnoringContinuation(newChild, 590 return beforeChildParent->addChildIgnoringContinuation(newChild,
571 beforeChild); 591 beforeChild);
572 592
573 // A table part will be wrapped by an inline anonymous table when it is added to the layout 593 // 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. 594 // to the layout tree, so treat it as inline when deciding where to add it.
575 bool childInline = newChild->isInline() || newChild->isTablePart(); 595 bool childInline = newChild->isInline() || newChild->isTablePart();
576 bool bcpInline = beforeChildParent->isInline(); 596 bool bcpInline = beforeChildParent->isInline();
577 bool flowInline = flow->isInline(); 597 bool flowInline = flow->isInline();
578 598
579 if (flow == beforeChildParent) 599 if (flow == beforeChildParent)
580 return flow->addChildIgnoringContinuation(newChild, beforeChild); 600 return flow->addChildIgnoringContinuation(newChild, beforeChild);
581 601
582 // The goal here is to match up if we can, so that we can coalesce and create the 602 // 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. 603 // the minimal # of continuations needed for the inline.
584 if (childInline == bcpInline || (beforeChild && beforeChild->isInline())) 604 if (childInline == bcpInline || (beforeChild && beforeChild->isInline()))
585 return beforeChildParent->addChildIgnoringContinuation(newChild, 605 return beforeChildParent->addChildIgnoringContinuation(newChild,
586 beforeChild); 606 beforeChild);
587 if (flowInline == childInline) 607 if (flowInline == childInline) {
588 return flow->addChildIgnoringContinuation(newChild, 608 // Just treat like an append.
589 0); // Just treat like an append. 609 return flow->addChildIgnoringContinuation(newChild, 0);
610 }
590 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 611 return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
591 } 612 }
592 613
593 void LayoutInline::paint(const PaintInfo& paintInfo, 614 void LayoutInline::paint(const PaintInfo& paintInfo,
594 const LayoutPoint& paintOffset) const { 615 const LayoutPoint& paintOffset) const {
595 InlinePainter(*this).paint(paintInfo, paintOffset); 616 InlinePainter(*this).paint(paintInfo, paintOffset);
596 } 617 }
597 618
598 template <typename GeneratorContext> 619 template <typename GeneratorContext>
599 void LayoutInline::generateLineBoxRects(GeneratorContext& yield) const { 620 void LayoutInline::generateLineBoxRects(GeneratorContext& yield) const {
(...skipping 11 matching lines...) Expand all
611 const LayoutInline* container) const { 632 const LayoutInline* container) const {
612 if (!culledInlineFirstLineBox()) 633 if (!culledInlineFirstLineBox())
613 return; 634 return;
614 635
615 bool isHorizontal = style()->isHorizontalWritingMode(); 636 bool isHorizontal = style()->isHorizontalWritingMode();
616 637
617 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 638 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
618 if (curr->isFloatingOrOutOfFlowPositioned()) 639 if (curr->isFloatingOrOutOfFlowPositioned())
619 continue; 640 continue;
620 641
621 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 642 // We want to get the margin box in the inline direction, and then use our
622 // direction (aligned to the root box's baseline). 643 // font ascent/descent in the block direction (aligned to the root box's
644 // baseline).
623 if (curr->isBox()) { 645 if (curr->isBox()) {
624 LayoutBox* currBox = toLayoutBox(curr); 646 LayoutBox* currBox = toLayoutBox(curr);
625 if (currBox->inlineBoxWrapper()) { 647 if (currBox->inlineBoxWrapper()) {
626 RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root(); 648 RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
627 LayoutUnit logicalTop = 649 LayoutUnit logicalTop =
628 rootBox.logicalTop() + (rootBox.getLineLayoutItem() 650 rootBox.logicalTop() + (rootBox.getLineLayoutItem()
629 .style(rootBox.isFirstLineStyle()) 651 .style(rootBox.isFirstLineStyle())
630 ->font() 652 ->font()
631 .getFontMetrics() 653 .getFontMetrics()
632 .ascent() - 654 .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 962 // If there are continuations, test them first because our containing block
941 // will not check them. 963 // will not check them.
942 LayoutBoxModelObject* continuation = this->continuation(); 964 LayoutBoxModelObject* continuation = this->continuation();
943 while (continuation) { 965 while (continuation) {
944 if (continuation->isInline() || continuation->slowFirstChild()) 966 if (continuation->isInline() || continuation->slowFirstChild())
945 return continuation->positionForPoint(point); 967 return continuation->positionForPoint(point);
946 continuation = toLayoutBlockFlow(continuation)->inlineElementContinuation(); 968 continuation = toLayoutBlockFlow(continuation)->inlineElementContinuation();
947 } 969 }
948 970
949 if (firstLineBoxIncludingCulling()) { 971 if (firstLineBoxIncludingCulling()) {
950 // This inline actually has a line box. We must have clicked in the border/ padding of one of these boxes. We 972 // This inline actually has a line box. We must have clicked in the
973 // border/padding of one of these boxes. We
951 // should try to find a result by asking our containing block. 974 // should try to find a result by asking our containing block.
952 return containingBlock()->positionForPoint(point); 975 return containingBlock()->positionForPoint(point);
953 } 976 }
954 977
955 return LayoutBoxModelObject::positionForPoint(point); 978 return LayoutBoxModelObject::positionForPoint(point);
956 } 979 }
957 980
958 namespace { 981 namespace {
959 982
960 class LinesBoundingBoxGeneratorContext { 983 class LinesBoundingBoxGeneratorContext {
(...skipping 12 matching lines...) Expand all
973 if (!alwaysCreateLineBoxes()) { 996 if (!alwaysCreateLineBoxes()) {
974 ASSERT(!firstLineBox()); 997 ASSERT(!firstLineBox());
975 FloatRect floatResult; 998 FloatRect floatResult;
976 LinesBoundingBoxGeneratorContext context(floatResult); 999 LinesBoundingBoxGeneratorContext context(floatResult);
977 generateCulledLineBoxRects(context, this); 1000 generateCulledLineBoxRects(context, this);
978 return enclosingLayoutRect(floatResult); 1001 return enclosingLayoutRect(floatResult);
979 } 1002 }
980 1003
981 LayoutRect result; 1004 LayoutRect result;
982 1005
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 1006 // 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 1007 // 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. 1008 // unable to reproduce this at all (and consequently unable to figure ot why
1009 // this is happening). The assert will hopefully catch the problem in debug
1010 // builds and help us someday figure out why. We also put in a redundant
1011 // check of lastLineBox() to avoid the crash for now.
986 ASSERT(!firstLineBox() == 1012 ASSERT(!firstLineBox() ==
987 !lastLineBox()); // Either both are null or both exist. 1013 !lastLineBox()); // Either both are null or both exist.
988 if (firstLineBox() && lastLineBox()) { 1014 if (firstLineBox() && lastLineBox()) {
989 // Return the width of the minimal left side and the maximal right side. 1015 // Return the width of the minimal left side and the maximal right side.
990 LayoutUnit logicalLeftSide; 1016 LayoutUnit logicalLeftSide;
991 LayoutUnit logicalRightSide; 1017 LayoutUnit logicalRightSide;
992 for (InlineFlowBox* curr = firstLineBox(); curr; 1018 for (InlineFlowBox* curr = firstLineBox(); curr;
993 curr = curr->nextLineBox()) { 1019 curr = curr->nextLineBox()) {
994 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide) 1020 if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
995 logicalLeftSide = curr->logicalLeft(); 1021 logicalLeftSide = curr->logicalLeft();
(...skipping 13 matching lines...) Expand all
1009 } 1035 }
1010 1036
1011 return result; 1037 return result;
1012 } 1038 }
1013 1039
1014 InlineBox* LayoutInline::culledInlineFirstLineBox() const { 1040 InlineBox* LayoutInline::culledInlineFirstLineBox() const {
1015 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 1041 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
1016 if (curr->isFloatingOrOutOfFlowPositioned()) 1042 if (curr->isFloatingOrOutOfFlowPositioned())
1017 continue; 1043 continue;
1018 1044
1019 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 1045 // We want to get the margin box in the inline direction, and then use our
1020 // direction (aligned to the root box's baseline). 1046 // font ascent/descent in the block direction (aligned to the root box's
1047 // baseline).
1021 if (curr->isBox()) 1048 if (curr->isBox())
1022 return toLayoutBox(curr)->inlineBoxWrapper(); 1049 return toLayoutBox(curr)->inlineBoxWrapper();
1023 if (curr->isLayoutInline()) { 1050 if (curr->isLayoutInline()) {
1024 LayoutInline* currInline = toLayoutInline(curr); 1051 LayoutInline* currInline = toLayoutInline(curr);
1025 InlineBox* result = currInline->firstLineBoxIncludingCulling(); 1052 InlineBox* result = currInline->firstLineBoxIncludingCulling();
1026 if (result) 1053 if (result)
1027 return result; 1054 return result;
1028 } else if (curr->isText()) { 1055 } else if (curr->isText()) {
1029 LayoutText* currText = toLayoutText(curr); 1056 LayoutText* currText = toLayoutText(curr);
1030 if (currText->firstTextBox()) 1057 if (currText->firstTextBox())
1031 return currText->firstTextBox(); 1058 return currText->firstTextBox();
1032 } 1059 }
1033 } 1060 }
1034 return nullptr; 1061 return nullptr;
1035 } 1062 }
1036 1063
1037 InlineBox* LayoutInline::culledInlineLastLineBox() const { 1064 InlineBox* LayoutInline::culledInlineLastLineBox() const {
1038 for (LayoutObject* curr = lastChild(); curr; curr = curr->previousSibling()) { 1065 for (LayoutObject* curr = lastChild(); curr; curr = curr->previousSibling()) {
1039 if (curr->isFloatingOrOutOfFlowPositioned()) 1066 if (curr->isFloatingOrOutOfFlowPositioned())
1040 continue; 1067 continue;
1041 1068
1042 // We want to get the margin box in the inline direction, and then use our f ont ascent/descent in the block 1069 // We want to get the margin box in the inline direction, and then use our
1043 // direction (aligned to the root box's baseline). 1070 // font ascent/descent in the block direction (aligned to the root box's
1071 // baseline).
1044 if (curr->isBox()) 1072 if (curr->isBox())
1045 return toLayoutBox(curr)->inlineBoxWrapper(); 1073 return toLayoutBox(curr)->inlineBoxWrapper();
1046 if (curr->isLayoutInline()) { 1074 if (curr->isLayoutInline()) {
1047 LayoutInline* currInline = toLayoutInline(curr); 1075 LayoutInline* currInline = toLayoutInline(curr);
1048 InlineBox* result = currInline->lastLineBoxIncludingCulling(); 1076 InlineBox* result = currInline->lastLineBoxIncludingCulling();
1049 if (result) 1077 if (result)
1050 return result; 1078 return result;
1051 } else if (curr->isText()) { 1079 } else if (curr->isText()) {
1052 LayoutText* currText = toLayoutText(curr); 1080 LayoutText* currText = toLayoutText(curr);
1053 if (currText->lastTextBox()) 1081 if (currText->lastTextBox())
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 1200
1173 return visualOverflowRect(); 1201 return visualOverflowRect();
1174 } 1202 }
1175 1203
1176 LayoutRect LayoutInline::visualOverflowRect() const { 1204 LayoutRect LayoutInline::visualOverflowRect() const {
1177 LayoutRect overflowRect = linesVisualOverflowBoundingBox(); 1205 LayoutRect overflowRect = linesVisualOverflowBoundingBox();
1178 LayoutUnit outlineOutset(style()->outlineOutsetExtent()); 1206 LayoutUnit outlineOutset(style()->outlineOutsetExtent());
1179 if (outlineOutset) { 1207 if (outlineOutset) {
1180 Vector<LayoutRect> rects; 1208 Vector<LayoutRect> rects;
1181 if (document().inNoQuirksMode()) { 1209 if (document().inNoQuirksMode()) {
1182 // We have already included outline extents of line boxes in linesVisualOv erflowBoundingBox(), 1210 // We have already included outline extents of line boxes in
1183 // so the following just add outline rects for children and continuations. 1211 // linesVisualOverflowBoundingBox(), so the following just add outline
1212 // rects for children and continuations.
1184 addOutlineRectsForChildrenAndContinuations( 1213 addOutlineRectsForChildrenAndContinuations(
1185 rects, LayoutPoint(), outlineRectsShouldIncludeBlockVisualOverflow()); 1214 rects, LayoutPoint(), outlineRectsShouldIncludeBlockVisualOverflow());
1186 } else { 1215 } else {
1187 // In non-standard mode, because the difference in LayoutBlock::minLineHei ghtForReplacedObject(), 1216 // In non-standard mode, because the difference in
1188 // linesVisualOverflowBoundingBox() may not cover outline rects of lines c ontaining replaced objects. 1217 // LayoutBlock::minLineHeightForReplacedObject(),
1218 // linesVisualOverflowBoundingBox() may not cover outline rects of lines
1219 // containing replaced objects.
1189 addOutlineRects(rects, LayoutPoint(), 1220 addOutlineRects(rects, LayoutPoint(),
1190 outlineRectsShouldIncludeBlockVisualOverflow()); 1221 outlineRectsShouldIncludeBlockVisualOverflow());
1191 } 1222 }
1192 if (!rects.isEmpty()) { 1223 if (!rects.isEmpty()) {
1193 LayoutRect outlineRect = unionRectEvenIfEmpty(rects); 1224 LayoutRect outlineRect = unionRectEvenIfEmpty(rects);
1194 outlineRect.inflate(outlineOutset); 1225 outlineRect.inflate(outlineOutset);
1195 overflowRect.unite(outlineRect); 1226 overflowRect.unite(outlineRect);
1196 } 1227 }
1197 } 1228 }
1198 return overflowRect; 1229 return overflowRect;
1199 } 1230 }
1200 1231
1201 bool LayoutInline::mapToVisualRectInAncestorSpace( 1232 bool LayoutInline::mapToVisualRectInAncestorSpace(
1202 const LayoutBoxModelObject* ancestor, 1233 const LayoutBoxModelObject* ancestor,
1203 LayoutRect& rect, 1234 LayoutRect& rect,
1204 VisualRectFlags visualRectFlags) const { 1235 VisualRectFlags visualRectFlags) const {
1205 if (ancestor == this) 1236 if (ancestor == this)
1206 return true; 1237 return true;
1207 1238
1208 LayoutObject* container = this->container(); 1239 LayoutObject* container = this->container();
1209 ASSERT(container == parent()); 1240 ASSERT(container == parent());
1210 if (!container) 1241 if (!container)
1211 return true; 1242 return true;
1212 1243
1213 if (style()->hasInFlowPosition() && layer()) { 1244 if (style()->hasInFlowPosition() && layer()) {
1214 // Apply the in-flow position offset when invalidating a rectangle. The laye r 1245 // 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 1246 // 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 1247 // 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(). 1248 // setStyle, the relative position flag on the LayoutObject has been
1249 // cleared, so use the one on the style().
1218 rect.move(layer()->offsetForInFlowPosition()); 1250 rect.move(layer()->offsetForInFlowPosition());
1219 } 1251 }
1220 1252
1221 LayoutBox* containerBox = 1253 LayoutBox* containerBox =
1222 container->isBox() ? toLayoutBox(container) : nullptr; 1254 container->isBox() ? toLayoutBox(container) : nullptr;
1223 if (containerBox && 1255 if (containerBox &&
1224 !containerBox->mapScrollingContentsRectToBoxSpace( 1256 !containerBox->mapScrollingContentsRectToBoxSpace(
1225 rect, container == ancestor ? ApplyNonScrollOverflowClip 1257 rect, container == ancestor ? ApplyNonScrollOverflowClip
1226 : ApplyOverflowClip, 1258 : ApplyOverflowClip,
1227 visualRectFlags)) 1259 visualRectFlags))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 1301
1270 void LayoutInline::updateHitTestResult(HitTestResult& result, 1302 void LayoutInline::updateHitTestResult(HitTestResult& result,
1271 const LayoutPoint& point) { 1303 const LayoutPoint& point) {
1272 if (result.innerNode()) 1304 if (result.innerNode())
1273 return; 1305 return;
1274 1306
1275 Node* n = node(); 1307 Node* n = node();
1276 LayoutPoint localPoint(point); 1308 LayoutPoint localPoint(point);
1277 if (n) { 1309 if (n) {
1278 if (isInlineElementContinuation()) { 1310 if (isInlineElementContinuation()) {
1279 // We're in the continuation of a split inline. Adjust our local point to be in the coordinate space 1311 // 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. 1312 // be in the coordinate space of the principal layoutObject's containing
1313 // block. This will end up being the innerNode.
1281 LayoutBlock* firstBlock = n->layoutObject()->containingBlock(); 1314 LayoutBlock* firstBlock = n->layoutObject()->containingBlock();
1282 1315
1283 // Get our containing block. 1316 // Get our containing block.
1284 LayoutBox* block = containingBlock(); 1317 LayoutBox* block = containingBlock();
1285 localPoint.moveBy(block->location() - firstBlock->locationOffset()); 1318 localPoint.moveBy(block->location() - firstBlock->locationOffset());
1286 } 1319 }
1287 1320
1288 result.setNodeAndPosition(n, localPoint); 1321 result.setNodeAndPosition(n, localPoint);
1289 } 1322 }
1290 } 1323 }
1291 1324
1292 void LayoutInline::dirtyLineBoxes(bool fullLayout) { 1325 void LayoutInline::dirtyLineBoxes(bool fullLayout) {
1293 if (fullLayout) { 1326 if (fullLayout) {
1294 m_lineBoxes.deleteLineBoxes(); 1327 m_lineBoxes.deleteLineBoxes();
1295 return; 1328 return;
1296 } 1329 }
1297 1330
1298 if (!alwaysCreateLineBoxes()) { 1331 if (!alwaysCreateLineBoxes()) {
1299 // We have to grovel into our children in order to dirty the appropriate lin es. 1332 // We have to grovel into our children in order to dirty the appropriate
1333 // lines.
1300 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) { 1334 for (LayoutObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
1301 if (curr->isFloatingOrOutOfFlowPositioned()) 1335 if (curr->isFloatingOrOutOfFlowPositioned())
1302 continue; 1336 continue;
1303 if (curr->isBox() && !curr->needsLayout()) { 1337 if (curr->isBox() && !curr->needsLayout()) {
1304 LayoutBox* currBox = toLayoutBox(curr); 1338 LayoutBox* currBox = toLayoutBox(curr);
1305 if (currBox->inlineBoxWrapper()) 1339 if (currBox->inlineBoxWrapper())
1306 currBox->inlineBoxWrapper()->root().markDirty(); 1340 currBox->inlineBoxWrapper()->root().markDirty();
1307 } else if (!curr->selfNeedsLayout()) { 1341 } else if (!curr->selfNeedsLayout()) {
1308 if (curr->isLayoutInline()) { 1342 if (curr->isLayoutInline()) {
1309 LayoutInline* currInline = toLayoutInline(curr); 1343 LayoutInline* currInline = toLayoutInline(curr);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 } 1395 }
1362 1396
1363 LayoutSize LayoutInline::offsetForInFlowPositionedInline( 1397 LayoutSize LayoutInline::offsetForInFlowPositionedInline(
1364 const LayoutBox& child) const { 1398 const LayoutBox& child) const {
1365 // FIXME: This function isn't right with mixed writing modes. 1399 // FIXME: This function isn't right with mixed writing modes.
1366 1400
1367 ASSERT(isInFlowPositioned()); 1401 ASSERT(isInFlowPositioned());
1368 if (!isInFlowPositioned()) 1402 if (!isInFlowPositioned())
1369 return LayoutSize(); 1403 return LayoutSize();
1370 1404
1371 // When we have an enclosing relpositioned inline, we need to add in the offse t of the first line 1405 // 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 1406 // offset of the first line box from the rest of the content, but only in the
1373 // relative to the inline itself. 1407 // cases where we know we're positioned relative to the inline itself.
1374 1408
1375 LayoutSize logicalOffset; 1409 LayoutSize logicalOffset;
1376 LayoutUnit inlinePosition; 1410 LayoutUnit inlinePosition;
1377 LayoutUnit blockPosition; 1411 LayoutUnit blockPosition;
1378 if (firstLineBox()) { 1412 if (firstLineBox()) {
1379 inlinePosition = firstLineBox()->logicalLeft(); 1413 inlinePosition = firstLineBox()->logicalLeft();
1380 blockPosition = firstLineBox()->logicalTop(); 1414 blockPosition = firstLineBox()->logicalTop();
1381 } else { 1415 } else {
1382 inlinePosition = layer()->staticInlinePosition(); 1416 inlinePosition = layer()->staticInlinePosition();
1383 blockPosition = layer()->staticBlockPosition(); 1417 blockPosition = layer()->staticBlockPosition();
1384 } 1418 }
1385 1419
1386 // Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an absolu te positioned box 1420 // 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 1421 // 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 1422 // 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. 1423 // relative-positioned inline has a negative offset we need to compensate for
1424 // it so that we align the positioned object with the edge of its containing
1425 // block.
1390 if (child.style()->hasStaticInlinePosition( 1426 if (child.style()->hasStaticInlinePosition(
1391 style()->isHorizontalWritingMode())) 1427 style()->isHorizontalWritingMode()))
1392 logicalOffset.setWidth( 1428 logicalOffset.setWidth(
1393 std::max(LayoutUnit(), -offsetForInFlowPosition().width())); 1429 std::max(LayoutUnit(), -offsetForInFlowPosition().width()));
1394 else 1430 else
1395 logicalOffset.setWidth(inlinePosition); 1431 logicalOffset.setWidth(inlinePosition);
1396 1432
1397 if (!child.style()->hasStaticBlockPosition( 1433 if (!child.style()->hasStaticBlockPosition(
1398 style()->isHorizontalWritingMode())) 1434 style()->isHorizontalWritingMode()))
1399 logicalOffset.setHeight(blockPosition); 1435 logicalOffset.setHeight(blockPosition);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason); 1552 paintInvalidator.invalidateDisplayItemClient(*box, invalidationReason);
1517 } 1553 }
1518 1554
1519 // TODO(lunalu): Not to just dump 0, 0 as the x and y here 1555 // TODO(lunalu): Not to just dump 0, 0 as the x and y here
1520 LayoutRect LayoutInline::debugRect() const { 1556 LayoutRect LayoutInline::debugRect() const {
1521 IntRect linesBox = enclosingIntRect(linesBoundingBox()); 1557 IntRect linesBox = enclosingIntRect(linesBoundingBox());
1522 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height())); 1558 return LayoutRect(IntRect(0, 0, linesBox.width(), linesBox.height()));
1523 } 1559 }
1524 1560
1525 } // namespace blink 1561 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutInline.h ('k') | third_party/WebKit/Source/core/layout/LayoutListBox.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698