OLD | NEW |
1 /** | 1 /** |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
6 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
7 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 7 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 table = new (renderArena()) RenderTable(document() /* is anonymous *
/); | 89 table = new (renderArena()) RenderTable(document() /* is anonymous *
/); |
90 RefPtr<RenderStyle> newStyle = RenderStyle::create(); | 90 RefPtr<RenderStyle> newStyle = RenderStyle::create(); |
91 newStyle->inheritFrom(style()); | 91 newStyle->inheritFrom(style()); |
92 newStyle->setDisplay(TABLE); | 92 newStyle->setDisplay(TABLE); |
93 table->setStyle(newStyle.release()); | 93 table->setStyle(newStyle.release()); |
94 addChild(table, beforeChild); | 94 addChild(table, beforeChild); |
95 } | 95 } |
96 table->addChild(newChild); | 96 table->addChild(newChild); |
97 } else { | 97 } else { |
98 // just add it... | 98 // just add it... |
99 insertChildNode(newChild, beforeChild); | 99 children()->insertChildNode(this, newChild, beforeChild); |
100 } | 100 } |
101 | 101 |
102 if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
{ | 102 if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
{ |
103 RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalTex
t(); | 103 RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalTex
t(); |
104 if (textToTransform) | 104 if (textToTransform) |
105 toRenderText(newChild)->setText(textToTransform.release(), true); | 105 toRenderText(newChild)->setText(textToTransform.release(), true); |
106 } | 106 } |
107 } | 107 } |
108 | 108 |
109 RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild, bool full
Remove) | |
110 { | |
111 ASSERT(oldChild->parent() == this); | |
112 | |
113 // So that we'll get the appropriate dirty bit set (either that a normal flo
w child got yanked or | |
114 // that a positioned child got yanked). We also repaint, so that the area e
xposed when the child | |
115 // disappears gets repainted properly. | |
116 if (!documentBeingDestroyed() && fullRemove && oldChild->m_everHadLayout) { | |
117 oldChild->setNeedsLayoutAndPrefWidthsRecalc(); | |
118 oldChild->repaint(); | |
119 } | |
120 | |
121 // If we have a line box wrapper, delete it. | |
122 oldChild->deleteLineBoxWrapper(); | |
123 | |
124 if (!documentBeingDestroyed() && fullRemove) { | |
125 // if we remove visible child from an invisible parent, we don't know th
e layer visibility any more | |
126 RenderLayer* layer = 0; | |
127 if (m_style->visibility() != VISIBLE && oldChild->style()->visibility()
== VISIBLE && !oldChild->hasLayer()) { | |
128 layer = enclosingLayer(); | |
129 layer->dirtyVisibleContentStatus(); | |
130 } | |
131 | |
132 // Keep our layer hierarchy updated. | |
133 if (oldChild->firstChild() || oldChild->hasLayer()) { | |
134 if (!layer) layer = enclosingLayer(); | |
135 oldChild->removeLayers(layer); | |
136 } | |
137 | |
138 // renumber ordered lists | |
139 if (oldChild->isListItem()) | |
140 updateListMarkerNumbers(oldChild->nextSibling()); | |
141 | |
142 if (oldChild->isPositioned() && childrenInline()) | |
143 dirtyLinesFromChangedChild(oldChild); | |
144 } | |
145 | |
146 // If oldChild is the start or end of the selection, then clear the selectio
n to | |
147 // avoid problems of invalid pointers. | |
148 // FIXME: The SelectionController should be responsible for this when it | |
149 // is notified of DOM mutations. | |
150 if (!documentBeingDestroyed() && oldChild->isSelectionBorder()) | |
151 view()->clearSelection(); | |
152 | |
153 // remove the child | |
154 if (oldChild->previousSibling()) | |
155 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); | |
156 if (oldChild->nextSibling()) | |
157 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling())
; | |
158 | |
159 if (children()->firstChild() == oldChild) | |
160 children()->setFirstChild(oldChild->nextSibling()); | |
161 if (children()->lastChild() == oldChild) | |
162 children()->setLastChild(oldChild->previousSibling()); | |
163 | |
164 oldChild->setPreviousSibling(0); | |
165 oldChild->setNextSibling(0); | |
166 oldChild->setParent(0); | |
167 | |
168 if (AXObjectCache::accessibilityEnabled()) | |
169 document()->axObjectCache()->childrenChanged(this); | |
170 | |
171 return oldChild; | |
172 } | |
173 | |
174 void RenderContainer::removeChild(RenderObject* oldChild) | 109 void RenderContainer::removeChild(RenderObject* oldChild) |
175 { | 110 { |
176 // We do this here instead of in removeChildNode, since the only extremely l
ow-level uses of remove/appendChildNode | 111 // We do this here instead of in removeChildNode, since the only extremely l
ow-level uses of remove/appendChildNode |
177 // cannot affect the positioned object list, and the floating object list is
irrelevant (since the list gets cleared on | 112 // cannot affect the positioned object list, and the floating object list is
irrelevant (since the list gets cleared on |
178 // layout anyway). | 113 // layout anyway). |
179 oldChild->removeFromObjectLists(); | 114 oldChild->removeFromObjectLists(); |
180 | 115 m_children.removeChildNode(this, oldChild); |
181 removeChildNode(oldChild); | |
182 } | |
183 | |
184 RenderObject* RenderContainer::beforeAfterContainer(RenderStyle::PseudoId type) | |
185 { | |
186 if (type == RenderStyle::BEFORE) { | |
187 RenderObject* first = this; | |
188 do { | |
189 // Skip list markers. | |
190 first = first->firstChild(); | |
191 while (first && first->isListMarker()) | |
192 first = first->nextSibling(); | |
193 } while (first && first->isAnonymous() && first->style()->styleType() ==
RenderStyle::NOPSEUDO); | |
194 if (first && first->style()->styleType() != type) | |
195 return 0; | |
196 return first; | |
197 } | |
198 if (type == RenderStyle::AFTER) { | |
199 RenderObject* last = this; | |
200 do { | |
201 last = last->lastChild(); | |
202 } while (last && last->isAnonymous() && last->style()->styleType() == Re
nderStyle::NOPSEUDO && !last->isListMarker()); | |
203 if (last && last->style()->styleType() != type) | |
204 return 0; | |
205 return last; | |
206 } | |
207 | |
208 ASSERT_NOT_REACHED(); | |
209 return 0; | |
210 } | |
211 | |
212 void RenderContainer::updateBeforeAfterContent(RenderStyle::PseudoId type) | |
213 { | |
214 // If this is an anonymous wrapper, then the parent applies its own pseudo-e
lement style to it. | |
215 if (parent() && parent()->createsAnonymousWrapper()) | |
216 return; | |
217 updateBeforeAfterContentForContainer(type, this); | |
218 } | |
219 | |
220 static RenderObject* findBeforeAfterParent(RenderObject* object) | |
221 { | |
222 // Only table parts need to search for the :before or :after parent | |
223 if (!(object->isTable() || object->isTableSection() || object->isTableRow())
) | |
224 return object; | |
225 | |
226 RenderObject* beforeAfterParent = object; | |
227 while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterPare
nt->isImage())) | |
228 beforeAfterParent = beforeAfterParent->firstChild(); | |
229 return beforeAfterParent; | |
230 } | |
231 | |
232 void RenderContainer::updateBeforeAfterContentForContainer(RenderStyle::PseudoId
type, RenderContainer* styledObject) | |
233 { | |
234 // Double check that the document did in fact use generated content rules.
Otherwise we should not have been called. | |
235 ASSERT(document()->usesBeforeAfterRules()); | |
236 | |
237 // In CSS2, before/after pseudo-content cannot nest. Check this first. | |
238 if (style()->styleType() == RenderStyle::BEFORE || style()->styleType() == R
enderStyle::AFTER) | |
239 return; | |
240 | |
241 RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type); | |
242 RenderObject* child = beforeAfterContainer(type); | |
243 | |
244 // Whether or not we currently have generated content attached. | |
245 bool oldContentPresent = child; | |
246 | |
247 // Whether or not we now want generated content. | |
248 bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display()
!= NONE; | |
249 | |
250 // For <q><p/></q>, if this object is the inline continuation of the <q>, we
only want to generate | |
251 // :after content and not :before content. | |
252 if (newContentWanted && type == RenderStyle::BEFORE && isRenderInline() && t
oRenderInline(this)->isInlineContinuation()) | |
253 newContentWanted = false; | |
254 | |
255 // Similarly, if we're the beginning of a <q>, and there's an inline continu
ation for our object, | |
256 // then we don't generate the :after content. | |
257 if (newContentWanted && type == RenderStyle::AFTER && isRenderInline() && to
RenderInline(this)->continuation()) | |
258 newContentWanted = false; | |
259 | |
260 // If we don't want generated content any longer, or if we have generated co
ntent, but it's no longer | |
261 // identical to the new content data we want to build render objects for, th
en we nuke all | |
262 // of the old generated content. | |
263 if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), ps
eudoElementStyle) == Node::Detach)) { | |
264 // Nuke the child. | |
265 if (child && child->style()->styleType() == type) { | |
266 oldContentPresent = false; | |
267 child->destroy(); | |
268 child = (type == RenderStyle::BEFORE) ? children()->firstChild() : c
hildren()->lastChild(); | |
269 } | |
270 } | |
271 | |
272 // If we have no pseudo-element style or if the pseudo-element style's displ
ay type is NONE, then we | |
273 // have no generated content and can now return. | |
274 if (!newContentWanted) | |
275 return; | |
276 | |
277 if (isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudo
ElementStyle->floating() == FNONE && | |
278 !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementSty
le->position() == FixedPosition)) | |
279 // According to the CSS2 spec (the end of section 12.1), the only allowe
d | |
280 // display values for the pseudo style are NONE and INLINE for inline fl
ows. | |
281 // FIXME: CSS2.1 lifted this restriction, but block display types will c
rash. | |
282 // For now we at least relax the restriction to allow all inline types l
ike inline-block | |
283 // and inline-table. | |
284 pseudoElementStyle->setDisplay(INLINE); | |
285 | |
286 if (oldContentPresent) { | |
287 if (child && child->style()->styleType() == type) { | |
288 // We have generated content present still. We want to walk this co
ntent and update our | |
289 // style information with the new pseudo-element style. | |
290 child->setStyle(pseudoElementStyle); | |
291 | |
292 RenderObject* beforeAfterParent = findBeforeAfterParent(child); | |
293 if (!beforeAfterParent) | |
294 return; | |
295 | |
296 // Note that if we ever support additional types of generated conten
t (which should be way off | |
297 // in the future), this code will need to be patched. | |
298 for (RenderObject* genChild = beforeAfterParent->firstChild(); genCh
ild; genChild = genChild->nextSibling()) { | |
299 if (genChild->isText()) | |
300 // Generated text content is a child whose style also needs
to be set to the pseudo-element style. | |
301 genChild->setStyle(pseudoElementStyle); | |
302 else if (genChild->isImage()) { | |
303 // Images get an empty style that inherits from the pseudo. | |
304 RefPtr<RenderStyle> style = RenderStyle::create(); | |
305 style->inheritFrom(pseudoElementStyle); | |
306 genChild->setStyle(style.release()); | |
307 } else | |
308 // Must be a first-letter container. updateFirstLetter() wil
l take care of it. | |
309 ASSERT(genChild->style()->styleType() == RenderStyle::FIRST_
LETTER); | |
310 } | |
311 } | |
312 return; // We've updated the generated content. That's all we needed to
do. | |
313 } | |
314 | |
315 RenderObject* insertBefore = (type == RenderStyle::BEFORE) ? children()->fir
stChild() : 0; | |
316 | |
317 // Generated content consists of a single container that houses multiple chi
ldren (specified | |
318 // by the content property). This generated content container gets the pseu
do-element style set on it. | |
319 RenderObject* generatedContentContainer = 0; | |
320 | |
321 // Walk our list of generated content and create render objects for each. | |
322 for (const ContentData* content = pseudoElementStyle->contentData(); content
; content = content->m_next) { | |
323 RenderObject* renderer = 0; | |
324 switch (content->m_type) { | |
325 case CONTENT_NONE: | |
326 break; | |
327 case CONTENT_TEXT: | |
328 renderer = new (renderArena()) RenderTextFragment(document() /*
anonymous object */, content->m_content.m_text); | |
329 renderer->setStyle(pseudoElementStyle); | |
330 break; | |
331 case CONTENT_OBJECT: { | |
332 RenderImageGeneratedContent* image = new (renderArena()) RenderI
mageGeneratedContent(document()); // anonymous object | |
333 RefPtr<RenderStyle> style = RenderStyle::create(); | |
334 style->inheritFrom(pseudoElementStyle); | |
335 image->setStyle(style.release()); | |
336 if (StyleImage* styleImage = content->m_content.m_image) | |
337 image->setStyleImage(styleImage); | |
338 renderer = image; | |
339 break; | |
340 } | |
341 case CONTENT_COUNTER: | |
342 renderer = new (renderArena()) RenderCounter(document(), *conten
t->m_content.m_counter); | |
343 renderer->setStyle(pseudoElementStyle); | |
344 break; | |
345 } | |
346 | |
347 if (renderer) { | |
348 if (!generatedContentContainer) { | |
349 // Make a generated box that might be any display type now that
we are able to drill down into children | |
350 // to find the original content properly. | |
351 generatedContentContainer = RenderObject::createObject(document(
), pseudoElementStyle); | |
352 generatedContentContainer->setStyle(pseudoElementStyle); | |
353 addChild(generatedContentContainer, insertBefore); | |
354 } | |
355 generatedContentContainer->addChild(renderer); | |
356 } | |
357 } | |
358 } | |
359 | |
360 bool RenderContainer::isAfterContent(RenderObject* child) const | |
361 { | |
362 if (!child) | |
363 return false; | |
364 if (child->style()->styleType() != RenderStyle::AFTER) | |
365 return false; | |
366 // Text nodes don't have their own styles, so ignore the style on a text nod
e. | |
367 if (child->isText() && !child->isBR()) | |
368 return false; | |
369 return true; | |
370 } | |
371 | |
372 static void invalidateCountersInContainer(RenderObject* container) | |
373 { | |
374 if (!container) | |
375 return; | |
376 container = findBeforeAfterParent(container); | |
377 if (!container) | |
378 return; | |
379 for (RenderObject* content = container->firstChild(); content; content = con
tent->nextSibling()) { | |
380 if (content->isCounter()) | |
381 static_cast<RenderCounter*>(content)->invalidate(); | |
382 } | |
383 } | |
384 | |
385 void RenderContainer::invalidateCounters() | |
386 { | |
387 if (documentBeingDestroyed()) | |
388 return; | |
389 | |
390 invalidateCountersInContainer(beforeAfterContainer(RenderStyle::BEFORE)); | |
391 invalidateCountersInContainer(beforeAfterContainer(RenderStyle::AFTER)); | |
392 } | |
393 | |
394 void RenderContainer::appendChildNode(RenderObject* newChild, bool fullAppend) | |
395 { | |
396 ASSERT(newChild->parent() == 0); | |
397 ASSERT(!isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableR
ow() && !newChild->isTableCell())); | |
398 | |
399 newChild->setParent(this); | |
400 RenderObject* lChild = children()->lastChild(); | |
401 | |
402 if (lChild) { | |
403 newChild->setPreviousSibling(lChild); | |
404 lChild->setNextSibling(newChild); | |
405 } else | |
406 children()->setFirstChild(newChild); | |
407 | |
408 children()->setLastChild(newChild); | |
409 | |
410 if (fullAppend) { | |
411 // Keep our layer hierarchy updated. Optimize for the common case where
we don't have any children | |
412 // and don't have a layer attached to ourselves. | |
413 RenderLayer* layer = 0; | |
414 if (newChild->firstChild() || newChild->hasLayer()) { | |
415 layer = enclosingLayer(); | |
416 newChild->addLayers(layer, newChild); | |
417 } | |
418 | |
419 // if the new child is visible but this object was not, tell the layer i
t has some visible content | |
420 // that needs to be drawn and layer visibility optimization can't be use
d | |
421 if (style()->visibility() != VISIBLE && newChild->style()->visibility()
== VISIBLE && !newChild->hasLayer()) { | |
422 if (!layer) | |
423 layer = enclosingLayer(); | |
424 if (layer) | |
425 layer->setHasVisibleContent(true); | |
426 } | |
427 | |
428 if (!newChild->isFloatingOrPositioned() && childrenInline()) | |
429 dirtyLinesFromChangedChild(newChild); | |
430 } | |
431 | |
432 newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing blo
ck hierarchy. | |
433 if (!normalChildNeedsLayout()) | |
434 setChildNeedsLayout(true); // We may supply the static position for an a
bsolute positioned child. | |
435 | |
436 if (AXObjectCache::accessibilityEnabled()) | |
437 document()->axObjectCache()->childrenChanged(this); | |
438 } | |
439 | |
440 void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeC
hild, bool fullInsert) | |
441 { | |
442 if (!beforeChild) { | |
443 appendChildNode(child); | |
444 return; | |
445 } | |
446 | |
447 ASSERT(!child->parent()); | |
448 while (beforeChild->parent() != this && beforeChild->parent()->isAnonymousBl
ock()) | |
449 beforeChild = beforeChild->parent(); | |
450 ASSERT(beforeChild->parent() == this); | |
451 | |
452 ASSERT(!isBlockFlow() || (!child->isTableSection() && !child->isTableRow() &
& !child->isTableCell())); | |
453 | |
454 if (beforeChild == children()->firstChild()) | |
455 children()->setFirstChild(child); | |
456 | |
457 RenderObject* prev = beforeChild->previousSibling(); | |
458 child->setNextSibling(beforeChild); | |
459 beforeChild->setPreviousSibling(child); | |
460 if(prev) prev->setNextSibling(child); | |
461 child->setPreviousSibling(prev); | |
462 | |
463 child->setParent(this); | |
464 | |
465 if (fullInsert) { | |
466 // Keep our layer hierarchy updated. Optimize for the common case where
we don't have any children | |
467 // and don't have a layer attached to ourselves. | |
468 RenderLayer* layer = 0; | |
469 if (child->firstChild() || child->hasLayer()) { | |
470 layer = enclosingLayer(); | |
471 child->addLayers(layer, child); | |
472 } | |
473 | |
474 // if the new child is visible but this object was not, tell the layer i
t has some visible content | |
475 // that needs to be drawn and layer visibility optimization can't be use
d | |
476 if (style()->visibility() != VISIBLE && child->style()->visibility() ==
VISIBLE && !child->hasLayer()) { | |
477 if (!layer) | |
478 layer = enclosingLayer(); | |
479 if (layer) | |
480 layer->setHasVisibleContent(true); | |
481 } | |
482 | |
483 | |
484 if (!child->isFloating() && childrenInline()) | |
485 dirtyLinesFromChangedChild(child); | |
486 } | |
487 | |
488 child->setNeedsLayoutAndPrefWidthsRecalc(); | |
489 if (!normalChildNeedsLayout()) | |
490 setChildNeedsLayout(true); // We may supply the static position for an a
bsolute positioned child. | |
491 | |
492 if (AXObjectCache::accessibilityEnabled()) | |
493 document()->axObjectCache()->childrenChanged(this); | |
494 } | |
495 | |
496 VisiblePosition RenderContainer::positionForCoordinates(int xPos, int yPos) | |
497 { | |
498 // no children...return this render object's element, if there is one, and o
ffset 0 | |
499 if (!children()->firstChild()) | |
500 return VisiblePosition(element(), 0, DOWNSTREAM); | |
501 | |
502 if (isTable() && element()) { | |
503 int right = contentWidth() + borderRight() + paddingRight() + borderLeft
() + paddingLeft(); | |
504 int bottom = contentHeight() + borderTop() + paddingTop() + borderBottom
() + paddingBottom(); | |
505 | |
506 if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) { | |
507 if (xPos <= right / 2) | |
508 return VisiblePosition(Position(element(), 0)); | |
509 else | |
510 return VisiblePosition(Position(element(), maxDeepOffset(element
()))); | |
511 } | |
512 } | |
513 | |
514 // Pass off to the closest child. | |
515 int minDist = INT_MAX; | |
516 RenderBox* closestRenderer = 0; | |
517 int newX = xPos; | |
518 int newY = yPos; | |
519 if (isTableRow()) { | |
520 newX += x(); | |
521 newY += y(); | |
522 } | |
523 for (RenderObject* renderObject = children()->firstChild(); renderObject; re
nderObject = renderObject->nextSibling()) { | |
524 if (!renderObject->firstChild() && !renderObject->isInline() && !renderO
bject->isBlockFlow() | |
525 || renderObject->style()->visibility() != VISIBLE) | |
526 continue; | |
527 | |
528 if (!renderObject->isBox()) | |
529 continue; | |
530 | |
531 RenderBox* renderer = toRenderBox(renderObject); | |
532 | |
533 int top = borderTop() + paddingTop() + (isTableRow() ? 0 : renderer->y()
); | |
534 int bottom = top + renderer->contentHeight(); | |
535 int left = borderLeft() + paddingLeft() + (isTableRow() ? 0 : renderer->
x()); | |
536 int right = left + renderer->contentWidth(); | |
537 | |
538 if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) { | |
539 if (renderer->isTableRow()) | |
540 return renderer->positionForCoordinates(xPos + newX - renderer->
x(), yPos + newY - renderer->y()); | |
541 return renderer->positionForCoordinates(xPos - renderer->x(), yPos -
renderer->y()); | |
542 } | |
543 | |
544 // Find the distance from (x, y) to the box. Split the space around the
box into 8 pieces | |
545 // and use a different compare depending on which piece (x, y) is in. | |
546 IntPoint cmp; | |
547 if (xPos > right) { | |
548 if (yPos < top) | |
549 cmp = IntPoint(right, top); | |
550 else if (yPos > bottom) | |
551 cmp = IntPoint(right, bottom); | |
552 else | |
553 cmp = IntPoint(right, yPos); | |
554 } else if (xPos < left) { | |
555 if (yPos < top) | |
556 cmp = IntPoint(left, top); | |
557 else if (yPos > bottom) | |
558 cmp = IntPoint(left, bottom); | |
559 else | |
560 cmp = IntPoint(left, yPos); | |
561 } else { | |
562 if (yPos < top) | |
563 cmp = IntPoint(xPos, top); | |
564 else | |
565 cmp = IntPoint(xPos, bottom); | |
566 } | |
567 | |
568 int x1minusx2 = cmp.x() - xPos; | |
569 int y1minusy2 = cmp.y() - yPos; | |
570 | |
571 int dist = x1minusx2 * x1minusx2 + y1minusy2 * y1minusy2; | |
572 if (dist < minDist) { | |
573 closestRenderer = renderer; | |
574 minDist = dist; | |
575 } | |
576 } | |
577 | |
578 if (closestRenderer) | |
579 return closestRenderer->positionForCoordinates(newX - closestRenderer->x
(), newY - closestRenderer->y()); | |
580 | |
581 return VisiblePosition(element(), 0, DOWNSTREAM); | |
582 } | 116 } |
583 | 117 |
584 void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, un
signed end, bool) | 118 void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, un
signed end, bool) |
585 { | 119 { |
586 if (!children()->firstChild() && (isInline() || isAnonymousBlock())) { | 120 if (!children()->firstChild() && (isInline() || isAnonymousBlock())) { |
587 FloatPoint absPos = localToAbsolute(FloatPoint()); | 121 FloatPoint absPos = localToAbsolute(FloatPoint()); |
588 absoluteRects(rects, absPos.x(), absPos.y()); | 122 absoluteRects(rects, absPos.x(), absPos.y()); |
589 return; | 123 return; |
590 } | 124 } |
591 | 125 |
(...skipping 22 matching lines...) Expand all Loading... |
614 unsigned offset = start; | 148 unsigned offset = start; |
615 for (RenderObject* child = childAt(start); child && offset < end; child = ch
ild->nextSibling(), ++offset) { | 149 for (RenderObject* child = childAt(start); child && offset < end; child = ch
ild->nextSibling(), ++offset) { |
616 if (child->isText() || child->isInline() || child->isAnonymousBlock()) | 150 if (child->isText() || child->isInline() || child->isAnonymousBlock()) |
617 child->absoluteQuads(quads); | 151 child->absoluteQuads(quads); |
618 } | 152 } |
619 } | 153 } |
620 | 154 |
621 #undef DEBUG_LAYOUT | 155 #undef DEBUG_LAYOUT |
622 | 156 |
623 } // namespace WebCore | 157 } // namespace WebCore |
OLD | NEW |