| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 332 |
| 333 Element* rootEditableElementOf(const Position& p, EditableType editableType) | 333 Element* rootEditableElementOf(const Position& p, EditableType editableType) |
| 334 { | 334 { |
| 335 Node* node = p.computeContainerNode(); | 335 Node* node = p.computeContainerNode(); |
| 336 if (!node) | 336 if (!node) |
| 337 return 0; | 337 return 0; |
| 338 | 338 |
| 339 if (isDisplayInsideTable(node)) | 339 if (isDisplayInsideTable(node)) |
| 340 node = node->parentNode(); | 340 node = node->parentNode(); |
| 341 | 341 |
| 342 return node->rootEditableElement(editableType); | 342 return rootEditableElement(*node, editableType); |
| 343 } | 343 } |
| 344 | 344 |
| 345 Element* rootEditableElementOf(const PositionInFlatTree& p, EditableType editabl
eType) | 345 Element* rootEditableElementOf(const PositionInFlatTree& p, EditableType editabl
eType) |
| 346 { | 346 { |
| 347 return rootEditableElementOf(toPositionInDOMTree(p), editableType); | 347 return rootEditableElementOf(toPositionInDOMTree(p), editableType); |
| 348 } | 348 } |
| 349 | 349 |
| 350 // TODO(yosin) This does not handle [table, 0] correctly. | 350 // TODO(yosin) This does not handle [table, 0] correctly. |
| 351 Element* rootEditableElementOf(const VisiblePosition& visiblePosition) | 351 Element* rootEditableElementOf(const VisiblePosition& visiblePosition) |
| 352 { | 352 { |
| 353 Node* anchorNode = visiblePosition.deepEquivalent().anchorNode(); | 353 Node* anchorNode = visiblePosition.deepEquivalent().anchorNode(); |
| 354 return anchorNode ? anchorNode->rootEditableElement() : nullptr; | 354 return anchorNode ? rootEditableElement(*anchorNode) : nullptr; |
| 355 } | 355 } |
| 356 | 356 |
| 357 // Finds the enclosing element until which the tree can be split. | 357 // Finds the enclosing element until which the tree can be split. |
| 358 // When a user hits ENTER, they won't expect this element to be split into two. | 358 // When a user hits ENTER, they won't expect this element to be split into two. |
| 359 // You may pass it as the second argument of splitTreeToNode. | 359 // You may pass it as the second argument of splitTreeToNode. |
| 360 Element* unsplittableElementForPosition(const Position& p) | 360 Element* unsplittableElementForPosition(const Position& p) |
| 361 { | 361 { |
| 362 // Since enclosingNodeOfType won't search beyond the highest root editable n
ode, | 362 // Since enclosingNodeOfType won't search beyond the highest root editable n
ode, |
| 363 // this code works even if the closest table cell was outside of the root ed
itable node. | 363 // this code works even if the closest table cell was outside of the root ed
itable node. |
| 364 Element* enclosingCell = toElement(enclosingNodeOfType(p, &isTableCell)); | 364 Element* enclosingCell = toElement(enclosingNodeOfType(p, &isTableCell)); |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 return true; | 906 return true; |
| 907 | 907 |
| 908 if (layoutObject->style()->isFloating()) | 908 if (layoutObject->style()->isFloating()) |
| 909 return true; | 909 return true; |
| 910 | 910 |
| 911 return false; | 911 return false; |
| 912 } | 912 } |
| 913 | 913 |
| 914 static HTMLElement* firstInSpecialElement(const Position& pos) | 914 static HTMLElement* firstInSpecialElement(const Position& pos) |
| 915 { | 915 { |
| 916 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); | 916 Element* element = rootEditableElement(*pos.computeContainerNode()); |
| 917 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*pos.anchorNode()))
{ | 917 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*pos.anchorNode()))
{ |
| 918 if (runner.rootEditableElement() != rootEditableElement) | 918 if (rootEditableElement(runner) != element) |
| 919 break; | 919 break; |
| 920 if (isSpecialHTMLElement(runner)) { | 920 if (isSpecialHTMLElement(runner)) { |
| 921 HTMLElement* specialElement = toHTMLElement(&runner); | 921 HTMLElement* specialElement = toHTMLElement(&runner); |
| 922 VisiblePosition vPos = createVisiblePosition(pos); | 922 VisiblePosition vPos = createVisiblePosition(pos); |
| 923 VisiblePosition firstInElement = createVisiblePosition(firstPosition
InOrBeforeNode(specialElement)); | 923 VisiblePosition firstInElement = createVisiblePosition(firstPosition
InOrBeforeNode(specialElement)); |
| 924 if (isDisplayInsideTable(specialElement) && vPos.deepEquivalent() ==
nextPositionOf(firstInElement).deepEquivalent()) | 924 if (isDisplayInsideTable(specialElement) && vPos.deepEquivalent() ==
nextPositionOf(firstInElement).deepEquivalent()) |
| 925 return specialElement; | 925 return specialElement; |
| 926 if (vPos.deepEquivalent() == firstInElement.deepEquivalent()) | 926 if (vPos.deepEquivalent() == firstInElement.deepEquivalent()) |
| 927 return specialElement; | 927 return specialElement; |
| 928 } | 928 } |
| 929 } | 929 } |
| 930 return 0; | 930 return 0; |
| 931 } | 931 } |
| 932 | 932 |
| 933 static HTMLElement* lastInSpecialElement(const Position& pos) | 933 static HTMLElement* lastInSpecialElement(const Position& pos) |
| 934 { | 934 { |
| 935 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); | 935 Element* element = rootEditableElement(*pos.computeContainerNode()); |
| 936 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*pos.anchorNode()))
{ | 936 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*pos.anchorNode()))
{ |
| 937 if (runner.rootEditableElement() != rootEditableElement) | 937 if (rootEditableElement(runner) != element) |
| 938 break; | 938 break; |
| 939 if (isSpecialHTMLElement(runner)) { | 939 if (isSpecialHTMLElement(runner)) { |
| 940 HTMLElement* specialElement = toHTMLElement(&runner); | 940 HTMLElement* specialElement = toHTMLElement(&runner); |
| 941 VisiblePosition vPos = createVisiblePosition(pos); | 941 VisiblePosition vPos = createVisiblePosition(pos); |
| 942 VisiblePosition lastInElement = createVisiblePosition(lastPositionIn
OrAfterNode(specialElement)); | 942 VisiblePosition lastInElement = createVisiblePosition(lastPositionIn
OrAfterNode(specialElement)); |
| 943 if (isDisplayInsideTable(specialElement) && vPos.deepEquivalent() ==
previousPositionOf(lastInElement).deepEquivalent()) | 943 if (isDisplayInsideTable(specialElement) && vPos.deepEquivalent() ==
previousPositionOf(lastInElement).deepEquivalent()) |
| 944 return specialElement; | 944 return specialElement; |
| 945 if (vPos.deepEquivalent() == lastInElement.deepEquivalent()) | 945 if (vPos.deepEquivalent() == lastInElement.deepEquivalent()) |
| 946 return specialElement; | 946 return specialElement; |
| 947 } | 947 } |
| 948 } | 948 } |
| 949 return 0; | 949 return 0; |
| 950 } | 950 } |
| 951 | 951 |
| 952 Position positionBeforeContainingSpecialElement(const Position& pos, HTMLElement
** containingSpecialElement) | 952 Position positionBeforeContainingSpecialElement(const Position& pos, HTMLElement
** containingSpecialElement) |
| 953 { | 953 { |
| 954 HTMLElement* n = firstInSpecialElement(pos); | 954 HTMLElement* n = firstInSpecialElement(pos); |
| 955 if (!n) | 955 if (!n) |
| 956 return pos; | 956 return pos; |
| 957 Position result = Position::inParentBeforeNode(*n); | 957 Position result = Position::inParentBeforeNode(*n); |
| 958 if (result.isNull() || result.anchorNode()->rootEditableElement() != pos.anc
horNode()->rootEditableElement()) | 958 if (result.isNull() || rootEditableElement(*result.anchorNode()) != rootEdit
ableElement(*pos.anchorNode())) |
| 959 return pos; | 959 return pos; |
| 960 if (containingSpecialElement) | 960 if (containingSpecialElement) |
| 961 *containingSpecialElement = n; | 961 *containingSpecialElement = n; |
| 962 return result; | 962 return result; |
| 963 } | 963 } |
| 964 | 964 |
| 965 Position positionAfterContainingSpecialElement(const Position& pos, HTMLElement*
* containingSpecialElement) | 965 Position positionAfterContainingSpecialElement(const Position& pos, HTMLElement*
* containingSpecialElement) |
| 966 { | 966 { |
| 967 HTMLElement* n = lastInSpecialElement(pos); | 967 HTMLElement* n = lastInSpecialElement(pos); |
| 968 if (!n) | 968 if (!n) |
| 969 return pos; | 969 return pos; |
| 970 Position result = Position::inParentAfterNode(*n); | 970 Position result = Position::inParentAfterNode(*n); |
| 971 if (result.isNull() || result.anchorNode()->rootEditableElement() != pos.anc
horNode()->rootEditableElement()) | 971 if (result.isNull() || rootEditableElement(*result.anchorNode()) != rootEdit
ableElement(*pos.anchorNode())) |
| 972 return pos; | 972 return pos; |
| 973 if (containingSpecialElement) | 973 if (containingSpecialElement) |
| 974 *containingSpecialElement = n; | 974 *containingSpecialElement = n; |
| 975 return result; | 975 return result; |
| 976 } | 976 } |
| 977 | 977 |
| 978 template <typename Strategy> | 978 template <typename Strategy> |
| 979 static Element* tableElementJustBeforeAlgorithm(const VisiblePositionTemplate<St
rategy>& visiblePosition) | 979 static Element* tableElementJustBeforeAlgorithm(const VisiblePositionTemplate<St
rategy>& visiblePosition) |
| 980 { | 980 { |
| 981 const PositionTemplate<Strategy> upstream(mostBackwardCaretPosition(visibleP
osition.deepEquivalent())); | 981 const PositionTemplate<Strategy> upstream(mostBackwardCaretPosition(visibleP
osition.deepEquivalent())); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 if (n->layoutObject()) | 1168 if (n->layoutObject()) |
| 1169 return true; | 1169 return true; |
| 1170 n = NodeTraversal::next(*n, node); | 1170 n = NodeTraversal::next(*n, node); |
| 1171 } | 1171 } |
| 1172 return false; | 1172 return false; |
| 1173 } | 1173 } |
| 1174 | 1174 |
| 1175 Node* highestNodeToRemoveInPruning(Node* node, Node* excludeNode) | 1175 Node* highestNodeToRemoveInPruning(Node* node, Node* excludeNode) |
| 1176 { | 1176 { |
| 1177 Node* previousNode = nullptr; | 1177 Node* previousNode = nullptr; |
| 1178 Element* rootEditableElement = node ? node->rootEditableElement() : nullptr; | 1178 Element* element = node ? rootEditableElement(*node) : nullptr; |
| 1179 for (; node; node = node->parentNode()) { | 1179 for (; node; node = node->parentNode()) { |
| 1180 if (LayoutObject* layoutObject = node->layoutObject()) { | 1180 if (LayoutObject* layoutObject = node->layoutObject()) { |
| 1181 if (!layoutObject->canHaveChildren() || hasARenderedDescendant(node,
previousNode) || rootEditableElement == node || excludeNode == node) | 1181 if (!layoutObject->canHaveChildren() || hasARenderedDescendant(node,
previousNode) || element == node || excludeNode == node) |
| 1182 return previousNode; | 1182 return previousNode; |
| 1183 } | 1183 } |
| 1184 previousNode = node; | 1184 previousNode = node; |
| 1185 } | 1185 } |
| 1186 return 0; | 1186 return 0; |
| 1187 } | 1187 } |
| 1188 | 1188 |
| 1189 Element* enclosingTableCell(const Position& p) | 1189 Element* enclosingTableCell(const Position& p) |
| 1190 { | 1190 { |
| 1191 return toElement(enclosingNodeOfType(p, isTableCell)); | 1191 return toElement(enclosingNodeOfType(p, isTableCell)); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 return createVisiblePosition(first).deepEquivalent() == createVisiblePositio
n(mostBackwardCaretPosition(second)).deepEquivalent(); | 1278 return createVisiblePosition(first).deepEquivalent() == createVisiblePositio
n(mostBackwardCaretPosition(second)).deepEquivalent(); |
| 1279 } | 1279 } |
| 1280 | 1280 |
| 1281 bool canMergeLists(Element* firstList, Element* secondList) | 1281 bool canMergeLists(Element* firstList, Element* secondList) |
| 1282 { | 1282 { |
| 1283 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList-
>isHTMLElement()) | 1283 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList-
>isHTMLElement()) |
| 1284 return false; | 1284 return false; |
| 1285 | 1285 |
| 1286 return firstList->hasTagName(secondList->tagQName()) // make sure the list t
ypes match (ol vs. ul) | 1286 return firstList->hasTagName(secondList->tagQName()) // make sure the list t
ypes match (ol vs. ul) |
| 1287 && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both l
ists are editable | 1287 && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both l
ists are editable |
| 1288 && firstList->rootEditableElement() == secondList->rootEditableElement() //
don't cross editing boundaries | 1288 && rootEditableElement(*firstList) == rootEditableElement(*secondList) // do
n't cross editing boundaries |
| 1289 && isVisiblyAdjacent(Position::inParentAfterNode(*firstList), Position::inPa
rentBeforeNode(*secondList)); | 1289 && isVisiblyAdjacent(Position::inParentAfterNode(*firstList), Position::inPa
rentBeforeNode(*secondList)); |
| 1290 // Make sure there is no visible content between this li and the previous li
st | 1290 // Make sure there is no visible content between this li and the previous li
st |
| 1291 } | 1291 } |
| 1292 | 1292 |
| 1293 bool isDisplayInsideTable(const Node* node) | 1293 bool isDisplayInsideTable(const Node* node) |
| 1294 { | 1294 { |
| 1295 if (!node || !node->isElementNode()) | 1295 if (!node || !node->isElementNode()) |
| 1296 return false; | 1296 return false; |
| 1297 | 1297 |
| 1298 LayoutObject* layoutObject = node->layoutObject(); | 1298 LayoutObject* layoutObject = node->layoutObject(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 | 1409 |
| 1410 return layoutObject->style()->visibility() == VISIBLE; | 1410 return layoutObject->style()->visibility() == VISIBLE; |
| 1411 } | 1411 } |
| 1412 | 1412 |
| 1413 // return first preceding DOM position rendered at a different location, or "thi
s" | 1413 // return first preceding DOM position rendered at a different location, or "thi
s" |
| 1414 static Position previousCharacterPosition(const Position& position, TextAffinity
affinity) | 1414 static Position previousCharacterPosition(const Position& position, TextAffinity
affinity) |
| 1415 { | 1415 { |
| 1416 if (position.isNull()) | 1416 if (position.isNull()) |
| 1417 return Position(); | 1417 return Position(); |
| 1418 | 1418 |
| 1419 Element* fromRootEditableElement = position.anchorNode()->rootEditableElemen
t(); | 1419 Element* fromRootEditableElement = rootEditableElement(*position.anchorNode(
)); |
| 1420 | 1420 |
| 1421 bool atStartOfLine = isStartOfLine(createVisiblePosition(position, affinity)
); | 1421 bool atStartOfLine = isStartOfLine(createVisiblePosition(position, affinity)
); |
| 1422 bool rendered = isVisuallyEquivalentCandidate(position); | 1422 bool rendered = isVisuallyEquivalentCandidate(position); |
| 1423 | 1423 |
| 1424 Position currentPos = position; | 1424 Position currentPos = position; |
| 1425 while (!currentPos.atStartOfTree()) { | 1425 while (!currentPos.atStartOfTree()) { |
| 1426 // TODO(yosin) When we use |previousCharacterPosition()| other than | 1426 // TODO(yosin) When we use |previousCharacterPosition()| other than |
| 1427 // finding leading whitespace, we should use |Character| instead of | 1427 // finding leading whitespace, we should use |Character| instead of |
| 1428 // |CodePoint|. | 1428 // |CodePoint|. |
| 1429 currentPos = previousPositionOf(currentPos, PositionMoveType::CodeUnit); | 1429 currentPos = previousPositionOf(currentPos, PositionMoveType::CodeUnit); |
| 1430 | 1430 |
| 1431 if (currentPos.anchorNode()->rootEditableElement() != fromRootEditableEl
ement) | 1431 if (rootEditableElement(*currentPos.anchorNode()) != fromRootEditableEle
ment) |
| 1432 return position; | 1432 return position; |
| 1433 | 1433 |
| 1434 if (atStartOfLine || !rendered) { | 1434 if (atStartOfLine || !rendered) { |
| 1435 if (isVisuallyEquivalentCandidate(currentPos)) | 1435 if (isVisuallyEquivalentCandidate(currentPos)) |
| 1436 return currentPos; | 1436 return currentPos; |
| 1437 } else if (rendersInDifferentPosition(position, currentPos)) { | 1437 } else if (rendersInDifferentPosition(position, currentPos)) { |
| 1438 return currentPos; | 1438 return currentPos; |
| 1439 } | 1439 } |
| 1440 } | 1440 } |
| 1441 | 1441 |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1812 { | 1812 { |
| 1813 if (!RuntimeEnabledFeatures::inputEventEnabled()) | 1813 if (!RuntimeEnabledFeatures::inputEventEnabled()) |
| 1814 return DispatchEventResult::NotCanceled; | 1814 return DispatchEventResult::NotCanceled; |
| 1815 if (!target) | 1815 if (!target) |
| 1816 return DispatchEventResult::NotCanceled; | 1816 return DispatchEventResult::NotCanceled; |
| 1817 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data
, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo
mposing, ranges); | 1817 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data
, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo
mposing, ranges); |
| 1818 return target->dispatchEvent(beforeInputEvent); | 1818 return target->dispatchEvent(beforeInputEvent); |
| 1819 } | 1819 } |
| 1820 | 1820 |
| 1821 } // namespace blink | 1821 } // namespace blink |
| OLD | NEW |