mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 612128 - document.execCommand("inserthtml") may insert HTML inside non-editable parts of a document; r=roc,bz a=bz
This commit is contained in:
parent
97fa315568
commit
bc86f1d53e
@ -1679,9 +1679,6 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttribu
|
||||
void
|
||||
nsGenericHTMLFormElement::UpdateEditableFormControlState()
|
||||
{
|
||||
// nsCSSFrameConstructor::MaybeConstructLazily is based on the logic of this
|
||||
// function, so should be kept in sync with that.
|
||||
|
||||
ContentEditableTristate value = GetContentEditableValue();
|
||||
if (value != eInherit) {
|
||||
SetEditableFlag(!!value);
|
||||
@ -1691,21 +1688,8 @@ nsGenericHTMLFormElement::UpdateEditableFormControlState()
|
||||
|
||||
nsIContent *parent = GetParent();
|
||||
|
||||
if (parent && parent->HasFlag(NODE_IS_EDITABLE)) {
|
||||
SetEditableFlag(PR_TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsTextControl(PR_FALSE)) {
|
||||
SetEditableFlag(PR_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not contentEditable we still need to check the readonly attribute.
|
||||
PRBool roState;
|
||||
GetBoolAttr(nsGkAtoms::readonly, &roState);
|
||||
|
||||
SetEditableFlag(!roState);
|
||||
PRBool inEditableSubtree = parent && parent->HasFlag(NODE_IS_EDITABLE);
|
||||
SetEditableFlag(inEditableSubtree);
|
||||
}
|
||||
|
||||
|
||||
@ -2797,6 +2781,18 @@ nsGenericHTMLFormElement::IntrinsicState() const
|
||||
state |= NS_EVENT_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
// Make the text controls read-write
|
||||
if (!state.HasState(NS_EVENT_STATE_MOZ_READWRITE) &&
|
||||
IsTextControl(PR_FALSE)) {
|
||||
PRBool roState;
|
||||
GetBoolAttr(nsGkAtoms::readonly, &roState);
|
||||
|
||||
if (!roState) {
|
||||
state |= NS_EVENT_STATE_MOZ_READWRITE;
|
||||
state &= ~NS_EVENT_STATE_MOZ_READONLY;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -1525,6 +1525,9 @@ nsTextEditorState::CreateRootNode()
|
||||
NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 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.
|
||||
|
@ -36,7 +36,9 @@ function init3()
|
||||
rng.setEnd(textNode, 1);
|
||||
targetWindow.getSelection().addRange(rng);
|
||||
|
||||
targetDocument.execCommand("inserthtml", false, "<p>");
|
||||
try {
|
||||
targetDocument.execCommand("inserthtml", false, "<p>");
|
||||
} catch(e) {}
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ public:
|
||||
virtual PRBool IsContainer(nsIDOMNode *aNode);
|
||||
|
||||
/** returns PR_TRUE if aNode is an editable node */
|
||||
PRBool IsEditable(nsIDOMNode *aNode);
|
||||
virtual PRBool IsEditable(nsIDOMNode *aNode);
|
||||
|
||||
virtual PRBool IsTextInDirtyFrameVisible(nsIDOMNode *aNode);
|
||||
|
||||
|
@ -315,7 +315,9 @@ 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) res = NS_ERROR_FAILURE;
|
||||
if (!targetNode || !IsEditable(targetNode)) {
|
||||
res = NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
else
|
||||
|
@ -6030,3 +6030,22 @@ nsHTMLEditor::GetPreferredIMEState(PRUint32 *aState)
|
||||
*aState = nsIContent::IME_STATUS_ENABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLEditor::IsEditable(nsIDOMNode* aNode) {
|
||||
if (!nsPlaintextEditor::IsEditable(aNode)) {
|
||||
return PR_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 PR_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 PR_TRUE;
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ public:
|
||||
virtual already_AddRefed<nsPIDOMEventTarget> GetPIDOMEventTarget();
|
||||
virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
|
||||
virtual PRBool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
|
||||
virtual PRBool IsEditable(nsIDOMNode *aNode);
|
||||
|
||||
/* ------------ nsStubMutationObserver overrides --------- */
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
|
@ -68,6 +68,7 @@ _TEST_FILES = \
|
||||
test_bug599322.html \
|
||||
test_bug607584.html \
|
||||
test_bug611182.html \
|
||||
test_bug612128.html \
|
||||
test_bug612447.html \
|
||||
test_CF_HTML_clipboard.html \
|
||||
test_contenteditable_focus.html \
|
||||
|
42
editor/libeditor/html/tests/test_bug612128.html
Normal file
42
editor/libeditor/html/tests/test_bug612128.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!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>
|
@ -3957,7 +3957,13 @@ nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent,
|
||||
content->SetNativeAnonymous();
|
||||
}
|
||||
|
||||
PRBool anonContentIsEditable = content->HasFlag(NODE_IS_EDITABLE);
|
||||
rv = content->BindToTree(mDocument, aParent, aParent, PR_TRUE);
|
||||
// If the anonymous content creator requested that the content should be
|
||||
// editable, honor its request.
|
||||
if (anonContentIsEditable) {
|
||||
content->SetFlags(NODE_IS_EDITABLE);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
@ -6196,25 +6202,6 @@ nsCSSFrameConstructor::ReframeTextIfNeeded(nsIContent* aParentContent,
|
||||
ContentInserted(aParentContent, aContent, nsnull, PR_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. The presence of the NODE_MAY_HAVE_CONTENT_EDITABLE_ATTR
|
||||
// flag only indicates a contenteditable attribute, it doesn't indicate if 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 PRBool
|
||||
IsActuallyEditable(nsIContent* aContainer, nsIContent* aChild)
|
||||
{
|
||||
return (aChild->IsEditable() &&
|
||||
(aContainer->IsEditable() ||
|
||||
aChild->HasFlag(NODE_MAY_HAVE_CONTENT_EDITABLE_ATTR)));
|
||||
}
|
||||
|
||||
// For inserts aChild should be valid, for appends it should be null.
|
||||
// Returns true if this operation can be lazy, false if not.
|
||||
PRBool
|
||||
@ -6229,7 +6216,7 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
|
||||
|
||||
if (aOperation == CONTENTINSERT) {
|
||||
if (aChild->IsRootOfAnonymousSubtree() ||
|
||||
aChild->IsXUL() || IsActuallyEditable(aContainer, aChild)) {
|
||||
aChild->IsEditable() || aChild->IsXUL()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
} else { // CONTENTAPPEND
|
||||
@ -6238,7 +6225,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() || IsActuallyEditable(aContainer, child)) {
|
||||
if (child->IsXUL() || child->IsEditable()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,10 @@ 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
|
||||
|
13
layout/reftests/editor/readonly-editable-ref.html
Normal file
13
layout/reftests/editor/readonly-editable-ref.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!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>
|
24
layout/reftests/editor/readonly-editable.html
Normal file
24
layout/reftests/editor/readonly-editable.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!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>
|
21
layout/reftests/editor/readonly-non-editable-ref.html
Normal file
21
layout/reftests/editor/readonly-non-editable-ref.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!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>
|
24
layout/reftests/editor/readonly-non-editable.html
Normal file
24
layout/reftests/editor/readonly-non-editable.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!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>
|
13
layout/reftests/editor/readwrite-editable-ref.html
Normal file
13
layout/reftests/editor/readwrite-editable-ref.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!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>
|
24
layout/reftests/editor/readwrite-editable.html
Normal file
24
layout/reftests/editor/readwrite-editable.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!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>
|
21
layout/reftests/editor/readwrite-non-editable-ref.html
Normal file
21
layout/reftests/editor/readwrite-non-editable-ref.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!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>
|
24
layout/reftests/editor/readwrite-non-editable.html
Normal file
24
layout/reftests/editor/readwrite-non-editable.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!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>
|
@ -47,3 +47,7 @@ asserts(1) == passwd-4.html passwd-ref.html # bug 596901
|
||||
== caret_after_reframe.html caret_after_reframe-ref.html
|
||||
== nobogusnode-1.html nobogusnode-ref.html
|
||||
== nobogusnode-2.html nobogusnode-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
|
||||
|
Loading…
Reference in New Issue
Block a user