Bug 689564. Only forward event attributes on body/frameset to the window if we also forward the corresponding on* property. r=smaug

This commit is contained in:
Boris Zbarsky 2011-09-28 11:54:50 -04:00
parent 8cc26d445d
commit 095402dd70
12 changed files with 109 additions and 15 deletions

View File

@ -21,7 +21,7 @@ function test()
}
function clickTest(doc, win) {
var clicks = doc.defaultView.clicks;
EventUtils.synthesizeMouse(doc.body, 100, 600, {}, win);
EventUtils.synthesizeMouseAtCenter(doc.body, {}, win);
is(doc.defaultView.clicks, clicks+1, "adding 1 more click on BODY");
}
function test1() {

View File

@ -4424,7 +4424,8 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
NS_PRECONDITION(aEventName, "Must have event name!");
PRBool defer = PR_TRUE;
nsEventListenerManager* manager = GetEventListenerManagerForAttr(&defer);
nsEventListenerManager* manager = GetEventListenerManagerForAttr(aEventName,
&defer);
if (!manager) {
return NS_OK;
}
@ -4701,7 +4702,8 @@ nsGenericElement::SetMappedAttribute(nsIDocument* aDocument,
}
nsEventListenerManager*
nsGenericElement::GetEventListenerManagerForAttr(PRBool* aDefer)
nsGenericElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
PRBool* aDefer)
{
*aDefer = PR_TRUE;
return GetListenerManager(PR_TRUE);

View File

@ -780,7 +780,7 @@ protected:
* needed for attachment of attribute-defined handlers
*/
virtual nsEventListenerManager*
GetEventListenerManagerForAttr(PRBool* aDefer);
GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer);
/**
* Copy attributes and state to another element

View File

@ -78,6 +78,9 @@
* Event names that are not exposed as IDL attributes at all should be
* enclosed in NON_IDL_EVENT. If NON_IDL_EVENT is not defined, it
* will be defined to the empty string.
*
* If you change which macros event names are enclosed in, please
* update the tests for bug 689564 and bug 659350 as needed.
*/
#ifdef DEFINED_FORWARDED_EVENT

View File

@ -111,6 +111,7 @@ _TEST_FILES = \
test_bug667919-2.html \
test_bug667612.html \
empty.js \
test_bug689564.html \
$(NULL)
#bug 585630

View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=689564
-->
<head>
<title>Test for Bug 689564</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=689564">Mozilla Bug 689564</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 689564 **/
var div = document.createElement("div");
div.setAttribute("onclick", "div");
is(window.onclick, null, "div should not forward onclick");
is(div.onclick.toString(), "function onclick(event) {\n div;\n}",
"div should have an onclick handler");
div.setAttribute("onscroll", "div");
is(window.onscroll, null, "div should not forward onscroll");
is(div.onscroll.toString(), "function onscroll(event) {\n div;\n}",
"div should have an onscroll handler");
div.setAttribute("onpopstate", "div");
is(window.onpopstate, null, "div should not forward onpopstate");
is(div.onpopstate, null, "div should not have onpopstate handler");
var body = document.createElement("body");
body.setAttribute("onclick", "body");
is(window.onclick, null, "body should not forward onclick");
is(body.onclick.toString(), "function onclick(event) {\n body;\n}",
"body should have an onclick handler");
body.setAttribute("onscroll", "body");
is(window.onscroll.toString(), "function onscroll(event) {\n body;\n}",
"body should forward onscroll");
body.setAttribute("onpopstate", "body");
is(window.onpopstate.toString(), "function onpopstate(event) {\n body;\n}",
"body should forward onpopstate");
var frameset = document.createElement("frameset");
frameset.setAttribute("onclick", "frameset");
is(window.onclick, null, "frameset should not forward onclick");
is(frameset.onclick.toString(), "function onclick(event) {\n frameset;\n}",
"frameset should have an onclick handler");
frameset.setAttribute("onscroll", "frameset");
is(window.onscroll.toString(), "function onscroll(event) {\n frameset;\n}",
"frameset should forward onscroll");
frameset.setAttribute("onpopstate", "frameset");
is(window.onpopstate.toString(), "function onpopstate(event) {\n frameset;\n}",
"frameset should forward onpopstate");
</script>
</pre>
</body>
</html>

View File

@ -1235,11 +1235,24 @@ nsGenericHTMLElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
}
nsEventListenerManager*
nsGenericHTMLElement::GetEventListenerManagerForAttr(PRBool* aDefer)
nsGenericHTMLElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
PRBool* aDefer)
{
// Attributes on the body and frameset tags get set on the global object
if (mNodeInfo->Equals(nsGkAtoms::body) ||
mNodeInfo->Equals(nsGkAtoms::frameset)) {
if ((mNodeInfo->Equals(nsGkAtoms::body) ||
mNodeInfo->Equals(nsGkAtoms::frameset)) &&
// We only forward some event attributes from body/frameset to window
(0
#define EVENT(name_, id_, type_, struct_) /* nothing */
#define FORWARDED_EVENT(name_, id_, type_, struct_) \
|| nsGkAtoms::on##name_ == aAttrName
#define WINDOW_EVENT FORWARDED_EVENT
#include "nsEventNameList.h"
#undef WINDOW_EVENT
#undef FORWARDED_EVENT
#undef EVENT
)
) {
nsPIDOMWindow *win;
// If we have a document, and it has a window, add the event
@ -1265,7 +1278,8 @@ nsGenericHTMLElement::GetEventListenerManagerForAttr(PRBool* aDefer)
return nsnull;
}
return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aDefer);
return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aAttrName,
aDefer);
}
nsresult

View File

@ -607,7 +607,7 @@ protected:
const nsAString* aValue, PRBool aNotify);
virtual nsEventListenerManager*
GetEventListenerManagerForAttr(PRBool* aDefer);
GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer);
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;

View File

@ -509,7 +509,7 @@ nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
}
nsEventListenerManager*
nsXULElement::GetEventListenerManagerForAttr(PRBool* aDefer)
nsXULElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer)
{
// XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc()
// here, override BindToTree for those classes and munge event
@ -529,7 +529,7 @@ nsXULElement::GetEventListenerManagerForAttr(PRBool* aDefer)
return piTarget->GetListenerManager(PR_TRUE);
}
return nsStyledElement::GetEventListenerManagerForAttr(aDefer);
return nsStyledElement::GetEventListenerManagerForAttr(aAttrName, aDefer);
}
// returns true if the element is not a list

View File

@ -637,7 +637,7 @@ protected:
nsAttrValue& aResult);
virtual nsEventListenerManager*
GetEventListenerManagerForAttr(PRBool* aDefer);
GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer);
/**
* Return our prototype's attribute, if one exists.

View File

@ -29,6 +29,8 @@ function errorHandler(msg, filename, linenr) {
window.onerror = errorHandler;
document.body.setAttribute("onclick", "var x=;");
// Force eager compilation
document.body.onclick;
is(errorCount, 1, "Error handler should have been called! (1)");
function recursiveHandler(msg, filename, linenr) {
@ -41,10 +43,14 @@ function recursiveHandler(msg, filename, linenr) {
window.onerror = recursiveHandler;
document.body.setAttribute("onclick", "var y=;");
// Force eager compilation
document.body.onclick;
is(errorCount, 2, "Error handler should have been called! (2)");
// Check that error handler works even after recursion error.
document.body.setAttribute("onclick", "var foo=;");
// Force eager compilation
document.body.onclick;
is(errorCount, 3, "Error handler should have been called! (3)");
window.onerror = function() { ++errorCount; };

View File

@ -31,11 +31,14 @@ function continueTest() {
ifrwindow.focus();
var utils = ifrwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0);
utils.sendMouseEvent("mouseup", 1, 1, 0, 1, 0);
var rect = ifrwindow.document.body.getBoundingClientRect();
var x = rect.left + (rect.width/2);
var y = rect.top + (rect.height/2);
utils.sendMouseEvent("mousedown", x, y, 0, 1, 0);
utils.sendMouseEvent("mouseup", x, y, 0, 1, 0);
is(ifrwindow.document.body.textContent, 1, "Should have got a click event!");
SimpleTest.finish();
}
]]></script>
</window>
</window>