Bug 639695 - Reconnect the HTML editor to the new presentation of a contenteditable document when it changes; r=roc

This fixes things such as the caret not showing up after the presshell for a
document containing a contenteditable element is recreated.
This commit is contained in:
Ehsan Akhgari 2011-03-11 18:45:20 -05:00
parent c06813a2c5
commit b528286d7e
5 changed files with 68 additions and 17 deletions

View File

@ -854,6 +854,20 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
doc->SetDesignMode(NS_LITERAL_STRING("off"));
doc->SetDesignMode(NS_LITERAL_STRING("on"));
} else {
// Re-initialie the presentation for contenteditable documents
nsCOMPtr<nsIEditorDocShell> editorDocshell = do_QueryInterface(mDocShell);
if (editorDocshell) {
PRBool editable = PR_FALSE,
hasEditingSession = PR_FALSE;
editorDocshell->GetEditable(&editable);
editorDocshell->GetHasEditingSession(&hasEditingSession);
nsCOMPtr<nsIEditor> editor;
editorDocshell->GetEditor(getter_AddRefs(editor));
if (editable && hasEditingSession && editor) {
editor->PostCreate();
}
}
}
}
}

View File

@ -158,6 +158,7 @@ nsEditor::nsEditor()
, mIsIMEComposing(PR_FALSE)
, mShouldTxnSetSelection(PR_TRUE)
, mDidPreDestroy(PR_FALSE)
, mDidPostCreate(PR_FALSE)
, mDocDirtyState(-1)
, mDocWeak(nsnull)
, mPhonetic(nsnull)
@ -275,6 +276,8 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIContent *aRoot, nsISelectionController *
// Make sure that the editor will be destroyed properly
mDidPreDestroy = PR_FALSE;
// Make sure that the ediotr will be created properly
mDidPostCreate = PR_FALSE;
return NS_OK;
}
@ -291,26 +294,31 @@ nsEditor::PostCreate()
nsresult rv = SetFlags(~mFlags);
NS_ENSURE_SUCCESS(rv, rv);
// Set up listeners
rv = CreateEventListeners();
if (NS_FAILED(rv))
{
RemoveEventListeners();
// These operations only need to happen on the first PostCreate call
if (!mDidPostCreate) {
mDidPostCreate = PR_TRUE;
return rv;
// Set up listeners
rv = CreateEventListeners();
if (NS_FAILED(rv))
{
RemoveEventListeners();
return rv;
}
rv = InstallEventListeners();
NS_ENSURE_SUCCESS(rv, rv);
// nuke the modification count, so the doc appears unmodified
// do this before we notify listeners
ResetModificationCount();
// update the UI with our state
NotifyDocumentListeners(eDocumentCreated);
NotifyDocumentListeners(eDocumentStateChanged);
}
rv = InstallEventListeners();
NS_ENSURE_SUCCESS(rv, rv);
// nuke the modification count, so the doc appears unmodified
// do this before we notify listeners
ResetModificationCount();
// update the UI with our state
NotifyDocumentListeners(eDocumentCreated);
NotifyDocumentListeners(eDocumentStateChanged);
// update nsTextStateManager and caret if we have focus
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
if (focusedContent) {

View File

@ -759,6 +759,7 @@ protected:
PRPackedBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
PRPackedBool mDidPreDestroy; // whether PreDestroy has been called
PRPackedBool mDidPostCreate; // whether PostCreate has been called
// various listeners
nsCOMArray<nsIEditActionListener> mActionListeners; // listens to all low level actions on the doc
nsCOMArray<nsIEditorObserver> mEditorObservers; // just notify once per high level change

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html class="reftest-wait">
<body>
<iframe src="data:text/html,<body><div></div></body>"></iframe>
<script type="text/javascript">
onload = function() {
var i = document.querySelector("iframe");
var win = i.contentWindow;
var doc = win.document;
var div = doc.querySelector("div");
win.getSelection().collapse(div, 0);
i.focus();
div.contentEditable = true;
div.focus();
setTimeout(function() {
var span = doc.createElement("span");
span.appendChild(doc.createTextNode("foo"));
div.appendChild(span);
div.style.outlineWidth = 0; // remove the focus outline
i.style.position = "absolute";
document.body.clientWidth;
document.documentElement.removeAttribute("class");
}, 0);
};
</script>
</body>
</html>

View File

@ -58,3 +58,4 @@ fails-if(Android) != spellcheck-hyphen-multiple-invalid.html spellcheck-hyphen-m
== spellcheck-dotafterquote-valid.html spellcheck-dotafterquote-valid-ref.html
== unneeded_scroll.html unneeded_scroll-ref.html
== caret_on_presshell_reinit.html caret_on_presshell_reinit-ref.html
== caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html