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

Side by Side Diff: third_party/WebKit/Source/core/editing/EditingUtilities.cpp

Issue 2089993003: Get rid of EUpdateStyle parameter from isEditablePosition() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 2016-06-27T14:42:23 Created 4 years, 5 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) 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 26 matching lines...) Expand all
37 #include "core/editing/PlainTextRange.h" 37 #include "core/editing/PlainTextRange.h"
38 #include "core/editing/PositionIterator.h" 38 #include "core/editing/PositionIterator.h"
39 #include "core/editing/VisiblePosition.h" 39 #include "core/editing/VisiblePosition.h"
40 #include "core/editing/VisibleSelection.h" 40 #include "core/editing/VisibleSelection.h"
41 #include "core/editing/VisibleUnits.h" 41 #include "core/editing/VisibleUnits.h"
42 #include "core/editing/iterators/TextIterator.h" 42 #include "core/editing/iterators/TextIterator.h"
43 #include "core/editing/serializers/HTMLInterchange.h" 43 #include "core/editing/serializers/HTMLInterchange.h"
44 #include "core/editing/state_machines/BackspaceStateMachine.h" 44 #include "core/editing/state_machines/BackspaceStateMachine.h"
45 #include "core/editing/state_machines/BackwardGraphemeBoundaryStateMachine.h" 45 #include "core/editing/state_machines/BackwardGraphemeBoundaryStateMachine.h"
46 #include "core/editing/state_machines/ForwardGraphemeBoundaryStateMachine.h" 46 #include "core/editing/state_machines/ForwardGraphemeBoundaryStateMachine.h"
47 #include "core/frame/FrameView.h"
47 #include "core/frame/LocalFrame.h" 48 #include "core/frame/LocalFrame.h"
48 #include "core/frame/UseCounter.h" 49 #include "core/frame/UseCounter.h"
49 #include "core/html/HTMLBRElement.h" 50 #include "core/html/HTMLBRElement.h"
50 #include "core/html/HTMLDivElement.h" 51 #include "core/html/HTMLDivElement.h"
51 #include "core/html/HTMLLIElement.h" 52 #include "core/html/HTMLLIElement.h"
52 #include "core/html/HTMLParagraphElement.h" 53 #include "core/html/HTMLParagraphElement.h"
53 #include "core/html/HTMLSpanElement.h" 54 #include "core/html/HTMLSpanElement.h"
54 #include "core/html/HTMLTableCellElement.h" 55 #include "core/html/HTMLTableCellElement.h"
55 #include "core/html/HTMLUListElement.h" 56 #include "core/html/HTMLUListElement.h"
56 #include "core/layout/LayoutObject.h" 57 #include "core/layout/LayoutObject.h"
57 #include "core/layout/LayoutTableCell.h" 58 #include "core/layout/LayoutTableCell.h"
58 #include "wtf/Assertions.h" 59 #include "wtf/Assertions.h"
59 #include "wtf/StdLibExtras.h" 60 #include "wtf/StdLibExtras.h"
60 #include "wtf/text/StringBuilder.h" 61 #include "wtf/text/StringBuilder.h"
61 #include "wtf/text/Unicode.h" 62 #include "wtf/text/Unicode.h"
62 63
63 namespace blink { 64 namespace blink {
64 65
65 using namespace HTMLNames; 66 using namespace HTMLNames;
66 67
67 namespace { 68 namespace {
69
68 std::ostream& operator<<(std::ostream& os, PositionMoveType type) 70 std::ostream& operator<<(std::ostream& os, PositionMoveType type)
69 { 71 {
70 static const char* const texts[] = { 72 static const char* const texts[] = {
71 "CodeUnit", "BackwardDeletion", "GraphemeCluster" 73 "CodeUnit", "BackwardDeletion", "GraphemeCluster"
72 }; 74 };
73 const auto& it = std::begin(texts) + static_cast<size_t>(type); 75 const auto& it = std::begin(texts) + static_cast<size_t>(type);
74 DCHECK_GE(it, std::begin(texts)) << "Unknown PositionMoveType value"; 76 DCHECK_GE(it, std::begin(texts)) << "Unknown PositionMoveType value";
75 DCHECK_LT(it, std::end(texts)) << "Unknown PositionMoveType value"; 77 DCHECK_LT(it, std::end(texts)) << "Unknown PositionMoveType value";
76 return os << *it; 78 return os << *it;
77 } 79 }
80
78 } // namespace 81 } // namespace
79 82
83 bool needsLayoutTreeUpdate(const Node& node)
84 {
85 const Document& document = node.document();
86 if (document.needsLayoutTreeUpdate())
87 return true;
88 // TODO(yosin): We should make |document::needsLayoutTreeUpdate()| to
89 // check |LayoutView::needsLayout()|.
90 return document.view() && document.view()->needsLayout();
91 }
92
93 bool needsLayoutTreeUpdate(const Position& position)
94 {
95 const Node* node = position.anchorNode();
96 if (!node)
97 return false;
98 return needsLayoutTreeUpdate(*node);
99 }
100
80 // Atomic means that the node has no children, or has children which are ignored for the 101 // Atomic means that the node has no children, or has children which are ignored for the
81 // purposes of editing. 102 // purposes of editing.
82 bool isAtomicNode(const Node *node) 103 bool isAtomicNode(const Node *node)
83 { 104 {
84 return node && (!node->hasChildren() || editingIgnoresContent(node)); 105 return node && (!node->hasChildren() || editingIgnoresContent(node));
85 } 106 }
86 107
87 template <typename Traversal> 108 template <typename Traversal>
88 static int comparePositions(Node* containerA, int offsetA, Node* containerB, int offsetB, bool* disconnected) 109 static int comparePositions(Node* containerA, int offsetA, Node* containerB, int offsetB, bool* disconnected)
89 { 110 {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 } 276 }
256 277
257 return highestRoot; 278 return highestRoot;
258 } 279 }
259 280
260 ContainerNode* highestEditableRoot(const PositionInFlatTree& position, EditableT ype editableType) 281 ContainerNode* highestEditableRoot(const PositionInFlatTree& position, EditableT ype editableType)
261 { 282 {
262 return highestEditableRoot(toPositionInDOMTree(position), editableType); 283 return highestEditableRoot(toPositionInDOMTree(position), editableType);
263 } 284 }
264 285
265 bool isEditablePosition(const Position& p, EditableType editableType, EUpdateSty le updateStyle) 286 bool isEditablePosition(const Position& position, EditableType editableType)
266 { 287 {
267 Node* node = p.parentAnchoredEquivalent().anchorNode(); 288 Node* node = position.parentAnchoredEquivalent().anchorNode();
268 if (!node) 289 if (!node)
269 return false; 290 return false;
270 if (updateStyle == UpdateStyle) 291 DCHECK(node->document().isActive());
271 node->document().updateStyleAndLayoutIgnorePendingStylesheets(); 292 if (node->document().lifecycle().state() >= DocumentLifecycle::InStyleRecalc ) {
272 else 293 // TODO(yosin): Once we change |LayoutObject::adjustStyleDifference()|
273 DCHECK_EQ(updateStyle, DoNotUpdateStyle); 294 // not to call |FrameSelection::hasCaret()|, we should not assume
295 // calling |isEditablePosition()| in |InStyleRecalc| is safe.
296 } else {
297 DCHECK(!needsLayoutTreeUpdate(position)) << position;
298 }
274 299
275 if (isDisplayInsideTable(node)) 300 if (isDisplayInsideTable(node))
276 node = node->parentNode(); 301 node = node->parentNode();
277 302
278 if (node->isDocumentNode()) 303 if (node->isDocumentNode())
279 return false; 304 return false;
280 return node->hasEditableStyle(editableType); 305 return node->hasEditableStyle(editableType);
281 } 306 }
282 307
283 bool isEditablePosition(const PositionInFlatTree& p, EditableType editableType, EUpdateStyle updateStyle) 308 bool isEditablePosition(const PositionInFlatTree& p, EditableType editableType)
284 { 309 {
285 return isEditablePosition(toPositionInDOMTree(p), editableType, updateStyle) ; 310 return isEditablePosition(toPositionInDOMTree(p), editableType);
286 } 311 }
287 312
288 bool isAtUnsplittableElement(const Position& pos) 313 bool isAtUnsplittableElement(const Position& pos)
289 { 314 {
290 Node* node = pos.anchorNode(); 315 Node* node = pos.anchorNode();
291 return (node == rootEditableElementOf(pos) || node == enclosingNodeOfType(po s, &isTableCell)); 316 return (node == rootEditableElementOf(pos) || node == enclosingNodeOfType(po s, &isTableCell));
292 } 317 }
293 318
294 319
295 bool isRichlyEditablePosition(const Position& p, EditableType editableType) 320 bool isRichlyEditablePosition(const Position& p, EditableType editableType)
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 499 }
475 500
476 VisiblePositionInFlatTree firstEditableVisiblePositionAfterPositionInRoot(const PositionInFlatTree& position, ContainerNode& highestRoot) 501 VisiblePositionInFlatTree firstEditableVisiblePositionAfterPositionInRoot(const PositionInFlatTree& position, ContainerNode& highestRoot)
477 { 502 {
478 return createVisiblePosition(firstEditablePositionAfterPositionInRoot(positi on, highestRoot)); 503 return createVisiblePosition(firstEditablePositionAfterPositionInRoot(positi on, highestRoot));
479 } 504 }
480 505
481 template <typename Strategy> 506 template <typename Strategy>
482 PositionTemplate<Strategy> firstEditablePositionAfterPositionInRootAlgorithm(con st PositionTemplate<Strategy>& position, Node& highestRoot) 507 PositionTemplate<Strategy> firstEditablePositionAfterPositionInRootAlgorithm(con st PositionTemplate<Strategy>& position, Node& highestRoot)
483 { 508 {
509 DCHECK(!needsLayoutTreeUpdate(highestRoot)) << position << ' ' << highestRoo t;
484 // position falls before highestRoot. 510 // position falls before highestRoot.
485 if (position.compareTo(PositionTemplate<Strategy>::firstPositionInNode(&high estRoot)) == -1 && highestRoot.hasEditableStyle()) 511 if (position.compareTo(PositionTemplate<Strategy>::firstPositionInNode(&high estRoot)) == -1 && highestRoot.hasEditableStyle())
486 return PositionTemplate<Strategy>::firstPositionInNode(&highestRoot); 512 return PositionTemplate<Strategy>::firstPositionInNode(&highestRoot);
487 513
488 PositionTemplate<Strategy> editablePosition = position; 514 PositionTemplate<Strategy> editablePosition = position;
489 515
490 if (position.anchorNode()->treeScope() != highestRoot.treeScope()) { 516 if (position.anchorNode()->treeScope() != highestRoot.treeScope()) {
491 Node* shadowAncestor = highestRoot.treeScope().ancestorInThisScope(edita blePosition.anchorNode()); 517 Node* shadowAncestor = highestRoot.treeScope().ancestorInThisScope(edita blePosition.anchorNode());
492 if (!shadowAncestor) 518 if (!shadowAncestor)
493 return PositionTemplate<Strategy>(); 519 return PositionTemplate<Strategy>();
(...skipping 26 matching lines...) Expand all
520 } 546 }
521 547
522 VisiblePositionInFlatTree lastEditableVisiblePositionBeforePositionInRoot(const PositionInFlatTree& position, ContainerNode& highestRoot) 548 VisiblePositionInFlatTree lastEditableVisiblePositionBeforePositionInRoot(const PositionInFlatTree& position, ContainerNode& highestRoot)
523 { 549 {
524 return createVisiblePosition(lastEditablePositionBeforePositionInRoot(positi on, highestRoot)); 550 return createVisiblePosition(lastEditablePositionBeforePositionInRoot(positi on, highestRoot));
525 } 551 }
526 552
527 template <typename Strategy> 553 template <typename Strategy>
528 PositionTemplate<Strategy> lastEditablePositionBeforePositionInRootAlgorithm(con st PositionTemplate<Strategy>& position, Node& highestRoot) 554 PositionTemplate<Strategy> lastEditablePositionBeforePositionInRootAlgorithm(con st PositionTemplate<Strategy>& position, Node& highestRoot)
529 { 555 {
556 DCHECK(!needsLayoutTreeUpdate(highestRoot)) << position << ' ' << highestRoo t;
530 // When position falls after highestRoot, the result is easy to compute. 557 // When position falls after highestRoot, the result is easy to compute.
531 if (position.compareTo(PositionTemplate<Strategy>::lastPositionInNode(&highe stRoot)) == 1) 558 if (position.compareTo(PositionTemplate<Strategy>::lastPositionInNode(&highe stRoot)) == 1)
532 return PositionTemplate<Strategy>::lastPositionInNode(&highestRoot); 559 return PositionTemplate<Strategy>::lastPositionInNode(&highestRoot);
533 560
534 PositionTemplate<Strategy> editablePosition = position; 561 PositionTemplate<Strategy> editablePosition = position;
535 562
536 if (position.anchorNode()->treeScope() != highestRoot.treeScope()) { 563 if (position.anchorNode()->treeScope() != highestRoot.treeScope()) {
537 Node* shadowAncestor = highestRoot.treeScope().ancestorInThisScope(edita blePosition.anchorNode()); 564 Node* shadowAncestor = highestRoot.treeScope().ancestorInThisScope(edita blePosition.anchorNode());
538 if (!shadowAncestor) 565 if (!shadowAncestor)
539 return PositionTemplate<Strategy>(); 566 return PositionTemplate<Strategy>();
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 return currentPos; 1437 return currentPos;
1411 } 1438 }
1412 } 1439 }
1413 1440
1414 return position; 1441 return position;
1415 } 1442 }
1416 1443
1417 // This assumes that it starts in editable content. 1444 // This assumes that it starts in editable content.
1418 Position leadingWhitespacePosition(const Position& position, TextAffinity affini ty, WhitespacePositionOption option) 1445 Position leadingWhitespacePosition(const Position& position, TextAffinity affini ty, WhitespacePositionOption option)
1419 { 1446 {
1420 DCHECK(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)) << position; 1447 DCHECK(isEditablePosition(position, ContentIsEditable)) << position;
1421 if (position.isNull()) 1448 if (position.isNull())
1422 return Position(); 1449 return Position();
1423 1450
1424 if (isHTMLBRElement(*mostBackwardCaretPosition(position).anchorNode())) 1451 if (isHTMLBRElement(*mostBackwardCaretPosition(position).anchorNode()))
1425 return Position(); 1452 return Position();
1426 1453
1427 const Position& prev = previousCharacterPosition(position, affinity); 1454 const Position& prev = previousCharacterPosition(position, affinity);
1428 if (prev == position) 1455 if (prev == position)
1429 return Position(); 1456 return Position();
1430 const Node* const anchorNode = prev.anchorNode(); 1457 const Node* const anchorNode = prev.anchorNode();
1431 if (!anchorNode || !anchorNode->isTextNode()) 1458 if (!anchorNode || !anchorNode->isTextNode())
1432 return Position(); 1459 return Position();
1433 if (enclosingBlockFlowElement(*anchorNode) != enclosingBlockFlowElement(*pos ition.anchorNode())) 1460 if (enclosingBlockFlowElement(*anchorNode) != enclosingBlockFlowElement(*pos ition.anchorNode()))
1434 return Position(); 1461 return Position();
1435 if (option == NotConsiderNonCollapsibleWhitespace && anchorNode->layoutObjec t() && !anchorNode->layoutObject()->style()->collapseWhiteSpace()) 1462 if (option == NotConsiderNonCollapsibleWhitespace && anchorNode->layoutObjec t() && !anchorNode->layoutObject()->style()->collapseWhiteSpace())
1436 return Position(); 1463 return Position();
1437 const String& string = toText(anchorNode)->data(); 1464 const String& string = toText(anchorNode)->data();
1438 const UChar previousCharacter = string[prev.computeOffsetInContainerNode()]; 1465 const UChar previousCharacter = string[prev.computeOffsetInContainerNode()];
1439 const bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOr Newline(previousCharacter) || previousCharacter == noBreakSpaceCharacter) : isCo llapsibleWhitespace(previousCharacter); 1466 const bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOr Newline(previousCharacter) || previousCharacter == noBreakSpaceCharacter) : isCo llapsibleWhitespace(previousCharacter);
1440 if (!isSpace || !isEditablePosition(prev)) 1467 if (!isSpace || !isEditablePosition(prev))
1441 return Position(); 1468 return Position();
1442 return prev; 1469 return prev;
1443 } 1470 }
1444 1471
1445 // This assumes that it starts in editable content. 1472 // This assumes that it starts in editable content.
1446 Position trailingWhitespacePosition(const Position& position, TextAffinity, Whit espacePositionOption option) 1473 Position trailingWhitespacePosition(const Position& position, TextAffinity, Whit espacePositionOption option)
1447 { 1474 {
1448 DCHECK(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)) << position; 1475 DCHECK(isEditablePosition(position, ContentIsEditable)) << position;
1449 if (position.isNull()) 1476 if (position.isNull())
1450 return Position(); 1477 return Position();
1451 1478
1452 VisiblePosition visiblePosition = createVisiblePosition(position); 1479 VisiblePosition visiblePosition = createVisiblePosition(position);
1453 UChar characterAfterVisiblePosition = characterAfter(visiblePosition); 1480 UChar characterAfterVisiblePosition = characterAfter(visiblePosition);
1454 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition); 1481 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition);
1455 // The space must not be in another paragraph and it must be editable. 1482 // The space must not be in another paragraph and it must be editable.
1456 if (isSpace && !isEndOfParagraph(visiblePosition) && nextPositionOf(visibleP osition, CannotCrossEditingBoundary).isNotNull()) 1483 if (isSpace && !isEndOfParagraph(visiblePosition) && nextPositionOf(visibleP osition, CannotCrossEditingBoundary).isNotNull())
1457 return position; 1484 return position;
1458 return Position(); 1485 return Position();
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 { 1811 {
1785 if (!RuntimeEnabledFeatures::inputEventEnabled()) 1812 if (!RuntimeEnabledFeatures::inputEventEnabled())
1786 return DispatchEventResult::NotCanceled; 1813 return DispatchEventResult::NotCanceled;
1787 if (!target) 1814 if (!target)
1788 return DispatchEventResult::NotCanceled; 1815 return DispatchEventResult::NotCanceled;
1789 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data , InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo mposing, ranges); 1816 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data , InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo mposing, ranges);
1790 return target->dispatchEvent(beforeInputEvent); 1817 return target->dispatchEvent(beforeInputEvent);
1791 } 1818 }
1792 1819
1793 } // namespace blink 1820 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/EditingUtilities.h ('k') | third_party/WebKit/Source/core/editing/VisibleSelection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698