FW: Should the base svg tag receive events? (testcase)

Same thing without the attachment.... file inline.  BTW, I don't suppose anyone has IE and can see how it reacts?
-----------------------------------------------------------
<!DOCTYPE HTML>
<!-- Credits/Copyright/Reference: http://www.whatwg.org/specs/web-apps/current-work/ -->
<!-- Credits/Copyright/Reference: http://www.w3.org/TR/SVG11/ & http://www.w3.org/TR/xml/ & http://www.w3.org/TR/xlink/-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
.graphical {
background-color:rgb(250,190,140);
}
.events {
/* can trigger events */
border-width:0px 0px 2px 0px;
border-style:dashed;
border-color:red;
}
</style>
<script>
/* Credits/Copyright/Reference:
-Raw Javascript (DOM)-
http://www.w3.org/TR/DOM-Level-2-Core/
http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html (quick reference of all JS DOM features)
http://www.w3.org/TR/DOM-Level-2-Events/
http://www.w3.org/TR/DOM-Level-2-Events/ecma-script-binding.html (JS Events Reference)
-Raw Javascript (language)-
http://www.ecma-international.org/publications/standards/Ecma-262.htm
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf (direct link)
*/
function getId(element) {
if(element.hasAttribute("id")) {
return element.getAttribute("id")
} else {
return null
}
}
function setup() {
addEventToAll(document, "mousedown", collect)
window.addEventListener("mouseup",showResult, false)
}
 
RESULT = new function(){
this.list = []
this.test = null
this.add = function(data) {
data.index = this.list.length
this.list.push(data)
if(data.currentTargetId.length > "test".length && data.currentTargetId.slice(0,4) == "test") { //what is the test number
this.test = data.currentTargetId.slice(0,5)
}
}
this.getData = function() {
return this.list
}
this.reset = function() {
this.list=[]
}
}
function collect(Event) {
// EventTarget = http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
// eventPhase = from http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event
RESULT.add({
"EventTarget": (Event.target+"").slice("[object ".length,-1),
"EventTargetId": getId(Event.target),
"eventPhase": Event.eventPhase,
"currentTarget": (Event.currentTarget+"").slice("[object ".length,-1),
"currentTargetId": getId(Event.currentTarget),
})
}
function showResult() {
resultStr = ""
actualResultStr = ""
EventTargetsMatched = true
if(RESULT.test) {
data = RESULT.getData()
for(key in data) {
index = data[key].index
actualObj = data[key]
testObj = tests[RESULT.test]
testObjEntry = testObj[index]
eventPhasePass = (actualObj.eventPhase == testObjEntry.phase) ? "pass" : "FAIL"
currentTargetPass = (actualObj.currentTarget == testObjEntry.element) ? "pass" : "FAIL"
currentTargetIdPass = (actualObj.currentTargetId == testObjEntry.elementId || (!actualObj.currentTargetId && !testObjEntry.elementId)) ? "pass" : "FAIL"
resultStr += index+ ": eventPhase: "+eventPhasePass+"\tcurrentTarget: "+currentTargetPass+"\tcurrentTargetId: "+currentTargetIdPass+"\n"
actualResultStr += "eventPhase: "+actualObj.eventPhase+"\tcurrentTarget: "+actualObj.currentTarget+"\tcurrentTargetId: "+actualObj.currentTargetId+"\n"
if(EventTargetsMatched && actualObj.EventTarget==testObj.targetElement && actualObj.EventTargetId==testObj.targetElementId) { // check EventTarget
} else {
//alert(actualObj.EventTarget+"=="+testObj.targetElement+" && "+actualObj.EventTargetId+"=="+testObj.targetElementId)
EventTargetsMatched = false
}
}
}
document.getElementById("result").value = resultStr
document.getElementById("result").value += (EventTargetsMatched) ? "\nPASS: EventTargets matched" : "\nFAIL: EventTargets did not match!!!!!!!!!"
document.getElementById("result").value += "\n\nActual Results:\n"+actualResultStr
RESULT.reset()
}
 
 
addEventToAll = function(node, type, func) {
if(typeof(node) == typeof({})) {
if(node.nodeType == 1 || node.nodeType == 9) {
node.addEventListener(type, func, true)
node.addEventListener(type, func, false)
}
if(node.hasChildNodes) {
for (key in node.childNodes) {
childNode = node.childNodes[key]
addEventToAll(childNode, type, func)
}
}
}
}
</script>
<script>
tests = {
test1: {
"targetElement": "HTMLDivElement",
"targetElementId": "test1_div2",
"0": {"phase":1, "element":"HTMLHtmlElement",},
"1": {"phase":1, "element":"HTMLBodyElement",},
"2": {"phase":1, "element":"HTMLDivElement", "elementId":"test1_div1",},
"3": {"phase":2, "element":"HTMLDivElement", "elementId":"test1_div2",},
"4": {"phase":2, "element":"HTMLDivElement", "elementId":"test1_div2",},
"5": {"phase":3, "element":"HTMLDivElement", "elementId":"test1_div1",},
"6": {"phase":3, "element":"HTMLBodyElement",},
"7": {"phase":3, "element":"HTMLHtmlElement",},
},
test2: {
"targetElement": "SVGRectElement",
"targetElementId": null,
"0": {"phase":1, "element":"HTMLHtmlElement",},
"1": {"phase":1, "element":"HTMLBodyElement",},
"2": {"phase":1, "element":"HTMLDivElement", "elementId":"test2_div1",},
"3": {"phase":1, "element":"SVGSVGElement",},
"4": {"phase":2, "element":"SVGRectElement",},
"5": {"phase":2, "element":"SVGRectElement",},
"6": {"phase":3, "element":"SVGSVGElement",},
"7": {"phase":3, "element":"HTMLDivElement", "elementId":"test2_div1",},
"8": {"phase":3, "element":"HTMLBodyElement",},
"9": {"phase":3, "element":"HTMLHtmlElement",},
},
test3: {
"targetElement": "HTMLDivElement",
"targetElementId": "test3_div2",
"0": {"phase":1, "element":"HTMLHtmlElement",},
"1": {"phase":1, "element":"HTMLBodyElement",},
"2": {"phase":1, "element":"HTMLDivElement", "elementId":"test3_div1",},
"3": {"phase":2, "element":"HTMLDivElement", "elementId":"test3_div2",},
"4": {"phase":2, "element":"HTMLDivElement", "elementId":"test3_div2",},
"5": {"phase":3, "element":"HTMLDivElement", "elementId":"test3_div1",},
"6": {"phase":3, "element":"HTMLBodyElement",},
"7": {"phase":3, "element":"HTMLHtmlElement",},
},
}
</script>
 
</head>
<body onload="setup()">
<div style="position:absolute; top:0px; left:900px; width:600px; height:500px; border:1px solid black; font-size:12px;">
Reference:<br/>
<ul>
<li><span class="graphical">orange</span> colored boxes = elements that visually appear to the user and can, thus, can probably be interacted with by the user</li>
<li><span class="events">red underlined</span> elements = elements that can receive mouse event interaction from the user. Note: that for html elements (which do not use "pointer-events"), this means all graphically rendered elements.... However, for SVG elements, this means it must be a graphical SVG element &amp; and not have "pointer-events" set to none.</li>
<li>.</li>
<li>"event trigger" - to prevent any possibility for confusion, the special phrase "event trigger" is used. In the context of this document, "event trigger" refers to which element triggers an Event. This will also be the same element contained in the "Event.target" property. Just like normal, events will capture up to this element, then bubble back to the document root from this element. This element will also be the same one listed as the "currentTarget" when the "eventPhase" is 2 (or AT_TARGET).<br/>
"target", "currentTarget", "eventPhase", and "AT_TARGET" are all references to the Event properties as noted here: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event
</li>
<li>.</li>
<li>Conclusion?<br/> It would appear that for an element to be the "event trigger", that two things must happen: (1) The element must be rendered visually &amp; (2) The element must be able to an "event trigger".<br/>However, a key point is that that you must think of html and svg differently in this regards (due to vagueness in the html spec and html implementations on this issue).
<br/>If an element is in the html namespace, there are often lots of little quirks. For example, sometimes certain invisible html elements can be the trigger for an event. None of the rules overide any of these special behaviours from html; html still acts like it always had: it is a separate namespace .
<br/>If an element is in the SVG namespace everything is VERY clearly defined. To be an event trigger: (1) the element MUST be an <a href="http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement">SVG graphical element</a>. SVG graphical elements are the only elements in the SVG namespace that are visible/rendered as something onscreen (you can't interact with something that is not visible/rendered). (2) the element MUST not have "pointer-events" set to none or have a particular aspect of it's "pointer-events" turned off through various pointer-events settings. (*) Thus, to find out which element will be the event trigger in the SVG namespace, you simply make sure it is graphical and has the proper pointer-event settings.
</li>
</ul>
<br/>
<br/>
</div>
 
<div id="test1_div1">
<div id="test1_div2" style="position:absolute; top:0px; left:0px; width:100px; height:100px; background-color:grey; z-index:1;">.</div>
<div style="position:absolute; top:0px; left:100px; width:800px; height:100px; border:1px solid black; font-size:12px;">
Layers:
<span class="graphical events">html</span>
+ <span class="graphical events">body</span>
+ <span class="graphical events">[div2]</span>
+ svg ... (Note: svg is non-graphical, but included for reference.)
<br/>
div should be the event trigger.
<br/>
Although the svg tag is on top of the div tag, svg tags cannot receive an event because they are just like a div with display:none in that they are not visually rendered (except for their children). By this logic (the fact that they render nothing on-screen), svg tags and all non-graphical svg elements are unable to receive an event or interact with the user in any way.</div>
<svg style="position:absolute; top:0px; left:0px; width:100px; height:100px; z-index:2;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" />
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(90,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(180,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(270,50,50)"/>
</svg>
</div>
<div id="test2_div1">
<div id="test2_div2" style="position:absolute; top:100px; left:0px; width:100px; height:100px; background-color:grey; z-index:1;">.</div>
<div style="position:absolute; top:100px; left:100px; width:800px; height:100px; border:1px solid black; font-size:12px;">
Layers:
<span class="graphical events">html</span>
+ <span class="graphical events">body</span>
+ <span class="graphical events">div2</span>
+ svg
+ <span class="graphical events">[rect]</span>
<br/>
rect is the event trigger.</div>
<svg style="position:absolute; top:100px; left:0px; width:100px; height:100px; z-index:2;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="0" y="0" width="100" height="100" fill="grey"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" />
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(90,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(180,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(270,50,50)"/>
</svg>
</div>
<div id="test3_div1">
<div id="test3_div2" style="position:absolute; top:200px; left:0px; width:100px; height:100px; background-color:grey; z-index:1;">.</div>
<div style="position:absolute; top:200px; left:100px; width:800px; height:100px; border:1px solid black; font-size:12px;">
Layers:
<span class="graphical events">html</span>
+ <span class="graphical events">body</span>
+ <span class="graphical events">[div2]</span>
+ svg
+ <span class="graphical">rect(pointer-events=none)</span>
<br/>
div is the event trigger.
<br/>
Rationale: The rect tag is visible (rendered on-screen) and would normally be the target, except that pointer-events is set to none. 16.1 P1 of the SVG spec says: "In other cases, the author might want a given element to ignore pointer events under all circumstances so that graphical elements underneath the given element will become the target of pointer events." By this logic, the event target should "fall through" to what is underneath the rect. However, as described in test1, the svg tag is non-graphical... so the next visible/rendered element as seen from the perspective of the user is the div tag. Thus, the div tag is the event target.</div>
<svg style="position:absolute; top:200px; left:0px; width:100px; height:100px; z-index:2;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="0" y="0" width="100" height="100" fill="grey" pointer-events="none"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" />
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(90,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(180,50,50)"/>
<path d="M 0,0 l 50,0 0,15 -25,10 -10,25 -15,0 z" fill="black" transform="rotate(270,50,50)"/>
</svg>
</div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
Event Capture &amp; Bubbling:
<br/>
The descriptions above merely describe which element will "trigger" an event. Once, an event has been "triggered," standard DOM event capture and bubbling to the "target" that "triggered" the event will proceed as normal through the DOM tree.
<textarea id="result" rows="30" cols="150"></textarea>
</body>
</html>
 

 


From: kevinar18@hotmail.com
CC: www-svg@w3.org
Subject: RE: Should the base svg tag receive events? (testcase)
Date: Mon, 16 Aug 2010 17:44:57 -0400




I did some work on a testcase that maybe covers some of the basics.
 
It only deals with svg in html pages right now.
There are 3 circles that you click on to run the tests in a browser.
 
 
 
 
Some info based on my understanding
 
THE SVG tag
A good way to think about it is an SVG tag is like an div with visibility=none.  Just like an invisible div tag, the svg tag can affect flow in an html page.  Just like an invisible div tag, the actual svg tag renders nothing onto the screen.  Just like an invisible div tag, you can't interact with an svg tag itself (trigger events, context menu, etc...) because nothing is rendered to the screen.
The only difference is that the childen of the svg tag can render themselves to the screen.
 
EVENT TRIGGERS
Within the SVG namespace, for an SVG element (g, rect, etc...)  to be the trigger of an event (the event target), it must exhibit 2 properties:
 
(1) It must be graphical and render to the screen  (Only these elments qualify: http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement)
(2) It must not have pointer-events set to none
 		 	   		  

Received on Monday, 16 August 2010 21:48:30 UTC