Reviewed by Kevin.
[WebKit-https.git] / WebCore / khtml / editing / htmlediting.h
1 /*
2  * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #ifndef __htmlediting_h__
27 #define __htmlediting_h__
28
29 #include "edit_command.h"
30 #include "composite_edit_command.h"
31 #include "apply_style_command.h"
32
33 #include "dom_nodeimpl.h"
34 #include "editing/edit_actions.h"
35 #include "qmap.h"
36 #include "qptrlist.h"
37 #include "qvaluelist.h"
38 #include "selection.h"
39 #include "shared.h"
40
41 namespace DOM {
42     class CSSMutableStyleDeclarationImpl;
43     class CSSProperty;
44     class CSSStyleDeclarationImpl;
45     class DocumentFragmentImpl;
46     class HTMLElementImpl;
47     class TextImpl;
48 }
49
50 namespace khtml {
51
52 class Selection;
53 class VisiblePosition;
54
55 //------------------------------------------------------------------------------------------
56 // DeleteFromTextNodeCommand
57
58 class DeleteFromTextNodeCommand : public EditCommand
59 {
60 public:
61     DeleteFromTextNodeCommand(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
62     virtual ~DeleteFromTextNodeCommand();
63         
64     virtual void doApply();
65     virtual void doUnapply();
66
67     DOM::TextImpl *node() const { return m_node; }
68     long offset() const { return m_offset; }
69     long count() const { return m_count; }
70
71 private:
72     DOM::TextImpl *m_node;
73     long m_offset;
74     long m_count;
75     DOM::DOMString m_text;
76 };
77
78 //------------------------------------------------------------------------------------------
79 // DeleteSelectionCommand
80
81 class DeleteSelectionCommand : public CompositeEditCommand
82
83 public:
84     DeleteSelectionCommand(DOM::DocumentImpl *document, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
85     DeleteSelectionCommand(DOM::DocumentImpl *document, const Selection &selection, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
86         
87     virtual void doApply();
88     virtual EditAction editingAction() const;
89     
90 private:
91     virtual bool preservesTypingStyle() const;
92
93     void initializePositionData();
94     void saveTypingStyleState();
95     void insertPlaceholderForAncestorBlockContent();
96     bool handleSpecialCaseBRDelete();
97     void handleGeneralDelete();
98     void fixupWhitespace();
99     void moveNodesAfterNode();
100     void calculateEndingPosition();
101     void calculateTypingStyleAfterDelete(DOM::NodeImpl *insertedPlaceholder);
102     void clearTransientState();
103
104     void setStartNode(DOM::NodeImpl *);
105
106     bool m_hasSelectionToDelete;
107     bool m_smartDelete;
108     bool m_mergeBlocksAfterDelete;
109     bool m_trailingWhitespaceValid;
110
111     // This data is transient and should be cleared at the end of the doApply function.
112     Selection m_selectionToDelete;
113     DOM::Position m_upstreamStart;
114     DOM::Position m_downstreamStart;
115     DOM::Position m_upstreamEnd;
116     DOM::Position m_downstreamEnd;
117     DOM::Position m_endingPosition;
118     DOM::Position m_leadingWhitespace;
119     DOM::Position m_trailingWhitespace;
120     DOM::NodeImpl *m_startBlock;
121     DOM::NodeImpl *m_endBlock;
122     DOM::NodeImpl *m_startNode;
123     DOM::CSSMutableStyleDeclarationImpl *m_typingStyle;
124 };
125
126 //------------------------------------------------------------------------------------------
127 // InsertIntoTextNode
128
129 class InsertIntoTextNode : public EditCommand
130 {
131 public:
132     InsertIntoTextNode(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
133     virtual ~InsertIntoTextNode();
134         
135     virtual void doApply();
136     virtual void doUnapply();
137
138     DOM::TextImpl *node() const { return m_node; }
139     long offset() const { return m_offset; }
140     DOM::DOMString text() const { return m_text; }
141
142 private:
143     DOM::TextImpl *m_node;
144     long m_offset;
145     DOM::DOMString m_text;
146 };
147
148 //------------------------------------------------------------------------------------------
149 // InsertNodeBeforeCommand
150
151 class InsertNodeBeforeCommand : public EditCommand
152 {
153 public:
154     InsertNodeBeforeCommand(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
155     virtual ~InsertNodeBeforeCommand();
156
157     virtual void doApply();
158     virtual void doUnapply();
159
160     DOM::NodeImpl *insertChild() const { return m_insertChild; }
161     DOM::NodeImpl *refChild() const { return m_refChild; }
162
163 private:
164     DOM::NodeImpl *m_insertChild;
165     DOM::NodeImpl *m_refChild; 
166 };
167
168 //------------------------------------------------------------------------------------------
169 // InsertLineBreakCommand
170
171 class InsertLineBreakCommand : public CompositeEditCommand
172 {
173 public:
174     InsertLineBreakCommand(DOM::DocumentImpl *document);
175
176     virtual void doApply();
177
178 private:
179     virtual bool preservesTypingStyle() const;
180     void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
181     void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
182 };
183
184 //------------------------------------------------------------------------------------------
185 // InsertParagraphSeparatorCommand
186
187 class InsertParagraphSeparatorCommand : public CompositeEditCommand
188 {
189 public:
190     InsertParagraphSeparatorCommand(DOM::DocumentImpl *document);
191     virtual ~InsertParagraphSeparatorCommand();
192
193     virtual void doApply();
194
195 private:
196     DOM::ElementImpl *createParagraphElement();
197     void calculateStyleBeforeInsertion(const DOM::Position &);
198     void applyStyleAfterInsertion();
199
200     virtual bool preservesTypingStyle() const;
201
202     QPtrList<DOM::NodeImpl> ancestors;
203     QPtrList<DOM::NodeImpl> clonedNodes;
204     DOM::CSSMutableStyleDeclarationImpl *m_style;
205 };
206
207 //------------------------------------------------------------------------------------------
208 // InsertParagraphSeparatorInQuotedContentCommand
209
210 class InsertParagraphSeparatorInQuotedContentCommand : public CompositeEditCommand
211 {
212 public:
213     InsertParagraphSeparatorInQuotedContentCommand(DOM::DocumentImpl *);
214     virtual ~InsertParagraphSeparatorInQuotedContentCommand();
215         
216     virtual void doApply();
217     
218 private:
219     QPtrList<DOM::NodeImpl> ancestors;
220     QPtrList<DOM::NodeImpl> clonedNodes;
221     DOM::ElementImpl *m_breakNode;
222 };
223
224 //------------------------------------------------------------------------------------------
225 // InsertTextCommand
226
227 class InsertTextCommand : public CompositeEditCommand
228 {
229 public:
230     InsertTextCommand(DOM::DocumentImpl *document);
231
232     virtual void doApply();
233
234     void deleteCharacter();
235     void input(const DOM::DOMString &text, bool selectInsertedText = false);
236     
237     unsigned long charactersAdded() const { return m_charactersAdded; }
238     
239 private:
240     virtual bool isInsertTextCommand() const;
241
242     DOM::Position prepareForTextInsertion(bool adjustDownstream);
243     void insertSpace(DOM::TextImpl *textNode, unsigned long offset);
244
245     unsigned long m_charactersAdded;
246 };
247
248 //------------------------------------------------------------------------------------------
249 // JoinTextNodesCommand
250
251 class JoinTextNodesCommand : public EditCommand
252 {
253 public:
254     JoinTextNodesCommand(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
255     virtual ~JoinTextNodesCommand();
256         
257     virtual void doApply();
258     virtual void doUnapply();
259
260     DOM::TextImpl *firstNode() const { return m_text1; }
261     DOM::TextImpl *secondNode() const { return m_text2; }
262
263 private:
264     DOM::TextImpl *m_text1;
265     DOM::TextImpl *m_text2;
266     unsigned long m_offset;
267 };
268
269 //------------------------------------------------------------------------------------------
270 // MoveSelectionCommand
271
272 class MoveSelectionCommand : public CompositeEditCommand
273 {
274 public:
275     MoveSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, DOM::Position &position, bool smartMove=false);
276     virtual ~MoveSelectionCommand();
277     
278     virtual void doApply();
279     virtual EditAction editingAction() const;
280     
281 private:
282     DOM::DocumentFragmentImpl *m_fragment;
283     DOM::Position m_position;
284     bool m_smartMove;
285 };
286
287 //------------------------------------------------------------------------------------------
288 // RebalanceWhitespaceCommand
289
290 class RebalanceWhitespaceCommand : public EditCommand
291 {
292 public:
293     RebalanceWhitespaceCommand(DOM::DocumentImpl *, const DOM::Position &);
294     virtual ~RebalanceWhitespaceCommand();
295
296     virtual void doApply();
297     virtual void doUnapply();
298
299 private:
300     enum { InvalidOffset = -1 };
301
302     virtual bool preservesTypingStyle() const;
303
304     DOM::DOMString m_beforeString;
305     DOM::DOMString m_afterString;
306     DOM::Position m_position;
307     long m_upstreamOffset;
308     long m_downstreamOffset;
309 };
310
311 //------------------------------------------------------------------------------------------
312 // RemoveCSSPropertyCommand
313
314 class RemoveCSSPropertyCommand : public EditCommand
315 {
316 public:
317     RemoveCSSPropertyCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
318     virtual ~RemoveCSSPropertyCommand();
319
320     virtual void doApply();
321     virtual void doUnapply();
322
323     DOM::CSSMutableStyleDeclarationImpl *styleDeclaration() const { return m_decl; }
324     int property() const { return m_property; }
325     
326 private:
327     DOM::CSSMutableStyleDeclarationImpl *m_decl;
328     int m_property;
329     DOM::DOMString m_oldValue;
330     bool m_important;
331 };
332
333 //------------------------------------------------------------------------------------------
334 // RemoveNodeAttributeCommand
335
336 class RemoveNodeAttributeCommand : public EditCommand
337 {
338 public:
339     RemoveNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
340     virtual ~RemoveNodeAttributeCommand();
341
342     virtual void doApply();
343     virtual void doUnapply();
344
345     DOM::ElementImpl *element() const { return m_element; }
346     DOM::NodeImpl::Id attribute() const { return m_attribute; }
347     
348 private:
349     DOM::ElementImpl *m_element;
350     DOM::NodeImpl::Id m_attribute;
351     DOM::DOMString m_oldValue;
352 };
353
354 //------------------------------------------------------------------------------------------
355 // RemoveNodeCommand
356
357 class RemoveNodeCommand : public EditCommand
358 {
359 public:
360     RemoveNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
361     virtual ~RemoveNodeCommand();
362         
363     virtual void doApply();
364     virtual void doUnapply();
365
366     DOM::NodeImpl *node() const { return m_removeChild; }
367
368 private:
369     DOM::NodeImpl *m_parent;    
370     DOM::NodeImpl *m_removeChild;
371     DOM::NodeImpl *m_refChild;    
372 };
373
374 //------------------------------------------------------------------------------------------
375 // RemoveNodePreservingChildrenCommand
376
377 class RemoveNodePreservingChildrenCommand : public CompositeEditCommand
378 {
379 public:
380     RemoveNodePreservingChildrenCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
381     virtual ~RemoveNodePreservingChildrenCommand();
382         
383     virtual void doApply();
384
385     DOM::NodeImpl *node() const { return m_node; }
386
387 private:
388     DOM::NodeImpl *m_node;
389 };
390
391 //------------------------------------------------------------------------------------------
392 // ReplaceSelectionCommand
393
394 // --- NodeDesiredStyle helper class
395
396 class NodeDesiredStyle
397 {
398 public:
399     NodeDesiredStyle(DOM::NodeImpl *, DOM::CSSMutableStyleDeclarationImpl *);
400     NodeDesiredStyle(const NodeDesiredStyle &);
401     ~NodeDesiredStyle();
402     
403     DOM::NodeImpl *node() const { return m_node; }
404     DOM::CSSMutableStyleDeclarationImpl *style() const { return m_style; }
405
406     NodeDesiredStyle &operator=(const NodeDesiredStyle &);
407
408 private:
409     DOM::NodeImpl *m_node;
410     DOM::CSSMutableStyleDeclarationImpl *m_style;
411 };
412
413 // --- ReplacementFragment helper class
414
415 class ReplacementFragment
416 {
417 public:
418     ReplacementFragment(DOM::DocumentImpl *, DOM::DocumentFragmentImpl *, bool matchStyle);
419     ~ReplacementFragment();
420
421     enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
422
423     DOM::DocumentFragmentImpl *root() const { return m_fragment; }
424     DOM::NodeImpl *firstChild() const;
425     DOM::NodeImpl *lastChild() const;
426
427     DOM::NodeImpl *mergeStartNode() const;
428
429     const QValueList<NodeDesiredStyle> &desiredStyles() { return m_styles; }
430         
431     void pruneEmptyNodes();
432
433     EFragmentType type() const { return m_type; }
434     bool isEmpty() const { return m_type == EmptyFragment; }
435     bool isSingleTextNode() const { return m_type == SingleTextNodeFragment; }
436     bool isTreeFragment() const { return m_type == TreeFragment; }
437
438     bool hasMoreThanOneBlock() const { return m_hasMoreThanOneBlock; }
439     bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAtStart; }
440     bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEnd; }
441
442 private:
443     // no copy construction or assignment
444     ReplacementFragment(const ReplacementFragment &);
445     ReplacementFragment &operator=(const ReplacementFragment &);
446     
447     static bool isInterchangeNewlineNode(const DOM::NodeImpl *);
448     static bool isInterchangeConvertedSpaceSpan(const DOM::NodeImpl *);
449
450     DOM::NodeImpl *insertFragmentForTestRendering();
451     void restoreTestRenderingNodesToFragment(DOM::NodeImpl *);
452     void computeStylesUsingTestRendering(DOM::NodeImpl *);
453     void removeUnrenderedNodesUsingTestRendering(DOM::NodeImpl *);
454     int countRenderedBlocks(DOM::NodeImpl *holder);
455     void removeStyleNodes();
456
457     // A couple simple DOM helpers
458     DOM::NodeImpl *enclosingBlock(DOM::NodeImpl *) const;
459     void removeNode(DOM::NodeImpl *);
460     void removeNodePreservingChildren(DOM::NodeImpl *);
461     void insertNodeBefore(DOM::NodeImpl *node, DOM::NodeImpl *refNode);
462
463     EFragmentType m_type;
464     DOM::DocumentImpl *m_document;
465     DOM::DocumentFragmentImpl *m_fragment;
466     QValueList<NodeDesiredStyle> m_styles;
467     bool m_matchStyle;
468     bool m_hasInterchangeNewlineAtStart;
469     bool m_hasInterchangeNewlineAtEnd;
470     bool m_hasMoreThanOneBlock;
471 };
472
473 class ReplaceSelectionCommand : public CompositeEditCommand
474 {
475 public:
476     ReplaceSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true, bool smartReplace=false, bool matchStyle=false);
477     virtual ~ReplaceSelectionCommand();
478     
479     virtual void doApply();
480     virtual EditAction editingAction() const;
481
482 private:
483     void completeHTMLReplacement(const DOM::Position &lastPositionToSelect);
484
485     void insertNodeAfterAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
486     void insertNodeAtAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
487     void insertNodeBeforeAndUpdateNodesInserted(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
488
489     void updateNodesInserted(DOM::NodeImpl *);
490     void fixupNodeStyles(const QValueList<NodeDesiredStyle> &);
491     void removeLinePlaceholderIfNeeded(DOM::NodeImpl *);
492
493     ReplacementFragment m_fragment;
494     DOM::NodeImpl *m_firstNodeInserted;
495     DOM::NodeImpl *m_lastNodeInserted;
496     DOM::NodeImpl *m_lastTopNodeInserted;
497     DOM::CSSMutableStyleDeclarationImpl *m_insertionStyle;
498     bool m_selectReplacement;
499     bool m_smartReplace;
500     bool m_matchStyle;
501 };
502
503 void computeAndStoreNodeDesiredStyle(DOM::NodeImpl *, QValueList<NodeDesiredStyle> &);
504
505 //------------------------------------------------------------------------------------------
506 // SetNodeAttributeCommand
507
508 class SetNodeAttributeCommand : public EditCommand
509 {
510 public:
511     SetNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
512     virtual ~SetNodeAttributeCommand();
513
514     virtual void doApply();
515     virtual void doUnapply();
516
517     DOM::ElementImpl *element() const { return m_element; }
518     DOM::NodeImpl::Id attribute() const { return m_attribute; }
519     DOM::DOMString value() const { return m_value; }
520     
521 private:
522     DOM::ElementImpl *m_element;
523     DOM::NodeImpl::Id m_attribute;
524     DOM::DOMString m_value;
525     DOM::DOMString m_oldValue;
526 };
527
528 //------------------------------------------------------------------------------------------
529 // SplitTextNodeCommand
530
531 class SplitTextNodeCommand : public EditCommand
532 {
533 public:
534     SplitTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
535     virtual ~SplitTextNodeCommand();
536         
537     virtual void doApply();
538     virtual void doUnapply();
539
540     DOM::TextImpl *node() const { return m_text2; }
541     long offset() const { return m_offset; }
542
543 private:
544     DOM::TextImpl *m_text1;
545     DOM::TextImpl *m_text2;
546     unsigned long m_offset;
547 };
548
549 //------------------------------------------------------------------------------------------
550 // WrapContentsInDummySpanCommand
551
552 class WrapContentsInDummySpanCommand : public EditCommand
553 {
554 public:
555     WrapContentsInDummySpanCommand(DOM::DocumentImpl *, DOM::ElementImpl *);
556     virtual ~WrapContentsInDummySpanCommand();
557         
558     virtual void doApply();
559     virtual void doUnapply();
560
561 private:
562     DOM::ElementImpl *m_element;
563     DOM::ElementImpl *m_dummySpan;
564 };
565
566 //------------------------------------------------------------------------------------------
567 // SplitElementCommand
568
569 class SplitElementCommand : public EditCommand
570 {
571 public:
572     SplitElementCommand(DOM::DocumentImpl *, DOM::ElementImpl *element, DOM::NodeImpl *atChild);
573     virtual ~SplitElementCommand();
574         
575     virtual void doApply();
576     virtual void doUnapply();
577
578 private:
579     DOM::ElementImpl *m_element1;
580     DOM::ElementImpl *m_element2;
581     DOM::NodeImpl *m_atChild;
582 };
583
584 //------------------------------------------------------------------------------------------
585 // MergeIdenticalElementsCommand
586
587 class MergeIdenticalElementsCommand : public EditCommand
588 {
589 public:
590     MergeIdenticalElementsCommand(DOM::DocumentImpl *, DOM::ElementImpl *first, DOM::ElementImpl *second);
591     virtual ~MergeIdenticalElementsCommand();
592         
593     virtual void doApply();
594     virtual void doUnapply();
595
596 private:
597     DOM::ElementImpl *m_element1;
598     DOM::ElementImpl *m_element2;
599     DOM::NodeImpl *m_atChild;
600 };
601
602 //------------------------------------------------------------------------------------------
603 // SplitTextNodeContainingElementCommand
604
605 class SplitTextNodeContainingElementCommand : public CompositeEditCommand
606 {
607 public:
608     SplitTextNodeContainingElementCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
609     virtual ~SplitTextNodeContainingElementCommand();
610         
611     virtual void doApply();
612
613 private:
614     DOM::TextImpl *m_text;
615     long m_offset;
616 };
617
618
619 //------------------------------------------------------------------------------------------
620 // TypingCommand
621
622 class TypingCommand : public CompositeEditCommand
623 {
624 public:
625     enum ETypingCommand { 
626         DeleteKey, 
627         ForwardDeleteKey, 
628         InsertText, 
629         InsertLineBreak, 
630         InsertParagraphSeparator,
631         InsertParagraphSeparatorInQuotedContent,
632     };
633
634     TypingCommand(DOM::DocumentImpl *document, ETypingCommand, const DOM::DOMString &text = "", bool selectInsertedText = false);
635
636     static void deleteKeyPressed(DOM::DocumentImpl *, bool smartDelete = false);
637     static void forwardDeleteKeyPressed(DOM::DocumentImpl *, bool smartDelete = false);
638     static void insertText(DOM::DocumentImpl *, const DOM::DOMString &, bool selectInsertedText = false);
639     static void insertLineBreak(DOM::DocumentImpl *);
640     static void insertParagraphSeparator(DOM::DocumentImpl *);
641     static void insertParagraphSeparatorInQuotedContent(DOM::DocumentImpl *);
642     static bool isOpenForMoreTypingCommand(const EditCommandPtr &);
643     static void closeTyping(const EditCommandPtr &);
644     
645     virtual void doApply();
646     virtual EditAction editingAction() const;
647
648     bool openForMoreTyping() const { return m_openForMoreTyping; }
649     void closeTyping() { m_openForMoreTyping = false; }
650
651     void insertText(const DOM::DOMString &text, bool selectInsertedText);
652     void insertTextRunWithoutNewlines(const DOM::DOMString &text, bool selectInsertedText);
653     void insertLineBreak();
654     void insertParagraphSeparatorInQuotedContent();
655     void insertParagraphSeparator();
656     void deleteKeyPressed();
657     void forwardDeleteKeyPressed();
658
659     bool smartDelete() { return m_smartDelete; }
660     void setSmartDelete(bool smartDelete) { m_smartDelete = smartDelete; }
661
662 private:
663     virtual bool isTypingCommand() const;
664     virtual bool preservesTypingStyle() const;
665
666     void markMisspellingsAfterTyping();
667     void typingAddedToOpenCommand();
668     
669     ETypingCommand m_commandType;
670     DOM::DOMString m_textToInsert;
671     bool m_openForMoreTyping;
672     bool m_applyEditing;
673     bool m_selectInsertedText;
674     bool m_smartDelete;
675 };
676
677 //------------------------------------------------------------------------------------------
678
679 DOM::ElementImpl *createDefaultParagraphElement(DOM::DocumentImpl *document);
680 DOM::ElementImpl *createBreakElement(DOM::DocumentImpl *document);
681
682 bool isNodeRendered(const DOM::NodeImpl *);
683 bool isProbablyBlock(const DOM::NodeImpl *);
684 bool isProbablyTableStructureNode(const DOM::NodeImpl *);
685 bool isMailBlockquote(const DOM::NodeImpl *);
686 DOM::NodeImpl *nearestMailBlockquote(const DOM::NodeImpl *);
687 bool isMailPasteAsQuotationNode(const DOM::NodeImpl *node);
688
689 //------------------------------------------------------------------------------------------
690
691 bool isTableStructureNode(const DOM::NodeImpl *node);
692 DOM::ElementImpl *createBlockPlaceholderElement(DOM::DocumentImpl *document);
693
694 } // end namespace khtml
695
696 #endif