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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |