| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 { | 1196 { |
| 1197 m_granularity = CharacterGranularity; | 1197 m_granularity = CharacterGranularity; |
| 1198 | 1198 |
| 1199 m_caretBlinkTimer.stop(); | 1199 m_caretBlinkTimer.stop(); |
| 1200 | 1200 |
| 1201 RenderView* view = m_frame->contentRenderer(); | 1201 RenderView* view = m_frame->contentRenderer(); |
| 1202 if (view) | 1202 if (view) |
| 1203 view->clearSelection(); | 1203 view->clearSelection(); |
| 1204 | 1204 |
| 1205 setSelection(VisibleSelection(), CloseTyping | ClearTypingStyle | DoNotUpdat
eAppearance); | 1205 setSelection(VisibleSelection(), CloseTyping | ClearTypingStyle | DoNotUpdat
eAppearance); |
| 1206 m_previousCaretNode.clear(); | 1206 m_previousCaretPosition.clear(); |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 void FrameSelection::setStart(const VisiblePosition &pos, EUserTriggered trigger
) | 1209 void FrameSelection::setStart(const VisiblePosition &pos, EUserTriggered trigger
) |
| 1210 { | 1210 { |
| 1211 if (m_selection.isBaseFirst()) | 1211 if (m_selection.isBaseFirst()) |
| 1212 setBase(pos, trigger); | 1212 setBase(pos, trigger); |
| 1213 else | 1213 else |
| 1214 setExtent(pos, trigger); | 1214 setExtent(pos, trigger); |
| 1215 } | 1215 } |
| 1216 | 1216 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1241 } | 1241 } |
| 1242 | 1242 |
| 1243 void FrameSelection::setExtent(const Position &pos, EAffinity affinity, EUserTri
ggered userTriggered) | 1243 void FrameSelection::setExtent(const Position &pos, EAffinity affinity, EUserTri
ggered userTriggered) |
| 1244 { | 1244 { |
| 1245 const bool selectionHasDirection = true; | 1245 const bool selectionHasDirection = true; |
| 1246 setSelection(VisibleSelection(m_selection.base(), pos, affinity, selectionHa
sDirection), CloseTyping | ClearTypingStyle | userTriggered); | 1246 setSelection(VisibleSelection(m_selection.base(), pos, affinity, selectionHa
sDirection), CloseTyping | ClearTypingStyle | userTriggered); |
| 1247 } | 1247 } |
| 1248 | 1248 |
| 1249 RenderObject* FrameSelection::caretRenderer() const | 1249 RenderObject* FrameSelection::caretRenderer() const |
| 1250 { | 1250 { |
| 1251 return CaretBase::caretRenderer(m_selection.start().deprecatedNode()); | 1251 return CaretBase::caretRenderer(m_selection.start()); |
| 1252 } | 1252 } |
| 1253 | 1253 |
| 1254 static bool isNonOrphanedCaret(const VisibleSelection& selection) | 1254 static bool isNonOrphanedCaret(const VisibleSelection& selection) |
| 1255 { | 1255 { |
| 1256 return selection.isCaret() && !selection.start().isOrphan() && !selection.en
d().isOrphan(); | 1256 return selection.isCaret() && !selection.start().isOrphan() && !selection.en
d().isOrphan(); |
| 1257 } | 1257 } |
| 1258 | 1258 |
| 1259 LayoutRect FrameSelection::localCaretRect() | 1259 LayoutRect FrameSelection::localCaretRect() |
| 1260 { | 1260 { |
| 1261 if (shouldUpdateCaretRect()) { | 1261 if (shouldUpdateCaretRect()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1285 FrameView* v = m_frame->document()->view(); | 1285 FrameView* v = m_frame->document()->view(); |
| 1286 if (!v) | 1286 if (!v) |
| 1287 return false; | 1287 return false; |
| 1288 | 1288 |
| 1289 LayoutRect oldRect = localCaretRectWithoutUpdate(); | 1289 LayoutRect oldRect = localCaretRectWithoutUpdate(); |
| 1290 LayoutRect newRect = localCaretRect(); | 1290 LayoutRect newRect = localCaretRect(); |
| 1291 if (oldRect == newRect && !m_absCaretBoundsDirty) | 1291 if (oldRect == newRect && !m_absCaretBoundsDirty) |
| 1292 return false; | 1292 return false; |
| 1293 | 1293 |
| 1294 IntRect oldAbsCaretBounds = m_absCaretBounds; | 1294 IntRect oldAbsCaretBounds = m_absCaretBounds; |
| 1295 m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start().deprecated
Node(), localCaretRectWithoutUpdate()); | 1295 m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start(), localCare
tRectWithoutUpdate()); |
| 1296 m_absCaretBoundsDirty = false; | 1296 m_absCaretBoundsDirty = false; |
| 1297 | 1297 |
| 1298 if (oldAbsCaretBounds == m_absCaretBounds) | 1298 if (oldAbsCaretBounds == m_absCaretBounds) |
| 1299 return false; | 1299 return false; |
| 1300 | 1300 |
| 1301 if (RenderView* view = m_frame->document()->renderView()) { | 1301 if (RenderView* view = m_frame->document()->renderView()) { |
| 1302 Node* node = m_selection.start().deprecatedNode(); | 1302 if (m_previousCaretPosition.isNotNull()) |
| 1303 if (m_previousCaretNode) | 1303 repaintCaretForLocalRect(m_previousCaretPosition, oldRect); |
| 1304 repaintCaretForLocalRect(m_previousCaretNode.get(), oldRect); | 1304 m_previousCaretPosition = m_selection.start(); |
| 1305 m_previousCaretNode = node; | |
| 1306 if (shouldRepaintCaret(view, isContentEditable())) | 1305 if (shouldRepaintCaret(view, isContentEditable())) |
| 1307 repaintCaretForLocalRect(node, newRect); | 1306 repaintCaretForLocalRect(m_previousCaretPosition, newRect); |
| 1308 } | 1307 } |
| 1309 | 1308 |
| 1310 return true; | 1309 return true; |
| 1311 } | 1310 } |
| 1312 | 1311 |
| 1313 void FrameSelection::invalidateCaretRect() | 1312 void FrameSelection::invalidateCaretRect() |
| 1314 { | 1313 { |
| 1315 if (!isCaret()) | 1314 if (!isCaret()) |
| 1316 return; | 1315 return; |
| 1317 | 1316 |
| 1318 CaretBase::invalidateCaretRect(m_selection.start().deprecatedNode(), recompu
teCaretRect()); | 1317 CaretBase::invalidateCaretRect(m_selection.start(), recomputeCaretRect()); |
| 1319 } | 1318 } |
| 1320 | 1319 |
| 1321 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai
ntOffset, const LayoutRect& clipRect) | 1320 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai
ntOffset, const LayoutRect& clipRect) |
| 1322 { | 1321 { |
| 1323 if (m_selection.isCaret() && m_caretPaint) | 1322 if (m_selection.isCaret() && m_caretPaint) |
| 1324 CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, pai
ntOffset, clipRect); | 1323 CaretBase::paintCaret(m_selection.start(), context, paintOffset, clipRec
t); |
| 1325 } | 1324 } |
| 1326 | 1325 |
| 1327 void FrameSelection::debugRenderer(RenderObject *r, bool selected) const | 1326 void FrameSelection::debugRenderer(RenderObject *r, bool selected) const |
| 1328 { | 1327 { |
| 1329 if (r->node()->isElementNode()) { | 1328 if (r->node()->isElementNode()) { |
| 1330 Element* element = toElement(r->node()); | 1329 Element* element = toElement(r->node()); |
| 1331 fprintf(stderr, "%s%s\n", selected ? "==> " : " ", element->localName
().string().utf8().data()); | 1330 fprintf(stderr, "%s%s\n", selected ? "==> " : " ", element->localName
().string().utf8().data()); |
| 1332 } else if (r->isText()) { | 1331 } else if (r->isText()) { |
| 1333 RenderText* textRenderer = toRenderText(r); | 1332 RenderText* textRenderer = toRenderText(r); |
| 1334 if (!textRenderer->textLength() || !textRenderer->firstTextBox()) { | 1333 if (!textRenderer->textLength() || !textRenderer->firstTextBox()) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 | 1394 |
| 1396 // Treat a collapsed selection like no selection. | 1395 // Treat a collapsed selection like no selection. |
| 1397 if (!isRange()) | 1396 if (!isRange()) |
| 1398 return false; | 1397 return false; |
| 1399 if (!document->renderer()) | 1398 if (!document->renderer()) |
| 1400 return false; | 1399 return false; |
| 1401 | 1400 |
| 1402 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H
itTestRequest::DisallowShadowContent); | 1401 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H
itTestRequest::DisallowShadowContent); |
| 1403 HitTestResult result(point); | 1402 HitTestResult result(point); |
| 1404 document->renderView()->hitTest(request, result); | 1403 document->renderView()->hitTest(request, result); |
| 1405 Node* innerNode = result.innerNode(); | 1404 RenderObject* renderer = result.renderer(); |
| 1406 if (!innerNode || !innerNode->renderer()) | 1405 if (!renderer) |
| 1407 return false; | 1406 return false; |
| 1408 | 1407 |
| 1409 VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(result.lo
calPoint())); | 1408 VisiblePosition visiblePos(renderer->positionForPoint(result.localPoint())); |
| 1410 if (visiblePos.isNull()) | 1409 if (visiblePos.isNull()) |
| 1411 return false; | 1410 return false; |
| 1412 | 1411 |
| 1413 if (m_selection.visibleStart().isNull() || m_selection.visibleEnd().isNull()
) | 1412 if (m_selection.visibleStart().isNull() || m_selection.visibleEnd().isNull()
) |
| 1414 return false; | 1413 return false; |
| 1415 | 1414 |
| 1416 Position start(m_selection.visibleStart().deepEquivalent()); | 1415 Position start(m_selection.visibleStart().deepEquivalent()); |
| 1417 Position end(m_selection.visibleEnd().deepEquivalent()); | 1416 Position end(m_selection.visibleEnd().deepEquivalent()); |
| 1418 Position p(visiblePos.deepEquivalent()); | 1417 Position p(visiblePos.deepEquivalent()); |
| 1419 | 1418 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 Position candidate = startPos.downstream(); | 1677 Position candidate = startPos.downstream(); |
| 1679 if (candidate.isCandidate()) | 1678 if (candidate.isCandidate()) |
| 1680 startPos = candidate; | 1679 startPos = candidate; |
| 1681 Position endPos = selection.end(); | 1680 Position endPos = selection.end(); |
| 1682 candidate = endPos.upstream(); | 1681 candidate = endPos.upstream(); |
| 1683 if (candidate.isCandidate()) | 1682 if (candidate.isCandidate()) |
| 1684 endPos = candidate; | 1683 endPos = candidate; |
| 1685 | 1684 |
| 1686 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted | 1685 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted |
| 1687 // because we don't yet notify the FrameSelection of text removal. | 1686 // because we don't yet notify the FrameSelection of text removal. |
| 1688 if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() !
= selection.visibleEnd()) { | 1687 if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() !
= selection.visibleEnd()) |
| 1689 RenderObject* startRenderer = startPos.deprecatedNode()->renderer(); | 1688 view->setSelection(startPos.rendererOfAnchorNode(), startPos.deprecatedO
ffsetInRendererOfAnchorNode(), endPos.rendererOfAnchorNode(), endPos.deprecatedO
ffsetInRendererOfAnchorNode()); |
| 1690 RenderObject* endRenderer = endPos.deprecatedNode()->renderer(); | |
| 1691 view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), en
dRenderer, endPos.deprecatedEditingOffset()); | |
| 1692 } | |
| 1693 } | 1689 } |
| 1694 | 1690 |
| 1695 void FrameSelection::setCaretVisibility(CaretVisibility visibility) | 1691 void FrameSelection::setCaretVisibility(CaretVisibility visibility) |
| 1696 { | 1692 { |
| 1697 if (caretVisibility() == visibility) | 1693 if (caretVisibility() == visibility) |
| 1698 return; | 1694 return; |
| 1699 | 1695 |
| 1700 m_frame->document()->updateLayoutIgnorePendingStylesheets(); | 1696 m_frame->document()->updateLayoutIgnorePendingStylesheets(); |
| 1701 if (m_caretPaint) { | 1697 if (m_caretPaint) { |
| 1702 m_caretPaint = false; | 1698 m_caretPaint = false; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 case VisibleSelection::CaretSelection: | 1897 case VisibleSelection::CaretSelection: |
| 1902 rect = absoluteCaretBounds(); | 1898 rect = absoluteCaretBounds(); |
| 1903 break; | 1899 break; |
| 1904 case VisibleSelection::RangeSelection: | 1900 case VisibleSelection::RangeSelection: |
| 1905 rect = revealExtentOption == RevealExtent ? VisiblePosition(extent()).ab
soluteCaretBounds() : enclosingIntRect(bounds(false)); | 1901 rect = revealExtentOption == RevealExtent ? VisiblePosition(extent()).ab
soluteCaretBounds() : enclosingIntRect(bounds(false)); |
| 1906 break; | 1902 break; |
| 1907 } | 1903 } |
| 1908 | 1904 |
| 1909 Position start = this->start(); | 1905 Position start = this->start(); |
| 1910 ASSERT(start.deprecatedNode()); | 1906 ASSERT(start.deprecatedNode()); |
| 1911 if (start.deprecatedNode() && start.deprecatedNode()->renderer()) { | 1907 if (start.rendererOfAnchorNode()) { |
| 1912 // FIXME: This code only handles scrolling the startContainer's layer, b
ut | 1908 // FIXME: This code only handles scrolling the startContainer's layer, b
ut |
| 1913 // the selection rect could intersect more than just that. | 1909 // the selection rect could intersect more than just that. |
| 1914 // See <rdar://problem/4799899>. | 1910 // See <rdar://problem/4799899>. |
| 1915 if (start.deprecatedNode()->renderer()->scrollRectToVisible(rect, alignm
ent, alignment)) | 1911 if (start.rendererOfAnchorNode()->scrollRectToVisible(rect, alignment, a
lignment)) |
| 1916 updateAppearance(); | 1912 updateAppearance(); |
| 1917 } | 1913 } |
| 1918 } | 1914 } |
| 1919 | 1915 |
| 1920 void FrameSelection::setSelectionFromNone() | 1916 void FrameSelection::setSelectionFromNone() |
| 1921 { | 1917 { |
| 1922 // Put a caret inside the body if the entire frame is editable (either the | 1918 // Put a caret inside the body if the entire frame is editable (either the |
| 1923 // entire WebView is editable or designMode is on for this document). | 1919 // entire WebView is editable or designMode is on for this document). |
| 1924 | 1920 |
| 1925 Document* document = m_frame->document(); | 1921 Document* document = m_frame->document(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1986 sel.showTreeForThis(); | 1982 sel.showTreeForThis(); |
| 1987 } | 1983 } |
| 1988 | 1984 |
| 1989 void showTree(const WebCore::FrameSelection* sel) | 1985 void showTree(const WebCore::FrameSelection* sel) |
| 1990 { | 1986 { |
| 1991 if (sel) | 1987 if (sel) |
| 1992 sel->showTreeForThis(); | 1988 sel->showTreeForThis(); |
| 1993 } | 1989 } |
| 1994 | 1990 |
| 1995 #endif | 1991 #endif |
| OLD | NEW |