OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006 Apple Computer, 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 // When inserting a new line, we want to avoid nesting empty divs if we can. Ot
herwise, when | 44 // When inserting a new line, we want to avoid nesting empty divs if we can. Ot
herwise, when |
45 // pasting, it's easy to have each new line be a div deeper than the previous.
E.g., in the case | 45 // pasting, it's easy to have each new line be a div deeper than the previous.
E.g., in the case |
46 // below, we want to insert at ^ instead of |. | 46 // below, we want to insert at ^ instead of |. |
47 // <div>foo<div>bar</div>|</div>^ | 47 // <div>foo<div>bar</div>|</div>^ |
48 static Element* highestVisuallyEquivalentDivBelowRoot(Element* startBlock) | 48 static Element* highestVisuallyEquivalentDivBelowRoot(Element* startBlock) |
49 { | 49 { |
50 Element* curBlock = startBlock; | 50 Element* curBlock = startBlock; |
51 // We don't want to return a root node (if it happens to be a div, e.g., in
a document fragment) because there are no | 51 // We don't want to return a root node (if it happens to be a div, e.g., in
a document fragment) because there are no |
52 // siblings for us to append to. | 52 // siblings for us to append to. |
53 while (!curBlock->nextSibling() && curBlock->parentElement()->hasTagName(div
Tag) && curBlock->parentElement()->parentElement()) { | 53 while (!curBlock->nextSibling() && isHTMLDivElement(*curBlock->parentElement
()) && curBlock->parentElement()->parentElement()) { |
54 if (curBlock->parentElement()->hasAttributes()) | 54 if (curBlock->parentElement()->hasAttributes()) |
55 break; | 55 break; |
56 curBlock = curBlock->parentElement(); | 56 curBlock = curBlock->parentElement(); |
57 } | 57 } |
58 return curBlock; | 58 return curBlock; |
59 } | 59 } |
60 | 60 |
61 InsertParagraphSeparatorCommand::InsertParagraphSeparatorCommand(Document& docum
ent, bool mustUseDefaultParagraphElement, bool pasteBlockqutoeIntoUnquotedArea) | 61 InsertParagraphSeparatorCommand::InsertParagraphSeparatorCommand(Document& docum
ent, bool mustUseDefaultParagraphElement, bool pasteBlockqutoeIntoUnquotedArea) |
62 : CompositeEditCommand(document) | 62 : CompositeEditCommand(document) |
63 , m_mustUseDefaultParagraphElement(mustUseDefaultParagraphElement) | 63 , m_mustUseDefaultParagraphElement(mustUseDefaultParagraphElement) |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 } | 163 } |
164 | 164 |
165 // FIXME: The parentAnchoredEquivalent conversion needs to be moved into enc
losingBlock. | 165 // FIXME: The parentAnchoredEquivalent conversion needs to be moved into enc
losingBlock. |
166 RefPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchored
Equivalent().containerNode()); | 166 RefPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchored
Equivalent().containerNode()); |
167 Node* listChildNode = enclosingListChild(insertionPosition.parentAnchoredEqu
ivalent().containerNode()); | 167 Node* listChildNode = enclosingListChild(insertionPosition.parentAnchoredEqu
ivalent().containerNode()); |
168 RefPtr<Element> listChild = listChildNode && listChildNode->isHTMLElement()
? toHTMLElement(listChildNode) : 0; | 168 RefPtr<Element> listChild = listChildNode && listChildNode->isHTMLElement()
? toHTMLElement(listChildNode) : 0; |
169 Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent(); | 169 Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent(); |
170 if (!startBlock | 170 if (!startBlock |
171 || !startBlock->nonShadowBoundaryParentNode() | 171 || !startBlock->nonShadowBoundaryParentNode() |
172 || isTableCell(startBlock.get()) | 172 || isTableCell(startBlock.get()) |
173 || startBlock->hasTagName(formTag) | 173 || isHTMLFormElement(*startBlock) |
174 // FIXME: If the node is hidden, we don't have a canonical position so w
e will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.
cgi?id=40342 | 174 // FIXME: If the node is hidden, we don't have a canonical position so w
e will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.
cgi?id=40342 |
175 || (!canonicalPos.isNull() && isRenderedTable(canonicalPos.deprecatedNod
e())) | 175 || (!canonicalPos.isNull() && isRenderedTable(canonicalPos.deprecatedNod
e())) |
176 || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->hasTagName(
hrTag))) { | 176 || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.deprecatedNo
de()))) { |
177 applyCommandToComposite(InsertLineBreakCommand::create(document())); | 177 applyCommandToComposite(InsertLineBreakCommand::create(document())); |
178 return; | 178 return; |
179 } | 179 } |
180 | 180 |
181 // Use the leftmost candidate. | 181 // Use the leftmost candidate. |
182 insertionPosition = insertionPosition.upstream(); | 182 insertionPosition = insertionPosition.upstream(); |
183 if (!insertionPosition.isCandidate()) | 183 if (!insertionPosition.isCandidate()) |
184 insertionPosition = insertionPosition.downstream(); | 184 insertionPosition = insertionPosition.downstream(); |
185 | 185 |
186 // Adjust the insertion position after the delete | 186 // Adjust the insertion position after the delete |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 233 } |
234 | 234 |
235 if (listChild && listChild != startBlock) { | 235 if (listChild && listChild != startBlock) { |
236 RefPtr<Element> listChildToInsert = listChild->cloneElementWitho
utChildren(); | 236 RefPtr<Element> listChildToInsert = listChild->cloneElementWitho
utChildren(); |
237 appendNode(blockToInsert, listChildToInsert.get()); | 237 appendNode(blockToInsert, listChildToInsert.get()); |
238 insertNodeAfter(listChildToInsert.get(), listChild); | 238 insertNodeAfter(listChildToInsert.get(), listChild); |
239 } else { | 239 } else { |
240 // Most of the time we want to stay at the nesting level of the
startBlock (e.g., when nesting within lists). However, | 240 // Most of the time we want to stay at the nesting level of the
startBlock (e.g., when nesting within lists). However, |
241 // for div nodes, this can result in nested div tags that are ha
rd to break out of. | 241 // for div nodes, this can result in nested div tags that are ha
rd to break out of. |
242 Element* siblingNode = startBlock.get(); | 242 Element* siblingNode = startBlock.get(); |
243 if (blockToInsert->hasTagName(divTag)) | 243 if (isHTMLDivElement(*blockToInsert)) |
244 siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlo
ck.get()); | 244 siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlo
ck.get()); |
245 insertNodeAfter(blockToInsert, siblingNode); | 245 insertNodeAfter(blockToInsert, siblingNode); |
246 } | 246 } |
247 } | 247 } |
248 | 248 |
249 // Recreate the same structure in the new paragraph. | 249 // Recreate the same structure in the new paragraph. |
250 | 250 |
251 Vector<RefPtr<Element> > ancestors; | 251 Vector<RefPtr<Element> > ancestors; |
252 getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprec
atedNode(), startBlock.get(), ancestors); | 252 getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprec
atedNode(), startBlock.get(), ancestors); |
253 RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToI
nsert); | 253 RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToI
nsert); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 if (positionAfterSplit.deprecatedNode()->isTextNode()) | 419 if (positionAfterSplit.deprecatedNode()->isTextNode()) |
420 insertTextIntoNode(toText(positionAfterSplit.containerNode()), 0
, nonBreakingSpaceString()); | 420 insertTextIntoNode(toText(positionAfterSplit.containerNode()), 0
, nonBreakingSpaceString()); |
421 } | 421 } |
422 } | 422 } |
423 | 423 |
424 setEndingSelection(VisibleSelection(firstPositionInNode(blockToInsert.get())
, DOWNSTREAM, endingSelection().isDirectional())); | 424 setEndingSelection(VisibleSelection(firstPositionInNode(blockToInsert.get())
, DOWNSTREAM, endingSelection().isDirectional())); |
425 applyStyleAfterInsertion(startBlock.get()); | 425 applyStyleAfterInsertion(startBlock.get()); |
426 } | 426 } |
427 | 427 |
428 } // namespace WebCore | 428 } // namespace WebCore |
OLD | NEW |