Bug 824080 HTML editor shouldn't set selection state as inactive at losing focus but the document has focus r=ehsan

This commit is contained in:
Masayuki Nakano 2013-05-18 09:07:46 +09:00
parent 11be5b49cd
commit a54b2183fe
18 changed files with 371 additions and 39 deletions

View File

@ -4957,6 +4957,63 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
return NS_OK;
}
void
nsEditor::FinalizeSelection()
{
nsCOMPtr<nsISelectionController> selCon;
nsresult rv = GetSelectionController(getter_AddRefs(selCon));
NS_ENSURE_SUCCESS_VOID(rv);
nsCOMPtr<nsISelection> selection;
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selection));
NS_ENSURE_SUCCESS_VOID(rv);
nsCOMPtr<nsISelectionPrivate> selectionPrivate = do_QueryInterface(selection);
NS_ENSURE_TRUE_VOID(selectionPrivate);
selectionPrivate->SetAncestorLimiter(nullptr);
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE_VOID(presShell);
nsRefPtr<nsCaret> caret = presShell->GetCaret();
if (caret) {
caret->SetIgnoreUserModify(true);
}
selCon->SetCaretEnabled(false);
if (!HasIndependentSelection()) {
// If this editor doesn't have an independent selection, i.e., it must
// mean that it is an HTML editor, the selection controller is shared with
// presShell. So, even this editor loses focus, other part of the document
// may still have focus.
nsCOMPtr<nsIDocument> doc = GetDocument();
ErrorResult ret;
if (!doc || !doc->HasFocus(ret)) {
// If the document already lost focus, mark the selection as disabled.
selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
} else {
// Otherwise, mark selection as normal because outside of a
// contenteditable element should be selected with normal selection
// color after here.
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
}
} else if (IsFormWidget() || IsPasswordEditor() ||
IsReadonly() || IsDisabled() || IsInputFiltered()) {
// In <input> or <textarea>, the independent selection should be hidden
// while this editor doesn't have focus.
selCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
} else {
// Otherwise, although we're not sure how this case happens, the
// independent selection should be marked as disabled.
selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
}
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
}
dom::Element *
nsEditor::GetRoot()
{

View File

@ -740,6 +740,11 @@ public:
IsInteractionAllowed();
}
bool HasIndependentSelection() const
{
return !!mSelConWeak;
}
// Get the input event target. This might return null.
virtual already_AddRefed<nsIContent> GetInputEventTargetContent() = 0;
@ -773,6 +778,9 @@ public:
// nothing.
nsresult InitializeSelection(nsIDOMEventTarget* aFocusEventTarget);
// Finalizes selection and caret for the editor.
void FinalizeSelection();
// This method has to be called by nsEditorEventListener::Focus.
// All actions that have to be done when the editor is focused needs to be
// added here.

View File

@ -897,45 +897,7 @@ nsEditorEventListener::Blur(nsIDOMEvent* aEvent)
if (element)
return NS_OK;
// turn off selection and caret
nsCOMPtr<nsISelectionController>selCon;
mEditor->GetSelectionController(getter_AddRefs(selCon));
if (selCon)
{
nsCOMPtr<nsISelection> selection;
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selection));
nsCOMPtr<nsISelectionPrivate> selectionPrivate =
do_QueryInterface(selection);
if (selectionPrivate) {
selectionPrivate->SetAncestorLimiter(nullptr);
}
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (presShell) {
nsRefPtr<nsCaret> caret = presShell->GetCaret();
if (caret) {
caret->SetIgnoreUserModify(true);
}
}
selCon->SetCaretEnabled(false);
if(mEditor->IsFormWidget() || mEditor->IsPasswordEditor() ||
mEditor->IsReadonly() || mEditor->IsDisabled() ||
mEditor->IsInputFiltered())
{
selCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);//hide but do NOT turn off
}
else
{
selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
}
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
}
mEditor->FinalizeSelection();
return NS_OK;
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor = document.getElementById("editor");
document.getSelection().selectAllChildren(document.body);
}
</script>
</head>
<body onload="doTest();">
<p>normal text</p>
<div id="editor">editable text</div>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor = document.getElementById("editor");
editor.focus();
editor.blur();
document.getSelection().selectAllChildren(document.body);
}
</script>
</head>
<body onload="doTest();">
<p>normal text</p>
<div id="editor" contenteditable>editable text</div>
</body>
</html>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.getElementById("text"));
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
editor.focus();
editor.blur();
}
</script>
</head>
<body>
<p id="text">normal text</p>
<iframe id="editor" onload="doTest();"
src="data:text/html,<body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.getElementById("text"));
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
editor.focus();
editor.blur();
}
</script>
</head>
<body>
<p id="text">normal text</p>
<iframe id="editor" onload="doTest();"
src="data:text/html,<script>document.designMode='on';</script><body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.getElementById("text"));
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
editor.focus();
}
</script>
</head>
<body>
<p id="text">normal text</p>
<iframe id="editor" onload="doTest();"
src="data:text/html,<body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.getElementById("text"));
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
editor.focus();
}
</script>
</head>
<body>
<p id="text">normal text</p>
<iframe id="editor" onload="doTest();"
src="data:text/html,<script>document.designMode='on';</script><body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.body);
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
}
</script>
</head>
<body>
<p id="text">normal text</p>
<div>content editable</div>
<iframe id="editor" onload="doTest();"
src="data:text/html,<body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor1 = document.getElementById("editor1");
editor1.focus();
editor1.blur();
document.getSelection().selectAllChildren(document.body);
var editor2 = document.getElementById("editor2");
var editorBody = editor2.contentDocument.body;
editor2.contentDocument.getSelection().selectAllChildren(editorBody);
editor2.focus();
editor2.blur();
}
</script>
</head>
<body>
<p>normal text</p>
<div id="editor1" contenteditable>content editable</div>
<iframe id="editor2" onload="doTest();"
src="data:text/html,<script>document.designMode='on';</script><body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.body);
var editor = document.getElementById("editor");
var editorBody = editor.contentDocument.body;
editor.contentDocument.getSelection().selectAllChildren(editorBody);
editor.focus();
}
</script>
</head>
<body>
<p id="text">normal text</p>
<div>content editable</div>
<iframe id="editor" onload="doTest();"
src="data:text/html,<body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor1 = document.getElementById("editor1");
editor1.focus();
editor1.blur();
document.getSelection().selectAllChildren(document.body);
var editor2 = document.getElementById("editor2");
var editorBody = editor2.contentDocument.body;
editor2.contentDocument.getSelection().selectAllChildren(editorBody);
editor2.focus();
}
</script>
</head>
<body>
<p>normal text</p>
<div id="editor1" contenteditable>content editable</div>
<iframe id="editor2" onload="doTest();"
src="data:text/html,<script>document.designMode='on';</script><body>editable text</body>"></iframe>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor = document.getElementById("editor");
editor.focus();
editor.blur();
}
</script>
</head>
<body onload="doTest()">
<p>normal text</p>
<textarea id="editor">textarea</textarea>
</body>
</html>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.body);
var editor = document.getElementById("editor");
editor.focus();
editor.select();
editor.blur();
}
</script>
</head>
<body onload="doTest()">
<p>normal text</p>
<textarea id="editor">textarea</textarea>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
var editor = document.getElementById("editor");
editor.focus();
editor.selectionStart = 2;
editor.selectionEnd = 4;
}
</script>
</head>
<body onload="doTest()">
<p>normal text</p>
<textarea id="editor">textarea</textarea>
</body>
</html>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function doTest()
{
document.getSelection().selectAllChildren(document.body);
var editor = document.getElementById("editor");
editor.focus();
editor.selectionStart = 2;
editor.selectionEnd = 4;
editor.blur();
editor.focus();
}
</script>
</head>
<body onload="doTest()">
<p>normal text</p>
<textarea id="editor">textarea</textarea>
</body>
</html>

View File

@ -98,3 +98,13 @@ skip-if(Android||B2G) needs-focus == 462758-grabbers-resizers.html 462758-grabbe
== 388980-1.html 388980-1-ref.html
needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1-ref.html
skip-if(B2G) fails-if(Android) needs-focus != spellcheck-superscript-2.html spellcheck-superscript-2-ref.html # bug 783658
== 824080-1.html 824080-1-ref.html
== 824080-2.html 824080-2-ref.html
== 824080-3.html 824080-3-ref.html
!= 824080-2.html 824080-3.html
== 824080-4.html 824080-4-ref.html
== 824080-5.html 824080-5-ref.html
!= 824080-4.html 824080-5.html
== 824080-6.html 824080-6-ref.html
== 824080-7.html 824080-7-ref.html
!= 824080-6.html 824080-7.html