2 * Copyright (C) 2005 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 #include "edit_command.h"
27 #include "selection.h"
28 #include "khtml_part.h"
30 #include "xml/dom_position.h"
31 #include "xml/dom_docimpl.h"
32 #include "css/css_valueimpl.h"
33 #include "css/css_computedstyle.h"
36 #include "KWQAssertions.h"
38 #define ASSERT(assertion) assert(assertion)
41 using DOM::DocumentImpl;
43 using DOM::CSSMutableStyleDeclarationImpl;
44 using DOM::CSSComputedStyleDeclarationImpl;
46 #define IF_IMPL_NULL_RETURN_ARG(arg) do { \
47 if (isNull()) { return arg; } \
50 #define IF_IMPL_NULL_RETURN do { \
51 if (isNull()) { return; } \
56 //------------------------------------------------------------------------------------------
59 EditCommandPtr::EditCommandPtr()
63 EditCommandPtr::EditCommandPtr(EditCommand *impl) : SharedPtr<EditCommand>(impl)
67 EditCommandPtr::EditCommandPtr(const EditCommandPtr &o) : SharedPtr<EditCommand>(o)
71 EditCommandPtr::~EditCommandPtr()
75 EditCommandPtr &EditCommandPtr::operator=(const EditCommandPtr &c)
77 static_cast<SharedPtr<EditCommand> &>(*this) = c;
81 bool EditCommandPtr::isCompositeStep() const
83 IF_IMPL_NULL_RETURN_ARG(false);
84 return get()->isCompositeStep();
87 bool EditCommandPtr::isInsertTextCommand() const
89 IF_IMPL_NULL_RETURN_ARG(false);
90 return get()->isInsertTextCommand();
93 bool EditCommandPtr::isTypingCommand() const
95 IF_IMPL_NULL_RETURN_ARG(false);
96 return get()->isTypingCommand();
99 void EditCommandPtr::apply() const
105 void EditCommandPtr::unapply() const
111 void EditCommandPtr::reapply() const
117 EditAction EditCommandPtr::editingAction() const
119 IF_IMPL_NULL_RETURN_ARG(EditActionUnspecified);
120 return get()->editingAction();
123 DocumentImpl * const EditCommandPtr::document() const
125 IF_IMPL_NULL_RETURN_ARG(0);
126 return get()->document();
129 Selection EditCommandPtr::startingSelection() const
131 IF_IMPL_NULL_RETURN_ARG(Selection());
132 return get()->startingSelection();
135 Selection EditCommandPtr::endingSelection() const
137 IF_IMPL_NULL_RETURN_ARG(Selection());
138 return get()->endingSelection();
141 void EditCommandPtr::setStartingSelection(const Selection &s) const
144 get()->setStartingSelection(s);
147 void EditCommandPtr::setStartingSelection(const VisiblePosition &p) const
150 get()->setStartingSelection(p);
153 void EditCommandPtr::setStartingSelection(const Position &p, EAffinity affinity) const
156 Selection s = Selection(p, affinity);
157 get()->setStartingSelection(s);
160 void EditCommandPtr::setEndingSelection(const Selection &s) const
163 get()->setEndingSelection(s);
166 void EditCommandPtr::setEndingSelection(const VisiblePosition &p) const
169 get()->setEndingSelection(p);
172 void EditCommandPtr::setEndingSelection(const Position &p, EAffinity affinity) const
175 Selection s = Selection(p, affinity);
176 get()->setEndingSelection(s);
179 CSSMutableStyleDeclarationImpl *EditCommandPtr::typingStyle() const
181 IF_IMPL_NULL_RETURN_ARG(0);
182 return get()->typingStyle();
185 void EditCommandPtr::setTypingStyle(CSSMutableStyleDeclarationImpl *style) const
188 get()->setTypingStyle(style);
191 EditCommandPtr EditCommandPtr::parent() const
193 IF_IMPL_NULL_RETURN_ARG(0);
194 return get()->parent();
197 void EditCommandPtr::setParent(const EditCommandPtr &cmd) const
200 get()->setParent(cmd.get());
203 EditCommandPtr &EditCommandPtr::emptyCommand()
205 static EditCommandPtr m_emptyCommand;
206 return m_emptyCommand;
209 //------------------------------------------------------------------------------------------
212 EditCommand::EditCommand(DocumentImpl *document)
213 : m_document(document), m_state(NotApplied), m_typingStyle(0), m_parent(0)
216 ASSERT(m_document->part());
218 m_startingSelection = m_document->part()->selection();
219 m_endingSelection = m_startingSelection;
221 m_document->part()->setSelection(Selection(), false, true);
224 EditCommand::~EditCommand()
229 m_typingStyle->deref();
232 void EditCommand::apply()
235 ASSERT(m_document->part());
236 ASSERT(state() == NotApplied);
238 KHTMLPart *part = m_document->part();
240 ASSERT(part->selection().isNone());
246 // FIXME: Improve typing style.
247 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
248 if (!preservesTypingStyle())
251 if (!isCompositeStep()) {
252 document()->updateLayout();
253 EditCommandPtr cmd(this);
254 part->appliedEditing(cmd);
258 void EditCommand::unapply()
261 ASSERT(m_document->part());
262 ASSERT(state() == Applied);
264 bool topLevel = !isCompositeStep();
266 KHTMLPart *part = m_document->part();
269 part->setSelection(Selection(), false, true);
271 ASSERT(part->selection().isNone());
275 m_state = NotApplied;
278 document()->updateLayout();
279 EditCommandPtr cmd(this);
280 part->unappliedEditing(cmd);
284 void EditCommand::reapply()
287 ASSERT(m_document->part());
288 ASSERT(state() == NotApplied);
290 bool topLevel = !isCompositeStep();
292 KHTMLPart *part = m_document->part();
295 part->setSelection(Selection(), false, true);
297 ASSERT(part->selection().isNone());
304 document()->updateLayout();
305 EditCommandPtr cmd(this);
306 part->reappliedEditing(cmd);
310 void EditCommand::doReapply()
315 EditAction EditCommand::editingAction() const
317 return EditActionUnspecified;
320 void EditCommand::setStartingSelection(const Selection &s)
322 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
323 cmd->m_startingSelection = s;
326 void EditCommand::setStartingSelection(const VisiblePosition &p)
328 Selection s = Selection(p);
329 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
330 cmd->m_startingSelection = s;
333 void EditCommand::setStartingSelection(const Position &p, EAffinity affinity)
335 Selection s = Selection(p, affinity);
336 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
337 cmd->m_startingSelection = s;
340 void EditCommand::setEndingSelection(const Selection &s)
342 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
343 cmd->m_endingSelection = s;
346 void EditCommand::setEndingSelection(const VisiblePosition &p)
348 Selection s = Selection(p);
349 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
350 cmd->m_endingSelection = s;
353 void EditCommand::setEndingSelection(const Position &p, EAffinity affinity)
355 Selection s = Selection(p, affinity);
356 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
357 cmd->m_endingSelection = s;
360 void EditCommand::assignTypingStyle(CSSMutableStyleDeclarationImpl *style)
362 if (m_typingStyle == style)
365 CSSMutableStyleDeclarationImpl *old = m_typingStyle;
366 m_typingStyle = style;
368 m_typingStyle->ref();
373 void EditCommand::setTypingStyle(CSSMutableStyleDeclarationImpl *style)
375 // FIXME: Improve typing style.
376 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
377 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
378 cmd->assignTypingStyle(style);
381 bool EditCommand::preservesTypingStyle() const
386 bool EditCommand::isInsertTextCommand() const
391 bool EditCommand::isTypingCommand() const
396 CSSMutableStyleDeclarationImpl *EditCommand::styleAtPosition(const Position &pos)
398 CSSComputedStyleDeclarationImpl *computedStyle = pos.computedStyle();
399 computedStyle->ref();
400 CSSMutableStyleDeclarationImpl *style = computedStyle->copyInheritableProperties();
401 computedStyle->deref();
403 // FIXME: Improve typing style.
404 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
405 CSSMutableStyleDeclarationImpl *typingStyle = document()->part()->typingStyle();
407 style->merge(typingStyle);