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"
28 #include "xml/dom_position.h"
29 #include "xml/dom_docimpl.h"
30 #include "css/css_valueimpl.h"
31 #include "css/css_computedstyle.h"
34 #include "KWQAssertions.h"
35 #include "KWQLogging.h"
36 #include "KWQKHTMLPart.h"
38 #define ASSERT(assertion) ((void)0)
39 #define ASSERT_WITH_MESSAGE(assertion, formatAndArgs...) ((void)0)
40 #define ASSERT_NOT_REACHED() ((void)0)
41 #define LOG(channel, formatAndArgs...) ((void)0)
42 #define ERROR(formatAndArgs...) ((void)0)
43 #define ASSERT(assertion) assert(assertion)
45 #define debugPosition(a,b) ((void)0)
46 #define debugNode(a,b) ((void)0)
50 using DOM::DocumentImpl;
52 using DOM::CSSMutableStyleDeclarationImpl;
53 using DOM::CSSComputedStyleDeclarationImpl;
55 #define IF_IMPL_NULL_RETURN_ARG(arg) do { \
56 if (isNull()) { return arg; } \
59 #define IF_IMPL_NULL_RETURN do { \
60 if (isNull()) { return; } \
65 //------------------------------------------------------------------------------------------
68 EditCommandPtr::EditCommandPtr()
72 EditCommandPtr::EditCommandPtr(EditCommand *impl) : SharedPtr<EditCommand>(impl)
76 EditCommandPtr::EditCommandPtr(const EditCommandPtr &o) : SharedPtr<EditCommand>(o)
80 EditCommandPtr::~EditCommandPtr()
84 EditCommandPtr &EditCommandPtr::operator=(const EditCommandPtr &c)
86 static_cast<SharedPtr<EditCommand> &>(*this) = c;
90 bool EditCommandPtr::isCompositeStep() const
92 IF_IMPL_NULL_RETURN_ARG(false);
93 return get()->isCompositeStep();
96 bool EditCommandPtr::isInsertTextCommand() const
98 IF_IMPL_NULL_RETURN_ARG(false);
99 return get()->isInsertTextCommand();
102 bool EditCommandPtr::isTypingCommand() const
104 IF_IMPL_NULL_RETURN_ARG(false);
105 return get()->isTypingCommand();
108 void EditCommandPtr::apply() const
114 void EditCommandPtr::unapply() const
120 void EditCommandPtr::reapply() const
126 EditAction EditCommandPtr::editingAction() const
128 IF_IMPL_NULL_RETURN_ARG(EditActionUnspecified);
129 return get()->editingAction();
132 DocumentImpl * const EditCommandPtr::document() const
134 IF_IMPL_NULL_RETURN_ARG(0);
135 return get()->document();
138 Selection EditCommandPtr::startingSelection() const
140 IF_IMPL_NULL_RETURN_ARG(Selection());
141 return get()->startingSelection();
144 Selection EditCommandPtr::endingSelection() const
146 IF_IMPL_NULL_RETURN_ARG(Selection());
147 return get()->endingSelection();
150 void EditCommandPtr::setStartingSelection(const Selection &s) const
153 get()->setStartingSelection(s);
156 void EditCommandPtr::setStartingSelection(const VisiblePosition &p) const
159 get()->setStartingSelection(p);
162 void EditCommandPtr::setStartingSelection(const Position &p, EAffinity affinity) const
165 Selection s = Selection(p, affinity);
166 get()->setStartingSelection(s);
169 void EditCommandPtr::setEndingSelection(const Selection &s) const
172 get()->setEndingSelection(s);
175 void EditCommandPtr::setEndingSelection(const VisiblePosition &p) const
178 get()->setEndingSelection(p);
181 void EditCommandPtr::setEndingSelection(const Position &p, EAffinity affinity) const
184 Selection s = Selection(p, affinity);
185 get()->setEndingSelection(s);
188 CSSMutableStyleDeclarationImpl *EditCommandPtr::typingStyle() const
190 IF_IMPL_NULL_RETURN_ARG(0);
191 return get()->typingStyle();
194 void EditCommandPtr::setTypingStyle(CSSMutableStyleDeclarationImpl *style) const
197 get()->setTypingStyle(style);
200 EditCommandPtr EditCommandPtr::parent() const
202 IF_IMPL_NULL_RETURN_ARG(0);
203 return get()->parent();
206 void EditCommandPtr::setParent(const EditCommandPtr &cmd) const
209 get()->setParent(cmd.get());
212 EditCommandPtr &EditCommandPtr::emptyCommand()
214 static EditCommandPtr m_emptyCommand;
215 return m_emptyCommand;
218 //------------------------------------------------------------------------------------------
221 EditCommand::EditCommand(DocumentImpl *document)
222 : m_document(document), m_state(NotApplied), m_typingStyle(0), m_parent(0)
225 ASSERT(m_document->part());
227 m_startingSelection = m_document->part()->selection();
228 m_endingSelection = m_startingSelection;
230 m_document->part()->setSelection(Selection(), false, true);
233 EditCommand::~EditCommand()
238 m_typingStyle->deref();
241 void EditCommand::apply()
244 ASSERT(m_document->part());
245 ASSERT(state() == NotApplied);
247 KHTMLPart *part = m_document->part();
249 ASSERT(part->selection().isNone());
255 // FIXME: Improve typing style.
256 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
257 if (!preservesTypingStyle())
260 if (!isCompositeStep()) {
261 document()->updateLayout();
262 EditCommandPtr cmd(this);
263 part->appliedEditing(cmd);
267 void EditCommand::unapply()
270 ASSERT(m_document->part());
271 ASSERT(state() == Applied);
273 bool topLevel = !isCompositeStep();
275 KHTMLPart *part = m_document->part();
278 part->setSelection(Selection(), false, true);
280 ASSERT(part->selection().isNone());
284 m_state = NotApplied;
287 document()->updateLayout();
288 EditCommandPtr cmd(this);
289 part->unappliedEditing(cmd);
293 void EditCommand::reapply()
296 ASSERT(m_document->part());
297 ASSERT(state() == NotApplied);
299 bool topLevel = !isCompositeStep();
301 KHTMLPart *part = m_document->part();
304 part->setSelection(Selection(), false, true);
306 ASSERT(part->selection().isNone());
313 document()->updateLayout();
314 EditCommandPtr cmd(this);
315 part->reappliedEditing(cmd);
319 void EditCommand::doReapply()
324 EditAction EditCommand::editingAction() const
326 return EditActionUnspecified;
329 void EditCommand::setStartingSelection(const Selection &s)
331 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
332 cmd->m_startingSelection = s;
335 void EditCommand::setStartingSelection(const VisiblePosition &p)
337 Selection s = Selection(p);
338 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
339 cmd->m_startingSelection = s;
342 void EditCommand::setStartingSelection(const Position &p, EAffinity affinity)
344 Selection s = Selection(p, affinity);
345 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
346 cmd->m_startingSelection = s;
349 void EditCommand::setEndingSelection(const Selection &s)
351 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
352 cmd->m_endingSelection = s;
355 void EditCommand::setEndingSelection(const VisiblePosition &p)
357 Selection s = Selection(p);
358 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
359 cmd->m_endingSelection = s;
362 void EditCommand::setEndingSelection(const Position &p, EAffinity affinity)
364 Selection s = Selection(p, affinity);
365 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
366 cmd->m_endingSelection = s;
369 void EditCommand::assignTypingStyle(CSSMutableStyleDeclarationImpl *style)
371 if (m_typingStyle == style)
374 CSSMutableStyleDeclarationImpl *old = m_typingStyle;
375 m_typingStyle = style;
377 m_typingStyle->ref();
382 void EditCommand::setTypingStyle(CSSMutableStyleDeclarationImpl *style)
384 // FIXME: Improve typing style.
385 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
386 for (EditCommand *cmd = this; cmd; cmd = cmd->m_parent)
387 cmd->assignTypingStyle(style);
390 bool EditCommand::preservesTypingStyle() const
395 bool EditCommand::isInsertTextCommand() const
400 bool EditCommand::isTypingCommand() const
405 CSSMutableStyleDeclarationImpl *EditCommand::styleAtPosition(const Position &pos)
407 CSSComputedStyleDeclarationImpl *computedStyle = pos.computedStyle();
408 computedStyle->ref();
409 CSSMutableStyleDeclarationImpl *style = computedStyle->copyInheritableProperties();
410 computedStyle->deref();
412 // FIXME: Improve typing style.
413 // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
414 CSSMutableStyleDeclarationImpl *typingStyle = document()->part()->typingStyle();
416 style->merge(typingStyle);