| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <link rel="stylesheet" href="../../fast/js/resources/js-test-style.css"/> |
| <script src="../../fast/js/resources/js-test-pre.js"/> |
| </head> |
| <body> |
| |
| <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"> |
| <defs> |
| <rect id="target" fill="red" width="100" height="100" onclick="eventHandler(evt)"/> |
| </defs> |
| <use id="test" xlink:href="url(#target)"/> |
| </svg> |
| |
| <p id="description"/> |
| <div id="console"/> |
| |
| <script> |
| var currentEvent; |
| var nextEventType; |
| var eventNotification; |
| |
| function eventHandler(evt) |
| { |
| if (evt.type != nextEventType) |
| return; |
| |
| currentEvent = evt; |
| eval(eventNotification); |
| } |
| |
| function fireMouseOverEvent(newEventNotification) |
| { |
| currentEvent = undefined; |
| nextEventType = "mouseover"; |
| eventNotification = newEventNotification; |
| |
| if (window.eventSender) |
| eventSender.mouseMoveTo(50, 50); |
| } |
| |
| function fireMouseClickEvent(newEventNotification) |
| { |
| currentEvent = undefined; |
| nextEventType = "click"; |
| eventNotification = newEventNotification; |
| |
| if (window.eventSender) { |
| eventSender.mouseMoveTo(50, 50); |
| eventSender.mouseDown(); |
| eventSender.mouseUp(); |
| } |
| } |
| |
| function fireSimulatedMouseClickEvent(newEventNotification, eventTarget) |
| { |
| currentEvent = undefined; |
| nextEventType = "click"; |
| eventNotification = newEventNotification; |
| |
| var event = document.createEvent("MouseEvents"); |
| event.initMouseEvent(nextEventType, true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); |
| |
| eventTarget.dispatchEvent(event); |
| } |
| |
| if (window.layoutTestController) |
| layoutTestController.waitUntilDone(); |
| |
| var useElement = document.getElementById("test"); |
| var rectElement = document.getElementById("target"); |
| |
| function verifyEvent(evtString, targetString, currentTargetString) |
| { |
| shouldBeEqualToString("currentEvent.toString()", "[object MouseEvent]"); |
| shouldBeEqualToString("currentEvent.type.toString()", evtString); |
| shouldBeEqualToString("currentEvent.target.toString()", targetString); |
| shouldBeEqualToString("currentEvent.currentTarget.toString()", currentTargetString); |
| } |
| |
| function verifyMouseOverEvent() |
| { |
| verifyEvent("mouseover", "[object SVGElementInstance]", "[object SVGElementInstance]"); |
| |
| shouldBeTrue("currentEvent.target.correspondingElement == rectElement"); |
| shouldBeTrue("currentEvent.target.correspondingUseElement == useElement"); |
| shouldBeTrue("currentEvent.currentTarget.correspondingElement == rectElement"); |
| shouldBeTrue("currentEvent.currentTarget.correspondingUseElement == useElement"); |
| shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); |
| shouldBeTrue("currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement"); |
| shouldBeTrue("currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement"); |
| } |
| |
| function verifyClickEvent() |
| { |
| verifyEvent("click", "[object SVGElementInstance]", "[object SVGElementInstance]"); |
| |
| shouldBeTrue("currentEvent.target.correspondingElement == rectElement"); |
| shouldBeTrue("currentEvent.target.correspondingUseElement == useElement"); |
| shouldBeTrue("currentEvent.currentTarget.correspondingElement == rectElement"); |
| shouldBeTrue("currentEvent.currentTarget.correspondingUseElement == useElement"); |
| shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); |
| shouldBeTrue("currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement"); |
| shouldBeTrue("currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement"); |
| } |
| |
| function verifyClickEventOnReferenced() |
| { |
| verifyEvent("click", "[object SVGRectElement]", "[object SVGRectElement]"); |
| |
| shouldBeTrue("currentEvent.target == rectElement"); |
| shouldBeTrue("currentEvent.currentTarget == rectElement"); |
| shouldBeTrue("currentEvent.target == currentEvent.currentTarget"); |
| } |
| |
| description("Test SVG use element specific event handling using SVGElementInstance: "); |
| debug("'useElement' is the original use element"); |
| debug("'rectElement' is the original element which gets cloned by the use element"); |
| |
| debug(""); |
| debug("Test #1: Verify that the use element and the contained SVGElementInstance objects are valid"); |
| debug(""); |
| |
| shouldBeEqualToString("useElement.toString()", "[object SVGUseElement]"); |
| shouldBeEqualToString("useElement.instanceRoot.toString()", "[object SVGElementInstance]"); |
| |
| shouldBeEqualToString("useElement.instanceRoot.correspondingElement.toString()", "[object SVGRectElement]"); |
| shouldBeTrue("useElement.instanceRoot.correspondingElement == rectElement"); |
| |
| shouldBeEqualToString("useElement.instanceRoot.correspondingUseElement.toString()", "[object SVGUseElement]"); |
| shouldBeTrue("useElement.instanceRoot.correspondingUseElement == useElement"); |
| |
| shouldBeEqualToString("typeof useElement.addEventListener", "function"); |
| shouldBeEqualToString("typeof useElement.removeEventListener", "function"); |
| shouldBeEqualToString("typeof useElement.dispatchEvent", "function"); |
| |
| // Spec: An element and all its corresponding SVGElementInstance objects share an event |
| // listener list. The currentTarget attribute of the event can be used to determine through |
| // which object an event listener was invoked. |
| useElement.instanceRoot.addEventListener("mouseover", eventHandler, false); |
| |
| function startEventTests() |
| { |
| debug(""); |
| debug("Test #2: Verify that events dispatched to the SVGElementInstance objects have correct target property values"); |
| debug(""); |
| |
| // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included as |
| // a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects. |
| // The event's target and currentTarget attributes are set to the SVGElementInstance that corresponds to the target |
| // and current target elements in the referenced subtree. An event propagates through the exposed and non-exposed |
| // portions of the tree in the same manner as it would in the regular document tree: first going from the root element |
| // to the 'use' element and then through non-exposed tree elements in the capture phase, followed by the target phase |
| // at the target of the event, then bubbling back through non-exposed tree to the use element and then back through |
| // regular tree to the root element in bubbling phase. |
| verifyMouseOverEvent(); |
| |
| // Prepare for next test |
| useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false); |
| useElement.instanceRoot.addEventListener("mouseover", eventHandler, false); |
| |
| // Causes svgAttributeChanged() logic to reclone the shadow tree |
| // If 'Test #3' is not executed, then it didn't properly reclone the event listeners. |
| useElement.instanceRoot.correspondingElement.setAttribute("x", useElement.instanceRoot.correspondingElement.getAttribute("x")); |
| |
| fireMouseOverEvent("eventTestOne()"); |
| } |
| |
| function eventTestOne() |
| { |
| debug(""); |
| debug("Test #3: Verify that event listeners attached to the shadow tree elements are copied when use reclones the internal shadow tree"); |
| debug(""); |
| |
| // Spec: If event attributes are assigned to referenced elements, then the actual target for the event will be the |
| // SVGElementInstance object within the "instance tree" corresponding to the given referenced element. |
| verifyMouseOverEvent(); |
| |
| // Prepare for next test |
| useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false); |
| rectElement.addEventListener("mouseover", eventHandler, false); |
| |
| fireMouseOverEvent("eventTestTwo()"); |
| } |
| |
| function eventTestTwo() |
| { |
| debug(""); |
| debug("Test #4: Verify that events dispatched to the referenced element end up on the SVElementInstance objects"); |
| debug(""); |
| |
| verifyMouseOverEvent(); |
| |
| // Prepare for next test |
| rectElement.removeEventListener("mouseover", eventHandler, false); |
| rectElement.addEventListener("mouseover", eventHandler, false); |
| |
| // Causes svgAttributeChanged() logic to reclone the shadow tree |
| // If 'Test #5' is not executed, then it didn't properly reclone the event listeners. |
| rectElement.setAttribute("x", rectElement.getAttribute("x")); |
| |
| fireMouseOverEvent("eventTestThree()"); |
| } |
| |
| function eventTestThree() |
| { |
| debug(""); |
| debug("Test #5: Verify that event listeners attached to the referenced elements are copied when use reclones the internal shadow tree"); |
| debug(""); |
| |
| verifyMouseOverEvent(); |
| |
| // Prepare for next test |
| rectElement.removeEventListener("mouseover", eventHandler, false); |
| |
| fireSimulatedMouseClickEvent("eventTestFour()", rectElement); |
| } |
| |
| function eventTestFour() |
| { |
| debug(""); |
| debug("Test #6: Verify that a click event got dispatched to the original tree as defined in the markup, when sent to the 'rectElement'"); |
| debug(""); |
| |
| verifyClickEventOnReferenced(); |
| |
| // Prepare for next test |
| fireSimulatedMouseClickEvent("eventTestFive()", useElement.instanceRoot); |
| } |
| |
| function eventTestFive() |
| { |
| debug(""); |
| debug("Test #7: Verify that a click event got dispatched to the instance tree when sent to the 'useElement.instanceRoot' with an event listener attached to 'rectElement'"); |
| debug(""); |
| |
| verifyClickEvent(); |
| |
| // Prepare for next test |
| fireMouseClickEvent("eventTestSix()"); |
| } |
| |
| function eventTestSix() |
| { |
| debug(""); |
| debug("Test #8: Verify that the original click event listener defined in markup is still working properly"); |
| debug(""); |
| |
| verifyClickEvent(); |
| |
| // Prepare for next test |
| rectElement.removeEventListener("click", eventHandler, false); |
| useElement.instanceRoot.addEventListener("click", eventHandler, false); |
| |
| fireMouseClickEvent("eventTestSeven()"); |
| } |
| |
| function eventTestSeven() |
| { |
| debug(""); |
| debug("Test #9: Verify that the original click event listener got removed and a new one attached to the use root SVGElementInstance"); |
| debug(""); |
| |
| verifyClickEvent(); |
| |
| // Prepare for next tests |
| fireSimulatedMouseClickEvent("eventTestEight()", useElement.instanceRoot); |
| } |
| |
| function eventTestEight() |
| { |
| debug(""); |
| debug("Test #10: Verify that the simulated click event got dispatched to the right target"); |
| debug(""); |
| |
| verifyClickEvent(); |
| |
| // Cleanup |
| useElement.instanceRoot.removeEventListener("click", eventHandler, false); |
| |
| stopEventTests(); |
| } |
| |
| function stopEventTests() |
| { |
| successfullyParsed = true; |
| |
| rectElement.setAttribute("fill", "green"); |
| shouldBeTrue("successfullyParsed"); |
| debug('<br /><span class="pass">TEST COMPLETE</span>'); |
| |
| if (window.layoutTestController) |
| layoutTestController.notifyDone(); |
| } |
| |
| fireMouseOverEvent("startEventTests()"); |
| </script> |
| |
| </body> |
| </html> |