File indexing completed on 2024-04-28 15:23:23

0001 /*
0002  * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
0014  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0016  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
0017  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0018  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0019  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0020  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0021  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0023  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #ifndef __htmleditingimpl_h__
0027 #define __htmleditingimpl_h__
0028 
0029 #include "misc/shared.h"
0030 
0031 #include "xml/dom_position.h"
0032 #include "xml/dom_selection.h"
0033 #include "dom/dom_string.h"
0034 
0035 #include "xml/dom_nodeimpl.h"
0036 
0037 #include <QList>
0038 
0039 namespace DOM
0040 {
0041 class CSSProperty;
0042 class CSSStyleDeclarationImpl;
0043 class DocumentFragmentImpl;
0044 class DocumentImpl;
0045 class DOMString;
0046 class ElementImpl;
0047 class HTMLElementImpl;
0048 class NodeImpl;
0049 class NodeListImpl;
0050 class Position;
0051 class Range;
0052 class Selection;
0053 class TextImpl;
0054 class TreeWalkerImpl;
0055 }
0056 
0057 using DOM::DocumentImpl;
0058 using DOM::NodeImpl;
0059 
0060 namespace khtml
0061 {
0062 
0063 class EditCommandImpl;
0064 
0065 class SharedCommandImpl : public Shared<SharedCommandImpl>
0066 {
0067 public:
0068     SharedCommandImpl() {}
0069     virtual ~SharedCommandImpl() {}
0070 
0071     virtual bool isCompositeStep() const = 0;
0072 
0073     virtual void apply() = 0;
0074     virtual void unapply() = 0;
0075     virtual void reapply() = 0;
0076 
0077     virtual DOM::DocumentImpl *document() const = 0;
0078 
0079     virtual DOM::Selection startingSelection() const = 0;
0080     virtual DOM::Selection endingSelection() const = 0;
0081 
0082     virtual void setStartingSelection(const DOM::Selection &s) = 0;
0083     virtual void setEndingSelection(const DOM::Selection &s) = 0;
0084 
0085     virtual EditCommandImpl *parent() const = 0;
0086     virtual void setParent(EditCommandImpl *) = 0;
0087 };
0088 
0089 //------------------------------------------------------------------------------------------
0090 // EditCommandImpl
0091 
0092 class EditCommandImpl : public SharedCommandImpl
0093 {
0094 public:
0095     EditCommandImpl(DOM::DocumentImpl *);
0096     virtual ~EditCommandImpl();
0097 
0098     bool isCompositeStep() const override
0099     {
0100         return parent();
0101     }
0102     EditCommandImpl *parent() const override;
0103     void setParent(EditCommandImpl *) override;
0104 
0105     enum ECommandState { NotApplied, Applied };
0106 
0107     void apply() override;
0108     void unapply() override;
0109     void reapply() override;
0110 
0111     virtual void doApply() = 0;
0112     virtual void doUnapply() = 0;
0113     virtual void doReapply();  // calls doApply()
0114 
0115     DOM::DocumentImpl *document() const override
0116     {
0117         return m_document.get();
0118     }
0119 
0120     DOM::Selection startingSelection() const override
0121     {
0122         return m_startingSelection;
0123     }
0124     DOM::Selection endingSelection() const override
0125     {
0126         return m_endingSelection;
0127     }
0128 
0129     ECommandState state() const
0130     {
0131         return m_state;
0132     }
0133     void setState(ECommandState state)
0134     {
0135         m_state = state;
0136     }
0137 
0138     void setStartingSelection(const DOM::Selection &s) override;
0139     void setEndingSelection(const DOM::Selection &s) override;
0140 
0141 public:
0142     virtual bool isTypingCommand() const
0143     {
0144         return false;
0145     }
0146     virtual bool isInputTextCommand() const
0147     {
0148         return false;
0149     }
0150 
0151 private:
0152     DocPtr<DOM::DocumentImpl> m_document;
0153     ECommandState m_state;
0154     DOM::Selection m_startingSelection;
0155     DOM::Selection m_endingSelection;
0156     RefPtr<EditCommandImpl> m_parent;
0157 };
0158 
0159 //------------------------------------------------------------------------------------------
0160 // CompositeEditCommandImpl
0161 
0162 class CompositeEditCommandImpl : public EditCommandImpl
0163 {
0164 public:
0165     CompositeEditCommandImpl(DOM::DocumentImpl *);
0166     virtual ~CompositeEditCommandImpl();
0167 
0168     void doApply() override = 0;
0169     void doUnapply() override;
0170     void doReapply() override;
0171 
0172 protected:
0173     //
0174     // sugary-sweet convenience functions to help create and apply edit commands in composite commands
0175     //
0176     void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
0177     void applyCommandToComposite(PassRefPtr<EditCommandImpl>);
0178     void deleteCollapsibleWhitespace();
0179     void deleteCollapsibleWhitespace(const DOM::Selection &selection);
0180     void deleteKeyPressed();
0181     void deleteSelection();
0182     void deleteSelection(const DOM::Selection &selection);
0183     void deleteText(DOM::TextImpl *node, long offset, long count);
0184     void inputText(const DOM::DOMString &text);
0185     void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
0186     void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
0187     void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
0188     void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
0189     void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
0190     void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
0191     void removeNodeAttribute(DOM::ElementImpl *, int attribute);
0192     void removeNode(DOM::NodeImpl *removeChild);
0193     void removeNodeAndPrune(DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode = nullptr);
0194     void removeNodePreservingChildren(DOM::NodeImpl *node);
0195     void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
0196     void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
0197     void splitTextNode(DOM::TextImpl *text, long offset);
0198 
0199     DOM::ElementImpl *createTypingStyleElement() const;
0200 
0201     QList<RefPtr<EditCommandImpl> > m_cmds;
0202 };
0203 
0204 //==========================================================================================
0205 // Concrete commands
0206 //------------------------------------------------------------------------------------------
0207 // AppendNodeCommandImpl
0208 
0209 class AppendNodeCommandImpl : public EditCommandImpl
0210 {
0211 public:
0212     AppendNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *parentNode, DOM::NodeImpl *appendChild);
0213     virtual ~AppendNodeCommandImpl();
0214 
0215     void doApply() override;
0216     void doUnapply() override;
0217 
0218     DOM::NodeImpl *parentNode() const
0219     {
0220         return m_parentNode;
0221     }
0222     DOM::NodeImpl *appendChild() const
0223     {
0224         return m_appendChild;
0225     }
0226 
0227 private:
0228     DOM::NodeImpl *m_parentNode;
0229     DOM::NodeImpl *m_appendChild;
0230 };
0231 
0232 //------------------------------------------------------------------------------------------
0233 // ApplyStyleCommandImpl
0234 
0235 class ApplyStyleCommandImpl : public CompositeEditCommandImpl
0236 {
0237 public:
0238     ApplyStyleCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *style);
0239     virtual ~ApplyStyleCommandImpl();
0240 
0241     void doApply() override;
0242 
0243     DOM::CSSStyleDeclarationImpl *style() const
0244     {
0245         return m_style;
0246     }
0247 
0248     struct StyleChange {
0249         StyleChange() : applyBold(false), applyItalic(false) {}
0250         DOM::DOMString cssStyle;
0251         bool applyBold: 1;
0252         bool applyItalic: 1;
0253     };
0254 
0255 private:
0256     // style-removal helpers
0257     bool isHTMLStyleNode(DOM::HTMLElementImpl *);
0258     void removeHTMLStyleNode(DOM::HTMLElementImpl *);
0259     void removeCSSStyle(DOM::HTMLElementImpl *);
0260     void removeStyle(const DOM::Position &start, const DOM::Position &end);
0261     bool nodeFullySelected(const DOM::NodeImpl *node) const;
0262 
0263     // style-application helpers
0264     bool currentlyHasStyle(const DOM::Position &, const DOM::CSSProperty *) const;
0265     StyleChange computeStyleChange(const DOM::Position &, DOM::CSSStyleDeclarationImpl *);
0266     bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
0267     DOM::NodeImpl *splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
0268     void surroundNodeRangeWithElement(DOM::NodeImpl *start, DOM::NodeImpl *end, DOM::ElementImpl *element);
0269     DOM::Position positionInsertionPoint(DOM::Position);
0270     void applyStyleIfNeeded(DOM::NodeImpl *start, DOM::NodeImpl *end);
0271 
0272     DOM::CSSStyleDeclarationImpl *m_style;
0273 };
0274 
0275 //------------------------------------------------------------------------------------------
0276 // DeleteCollapsibleWhitespaceCommandImpl
0277 
0278 class DeleteCollapsibleWhitespaceCommandImpl : public CompositeEditCommandImpl
0279 {
0280 public:
0281     DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document);
0282     DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
0283 
0284     virtual ~DeleteCollapsibleWhitespaceCommandImpl();
0285 
0286     void doApply() override;
0287 
0288 private:
0289     DOM::Position deleteWhitespace(const DOM::Position &pos);
0290 
0291     unsigned long m_charactersDeleted;
0292     DOM::Selection m_selectionToCollapse;
0293     bool m_hasSelectionToCollapse;
0294 };
0295 
0296 //------------------------------------------------------------------------------------------
0297 // DeleteSelectionCommandImpl
0298 
0299 class DeleteSelectionCommandImpl : public CompositeEditCommandImpl
0300 {
0301 public:
0302     DeleteSelectionCommandImpl(DOM::DocumentImpl *document);
0303     DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
0304 
0305     virtual ~DeleteSelectionCommandImpl();
0306 
0307     void doApply() override;
0308 
0309 private:
0310     void deleteContentBeforeOffset(NodeImpl *node, int offset);
0311     void deleteContentAfterOffset(NodeImpl *node, int offset);
0312     void deleteContentInsideNode(NodeImpl *node, int startOffset, int endOffset);
0313     void deleteDownstreamWS(const DOM::Position &start);
0314     bool containsOnlyWhitespace(const DOM::Position &start, const DOM::Position &end);
0315     void joinTextNodesWithSameStyle();
0316 
0317     DOM::Selection m_selectionToDelete;
0318     bool m_hasSelectionToDelete;
0319 };
0320 
0321 //------------------------------------------------------------------------------------------
0322 // DeleteTextCommandImpl
0323 
0324 class DeleteTextCommandImpl : public EditCommandImpl
0325 {
0326 public:
0327     DeleteTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
0328     virtual ~DeleteTextCommandImpl();
0329 
0330     void doApply() override;
0331     void doUnapply() override;
0332 
0333     DOM::TextImpl *node() const
0334     {
0335         return m_node;
0336     }
0337     long offset() const
0338     {
0339         return m_offset;
0340     }
0341     long count() const
0342     {
0343         return m_count;
0344     }
0345 
0346 private:
0347     DOM::TextImpl *m_node;
0348     long m_offset;
0349     long m_count;
0350     DOM::DOMString m_text;
0351 };
0352 
0353 //------------------------------------------------------------------------------------------
0354 // InputNewlineCommandImpl
0355 
0356 class InputNewlineCommandImpl : public CompositeEditCommandImpl
0357 {
0358 public:
0359     InputNewlineCommandImpl(DOM::DocumentImpl *document);
0360     virtual ~InputNewlineCommandImpl();
0361 
0362     void doApply() override;
0363 
0364 private:
0365     void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
0366     void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
0367 };
0368 
0369 //------------------------------------------------------------------------------------------
0370 // InputTextCommandImpl
0371 
0372 class InputTextCommandImpl : public CompositeEditCommandImpl
0373 {
0374 public:
0375     InputTextCommandImpl(DOM::DocumentImpl *document);
0376     virtual ~InputTextCommandImpl();
0377 
0378     void doApply() override;
0379 
0380     void deleteCharacter();
0381     void input(const DOM::DOMString &text);
0382 
0383     unsigned long charactersAdded() const
0384     {
0385         return m_charactersAdded;
0386     }
0387 
0388     bool isInputTextCommand() const override
0389     {
0390         return true;
0391     }
0392 private:
0393     DOM::Position prepareForTextInsertion(bool adjustDownstream);
0394     void execute(const DOM::DOMString &text);
0395     void insertSpace(DOM::TextImpl *textNode, unsigned long offset);
0396 
0397     unsigned long m_charactersAdded;
0398 };
0399 
0400 //------------------------------------------------------------------------------------------
0401 // InsertNodeBeforeCommandImpl
0402 
0403 class InsertNodeBeforeCommandImpl : public EditCommandImpl
0404 {
0405 public:
0406     InsertNodeBeforeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
0407     virtual ~InsertNodeBeforeCommandImpl();
0408 
0409     void doApply() override;
0410     void doUnapply() override;
0411 
0412     DOM::NodeImpl *insertChild() const
0413     {
0414         return m_insertChild;
0415     }
0416     DOM::NodeImpl *refChild() const
0417     {
0418         return m_refChild;
0419     }
0420 
0421 private:
0422     DOM::NodeImpl *m_insertChild;
0423     DOM::NodeImpl *m_refChild;
0424 };
0425 
0426 //------------------------------------------------------------------------------------------
0427 // InsertTextCommandImpl
0428 
0429 class InsertTextCommandImpl : public EditCommandImpl
0430 {
0431 public:
0432     InsertTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
0433     virtual ~InsertTextCommandImpl();
0434 
0435     void doApply() override;
0436     void doUnapply() override;
0437 
0438     DOM::TextImpl *node() const
0439     {
0440         return m_node;
0441     }
0442     long offset() const
0443     {
0444         return m_offset;
0445     }
0446     DOM::DOMString text() const
0447     {
0448         return m_text;
0449     }
0450 
0451 private:
0452     DOM::TextImpl *m_node;
0453     long m_offset;
0454     DOM::DOMString m_text;
0455 };
0456 
0457 //------------------------------------------------------------------------------------------
0458 // JoinTextNodesCommandImpl
0459 
0460 class JoinTextNodesCommandImpl : public EditCommandImpl
0461 {
0462 public:
0463     JoinTextNodesCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
0464     virtual ~JoinTextNodesCommandImpl();
0465 
0466     void doApply() override;
0467     void doUnapply() override;
0468 
0469     DOM::TextImpl *firstNode() const
0470     {
0471         return m_text1;
0472     }
0473     DOM::TextImpl *secondNode() const
0474     {
0475         return m_text2;
0476     }
0477 
0478 private:
0479     DOM::TextImpl *m_text1;
0480     DOM::TextImpl *m_text2;
0481     unsigned long m_offset;
0482 };
0483 
0484 //------------------------------------------------------------------------------------------
0485 // ReplaceSelectionCommandImpl
0486 
0487 class ReplaceSelectionCommandImpl : public CompositeEditCommandImpl
0488 {
0489 public:
0490     ReplaceSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement = true);
0491     virtual ~ReplaceSelectionCommandImpl();
0492 
0493     void doApply() override;
0494 
0495 private:
0496     DOM::DocumentFragmentImpl *m_fragment;
0497     bool m_selectReplacement;
0498 };
0499 
0500 //------------------------------------------------------------------------------------------
0501 // MoveSelectionCommandImpl
0502 
0503 class MoveSelectionCommandImpl : public CompositeEditCommandImpl
0504 {
0505 public:
0506     MoveSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, DOM::Position &position);
0507     virtual ~MoveSelectionCommandImpl();
0508 
0509     void doApply() override;
0510 
0511 private:
0512     DOM::DocumentFragmentImpl *m_fragment;
0513     DOM::Position m_position;
0514 };
0515 
0516 //------------------------------------------------------------------------------------------
0517 // RemoveCSSPropertyCommand
0518 
0519 class RemoveCSSPropertyCommandImpl : public EditCommandImpl
0520 {
0521 public:
0522     RemoveCSSPropertyCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
0523     virtual ~RemoveCSSPropertyCommandImpl();
0524 
0525     void doApply() override;
0526     void doUnapply() override;
0527 
0528     DOM::CSSStyleDeclarationImpl *styleDeclaration() const
0529     {
0530         return m_decl;
0531     }
0532     int property() const
0533     {
0534         return m_property;
0535     }
0536 
0537 private:
0538     DOM::CSSStyleDeclarationImpl *m_decl;
0539     int m_property;
0540     DOM::DOMString m_oldValue;
0541     bool m_important;
0542 };
0543 
0544 //------------------------------------------------------------------------------------------
0545 // RemoveNodeAttributeCommandImpl
0546 
0547 class RemoveNodeAttributeCommandImpl : public EditCommandImpl
0548 {
0549 public:
0550     RemoveNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
0551     virtual ~RemoveNodeAttributeCommandImpl();
0552 
0553     void doApply() override;
0554     void doUnapply() override;
0555 
0556     DOM::ElementImpl *element() const
0557     {
0558         return m_element;
0559     }
0560     DOM::NodeImpl::Id attribute() const
0561     {
0562         return m_attribute;
0563     }
0564 
0565 private:
0566     DOM::ElementImpl *m_element;
0567     DOM::NodeImpl::Id m_attribute;
0568     DOM::DOMString m_oldValue;
0569 };
0570 
0571 //------------------------------------------------------------------------------------------
0572 // RemoveNodeCommandImpl
0573 
0574 class RemoveNodeCommandImpl : public EditCommandImpl
0575 {
0576 public:
0577     RemoveNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
0578     virtual ~RemoveNodeCommandImpl();
0579 
0580     void doApply() override;
0581     void doUnapply() override;
0582 
0583     DOM::NodeImpl *node() const
0584     {
0585         return m_removeChild;
0586     }
0587 
0588 private:
0589     DOM::NodeImpl *m_parent;
0590     DOM::NodeImpl *m_removeChild;
0591     DOM::NodeImpl *m_refChild;
0592 };
0593 
0594 //------------------------------------------------------------------------------------------
0595 // RemoveNodeAndPruneCommandImpl
0596 
0597 class RemoveNodeAndPruneCommandImpl : public CompositeEditCommandImpl
0598 {
0599 public:
0600     RemoveNodeAndPruneCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode = nullptr);
0601     virtual ~RemoveNodeAndPruneCommandImpl();
0602 
0603     void doApply() override;
0604 
0605     DOM::NodeImpl *pruneNode() const
0606     {
0607         return m_pruneNode;
0608     }
0609     DOM::NodeImpl *stopNode() const
0610     {
0611         return m_stopNode;
0612     }
0613 
0614 private:
0615     DOM::NodeImpl *m_pruneNode;
0616     DOM::NodeImpl *m_stopNode;
0617 };
0618 
0619 //------------------------------------------------------------------------------------------
0620 // RemoveNodePreservingChildrenCommandImpl
0621 
0622 class RemoveNodePreservingChildrenCommandImpl : public CompositeEditCommandImpl
0623 {
0624 public:
0625     RemoveNodePreservingChildrenCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
0626     virtual ~RemoveNodePreservingChildrenCommandImpl();
0627 
0628     void doApply() override;
0629 
0630     DOM::NodeImpl *node() const
0631     {
0632         return m_node;
0633     }
0634 
0635 private:
0636     DOM::NodeImpl *m_node;
0637 };
0638 
0639 //------------------------------------------------------------------------------------------
0640 // SetNodeAttributeCommandImpl
0641 
0642 class SetNodeAttributeCommandImpl : public EditCommandImpl
0643 {
0644 public:
0645     SetNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
0646     virtual ~SetNodeAttributeCommandImpl();
0647 
0648     void doApply() override;
0649     void doUnapply() override;
0650 
0651     DOM::ElementImpl *element() const
0652     {
0653         return m_element;
0654     }
0655     DOM::NodeImpl::Id attribute() const
0656     {
0657         return m_attribute;
0658     }
0659     DOM::DOMString value() const
0660     {
0661         return m_value;
0662     }
0663 
0664 private:
0665     DOM::ElementImpl *m_element;
0666     DOM::NodeImpl::Id m_attribute;
0667     DOM::DOMString m_value;
0668     DOM::DOMString m_oldValue;
0669 };
0670 
0671 //------------------------------------------------------------------------------------------
0672 // SplitTextNodeCommandImpl
0673 
0674 class SplitTextNodeCommandImpl : public EditCommandImpl
0675 {
0676 public:
0677     SplitTextNodeCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, long);
0678     virtual ~SplitTextNodeCommandImpl();
0679 
0680     void doApply() override;
0681     void doUnapply() override;
0682 
0683     DOM::TextImpl *node() const
0684     {
0685         return m_text2;
0686     }
0687     long offset() const
0688     {
0689         return m_offset;
0690     }
0691 
0692 private:
0693     DOM::TextImpl *m_text1;
0694     DOM::TextImpl *m_text2;
0695     unsigned long m_offset;
0696 };
0697 
0698 //------------------------------------------------------------------------------------------
0699 // TypingCommandImpl
0700 
0701 class TypingCommandImpl : public CompositeEditCommandImpl
0702 {
0703 public:
0704     TypingCommandImpl(DOM::DocumentImpl *document);
0705     virtual ~TypingCommandImpl();
0706 
0707     void doApply() override;
0708 
0709     bool openForMoreTyping() const
0710     {
0711         return m_openForMoreTyping;
0712     }
0713     void closeTyping()
0714     {
0715         m_openForMoreTyping = false;
0716     }
0717 
0718     void insertText(const DOM::DOMString &text);
0719     void insertNewline();
0720     void deleteKeyPressed();
0721 
0722     bool isTypingCommand() const override
0723     {
0724         return true;
0725     }
0726 
0727     static void deleteKeyPressed0(DocumentImpl *document);
0728     static void insertNewline0(DocumentImpl *document);
0729     static void insertText0(DocumentImpl *document, const DOMString &text);
0730 
0731 private:
0732     void issueCommandForDeleteKey();
0733     void removeCommand(const PassRefPtr<EditCommandImpl>);
0734     void typingAddedToOpenCommand();
0735 
0736     bool m_openForMoreTyping;
0737 };
0738 
0739 //------------------------------------------------------------------------------------------
0740 // InsertListCommandImpl
0741 
0742 class InsertListCommandImpl : public CompositeEditCommandImpl
0743 {
0744 public:
0745     enum Type { OrderedList, UnorderedList };
0746 
0747     InsertListCommandImpl(DOM::DocumentImpl *document, Type type);
0748     virtual ~InsertListCommandImpl();
0749 
0750     void doApply() override;
0751 
0752     static void insertList(DocumentImpl *document, Type type);
0753 
0754 private:
0755     Type m_listType;
0756 };
0757 
0758 //------------------------------------------------------------------------------------------
0759 
0760 //------------------------------------------------------------------------------------------
0761 // IndentOutdentCommandImpl
0762 
0763 class IndentOutdentCommandImpl : public CompositeEditCommandImpl
0764 {
0765 public:
0766     enum Type { Indent, Outdent };
0767 
0768     IndentOutdentCommandImpl(DocumentImpl *document, Type type);
0769     virtual ~IndentOutdentCommandImpl();
0770 
0771     void doApply() override;
0772 
0773 private:
0774     void indent();
0775     void outdent();
0776 
0777     Type m_commandType;
0778 };
0779 
0780 //------------------------------------------------------------------------------------------
0781 
0782 } // end namespace khtml
0783 
0784 #endif
0785