00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __htmleditingimpl_h__
00027 #define __htmleditingimpl_h__
00028
00029 #include "misc/shared.h"
00030 #include "htmlediting.h"
00031
00032 #include "xml/dom_position.h"
00033 #include "xml/dom_selection.h"
00034 #include "dom/dom_string.h"
00035
00036 #include <QList>
00037
00038 namespace DOM {
00039 class CSSProperty;
00040 class CSSStyleDeclarationImpl;
00041 class DocumentImpl;
00042 class DOMString;
00043 class ElementImpl;
00044 class HTMLElementImpl;
00045 class NodeImpl;
00046 class NodeListImpl;
00047 class Position;
00048 class Range;
00049 class Selection;
00050 class TextImpl;
00051 class TreeWalkerImpl;
00052 }
00053
00054 namespace khtml {
00055
00056
00057
00058
00059 class EditCommandImpl : public SharedCommandImpl
00060 {
00061 public:
00062 EditCommandImpl(DOM::DocumentImpl *);
00063 virtual ~EditCommandImpl();
00064
00065 virtual int commandID() const;
00066 bool isCompositeStep() const { return parent(); }
00067 EditCommandImpl* parent() const;
00068 void setParent(EditCommandImpl *);
00069
00070 enum ECommandState { NotApplied, Applied };
00071
00072 void apply();
00073 void unapply();
00074 void reapply();
00075
00076 virtual void doApply() = 0;
00077 virtual void doUnapply() = 0;
00078 virtual void doReapply();
00079
00080 virtual DOM::DocumentImpl* document() const { return m_document.get(); }
00081
00082 DOM::Selection startingSelection() const { return m_startingSelection; }
00083 DOM::Selection endingSelection() const { return m_endingSelection; }
00084
00085 ECommandState state() const { return m_state; }
00086 void setState(ECommandState state) { m_state = state; }
00087
00088 void setStartingSelection(const DOM::Selection &s);
00089 void setEndingSelection(const DOM::Selection &s);
00090
00091 private:
00092 DocPtr<DOM::DocumentImpl> m_document;
00093 ECommandState m_state;
00094 DOM::Selection m_startingSelection;
00095 DOM::Selection m_endingSelection;
00096 EditCommandImpl* m_parent;
00097 };
00098
00099
00100
00101
00102 class CompositeEditCommandImpl : public EditCommandImpl
00103 {
00104 public:
00105 CompositeEditCommandImpl(DOM::DocumentImpl *);
00106 virtual ~CompositeEditCommandImpl();
00107
00108 virtual int commandID() const;
00109
00110 virtual void doApply() = 0;
00111 virtual void doUnapply();
00112 virtual void doReapply();
00113
00114 protected:
00115
00116
00117
00118 void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
00119 void applyCommandToComposite(EditCommand &);
00120 void deleteCollapsibleWhitespace();
00121 void deleteCollapsibleWhitespace(const DOM::Selection &selection);
00122 void deleteKeyPressed();
00123 void deleteSelection();
00124 void deleteSelection(const DOM::Selection &selection);
00125 void deleteText(DOM::TextImpl *node, long offset, long count);
00126 void inputText(const DOM::DOMString &text);
00127 void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
00128 void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
00129 void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
00130 void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
00131 void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
00132 void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
00133 void removeNodeAttribute(DOM::ElementImpl *, int attribute);
00134 void removeNode(DOM::NodeImpl *removeChild);
00135 void removeNodeAndPrune(DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
00136 void removeNodePreservingChildren(DOM::NodeImpl *node);
00137 void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
00138 void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
00139 void splitTextNode(DOM::TextImpl *text, long offset);
00140
00141 DOM::ElementImpl *createTypingStyleElement() const;
00142
00143 QList<EditCommand> m_cmds;
00144 };
00145
00146
00147
00148
00149
00150
00151 class AppendNodeCommandImpl : public EditCommandImpl
00152 {
00153 public:
00154 AppendNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *parentNode, DOM::NodeImpl *appendChild);
00155 virtual ~AppendNodeCommandImpl();
00156
00157 virtual int commandID() const;
00158
00159 virtual void doApply();
00160 virtual void doUnapply();
00161
00162 DOM::NodeImpl *parentNode() const { return m_parentNode; }
00163 DOM::NodeImpl *appendChild() const { return m_appendChild; }
00164
00165 private:
00166 DOM::NodeImpl *m_parentNode;
00167 DOM::NodeImpl *m_appendChild;
00168 };
00169
00170
00171
00172
00173 class ApplyStyleCommandImpl : public CompositeEditCommandImpl
00174 {
00175 public:
00176 ApplyStyleCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *style);
00177 virtual ~ApplyStyleCommandImpl();
00178
00179 virtual int commandID() const;
00180
00181 virtual void doApply();
00182
00183 DOM::CSSStyleDeclarationImpl *style() const { return m_style; }
00184
00185 struct StyleChange {
00186 StyleChange() : applyBold(false), applyItalic(false) {}
00187 DOM::DOMString cssStyle;
00188 bool applyBold:1;
00189 bool applyItalic:1;
00190 };
00191
00192 private:
00193
00194 bool isHTMLStyleNode(DOM::HTMLElementImpl *);
00195 void removeHTMLStyleNode(DOM::HTMLElementImpl *);
00196 void removeCSSStyle(DOM::HTMLElementImpl *);
00197 void removeStyle(const DOM::Position &start, const DOM::Position &end);
00198 bool nodeFullySelected(const DOM::NodeImpl *node) const;
00199
00200
00201 bool currentlyHasStyle(const DOM::Position &, const DOM::CSSProperty *) const;
00202 StyleChange computeStyleChange(const DOM::Position &, DOM::CSSStyleDeclarationImpl *);
00203 bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
00204 DOM::NodeImpl *splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
00205 void surroundNodeRangeWithElement(DOM::NodeImpl *start, DOM::NodeImpl *end, DOM::ElementImpl *element);
00206 DOM::Position positionInsertionPoint(DOM::Position);
00207 void applyStyleIfNeeded(DOM::NodeImpl *start, DOM::NodeImpl *end);
00208
00209 DOM::CSSStyleDeclarationImpl *m_style;
00210 };
00211
00212
00213
00214
00215 class DeleteCollapsibleWhitespaceCommandImpl : public CompositeEditCommandImpl
00216 {
00217 public:
00218 DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document);
00219 DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
00220
00221 virtual ~DeleteCollapsibleWhitespaceCommandImpl();
00222
00223 virtual int commandID() const;
00224
00225 virtual void doApply();
00226
00227 private:
00228 DOM::Position deleteWhitespace(const DOM::Position &pos);
00229
00230 unsigned long m_charactersDeleted;
00231 DOM::Selection m_selectionToCollapse;
00232 bool m_hasSelectionToCollapse;
00233 };
00234
00235
00236
00237
00238 class DeleteSelectionCommandImpl : public CompositeEditCommandImpl
00239 {
00240 public:
00241 DeleteSelectionCommandImpl(DOM::DocumentImpl *document);
00242 DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
00243
00244 virtual ~DeleteSelectionCommandImpl();
00245
00246 virtual int commandID() const;
00247
00248 virtual void doApply();
00249
00250 private:
00251 void deleteDownstreamWS(const DOM::Position &start);
00252 bool containsOnlyWhitespace(const DOM::Position &start, const DOM::Position &end);
00253 void joinTextNodesWithSameStyle();
00254
00255 DOM::Selection m_selectionToDelete;
00256 bool m_hasSelectionToDelete;
00257 };
00258
00259
00260
00261
00262 class DeleteTextCommandImpl : public EditCommandImpl
00263 {
00264 public:
00265 DeleteTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
00266 virtual ~DeleteTextCommandImpl();
00267
00268 virtual int commandID() const;
00269
00270 virtual void doApply();
00271 virtual void doUnapply();
00272
00273 DOM::TextImpl *node() const { return m_node; }
00274 long offset() const { return m_offset; }
00275 long count() const { return m_count; }
00276
00277 private:
00278 DOM::TextImpl *m_node;
00279 long m_offset;
00280 long m_count;
00281 DOM::DOMString m_text;
00282 };
00283
00284
00285
00286
00287 class InputNewlineCommandImpl : public CompositeEditCommandImpl
00288 {
00289 public:
00290 InputNewlineCommandImpl(DOM::DocumentImpl *document);
00291 virtual ~InputNewlineCommandImpl();
00292
00293 virtual int commandID() const;
00294
00295 virtual void doApply();
00296
00297 private:
00298 void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
00299 void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
00300 };
00301
00302
00303
00304
00305 class InputTextCommandImpl : public CompositeEditCommandImpl
00306 {
00307 public:
00308 InputTextCommandImpl(DOM::DocumentImpl *document);
00309 virtual ~InputTextCommandImpl();
00310
00311 virtual int commandID() const;
00312
00313 virtual void doApply();
00314
00315 void deleteCharacter();
00316 void input(const DOM::DOMString &text);
00317
00318 unsigned long charactersAdded() const { return m_charactersAdded; }
00319
00320 private:
00321 DOM::Position prepareForTextInsertion(bool adjustDownstream);
00322 void execute(const DOM::DOMString &text);
00323 void insertSpace(DOM::TextImpl *textNode, unsigned long offset);
00324
00325 unsigned long m_charactersAdded;
00326 };
00327
00328
00329
00330
00331 class InsertNodeBeforeCommandImpl : public EditCommandImpl
00332 {
00333 public:
00334 InsertNodeBeforeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
00335 virtual ~InsertNodeBeforeCommandImpl();
00336
00337 virtual int commandID() const;
00338
00339 virtual void doApply();
00340 virtual void doUnapply();
00341
00342 DOM::NodeImpl *insertChild() const { return m_insertChild; }
00343 DOM::NodeImpl *refChild() const { return m_refChild; }
00344
00345 private:
00346 DOM::NodeImpl *m_insertChild;
00347 DOM::NodeImpl *m_refChild;
00348 };
00349
00350
00351
00352
00353 class InsertTextCommandImpl : public EditCommandImpl
00354 {
00355 public:
00356 InsertTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
00357 virtual ~InsertTextCommandImpl();
00358
00359 virtual int commandID() const;
00360
00361 virtual void doApply();
00362 virtual void doUnapply();
00363
00364 DOM::TextImpl *node() const { return m_node; }
00365 long offset() const { return m_offset; }
00366 DOM::DOMString text() const { return m_text; }
00367
00368 private:
00369 DOM::TextImpl *m_node;
00370 long m_offset;
00371 DOM::DOMString m_text;
00372 };
00373
00374
00375
00376
00377 class JoinTextNodesCommandImpl : public EditCommandImpl
00378 {
00379 public:
00380 JoinTextNodesCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
00381 virtual ~JoinTextNodesCommandImpl();
00382
00383 virtual int commandID() const;
00384
00385 virtual void doApply();
00386 virtual void doUnapply();
00387
00388 DOM::TextImpl *firstNode() const { return m_text1; }
00389 DOM::TextImpl *secondNode() const { return m_text2; }
00390
00391 private:
00392 DOM::TextImpl *m_text1;
00393 DOM::TextImpl *m_text2;
00394 unsigned long m_offset;
00395 };
00396
00397
00398
00399
00400 class ReplaceSelectionCommandImpl : public CompositeEditCommandImpl
00401 {
00402 public:
00403 ReplaceSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, bool selectReplacement=true);
00404 virtual ~ReplaceSelectionCommandImpl();
00405
00406 virtual int commandID() const;
00407
00408 virtual void doApply();
00409
00410 private:
00411 DOM::DocumentFragmentImpl *m_fragment;
00412 bool m_selectReplacement;
00413 };
00414
00415
00416
00417
00418 class MoveSelectionCommandImpl : public CompositeEditCommandImpl
00419 {
00420 public:
00421 MoveSelectionCommandImpl(DOM::DocumentImpl *document, DOM::DocumentFragmentImpl *fragment, DOM::Position &position);
00422 virtual ~MoveSelectionCommandImpl();
00423
00424 virtual int commandID() const;
00425
00426 virtual void doApply();
00427
00428 private:
00429 DOM::DocumentFragmentImpl *m_fragment;
00430 DOM::Position m_position;
00431 };
00432
00433
00434
00435
00436 class RemoveCSSPropertyCommandImpl : public EditCommandImpl
00437 {
00438 public:
00439 RemoveCSSPropertyCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
00440 virtual ~RemoveCSSPropertyCommandImpl();
00441
00442 virtual int commandID() const;
00443
00444 virtual void doApply();
00445 virtual void doUnapply();
00446
00447 DOM::CSSStyleDeclarationImpl *styleDeclaration() const { return m_decl; }
00448 int property() const { return m_property; }
00449
00450 private:
00451 DOM::CSSStyleDeclarationImpl *m_decl;
00452 int m_property;
00453 DOM::DOMString m_oldValue;
00454 bool m_important;
00455 };
00456
00457
00458
00459
00460 class RemoveNodeAttributeCommandImpl : public EditCommandImpl
00461 {
00462 public:
00463 RemoveNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
00464 virtual ~RemoveNodeAttributeCommandImpl();
00465
00466 virtual int commandID() const;
00467
00468 virtual void doApply();
00469 virtual void doUnapply();
00470
00471 DOM::ElementImpl *element() const { return m_element; }
00472 DOM::NodeImpl::Id attribute() const { return m_attribute; }
00473
00474 private:
00475 DOM::ElementImpl *m_element;
00476 DOM::NodeImpl::Id m_attribute;
00477 DOM::DOMString m_oldValue;
00478 };
00479
00480
00481
00482
00483 class RemoveNodeCommandImpl : public EditCommandImpl
00484 {
00485 public:
00486 RemoveNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
00487 virtual ~RemoveNodeCommandImpl();
00488
00489 virtual int commandID() const;
00490
00491 virtual void doApply();
00492 virtual void doUnapply();
00493
00494 DOM::NodeImpl *node() const { return m_removeChild; }
00495
00496 private:
00497 DOM::NodeImpl *m_parent;
00498 DOM::NodeImpl *m_removeChild;
00499 DOM::NodeImpl *m_refChild;
00500 };
00501
00502
00503
00504
00505 class RemoveNodeAndPruneCommandImpl : public CompositeEditCommandImpl
00506 {
00507 public:
00508 RemoveNodeAndPruneCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
00509 virtual ~RemoveNodeAndPruneCommandImpl();
00510
00511 virtual int commandID() const;
00512
00513 virtual void doApply();
00514
00515 DOM::NodeImpl *pruneNode() const { return m_pruneNode; }
00516 DOM::NodeImpl *stopNode() const { return m_stopNode; }
00517
00518 private:
00519 DOM::NodeImpl *m_pruneNode;
00520 DOM::NodeImpl *m_stopNode;
00521 };
00522
00523
00524
00525
00526 class RemoveNodePreservingChildrenCommandImpl : public CompositeEditCommandImpl
00527 {
00528 public:
00529 RemoveNodePreservingChildrenCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
00530 virtual ~RemoveNodePreservingChildrenCommandImpl();
00531
00532 virtual int commandID() const;
00533
00534 virtual void doApply();
00535
00536 DOM::NodeImpl *node() const { return m_node; }
00537
00538 private:
00539 DOM::NodeImpl *m_node;
00540 };
00541
00542
00543
00544
00545 class SetNodeAttributeCommandImpl : public EditCommandImpl
00546 {
00547 public:
00548 SetNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
00549 virtual ~SetNodeAttributeCommandImpl();
00550
00551 virtual int commandID() const;
00552
00553 virtual void doApply();
00554 virtual void doUnapply();
00555
00556 DOM::ElementImpl *element() const { return m_element; }
00557 DOM::NodeImpl::Id attribute() const { return m_attribute; }
00558 DOM::DOMString value() const { return m_value; }
00559
00560 private:
00561 DOM::ElementImpl *m_element;
00562 DOM::NodeImpl::Id m_attribute;
00563 DOM::DOMString m_value;
00564 DOM::DOMString m_oldValue;
00565 };
00566
00567
00568
00569
00570 class SplitTextNodeCommandImpl : public EditCommandImpl
00571 {
00572 public:
00573 SplitTextNodeCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, long);
00574 virtual ~SplitTextNodeCommandImpl();
00575
00576 virtual int commandID() const;
00577
00578 virtual void doApply();
00579 virtual void doUnapply();
00580
00581 DOM::TextImpl *node() const { return m_text2; }
00582 long offset() const { return m_offset; }
00583
00584 private:
00585 DOM::TextImpl *m_text1;
00586 DOM::TextImpl *m_text2;
00587 unsigned long m_offset;
00588 };
00589
00590
00591
00592
00593 class TypingCommandImpl : public CompositeEditCommandImpl
00594 {
00595 public:
00596 TypingCommandImpl(DOM::DocumentImpl *document);
00597 virtual ~TypingCommandImpl();
00598
00599 virtual int commandID() const;
00600
00601 virtual void doApply();
00602
00603 bool openForMoreTyping() const { return m_openForMoreTyping; }
00604 void closeTyping() { m_openForMoreTyping = false; }
00605
00606 void insertText(const DOM::DOMString &text);
00607 void insertNewline();
00608 void deleteKeyPressed();
00609
00610 private:
00611 void issueCommandForDeleteKey();
00612 void removeCommand(const EditCommand &);
00613 void typingAddedToOpenCommand();
00614
00615 bool m_openForMoreTyping;
00616 };
00617
00618
00619
00620 }
00621
00622 #endif
00623