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

Side by Side Diff: Source/core/editing/htmlediting.cpp

Issue 59963002: Unable to delete the first and the last characters of a contenteditable div with display: table. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Adding new method to preserve old behavior. Created 7 years, 1 month 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 bool isEditablePosition(const Position& p, EditableType editableType, EUpdateSty le updateStyle) 153 bool isEditablePosition(const Position& p, EditableType editableType, EUpdateSty le updateStyle)
154 { 154 {
155 Node* node = p.deprecatedNode(); 155 Node* node = p.deprecatedNode();
156 if (!node) 156 if (!node)
157 return false; 157 return false;
158 if (updateStyle == UpdateStyle) 158 if (updateStyle == UpdateStyle)
159 node->document().updateLayoutIgnorePendingStylesheets(); 159 node->document().updateLayoutIgnorePendingStylesheets();
160 else 160 else
161 ASSERT(updateStyle == DoNotUpdateStyle); 161 ASSERT(updateStyle == DoNotUpdateStyle);
162 162
163 if (node->renderer() && node->renderer()->isTable()) 163 if (isTableElement(node))
164 node = node->parentNode(); 164 node = node->parentNode();
165 165
166 return node->rendererIsEditable(editableType); 166 return node->rendererIsEditable(editableType);
167 } 167 }
168 168
169 bool isAtUnsplittableElement(const Position& pos) 169 bool isAtUnsplittableElement(const Position& pos)
170 { 170 {
171 Node* node = pos.deprecatedNode(); 171 Node* node = pos.deprecatedNode();
172 return (node == editableRootForPosition(pos) || node == enclosingNodeOfType( pos, &isTableCell)); 172 return (node == editableRootForPosition(pos) || node == enclosingNodeOfType( pos, &isTableCell));
173 } 173 }
174 174
175 175
176 bool isRichlyEditablePosition(const Position& p, EditableType editableType) 176 bool isRichlyEditablePosition(const Position& p, EditableType editableType)
177 { 177 {
178 Node* node = p.deprecatedNode(); 178 Node* node = p.deprecatedNode();
179 if (!node) 179 if (!node)
180 return false; 180 return false;
181 181
182 if (node->renderer() && node->renderer()->isTable()) 182 if (isTableElement(node))
183 node = node->parentNode(); 183 node = node->parentNode();
184 184
185 return node->rendererIsRichlyEditable(editableType); 185 return node->rendererIsRichlyEditable(editableType);
186 } 186 }
187 187
188 Element* editableRootForPosition(const Position& p, EditableType editableType) 188 Element* editableRootForPosition(const Position& p, EditableType editableType)
189 { 189 {
190 Node* node = p.containerNode(); 190 Node* node = p.containerNode();
191 if (!node) 191 if (!node)
192 return 0; 192 return 0;
193 193
194 if (node->renderer() && node->renderer()->isTable()) 194 if (isTableElement(node))
195 node = node->parentNode(); 195 node = node->parentNode();
196 196
197 return node->rootEditableElement(editableType); 197 return node->rootEditableElement(editableType);
198 } 198 }
199 199
200 // Finds the enclosing element until which the tree can be split. 200 // Finds the enclosing element until which the tree can be split.
201 // When a user hits ENTER, he/she won't expect this element to be split into two . 201 // When a user hits ENTER, he/she won't expect this element to be split into two .
202 // You may pass it as the second argument of splitTreeToNode. 202 // You may pass it as the second argument of splitTreeToNode.
203 Element* unsplittableElementForPosition(const Position& p) 203 Element* unsplittableElementForPosition(const Position& p)
204 { 204 {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 return false; 427 return false;
428 } 428 }
429 429
430 static Node* firstInSpecialElement(const Position& pos) 430 static Node* firstInSpecialElement(const Position& pos)
431 { 431 {
432 Node* rootEditableElement = pos.containerNode()->rootEditableElement(); 432 Node* rootEditableElement = pos.containerNode()->rootEditableElement();
433 for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEd itableElement; n = n->parentNode()) 433 for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEd itableElement; n = n->parentNode())
434 if (isSpecialElement(n)) { 434 if (isSpecialElement(n)) {
435 VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); 435 VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
436 VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBe foreNode(n), DOWNSTREAM); 436 VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBe foreNode(n), DOWNSTREAM);
437 if (isTableElement(n) && vPos == firstInElement.next()) 437 if (isRenderedTable(n) && vPos == firstInElement.next())
438 return n; 438 return n;
439 if (vPos == firstInElement) 439 if (vPos == firstInElement)
440 return n; 440 return n;
441 } 441 }
442 return 0; 442 return 0;
443 } 443 }
444 444
445 static Node* lastInSpecialElement(const Position& pos) 445 static Node* lastInSpecialElement(const Position& pos)
446 { 446 {
447 Node* rootEditableElement = pos.containerNode()->rootEditableElement(); 447 Node* rootEditableElement = pos.containerNode()->rootEditableElement();
448 for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEd itableElement; n = n->parentNode()) 448 for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEd itableElement; n = n->parentNode())
449 if (isSpecialElement(n)) { 449 if (isSpecialElement(n)) {
450 VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); 450 VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
451 VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfte rNode(n), DOWNSTREAM); 451 VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfte rNode(n), DOWNSTREAM);
452 if (isTableElement(n) && vPos == lastInElement.previous()) 452 if (isRenderedTable(n) && vPos == lastInElement.previous())
453 return n; 453 return n;
454 if (vPos == lastInElement) 454 if (vPos == lastInElement)
455 return n; 455 return n;
456 } 456 }
457 return 0; 457 return 0;
458 } 458 }
459 459
460 Position positionBeforeContainingSpecialElement(const Position& pos, Node** cont ainingSpecialElement) 460 Position positionBeforeContainingSpecialElement(const Position& pos, Node** cont ainingSpecialElement)
461 { 461 {
462 Node* n = firstInSpecialElement(pos); 462 Node* n = firstInSpecialElement(pos);
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList- >isHTMLElement()) 745 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList- >isHTMLElement())
746 return false; 746 return false;
747 747
748 return firstList->hasTagName(secondList->tagQName()) // make sure the list t ypes match (ol vs. ul) 748 return firstList->hasTagName(secondList->tagQName()) // make sure the list t ypes match (ol vs. ul)
749 && firstList->rendererIsEditable() && secondList->rendererIsEditable() // bo th lists are editable 749 && firstList->rendererIsEditable() && secondList->rendererIsEditable() // bo th lists are editable
750 && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries 750 && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
751 && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentB eforeNode(secondList)); 751 && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentB eforeNode(secondList));
752 // Make sure there is no visible content between this li and the previous li st 752 // Make sure there is no visible content between this li and the previous li st
753 } 753 }
754 754
755 // FIXME: do not require renderer, so that this can be used within fragments, or rename to isRenderedTable() 755 bool isTableElement(const Node* n)
756 bool isTableElement(Node* n)
757 { 756 {
758 if (!n || !n->isElementNode()) 757 if (!n || !n->isElementNode())
759 return false; 758 return false;
760 759
761 RenderObject* renderer = n->renderer(); 760 return n->hasTagName(tableTag);
761 }
762
763 bool isRenderedTable(const Node* node)
764 {
765 if (!node || !node->isElementNode())
766 return false;
767
768 RenderObject* renderer = node->renderer();
762 return (renderer && (renderer->style()->display() == TABLE || renderer->styl e()->display() == INLINE_TABLE)); 769 return (renderer && (renderer->style()->display() == TABLE || renderer->styl e()->display() == INLINE_TABLE));
763 } 770 }
764 771
765 bool isTableCell(const Node* node) 772 bool isTableCell(const Node* node)
766 { 773 {
767 RenderObject* r = node->renderer(); 774 RenderObject* r = node->renderer();
768 if (!r) 775 if (!r)
769 return node->hasTagName(tdTag) || node->hasTagName(thTag); 776 return node->hasTagName(tdTag) || node->hasTagName(thTag);
770 777
771 return r->isTableCell(); 778 return r->isTableCell();
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 // if the selection starts just before a paragraph break, skip over it 1161 // if the selection starts just before a paragraph break, skip over it
1155 if (isEndOfParagraph(visiblePosition)) 1162 if (isEndOfParagraph(visiblePosition))
1156 return visiblePosition.next().deepEquivalent().downstream(); 1163 return visiblePosition.next().deepEquivalent().downstream();
1157 1164
1158 // otherwise, make sure to be at the start of the first selected node, 1165 // otherwise, make sure to be at the start of the first selected node,
1159 // instead of possibly at the end of the last node before the selection 1166 // instead of possibly at the end of the last node before the selection
1160 return visiblePosition.deepEquivalent().downstream(); 1167 return visiblePosition.deepEquivalent().downstream();
1161 } 1168 }
1162 1169
1163 } // namespace WebCore 1170 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698