--- /dev/null
+<script>
+window.onload = function() {
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ document.execCommand("selectall", false);
+ document.designMode="on";
+ document.execCommand("insertparagraph", false);
+ document.execCommand("InsertText", false);
+
+ document.firstChild.appendChild(document.createElement('body'));
+ document.body.innerText = "This tests executing an editing command while executing a typing command.\nPASS";
+};
+
+document.addEventListener("DOMNodeRemovedFromDocument",
+ function() { document.execCommand("JustifyNone", false); },true);
+
+</script>
+2012-01-13 Ryosuke Niwa <rniwa@webkit.org>
+
+ Crash in CompositeEditCommand::ensureComposition
+ https://bugs.webkit.org/show_bug.cgi?id=76207
+
+ Reviewed by Chang Shu.
+
+ The crash was caused by TypingCommand not kept alive when new editing commands are executed
+ during adding more typings to the open last typing command since m_lastEditCommand is replaced
+ by the new command. Fixed the bug by keeping them alive a little longer with RefPtr.
+
+ Test: editing/execCommand/editing-command-while-executing-typing-command-crash.html
+
+ * editing/FrameSelection.cpp:
+ (WebCore::shouldStopBlinkingDueToTypingCommand):
+ (WebCore::FrameSelection::updateAppearance):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::deleteSelection):
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ (WebCore::TypingCommand::insertText):
+ (WebCore::TypingCommand::insertLineBreak):
+ (WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
+ (WebCore::TypingCommand::insertParagraphSeparator):
+ (WebCore::TypingCommand::lastTypingCommandIfStillOpenForTyping):
+ (WebCore::TypingCommand::closeTyping):
+ * editing/TypingCommand.h:
+
2012-01-19 Andreas Kling <awesomekling@apple.com>
Unreviewed debug build fix.
return m_focused && m_frame->page() && m_frame->page()->focusController()->isActive();
}
+inline static bool shouldStopBlinkingDueToTypingCommand(Frame* frame)
+{
+ return frame->editor()->lastEditCommand() && frame->editor()->lastEditCommand()->shouldStopCaretBlinking();
+}
+
void FrameSelection::updateAppearance()
{
#if ENABLE(TEXT_CARET)
bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
bool shouldBlink = caretIsVisible() && isCaret() && (isContentEditable() || caretBrowsing);
-
- CompositeEditCommand* lastEditCommand = m_frame ? m_frame->editor()->lastEditCommand() : 0;
- bool shouldStopBlinkingDueToTypingCommand = lastEditCommand && lastEditCommand->shouldStopCaretBlinking();
// If the caret moved, stop the blink timer so we can restart with a
// black caret in the new location.
- if (caretRectChanged || !shouldBlink || shouldStopBlinkingDueToTypingCommand)
+ if (caretRectChanged || !shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame))
m_caretBlinkTimer.stop();
// Start blinking with a black caret. Be sure not to restart if we're
if (!frame->selection()->isRange())
return;
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->deleteSelection(options & SmartDelete);
return;
{
ASSERT(document);
if (granularity == CharacterGranularity) {
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
- updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand, document->frame());
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), document->frame());
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->deleteKeyPressed(granularity, options & KillRing);
return;
ASSERT(document);
Frame* frame = document->frame();
if (granularity == CharacterGranularity) {
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
- updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand, frame);
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame);
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->forwardDeleteKeyPressed(granularity, options & KillRing);
return;
// Set the starting and ending selection appropriately if we are using a selection
// that is different from the current selection. In the future, we should change EditCommand
// to deal with custom selections in a general way that can be used by all of the commands.
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
if (lastTypingCommand->endingSelection() != selectionForInsertion) {
lastTypingCommand->setStartingSelection(selectionForInsertion);
lastTypingCommand->setEndingSelection(selectionForInsertion);
void TypingCommand::insertLineBreak(Document *document, Options options)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertLineBreak();
return;
void TypingCommand::insertParagraphSeparatorInQuotedContent(Document *document)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->insertParagraphSeparatorInQuotedContent();
return;
}
void TypingCommand::insertParagraphSeparator(Document *document, Options options)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertParagraphSeparator();
return;
applyCommand(TypingCommand::create(document, InsertParagraphSeparator, "", options));
}
-TypingCommand* TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
+PassRefPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
{
ASSERT(frame);
- CompositeEditCommand* lastEditCommand = frame->editor()->lastEditCommand();
- if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand)->isOpenForMoreTyping())
+ RefPtr<CompositeEditCommand> lastEditCommand = frame->editor()->lastEditCommand();
+ if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand.get())->isOpenForMoreTyping())
return 0;
- return static_cast<TypingCommand*>(lastEditCommand);
+ return static_cast<TypingCommand*>(lastEditCommand.get());
}
void TypingCommand::closeTyping(Frame* frame)
{
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
lastTypingCommand->closeTyping();
}