Changeset 168650 in webkit
- Timestamp:
- May 12, 2014 3:47:39 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r168647 r168650 1 2014-05-12 Brady Eidson <beidson@apple.com> 2 3 Teach Editor to support more direct replacement of a Node 4 <rdar://problem/16817952> and https://bugs.webkit.org/show_bug.cgi?id=132834 5 6 Reviewed by Enrica Casucci. 7 8 The new method "Editor::replaceNodeFromPasteboard" has the intent that the new DocumentFragment 9 from the pasteboard is as similar to the old Node as possible. 10 11 In practice, the new DocumentFragment: 12 1 - Can represent a single node that's missing various attributes the original Node had. 13 2 - Can be an unwanted fragment of arbitrary depth when the replacement happens inside Mail.app 14 15 This fixes both of these issues. 16 17 Add a MailBlockquoteHandling enum class for various Editor operations to pass through to the 18 ReplaceSelectionCommand: 19 * editing/Editor.cpp: 20 (WebCore::Editor::handleTextEvent): 21 (WebCore::Editor::pasteAsFragment): 22 (WebCore::Editor::pasteWithPasteboard): 23 (WebCore::Editor::replaceSelectionWithFragment): 24 * editing/Editor.h: 25 26 * dom/TextEvent.cpp: 27 (WebCore::TextEvent::createForPlainTextPaste): 28 (WebCore::TextEvent::createForFragmentPaste): 29 (WebCore::TextEvent::TextEvent): 30 * dom/TextEvent.h: 31 (WebCore::TextEvent::mailBlockquoteHandling): 32 33 * editing/ReplaceSelectionCommand.cpp: 34 (WebCore::ReplaceSelectionCommand::ReplaceSelectionCommand): 35 (WebCore::ReplaceSelectionCommand::doApply): Consider whether or not this particular Editor 36 operation was meant to give special consideration to Mail's Blockquotes. 37 * editing/ReplaceSelectionCommand.h: 38 39 * editing/efl/EditorEfl.cpp: 40 (WebCore::Editor::pasteWithPasteboard): 41 * editing/ios/EditorIOS.mm: 42 (WebCore::Editor::pasteWithPasteboard): 43 44 * editing/mac/EditorMac.mm: 45 (WebCore::Editor::pasteWithPasteboard): 46 (WebCore::Editor::readSelectionFromPasteboard): 47 (WebCore::maybeCopyNodeAttributesToFragment): If the new DocumentFragment represents a single HTML node 48 with the same tag name is the original HTML node, copy over most attributes from the original node. 49 (WebCore::Editor::replaceNodeFromPasteboard): Create the fragment, run it through maybeCopyNodeAttributesToFragment. 50 51 * WebCore.exp.in: 52 1 53 2014-05-12 Alex Christensen <achristensen@webkit.org> 2 54 -
trunk/Source/WebCore/WebCore.exp.in
r168647 r168650 1151 1151 __ZN7WebCore6Editor14setCompositionERKN3WTF6StringERKNS1_6VectorINS_20CompositionUnderlineELm0ENS1_15CrashOnOverflowEEEjj 1152 1152 __ZN7WebCore6Editor14simplifyMarkupEPNS_4NodeES2_ 1153 __ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbb 1153 __ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbNS_22MailBlockquoteHandlingE 1154 1154 __ZN7WebCore6Editor16pasteAsPlainTextEv 1155 1155 __ZN7WebCore6Editor17cancelCompositionEv … … 1171 1171 __ZN7WebCore6Editor26toggleOverwriteModeEnabledEv 1172 1172 __ZN7WebCore6Editor26writeSelectionToPasteboardERNS_10PasteboardE 1173 __ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbb 1173 __ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbbNS_22MailBlockquoteHandlingE 1174 1174 __ZN7WebCore6Editor28updateEditorUINowIfScheduledEv 1175 1175 __ZN7WebCore6Editor29canDecreaseSelectionListLevelEv … … 2258 2258 __ZN7WebCore6Editor25replaceNodeFromPasteboardEPNS_4NodeERKN3WTF6StringE 2259 2259 __ZN7WebCore6Editor26dataSelectionForPasteboardERKN3WTF6StringE 2260 __ZN7WebCore6Editor27readSelectionFromPasteboardERKN3WTF6StringE 2260 __ZN7WebCore6Editor27readSelectionFromPasteboardERKN3WTF6StringENS_22MailBlockquoteHandlingE 2261 2261 __ZN7WebCore6Editor28stringSelectionForPasteboardEv 2262 2262 __ZN7WebCore6Editor28toggleAutomaticLinkDetectionEv -
trunk/Source/WebCore/dom/TextEvent.cpp
r165676 r168650 29 29 30 30 #include "DocumentFragment.h" 31 #include "Editor.h" 31 32 32 33 namespace WebCore { … … 44 45 PassRefPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace) 45 46 { 46 return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false ));47 return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false, MailBlockquoteHandling::RespectBlockquote)); 47 48 } 48 49 49 PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle )50 PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling mailBlockquoteHandling) 50 51 { 51 return adoptRef(new TextEvent(view, "", data, shouldSmartReplace, shouldMatchStyle ));52 return adoptRef(new TextEvent(view, "", data, shouldSmartReplace, shouldMatchStyle, mailBlockquoteHandling)); 52 53 } 53 54 … … 66 67 , m_shouldSmartReplace(false) 67 68 , m_shouldMatchStyle(false) 69 , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote) 68 70 { 69 71 } … … 76 78 , m_shouldSmartReplace(false) 77 79 , m_shouldMatchStyle(false) 80 , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote) 78 81 { 79 82 } 80 83 81 TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefPtr<DocumentFragment> pastingFragment, 82 bool shouldSmartReplace, bool shouldMatchStyle) 84 TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefPtr<DocumentFragment> pastingFragment, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling mailBlockquoteHandling) 83 85 : UIEvent(eventNames().textInputEvent, true, true, view, 0) 84 86 , m_inputType(TextEventInputPaste) … … 87 89 , m_shouldSmartReplace(shouldSmartReplace) 88 90 , m_shouldMatchStyle(shouldMatchStyle) 91 , m_mailBlockquoteHandling(mailBlockquoteHandling) 89 92 { 90 93 } … … 96 99 , m_shouldSmartReplace(false) 97 100 , m_shouldMatchStyle(false) 101 , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote) 98 102 , m_dictationAlternatives(dictationAlternatives) 99 103 { -
trunk/Source/WebCore/dom/TextEvent.h
r165676 r168650 36 36 class DocumentFragment; 37 37 38 enum class MailBlockquoteHandling; 39 38 40 class TextEvent : public UIEvent { 39 41 public: … … 41 43 static PassRefPtr<TextEvent> create(); 42 44 static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard); 43 static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace);44 static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle);45 static PassRefPtr<TextEvent> createForDrop(PassRefPtr<AbstractView> view, const String& data);45 static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView>, const String& data, bool shouldSmartReplace); 46 static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView>, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling); 47 static PassRefPtr<TextEvent> createForDrop(PassRefPtr<AbstractView>, const String& data); 46 48 static PassRefPtr<TextEvent> createForDictation(PassRefPtr<AbstractView>, const String& data, const Vector<DictationAlternative>& dictationAlternatives); 47 49 … … 63 65 bool shouldSmartReplace() const { return m_shouldSmartReplace; } 64 66 bool shouldMatchStyle() const { return m_shouldMatchStyle; } 67 MailBlockquoteHandling mailBlockquoteHandling() const { return m_mailBlockquoteHandling; } 65 68 DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); } 66 69 const Vector<DictationAlternative>& dictationAlternatives() const { return m_dictationAlternatives; } … … 70 73 71 74 TextEvent(PassRefPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard); 72 TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment>, 73 bool shouldSmartReplace, bool shouldMatchStyle); 75 TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment>, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling); 74 76 TextEvent(PassRefPtr<AbstractView>, const String& data, const Vector<DictationAlternative>& dictationAlternatives); 75 77 … … 82 84 bool m_shouldSmartReplace; 83 85 bool m_shouldMatchStyle; 86 MailBlockquoteHandling m_mailBlockquoteHandling; 84 87 Vector<DictationAlternative> m_dictationAlternatives; 85 88 }; -
trunk/Source/WebCore/editing/Editor.cpp
r167542 r168650 267 267 return true; 268 268 #endif 269 replaceSelectionWithFragment(event->pastingFragment(), false, event->shouldSmartReplace(), event->shouldMatchStyle() );269 replaceSelectionWithFragment(event->pastingFragment(), false, event->shouldSmartReplace(), event->shouldMatchStyle(), event->mailBlockquoteHandling()); 270 270 #if PLATFORM(IOS) 271 271 } … … 529 529 } 530 530 531 void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle )531 void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle, MailBlockquoteHandling respectsMailBlockquote) 532 532 { 533 533 Node* target = findEventTargetFromSelection(); 534 534 if (!target) 535 535 return; 536 target->dispatchEvent(TextEvent::createForFragmentPaste(document().domWindow(), pastingFragment, smartReplace, matchStyle ), IGNORE_EXCEPTION);536 target->dispatchEvent(TextEvent::createForFragmentPaste(document().domWindow(), pastingFragment, smartReplace, matchStyle, respectsMailBlockquote), IGNORE_EXCEPTION); 537 537 } 538 538 … … 566 566 567 567 #if !PLATFORM(COCOA) && !PLATFORM(EFL) 568 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText )568 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling) 569 569 { 570 570 RefPtr<Range> range = selectedRange(); … … 575 575 RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, *range, allowPlainText, chosePlainText); 576 576 if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted)) 577 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText );577 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling); 578 578 } 579 579 #endif … … 598 598 } 599 599 600 void Editor::replaceSelectionWithFragment(PassRefPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle )600 void Editor::replaceSelectionWithFragment(PassRefPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle, MailBlockquoteHandling mailBlockquoteHandling) 601 601 { 602 602 VisibleSelection selection = m_frame.selection().selection(); … … 611 611 if (matchStyle) 612 612 options |= ReplaceSelectionCommand::MatchStyle; 613 if (mailBlockquoteHandling == MailBlockquoteHandling::IgnoreBlockquote) 614 options |= ReplaceSelectionCommand::IgnoreMailBlockquote; 615 613 616 applyCommand(ReplaceSelectionCommand::create(document(), fragment, options, EditActionPaste)); 614 617 revealSelectionAfterEditingOperation(); -
trunk/Source/WebCore/editing/Editor.h
r168378 r168650 91 91 enum EditorParagraphSeparator { EditorParagraphSeparatorIsDiv, EditorParagraphSeparatorIsP }; 92 92 93 enum class MailBlockquoteHandling { 94 RespectBlockquote, 95 IgnoreBlockquote, 96 }; 97 93 98 class Editor { 94 99 public: … … 336 341 void dismissCorrectionPanelAsIgnored(); 337 342 338 void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle );343 void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); 339 344 void pasteAsPlainText(const String&, bool smartReplace); 340 345 … … 378 383 WritingDirection baseWritingDirectionForSelectionStart() const; 379 384 380 void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle );385 void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); 381 386 void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace); 382 387 bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const; … … 432 437 bool canCopyExcludingStandaloneImages(); 433 438 void takeFindStringFromSelection(); 434 void readSelectionFromPasteboard(const String& pasteboardName );439 void readSelectionFromPasteboard(const String& pasteboardName, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); 435 440 void replaceNodeFromPasteboard(Node*, const String& pasteboardName); 436 441 PassRefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName); … … 451 456 bool canSmartReplaceWithPasteboard(Pasteboard&); 452 457 void pasteAsPlainTextWithPasteboard(Pasteboard&); 453 void pasteWithPasteboard(Pasteboard*, bool allowPlainText );458 void pasteWithPasteboard(Pasteboard*, bool allowPlainText, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); 454 459 String plainTextFromPasteboard(const PasteboardPlainText&); 455 460 -
trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp
r168460 r168650 379 379 , m_sanitizeFragment(options & SanitizeFragment) 380 380 , m_shouldMergeEnd(false) 381 , m_ignoreMailBlockquote(options & IgnoreMailBlockquote) 381 382 { 382 383 } … … 934 935 935 936 Position insertionPos = selection.start(); 936 bool s tartIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailBlockquote, CanCrossEditingBoundary);937 bool shouldHandleMailBlockquote = enclosingNodeOfType(insertionPos, isMailBlockquote, CanCrossEditingBoundary) && !m_ignoreMailBlockquote; 937 938 bool selectionIsPlainText = !selection.isContentRichlyEditable(); 938 939 Element* currentRoot = selection.rootEditableElement(); 939 940 940 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !s tartIsInsideMailBlockquote) ||941 startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText)941 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !shouldHandleMailBlockquote) 942 || startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText) 942 943 m_preventNesting = false; 943 944 … … 949 950 // Merge blocks if the start of the selection was in a Mail blockquote, since we handle 950 951 // that case specially to prevent nesting. 951 bool mergeBlocksAfterDelete = s tartIsInsideMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart);952 bool mergeBlocksAfterDelete = shouldHandleMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart); 952 953 // FIXME: We should only expand to include fully selected special elements if we are copying a 953 954 // selection and pasting it on top of itself. … … 978 979 // not <div>xbar<div>bar</div><div>bazx</div></div>. 979 980 // Don't do this if the selection started in a Mail blockquote. 980 if (m_preventNesting && !s tartIsInsideMailBlockquote && !isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart)) {981 if (m_preventNesting && !shouldHandleMailBlockquote && !isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart)) { 981 982 insertParagraphSeparator(); 982 983 setEndingSelection(endingSelection().visibleStart().previous()); … … 988 989 // out of any surrounding Mail blockquotes. Unless we're inserting in a table, in which case 989 990 // breaking the blockquote will prevent the content from actually being inserted in the table. 990 if (s tartIsInsideMailBlockquote && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTableStructureNode))) {991 if (shouldHandleMailBlockquote && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTableStructureNode))) { 991 992 applyCommandToComposite(BreakBlockquoteCommand::create(document())); 992 993 // This will leave a br between the split. … … 1017 1018 // Adjust insertionPos to prevent nesting. 1018 1019 // If the start was in a Mail blockquote, we will have already handled adjusting insertionPos above. 1019 if (m_preventNesting && insertionBlock && !isTableCell(insertionBlock.get()) && !s tartIsInsideMailBlockquote) {1020 if (m_preventNesting && insertionBlock && !isTableCell(insertionBlock.get()) && !shouldHandleMailBlockquote) { 1020 1021 ASSERT(insertionBlock != currentRoot); 1021 1022 VisiblePosition visibleInsertionPos(insertionPos); … … 1163 1164 m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph); 1164 1165 1165 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasInterchangeNewlineAtStart(), s tartIsInsideMailBlockquote)) {1166 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasInterchangeNewlineAtStart(), shouldHandleMailBlockquote)) { 1166 1167 VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedContent(); 1167 1168 VisiblePosition destination = startOfParagraphToMove.previous(); … … 1212 1213 // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph 1213 1214 // block's style seems to annoy users. 1214 insertParagraphSeparator(true, !s tartIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),1215 insertParagraphSeparator(true, !shouldHandleMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1215 1216 isMailBlockquote, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode())); 1216 1217 } -
trunk/Source/WebCore/editing/ReplaceSelectionCommand.h
r165676 r168650 43 43 PreventNesting = 1 << 3, 44 44 MovingParagraph = 1 << 4, 45 SanitizeFragment = 1 << 5 45 SanitizeFragment = 1 << 5, 46 IgnoreMailBlockquote = 1 << 6, 46 47 }; 47 48 … … 116 117 bool m_sanitizeFragment; 117 118 bool m_shouldMergeEnd; 119 bool m_ignoreMailBlockquote; 118 120 }; 119 121 -
trunk/Source/WebCore/editing/efl/EditorEfl.cpp
r165676 r168650 43 43 } 44 44 45 void Editor::pasteWithPasteboard(Pasteboard*, bool )45 void Editor::pasteWithPasteboard(Pasteboard*, bool, MailBlockquoteHandling) 46 46 { 47 47 notImplemented(); -
trunk/Source/WebCore/editing/ios/EditorIOS.mm
r168579 r168650 552 552 } 553 553 554 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText )554 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling) 555 555 { 556 556 RefPtr<Range> range = selectedRange(); … … 562 562 563 563 if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted)) 564 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false );564 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling); 565 565 } 566 566 -
trunk/Source/WebCore/editing/mac/EditorMac.mm
r168579 r168650 83 83 } 84 84 85 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText )85 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling) 86 86 { 87 87 RefPtr<Range> range = selectedRange(); … … 94 94 95 95 if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted)) 96 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false );96 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling); 97 97 98 98 client()->setInsertionPasteboard(String()); … … 258 258 } 259 259 260 void Editor::readSelectionFromPasteboard(const String& pasteboardName )260 void Editor::readSelectionFromPasteboard(const String& pasteboardName, MailBlockquoteHandling mailBlockquoteHandling) 261 261 { 262 262 Pasteboard pasteboard(pasteboardName); 263 263 if (m_frame.selection().selection().isContentRichlyEditable()) 264 pasteWithPasteboard(&pasteboard, true );264 pasteWithPasteboard(&pasteboard, true, mailBlockquoteHandling); 265 265 else 266 266 pasteAsPlainTextWithPasteboard(pasteboard); 267 267 } 268 268 269 static void maybeCopyNodeAttributesToFragment(Node* node, DocumentFragment* fragment) 270 { 271 // This is only supported for single-Node fragments. 272 Node* firstChild = fragment->firstChild(); 273 if (firstChild != fragment->lastChild()) 274 return; 275 276 // And only supported for HTML elements. 277 if (!node->isHTMLElement() || !firstChild->isHTMLElement()) 278 return; 279 280 // And only if the source Element and destination Element have the same HTML tag name. 281 const Element& oldElement = toHTMLElement(*node); 282 Element& newElement = toHTMLElement(*firstChild); 283 if (!oldElement.hasTagName(newElement.tagQName())) 284 return; 285 286 for (const Attribute& attribute : oldElement.attributesIterator()) { 287 if (newElement.hasAttribute(attribute.name())) 288 continue; 289 newElement.setAttribute(attribute.name(), attribute.value()); 290 } 291 } 292 269 293 void Editor::replaceNodeFromPasteboard(Node* node, const String& pasteboardName) 270 294 { … … 277 301 m_frame.selection().setSelection(VisibleSelection(range.get()), FrameSelection::DoNotSetFocus); 278 302 279 readSelectionFromPasteboard(pasteboardName); 303 Pasteboard pasteboard(pasteboardName); 304 305 if (!m_frame.selection().selection().isContentRichlyEditable()) { 306 pasteAsPlainTextWithPasteboard(pasteboard); 307 return; 308 } 309 310 // FIXME: How can this hard-coded pasteboard name be right, given that the passed-in pasteboard has a name? 311 client()->setInsertionPasteboard(NSGeneralPboard); 312 313 bool chosePlainText; 314 RefPtr<DocumentFragment> fragment = webContentFromPasteboard(pasteboard, *range, true, chosePlainText); 315 316 maybeCopyNodeAttributesToFragment(node, fragment.get()); 317 318 if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted)) 319 pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), false, MailBlockquoteHandling::IgnoreBlockquote); 320 321 client()->setInsertionPasteboard(String()); 280 322 } 281 323
Note: See TracChangeset
for help on using the changeset viewer.