| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2  * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 
| 3  * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 3  * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 
| 4  * | 4  * | 
| 5  * Redistribution and use in source and binary forms, with or without | 5  * Redistribution and use in source and binary forms, with or without | 
| 6  * modification, are permitted provided that the following conditions | 6  * modification, are permitted provided that the following conditions | 
| 7  * are met: | 7  * are met: | 
| 8  * 1. Redistributions of source code must retain the above copyright | 8  * 1. Redistributions of source code must retain the above copyright | 
| 9  *    notice, this list of conditions and the following disclaimer. | 9  *    notice, this list of conditions and the following disclaimer. | 
| 10  * 2. Redistributions in binary form must reproduce the above copyright | 10  * 2. Redistributions in binary form must reproduce the above copyright | 
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 171 | 171 | 
| 172     RefPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.g
      et()).toNormalizedRange(); | 172     RefPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.g
      et()).toNormalizedRange(); | 
| 173     String text = plainText(range.get(), static_cast<TextIteratorBehavior>(TextI
      teratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility)); | 173     String text = plainText(range.get(), static_cast<TextIteratorBehavior>(TextI
      teratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility)); | 
| 174 | 174 | 
| 175     removeInterchangeNodes(holder.get()); | 175     removeInterchangeNodes(holder.get()); | 
| 176     removeUnrenderedNodes(holder.get()); | 176     removeUnrenderedNodes(holder.get()); | 
| 177     restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 177     restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 
| 178 | 178 | 
| 179     // Give the root a chance to change the text. | 179     // Give the root a chance to change the text. | 
| 180     RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text); | 180     RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text); | 
| 181     editableRoot->dispatchEvent(evt, ASSERT_NO_EXCEPTION_STATE); | 181     editableRoot->dispatchEvent(evt, ASSERT_NO_EXCEPTION); | 
| 182     if (text != evt->text() || !editableRoot->rendererIsRichlyEditable()) { | 182     if (text != evt->text() || !editableRoot->rendererIsRichlyEditable()) { | 
| 183         restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 183         restoreAndRemoveTestRenderingNodesToFragment(holder.get()); | 
| 184 | 184 | 
| 185         m_fragment = createFragmentFromText(selection.toNormalizedRange().get(),
       evt->text()); | 185         m_fragment = createFragmentFromText(selection.toNormalizedRange().get(),
       evt->text()); | 
| 186         if (!m_fragment->firstChild()) | 186         if (!m_fragment->firstChild()) | 
| 187             return; | 187             return; | 
| 188 | 188 | 
| 189         holder = insertFragmentForTestRendering(editableRoot.get()); | 189         holder = insertFragmentForTestRendering(editableRoot.get()); | 
| 190         removeInterchangeNodes(holder.get()); | 190         removeInterchangeNodes(holder.get()); | 
| 191         removeUnrenderedNodes(holder.get()); | 191         removeUnrenderedNodes(holder.get()); | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 222 | 222 | 
| 223 void ReplacementFragment::removeNode(PassRefPtr<Node> node) | 223 void ReplacementFragment::removeNode(PassRefPtr<Node> node) | 
| 224 { | 224 { | 
| 225     if (!node) | 225     if (!node) | 
| 226         return; | 226         return; | 
| 227 | 227 | 
| 228     ContainerNode* parent = node->nonShadowBoundaryParentNode(); | 228     ContainerNode* parent = node->nonShadowBoundaryParentNode(); | 
| 229     if (!parent) | 229     if (!parent) | 
| 230         return; | 230         return; | 
| 231 | 231 | 
| 232     parent->removeChild(node.get(), ASSERT_NO_EXCEPTION_STATE); | 232     parent->removeChild(node.get(), ASSERT_NO_EXCEPTION); | 
| 233 } | 233 } | 
| 234 | 234 | 
| 235 void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode) | 235 void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode) | 
| 236 { | 236 { | 
| 237     if (!node || !refNode) | 237     if (!node || !refNode) | 
| 238         return; | 238         return; | 
| 239 | 239 | 
| 240     ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); | 240     ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); | 
| 241     if (!parent) | 241     if (!parent) | 
| 242         return; | 242         return; | 
| 243 | 243 | 
| 244     parent->insertBefore(node, refNode, ASSERT_NO_EXCEPTION_STATE); | 244     parent->insertBefore(node, refNode, ASSERT_NO_EXCEPTION); | 
| 245 } | 245 } | 
| 246 | 246 | 
| 247 PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* ro
      otEditableElement) | 247 PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* ro
      otEditableElement) | 
| 248 { | 248 { | 
| 249     RefPtr<Element> holder = createDefaultParagraphElement(m_document.get()); | 249     RefPtr<Element> holder = createDefaultParagraphElement(m_document.get()); | 
| 250 | 250 | 
| 251     holder->appendChild(m_fragment, ASSERT_NO_EXCEPTION_STATE); | 251     holder->appendChild(m_fragment, ASSERT_NO_EXCEPTION); | 
| 252     rootEditableElement->appendChild(holder.get(), ASSERT_NO_EXCEPTION_STATE); | 252     rootEditableElement->appendChild(holder.get(), ASSERT_NO_EXCEPTION); | 
| 253     m_document->updateLayoutIgnorePendingStylesheets(); | 253     m_document->updateLayoutIgnorePendingStylesheets(); | 
| 254 | 254 | 
| 255     return holder.release(); | 255     return holder.release(); | 
| 256 } | 256 } | 
| 257 | 257 | 
| 258 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* 
      holder) | 258 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element* 
      holder) | 
| 259 { | 259 { | 
| 260     if (!holder) | 260     if (!holder) | 
| 261         return; | 261         return; | 
| 262 | 262 | 
| 263     while (RefPtr<Node> node = holder->firstChild()) { | 263     while (RefPtr<Node> node = holder->firstChild()) { | 
| 264         holder->removeChild(node.get(), ASSERT_NO_EXCEPTION_STATE); | 264         holder->removeChild(node.get(), ASSERT_NO_EXCEPTION); | 
| 265         m_fragment->appendChild(node.get(), ASSERT_NO_EXCEPTION_STATE); | 265         m_fragment->appendChild(node.get(), ASSERT_NO_EXCEPTION); | 
| 266     } | 266     } | 
| 267 | 267 | 
| 268     removeNode(holder); | 268     removeNode(holder); | 
| 269 } | 269 } | 
| 270 | 270 | 
| 271 void ReplacementFragment::removeUnrenderedNodes(Node* holder) | 271 void ReplacementFragment::removeUnrenderedNodes(Node* holder) | 
| 272 { | 272 { | 
| 273     Vector<RefPtr<Node> > unrendered; | 273     Vector<RefPtr<Node> > unrendered; | 
| 274 | 274 | 
| 275     for (Node* node = holder->firstChild(); node; node = NodeTraversal::next(nod
      e, holder)) | 275     for (Node* node = holder->firstChild(); node; node = NodeTraversal::next(nod
      e, holder)) | 
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 540             } | 540             } | 
| 541             // There are other styles that style rules can give to style spans, | 541             // There are other styles that style rules can give to style spans, | 
| 542             // but these are the two important ones because they'll prevent | 542             // but these are the two important ones because they'll prevent | 
| 543             // inserted content from appearing in the right paragraph. | 543             // inserted content from appearing in the right paragraph. | 
| 544             // FIXME: Hyatt is concerned that selectively using display:inline w
      ill give inconsistent | 544             // FIXME: Hyatt is concerned that selectively using display:inline w
      ill give inconsistent | 
| 545             // results. We already know one issue because td elements ignore the
      ir display property | 545             // results. We already know one issue because td elements ignore the
      ir display property | 
| 546             // in quirks mode (which Mail.app is always in). We should look for 
      an alternative. | 546             // in quirks mode (which Mail.app is always in). We should look for 
      an alternative. | 
| 547 | 547 | 
| 548             // Mutate using the CSSOM wrapper so we get the same event behavior 
      as a script. | 548             // Mutate using the CSSOM wrapper so we get the same event behavior 
      as a script. | 
| 549             if (isBlock(element)) | 549             if (isBlock(element)) | 
| 550                 element->style()->setPropertyInternal(CSSPropertyDisplay, "inlin
      e", false, IGNORE_EXCEPTION_STATE); | 550                 element->style()->setPropertyInternal(CSSPropertyDisplay, "inlin
      e", false, IGNORE_EXCEPTION); | 
| 551             if (element->renderer() && element->renderer()->style()->isFloating(
      )) | 551             if (element->renderer() && element->renderer()->style()->isFloating(
      )) | 
| 552                 element->style()->setPropertyInternal(CSSPropertyFloat, "none", 
      false, IGNORE_EXCEPTION_STATE); | 552                 element->style()->setPropertyInternal(CSSPropertyFloat, "none", 
      false, IGNORE_EXCEPTION); | 
| 553         } | 553         } | 
| 554     } | 554     } | 
| 555 } | 555 } | 
| 556 | 556 | 
| 557 static bool isProhibitedParagraphChild(const AtomicString& name) | 557 static bool isProhibitedParagraphChild(const AtomicString& name) | 
| 558 { | 558 { | 
| 559     // https://dvcs.w3.org/hg/editing/raw-file/57abe6d3cb60/editing.html#prohibi
      ted-paragraph-child | 559     // https://dvcs.w3.org/hg/editing/raw-file/57abe6d3cb60/editing.html#prohibi
      ted-paragraph-child | 
| 560     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, elements, ()); | 560     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, elements, ()); | 
| 561     if (elements.isEmpty()) { | 561     if (elements.isEmpty()) { | 
| 562         elements.add(addressTag.localName()); | 562         elements.add(addressTag.localName()); | 
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1422     // If we're in the middle of a list item, we should split it into two separa
      te | 1422     // If we're in the middle of a list item, we should split it into two separa
      te | 
| 1423     // list items and insert these nodes between them. | 1423     // list items and insert these nodes between them. | 
| 1424     if (isMiddle) { | 1424     if (isMiddle) { | 
| 1425         int textNodeOffset = insertPos.offsetInContainerNode(); | 1425         int textNodeOffset = insertPos.offsetInContainerNode(); | 
| 1426         if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) | 1426         if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) | 
| 1427             splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); | 1427             splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); | 
| 1428         splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); | 1428         splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); | 
| 1429     } | 1429     } | 
| 1430 | 1430 | 
| 1431     while (RefPtr<Node> listItem = listElement->firstChild()) { | 1431     while (RefPtr<Node> listItem = listElement->firstChild()) { | 
| 1432         listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION_STATE); | 1432         listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); | 
| 1433         if (isStart || isMiddle) { | 1433         if (isStart || isMiddle) { | 
| 1434             insertNodeBefore(listItem, lastNode); | 1434             insertNodeBefore(listItem, lastNode); | 
| 1435             insertedNodes.respondToNodeInsertion(listItem.get()); | 1435             insertedNodes.respondToNodeInsertion(listItem.get()); | 
| 1436         } else if (isEnd) { | 1436         } else if (isEnd) { | 
| 1437             insertNodeAfter(listItem, lastNode); | 1437             insertNodeAfter(listItem, lastNode); | 
| 1438             insertedNodes.respondToNodeInsertion(listItem.get()); | 1438             insertedNodes.respondToNodeInsertion(listItem.get()); | 
| 1439             lastNode = listItem.get(); | 1439             lastNode = listItem.get(); | 
| 1440         } else | 1440         } else | 
| 1441             ASSERT_NOT_REACHED(); | 1441             ASSERT_NOT_REACHED(); | 
| 1442     } | 1442     } | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1487         removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); | 1487         removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); | 
| 1488 | 1488 | 
| 1489     VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
      d); | 1489     VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
      d); | 
| 1490 | 1490 | 
| 1491     setEndingSelection(selectionAfterReplace); | 1491     setEndingSelection(selectionAfterReplace); | 
| 1492 | 1492 | 
| 1493     return true; | 1493     return true; | 
| 1494 } | 1494 } | 
| 1495 | 1495 | 
| 1496 } // namespace WebCore | 1496 } // namespace WebCore | 
| OLD | NEW | 
|---|