author | Masayuki Nakano <masayuki@d-toybox.com> |
Sat, 26 Nov 2011 13:51:48 +0900 | |
changeset 82441 | dad793c1b1437c83315fda28289228767a0a7a92 |
parent 82440 | 5c6903c68234a2a290861eaa9cf921989281d2bf |
child 82442 | 1a9cc49f9cf1276defa2726c8849d1d83c1780d5 |
push id | 519 |
push user | akeybl@mozilla.com |
push date | Wed, 01 Feb 2012 00:38:35 +0000 |
treeherder | mozilla-beta@788ea1ef610b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | ehsan |
bugs | 674770 |
milestone | 11.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -5382,22 +5382,39 @@ nsEditor::IsActiveInDOMWindow() bool nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent) { // If the event is trusted, the event should always cause input. nsCOMPtr<nsIDOMNSEvent> NSEvent = do_QueryInterface(aEvent); NS_ENSURE_TRUE(NSEvent, false); + // If this is mouse event but this editor doesn't have focus, we shouldn't + // handle it. + nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent); + if (mouseEvent) { + nsCOMPtr<nsIContent> focusedContent = GetFocusedContent(); + if (!focusedContent) { + return false; + } + } + bool isTrusted; nsresult rv = NSEvent->GetIsTrusted(&isTrusted); NS_ENSURE_SUCCESS(rv, false); if (isTrusted) { return true; } + + // Ignore untrusted mouse event. + // XXX Why are we handling other untrusted input events? + if (mouseEvent) { + return false; + } + // Otherwise, we shouldn't handle any input events when we're not an active // element of the DOM window. return IsActiveInDOMWindow(); } NS_IMETHODIMP nsEditor::GetLastKeypressEventTrusted(bool *aWasTrusted) {
--- a/editor/libeditor/base/nsEditorEventListener.cpp +++ b/editor/libeditor/base/nsEditorEventListener.cpp @@ -174,16 +174,21 @@ nsEditorEventListener::InstallToEditor() elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragexit"), NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_SYSTEM_EVENT); elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"), NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_SYSTEM_EVENT); + // XXX We should add the mouse event listeners as system event group. + // E.g., web applications cannot prevent middle mouse paste by + // preventDefault() of click event at bubble phase. + // However, if we do so, all click handlers in any frames and frontend + // code need to check if it's editable. It makes easier create new bugs. elmP->AddEventListenerByType(this, NS_LITERAL_STRING("mousedown"), NS_EVENT_FLAG_CAPTURE); elmP->AddEventListenerByType(this, NS_LITERAL_STRING("mouseup"), NS_EVENT_FLAG_CAPTURE); elmP->AddEventListenerByType(this, NS_LITERAL_STRING("click"), @@ -509,24 +514,26 @@ nsEditorEventListener::KeyPress(nsIDOMEv } NS_IMETHODIMP nsEditorEventListener::MouseClick(nsIDOMEvent* aMouseEvent) { NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_AVAILABLE); nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent); - nsCOMPtr<nsIDOMNSEvent> nsevent = do_QueryInterface(aMouseEvent); - bool isTrusted = false; - if (!mouseEvent || !nsevent || - NS_FAILED(nsevent->GetIsTrusted(&isTrusted)) || !isTrusted) { - // Non-ui or non-trusted event passed in. Bad things. + NS_ENSURE_TRUE(mouseEvent, NS_OK); + + // nothing to do if editor isn't editable or clicked on out of the editor. + if (mEditor->IsReadonly() || mEditor->IsDisabled() || + !mEditor->IsAcceptableInputEvent(aMouseEvent)) { return NS_OK; } + nsCOMPtr<nsIDOMNSEvent> nsevent = do_QueryInterface(aMouseEvent); + NS_ASSERTION(nsevent, "nsevent must not be NULL here"); bool preventDefault; nsresult rv = nsevent->GetPreventDefault(&preventDefault); if (NS_FAILED(rv) || preventDefault) { // We're done if 'preventdefault' is true (see for example bug 70698). return rv; } // If we got a mouse down inside the editing area, we should force the
--- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -5985,20 +5985,55 @@ nsHTMLEditor::IsAcceptableInputEvent(nsI return targetDocument == document; } // Otherwise, check whether the event target is in this document or not. nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target); NS_ENSURE_TRUE(targetContent, false); return document == targetContent->GetCurrentDoc(); } - // If this is for contenteditable, we should check whether the target is - // editable or not. + // This HTML editor is for contenteditable. We need to check the validity of + // the target. nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target); NS_ENSURE_TRUE(targetContent, false); + + // If the event is a mouse event, we need to check if the target content is + // the focused editing host or its descendant. + nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent); + if (mouseEvent) { + nsIContent* editingHost = GetActiveEditingHost(); + // If there is no active editing host, we cannot handle the mouse event + // correctly. + if (!editingHost) { + return false; + } + // If clicked on non-editable root element but the body element is the + // active editing host, we should assume that the click event is targetted. + if (targetContent == document->GetRootElement() && + !targetContent->HasFlag(NODE_IS_EDITABLE) && + editingHost == document->GetBodyElement()) { + targetContent = editingHost; + } + // If the target element is neither the active editing host nor a descendant + // of it, we may not be able to handle the event. + if (!nsContentUtils::ContentIsDescendantOf(targetContent, editingHost)) { + return false; + } + // If the clicked element has an independent selection, we shouldn't + // handle this click event. + if (targetContent->HasIndependentSelection()) { + return false; + } + // If the target content is editable, we should handle this event. + return targetContent->HasFlag(NODE_IS_EDITABLE); + } + + // If the target of the other events which target focused element isn't + // editable or has an independent selection, this editor shouldn't handle the + // event. if (!targetContent->HasFlag(NODE_IS_EDITABLE) || targetContent->HasIndependentSelection()) { return false; } // Finally, check whether we're actually focused or not. When we're not // focused, we should ignore the dispatched event by script (or something) // because content editable element needs selection in itself for editing.