Closed
Bug 1053048
Opened 10 years ago
Closed 10 years ago
Accessing selectionStart or selectionEnd from nsISelectionListener::NotifySelectionChanged() may cause cancelling the edit action
Categories
(Core :: DOM: Editor, defect)
Tracking
()
RESOLVED
FIXED
mozilla34
People
(Reporter: masayuki, Assigned: masayuki)
References
()
Details
Attachments
(3 files, 4 obsolete files)
3.52 KB,
patch
|
ehsan.akhgari
:
review+
|
Details | Diff | Splinter Review |
3.57 KB,
patch
|
ehsan.akhgari
:
review+
|
Details | Diff | Splinter Review |
12.34 KB,
patch
|
smaug
:
superreview+
|
Details | Diff | Splinter Review |
spinning off from bug 1026997. 1. Load the URL with a build applied the attached patch. 2. Click blank area of the <textarea> 3. Press Enter key Line break should be inserted but actually not inserted. The stack trace of calling nsISelectionListener::NotifySelectionChanged(): > xul.dll!mozilla::IMEContentObserver::NotifySelectionChanged(nsIDOMDocument * aDOMDocument, nsISelection * aSelection, short aReason) Line 375 C++ > xul.dll!nsFrameSelection::NotifySelectionListeners(short aType) Line 2018 + 0xb3 bytes C++ > xul.dll!nsFrameSelection::EndBatchChanges() Line 2007 + 0xc bytes C++ > xul.dll!mozilla::dom::Selection::EndBatchChanges() Line 5621 C++ > xul.dll!nsEditor::EndUpdateViewBatch() Line 4134 C++ > xul.dll!nsEditor::EndPlaceHolderTransaction() Line 951 C++ > xul.dll!nsAutoPlaceHolderBatch::~nsAutoPlaceHolderBatch() Line 36 + 0x16 bytes C++ > xul.dll!nsPlaintextEditor::TypedText(const nsAString_internal & aString, nsPlaintextEditor::ETypingAction aAction) Line 433 + 0x16 bytes C++ > xul.dll!nsPlaintextEditor::HandleKeyPressEvent(nsIDOMKeyEvent * aKeyEvent) Line 402 + 0x11 bytes C++ > xul.dll!nsEditorEventListener::KeyPress(nsIDOMEvent * aKeyEvent) Line 500 C++ Flushing layout is here: http://mxr.mozilla.org/mozilla-central/source/content/html/content/src/nsGenericHTMLElement.cpp?rev=a0778b3a1c04#1090 >> xul.dll!nsGenericHTMLElement::GetFormControlFrame(bool aFlushFrames) Line 1090 C++ > xul.dll!mozilla::dom::HTMLTextAreaElement::GetSelectionRange(int * aSelectionStart, int * aSelectionEnd) Line 765 C++ > xul.dll!mozilla::dom::HTMLTextAreaElement::GetSelectionStart(mozilla::ErrorResult & aError) Line 648 + 0xf bytes C++ > xul.dll!mozilla::dom::HTMLTextAreaElement::GetSelectionStart(int * aSelectionStart) Line 641 C++ > xul.dll!mozilla::IMEContentObserver::NotifySelectionChanged(nsIDOMDocument * aDOMDocument, nsISelection * aSelection, short aReason) Line 375 C++
Assignee | ||
Comment 1•10 years ago
|
||
This is the minimum patch for reproducing this bug.
Assignee | ||
Comment 2•10 years ago
|
||
Okay, probably, I understand the cause. Currently, testing on tryserver: https://tbpl.mozilla.org/?tree=Try&rev=9663b8fa1ccc
Assignee: nobody → masayuki
Assignee | ||
Comment 3•10 years ago
|
||
Attachment #8472116 -
Attachment is obsolete: true
Attachment #8472133 -
Attachment is obsolete: true
Attachment #8472970 -
Flags: review?(ehsan)
Assignee | ||
Comment 4•10 years ago
|
||
In the normal path, methods related to this bug are called as following order: 1. nsEditor::EndPlaceHolderTransaction() 2. selection listeners 3. nsTextInputListener::EditAction() 4. flushing layout 5. nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame) In the #3, the <textarea> or <input>'s value is modified and marked as "modified". However, at reproducing this bug, the order is: 1. nsEditor::EndPlaceHolderTransaction() 2. selection listeners 3. flushing layout 4. nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame) 5. nsTextInputListener::EditAction() Therefore, at detaching the editor, the modified value is ignored since following mTextCtrlElement->ValueChanged() returns false. http://mxr.mozilla.org/mozilla-central/source/content/html/content/src/nsTextEditorState.cpp?rev=a0778b3a1c04#1846 This is the reason why the old value is back at creating new editor for reframe. This patch ensures to call nsTextInputListener::EditAction() when nsTextEditorState::UnbindFromFrame() is called before it.
Attachment #8472975 -
Flags: review?(ehsan)
Assignee | ||
Updated•10 years ago
|
Status: NEW → ASSIGNED
Comment 5•10 years ago
|
||
Comment on attachment 8472975 [details] [diff] [review] Fix Review of attachment 8472975 [details] [diff] [review]: ----------------------------------------------------------------- I don't like this approach very much, but I can't think of a better way to fix this...
Attachment #8472975 -
Flags: review?(ehsan) → review+
Updated•10 years ago
|
Attachment #8472970 -
Flags: review?(ehsan) → review+
Assignee | ||
Comment 6•10 years ago
|
||
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #5) > I don't like this approach very much, but I can't think of a better way to > fix this... If you don't like mInEditAction, nsIEditor can have similar method (e.g., nsIEditor::IsHandlingEditAction()). But nsEditor needs to manage it with similar flag but it can be shared with IMEContentObserver and some other addons. If you like this approach better, I'll post new patch.
Flags: needinfo?(ehsan)
Comment 7•10 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #6) > (In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from > comment #5) > > I don't like this approach very much, but I can't think of a better way to > > fix this... > > If you don't like mInEditAction, nsIEditor can have similar method (e.g., > nsIEditor::IsHandlingEditAction()). But nsEditor needs to manage it with > similar flag but it can be shared with IMEContentObserver and some other > addons. If you like this approach better, I'll post new patch. Hmm, yes, I think that would be a bit better...
Flags: needinfo?(ehsan)
Assignee | ||
Comment 8•10 years ago
|
||
Okay, I'll recreate it with changing nsIEditor.
Assignee | ||
Comment 9•10 years ago
|
||
Let's create nsIEditor::isInEditAction for sharing the state between IMEContentObserver and nsTextEditorState.
Attachment #8474481 -
Flags: superreview?(bugs)
Attachment #8474481 -
Flags: review?(ehsan)
Comment 10•10 years ago
|
||
Comment on attachment 8474481 [details] [diff] [review] Implement nsIEditor.isInEditAction readonly attribute Could we make the attribute [infallible]
Attachment #8474481 -
Flags: superreview?(bugs) → superreview+
Assignee | ||
Comment 11•10 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #10) > Comment on attachment 8474481 [details] [diff] [review] > Implement nsIEditor.isInEditAction readonly attribute > > Could we make the attribute [infallible] Adding [infallible] cases bustage: > 0:17.14 xpidl.IDLError: error: [infallible] attributes are only allowed on [builtinclass] interfaces, ../../../dist/idl\nsIEditor.idl line 557:24 > 0:17.14 [infallible] readonly attribute boolean isInEditAction; Should I make nsIEditor as [builtinclass]? (I don't know the meaning of [buildinclass].)
Flags: needinfo?(bugs)
Comment 12•10 years ago
|
||
Oh, nsIEditor should be builtinclass. That means C++ only implementations.
Flags: needinfo?(bugs)
Assignee | ||
Comment 13•10 years ago
|
||
Comment on attachment 8474481 [details] [diff] [review] Implement nsIEditor.isInEditAction readonly attribute Thanks. I'll post a new patch.
Attachment #8474481 -
Flags: review?(ehsan)
Assignee | ||
Comment 14•10 years ago
|
||
I forgot to update uuid of nsIEditor derived classes (nsIPlaintextEditor and nIHTMLEditor).
Attachment #8474481 -
Attachment is obsolete: true
Attachment #8474879 -
Flags: superreview?(bugs)
Attachment #8474879 -
Flags: review?(ehsan)
Comment 15•10 years ago
|
||
Comment on attachment 8474879 [details] [diff] [review] Implement nsIEditor.isInEditAction readonly attribute Review of attachment 8474879 [details] [diff] [review]: ----------------------------------------------------------------- ::: editor/libeditor/nsEditor.cpp @@ +5341,5 @@ > +nsEditor::GetIsInEditAction(bool* aIsInEditAction) > +{ > + if (NS_WARN_IF(!aIsInEditAction)) { > + return NS_ERROR_INVALID_ARG; > + } Once you've marked this as [noscript] you can drop this check, since then only our internal code can call this function. ::: editor/nsIEditor.idl @@ +554,5 @@ > + * True if an edit action is being handled (in other words, between calls of > + * nsIEditorObserver::BeforeEditAction() and nsIEditorObserver::EditAction() > + * or nsIEditorObserver::CancelEditAction(). Otherwise, false. > + */ > + [infallible] readonly attribute boolean isInEditAction; Please mark this [noscript] as well.
Attachment #8474879 -
Flags: review?(ehsan) → review+
Assignee | ||
Comment 16•10 years ago
|
||
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #15) > Comment on attachment 8474879 [details] [diff] [review] > Implement nsIEditor.isInEditAction readonly attribute > > Review of attachment 8474879 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: editor/libeditor/nsEditor.cpp > @@ +5341,5 @@ > > +nsEditor::GetIsInEditAction(bool* aIsInEditAction) > > +{ > > + if (NS_WARN_IF(!aIsInEditAction)) { > > + return NS_ERROR_INVALID_ARG; > > + } > > Once you've marked this as [noscript] you can drop this check, since then > only our internal code can call this function. Sounds strange. Isn't this check needed for invalid C++ call? > ::: editor/nsIEditor.idl > @@ +554,5 @@ > > + * True if an edit action is being handled (in other words, between calls of > > + * nsIEditorObserver::BeforeEditAction() and nsIEditorObserver::EditAction() > > + * or nsIEditorObserver::CancelEditAction(). Otherwise, false. > > + */ > > + [infallible] readonly attribute boolean isInEditAction; > > Please mark this [noscript] as well. Hmm, I think that this may be useful attribute for some addons, dom/inputmetnods (B2G IME) and Gaia. Do you really think that this should be noscript?
Flags: needinfo?(ehsan)
Comment 17•10 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #16) > (In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from > comment #15) > > Comment on attachment 8474879 [details] [diff] [review] > > Implement nsIEditor.isInEditAction readonly attribute > > > > Review of attachment 8474879 [details] [diff] [review]: > > ----------------------------------------------------------------- > > > > ::: editor/libeditor/nsEditor.cpp > > @@ +5341,5 @@ > > > +nsEditor::GetIsInEditAction(bool* aIsInEditAction) > > > +{ > > > + if (NS_WARN_IF(!aIsInEditAction)) { > > > + return NS_ERROR_INVALID_ARG; > > > + } > > > > Once you've marked this as [noscript] you can drop this check, since then > > only our internal code can call this function. > > Sounds strange. Isn't this check needed for invalid C++ call? Well, invalid C++ doing this will just crash, which we will hopefully catch during testing. :-) But if you feel uncomfortable feel free to ignore that part of my comment, I don't feel very strongly about it. > > ::: editor/nsIEditor.idl > > @@ +554,5 @@ > > > + * True if an edit action is being handled (in other words, between calls of > > > + * nsIEditorObserver::BeforeEditAction() and nsIEditorObserver::EditAction() > > > + * or nsIEditorObserver::CancelEditAction(). Otherwise, false. > > > + */ > > > + [infallible] readonly attribute boolean isInEditAction; > > > > Please mark this [noscript] as well. > > Hmm, I think that this may be useful attribute for some addons, > dom/inputmetnods (B2G IME) and Gaia. Do you really think that this should be > noscript? Yes. Any add-on which relies on this is relying on our implementation detail. Also, I really think we should not expose more scriptable editor APIs unless there is a great reason to do so.
Flags: needinfo?(ehsan)
Assignee | ||
Comment 18•10 years ago
|
||
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #17) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #16) > > (In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from > > comment #15) > > > Comment on attachment 8474879 [details] [diff] [review] > > > Implement nsIEditor.isInEditAction readonly attribute > > > > > > Review of attachment 8474879 [details] [diff] [review]: > > > ----------------------------------------------------------------- > > > > > > ::: editor/libeditor/nsEditor.cpp > > > @@ +5341,5 @@ > > > > +nsEditor::GetIsInEditAction(bool* aIsInEditAction) > > > > +{ > > > > + if (NS_WARN_IF(!aIsInEditAction)) { > > > > + return NS_ERROR_INVALID_ARG; > > > > + } > > > > > > Once you've marked this as [noscript] you can drop this check, since then > > > only our internal code can call this function. > > > > Sounds strange. Isn't this check needed for invalid C++ call? > > Well, invalid C++ doing this will just crash, which we will hopefully catch > during testing. :-) But if you feel uncomfortable feel free to ignore that > part of my comment, I don't feel very strongly about it. Okay, then, I'll use MOZ_ASSERT(). > > > ::: editor/nsIEditor.idl > > > @@ +554,5 @@ > > > > + * True if an edit action is being handled (in other words, between calls of > > > > + * nsIEditorObserver::BeforeEditAction() and nsIEditorObserver::EditAction() > > > > + * or nsIEditorObserver::CancelEditAction(). Otherwise, false. > > > > + */ > > > > + [infallible] readonly attribute boolean isInEditAction; > > > > > > Please mark this [noscript] as well. > > > > Hmm, I think that this may be useful attribute for some addons, > > dom/inputmetnods (B2G IME) and Gaia. Do you really think that this should be > > noscript? > > Yes. Any add-on which relies on this is relying on our implementation > detail. Also, I really think we should not expose more scriptable editor > APIs unless there is a great reason to do so. Okay.
Assignee | ||
Comment 19•10 years ago
|
||
Attachment #8474879 -
Attachment is obsolete: true
Attachment #8474879 -
Flags: superreview?(bugs)
Attachment #8474911 -
Flags: superreview?(bugs)
Comment 20•10 years ago
|
||
BTW: thanks for figuring this bug out! :)
Assignee | ||
Comment 21•10 years ago
|
||
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #20) > BTW: thanks for figuring this bug out! :) You're welcome ;-) This makes TSF confused due to the different result from the text and selection change notification.
Updated•10 years ago
|
Attachment #8474911 -
Flags: superreview?(bugs) → superreview+
Assignee | ||
Comment 22•10 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/77bf46f52906 https://hg.mozilla.org/integration/mozilla-inbound/rev/99f640f31359 https://hg.mozilla.org/integration/mozilla-inbound/rev/e8101d5f9def
Comment 23•10 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/e8101d5f9def https://hg.mozilla.org/mozilla-central/rev/99f640f31359 https://hg.mozilla.org/mozilla-central/rev/77bf46f52906
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla34
Comment 24•10 years ago
|
||
There have been some comments on the tb-planning list concerning the change making nsIEditor [builtinclass]. I don't really know if that is a good idea or not, but because this has some major impact on certain Thunderbird addons, we deserve more discussion of rationale beyond "Should I make nsIEditor as [builtinclass]? (I don't know the meaning of [buildinclass]) ... Oh, nsIEditor should be builtinclass." Yes, I know, you'll ask "What are your use cases?" But the whole point of extendable code is that it allows people to do use cases that were not considered when the original code was written. It seems to me that the onus is on the person who removes a capability that others have relied on to justify the change. Again, I am not saying it is a good or bad idea, I just would like for addon authors to understand what problem is being solved that justifies the pain they are being caused. Hopefully the discussion will be open-minded enough that the option of backing out the change would also be considered seriously.
Assignee | ||
Comment 25•10 years ago
|
||
rkent: See comment 12. buldinclass meants it's only implemented by C++. Anyway, it's almost impossible to implement editor with JS. So, there must be no use case.
Comment 26•10 years ago
|
||
:masayuki "buildinclass meants it's only implemented by C++" is a definition of what that does, not an explanation of why it is needed in this case. "Anyway, it's almost impossible to implement editor with JS. So, there must be no use case." Now that you know that one of the most important Thunderbird extensions, written by an official Mozilla Mailnews peer, has a use case, I would think you would start to question your assumption "there must be no use case". "it's almost impossible to implement (an interface) with JS" still permits the use where a js front end to a C++ implementation is written. Obviously there is a use case or we would not be complaining. All that I am asking for is that you state the reasons why this change had to be made, and be open minded about possibly reverting that change if that reason turns out to be unnecessary. I don't think that is too much to ask.
Assignee | ||
Comment 27•10 years ago
|
||
rkent: It's possible to revert the change. If you think the actual regression by it, please file a bug. Here is not a good place for discussing it.
Assignee | ||
Comment 28•10 years ago
|
||
> If you think the actual regression by it,
If you know... I meant.
Comment 29•10 years ago
|
||
nsIEditor implemented in JS? That is very surprising to me, and obviously didn't know that when reviewing. We can revert the change pretty easily though. Just tiny bit uglier C++ code, but that is fine. Masayuki, do you think you could make the change. And add a comment to nsIEditor that there are actually addons implementing it in JS. rkent, thanks for bringing this up.
Comment 30•10 years ago
|
||
Or I can make the change too.
Comment 31•10 years ago
|
||
Thanks.
You need to log in
before you can comment on or make changes to this bug.
Description
•