From 74d9b6f1fb635f066b256572e8fc447befd74c8e Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 25 Oct 2011 22:32:55 -0400 Subject: [PATCH] Backout changeset be42bc18185a (bug 612128) because of bug 688423 --- .../html/content/src/nsGenericHTMLElement.cpp | 43 ++++++++++---- .../html/content/src/nsGenericHTMLElement.h | 2 + .../html/content/src/nsHTMLInputElement.cpp | 1 + content/html/content/src/nsHTMLInputElement.h | 5 ++ .../content/src/nsHTMLTextAreaElement.cpp | 8 +++ .../html/content/src/nsTextEditorState.cpp | 3 - .../libeditor/base/crashtests/382527-1.html | 4 +- editor/libeditor/base/nsEditor.h | 2 +- editor/libeditor/base/nsEditorCommands.cpp | 8 +-- editor/libeditor/html/nsHTMLDataTransfer.cpp | 4 +- editor/libeditor/html/nsHTMLEditor.cpp | 25 -------- editor/libeditor/html/nsHTMLEditor.h | 1 - editor/libeditor/html/tests/Makefile.in | 1 - .../libeditor/html/tests/test_bug612128.html | 42 -------------- .../libeditor/html/tests/test_bug676401.html | 9 +-- layout/base/nsCSSFrameConstructor.cpp | 58 +++++++------------ layout/generic/nsIAnonymousContentCreator.h | 4 -- .../editor/readonly-editable-ref.html | 13 ----- layout/reftests/editor/readonly-editable.html | 24 -------- .../editor/readonly-non-editable-ref.html | 21 ------- .../editor/readonly-non-editable.html | 24 -------- .../editor/readwrite-editable-ref.html | 13 ----- .../reftests/editor/readwrite-editable.html | 24 -------- .../editor/readwrite-non-editable-ref.html | 21 ------- .../editor/readwrite-non-editable.html | 24 -------- layout/reftests/editor/reftest.list | 4 -- 26 files changed, 75 insertions(+), 313 deletions(-) delete mode 100644 editor/libeditor/html/tests/test_bug612128.html delete mode 100644 layout/reftests/editor/readonly-editable-ref.html delete mode 100644 layout/reftests/editor/readonly-editable.html delete mode 100644 layout/reftests/editor/readonly-non-editable-ref.html delete mode 100644 layout/reftests/editor/readonly-non-editable.html delete mode 100644 layout/reftests/editor/readwrite-editable-ref.html delete mode 100644 layout/reftests/editor/readwrite-editable.html delete mode 100644 layout/reftests/editor/readwrite-non-editable-ref.html delete mode 100644 layout/reftests/editor/readwrite-non-editable.html diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 484d52275dd..c55f4ee806a 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -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; } diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index 4c27e650c47..975d617eae0 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -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. * diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 625d3078c1f..fb7c876823e 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -846,6 +846,7 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, UpdateTypeMismatchValidityState(); } + UpdateEditableState(aNotify); UpdateState(aNotify); } diff --git a/content/html/content/src/nsHTMLInputElement.h b/content/html/content/src/nsHTMLInputElement.h index 925888f3192..c3d864ed1a7 100644 --- a/content/html/content/src/nsHTMLInputElement.h +++ b/content/html/content/src/nsHTMLInputElement.h @@ -235,6 +235,11 @@ public: NS_IMETHOD FireAsyncClickHandler(); + virtual void UpdateEditableState(bool aNotify) + { + return UpdateEditableFormControlState(aNotify); + } + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLInputElement, nsGenericHTMLFormElement) diff --git a/content/html/content/src/nsHTMLTextAreaElement.cpp b/content/html/content/src/nsHTMLTextAreaElement.cpp index 266e124bfbb..0a0c6c9e30f 100644 --- a/content/html/content/src/nsHTMLTextAreaElement.cpp +++ b/content/html/content/src/nsHTMLTextAreaElement.cpp @@ -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); } diff --git a/content/html/content/src/nsTextEditorState.cpp b/content/html/content/src/nsTextEditorState.cpp index 8efe9b22515..971b5a5b844 100644 --- a/content/html/content/src/nsTextEditorState.cpp +++ b/content/html/content/src/nsTextEditorState.cpp @@ -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. diff --git a/editor/libeditor/base/crashtests/382527-1.html b/editor/libeditor/base/crashtests/382527-1.html index 2441dcd87b5..ff33a141794 100644 --- a/editor/libeditor/base/crashtests/382527-1.html +++ b/editor/libeditor/base/crashtests/382527-1.html @@ -36,9 +36,7 @@ function init3() rng.setEnd(textNode, 1); targetWindow.getSelection().addRange(rng); - try { - targetDocument.execCommand("inserthtml", false, "

"); - } catch(e) {} + targetDocument.execCommand("inserthtml", false, "

"); document.documentElement.removeAttribute("class"); } diff --git a/editor/libeditor/base/nsEditor.h b/editor/libeditor/base/nsEditor.h index f88cb99667d..95aa6207c28 100644 --- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -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); diff --git a/editor/libeditor/base/nsEditorCommands.cpp b/editor/libeditor/base/nsEditorCommands.cpp index 0e25d6c2ca9..d6c46d18e96 100644 --- a/editor/libeditor/base/nsEditorCommands.cpp +++ b/editor/libeditor/base/nsEditorCommands.cpp @@ -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 editor = do_QueryInterface(aCommandRefCon); if (editor) { @@ -678,7 +676,7 @@ nsSelectAllCommand::IsCommandEnabled(const char * aCommandName, NS_ENSURE_SUCCESS(rv, rv); *outCmdEnabled = !docIsEmpty; } - } + } return rv; } diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index f1178e0db28..49182f880a6 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -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 diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 74f4b6d1005..bb71271c6b2 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -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 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; -} diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h index c187928b206..572bb29ab82 100644 --- a/editor/libeditor/html/nsHTMLEditor.h +++ b/editor/libeditor/html/nsHTMLEditor.h @@ -154,7 +154,6 @@ public: virtual already_AddRefed GetDOMEventTarget(); virtual already_AddRefed FindSelectionRoot(nsINode *aNode); virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent); - virtual bool IsEditable(nsIDOMNode *aNode); /* ------------ nsStubMutationObserver overrides --------- */ NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED diff --git a/editor/libeditor/html/tests/Makefile.in b/editor/libeditor/html/tests/Makefile.in index e594acf3b45..c702714eafd 100644 --- a/editor/libeditor/html/tests/Makefile.in +++ b/editor/libeditor/html/tests/Makefile.in @@ -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 \ diff --git a/editor/libeditor/html/tests/test_bug612128.html b/editor/libeditor/html/tests/test_bug612128.html deleted file mode 100644 index 660bb54904e..00000000000 --- a/editor/libeditor/html/tests/test_bug612128.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Test for Bug 612128 - - - - - - -Mozilla Bug 612128 -

-
- -
-
-
-
-
- - diff --git a/editor/libeditor/html/tests/test_bug676401.html b/editor/libeditor/html/tests/test_bug676401.html index e1915c7b9b8..ba60753f757 100644 --- a/editor/libeditor/html/tests/test_bug676401.html +++ b/editor/libeditor/html/tests/test_bug676401.html @@ -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); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index c685c6b6264..3769c8cd408 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -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; } } diff --git a/layout/generic/nsIAnonymousContentCreator.h b/layout/generic/nsIAnonymousContentCreator.h index 4c351a99b69..b1e84dc5305 100644 --- a/layout/generic/nsIAnonymousContentCreator.h +++ b/layout/generic/nsIAnonymousContentCreator.h @@ -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 diff --git a/layout/reftests/editor/readonly-editable-ref.html b/layout/reftests/editor/readonly-editable-ref.html deleted file mode 100644 index 99f1e510173..00000000000 --- a/layout/reftests/editor/readonly-editable-ref.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/layout/reftests/editor/readonly-editable.html b/layout/reftests/editor/readonly-editable.html deleted file mode 100644 index 49210e58147..00000000000 --- a/layout/reftests/editor/readonly-editable.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - hide me - hide me - hide me - hide me - hide me - hide me - hide me - hide me - - diff --git a/layout/reftests/editor/readonly-non-editable-ref.html b/layout/reftests/editor/readonly-non-editable-ref.html deleted file mode 100644 index a91071e42c3..00000000000 --- a/layout/reftests/editor/readonly-non-editable-ref.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - hide me - - hide me - - hide me - - hide me - - - diff --git a/layout/reftests/editor/readonly-non-editable.html b/layout/reftests/editor/readonly-non-editable.html deleted file mode 100644 index 9766045ed73..00000000000 --- a/layout/reftests/editor/readonly-non-editable.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - hide me - hide me - hide me - hide me - hide me - hide me - hide me - hide me - - diff --git a/layout/reftests/editor/readwrite-editable-ref.html b/layout/reftests/editor/readwrite-editable-ref.html deleted file mode 100644 index 99f1e510173..00000000000 --- a/layout/reftests/editor/readwrite-editable-ref.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/layout/reftests/editor/readwrite-editable.html b/layout/reftests/editor/readwrite-editable.html deleted file mode 100644 index 49210e58147..00000000000 --- a/layout/reftests/editor/readwrite-editable.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - hide me - hide me - hide me - hide me - hide me - hide me - hide me - hide me - - diff --git a/layout/reftests/editor/readwrite-non-editable-ref.html b/layout/reftests/editor/readwrite-non-editable-ref.html deleted file mode 100644 index 12e1c46c0ae..00000000000 --- a/layout/reftests/editor/readwrite-non-editable-ref.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - hide me - - hide me - - hide me - - hide me - - diff --git a/layout/reftests/editor/readwrite-non-editable.html b/layout/reftests/editor/readwrite-non-editable.html deleted file mode 100644 index 535f21f1aa0..00000000000 --- a/layout/reftests/editor/readwrite-non-editable.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - hide me - hide me - hide me - hide me - hide me - hide me - hide me - hide me - - diff --git a/layout/reftests/editor/reftest.list b/layout/reftests/editor/reftest.list index 55229b805ac..f50a9a3a437 100644 --- a/layout/reftests/editor/reftest.list +++ b/layout/reftests/editor/reftest.list @@ -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