Fix for bug 406596 (Link/anchor elements are focused within an contentEditable element). r/sr=jst, a=beltzner.

This commit is contained in:
peterv@propagandism.org 2008-04-15 11:40:38 -07:00
Родитель f2fddd2288
Коммит c37d1b0f6f
16 изменённых файлов: 264 добавлений и 61 удалений

Просмотреть файл

@ -3520,6 +3520,13 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
GetDocSelectionLocation(getter_AddRefs(selectionContent), getter_AddRefs(endSelectionContent), &selectionFrame, &selectionOffset);
if (selectionContent == rootContent) // If selection on rootContent, same as null -- we have no selection yet
selectionFrame = nsnull;
// Don't start from the selection if the selection is in a contentEditable
// region.
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (htmlDoc &&
htmlDoc->GetEditingState() == nsIHTMLDocument::eContentEditable &&
selectionContent && selectionContent->HasFlag(NODE_IS_EDITABLE))
selectionFrame = nsnull;
// Only use tabindex if selection is synchronized with focus
// That way, if the user clicks in content, or does a find text that lands between focusable elements,
// they can then tab relative to that selection

Просмотреть файл

@ -2589,10 +2589,11 @@ nsGenericHTMLFormElement::GetDesiredIMEState()
}
PRBool
nsGenericHTMLFrameElement::IsFocusable(PRInt32 *aTabIndex)
nsGenericHTMLFrameElement::IsHTMLFocusable(PRBool *aIsFocusable,
PRInt32 *aTabIndex)
{
if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
return PR_FALSE;
if (nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
// If there is no subdocument, docshell or content viewer, it's not tabbable
@ -2623,11 +2624,12 @@ nsGenericHTMLFrameElement::IsFocusable(PRInt32 *aTabIndex)
}
}
*aIsFocusable = isFocusable;
if (!isFocusable && aTabIndex) {
*aTabIndex = -1;
}
return isFocusable;
return PR_FALSE;
}
nsresult
@ -3121,7 +3123,7 @@ nsGenericHTMLElement::RemoveFocus(nsPresContext *aPresContext)
}
PRBool
nsGenericHTMLElement::IsFocusable(PRInt32 *aTabIndex)
nsGenericHTMLElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
nsIDocument *doc = GetCurrentDoc();
if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) {
@ -3130,14 +3132,19 @@ nsGenericHTMLElement::IsFocusable(PRInt32 *aTabIndex)
*aTabIndex = -1;
}
return PR_FALSE;
*aIsFocusable = PR_FALSE;
return PR_TRUE;
}
PRInt32 tabIndex = 0; // Default value for non HTML elements with -moz-user-focus
GetTabIndex(&tabIndex);
PRBool disabled;
PRBool override, disabled;
if (IsEditableRoot()) {
// Editable roots should always be focusable.
override = PR_TRUE;
// Ignore the disabled attribute in editable contentEditable/designMode
// roots.
disabled = PR_FALSE;
@ -3148,6 +3155,8 @@ nsGenericHTMLElement::IsFocusable(PRInt32 *aTabIndex)
}
}
else {
override = PR_FALSE;
// Just check for disabled attribute on all HTML elements
disabled = HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
if (disabled) {
@ -3160,7 +3169,10 @@ nsGenericHTMLElement::IsFocusable(PRInt32 *aTabIndex)
}
// If a tabindex is specified at all, or the default tabindex is 0, we're focusable
return tabIndex >= 0 || (!disabled && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex));
*aIsFocusable = tabIndex >= 0 ||
(!disabled && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex));
return override;
}
void

Просмотреть файл

@ -212,7 +212,17 @@ public:
PRBool aNotify);
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
virtual void RemoveFocus(nsPresContext *aPresContext);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull)
{
PRBool isFocusable;
IsHTMLFocusable(&isFocusable, aTabIndex);
return isFocusable;
}
/**
* Returns PR_TRUE if a subclass is not allowed to override the value returned
* in aIsFocusable.
*/
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
PRBool aIsTrustedEvent);
@ -909,7 +919,7 @@ public:
NS_DECL_NSIFRAMELOADEROWNER
// nsIContent
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);

Просмотреть файл

@ -109,7 +109,7 @@ public:
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual void SetFocus(nsPresContext* aPresContext);
virtual PRBool IsFocusable(PRBool *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
@ -250,10 +250,20 @@ nsHTMLAnchorElement::SetFocus(nsPresContext* aPresContext)
}
PRBool
nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLAnchorElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
return PR_FALSE;
if (nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
if (IsEditable()) {
if (aTabIndex) {
*aTabIndex = -1;
}
*aIsFocusable = PR_FALSE;
return PR_TRUE;
}
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
@ -265,6 +275,9 @@ nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
if (aTabIndex) {
*aTabIndex = -1;
}
*aIsFocusable = PR_FALSE;
return PR_FALSE;
}
}
@ -273,7 +286,9 @@ nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
*aTabIndex = -1;
}
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
nsresult

Просмотреть файл

@ -111,7 +111,7 @@ public:
// nsIContent overrides...
virtual void SetFocus(nsPresContext* aPresContext);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
@ -244,15 +244,18 @@ nsHTMLButtonElement::Click()
}
PRBool
nsHTMLButtonElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLButtonElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
return PR_FALSE;
if (nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
if (aTabIndex && (sTabFocusModel & eTabFocus_formElementsMask) == 0) {
*aTabIndex = -1;
}
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
void

Просмотреть файл

@ -123,7 +123,7 @@ public:
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
// SetAttr override. C++ is stupid, so have to override both
// overloaded methods.
@ -435,7 +435,7 @@ nsHTMLImageElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
}
PRBool
nsHTMLImageElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLImageElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
PRInt32 tabIndex;
GetTabIndex(&tabIndex);
@ -455,7 +455,7 @@ nsHTMLImageElement::IsFocusable(PRInt32 *aTabIndex)
}
// Image map is not focusable itself, but flag as tabbable
// so that image map areas get walked into.
return PR_FALSE;
*aIsFocusable = PR_FALSE;
}
}
@ -464,7 +464,10 @@ nsHTMLImageElement::IsFocusable(PRInt32 *aTabIndex)
*aTabIndex = (sTabFocusModel & eTabFocus_formElementsMask)? tabIndex : -1;
}
return tabIndex >= 0 || HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex);
*aIsFocusable = tabIndex >= 0 ||
HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex);
return PR_FALSE;
}
nsresult

Просмотреть файл

@ -198,7 +198,7 @@ public:
// nsIContent
virtual void SetFocus(nsPresContext* aPresContext);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
@ -2902,14 +2902,15 @@ nsHTMLInputElement::WillRemoveFromRadioGroup()
}
PRBool
nsHTMLInputElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLInputElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
return PR_FALSE;
if (nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) {
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
if (mType == NS_FORM_INPUT_HIDDEN || mType == NS_FORM_INPUT_FILE) {
@ -2917,12 +2918,14 @@ nsHTMLInputElement::IsFocusable(PRInt32 *aTabIndex)
if (aTabIndex) {
*aTabIndex = -1;
}
*aIsFocusable = PR_FALSE;
return PR_FALSE;
}
if (!aTabIndex) {
// The other controls are all focusable
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
// We need to set tabindex to -1 if we're not tabbable
@ -2932,14 +2935,16 @@ nsHTMLInputElement::IsFocusable(PRInt32 *aTabIndex)
}
if (mType != NS_FORM_INPUT_RADIO) {
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
PRBool checked;
GetChecked(&checked);
if (checked) {
// Selected radio buttons are tabbable
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
// Current radio button is not selected.
@ -2947,7 +2952,8 @@ nsHTMLInputElement::IsFocusable(PRInt32 *aTabIndex)
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsAutoString name;
if (!container || !GetNameIfExists(name)) {
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
@ -2955,7 +2961,8 @@ nsHTMLInputElement::IsFocusable(PRInt32 *aTabIndex)
if (currentRadio) {
*aTabIndex = -1;
}
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
nsresult

Просмотреть файл

@ -80,7 +80,7 @@ public:
nsIAtom *aPrefix, const nsAString &aValue,
PRBool aNotify);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual PRUint32 GetDesiredIMEState();
// Overriden nsIFormControl methods
@ -247,7 +247,7 @@ nsHTMLObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
}
PRBool
nsHTMLObjectElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLObjectElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (Type() == eType_Plugin) {
// Has plugin content: let the plugin decide what to do in terms of
@ -256,10 +256,12 @@ nsHTMLObjectElement::IsFocusable(PRInt32 *aTabIndex)
GetTabIndex(aTabIndex);
}
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
return nsGenericHTMLFormElement::IsFocusable(aTabIndex);
return nsGenericHTMLFormElement::IsHTMLFocusable(aIsFocusable, aTabIndex);
}
PRUint32

Просмотреть файл

@ -1265,15 +1265,16 @@ nsHTMLSelectElement::SetFocus(nsPresContext* aPresContext)
}
PRBool
nsHTMLSelectElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLSelectElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
return PR_FALSE;
if (nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
if (aTabIndex && (sTabFocusModel & eTabFocus_formElementsMask) == 0) {
*aTabIndex = -1;
}
return PR_TRUE;
*aIsFocusable = PR_TRUE;
return PR_FALSE;
}
NS_IMETHODIMP

Просмотреть файл

@ -257,7 +257,7 @@ public:
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual void SetFocus(nsPresContext* aPresContext);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);

Просмотреть файл

@ -109,7 +109,7 @@ public:
NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual PRUint32 GetDesiredIMEState();
virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
@ -292,7 +292,8 @@ nsHTMLSharedObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
}
PRBool
nsHTMLSharedObjectElement::IsFocusable(PRInt32 *aTabIndex)
nsHTMLSharedObjectElement::IsHTMLFocusable(PRBool *aIsFocusable,
PRInt32 *aTabIndex)
{
if (mNodeInfo->Equals(nsGkAtoms::embed) || Type() == eType_Plugin) {
// Has plugin content: let the plugin decide what to do in terms of
@ -304,7 +305,7 @@ nsHTMLSharedObjectElement::IsFocusable(PRInt32 *aTabIndex)
return PR_TRUE;
}
return nsGenericHTMLElement::IsFocusable(aTabIndex);
return nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex);
}
PRUint32

Просмотреть файл

@ -109,6 +109,8 @@ _TEST_FILES = test_bug589.html \
test_bug408231.html \
test_bug417760.html \
file_bug417760.png \
test_bug406596.html \
test_bug421640.html \
$(NULL)
libs:: $(_TEST_FILES)

Просмотреть файл

@ -0,0 +1,86 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=406596
-->
<head>
<title>Test for Bug 406596</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=406596">Mozilla Bug 406596</a>
<div id="content">
<div id="edit" contenteditable="true">This text is editable, you can change its content <a href="#" id="a" tabindex="0">abcd</a> <input type="submit" value="abcd" id="b"></input> <img src="foo.png" id="c"></div>
<div tabindex="0">This text is not editable but is focusable</div>
<div tabindex="0">This text is not editable but is focusable</div>
<a href="#" id="d" contenteditable="true">abcd</a>
<div tabindex="0">This text is not editable but is focusable</div>
<div tabindex="0">This text is not editable but is focusable</div>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 406596 **/
function testTabbing(click, focus, selectionOffset) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var elem = document.getElementById(click);
var rect = elem.getBoundingClientRect();
var selection = window.getSelection();
wu.sendMouseEvent("mousedown", rect.left + 10, rect.top + 1, 0, 1, 0);
wu.sendMouseEvent("mousemove", rect.left + 10 + selectionOffset, rect.top + 1,
0, 1, 0);
wu.sendMouseEvent("mouseup", rect.left + 10 + selectionOffset, rect.top + 1,
0, 1, 0);
if (selectionOffset) {
is(selection.rangeCount, 1, "there should be one range in the selection");
var range = selection.getRangeAt(0);
}
var focusedElement = document.activeElement;
is(focusedElement, document.getElementById(focus),
"clicking should move focus to the contentEditable node");
synthesizeKey("VK_TAB", {});
synthesizeKey("VK_TAB", {});
synthesizeKey("VK_TAB", { shiftKey: true });
synthesizeKey("VK_TAB", { shiftKey: true });
is(document.activeElement, focusedElement,
"tab/shift-tab should move focus back to the contentEditable node");
if (selectionOffset) {
is(selection.rangeCount, 1,
"there should still be one range in the selection");
var newRange = selection.getRangeAt(0);
is(newRange.compareBoundaryPoints(Range.START_TO_START, range), 0,
"the selection should be the same as before the tabbing");
is(newRange.compareBoundaryPoints(Range.END_TO_END, range), 0,
"the selection should be the same as before the tabbing");
}
}
function test() {
window.getSelection().removeAllRanges();
testTabbing("edit", "edit", 0);
testTabbing("a", "edit", 0);
testTabbing("d", "d", 0);
testTabbing("edit", "edit", 10);
testTabbing("a", "edit", 10);
testTabbing("d", "d", 10);
SimpleTest.finish();
}
window.onload = function() {
SimpleTest.waitForExplicitFinish();
setTimeout(test, 0);
};
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=421640
-->
<head>
<title>Test for Bug 421640</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=421640">Mozilla Bug 421640</a>
<div id="content">
<div id="edit" contenteditable="true">This text is editable</div>
<div><button id="button">Test</button></div>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 421640 **/
function test(click, focus, nextFocus) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var selection = window.getSelection();
var edit = document.getElementById("edit");
var text = edit.firstChild;
selection.removeAllRanges();
var rect = edit.getBoundingClientRect();
wu.sendMouseEvent("mousedown", rect.left + 1, rect.top + 1, 0, 1, 0);
wu.sendMouseEvent("mousemove", rect.right - 1, rect.top + 1, 0, 1, 0);
wu.sendMouseEvent("mouseup", rect.right - 1, rect.top + 1, 0, 1, 0);
is(selection.anchorNode, text, "");
rect = document.getElementById("button").getBoundingClientRect();
wu.sendMouseEvent("mousedown", rect.left + 10, rect.top + 1, 0, 1, 0);
wu.sendMouseEvent("mouseup", rect.left + 10, rect.top + 1, 0, 1, 0);
is(selection.anchorNode, text, "");
SimpleTest.finish();
}
window.onload = function() {
SimpleTest.waitForExplicitFinish();
setTimeout(test, 0);
};
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -996,7 +996,8 @@ NS_IMPL_ISUPPORTS2(nsTextEditorFocusListener, nsIDOMEventListener, nsIDOMFocusLi
nsTextEditorFocusListener::nsTextEditorFocusListener(nsIEditor *aEditor,
nsIPresShell *aShell)
: mEditor(aEditor),
mPresShell(do_GetWeakReference(aShell))
mPresShell(do_GetWeakReference(aShell)),
mIsFocused(PR_FALSE)
{
}
@ -1108,6 +1109,8 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
if (!IsTargetFocused(target))
return NS_OK;
mIsFocused = PR_TRUE;
// turn on selection and caret
if (mEditor)
{
@ -1161,7 +1164,7 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
selectionPrivate->SetAncestorLimiter(editableRoot);
}
if (!editableRoot) {
if (selection && !editableRoot) {
PRInt32 rangeCount;
selection->GetRangeCount(&rangeCount);
if (rangeCount == 0) {
@ -1182,7 +1185,7 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
{
NS_ENSURE_ARG(aEvent);
// turn off selection and caret
if (mEditor)
if (mEditor && mIsFocused)
{
// when imeEditor exists, call ForceCompositionEnd() to tell
// the input focus is leaving first
@ -1209,18 +1212,6 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
}
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
nsCOMPtr<nsISelectionController> presSelCon =
do_QueryInterface(presShell);
if (presSelCon == selCon && selection) {
nsCOMPtr<nsIDOMEventTarget> target;
aEvent->GetTarget(getter_AddRefs(target));
nsCOMPtr<nsINode> node = do_QueryInterface(target);
nsIDocument* doc = node ? node->GetOwnerDoc() : nsnull;
if (doc && !doc->HasFlag(NODE_IS_EDITABLE)) {
selection->RemoveAllRanges();
}
}
if (presShell) {
nsCOMPtr<nsICaret> caret;
presShell->GetCaret(getter_AddRefs(caret));
@ -1250,6 +1241,9 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
}
}
}
mIsFocused = PR_FALSE;
return NS_OK;
}

Просмотреть файл

@ -264,6 +264,7 @@ public:
protected:
nsIEditor* mEditor; // weak reference
nsWeakPtr mPresShell;
PRBool mIsFocused;
};