Backout changeset be42bc18185a (bug 612128) because of bug 688423

This commit is contained in:
Ehsan Akhgari 2011-10-25 22:32:55 -04:00
parent 037b12b7d1
commit 74d9b6f1fb
26 changed files with 75 additions and 313 deletions

View File

@ -1793,6 +1793,37 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttribu
}
}
void
nsGenericHTMLFormElement::UpdateEditableFormControlState(bool aNotify)
{
// nsCSSFrameConstructor::MaybeConstructLazily is based on the logic of this
// function, so should be kept in sync with that.
ContentEditableTristate value = GetContentEditableValue();
if (value != eInherit) {
DoSetEditableFlag(!!value, aNotify);
return;
}
nsIContent *parent = GetParent();
if (parent && parent->HasFlag(NODE_IS_EDITABLE)) {
DoSetEditableFlag(true, aNotify);
return;
}
if (!IsTextControl(false)) {
DoSetEditableFlag(false, aNotify);
return;
}
// If not contentEditable we still need to check the readonly attribute.
bool roState;
GetBoolAttr(nsGkAtoms::readonly, &roState);
DoSetEditableFlag(!roState, aNotify);
}
/* static */ const nsGenericHTMLElement::MappedAttributeEntry
nsGenericHTMLElement::sCommonAttributeMap[] = {
@ -2885,18 +2916,6 @@ nsGenericHTMLFormElement::IntrinsicState() const
state |= NS_EVENT_STATE_DEFAULT;
}
// Make the text controls read-write
if (!state.HasState(NS_EVENT_STATE_MOZ_READWRITE) &&
IsTextControl(false)) {
bool roState;
GetBoolAttr(nsGkAtoms::readonly, &roState);
if (!roState) {
state |= NS_EVENT_STATE_MOZ_READWRITE;
state &= ~NS_EVENT_STATE_MOZ_READONLY;
}
}
return state;
}

View File

@ -928,6 +928,8 @@ protected:
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, bool aNotify);
void UpdateEditableFormControlState(bool aNotify);
/**
* This method will update the form owner, using @form or looking to a parent.
*

View File

@ -846,6 +846,7 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
UpdateTypeMismatchValidityState();
}
UpdateEditableState(aNotify);
UpdateState(aNotify);
}

View File

@ -235,6 +235,11 @@ public:
NS_IMETHOD FireAsyncClickHandler();
virtual void UpdateEditableState(bool aNotify)
{
return UpdateEditableFormControlState(aNotify);
}
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLInputElement,
nsGenericHTMLFormElement)

View File

@ -203,6 +203,11 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
virtual void UpdateEditableState(bool aNotify)
{
return UpdateEditableFormControlState(aNotify);
}
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLTextAreaElement,
nsGenericHTMLFormElement)
@ -1269,6 +1274,9 @@ nsHTMLTextAreaElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
UpdateTooLongValidityState();
}
if (aName == nsGkAtoms::readonly) {
UpdateEditableState(aNotify);
}
UpdateState(aNotify);
}

View File

@ -1563,9 +1563,6 @@ nsTextEditorState::CreateRootNode()
nsresult
nsTextEditorState::InitializeRootNode()
{
// Make our root node editable
mRootNode->SetFlags(NODE_IS_EDITABLE);
// Set the necessary classes on the text control. We use class values
// instead of a 'style' attribute so that the style comes from a user-agent
// style sheet and is still applied even if author styles are disabled.

View File

@ -36,9 +36,7 @@ function init3()
rng.setEnd(textNode, 1);
targetWindow.getSelection().addRange(rng);
try {
targetDocument.execCommand("inserthtml", false, "<p>");
} catch(e) {}
targetDocument.execCommand("inserthtml", false, "<p>");
document.documentElement.removeAttribute("class");
}

View File

@ -548,7 +548,7 @@ public:
virtual bool IsContainer(nsIDOMNode *aNode);
/** returns true if aNode is an editable node */
virtual bool IsEditable(nsIDOMNode *aNode);
bool IsEditable(nsIDOMNode *aNode);
virtual bool IsTextInDirtyFrameVisible(nsIDOMNode *aNode);

View File

@ -662,11 +662,9 @@ nsSelectAllCommand::IsCommandEnabled(const char * aCommandName,
NS_ENSURE_ARG_POINTER(outCmdEnabled);
nsresult rv = NS_OK;
// You can always select all, unless the selection is editable,
// and the editable region is empty!
*outCmdEnabled = true;
*outCmdEnabled = false;
bool docIsEmpty, selectionIsEditable;
// you can select all if there is an editor which is non-empty
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
if (editor) {
@ -678,7 +676,7 @@ nsSelectAllCommand::IsCommandEnabled(const char * aCommandName,
NS_ENSURE_SUCCESS(rv, rv);
*outCmdEnabled = !docIsEmpty;
}
}
}
return rv;
}

View File

@ -313,9 +313,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
// if caller didn't provide the destination/target node,
// fetch the paste insertion point from our selection
res = GetStartNodeAndOffset(selection, getter_AddRefs(targetNode), &targetOffset);
if (!targetNode || !IsEditable(targetNode)) {
res = NS_ERROR_FAILURE;
}
if (!targetNode) res = NS_ERROR_FAILURE;
NS_ENSURE_SUCCESS(res, res);
}
else

View File

@ -431,12 +431,6 @@ nsHTMLEditor::FindSelectionRoot(nsINode *aNode)
}
if (!content->HasFlag(NODE_IS_EDITABLE)) {
// If the content is in read-write state but is not editable itself,
// return it as the selection root.
if (content->IsElement() &&
content->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
return content.forget();
}
return nsnull;
}
@ -6034,22 +6028,3 @@ nsHTMLEditor::GetPreferredIMEState(PRUint32 *aState)
*aState = nsIContent::IME_STATUS_ENABLE;
return NS_OK;
}
bool
nsHTMLEditor::IsEditable(nsIDOMNode* aNode) {
if (!nsPlaintextEditor::IsEditable(aNode)) {
return false;
}
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
if (!node) {
// If what we're dealing with is not a node, then it's not editable!
return false;
}
if (node->IsElement()) {
// If we're dealing with an element, then ask it whether it's editable.
return node->IsEditable();
}
// We might be dealing with a text node for example, which we always consider
// to be editable.
return true;
}

View File

@ -154,7 +154,6 @@ public:
virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget();
virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
virtual bool IsEditable(nsIDOMNode *aNode);
/* ------------ nsStubMutationObserver overrides --------- */
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED

View File

@ -79,7 +79,6 @@ _TEST_FILES = \
test_bug599322.html \
test_bug607584.html \
test_bug611182.html \
test_bug612128.html \
test_bug612447.html \
test_bug620906.html \
test_bug622371.html \

View File

@ -1,42 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=612128
-->
<head>
<title>Test for Bug 612128</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/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=612128">Mozilla Bug 612128</a>
<p id="display"></p>
<div id="content">
<input>
<div contenteditable></div>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 612128 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
document.querySelector("input").focus();
var threw = false;
try {
document.execCommand("inserthtml", null, "<span>f" + "oo</span>");
} catch (e) {
threw = true;
}
ok(threw, "The inserthtml command should fail");
is(document.querySelectorAll("span").length, 0, "No span element should be injected inside the page");
is(document.body.innerHTML.indexOf("f" + "oo"), -1, "No text should be injected inside the page");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -35,17 +35,10 @@ var gBlock1, gBlock2;
function IsCommandEnabled(command) {
var enabled;
var resultInNonEditableRegion = false;
if (command == "selectAll") {
// The select all command is sort of exceptional, as it needs to be enabled
// everywhere.
resultInNonEditableRegion = true;
}
// non-editable div: should return false
window.getSelection().selectAllChildren(gBlock1);
enabled = document.queryCommandEnabled(command);
is(enabled, resultInNonEditableRegion, "'" + command + "' should not be enabled on a non-editable block.");
is(enabled, false, "'" + command + "' should not be enabled on a non-editable block.");
// editable div: should return true
window.getSelection().selectAllChildren(gBlock2);

View File

@ -3882,31 +3882,6 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
return NS_OK;
}
static void
SetFlagsOnSubtree(nsIContent *aNode, PtrBits aFlagsToSet)
{
#ifdef DEBUG
// Make sure that the node passed to us doesn't have any XBL children
{
nsIDocument *doc = aNode->OwnerDoc();
NS_ASSERTION(doc, "The node must be in a document");
NS_ASSERTION(!doc->BindingManager()->GetXBLChildNodesFor(aNode),
"The node should not have any XBL children");
}
#endif
// Set the flag on the node itself
aNode->SetFlags(aFlagsToSet);
// Set the flag on all of its children recursively
PRUint32 count;
nsIContent * const *children = aNode->GetChildArray(&count);
for (PRUint32 index = 0; index < count; ++index) {
SetFlagsOnSubtree(children[index], aFlagsToSet);
}
}
nsresult
nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent,
nsIFrame* aParentFrame,
@ -3934,17 +3909,7 @@ nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent,
content->SetNativeAnonymous();
}
bool anonContentIsEditable = content->HasFlag(NODE_IS_EDITABLE);
rv = content->BindToTree(mDocument, aParent, aParent, true);
// If the anonymous content creator requested that the content should be
// editable, honor its request.
// We need to set the flag on the whole subtree, because existing
// children's flags have already been set as part of the BindToTree operation.
if (anonContentIsEditable) {
NS_ASSERTION(aParentFrame->GetType() == nsGkAtoms::textInputFrame,
"We only expect this for anonymous content under a text control frame");
SetFlagsOnSubtree(content, NODE_IS_EDITABLE);
}
if (NS_FAILED(rv)) {
content->UnbindFromTree();
return rv;
@ -6167,6 +6132,25 @@ nsCSSFrameConstructor::ReframeTextIfNeeded(nsIContent* aParentContent,
ContentInserted(aParentContent, aContent, nsnull, false);
}
// We want to disable lazy frame construction for nodes that are under an
// editor. We use nsINode::IsEditable, but that includes inputs with type text
// and password and textareas, which are common and aren't really editable (the
// native anonymous content under them is what is actually editable) so we want
// to construct frames for those lazily.
// The logic for this check is based on
// nsGenericHTMLFormElement::UpdateEditableFormControlState and so must be kept
// in sync with that. MayHaveContentEditableAttr() being true only indicates
// a contenteditable attribute, it doesn't indicate whether it is true or false,
// so we force eager construction in some cases when the node is not editable,
// but that should be rare.
static inline bool
IsActuallyEditable(nsIContent* aContainer, nsIContent* aChild)
{
return (aChild->IsEditable() &&
(aContainer->IsEditable() ||
aChild->MayHaveContentEditableAttr()));
}
// For inserts aChild should be valid, for appends it should be null.
// Returns true if this operation can be lazy, false if not.
bool
@ -6181,7 +6165,7 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
if (aOperation == CONTENTINSERT) {
if (aChild->IsRootOfAnonymousSubtree() ||
aChild->IsEditable() || aChild->IsXUL()) {
aChild->IsXUL() || IsActuallyEditable(aContainer, aChild)) {
return false;
}
} else { // CONTENTAPPEND
@ -6190,7 +6174,7 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
for (nsIContent* child = aChild; child; child = child->GetNextSibling()) {
NS_ASSERTION(!child->IsRootOfAnonymousSubtree(),
"Should be coming through the CONTENTAPPEND case");
if (child->IsXUL() || child->IsEditable()) {
if (child->IsXUL() || IsActuallyEditable(aContainer, child)) {
return false;
}
}

View File

@ -79,10 +79,6 @@ public:
* Creates "native" anonymous content and adds the created content to
* the aElements array. None of the returned elements can be nsnull.
*
* If the anonymous content creator sets the editable flag on some
* of the elements that it creates, the flag will be applied to the node
* upon being bound to the document.
*
* @note The returned elements are owned by this object. This object is
* responsible for calling UnbindFromTree on the elements it returned
* from CreateAnonymousContent when appropriate (i.e. before releasing

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<input>
<input readonly>
<input type=password>
<input type=password readonly>
<input type=email>
<input type=email readonly>
<textarea></textarea>
<textarea readonly></textarea>
</body>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
:-moz-read-write + span {
display: none;
}
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body contenteditable>
<input><span>hide me</span>
<input readonly><span>hide me</span>
<input type=password><span>hide me</span>
<input type=password readonly><span>hide me</span>
<input type=email><span>hide me</span>
<input type=email readonly><span>hide me</span>
<textarea></textarea><span>hide me</span>
<textarea readonly></textarea><span>hide me</span>
</body>
</html>

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body>
<input><span>hide me</span>
<input readonly>
<input type=password><span>hide me</span>
<input type=password readonly>
<input type=email><span>hide me</span>
<input type=email readonly>
<textarea></textarea><span>hide me</span>
<textarea readonly></textarea>
</body>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
:-moz-read-only + span {
display: none;
}
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body>
<input><span>hide me</span>
<input readonly><span>hide me</span>
<input type=password><span>hide me</span>
<input type=password readonly><span>hide me</span>
<input type=email><span>hide me</span>
<input type=email readonly><span>hide me</span>
<textarea></textarea><span>hide me</span>
<textarea readonly></textarea><span>hide me</span>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<input>
<input readonly>
<input type=password>
<input type=password readonly>
<input type=email>
<input type=email readonly>
<textarea></textarea>
<textarea readonly></textarea>
</body>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
:-moz-read-write + span {
display: none;
}
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body contenteditable>
<input><span>hide me</span>
<input readonly><span>hide me</span>
<input type=password><span>hide me</span>
<input type=password readonly><span>hide me</span>
<input type=email><span>hide me</span>
<input type=email readonly><span>hide me</span>
<textarea></textarea><span>hide me</span>
<textarea readonly></textarea><span>hide me</span>
</body>
</html>

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body>
<input>
<input readonly><span>hide me</span>
<input type=password>
<input type=password readonly><span>hide me</span>
<input type=email>
<input type=email readonly><span>hide me</span>
<textarea></textarea>
<textarea readonly></textarea><span>hide me</span>
</body>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
:-moz-read-write + span {
display: none;
}
span {
color: transparent; /* workaround for bug 617524 */
outline: 1px solid green;
}
</style>
</head>
<body>
<input><span>hide me</span>
<input readonly><span>hide me</span>
<input type=password><span>hide me</span>
<input type=password readonly><span>hide me</span>
<input type=email><span>hide me</span>
<input type=email readonly><span>hide me</span>
<textarea></textarea><span>hide me</span>
<textarea readonly></textarea><span>hide me</span>
</body>
</html>

View File

@ -83,10 +83,6 @@ skip-if(Android) == 674212-spellcheck.html 674212-spellcheck-ref.html
skip-if(Android) == 338427-2.html 338427-2-ref.html
skip-if(Android) needs-focus == 338427-3.html 338427-3-ref.html
skip-if(Android) == 462758-grabbers-resizers.html 462758-grabbers-resizers-ref.html
== readwrite-non-editable.html readwrite-non-editable-ref.html
== readwrite-editable.html readwrite-editable-ref.html
== readonly-non-editable.html readonly-non-editable-ref.html
== readonly-editable.html readonly-editable-ref.html
== dynamic-overflow-change.html dynamic-overflow-change-ref.html
== 694880-1.html 694880-ref.html
== 694880-2.html 694880-ref.html