2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef __htmleditingimpl_h__
27 #define __htmleditingimpl_h__
29 #include "misc/shared.h"
30 #include "htmlediting.h"
32 #include "xml/dom_position.h"
33 #include "xml/dom_selection.h"
34 #include "dom/dom_string.h"
40 class CSSStyleDeclarationImpl
;
44 class HTMLElementImpl
;
56 //------------------------------------------------------------------------------------------
59 class EditCommandImpl
: public SharedCommandImpl
62 EditCommandImpl(DOM::DocumentImpl
*);
63 virtual ~EditCommandImpl();
65 virtual int commandID() const;
66 bool isCompositeStep() const { return parent(); }
67 EditCommandImpl
* parent() const;
68 void setParent(EditCommandImpl
*);
70 enum ECommandState
{ NotApplied
, Applied
};
76 virtual void doApply() = 0;
77 virtual void doUnapply() = 0;
78 virtual void doReapply(); // calls doApply()
80 virtual DOM::DocumentImpl
* document() const { return m_document
.get(); }
82 DOM::Selection
startingSelection() const { return m_startingSelection
; }
83 DOM::Selection
endingSelection() const { return m_endingSelection
; }
85 ECommandState
state() const { return m_state
; }
86 void setState(ECommandState state
) { m_state
= state
; }
88 void setStartingSelection(const DOM::Selection
&s
);
89 void setEndingSelection(const DOM::Selection
&s
);
92 DocPtr
<DOM::DocumentImpl
> m_document
;
93 ECommandState m_state
;
94 DOM::Selection m_startingSelection
;
95 DOM::Selection m_endingSelection
;
96 EditCommandImpl
* m_parent
;
99 //------------------------------------------------------------------------------------------
100 // CompositeEditCommandImpl
102 class CompositeEditCommandImpl
: public EditCommandImpl
105 CompositeEditCommandImpl(DOM::DocumentImpl
*);
106 virtual ~CompositeEditCommandImpl();
108 virtual int commandID() const;
110 virtual void doApply() = 0;
111 virtual void doUnapply();
112 virtual void doReapply();
116 // sugary-sweet convenience functions to help create and apply edit commands in composite commands
118 void appendNode(DOM::NodeImpl
*parent
, DOM::NodeImpl
*appendChild
);
119 void applyCommandToComposite(EditCommand
&);
120 void deleteCollapsibleWhitespace();
121 void deleteCollapsibleWhitespace(const DOM::Selection
&selection
);
122 void deleteKeyPressed();
123 void deleteSelection();
124 void deleteSelection(const DOM::Selection
&selection
);
125 void deleteText(DOM::TextImpl
*node
, long offset
, long count
);
126 void inputText(const DOM::DOMString
&text
);
127 void insertNodeAfter(DOM::NodeImpl
*insertChild
, DOM::NodeImpl
*refChild
);
128 void insertNodeAt(DOM::NodeImpl
*insertChild
, DOM::NodeImpl
*refChild
, long offset
);
129 void insertNodeBefore(DOM::NodeImpl
*insertChild
, DOM::NodeImpl
*refChild
);
130 void insertText(DOM::TextImpl
*node
, long offset
, const DOM::DOMString
&text
);
131 void joinTextNodes(DOM::TextImpl
*text1
, DOM::TextImpl
*text2
);
132 void removeCSSProperty(DOM::CSSStyleDeclarationImpl
*, int property
);
133 void removeNodeAttribute(DOM::ElementImpl
*, int attribute
);
134 void removeNode(DOM::NodeImpl
*removeChild
);
135 void removeNodeAndPrune(DOM::NodeImpl
*pruneNode
, DOM::NodeImpl
*stopNode
=0);
136 void removeNodePreservingChildren(DOM::NodeImpl
*node
);
137 void replaceText(DOM::TextImpl
*node
, long offset
, long count
, const DOM::DOMString
&replacementText
);
138 void setNodeAttribute(DOM::ElementImpl
*, int attribute
, const DOM::DOMString
&);
139 void splitTextNode(DOM::TextImpl
*text
, long offset
);
141 DOM::ElementImpl
*createTypingStyleElement() const;
143 QList
<EditCommand
> m_cmds
;
146 //==========================================================================================
148 //------------------------------------------------------------------------------------------
149 // AppendNodeCommandImpl
151 class AppendNodeCommandImpl
: public EditCommandImpl
154 AppendNodeCommandImpl(DOM::DocumentImpl
*, DOM::NodeImpl
*parentNode
, DOM::NodeImpl
*appendChild
);
155 virtual ~AppendNodeCommandImpl();
157 virtual int commandID() const;
159 virtual void doApply();
160 virtual void doUnapply();
162 DOM::NodeImpl
*parentNode() const { return m_parentNode
; }
163 DOM::NodeImpl
*appendChild() const { return m_appendChild
; }
166 DOM::NodeImpl
*m_parentNode
;
167 DOM::NodeImpl
*m_appendChild
;
170 //------------------------------------------------------------------------------------------
171 // ApplyStyleCommandImpl
173 class ApplyStyleCommandImpl
: public CompositeEditCommandImpl
176 ApplyStyleCommandImpl(DOM::DocumentImpl
*, DOM::CSSStyleDeclarationImpl
*style
);
177 virtual ~ApplyStyleCommandImpl();
179 virtual int commandID() const;
181 virtual void doApply();
183 DOM::CSSStyleDeclarationImpl
*style() const { return m_style
; }
186 StyleChange() : applyBold(false), applyItalic(false) {}
187 DOM::DOMString cssStyle
;
193 // style-removal helpers
194 bool isHTMLStyleNode(DOM::HTMLElementImpl
*);
195 void removeHTMLStyleNode(DOM::HTMLElementImpl
*);
196 void removeCSSStyle(DOM::HTMLElementImpl
*);
197 void removeStyle(const DOM::Position
&start
, const DOM::Position
&end
);
198 bool nodeFullySelected(const DOM::NodeImpl
*node
) const;
200 // style-application helpers
201 bool currentlyHasStyle(const DOM::Position
&, const DOM::CSSProperty
*) const;
202 StyleChange
computeStyleChange(const DOM::Position
&, DOM::CSSStyleDeclarationImpl
*);
203 bool splitTextAtStartIfNeeded(const DOM::Position
&start
, const DOM::Position
&end
);
204 DOM::NodeImpl
*splitTextAtEndIfNeeded(const DOM::Position
&start
, const DOM::Position
&end
);
205 void surroundNodeRangeWithElement(DOM::NodeImpl
*start
, DOM::NodeImpl
*end
, DOM::ElementImpl
*element
);
206 DOM::Position
positionInsertionPoint(DOM::Position
);
207 void applyStyleIfNeeded(DOM::NodeImpl
*start
, DOM::NodeImpl
*end
);
209 DOM::CSSStyleDeclarationImpl
*m_style
;
212 //------------------------------------------------------------------------------------------
213 // DeleteCollapsibleWhitespaceCommandImpl
215 class DeleteCollapsibleWhitespaceCommandImpl
: public CompositeEditCommandImpl
218 DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl
*document
);
219 DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl
*document
, const DOM::Selection
&selection
);
221 virtual ~DeleteCollapsibleWhitespaceCommandImpl();
223 virtual int commandID() const;
225 virtual void doApply();
228 DOM::Position
deleteWhitespace(const DOM::Position
&pos
);
230 unsigned long m_charactersDeleted
;
231 DOM::Selection m_selectionToCollapse
;
232 bool m_hasSelectionToCollapse
;
235 //------------------------------------------------------------------------------------------
236 // DeleteSelectionCommandImpl
238 class DeleteSelectionCommandImpl
: public CompositeEditCommandImpl
241 DeleteSelectionCommandImpl(DOM::DocumentImpl
*document
);
242 DeleteSelectionCommandImpl(DOM::DocumentImpl
*document
, const DOM::Selection
&selection
);
244 virtual ~DeleteSelectionCommandImpl();
246 virtual int commandID() const;
248 virtual void doApply();
251 void deleteDownstreamWS(const DOM::Position
&start
);
252 bool containsOnlyWhitespace(const DOM::Position
&start
, const DOM::Position
&end
);
253 void joinTextNodesWithSameStyle();
255 DOM::Selection m_selectionToDelete
;
256 bool m_hasSelectionToDelete
;
259 //------------------------------------------------------------------------------------------
260 // DeleteTextCommandImpl
262 class DeleteTextCommandImpl
: public EditCommandImpl
265 DeleteTextCommandImpl(DOM::DocumentImpl
*document
, DOM::TextImpl
*node
, long offset
, long count
);
266 virtual ~DeleteTextCommandImpl();
268 virtual int commandID() const;
270 virtual void doApply();
271 virtual void doUnapply();
273 DOM::TextImpl
*node() const { return m_node
; }
274 long offset() const { return m_offset
; }
275 long count() const { return m_count
; }
278 DOM::TextImpl
*m_node
;
281 DOM::DOMString m_text
;
284 //------------------------------------------------------------------------------------------
285 // InputNewlineCommandImpl
287 class InputNewlineCommandImpl
: public CompositeEditCommandImpl
290 InputNewlineCommandImpl(DOM::DocumentImpl
*document
);
291 virtual ~InputNewlineCommandImpl();
293 virtual int commandID() const;
295 virtual void doApply();
298 void insertNodeAfterPosition(DOM::NodeImpl
*node
, const DOM::Position
&pos
);
299 void insertNodeBeforePosition(DOM::NodeImpl
*node
, const DOM::Position
&pos
);
302 //------------------------------------------------------------------------------------------
303 // InputTextCommandImpl
305 class InputTextCommandImpl
: public CompositeEditCommandImpl
308 InputTextCommandImpl(DOM::DocumentImpl
*document
);
309 virtual ~InputTextCommandImpl();
311 virtual int commandID() const;
313 virtual void doApply();
315 void deleteCharacter();
316 void input(const DOM::DOMString
&text
);
318 unsigned long charactersAdded() const { return m_charactersAdded
; }
321 DOM::Position
prepareForTextInsertion(bool adjustDownstream
);
322 void execute(const DOM::DOMString
&text
);
323 void insertSpace(DOM::TextImpl
*textNode
, unsigned long offset
);
325 unsigned long m_charactersAdded
;
328 //------------------------------------------------------------------------------------------
329 // InsertNodeBeforeCommandImpl
331 class InsertNodeBeforeCommandImpl
: public EditCommandImpl
334 InsertNodeBeforeCommandImpl(DOM::DocumentImpl
*, DOM::NodeImpl
*insertChild
, DOM::NodeImpl
*refChild
);
335 virtual ~InsertNodeBeforeCommandImpl();
337 virtual int commandID() const;
339 virtual void doApply();
340 virtual void doUnapply();
342 DOM::NodeImpl
*insertChild() const { return m_insertChild
; }
343 DOM::NodeImpl
*refChild() const { return m_refChild
; }
346 DOM::NodeImpl
*m_insertChild
;
347 DOM::NodeImpl
*m_refChild
;
350 //------------------------------------------------------------------------------------------
351 // InsertTextCommandImpl
353 class InsertTextCommandImpl
: public EditCommandImpl
356 InsertTextCommandImpl(DOM::DocumentImpl
*document
, DOM::TextImpl
*, long, const DOM::DOMString
&);
357 virtual ~InsertTextCommandImpl();
359 virtual int commandID() const;
361 virtual void doApply();
362 virtual void doUnapply();
364 DOM::TextImpl
*node() const { return m_node
; }
365 long offset() const { return m_offset
; }
366 DOM::DOMString
text() const { return m_text
; }
369 DOM::TextImpl
*m_node
;
371 DOM::DOMString m_text
;
374 //------------------------------------------------------------------------------------------
375 // JoinTextNodesCommandImpl
377 class JoinTextNodesCommandImpl
: public EditCommandImpl
380 JoinTextNodesCommandImpl(DOM::DocumentImpl
*, DOM::TextImpl
*, DOM::TextImpl
*);
381 virtual ~JoinTextNodesCommandImpl();
383 virtual int commandID() const;
385 virtual void doApply();
386 virtual void doUnapply();
388 DOM::TextImpl
*firstNode() const { return m_text1
; }
389 DOM::TextImpl
*secondNode() const { return m_text2
; }
392 DOM::TextImpl
*m_text1
;
393 DOM::TextImpl
*m_text2
;
394 unsigned long m_offset
;
397 //------------------------------------------------------------------------------------------
398 // ReplaceSelectionCommandImpl
400 class ReplaceSelectionCommandImpl
: public CompositeEditCommandImpl
403 ReplaceSelectionCommandImpl(DOM::DocumentImpl
*document
, DOM::DocumentFragmentImpl
*fragment
, bool selectReplacement
=true);
404 virtual ~ReplaceSelectionCommandImpl();
406 virtual int commandID() const;
408 virtual void doApply();
411 DOM::DocumentFragmentImpl
*m_fragment
;
412 bool m_selectReplacement
;
415 //------------------------------------------------------------------------------------------
416 // MoveSelectionCommandImpl
418 class MoveSelectionCommandImpl
: public CompositeEditCommandImpl
421 MoveSelectionCommandImpl(DOM::DocumentImpl
*document
, DOM::DocumentFragmentImpl
*fragment
, DOM::Position
&position
);
422 virtual ~MoveSelectionCommandImpl();
424 virtual int commandID() const;
426 virtual void doApply();
429 DOM::DocumentFragmentImpl
*m_fragment
;
430 DOM::Position m_position
;
433 //------------------------------------------------------------------------------------------
434 // RemoveCSSPropertyCommand
436 class RemoveCSSPropertyCommandImpl
: public EditCommandImpl
439 RemoveCSSPropertyCommandImpl(DOM::DocumentImpl
*, DOM::CSSStyleDeclarationImpl
*, int property
);
440 virtual ~RemoveCSSPropertyCommandImpl();
442 virtual int commandID() const;
444 virtual void doApply();
445 virtual void doUnapply();
447 DOM::CSSStyleDeclarationImpl
*styleDeclaration() const { return m_decl
; }
448 int property() const { return m_property
; }
451 DOM::CSSStyleDeclarationImpl
*m_decl
;
453 DOM::DOMString m_oldValue
;
457 //------------------------------------------------------------------------------------------
458 // RemoveNodeAttributeCommandImpl
460 class RemoveNodeAttributeCommandImpl
: public EditCommandImpl
463 RemoveNodeAttributeCommandImpl(DOM::DocumentImpl
*, DOM::ElementImpl
*, DOM::NodeImpl::Id attribute
);
464 virtual ~RemoveNodeAttributeCommandImpl();
466 virtual int commandID() const;
468 virtual void doApply();
469 virtual void doUnapply();
471 DOM::ElementImpl
*element() const { return m_element
; }
472 DOM::NodeImpl::Id
attribute() const { return m_attribute
; }
475 DOM::ElementImpl
*m_element
;
476 DOM::NodeImpl::Id m_attribute
;
477 DOM::DOMString m_oldValue
;
480 //------------------------------------------------------------------------------------------
481 // RemoveNodeCommandImpl
483 class RemoveNodeCommandImpl
: public EditCommandImpl
486 RemoveNodeCommandImpl(DOM::DocumentImpl
*, DOM::NodeImpl
*);
487 virtual ~RemoveNodeCommandImpl();
489 virtual int commandID() const;
491 virtual void doApply();
492 virtual void doUnapply();
494 DOM::NodeImpl
*node() const { return m_removeChild
; }
497 DOM::NodeImpl
*m_parent
;
498 DOM::NodeImpl
*m_removeChild
;
499 DOM::NodeImpl
*m_refChild
;
502 //------------------------------------------------------------------------------------------
503 // RemoveNodeAndPruneCommandImpl
505 class RemoveNodeAndPruneCommandImpl
: public CompositeEditCommandImpl
508 RemoveNodeAndPruneCommandImpl(DOM::DocumentImpl
*, DOM::NodeImpl
*pruneNode
, DOM::NodeImpl
*stopNode
=0);
509 virtual ~RemoveNodeAndPruneCommandImpl();
511 virtual int commandID() const;
513 virtual void doApply();
515 DOM::NodeImpl
*pruneNode() const { return m_pruneNode
; }
516 DOM::NodeImpl
*stopNode() const { return m_stopNode
; }
519 DOM::NodeImpl
*m_pruneNode
;
520 DOM::NodeImpl
*m_stopNode
;
523 //------------------------------------------------------------------------------------------
524 // RemoveNodePreservingChildrenCommandImpl
526 class RemoveNodePreservingChildrenCommandImpl
: public CompositeEditCommandImpl
529 RemoveNodePreservingChildrenCommandImpl(DOM::DocumentImpl
*, DOM::NodeImpl
*);
530 virtual ~RemoveNodePreservingChildrenCommandImpl();
532 virtual int commandID() const;
534 virtual void doApply();
536 DOM::NodeImpl
*node() const { return m_node
; }
539 DOM::NodeImpl
*m_node
;
542 //------------------------------------------------------------------------------------------
543 // SetNodeAttributeCommandImpl
545 class SetNodeAttributeCommandImpl
: public EditCommandImpl
548 SetNodeAttributeCommandImpl(DOM::DocumentImpl
*, DOM::ElementImpl
*, DOM::NodeImpl::Id attribute
, const DOM::DOMString
&value
);
549 virtual ~SetNodeAttributeCommandImpl();
551 virtual int commandID() const;
553 virtual void doApply();
554 virtual void doUnapply();
556 DOM::ElementImpl
*element() const { return m_element
; }
557 DOM::NodeImpl::Id
attribute() const { return m_attribute
; }
558 DOM::DOMString
value() const { return m_value
; }
561 DOM::ElementImpl
*m_element
;
562 DOM::NodeImpl::Id m_attribute
;
563 DOM::DOMString m_value
;
564 DOM::DOMString m_oldValue
;
567 //------------------------------------------------------------------------------------------
568 // SplitTextNodeCommandImpl
570 class SplitTextNodeCommandImpl
: public EditCommandImpl
573 SplitTextNodeCommandImpl(DOM::DocumentImpl
*, DOM::TextImpl
*, long);
574 virtual ~SplitTextNodeCommandImpl();
576 virtual int commandID() const;
578 virtual void doApply();
579 virtual void doUnapply();
581 DOM::TextImpl
*node() const { return m_text2
; }
582 long offset() const { return m_offset
; }
585 DOM::TextImpl
*m_text1
;
586 DOM::TextImpl
*m_text2
;
587 unsigned long m_offset
;
590 //------------------------------------------------------------------------------------------
593 class TypingCommandImpl
: public CompositeEditCommandImpl
596 TypingCommandImpl(DOM::DocumentImpl
*document
);
597 virtual ~TypingCommandImpl();
599 virtual int commandID() const;
601 virtual void doApply();
603 bool openForMoreTyping() const { return m_openForMoreTyping
; }
604 void closeTyping() { m_openForMoreTyping
= false; }
606 void insertText(const DOM::DOMString
&text
);
607 void insertNewline();
608 void deleteKeyPressed();
611 void issueCommandForDeleteKey();
612 void removeCommand(const EditCommand
&);
613 void typingAddedToOpenCommand();
615 bool m_openForMoreTyping
;
618 //------------------------------------------------------------------------------------------
620 } // end namespace khtml