From 99c3b62e28d1c745b1de842f1cb5fd0088698f92 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 28 Jan 2015 15:27:33 +0900 Subject: [PATCH] Bug 917322 part.21 Ensure to cancel composition when TextInputProcessor is released r=smaug --- dom/base/TextInputProcessor.cpp | 10 ++++++ dom/base/TextInputProcessor.h | 5 +-- .../chrome/window_nsITextInputProcessor.xul | 32 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/dom/base/TextInputProcessor.cpp b/dom/base/TextInputProcessor.cpp index a943f7aa41d..ab7b8949835 100644 --- a/dom/base/TextInputProcessor.cpp +++ b/dom/base/TextInputProcessor.cpp @@ -65,6 +65,16 @@ TextInputProcessor::TextInputProcessor() TextInputProcessor::~TextInputProcessor() { + if (mDispatcher && mDispatcher->IsComposing()) { + // If this is composing and not canceling the composition, nobody can steal + // the rights of TextEventDispatcher from this instance. Therefore, this + // needs to cancel the composition here. + if (NS_SUCCEEDED(IsValidStateForComposition())) { + nsRefPtr kungFuDeathGrip(mDispatcher); + nsEventStatus status = nsEventStatus_eIgnore; + mDispatcher->CommitComposition(status, &EmptyString()); + } + } } NS_IMETHODIMP diff --git a/dom/base/TextInputProcessor.h b/dom/base/TextInputProcessor.h index 52cb2de352a..90ae42888e0 100644 --- a/dom/base/TextInputProcessor.h +++ b/dom/base/TextInputProcessor.h @@ -34,9 +34,10 @@ public: NS_IMETHOD_(void) OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) MOZ_OVERRIDE; -private: - ~TextInputProcessor(); +protected: + virtual ~TextInputProcessor(); +private: nsresult InitInternal(nsIDOMWindow* aWindow, nsITextInputProcessorCallback* aCallback, bool aForTests, diff --git a/dom/base/test/chrome/window_nsITextInputProcessor.xul b/dom/base/test/chrome/window_nsITextInputProcessor.xul index cf001fe994c..1f6e62aedd4 100644 --- a/dom/base/test/chrome/window_nsITextInputProcessor.xul +++ b/dom/base/test/chrome/window_nsITextInputProcessor.xul @@ -250,6 +250,37 @@ function runInitMethodTests() } } +function runReleaseTests() +{ + var description = "runReleaseTests(): "; + + var TIP = createTIP(); + ok(TIP.initForTests(window), + description + "TIP.initForTests() should succeed"); + + input.value = ""; + input.focus(); + + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + is(input.value, "foo", + description + "the input should have composition string"); + + // Release the TIP + TIP = null; + // Needs to run GC forcibly for testing this. + SpecialPowers.gc(); + + is(input.value, "", + description + "the input should be empty because the composition should be canceled"); + + TIP = createTIP(); + ok(TIP.initForTests(window), + description + "TIP.initForTests() should succeed #2"); +} + function runCompositionTests() { var description = "runCompositionTests(): "; @@ -988,6 +1019,7 @@ function runTests() textareaInFrame = iframe.contentDocument.getElementById("textarea"); runInitMethodTests(); + runReleaseTests(); runCompositionTests(); runErrorTests(); runCommitCompositionTests();