| OLD | NEW |
| (Empty) |
| 1 <html xmlns="http://www.w3.org/1999/xhtml"> | |
| 2 <head> | |
| 3 <script src="../../resources/js-test.js"></script> | |
| 4 </head> | |
| 5 <body onload="eventTestOne()"> | |
| 6 | |
| 7 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlin
k" width="100px" height="100px"> | |
| 8 <defs> | |
| 9 <rect id="target" fill="red" width="100" height="100" onclick="eventHandle
r(evt)"/> | |
| 10 </defs> | |
| 11 <use id="test" xlink:href="#target"/> | |
| 12 </svg> | |
| 13 | |
| 14 <p id="description"/> | |
| 15 <div id="console"/> | |
| 16 | |
| 17 <script> | |
| 18 // Setting up the testcase | |
| 19 window.jsTestIsAsync = true; | |
| 20 if (window.testRunner) | |
| 21 testRunner.waitUntilDone(); | |
| 22 | |
| 23 var useElement = document.getElementById("test"); | |
| 24 var rectElement = document.getElementById("target"); | |
| 25 | |
| 26 // Start test immediately, to see wheter instanceRoot is already available, as e
xpected. | |
| 27 description("Test SVG use element specific event handling using SVGElementInstan
ce: "); | |
| 28 debug("'useElement' is the original use element"); | |
| 29 debug("'rectElement' is the original element which gets cloned by the use elemen
t"); | |
| 30 | |
| 31 // Helper functions | |
| 32 function eventHandler(evt) | |
| 33 { | |
| 34 if (evt.type != nextEventType) { | |
| 35 debug("RECEIVED UNEXPECTED EVENT! shouldBe='" + nextEventType + "' was='
" + evt.type + "'"); | |
| 36 return; | |
| 37 } | |
| 38 | |
| 39 currentEvent = evt; | |
| 40 nextEventType = "not yet set"; | |
| 41 eval(eventNotification); | |
| 42 } | |
| 43 | |
| 44 function fireMouseOverEvent(newEventNotification) | |
| 45 { | |
| 46 currentEvent = undefined; | |
| 47 nextEventType = "mouseover"; | |
| 48 eventNotification = newEventNotification; | |
| 49 | |
| 50 if (window.eventSender) { | |
| 51 setTimeout(function() { | |
| 52 eventSender.mouseMoveTo(200, 200); | |
| 53 eventSender.mouseMoveTo(50, 50); | |
| 54 }, 0); | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 function fireMouseClickEvent(newEventNotification) | |
| 59 { | |
| 60 currentEvent = undefined; | |
| 61 nextEventType = "click"; | |
| 62 eventNotification = newEventNotification; | |
| 63 | |
| 64 if (window.eventSender) { | |
| 65 setTimeout(function() { | |
| 66 eventSender.mouseMoveTo(50, 50); | |
| 67 eventSender.mouseDown(); | |
| 68 eventSender.mouseUp(); | |
| 69 }, 0); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 function fireSimulatedMouseOverEvent(newEventNotification, eventTarget) | |
| 74 { | |
| 75 currentEvent = undefined; | |
| 76 nextEventType = "mouseover"; | |
| 77 eventNotification = newEventNotification; | |
| 78 | |
| 79 var event = document.createEvent("MouseEvents"); | |
| 80 event.initMouseEvent(nextEventType, true, true, document.defaultView, 1, 0,
0, 0, 0, false, false, false, false, 0, null); | |
| 81 | |
| 82 eventTarget.dispatchEvent(event); | |
| 83 } | |
| 84 | |
| 85 function fireSimulatedMouseClickEvent(newEventNotification, eventTarget) | |
| 86 { | |
| 87 currentEvent = undefined; | |
| 88 nextEventType = "click"; | |
| 89 eventNotification = newEventNotification; | |
| 90 | |
| 91 var event = document.createEvent("MouseEvents"); | |
| 92 event.initMouseEvent(nextEventType, true, true, document.defaultView, 1, 0,
0, 0, 0, false, false, false, false, 0, null); | |
| 93 | |
| 94 eventTarget.dispatchEvent(event); | |
| 95 } | |
| 96 | |
| 97 function verifyEvent(evtString, targetString, currentTargetString) | |
| 98 { | |
| 99 shouldBeEqualToString("currentEvent.toString()", "[object MouseEvent]"); | |
| 100 shouldBeEqualToString("currentEvent.type.toString()", evtString); | |
| 101 shouldBeEqualToString("currentEvent.target.toString()", targetString); | |
| 102 shouldBeEqualToString("currentEvent.currentTarget.toString()", currentTarget
String); | |
| 103 } | |
| 104 | |
| 105 function verifyMouseOverEvent() | |
| 106 { | |
| 107 verifyEvent("mouseover", "[object SVGElementInstance]", "[object SVGElementI
nstance]"); | |
| 108 | |
| 109 shouldBeTrue("currentEvent.target.correspondingElement == rectElement"); | |
| 110 shouldBeTrue("currentEvent.target.correspondingUseElement == useElement"); | |
| 111 shouldBeTrue("currentEvent.currentTarget.correspondingElement == rectElement
"); | |
| 112 shouldBeTrue("currentEvent.currentTarget.correspondingUseElement == useEleme
nt"); | |
| 113 shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); | |
| 114 shouldBeTrue("currentEvent.target.correspondingElement == currentEvent.curre
ntTarget.correspondingElement"); | |
| 115 shouldBeTrue("currentEvent.target.correspondingUseElement == currentEvent.cu
rrentTarget.correspondingUseElement"); | |
| 116 } | |
| 117 | |
| 118 function verifyClickEvent() | |
| 119 { | |
| 120 verifyEvent("click", "[object SVGElementInstance]", "[object SVGElementInsta
nce]"); | |
| 121 | |
| 122 shouldBeTrue("currentEvent.target.correspondingElement == rectElement"); | |
| 123 shouldBeTrue("currentEvent.target.correspondingUseElement == useElement"); | |
| 124 shouldBeTrue("currentEvent.currentTarget.correspondingElement == rectElement
"); | |
| 125 shouldBeTrue("currentEvent.currentTarget.correspondingUseElement == useEleme
nt"); | |
| 126 shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); | |
| 127 shouldBeTrue("currentEvent.target.correspondingElement == currentEvent.curre
ntTarget.correspondingElement"); | |
| 128 shouldBeTrue("currentEvent.target.correspondingUseElement == currentEvent.cu
rrentTarget.correspondingUseElement"); | |
| 129 } | |
| 130 | |
| 131 function verifyClickEventOnReferenced() | |
| 132 { | |
| 133 verifyEvent("click", "[object SVGRectElement]", "[object SVGRectElement]"); | |
| 134 | |
| 135 shouldBeTrue("currentEvent.target == rectElement"); | |
| 136 shouldBeTrue("currentEvent.currentTarget == rectElement"); | |
| 137 shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); | |
| 138 } | |
| 139 | |
| 140 function checkEventListenerNotReachable() | |
| 141 { | |
| 142 debug(""); | |
| 143 debug("YOU SHOULD NOT SEE THIS TEXT. OTHERWHISE REMOVING EVENT LISTENERS FAI
LED!"); | |
| 144 debug(""); | |
| 145 } | |
| 146 | |
| 147 // Event test sections | |
| 148 function eventTestOne() | |
| 149 { | |
| 150 debug(""); | |
| 151 debug("Test #1: Verify that the use element and the contained SVGElementInst
ance objects are valid"); | |
| 152 debug(""); | |
| 153 | |
| 154 shouldBeEqualToString("useElement.toString()", "[object SVGUseElement]"); | |
| 155 shouldBeEqualToString("useElement.instanceRoot.toString()", "[object SVGElem
entInstance]"); | |
| 156 | |
| 157 shouldBeEqualToString("useElement.instanceRoot.correspondingElement.toString
()", "[object SVGRectElement]"); | |
| 158 shouldBeTrue("useElement.instanceRoot.correspondingElement == rectElement"); | |
| 159 | |
| 160 shouldBeEqualToString("useElement.instanceRoot.correspondingUseElement.toStr
ing()", "[object SVGUseElement]"); | |
| 161 shouldBeTrue("useElement.instanceRoot.correspondingUseElement == useElement"
); | |
| 162 | |
| 163 shouldBeEqualToString("typeof useElement.addEventListener", "function"); | |
| 164 shouldBeEqualToString("typeof useElement.removeEventListener", "function"); | |
| 165 shouldBeEqualToString("typeof useElement.dispatchEvent", "function"); | |
| 166 | |
| 167 // Spec: An element and all its corresponding SVGElementInstance objects sha
re an event | |
| 168 // listener list. The currentTarget attribute of the event can be used to de
termine through | |
| 169 // which object an event listener was invoked. | |
| 170 useElement.instanceRoot.addEventListener("mouseover", eventHandler, false); | |
| 171 fireMouseOverEvent("eventTestTwo()"); | |
| 172 } | |
| 173 | |
| 174 function eventTestTwo() | |
| 175 { | |
| 176 debug(""); | |
| 177 debug("Test #2: Verify that events dispatched to the SVGElementInstance obje
cts have correct target property values"); | |
| 178 debug(""); | |
| 179 | |
| 180 // Spec: The event handling for the non-exposed tree works as if the referen
ced element had been textually included as | |
| 181 // a deeply cloned child of the 'use' element, except that events are dispat
ched to the SVGElementInstance objects. | |
| 182 // The event's target and currentTarget attributes are set to the SVGElement
Instance that corresponds to the target | |
| 183 // and current target elements in the referenced subtree. An event propagate
s through the exposed and non-exposed | |
| 184 // portions of the tree in the same manner as it would in the regular docume
nt tree: first going from the root element | |
| 185 // to the 'use' element and then through non-exposed tree elements in the ca
pture phase, followed by the target phase | |
| 186 // at the target of the event, then bubbling back through non-exposed tree t
o the use element and then back through | |
| 187 // regular tree to the root element in bubbling phase. | |
| 188 verifyMouseOverEvent(); | |
| 189 | |
| 190 useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false
); | |
| 191 fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", useElement.i
nstanceRoot); | |
| 192 fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", rectElement)
; | |
| 193 rectElement.addEventListener("mouseover", eventHandler, false); | |
| 194 | |
| 195 fireMouseOverEvent("eventTestThree()"); | |
| 196 } | |
| 197 | |
| 198 function eventTestThree() | |
| 199 { | |
| 200 debug(""); | |
| 201 debug("Test #3: Verify that events dispatched by the user end up on the SVGE
lementInstance objects"); | |
| 202 debug(""); | |
| 203 | |
| 204 verifyMouseOverEvent(); | |
| 205 | |
| 206 useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false
); | |
| 207 fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", useElement.i
nstanceRoot); | |
| 208 fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", rectElement)
; | |
| 209 fireSimulatedMouseClickEvent("eventTestFour()", rectElement); | |
| 210 } | |
| 211 | |
| 212 function eventTestFour() | |
| 213 { | |
| 214 debug(""); | |
| 215 debug("Test #4: Verify that a click event got dispatched to the original tre
e as defined in the markup, when sent to the 'rectElement'"); | |
| 216 debug(""); | |
| 217 | |
| 218 verifyClickEventOnReferenced(); | |
| 219 | |
| 220 fireSimulatedMouseClickEvent("eventTestFive()", useElement.instanceRoot); | |
| 221 } | |
| 222 | |
| 223 function eventTestFive() | |
| 224 { | |
| 225 debug(""); | |
| 226 debug("Test #5: Verify that a click event got dispatched to the instance tre
e when sent to the 'useElement.instanceRoot' with an event listener attached to
'rectElement'"); | |
| 227 debug(""); | |
| 228 | |
| 229 verifyClickEvent(); | |
| 230 | |
| 231 // This tests a webkit specific quirk: removeAttribute() on the target eleme
nt, causes us to reclone the shadow tree. | |
| 232 // All event listener mutations are synchronized with the shadow tree and do
not cause reclones. So if we add the | |
| 233 // click event listener to the current instanceRoot, remove the existing cli
ck listener from markup and then fire | |
| 234 // a click event, we're sure that the shadow tree is recloned before the eve
ntTestSix() function is executed. | |
| 235 // If eventTestSix() is reached, we've properly preserved the dynamically cr
eated click event listener after recloning. | |
| 236 useElement.instanceRoot.addEventListener("click", eventHandler, false); | |
| 237 rectElement.removeAttribute("onclick"); | |
| 238 | |
| 239 fireMouseClickEvent("eventTestSix()"); | |
| 240 } | |
| 241 | |
| 242 function eventTestSix() | |
| 243 { | |
| 244 debug(""); | |
| 245 debug("Test #6: Verify that the original click event listener got removed an
d a new one attached is attached to the use root SVGElementInstance"); | |
| 246 debug(""); | |
| 247 | |
| 248 verifyClickEvent(); | |
| 249 | |
| 250 useElement.instanceRoot.removeEventListener("click", eventHandler, false); | |
| 251 fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", useElement.
instanceRoot); | |
| 252 fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", rectElement
); | |
| 253 rectElement.addEventListener("click", eventHandler, false); | |
| 254 | |
| 255 fireMouseClickEvent("eventTestSeven()"); | |
| 256 } | |
| 257 | |
| 258 function eventTestSeven() | |
| 259 { | |
| 260 debug(""); | |
| 261 debug("Test #7: Verify that the recreating the original click event listener
dynamically worked and the event is still dispatched to the instance tree"); | |
| 262 debug(""); | |
| 263 | |
| 264 verifyClickEvent(); | |
| 265 | |
| 266 // Prepare for next tests | |
| 267 fireSimulatedMouseClickEvent("eventTestEight()", useElement.instanceRoot); | |
| 268 } | |
| 269 | |
| 270 function eventTestEight() | |
| 271 { | |
| 272 debug(""); | |
| 273 debug("Test #8: Verify that the simulated click event got dispatched to the
right target"); | |
| 274 debug(""); | |
| 275 | |
| 276 verifyClickEvent(); | |
| 277 | |
| 278 // Cleanup | |
| 279 useElement.instanceRoot.removeEventListener("click", eventHandler, false); | |
| 280 fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", useElement.
instanceRoot); | |
| 281 fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", rectElement
); | |
| 282 | |
| 283 // Indicate finish | |
| 284 rectElement.setAttribute("fill", "green"); | |
| 285 | |
| 286 finishJSTest(); | |
| 287 } | |
| 288 </script> | |
| 289 | |
| 290 </body> | |
| 291 </html> | |
| OLD | NEW |