Reviewed by John
[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 "dom_nodeimpl.h"
30 #include "qptrlist.h"
31 #include "qvaluelist.h"
32 #include "selection.h"
33 #include "shared.h"
34
35 namespace DOM {
36     class CSSProperty;
37     class DocumentFragmentImpl;
38     class HTMLElementImpl;
39     class TextImpl;
40 }
41
42 namespace khtml {
43
44 class EditCommand;
45 class Selection;
46 class VisiblePosition;
47
48 //------------------------------------------------------------------------------------------
49 // EditCommandPtr
50
51 class EditCommandPtr : public SharedPtr<EditCommand>
52 {
53 public:
54     EditCommandPtr();
55     EditCommandPtr(EditCommand *);
56     EditCommandPtr(const EditCommandPtr &);
57     ~EditCommandPtr();
58
59     EditCommandPtr &operator=(const EditCommandPtr &);
60
61     bool isCompositeStep() const;
62
63     void apply() const;
64     void unapply() const;
65     void reapply() const;
66
67     DOM::DocumentImpl * const document() const;
68
69     khtml::Selection startingSelection() const;
70     khtml::Selection endingSelection() const;
71
72     void setStartingSelection(const khtml::Selection &s) const;
73     void setEndingSelection(const khtml::Selection &s) const;
74
75     DOM::CSSStyleDeclarationImpl *typingStyle() const;
76     void setTypingStyle(DOM::CSSStyleDeclarationImpl *) const;
77
78     EditCommandPtr parent() const;
79     void setParent(const EditCommandPtr &) const;
80
81     bool isInputTextCommand() const;
82     bool isInputNewlineCommand() const;
83     bool isTypingCommand() const;
84
85     static EditCommandPtr &emptyCommand();
86 };
87
88 //------------------------------------------------------------------------------------------
89 // StyleChange
90
91 class StyleChange {
92 public:
93     enum ELegacyHTMLStyles { DoNotUseLegacyHTMLStyles, UseLegacyHTMLStyles };
94
95     explicit StyleChange(DOM::CSSStyleDeclarationImpl *, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
96     StyleChange(DOM::CSSStyleDeclarationImpl *, const DOM::Position &, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
97
98     DOM::DOMString cssStyle() const { return m_cssStyle; }
99     bool applyBold() const { return m_applyBold; }
100     bool applyItalic() const { return m_applyItalic; }
101     bool usesLegacyStyles() const { return m_usesLegacyStyles; }
102
103 private:
104     void init(DOM::CSSStyleDeclarationImpl *, const DOM::Position &);
105     bool checkForLegacyHTMLStyleChange(const DOM::CSSProperty *);
106     static bool currentlyHasStyle(const DOM::Position &, const DOM::CSSProperty *);
107     
108     DOM::DOMString m_cssStyle;
109     bool m_applyBold;
110     bool m_applyItalic;
111     bool m_usesLegacyStyles;
112 };
113
114 //------------------------------------------------------------------------------------------
115 // EditCommand
116
117 class EditCommand : public Shared<EditCommand>
118 {
119 public:
120     EditCommand(DOM::DocumentImpl *);
121     virtual ~EditCommand();
122
123     bool isCompositeStep() const { return m_parent.notNull(); }
124     EditCommand *parent() const { return m_parent.get(); }
125     void setParent(EditCommand *parent) { m_parent = parent; }
126
127     enum ECommandState { NotApplied, Applied };
128     
129     void apply();       
130     void unapply();
131     void reapply();
132
133     virtual void doApply() = 0;
134     virtual void doUnapply() = 0;
135     virtual void doReapply();  // calls doApply()
136
137     virtual DOM::DocumentImpl * const document() const { return m_document; }
138
139     khtml::Selection startingSelection() const { return m_startingSelection; }
140     khtml::Selection endingSelection() const { return m_endingSelection; }
141
142     void setEndingSelectionNeedsLayout(bool flag=true) { m_endingSelection.setNeedsLayout(flag); }
143         
144     ECommandState state() const { return m_state; }
145     void setState(ECommandState state) { m_state = state; }
146
147     void setStartingSelection(const khtml::Selection &s);
148     void setEndingSelection(const khtml::Selection &s);
149
150     DOM::CSSStyleDeclarationImpl *typingStyle() const { return m_typingStyle; };
151     void setTypingStyle(DOM::CSSStyleDeclarationImpl *);
152     
153     virtual bool isInputTextCommand() const;
154     virtual bool isTypingCommand() const;
155
156 private:
157     void assignTypingStyle(DOM::CSSStyleDeclarationImpl *);
158
159     virtual bool preservesTypingStyle() const;
160
161     DOM::DocumentImpl *m_document;
162     ECommandState m_state;
163     khtml::Selection m_startingSelection;
164     khtml::Selection m_endingSelection;
165     DOM::CSSStyleDeclarationImpl *m_typingStyle;
166     EditCommandPtr m_parent;
167 };
168
169 //------------------------------------------------------------------------------------------
170 // CompositeEditCommand
171
172 class CompositeEditCommand : public EditCommand
173 {
174 public:
175     CompositeEditCommand(DOM::DocumentImpl *);
176         
177     virtual void doUnapply();
178     virtual void doReapply();
179
180 protected:
181     //
182     // sugary-sweet convenience functions to help create and apply edit commands in composite commands
183     //
184     void appendNode(DOM::NodeImpl *appendChild, DOM::NodeImpl *parentNode);
185     void applyCommandToComposite(EditCommandPtr &);
186     void deleteKeyPressed();
187     void deleteSelection(bool smartDelete=false, bool mergeBlocksAfterDelete=true);
188     void deleteSelection(const khtml::Selection &selection, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
189     void deleteText(DOM::TextImpl *node, long offset, long count);
190     void inputText(const DOM::DOMString &text, bool selectInsertedText = false);
191     void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
192     void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
193     void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
194     void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
195     void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
196     void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
197     void removeFullySelectedNode(DOM::NodeImpl *);
198     void removeNodeAttribute(DOM::ElementImpl *, int attribute);
199     void removeNode(DOM::NodeImpl *removeChild);
200     void removeNodePreservingChildren(DOM::NodeImpl *node);
201     void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
202     void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
203     void splitTextNode(DOM::TextImpl *text, long offset);
204
205     DOM::NodeImpl *applyTypingStyle(DOM::NodeImpl *) const;
206
207     void deleteInsignificantText(DOM::TextImpl *, int start, int end);
208     void deleteInsignificantText(const DOM::Position &start, const DOM::Position &end);
209     void deleteInsignificantTextDownstream(const DOM::Position &);
210
211     void insertBlockPlaceholderIfNeeded(DOM::NodeImpl *);
212     bool removeBlockPlaceholderIfNeeded(DOM::NodeImpl *);
213
214     QValueList<EditCommandPtr> m_cmds;
215 };
216
217 //==========================================================================================
218 // Concrete commands
219 //------------------------------------------------------------------------------------------
220 // AppendNodeCommand
221
222 class AppendNodeCommand : public EditCommand
223 {
224 public:
225     AppendNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *appendChild, DOM::NodeImpl *parentNode);
226     virtual ~AppendNodeCommand();
227
228     virtual void doApply();
229     virtual void doUnapply();
230
231     DOM::NodeImpl *appendChild() const { return m_appendChild; }
232     DOM::NodeImpl *parentNode() const { return m_parentNode; }
233
234 private:
235     DOM::NodeImpl *m_appendChild;
236     DOM::NodeImpl *m_parentNode;    
237 };
238
239 //------------------------------------------------------------------------------------------
240 // ApplyStyleCommand
241
242 class ApplyStyleCommand : public CompositeEditCommand
243 {
244 public:
245     ApplyStyleCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *style);
246     virtual ~ApplyStyleCommand();
247         
248     virtual void doApply();
249
250     DOM::CSSStyleDeclarationImpl *style() const { return m_style; }
251
252 private:
253     // style-removal helpers
254     bool isHTMLStyleNode(DOM::CSSStyleDeclarationImpl *, DOM::HTMLElementImpl *);
255     void removeHTMLStyleNode(DOM::HTMLElementImpl *);
256     void removeCSSStyle(DOM::CSSStyleDeclarationImpl *, DOM::HTMLElementImpl *);
257     void removeBlockStyle(DOM::CSSStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
258     void removeInlineStyle(DOM::CSSStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
259     bool nodeFullySelected(DOM::NodeImpl *, const DOM::Position &start, const DOM::Position &end) const;
260
261     // style-application helpers
262     void applyBlockStyle(DOM::CSSStyleDeclarationImpl *);
263     void applyInlineStyle(DOM::CSSStyleDeclarationImpl *);
264     void addBlockStyleIfNeeded(DOM::CSSStyleDeclarationImpl *, DOM::HTMLElementImpl *);
265     void addInlineStyleIfNeeded(DOM::CSSStyleDeclarationImpl *, DOM::NodeImpl *start, DOM::NodeImpl *end);
266     bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
267     DOM::NodeImpl *splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
268     void surroundNodeRangeWithElement(DOM::NodeImpl *start, DOM::NodeImpl *end, DOM::ElementImpl *element);
269     DOM::Position positionInsertionPoint(DOM::Position);
270     
271     DOM::CSSStyleDeclarationImpl *m_style;
272 };
273
274 //------------------------------------------------------------------------------------------
275 // DeleteSelectionCommand
276
277 class DeleteSelectionCommand : public CompositeEditCommand
278
279 public:
280     DeleteSelectionCommand(DOM::DocumentImpl *document, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
281     DeleteSelectionCommand(DOM::DocumentImpl *document, const khtml::Selection &selection, bool smartDelete=false, bool mergeBlocksAfterDelete=true);
282         
283     virtual void doApply();
284     
285 private:
286     virtual bool preservesTypingStyle() const;
287
288     void initializePositionData();
289     DOM::Position startPositionForDelete() const;
290     DOM::Position endPositionForDelete() const;
291     void saveTypingStyleState();
292     bool canPerformSpecialCaseBRDelete();
293     void performGeneralDelete();
294     void fixupWhitespace();
295     void moveNodesAfterNode();
296     void calculateEndingPosition();
297     void calculateTypingStyleAfterDelete();
298     void clearTransientState();
299
300     bool m_hasSelectionToDelete;
301     bool m_smartDelete;
302     bool m_mergeBlocksAfterDelete;
303     bool m_trailingWhitespaceValid;
304
305     // This data is transient and should be cleared at the end of the doApply function.
306     khtml::Selection m_selectionToDelete;
307     DOM::Position m_upstreamStart;
308     DOM::Position m_downstreamStart;
309     DOM::Position m_upstreamEnd;
310     DOM::Position m_downstreamEnd;
311     DOM::Position m_endingPosition;
312     DOM::Position m_leadingWhitespace;
313     DOM::Position m_trailingWhitespace;
314     DOM::NodeImpl *m_startBlock;
315     DOM::NodeImpl *m_endBlock;
316     DOM::NodeImpl *m_startNode;
317     DOM::CSSStyleDeclarationImpl *m_typingStyle;
318 };
319
320 //------------------------------------------------------------------------------------------
321 // DeleteTextCommand
322
323 class DeleteTextCommand : public EditCommand
324 {
325 public:
326     DeleteTextCommand(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
327     virtual ~DeleteTextCommand();
328         
329     virtual void doApply();
330     virtual void doUnapply();
331
332     DOM::TextImpl *node() const { return m_node; }
333     long offset() const { return m_offset; }
334     long count() const { return m_count; }
335
336 private:
337     DOM::TextImpl *m_node;
338     long m_offset;
339     long m_count;
340     DOM::DOMString m_text;
341 };
342
343 //------------------------------------------------------------------------------------------
344 // InputNewlineCommand
345
346 class InputNewlineCommand : public CompositeEditCommand
347 {
348 public:
349     InputNewlineCommand(DOM::DocumentImpl *document);
350
351     virtual void doApply();
352
353 private:
354     void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
355     void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
356 };
357
358 //------------------------------------------------------------------------------------------
359 // InputNewlineInQuotedContentCommand
360
361 class InputNewlineInQuotedContentCommand : public CompositeEditCommand
362 {
363 public:
364     InputNewlineInQuotedContentCommand(DOM::DocumentImpl *);
365     virtual ~InputNewlineInQuotedContentCommand();
366         
367     virtual void doApply();
368     
369 private:
370     bool isMailBlockquote(const DOM::NodeImpl *) const;
371     bool isLastVisiblePositionInBlockquote(const VisiblePosition &pos, const DOM::NodeImpl *) const;
372
373     QPtrList<DOM::NodeImpl> ancestors;
374     QPtrList<DOM::NodeImpl> clonedNodes;
375     DOM::ElementImpl *m_breakNode;
376 };
377
378 //------------------------------------------------------------------------------------------
379 // InputTextCommand
380
381 class InputTextCommand : public CompositeEditCommand
382 {
383 public:
384     InputTextCommand(DOM::DocumentImpl *document);
385
386     virtual void doApply();
387
388     void deleteCharacter();
389     void input(const DOM::DOMString &text, bool selectInsertedText = false);
390     
391     unsigned long charactersAdded() const { return m_charactersAdded; }
392     
393 private:
394     virtual bool isInputTextCommand() const;
395
396     DOM::Position prepareForTextInsertion(bool adjustDownstream);
397     void insertSpace(DOM::TextImpl *textNode, unsigned long offset);
398
399     unsigned long m_charactersAdded;
400 };
401
402 //------------------------------------------------------------------------------------------
403 // InsertNodeBeforeCommand
404
405 class InsertNodeBeforeCommand : public EditCommand
406 {
407 public:
408     InsertNodeBeforeCommand(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
409     virtual ~InsertNodeBeforeCommand();
410
411     virtual void doApply();
412     virtual void doUnapply();
413
414     DOM::NodeImpl *insertChild() const { return m_insertChild; }
415     DOM::NodeImpl *refChild() const { return m_refChild; }
416
417 private:
418     DOM::NodeImpl *m_insertChild;
419     DOM::NodeImpl *m_refChild; 
420 };
421
422 //------------------------------------------------------------------------------------------
423 // InsertTextCommand
424
425 class InsertTextCommand : public EditCommand
426 {
427 public:
428     InsertTextCommand(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
429     virtual ~InsertTextCommand();
430         
431     virtual void doApply();
432     virtual void doUnapply();
433
434     DOM::TextImpl *node() const { return m_node; }
435     long offset() const { return m_offset; }
436     DOM::DOMString text() const { return m_text; }
437
438 private:
439     DOM::TextImpl *m_node;
440     long m_offset;
441     DOM::DOMString m_text;
442 };
443
444 //------------------------------------------------------------------------------------------
445 // JoinTextNodesCommand
446
447 class JoinTextNodesCommand : public EditCommand
448 {
449 public:
450     JoinTextNodesCommand(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
451     virtual ~JoinTextNodesCommand();
452         
453     virtual void doApply();
454     virtual void doUnapply();
455
456     DOM::TextImpl *firstNode() const { return m_text1; }
457     DOM::TextImpl *secondNode() const { return m_text2; }
458
459 private:
460     DOM::TextImpl *m_text1;
461     DOM::TextImpl *m_text2;
462     unsigned long m_offset;
463 };
464
465 //------------------------------------------------------------------------------------------
466 // ReplaceSelectionCommand
467
468 class ReplaceSelectionCommand : public CompositeEditCommand
469 {
470 public:
471     ReplaceSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true, bool smartReplace=false);
472     virtual ~ReplaceSelectionCommand();
473     
474     virtual void doApply();
475
476 private:
477     DOM::DocumentFragmentImpl *m_fragment;
478     bool m_selectReplacement;
479     bool m_smartReplace;
480 };
481
482 //------------------------------------------------------------------------------------------
483 // MoveSelectionCommand
484
485 class MoveSelectionCommand : public CompositeEditCommand
486 {
487 public:
488     MoveSelectionCommand(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, DOM::Position &position, bool smartMove=false);
489     virtual ~MoveSelectionCommand();
490     
491     virtual void doApply();
492     
493 private:
494     DOM::DocumentFragmentImpl *m_fragment;
495     DOM::Position m_position;
496     bool m_smartMove;
497 };
498
499 //------------------------------------------------------------------------------------------
500 // RemoveCSSPropertyCommand
501
502 class RemoveCSSPropertyCommand : public EditCommand
503 {
504 public:
505     RemoveCSSPropertyCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
506     virtual ~RemoveCSSPropertyCommand();
507
508     virtual void doApply();
509     virtual void doUnapply();
510
511     DOM::CSSStyleDeclarationImpl *styleDeclaration() const { return m_decl; }
512     int property() const { return m_property; }
513     
514 private:
515     DOM::CSSStyleDeclarationImpl *m_decl;
516     int m_property;
517     DOM::DOMString m_oldValue;
518     bool m_important;
519 };
520
521 //------------------------------------------------------------------------------------------
522 // RemoveNodeAttributeCommand
523
524 class RemoveNodeAttributeCommand : public EditCommand
525 {
526 public:
527     RemoveNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
528     virtual ~RemoveNodeAttributeCommand();
529
530     virtual void doApply();
531     virtual void doUnapply();
532
533     DOM::ElementImpl *element() const { return m_element; }
534     DOM::NodeImpl::Id attribute() const { return m_attribute; }
535     
536 private:
537     DOM::ElementImpl *m_element;
538     DOM::NodeImpl::Id m_attribute;
539     DOM::DOMString m_oldValue;
540 };
541
542 //------------------------------------------------------------------------------------------
543 // RemoveNodeCommand
544
545 class RemoveNodeCommand : public EditCommand
546 {
547 public:
548     RemoveNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
549     virtual ~RemoveNodeCommand();
550         
551     virtual void doApply();
552     virtual void doUnapply();
553
554     DOM::NodeImpl *node() const { return m_removeChild; }
555
556 private:
557     DOM::NodeImpl *m_parent;    
558     DOM::NodeImpl *m_removeChild;
559     DOM::NodeImpl *m_refChild;    
560 };
561
562 //------------------------------------------------------------------------------------------
563 // RemoveNodePreservingChildrenCommand
564
565 class RemoveNodePreservingChildrenCommand : public CompositeEditCommand
566 {
567 public:
568     RemoveNodePreservingChildrenCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
569     virtual ~RemoveNodePreservingChildrenCommand();
570         
571     virtual void doApply();
572
573     DOM::NodeImpl *node() const { return m_node; }
574
575 private:
576     DOM::NodeImpl *m_node;
577 };
578
579 //------------------------------------------------------------------------------------------
580 // SetNodeAttributeCommand
581
582 class SetNodeAttributeCommand : public EditCommand
583 {
584 public:
585     SetNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
586     virtual ~SetNodeAttributeCommand();
587
588     virtual void doApply();
589     virtual void doUnapply();
590
591     DOM::ElementImpl *element() const { return m_element; }
592     DOM::NodeImpl::Id attribute() const { return m_attribute; }
593     DOM::DOMString value() const { return m_value; }
594     
595 private:
596     DOM::ElementImpl *m_element;
597     DOM::NodeImpl::Id m_attribute;
598     DOM::DOMString m_value;
599     DOM::DOMString m_oldValue;
600 };
601
602 //------------------------------------------------------------------------------------------
603 // SplitTextNodeCommand
604
605 class SplitTextNodeCommand : public EditCommand
606 {
607 public:
608     SplitTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
609     virtual ~SplitTextNodeCommand();
610         
611     virtual void doApply();
612     virtual void doUnapply();
613
614     DOM::TextImpl *node() const { return m_text2; }
615     long offset() const { return m_offset; }
616
617 private:
618     DOM::TextImpl *m_text1;
619     DOM::TextImpl *m_text2;
620     unsigned long m_offset;
621 };
622
623 //------------------------------------------------------------------------------------------
624 // TypingCommand
625
626 class TypingCommand : public CompositeEditCommand
627 {
628 public:
629     enum ETypingCommand { DeleteKey, InsertText, InsertNewline, InsertNewlineInQuotedContent };
630
631     TypingCommand(DOM::DocumentImpl *document, ETypingCommand, const DOM::DOMString &text = "", bool selectInsertedText = false);
632
633     static void deleteKeyPressed(DOM::DocumentImpl *document);
634     static void insertText(DOM::DocumentImpl *document, const DOM::DOMString &text, bool selectInsertedText = false);
635     static void insertNewline(DOM::DocumentImpl *document);
636     static void insertNewlineInQuotedContent(DOM::DocumentImpl *document);
637     static bool isOpenForMoreTypingCommand(const EditCommandPtr &);
638     static void closeTyping(const EditCommandPtr &);
639     
640     virtual void doApply();
641
642     bool openForMoreTyping() const { return m_openForMoreTyping; }
643     void closeTyping() { m_openForMoreTyping = false; }
644
645     void insertText(const DOM::DOMString &text, bool selectInsertedText);
646     void insertNewline();
647     void insertNewlineInQuotedContent();
648     void deleteKeyPressed();
649
650 private:
651     virtual bool isTypingCommand() const;
652     virtual bool preservesTypingStyle() const;
653
654     void issueCommandForDeleteKey();
655     void removeCommand(const EditCommandPtr &);
656     void markMisspellingsAfterTyping();
657     void typingAddedToOpenCommand();
658     
659     ETypingCommand m_commandType;
660     DOM::DOMString m_textToInsert;
661     bool m_openForMoreTyping;
662     bool m_applyEditing;
663     bool m_selectInsertedText;
664 };
665
666 //------------------------------------------------------------------------------------------
667
668 } // end namespace khtml
669
670 #endif