Bug 542317 - Caret missing when an iframe is put into design mode when it already has focus; r=roc a=blocking-final+

This commit is contained in:
Ehsan Akhgari 2010-10-29 12:30:52 -04:00
parent 94296c5dc6
commit 03166cf845
7 changed files with 40 additions and 35 deletions

View File

@ -312,23 +312,18 @@ nsEditor::PostCreate()
NotifyDocumentListeners(eDocumentStateChanged);
// update nsTextStateManager and caret if we have focus
if (HasFocus()) {
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ASSERTION(fm, "no focus manager?");
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
if (focusedContent) {
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
NS_ASSERTION(ps, "no pres shell even though we have focus");
nsPresContext* pc = ps->GetPresContext();
nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
if (focusedContent) {
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
NS_ASSERTION(ps, "no pres shell even though we have focus");
nsPresContext* pc = ps->GetPresContext();
nsIMEStateManager::OnTextStateBlur(pc, nsnull);
nsIMEStateManager::OnTextStateFocus(pc, focusedContent);
nsIMEStateManager::OnTextStateBlur(pc, nsnull);
nsIMEStateManager::OnTextStateFocus(pc, focusedContent);
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(focusedContent);
if (target) {
InitializeSelection(target);
}
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(focusedContent);
if (target) {
InitializeSelection(target);
}
}
return NS_OK;
@ -489,7 +484,8 @@ nsEditor::SetFlags(PRUint32 aFlags)
// Might be changing editable state, so, we need to reset current IME state
// if we're focused and the flag change causes IME state change.
if (HasFocus()) {
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
if (focusedContent) {
// Use "enable" for the default value because if IME is disabled
// unexpectedly, it makes serious a11y problem.
PRUint32 newState = nsIContent::IME_STATUS_ENABLE;
@ -5260,19 +5256,19 @@ nsEditor::GetNativeKeyEvent(nsIDOMKeyEvent* aDOMKeyEvent)
return static_cast<nsKeyEvent*>(nativeEvent);
}
PRBool
nsEditor::HasFocus()
already_AddRefed<nsIContent>
nsEditor::GetFocusedContent()
{
nsCOMPtr<nsPIDOMEventTarget> piTarget = GetPIDOMEventTarget();
if (!piTarget) {
return PR_FALSE;
return nsnull;
}
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ENSURE_TRUE(fm, PR_FALSE);
NS_ENSURE_TRUE(fm, nsnull);
nsCOMPtr<nsIContent> content = fm->GetFocusedContent();
return SameCOMIdentity(content, piTarget);
return SameCOMIdentity(content, piTarget) ? content.forget() : nsnull;
}
PRBool

View File

@ -666,11 +666,11 @@ public:
IsInteractionAllowed();
}
// Whether the editor has application level focus or not.
virtual PRBool HasFocus();
// Get the focused content, if we're focused. Returns null otherwise.
virtual already_AddRefed<nsIContent> GetFocusedContent();
// Whether the editor is active on the DOM window. Note that when this
// returns true but HasFocus() returns false, it means that this editor was
// returns true but GetFocusedContent() returns null, it means that this editor was
// focused when the DOM window was active.
virtual PRBool IsActiveInDOMWindow();

View File

@ -5763,13 +5763,13 @@ nsHTMLEditor::GetReturnInParagraphCreatesNewParagraph(PRBool *aCreatesNewParagra
return NS_OK;
}
PRBool
nsHTMLEditor::HasFocus()
already_AddRefed<nsIContent>
nsHTMLEditor::GetFocusedContent()
{
NS_ENSURE_TRUE(mDocWeak, PR_FALSE);
NS_ENSURE_TRUE(mDocWeak, nsnull);
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ENSURE_TRUE(fm, PR_FALSE);
NS_ENSURE_TRUE(fm, nsnull);
nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
@ -5777,12 +5777,17 @@ nsHTMLEditor::HasFocus()
PRBool inDesignMode = doc->HasFlag(NODE_IS_EDITABLE);
if (!focusedContent) {
// in designMode, nobody gets focus in most cases.
return inDesignMode ? OurWindowHasFocus() : PR_FALSE;
if (inDesignMode && OurWindowHasFocus()) {
nsCOMPtr<nsIContent> docRoot = doc->GetRootElement();
return docRoot.forget();
}
return nsnull;
}
if (inDesignMode) {
return OurWindowHasFocus() ?
nsContentUtils::ContentIsDescendantOf(focusedContent, doc) : PR_FALSE;
return OurWindowHasFocus() &&
nsContentUtils::ContentIsDescendantOf(focusedContent, doc) ?
focusedContent.forget() : nsnull;
}
// We're HTML editor for contenteditable
@ -5791,10 +5796,10 @@ nsHTMLEditor::HasFocus()
// we don't have focus.
if (!focusedContent->HasFlag(NODE_IS_EDITABLE) ||
focusedContent->HasIndependentSelection()) {
return PR_FALSE;
return nsnull;
}
// If our window is focused, we're focused.
return OurWindowHasFocus();
return OurWindowHasFocus() ? focusedContent.forget() : nsnull;
}
PRBool
@ -5907,7 +5912,8 @@ nsHTMLEditor::GetBodyElement(nsIDOMHTMLElement** aBody)
already_AddRefed<nsINode>
nsHTMLEditor::GetFocusedNode()
{
if (!HasFocus()) {
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
if (!focusedContent) {
return nsnull;
}

View File

@ -148,7 +148,7 @@ public:
NS_IMETHOD GetIsDocumentEditable(PRBool *aIsDocumentEditable);
NS_IMETHODIMP BeginningOfDocument();
virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
virtual PRBool HasFocus();
virtual already_AddRefed<nsIContent> GetFocusedContent();
virtual PRBool IsActiveInDOMWindow();
virtual already_AddRefed<nsPIDOMEventTarget> GetPIDOMEventTarget();
virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);

View File

@ -0,0 +1 @@
<body onload="frames[0].document.designMode = 'on'; frames[0].focus()"><iframe></iframe></body>

View File

@ -0,0 +1 @@
<body onload="frames[0].focus(); frames[0].document.designMode = 'on'"><iframe></iframe></body>

View File

@ -1426,6 +1426,7 @@ asserts(5) == 528038-2.html 528038-2-ref.html # bug 512749
== 539880-1-dynamic.html 539880-1-ref.html
== 541382-1.html 541382-1-ref.html
random-if(!haveTestPlugin) == 541406-1.html 541406-1-ref.html
== 542317-1.html 542317-1-ref.html
== 542605-hidden-unscrollable.xul 542605-hidden-unscrollable-ref.xul
== 542620-1.html 542620-1-ref.html
== 545049-1.html 545049-1-ref.html