VisiblePosition RenderReplaced::positionForCoordinates(int x, int y) { InlineBox* box = inlineBoxWrapper(); if (!box) return VisiblePosition(element(), 0, DOWNSTREAM); // FIXME: This code is buggy if the replaced element is relative positioned. RootInlineBox* root = box->root(); int top = root->topOverflow(); int bottom = root->nextRootBox() ? root->nextRootBox()->topOverflow() : root->bottomOverflow(); if (y + yPos() < top) return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM); // coordinates are above if (y + yPos() >= bottom) return VisiblePosition(element(), caretMaxOffset(), DOWNSTREAM); // coordinates are below if (element()) { if (x <= width() / 2) return VisiblePosition(element(), 0, DOWNSTREAM); return VisiblePosition(element(), 1, DOWNSTREAM); } return RenderBox::positionForCoordinates(x, y); }
VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point) { InlineBox* box = inlineBoxWrapper(); if (!box) return createVisiblePosition(0, DOWNSTREAM); // FIXME: This code is buggy if the replaced element is relative positioned. RootInlineBox* root = box->root(); int top = root->topOverflow(); int bottom = root->nextRootBox() ? root->nextRootBox()->topOverflow() : root->bottomOverflow(); if (point.y() + y() < top) return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above if (point.y() + y() >= bottom) return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below if (node()) { if (point.x() <= width() / 2) return createVisiblePosition(0, DOWNSTREAM); return createVisiblePosition(1, DOWNSTREAM); } return RenderBox::positionForPoint(point); }
VisiblePosition RenderReplaced::positionForCoordinates(int _x, int _y) { InlineBox *box = inlineBoxWrapper(); if (!box) return VisiblePosition(element(), 0, DOWNSTREAM); RootInlineBox *root = box->root(); int absx, absy; containingBlock()->absolutePosition(absx, absy); int top = absy + root->topOverflow(); int bottom = root->nextRootBox() ? absy + root->nextRootBox()->topOverflow() : absy + root->bottomOverflow(); if (_y < top) return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM); // coordinates are above if (_y >= bottom) return VisiblePosition(element(), caretMaxOffset(), DOWNSTREAM); // coordinates are below if (element()) { if (_x <= absx + xPos() + (width() / 2)) return VisiblePosition(element(), 0, DOWNSTREAM); return VisiblePosition(element(), 1, DOWNSTREAM); } return RenderBox::positionForCoordinates(_x, _y); }
VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x) { Position p = visiblePosition.deepEquivalent(); Node *node = p.node(); Node* highestRoot = highestEditableRoot(p); if (!node) return VisiblePosition(); node->document()->updateLayoutIgnorePendingStylesheets(); RenderObject *renderer = node->renderer(); if (!renderer) return VisiblePosition(); RenderBlock *containingBlock = 0; RootInlineBox *root = 0; InlineBox* box; int ignoredCaretOffset; visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); if (box) { root = box->root()->nextRootBox(); if (root) containingBlock = renderer->containingBlock(); } if (!root) { // This containing editable block does not have a next line. // Need to move forward to next containing editable block in this root editable // block and find the first root line box in that block. Node* startBlock = enclosingBlock(node); Node* n = nextLeafWithSameEditability(node, p.offset()); while (n && startBlock == enclosingBlock(n)) n = nextLeafWithSameEditability(n); while (n) { if (highestEditableRoot(Position(n, 0)) != highestRoot) break; Position pos(n, caretMinOffset(n)); if (pos.isCandidate()) { ASSERT(n->renderer()); pos.getInlineBoxAndOffset(DOWNSTREAM, box, ignoredCaretOffset); if (box) { // next root line box found root = box->root(); containingBlock = n->renderer()->containingBlock(); break; } return VisiblePosition(pos, DOWNSTREAM); } n = nextLeafWithSameEditability(n); } } if (root) { // FIXME: Can be wrong for multi-column layout. int absx, absy; containingBlock->absolutePositionForContent(absx, absy); if (containingBlock->hasOverflowClip()) containingBlock->layer()->subtractScrollOffset(absx, absy); RenderObject *renderer = root->closestLeafChildForXPos(x - absx, isEditablePosition(p))->object(); Node* node = renderer->element(); if (editingIgnoresContent(node)) return Position(node->parent(), node->nodeIndex()); return renderer->positionForCoordinates(x - absx, root->topOverflow()); } // Could not find a next line. This means we must already be on the last line. // Move to the end of the content in this block, which effectively moves us // to the end of the line we're on. Element* rootElement = node->isContentEditable() ? node->rootEditableElement() : node->document()->documentElement(); return VisiblePosition(rootElement, rootElement ? rootElement->childNodeCount() : 0, DOWNSTREAM); }