2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef __htmlediting_h__
27 #define __htmlediting_h__
29 #include "edit_command.h"
30 #include "dom_nodeimpl.h"
31 #include "editing/edit_actions.h"
34 #include "qvaluelist.h"
35 #include "selection.h"
39 class CSSMutableStyleDeclarationImpl;
41 class CSSStyleDeclarationImpl;
42 class DocumentFragmentImpl;
43 class HTMLElementImpl;
51 class VisiblePosition;
53 //------------------------------------------------------------------------------------------
58 enum ELegacyHTMLStyles { DoNotUseLegacyHTMLStyles, UseLegacyHTMLStyles };
60 explicit StyleChange(DOM::CSSStyleDeclarationImpl *, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
61 StyleChange(DOM::CSSStyleDeclarationImpl *, const DOM::Position &, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
63 static ELegacyHTMLStyles styleModeForParseMode(bool);
65 DOM::DOMString cssStyle() const { return m_cssStyle; }
66 bool applyBold() const { return m_applyBold; }
67 bool applyItalic() const { return m_applyItalic; }
68 bool applyFontColor() const { return m_applyFontColor.length() > 0; }
69 bool applyFontFace() const { return m_applyFontFace.length() > 0; }
70 bool applyFontSize() const { return m_applyFontSize.length() > 0; }
72 DOM::DOMString fontColor() { return m_applyFontColor; }
73 DOM::DOMString fontFace() { return m_applyFontFace; }
74 DOM::DOMString fontSize() { return m_applyFontSize; }
76 bool usesLegacyStyles() const { return m_usesLegacyStyles; }
79 void init(DOM::CSSStyleDeclarationImpl *, const DOM::Position &);
80 bool checkForLegacyHTMLStyleChange(const DOM::CSSProperty *);
81 static bool currentlyHasStyle(const DOM::Position &, const DOM::CSSProperty *);
83 DOM::DOMString m_cssStyle;
86 DOM::DOMString m_applyFontColor;
87 DOM::DOMString m_applyFontFace;
88 DOM::DOMString m_applyFontSize;
89 bool m_usesLegacyStyles;
92 //------------------------------------------------------------------------------------------
93 // CompositeEditCommand
95 class CompositeEditCommand : public EditCommand
98 CompositeEditCommand(DOM::DocumentImpl *);
100 virtual void doUnapply();
101 virtual void doReapply();
105 // sugary-sweet convenience functions to help create and apply edit commands in composite commands
107 void appendNode(DOM::NodeImpl *appendChild, DOM::NodeImpl *parentNode);
108 void applyCommandToComposite(EditCommandPtr &);
109 void applyStyle(DOM::CSSStyleDeclarationImpl *style, EditAction editingAction=EditActionChangeAttributes);
110 void deleteKeyPressed();
111 void deleteSelection(bool smartDelete=false, bool mergeBlocksAfterDelete=true);
112 void deleteSelection(const Selection &selection, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
113 void deleteTextFromNode(DOM::TextImpl *node, long offset, long count);
114 void inputText(const DOM::DOMString &text, bool selectInsertedText = false);
115 void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
116 void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
117 void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
118 void insertParagraphSeparator();
119 void insertTextIntoNode(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
120 void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
121 void rebalanceWhitespace();
122 void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
123 void removeFullySelectedNode(DOM::NodeImpl *node);
124 void removeNodeAttribute(DOM::ElementImpl *, int attribute);
125 void removeChildrenInRange(DOM::NodeImpl *node, int from, int to);
126 void removeNode(DOM::NodeImpl *removeChild);
127 void removeNodePreservingChildren(DOM::NodeImpl *node);
128 void replaceTextInNode(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
129 void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
130 void splitTextNode(DOM::TextImpl *text, long offset);
131 void splitElement(DOM::ElementImpl *element, DOM::NodeImpl *atChild);
132 void mergeIdenticalElements(DOM::ElementImpl *first, DOM::ElementImpl *second);
133 void wrapContentsInDummySpan(DOM::ElementImpl *element);
134 void splitTextNodeContainingElement(DOM::TextImpl *text, long offset);
136 void deleteInsignificantText(DOM::TextImpl *, int start, int end);
137 void deleteInsignificantText(const DOM::Position &start, const DOM::Position &end);
138 void deleteInsignificantTextDownstream(const DOM::Position &);
140 DOM::NodeImpl *appendBlockPlaceholder(DOM::NodeImpl *);
141 DOM::NodeImpl *insertBlockPlaceholder(const DOM::Position &pos);
142 DOM::NodeImpl *addBlockPlaceholderIfNeeded(DOM::NodeImpl *);
143 bool removeBlockPlaceholder(DOM::NodeImpl *);
144 DOM::NodeImpl *findBlockPlaceholder(DOM::NodeImpl *);
146 void moveParagraphContentsToNewBlockIfNecessary(const DOM::Position &);
148 QValueList<EditCommandPtr> m_cmds;
151 //==========================================================================================
153 //------------------------------------------------------------------------------------------
156 class AppendNodeCommand : public EditCommand
159 AppendNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *appendChild, DOM::NodeImpl *parentNode);
160 virtual ~AppendNodeCommand();
162 virtual void doApply();
163 virtual void doUnapply();
165 DOM::NodeImpl *appendChild() const { return m_appendChild; }
166 DOM::NodeImpl *parentNode() const { return m_parentNode; }
169 DOM::NodeImpl *m_appendChild;
170 DOM::NodeImpl *m_parentNode;
173 //------------------------------------------------------------------------------------------
176 class ApplyStyleCommand : public CompositeEditCommand
179 enum EPropertyLevel { PropertyDefault, ForceBlockProperties };
181 ApplyStyleCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *style, EditAction editingAction=EditActionChangeAttributes, EPropertyLevel=PropertyDefault);
182 virtual ~ApplyStyleCommand();
184 virtual void doApply();
185 virtual EditAction editingAction() const;
187 DOM::CSSMutableStyleDeclarationImpl *style() const { return m_style; }
190 // style-removal helpers
191 bool isHTMLStyleNode(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
192 void removeHTMLStyleNode(DOM::HTMLElementImpl *);
193 void removeHTMLFontStyle(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
194 void removeCSSStyle(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
195 void removeBlockStyle(DOM::CSSMutableStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
196 void removeInlineStyle(DOM::CSSMutableStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
197 bool nodeFullySelected(DOM::NodeImpl *, const DOM::Position &start, const DOM::Position &end) const;
198 bool nodeFullyUnselected(DOM::NodeImpl *node, const DOM::Position &start, const DOM::Position &end) const;
199 DOM::CSSMutableStyleDeclarationImpl *extractTextDecorationStyle(DOM::NodeImpl *node);
200 DOM::CSSMutableStyleDeclarationImpl *extractAndNegateTextDecorationStyle(DOM::NodeImpl *node);
201 void applyTextDecorationStyle(DOM::NodeImpl *node, DOM::CSSMutableStyleDeclarationImpl *style);
202 void pushDownTextDecorationStyleAroundNode(DOM::NodeImpl *node, const DOM::Position &start, const DOM::Position &end, bool force);
203 void pushDownTextDecorationStyleAtBoundaries(const DOM::Position &start, const DOM::Position &end);
205 // style-application helpers
206 void applyBlockStyle(DOM::CSSMutableStyleDeclarationImpl *);
207 void applyRelativeFontStyleChange(DOM::CSSMutableStyleDeclarationImpl *);
208 void applyInlineStyle(DOM::CSSMutableStyleDeclarationImpl *);
209 void addBlockStyleIfNeeded(DOM::CSSMutableStyleDeclarationImpl *, DOM::NodeImpl *);
210 void addInlineStyleIfNeeded(DOM::CSSMutableStyleDeclarationImpl *, DOM::NodeImpl *start, DOM::NodeImpl *end);
211 bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
212 bool splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
213 bool splitTextElementAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
214 bool splitTextElementAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
215 bool mergeStartWithPreviousIfIdentical(const DOM::Position &start, const DOM::Position &end);
216 bool mergeEndWithNextIfIdentical(const DOM::Position &start, const DOM::Position &end);
217 void cleanUpEmptyStyleSpans(const DOM::Position &start, const DOM::Position &end);
219 void surroundNodeRangeWithElement(DOM::NodeImpl *start, DOM::NodeImpl *end, DOM::ElementImpl *element);
220 float computedFontSize(const DOM::NodeImpl *);
221 void joinChildTextNodes(DOM::NodeImpl *, const DOM::Position &start, const DOM::Position &end);
223 DOM::CSSMutableStyleDeclarationImpl *m_style;
224 EditAction m_editingAction;
225 EPropertyLevel m_propertyLevel;
228 //------------------------------------------------------------------------------------------
229 // DeleteFromTextNodeCommand
231 class DeleteFromTextNodeCommand : public EditCommand
234 DeleteFromTextNodeCommand(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
235 virtual ~DeleteFromTextNodeCommand();
237 virtual void doApply();
238 virtual void doUnapply();
240 DOM::TextImpl *node() const { return m_node; }
241 long offset() const { return m_offset; }
242 long count() const { return m_count; }
245 DOM::TextImpl *m_node;
248 DOM::DOMString m_text;
251 //------------------------------------------------------------------------------------------
252 // DeleteSelectionCommand
254 class DeleteSelectionCommand : public CompositeEditCommand
257 DeleteSelectionCommand(DOM::DocumentImpl *document, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
258 DeleteSelectionCommand(DOM::DocumentImpl *document, const Selection &selection, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
260 virtual void doApply();
261 virtual EditAction editingAction() const;
264 virtual bool preservesTypingStyle() const;
266 void initializePositionData();
267 void saveTypingStyleState();
268 void insertPlaceholderForAncestorBlockContent();
269 bool handleSpecialCaseBRDelete();
270 void handleGeneralDelete();
271 void fixupWhitespace();
272 void moveNodesAfterNode();
273 void calculateEndingPosition();
274 void calculateTypingStyleAfterDelete(DOM::NodeImpl *insertedPlaceholder);
275 void clearTransientState();
277 void setStartNode(DOM::NodeImpl *);
279 bool m_hasSelectionToDelete;
281 bool m_mergeBlocksAfterDelete;
282 bool m_trailingWhitespaceValid;
284 // This data is transient and should be cleared at the end of the doApply function.
285 Selection m_selectionToDelete;
286 DOM::Position m_upstreamStart;
287 DOM::Position m_downstreamStart;
288 DOM::Position m_upstreamEnd;
289 DOM::Position m_downstreamEnd;
290 DOM::Position m_endingPosition;
291 DOM::Position m_leadingWhitespace;
292 DOM::Position m_trailingWhitespace;
293 DOM::NodeImpl *m_startBlock;
294 DOM::NodeImpl *m_endBlock;
295 DOM::NodeImpl *m_startNode;
296 DOM::CSSMutableStyleDeclarationImpl *m_typingStyle;
299 //------------------------------------------------------------------------------------------
300 // InsertIntoTextNode
302 class InsertIntoTextNode : public EditCommand
305 InsertIntoTextNode(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
306 virtual ~InsertIntoTextNode();
308 virtual void doApply();
309 virtual void doUnapply();
311 DOM::TextImpl *node() const { return m_node; }
312 long offset() const { return m_offset; }
313 DOM::DOMString text() const { return m_text; }
316 DOM::TextImpl *m_node;
318 DOM::DOMString m_text;
321 //------------------------------------------------------------------------------------------
322 // InsertNodeBeforeCommand
324 class InsertNodeBeforeCommand : public EditCommand
327 InsertNodeBeforeCommand(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
328 virtual ~InsertNodeBeforeCommand();
330 virtual void doApply();
331 virtual void doUnapply();
333 DOM::NodeImpl *insertChild() const { return m_insertChild; }
334 DOM::NodeImpl *refChild() const { return m_refChild; }
337 DOM::NodeImpl *m_insertChild;
338 DOM::NodeImpl *m_refChild;
341 //------------------------------------------------------------------------------------------
342 // InsertLineBreakCommand
344 class InsertLineBreakCommand : public CompositeEditCommand
347 InsertLineBreakCommand(DOM::DocumentImpl *document);
349 virtual void doApply();
352 virtual bool preservesTypingStyle() const;
353 void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
354 void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
357 //------------------------------------------------------------------------------------------
358 // InsertParagraphSeparatorCommand
360 class InsertParagraphSeparatorCommand : public CompositeEditCommand
363 InsertParagraphSeparatorCommand(DOM::DocumentImpl *document);
364 virtual ~InsertParagraphSeparatorCommand();
366 virtual void doApply();
369 DOM::ElementImpl *createParagraphElement();
370 void calculateStyleBeforeInsertion(const DOM::Position &);
371 void applyStyleAfterInsertion();
373 virtual bool preservesTypingStyle() const;
375 QPtrList<DOM::NodeImpl> ancestors;
376 QPtrList<DOM::NodeImpl> clonedNodes;
377 DOM::CSSMutableStyleDeclarationImpl *m_style;
380 //------------------------------------------------------------------------------------------
381 // InsertParagraphSeparatorInQuotedContentCommand
383 class InsertParagraphSeparatorInQuotedContentCommand : public CompositeEditCommand
386 InsertParagraphSeparatorInQuotedContentCommand(DOM::DocumentImpl *);
387 virtual ~InsertParagraphSeparatorInQuotedContentCommand();
389 virtual void doApply();
392 QPtrList<DOM::NodeImpl> ancestors;
393 QPtrList<DOM::NodeImpl> clonedNodes;
394 DOM::ElementImpl *m_breakNode;
397 //------------------------------------------------------------------------------------------
400 class InsertTextCommand : public CompositeEditCommand
403 InsertTextCommand(DOM::DocumentImpl *document);
405 virtual void doApply();
407 void deleteCharacter();
408 void input(const DOM::DOMString &text, bool selectInsertedText = false);
410 unsigned long charactersAdded() const { return m_charactersAdded; }
413 virtual bool isInsertTextCommand() const;
415 DOM::Position prepareForTextInsertion(bool adjustDownstream);
416 void insertSpace(DOM::TextImpl *textNode, unsigned long offset);
418 unsigned long m_charactersAdded;
421 //------------------------------------------------------------------------------------------
422 // JoinTextNodesCommand
424 class JoinTextNodesCommand : public EditCommand
427 JoinTextNodesCommand(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
428 virtual ~JoinTextNodesCommand();
430 virtual void doApply();
431 virtual void doUnapply();
433 DOM::TextImpl *firstNode() const { return m_text1; }
434 DOM::TextImpl *secondNode() const { return m_text2; }
437 DOM::TextImpl *m_text1;
438 DOM::TextImpl *m_text2;
439 unsigned long m_offset;
442 //------------------------------------------------------------------------------------------
443 // MoveSelectionCommand
445 class MoveSelectionCommand : public CompositeEditCommand
448 MoveSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, DOM::Position &position, bool smartMove=false);
449 virtual ~MoveSelectionCommand();
451 virtual void doApply();
452 virtual EditAction editingAction() const;
455 DOM::DocumentFragmentImpl *m_fragment;
456 DOM::Position m_position;
460 //------------------------------------------------------------------------------------------
461 // RebalanceWhitespaceCommand
463 class RebalanceWhitespaceCommand : public EditCommand
466 RebalanceWhitespaceCommand(DOM::DocumentImpl *, const DOM::Position &);
467 virtual ~RebalanceWhitespaceCommand();
469 virtual void doApply();
470 virtual void doUnapply();
473 enum { InvalidOffset = -1 };
475 virtual bool preservesTypingStyle() const;
477 DOM::DOMString m_beforeString;
478 DOM::DOMString m_afterString;
479 DOM::Position m_position;
480 long m_upstreamOffset;
481 long m_downstreamOffset;
484 //------------------------------------------------------------------------------------------
485 // RemoveCSSPropertyCommand
487 class RemoveCSSPropertyCommand : public EditCommand
490 RemoveCSSPropertyCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
491 virtual ~RemoveCSSPropertyCommand();
493 virtual void doApply();
494 virtual void doUnapply();
496 DOM::CSSMutableStyleDeclarationImpl *styleDeclaration() const { return m_decl; }
497 int property() const { return m_property; }
500 DOM::CSSMutableStyleDeclarationImpl *m_decl;
502 DOM::DOMString m_oldValue;
506 //------------------------------------------------------------------------------------------
507 // RemoveNodeAttributeCommand
509 class RemoveNodeAttributeCommand : public EditCommand
512 RemoveNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
513 virtual ~RemoveNodeAttributeCommand();
515 virtual void doApply();
516 virtual void doUnapply();
518 DOM::ElementImpl *element() const { return m_element; }
519 DOM::NodeImpl::Id attribute() const { return m_attribute; }
522 DOM::ElementImpl *m_element;
523 DOM::NodeImpl::Id m_attribute;
524 DOM::DOMString m_oldValue;
527 //------------------------------------------------------------------------------------------
530 class RemoveNodeCommand : public EditCommand
533 RemoveNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
534 virtual ~RemoveNodeCommand();
536 virtual void doApply();
537 virtual void doUnapply();
539 DOM::NodeImpl *node() const { return m_removeChild; }
542 DOM::NodeImpl *m_parent;
543 DOM::NodeImpl *m_removeChild;
544 DOM::NodeImpl *m_refChild;
547 //------------------------------------------------------------------------------------------
548 // RemoveNodePreservingChildrenCommand
550 class RemoveNodePreservingChildrenCommand : public CompositeEditCommand
553 RemoveNodePreservingChildrenCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
554 virtual ~RemoveNodePreservingChildrenCommand();
556 virtual void doApply();
558 DOM::NodeImpl *node() const { return m_node; }
561 DOM::NodeImpl *m_node;
564 //------------------------------------------------------------------------------------------
565 // ReplaceSelectionCommand
567 // --- NodeDesiredStyle helper class
569 class NodeDesiredStyle
572 NodeDesiredStyle(DOM::NodeImpl *, DOM::CSSMutableStyleDeclarationImpl *);
573 NodeDesiredStyle(const NodeDesiredStyle &);
576 DOM::NodeImpl *node() const { return m_node; }
577 DOM::CSSMutableStyleDeclarationImpl *style() const { return m_style; }
579 NodeDesiredStyle &operator=(const NodeDesiredStyle &);
582 DOM::NodeImpl *m_node;
583 DOM::CSSMutableStyleDeclarationImpl *m_style;
586 // --- ReplacementFragment helper class
588 class ReplacementFragment
591 ReplacementFragment(DOM::DocumentImpl *, DOM::DocumentFragmentImpl *, bool matchStyle);
592 ~ReplacementFragment();
594 enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
596 DOM::DocumentFragmentImpl *root() const { return m_fragment; }
597 DOM::NodeImpl *firstChild() const;
598 DOM::NodeImpl *lastChild() const;
600 DOM::NodeImpl *mergeStartNode() const;
602 const QValueList<NodeDesiredStyle> &desiredStyles() { return m_styles; }
604 void pruneEmptyNodes();
606 EFragmentType type() const { return m_type; }
607 bool isEmpty() const { return m_type == EmptyFragment; }
608 bool isSingleTextNode() const { return m_type == SingleTextNodeFragment; }
609 bool isTreeFragment() const { return m_type == TreeFragment; }
611 bool hasMoreThanOneBlock() const { return m_hasMoreThanOneBlock; }
612 bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAtStart; }
613 bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEnd; }
616 // no copy construction or assignment
617 ReplacementFragment(const ReplacementFragment &);
618 ReplacementFragment &operator=(const ReplacementFragment &);
620 static bool isInterchangeNewlineNode(const DOM::NodeImpl *);
621 static bool isInterchangeConvertedSpaceSpan(const DOM::NodeImpl *);
623 DOM::NodeImpl *insertFragmentForTestRendering();
624 void restoreTestRenderingNodesToFragment(DOM::NodeImpl *);
625 void computeStylesUsingTestRendering(DOM::NodeImpl *);
626 void removeUnrenderedNodesUsingTestRendering(DOM::NodeImpl *);
627 int countRenderedBlocks(DOM::NodeImpl *holder);
628 void removeStyleNodes();
630 // A couple simple DOM helpers
631 DOM::NodeImpl *enclosingBlock(DOM::NodeImpl *) const;
632 void removeNode(DOM::NodeImpl *);
633 void removeNodePreservingChildren(DOM::NodeImpl *);
634 void insertNodeBefore(DOM::NodeImpl *node, DOM::NodeImpl *refNode);
636 EFragmentType m_type;
637 DOM::DocumentImpl *m_document;
638 DOM::DocumentFragmentImpl *m_fragment;
639 QValueList<NodeDesiredStyle> m_styles;
641 bool m_hasInterchangeNewlineAtStart;
642 bool m_hasInterchangeNewlineAtEnd;
643 bool m_hasMoreThanOneBlock;
646 class ReplaceSelectionCommand : public CompositeEditCommand
649 ReplaceSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true, bool smartReplace=false, bool matchStyle=false);
650 virtual ~ReplaceSelectionCommand();
652 virtual void doApply();
653 virtual EditAction editingAction() const;
656 void completeHTMLReplacement(const DOM::Position &lastPositionToSelect);
658 void insertNodeAfterAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
659 void insertNodeAtAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
660 void insertNodeBeforeAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
662 void updateNodesInserted(DOM::NodeImpl *);
663 void fixupNodeStyles(const QValueList<NodeDesiredStyle> &);
664 void removeLinePlaceholderIfNeeded(DOM::NodeImpl *);
666 ReplacementFragment m_fragment;
667 DOM::NodeImpl *m_firstNodeInserted;
668 DOM::NodeImpl *m_lastNodeInserted;
669 DOM::NodeImpl *m_lastTopNodeInserted;
670 DOM::CSSMutableStyleDeclarationImpl *m_insertionStyle;
671 bool m_selectReplacement;
676 void computeAndStoreNodeDesiredStyle(DOM::NodeImpl *, QValueList<NodeDesiredStyle> &);
678 //------------------------------------------------------------------------------------------
679 // SetNodeAttributeCommand
681 class SetNodeAttributeCommand : public EditCommand
684 SetNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
685 virtual ~SetNodeAttributeCommand();
687 virtual void doApply();
688 virtual void doUnapply();
690 DOM::ElementImpl *element() const { return m_element; }
691 DOM::NodeImpl::Id attribute() const { return m_attribute; }
692 DOM::DOMString value() const { return m_value; }
695 DOM::ElementImpl *m_element;
696 DOM::NodeImpl::Id m_attribute;
697 DOM::DOMString m_value;
698 DOM::DOMString m_oldValue;
701 //------------------------------------------------------------------------------------------
702 // SplitTextNodeCommand
704 class SplitTextNodeCommand : public EditCommand
707 SplitTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
708 virtual ~SplitTextNodeCommand();
710 virtual void doApply();
711 virtual void doUnapply();
713 DOM::TextImpl *node() const { return m_text2; }
714 long offset() const { return m_offset; }
717 DOM::TextImpl *m_text1;
718 DOM::TextImpl *m_text2;
719 unsigned long m_offset;
722 //------------------------------------------------------------------------------------------
723 // WrapContentsInDummySpanCommand
725 class WrapContentsInDummySpanCommand : public EditCommand
728 WrapContentsInDummySpanCommand(DOM::DocumentImpl *, DOM::ElementImpl *);
729 virtual ~WrapContentsInDummySpanCommand();
731 virtual void doApply();
732 virtual void doUnapply();
735 DOM::ElementImpl *m_element;
736 DOM::ElementImpl *m_dummySpan;
739 //------------------------------------------------------------------------------------------
740 // SplitElementCommand
742 class SplitElementCommand : public EditCommand
745 SplitElementCommand(DOM::DocumentImpl *, DOM::ElementImpl *element, DOM::NodeImpl *atChild);
746 virtual ~SplitElementCommand();
748 virtual void doApply();
749 virtual void doUnapply();
752 DOM::ElementImpl *m_element1;
753 DOM::ElementImpl *m_element2;
754 DOM::NodeImpl *m_atChild;
757 //------------------------------------------------------------------------------------------
758 // MergeIdenticalElementsCommand
760 class MergeIdenticalElementsCommand : public EditCommand
763 MergeIdenticalElementsCommand(DOM::DocumentImpl *, DOM::ElementImpl *first, DOM::ElementImpl *second);
764 virtual ~MergeIdenticalElementsCommand();
766 virtual void doApply();
767 virtual void doUnapply();
770 DOM::ElementImpl *m_element1;
771 DOM::ElementImpl *m_element2;
772 DOM::NodeImpl *m_atChild;
775 //------------------------------------------------------------------------------------------
776 // SplitTextNodeContainingElementCommand
778 class SplitTextNodeContainingElementCommand : public CompositeEditCommand
781 SplitTextNodeContainingElementCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
782 virtual ~SplitTextNodeContainingElementCommand();
784 virtual void doApply();
787 DOM::TextImpl *m_text;
792 //------------------------------------------------------------------------------------------
795 class TypingCommand : public CompositeEditCommand
798 enum ETypingCommand {
803 InsertParagraphSeparator,
804 InsertParagraphSeparatorInQuotedContent,
807 TypingCommand(DOM::DocumentImpl *document, ETypingCommand, const DOM::DOMString &text = "", bool selectInsertedText = false);
809 static void deleteKeyPressed(DOM::DocumentImpl *, bool smartDelete = false);
810 static void forwardDeleteKeyPressed(DOM::DocumentImpl *, bool smartDelete = false);
811 static void insertText(DOM::DocumentImpl *, const DOM::DOMString &, bool selectInsertedText = false);
812 static void insertLineBreak(DOM::DocumentImpl *);
813 static void insertParagraphSeparator(DOM::DocumentImpl *);
814 static void insertParagraphSeparatorInQuotedContent(DOM::DocumentImpl *);
815 static bool isOpenForMoreTypingCommand(const EditCommandPtr &);
816 static void closeTyping(const EditCommandPtr &);
818 virtual void doApply();
819 virtual EditAction editingAction() const;
821 bool openForMoreTyping() const { return m_openForMoreTyping; }
822 void closeTyping() { m_openForMoreTyping = false; }
824 void insertText(const DOM::DOMString &text, bool selectInsertedText);
825 void insertTextRunWithoutNewlines(const DOM::DOMString &text, bool selectInsertedText);
826 void insertLineBreak();
827 void insertParagraphSeparatorInQuotedContent();
828 void insertParagraphSeparator();
829 void deleteKeyPressed();
830 void forwardDeleteKeyPressed();
832 bool smartDelete() { return m_smartDelete; }
833 void setSmartDelete(bool smartDelete) { m_smartDelete = smartDelete; }
836 virtual bool isTypingCommand() const;
837 virtual bool preservesTypingStyle() const;
839 void markMisspellingsAfterTyping();
840 void typingAddedToOpenCommand();
842 ETypingCommand m_commandType;
843 DOM::DOMString m_textToInsert;
844 bool m_openForMoreTyping;
846 bool m_selectInsertedText;
850 //------------------------------------------------------------------------------------------
852 DOM::ElementImpl *floatRefdElement(DOM::ElementImpl *element);
853 DOM::ElementImpl *createDefaultParagraphElement(DOM::DocumentImpl *document);
854 DOM::ElementImpl *createBlockPlaceholderElement(DOM::DocumentImpl *document);
855 DOM::ElementImpl *createBreakElement(DOM::DocumentImpl *document);
856 DOM::ElementImpl *createFontElement(DOM::DocumentImpl *document);
857 DOM::ElementImpl *createStyleSpanElement(DOM::DocumentImpl *document);
859 bool isNodeRendered(const DOM::NodeImpl *);
860 bool isProbablyBlock(const DOM::NodeImpl *);
861 bool isProbablyTableStructureNode(const DOM::NodeImpl *);
862 bool isMailBlockquote(const DOM::NodeImpl *);
863 DOM::NodeImpl *nearestMailBlockquote(const DOM::NodeImpl *);
864 bool isMailPasteAsQuotationNode(const DOM::NodeImpl *node);
866 //------------------------------------------------------------------------------------------
868 } // end namespace khtml