Bug 674770 part.1 Shouldn't accept click event if the event target isn't in focused editor r=ehsan

This commit is contained in:
Masayuki Nakano 2011-11-26 13:51:48 +09:00
parent 311812671e
commit 3d287e297d
3 changed files with 66 additions and 7 deletions

View File

@ -5387,12 +5387,29 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
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();

View File

@ -179,6 +179,11 @@ nsEditorEventListener::InstallToEditor()
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);
@ -514,14 +519,16 @@ 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) {

View File

@ -5990,10 +5990,45 @@ nsHTMLEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
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;