/* global QUnit, $, TouchUtil, Util, testLog */ (function () { var viewer; QUnit.module("Events", { beforeEach: function () { $('
').appendTo("#qunit-fixture"); testLog.reset(); viewer = OpenSeadragon({ id: "eventsexample", prefixUrl: "/build/openseadragon/images/", springStiffness: 100, // Faster animation = faster tests }); }, afterEach: function () { if (viewer && viewer.close) { viewer.close(); } viewer = null; }, }); // ---------- QUnit.test("MouseTracker: mouse gestures", function (assert) { var done = assert.async(); var $canvas = $(viewer.element) .find(".openseadragon-canvas") .not(".navigator .openseadragon-canvas"), simEvent = {}, offset = $canvas.offset(), tracker = viewer.innerTracker, origEnterHandler, origLeaveHandler, origPressHandler, origReleaseHandler, origNonPrimaryPressHandler, origNonPrimaryReleaseHandler, origMoveHandler, origClickHandler, origDblClickHandler, origDragHandler, origDragEndHandler, enterCount, leaveCount, pressCount, releaseCount, rightPressCount, rightReleaseCount, middlePressCount, middleReleaseCount, moveCount, clickCount, dblClickCount, dragCount, dragEndCount, insideElementPressed, insideElementReleased, quickClick, speed, direction; var hookViewerHandlers = function () { origEnterHandler = tracker.enterHandler; tracker.enterHandler = function (event) { enterCount++; if (origEnterHandler) { return origEnterHandler(event); } else { return true; } }; origLeaveHandler = tracker.leaveHandler; tracker.leaveHandler = function (event) { leaveCount++; if (origLeaveHandler) { return origLeaveHandler(event); } else { return true; } }; origPressHandler = tracker.pressHandler; tracker.pressHandler = function (event) { pressCount++; if (origPressHandler) { return origPressHandler(event); } else { return true; } }; origReleaseHandler = tracker.releaseHandler; tracker.releaseHandler = function (event) { releaseCount++; insideElementPressed = event.insideElementPressed; insideElementReleased = event.insideElementReleased; if (origReleaseHandler) { return origReleaseHandler(event); } else { return true; } }; origNonPrimaryPressHandler = tracker.nonPrimaryPressHandler; tracker.nonPrimaryPressHandler = function (event) { if (event.button === 0) { pressCount++; } else if (event.button === 1) { middlePressCount++; } else if (event.button === 2) { rightPressCount++; } if (origNonPrimaryPressHandler) { return origNonPrimaryPressHandler(event); } else { return true; } }; origNonPrimaryReleaseHandler = tracker.nonPrimaryReleaseHandler; tracker.nonPrimaryReleaseHandler = function (event) { if (event.button === 0) { releaseCount++; } else if (event.button === 1) { middleReleaseCount++; } else if (event.button === 2) { rightReleaseCount++; } if (origNonPrimaryReleaseHandler) { return origNonPrimaryReleaseHandler(event); } else { return true; } }; origMoveHandler = tracker.moveHandler; tracker.moveHandler = function (event) { moveCount++; if (origMoveHandler) { return origMoveHandler(event); } else { return true; } }; origClickHandler = tracker.clickHandler; tracker.clickHandler = function (event) { clickCount++; quickClick = event.quick; if (origClickHandler) { return origClickHandler(event); } else { return true; } }; origDblClickHandler = tracker.dblClickHandler; tracker.dblClickHandler = function (event) { dblClickCount++; if (origDblClickHandler) { return origDblClickHandler(event); } else { return true; } }; origDragHandler = tracker.dragHandler; tracker.dragHandler = function (event) { dragCount++; if (origDragHandler) { return origDragHandler(event); } else { return true; } }; origDragEndHandler = tracker.dragEndHandler; tracker.dragEndHandler = function (event) { dragEndCount++; speed = event.speed; direction = event.direction; if (origDragEndHandler) { return origDragEndHandler(event); } else { return true; } }; }; var unhookViewerHandlers = function () { tracker.enterHandler = origEnterHandler; tracker.leaveHandler = origLeaveHandler; tracker.pressHandler = origPressHandler; tracker.releaseHandler = origReleaseHandler; tracker.moveHandler = origMoveHandler; tracker.clickHandler = origClickHandler; tracker.dblClickHandler = origDblClickHandler; tracker.dragHandler = origDragHandler; tracker.dragEndHandler = origDragEndHandler; }; var simulateEnter = function (x, y) { simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; $canvas.simulate("mouseenter", simEvent); }; var simulateLeave = function (x, y) { simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; simEvent.relatedTarget = document.body; $canvas.simulate("mouseleave", simEvent); }; //var simulateLeaveFrame = function (x, y) { // simEvent.clientX = offset.left + x; // simEvent.clientY = offset.top + y; // simEvent.relatedTarget = document.getElementsByTagName("html")[0]; // $canvas.simulate( 'mouseleave', simEvent ); //}; var simulateDown = function (x, y) { simEvent.button = 0; simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; $canvas.simulate("mousedown", simEvent); }; var simulateUp = function (x, y) { simEvent.button = 0; simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; $canvas.simulate("mouseup", simEvent); }; var simulateNonPrimaryDown = function (x, y, button) { simEvent.button = button; simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; $canvas.simulate("mousedown", simEvent); }; var simulateNonPrimaryUp = function (x, y, button) { simEvent.button = button; simEvent.clientX = offset.left + x; simEvent.clientY = offset.top + y; $canvas.simulate("mouseup", simEvent); }; var simulateMove = function (dX, dY, count) { var i; for (i = 0; i < count; i++) { simEvent.clientX += dX; simEvent.clientY += dY; $canvas.simulate("mousemove", simEvent); } }; var resetForAssessment = function () { simEvent = { button: 0, clientX: offset.left, clientY: offset.top, }; enterCount = 0; leaveCount = 0; pressCount = 0; releaseCount = 0; rightPressCount = 0; rightReleaseCount = 0; middlePressCount = 0; middleReleaseCount = 0; moveCount = 0; clickCount = 0; dblClickCount = 0; dragCount = 0; dragEndCount = 0; insideElementPressed = false; insideElementReleased = false; quickClick = false; speed = 0; direction = 2 * Math.PI; }; var assessGestureExpectations = function (expected) { var pointersList = tracker.getActivePointersListByType("mouse"); if ("enterCount" in expected) { assert.equal( enterCount, expected.enterCount, expected.description + "enterHandler event count matches expected (" + expected.enterCount + ")" ); } if ("leaveCount" in expected) { assert.equal( leaveCount, expected.leaveCount, expected.description + "leaveHandler event count matches expected (" + expected.leaveCount + ")" ); } if ("pressCount" in expected) { assert.equal( pressCount, expected.pressCount, expected.description + "pressHandler event count matches expected (" + expected.pressCount + ")" ); } if ("releaseCount" in expected) { assert.equal( releaseCount, expected.releaseCount, expected.description + "releaseHandler event count matches expected (" + expected.releaseCount + ")" ); } if ("rightPressCount" in expected) { assert.equal( rightPressCount, expected.rightPressCount, expected.description + "nonPrimaryPressHandler event count (secondary/right button) matches expected (" + expected.rightPressCount + ")" ); } if ("rightReleaseCount" in expected) { assert.equal( rightReleaseCount, expected.rightReleaseCount, expected.description + "nonPrimaryReleaseHandler event count (secondary/right button) matches expected (" + expected.rightReleaseCount + ")" ); } if ("middlePressCount" in expected) { assert.equal( middlePressCount, expected.middlePressCount, expected.description + "nonPrimaryPressHandler event count (aux/middle button) matches expected (" + expected.middlePressCount + ")" ); } if ("middleReleaseCount" in expected) { assert.equal( middleReleaseCount, expected.middleReleaseCount, expected.description + "nonPrimaryReleaseHandler event count (aux/middle button) matches expected (" + expected.middleReleaseCount + ")" ); } if ("moveCount" in expected) { assert.equal( moveCount, expected.moveCount, expected.description + "moveHandler event count matches expected (" + expected.moveCount + ")" ); } if ("clickCount" in expected) { assert.equal( clickCount, expected.clickCount, expected.description + "clickHandler event count matches expected (" + expected.clickCount + ")" ); } if ("dblClickCount" in expected) { assert.equal( dblClickCount, expected.dblClickCount, expected.description + "dblClickHandler event count matches expected (" + expected.dblClickCount + ")" ); } if ("dragCount" in expected) { assert.equal( dragCount, expected.dragCount, expected.description + "dragHandler event count matches expected (" + expected.dragCount + ")" ); } if ("dragEndCount" in expected) { assert.equal( dragEndCount, expected.dragEndCount, expected.description + "dragEndHandler event count matches expected (" + expected.dragEndCount + ")" ); } if ("insideElementPressed" in expected) { assert.equal( insideElementPressed, expected.insideElementPressed, expected.description + "releaseHandler event.insideElementPressed matches expected (" + expected.insideElementPressed + ")" ); } if ("insideElementReleased" in expected) { assert.equal( insideElementReleased, expected.insideElementReleased, expected.description + "releaseHandler event.insideElementReleased matches expected (" + expected.insideElementReleased + ")" ); } if ("contacts" in expected) { assert.equal( pointersList.contacts, expected.contacts, expected.description + "Remaining pointer contact count matches expected (" + expected.contacts + ")" ); } if ("trackedPointers" in expected) { assert.equal( pointersList.getLength(), expected.trackedPointers, expected.description + "Remaining tracked pointer count matches expected (" + expected.trackedPointers + ")" ); } if ("quickClick" in expected) { assert.equal( quickClick, expected.quickClick, expected.description + "clickHandler event.quick matches expected (" + expected.quickClick + ")" ); } if ("speed" in expected) { Util.assessNumericValue( expected.speed, speed, 1.0, expected.description + "Drag speed " ); } if ("direction" in expected) { Util.assessNumericValue( expected.direction, direction, 0.2, expected.description + "Drag direction " ); } }; var onOpen = function (event) { viewer.removeHandler("open", onOpen); hookViewerHandlers(); // enter-move-release (release in tracked element, press in unknown element) // (Note we also test to see if the pointer is still being tracked by not simulating a leave event until after assessment) resetForAssessment(); simulateEnter(0, 0); simulateMove(1, 1, 10); simulateMove(-1, -1, 10); simulateUp(0, 0); assessGestureExpectations({ description: "enter-move-release (release in tracked element, press in unknown element): ", enterCount: 1, leaveCount: 0, pressCount: 0, releaseCount: 1, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 20, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, insideElementPressed: false, insideElementReleased: true, contacts: 0, trackedPointers: 1, //quickClick: false }); simulateLeave(-1, -1); // flush tracked pointer // enter-move-leave (fly-over) resetForAssessment(); simulateEnter(0, 0); simulateMove(1, 1, 10); simulateMove(-1, -1, 10); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-move-leave (fly-over): ", enterCount: 1, leaveCount: 1, pressCount: 0, releaseCount: 0, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 20, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, //insideElementPressed: false, //insideElementReleased: false, contacts: 0, trackedPointers: 0, //quickClick: false }); // move-leave (fly-over, no enter event) resetForAssessment(); simulateMove(1, 1, 10); simulateMove(-1, -1, 10); simulateLeave(-1, -1); assessGestureExpectations({ description: "move-leave (fly-over, no enter event): ", enterCount: 0, leaveCount: 1, pressCount: 0, releaseCount: 0, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 20, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, //insideElementPressed: false, //insideElementReleased: false, contacts: 0, trackedPointers: 0, //quickClick: false }); // enter-press-release-press-release-leave (primary/left double click) resetForAssessment(); simulateEnter(0, 0); simulateDown(0, 0); simulateUp(0, 0); simulateDown(0, 0); simulateUp(0, 0); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-press-release-press-release-leave (primary/left double click): ", enterCount: 1, leaveCount: 1, pressCount: 2, releaseCount: 2, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 0, clickCount: 2, dblClickCount: 1, dragCount: 0, dragEndCount: 2, // v2.5.0+ drag-end event now fired even if pointer didn't move (#1459) insideElementPressed: true, insideElementReleased: true, contacts: 0, trackedPointers: 0, //quickClick: true }); // enter-press-release-leave (primary/left click) resetForAssessment(); simulateEnter(0, 0); simulateDown(0, 0); simulateUp(0, 0); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-press-release-leave (primary/left click): ", enterCount: 1, leaveCount: 1, pressCount: 1, releaseCount: 1, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 0, clickCount: 1, dblClickCount: 0, dragCount: 0, dragEndCount: 1, // v2.5.0+ drag-end event now fired even if pointer didn't move (#1459) insideElementPressed: true, insideElementReleased: true, contacts: 0, trackedPointers: 0, quickClick: true, }); // enter-nonprimarypress-nonprimaryrelease-leave (secondary/right click) resetForAssessment(); simulateEnter(0, 0); simulateNonPrimaryDown(0, 0, 2); simulateNonPrimaryUp(0, 0, 2); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-nonprimarypress-nonprimaryrelease-leave (secondary/right click): ", enterCount: 1, leaveCount: 1, pressCount: 0, releaseCount: 0, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, middleReleaseCount: 0, moveCount: 0, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, //insideElementPressed: true, //insideElementReleased: true, contacts: 0, trackedPointers: 0, //quickClick: true }); // enter-nonprimarypress-nonprimaryrelease-leave (aux/middle click) resetForAssessment(); simulateEnter(0, 0); simulateNonPrimaryDown(0, 0, 1); simulateNonPrimaryUp(0, 0, 1); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-nonprimarypress-nonprimaryrelease-leave (aux/middle click): ", enterCount: 1, leaveCount: 1, pressCount: 0, releaseCount: 0, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 1, middleReleaseCount: 1, moveCount: 0, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, //insideElementPressed: true, //insideElementReleased: true, contacts: 0, trackedPointers: 0, //quickClick: true }); // enter-nonprimarypress-move-nonprimaryrelease-move-leave (secondary/right button drag, release in tracked element) resetForAssessment(); simulateEnter(0, 0); simulateNonPrimaryDown(0, 0, 2); simulateMove(1, 1, 100); simulateNonPrimaryUp(10, 10, 2); simulateMove(-1, -1, 100); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-nonprimarypress-move-nonprimaryrelease-move-leave (secondary/right button drag, release in tracked element): ", enterCount: 1, leaveCount: 1, pressCount: 0, releaseCount: 0, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, middleReleaseCount: 0, moveCount: 200, clickCount: 0, dblClickCount: 0, dragCount: 0, dragEndCount: 0, //insideElementPressed: true, //insideElementReleased: true, contacts: 0, trackedPointers: 0, //quickClick: false }); // enter-press-move-release-move-leave (drag, release in tracked element) resetForAssessment(); simulateEnter(0, 0); simulateDown(0, 0); simulateMove(1, 1, 100); simulateUp(10, 10); simulateMove(-1, -1, 100); simulateLeave(-1, -1); assessGestureExpectations({ description: "enter-press-move-release-move-leave (drag, release in tracked element): ", enterCount: 1, leaveCount: 1, pressCount: 1, releaseCount: 1, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 200, clickCount: 1, dblClickCount: 0, dragCount: 100, dragEndCount: 1, insideElementPressed: true, insideElementReleased: true, contacts: 0, trackedPointers: 0, quickClick: false, }); // enter-press-move-leave-move-release (drag, release outside tracked element) resetForAssessment(); simulateEnter(0, 0); simulateDown(0, 0); simulateMove(1, 1, 5); simulateMove(-1, -1, 5); simulateLeave(-1, -1); simulateMove(-1, -1, 5); simulateUp(-5, -5); assessGestureExpectations({ description: "enter-press-move-leave-move-release (drag, release outside tracked element): ", enterCount: 1, leaveCount: 1, pressCount: 1, releaseCount: 1, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 0, middleReleaseCount: 0, moveCount: 15, clickCount: 0, dblClickCount: 0, dragCount: 15, dragEndCount: 1, insideElementPressed: true, insideElementReleased: false, contacts: 0, trackedPointers: 0, quickClick: false, }); //// enter-press-move-leave-move-release-outside (drag, release outside iframe) //resetForAssessment(); //simulateEnter(0, 0); //simulateDown(0, 0); //simulateMove(1, 1, 5); //simulateMove(-1, -1, 5); //simulateLeaveFrame(-1, -1); //// you don't actually receive the mouseup if you mouseup outside of the document //assessGestureExpectations({ // description: 'enter-press-move-leave-move-release-outside (drag, release outside iframe): ', // enterCount: 1, // leaveCount: 1, // pressCount: 1, // releaseCount: 1, // rightPressCount: 0, // rightReleaseCount: 0, // middlePressCount: 0, // middleReleaseCount: 0, // moveCount: 10, // clickCount: 0, // dblClickCount: 0, // dragCount: 10, // dragEndCount: 1, // insideElementPressed: true, // insideElementReleased: false, // contacts: 0, // trackedPointers: 0, // quickClick: false //}); unhookViewerHandlers(); viewer.close(); done(); }; viewer.addHandler("open", onOpen); viewer.open("/test/data/testpattern.dzi"); }); // ---------- if ("TouchEvent" in window) { QUnit.test("MouseTracker: touch events", function (assert) { var done = assert.async(); var tracker = viewer.innerTracker, touches; var reset = function () { touches = []; TouchUtil.reset(); }; var assessTouchExpectations = function (expected) { var pointersList = tracker.getActivePointersListByType("touch"); if ("captureCount" in expected) { assert.equal( pointersList.captureCount, expected.captureCount, expected.description + "Pointer capture count matches expected (" + expected.captureCount + ")" ); } if ("contacts" in expected) { assert.equal( pointersList.contacts, expected.contacts, expected.description + "Pointer contact count matches expected (" + expected.contacts + ")" ); } if ("trackedPointers" in expected) { assert.equal( pointersList.getLength(), expected.trackedPointers, expected.description + "Tracked pointer count matches expected (" + expected.trackedPointers + ")" ); } }; var onOpen = function (event) { viewer.removeHandler("open", onOpen); TouchUtil.initTracker(tracker); // start-end-end (multi-touch start event) reset(); touches = TouchUtil.start([0, 0], [20, 20]); assessTouchExpectations({ description: "start-end-end (multi-touch start event) [capture]: ", captureCount: 2, contacts: 2, trackedPointers: 2, }); TouchUtil.end(touches[1]); TouchUtil.end(touches[0]); assessTouchExpectations({ description: "start-end-end (multi-touch start event) [release]: ", captureCount: 0, contacts: 0, trackedPointers: 0, }); // start-start-end (multi-touch end event) reset(); touches.push(TouchUtil.start([0, 0])); touches.push(TouchUtil.start([20, 20])); assessTouchExpectations({ description: "start-start-end (multi-touch end event) [capture]: ", captureCount: 2, contacts: 2, trackedPointers: 2, }); TouchUtil.end(touches); assessTouchExpectations({ description: "start-start-end (multi-touch end event) [release]: ", captureCount: 0, contacts: 0, trackedPointers: 0, }); TouchUtil.resetTracker(tracker); viewer.close(); done(); }; viewer.addHandler("open", onOpen); viewer.open("/test/data/testpattern.dzi"); }); } // ---------- QUnit.test("Viewer: preventDefaultAction", function (assert) { var done = assert.async(); var $canvas = $(viewer.element) .find(".openseadragon-canvas") .not(".navigator .openseadragon-canvas"); //var tracker = viewer.innerTracker; var epsilon = 0.0000001; function simulateClickAndDrag() { $canvas.simulate("focus"); // Drag to pan Util.simulateViewerClickWithDrag({ viewer: viewer, widthFactor: 0.25, heightFactor: 0.25, dragCount: 10, dragDx: 1, dragDy: 1, }); // Click to zoom Util.simulateViewerClickWithDrag({ viewer: viewer, widthFactor: 0.25, heightFactor: 0.25, dragCount: 0, dragDx: 0, dragDy: 0, }); $canvas.simulate("blur"); } var onOpen = function () { viewer.removeHandler("open", onOpen); // Hook viewer events to set preventDefaultAction var onCanvasClick = function (event) { event.preventDefaultAction = true; }; var onCanvasDrag = function (event) { event.preventDefaultAction = true; }; viewer.addHandler("canvas-click", onCanvasClick); viewer.addHandler("canvas-drag", onCanvasDrag); var originalZoom = viewer.viewport.getZoom(); var originalBounds = viewer.viewport.getBounds(); simulateClickAndDrag(); var zoom = viewer.viewport.getZoom(); var bounds = viewer.viewport.getBounds(); Util.assessNumericValue( assert, zoom, originalZoom, epsilon, "Zoom should be prevented" ); Util.assertRectangleEquals( assert, bounds, originalBounds, epsilon, "Pan should be prevented" ); viewer.removeHandler("canvas-click", onCanvasClick); viewer.removeHandler("canvas-drag", onCanvasDrag); simulateClickAndDrag(); zoom = viewer.viewport.getZoom(); bounds = viewer.viewport.getBounds(); Util.assessNumericValue( assert, zoom, 0.002, epsilon, "Zoom should not be prevented" ); Util.assertRectangleEquals( assert, new OpenSeadragon.Rect(-249.5, -0.25, 500, 0.5), bounds, epsilon, "Pan should not be prevented" ); viewer.close(); done(); }; viewer.addHandler("open", onOpen); viewer.open("/test/data/testpattern.dzi"); }); // ---------- QUnit.test( "Viewer: preventDefaultAction in dblClickHandler", function (assert) { var done = assert.async(); var tracker = viewer.innerTracker; var epsilon = 0.0000001; function simulateDblTap() { var touches = []; TouchUtil.reset(); touches.push(TouchUtil.start([0, 0])); TouchUtil.end(touches[0]); touches.push(TouchUtil.start([0, 0])); TouchUtil.end(touches[1]); } var onOpen = function () { viewer.removeHandler("open", onOpen); var originalZoom = viewer.viewport.getZoom(); var onCanvasDblClick = function (event) { event.preventDefaultAction = true; }; viewer.addHandler("canvas-double-click", onCanvasDblClick); TouchUtil.initTracker(tracker); simulateDblTap(); var zoom = viewer.viewport.getZoom(); Util.assessNumericValue( assert, originalZoom, zoom, epsilon, "Zoom on double tap should be prevented" ); // Reset event handler to original viewer.removeHandler("canvas-double-click", onCanvasDblClick); simulateDblTap(); originalZoom *= viewer.zoomPerClick; zoom = viewer.viewport.getZoom(); Util.assessNumericValue( assert, originalZoom, zoom, epsilon, "Zoom on double tap should not be prevented" ); TouchUtil.resetTracker(tracker); viewer.close(); done(); }; viewer.addHandler("open", onOpen); viewer.open("/test/data/testpattern.dzi"); } ); // ---------- QUnit.test( "EventSource/MouseTracker/Viewer: event.originalEvent event.userData canvas-drag canvas-drag-end canvas-release canvas-click", function (assert) { var done = assert.async(); var $canvas = $(viewer.element) .find(".openseadragon-canvas") .not(".navigator .openseadragon-canvas"), mouseTracker = null, userData = { item1: "Test user data", item2: Math.random() }, originalUserData = { item1: userData.item1, item2: userData.item2, }, dragCount = 10, dragsHandledEventSource = 0, dragEndsHandledEventSource = 0, releasesHandledEventSource = 0, clicksHandledEventSource = 0, eventsHandledMouseTracker = 0, eventSourcePassedMouseTracker = 0, originalEventsPassedMouseTracker = 0, eventsHandledViewer = 0, originalEventsPassedViewer = 0, dragEndsExpected = 1, releasesExpected = 1; var onOpen = function () { viewer.removeHandler("open", onOpen); viewer.addHandler("canvas-drag", onEventSourceDrag); viewer.addHandler("canvas-drag-end", onEventSourceDragEnd); viewer.addHandler("canvas-release", onEventSourceRelease); viewer.addHandler("canvas-click", onEventSourceClick); mouseTracker = new OpenSeadragon.MouseTracker({ element: $canvas[0], userData: userData, clickTimeThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickTimeThreshold, clickDistThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickDistThreshold, dblClickTimeThreshold: OpenSeadragon.DEFAULT_SETTINGS.dblClickTimeThreshold, dblClickDistThreshold: OpenSeadragon.DEFAULT_SETTINGS.dblClickDistThreshold, focusHandler: onMouseTrackerFocus, blurHandler: onMouseTrackerBlur, enterHandler: onMouseTrackerEnter, pressHandler: onMouseTrackerPress, moveHandler: onMouseTrackerMove, dragHandler: onMouseTrackerDrag, dragEndHandler: onMouseTrackerDragEnd, releaseHandler: onMouseTrackerRelease, clickHandler: onMouseTrackerClick, leaveHandler: onMouseTrackerLeave, }); var event = { clientX: 1, clientY: 1, }; $canvas.simulate("focus", event); Util.simulateViewerClickWithDrag({ viewer: viewer, widthFactor: 0.25, heightFactor: 0.25, dragCount: dragCount, dragDx: 1, dragDy: 1, }); $canvas.simulate("blur", event); }; var checkOriginalEventReceivedViewer = function (event) { eventsHandledViewer++; //TODO Provide a better check for the original event...simulate doesn't currently extend the object // with arbitrary user data. if (event && event.originalEvent) { originalEventsPassedViewer++; } }; var onEventSourceDrag = function (event) { checkOriginalEventReceivedViewer(event); dragsHandledEventSource++; }; var onEventSourceDragEnd = function (event) { checkOriginalEventReceivedViewer(event); dragEndsHandledEventSource++; }; var onEventSourceRelease = function (event) { checkOriginalEventReceivedViewer(event); releasesHandledEventSource++; }; var onEventSourceClick = function (event) { checkOriginalEventReceivedViewer(event); clicksHandledEventSource++; }; var checkOriginalEventReceived = function (event) { eventsHandledMouseTracker++; if (event && event.eventSource === mouseTracker) { eventSourcePassedMouseTracker++; } //TODO Provide a better check for the original event...simulate doesn't currently extend the object // with arbitrary user data. if (event && event.originalEvent) { originalEventsPassedMouseTracker++; } }; var onMouseTrackerFocus = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerBlur = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerEnter = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerPress = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerMove = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerDrag = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerDragEnd = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerRelease = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerClick = function (event) { checkOriginalEventReceived(event); }; var onMouseTrackerLeave = function (event) { checkOriginalEventReceived(event); mouseTracker.destroy(); viewer.removeHandler("canvas-drag", onEventSourceDrag); viewer.removeHandler("canvas-release", onEventSourceRelease); viewer.removeHandler("canvas-click", onEventSourceClick); assert.equal( dragsHandledEventSource, dragCount, "'canvas-drag' event count matches 'mousemove' event count (" + dragCount + ")" ); assert.equal( dragEndsHandledEventSource, dragEndsExpected, "'canvas-drag-end' event count matches expected (" + dragEndsExpected + ")" ); assert.equal( releasesHandledEventSource, releasesExpected, "'canvas-release' event count matches expected (" + releasesExpected + ")" ); assert.equal( clicksHandledEventSource, releasesExpected, "'canvas-click' event count matches expected (" + releasesExpected + ")" ); assert.equal( originalEventsPassedViewer, eventsHandledViewer, "Original event received count matches expected (" + eventsHandledViewer + ")" ); assert.equal( eventSourcePassedMouseTracker, eventsHandledMouseTracker, "Event source received count matches expected (" + eventsHandledMouseTracker + ")" ); assert.equal( originalEventsPassedMouseTracker, eventsHandledMouseTracker, "Original event received count matches expected (" + eventsHandledMouseTracker + ")" ); assert.deepEqual( event.userData, originalUserData, "MouseTracker userData was untouched" ); viewer.close(); done(); }; viewer.addHandler("open", onOpen); viewer.open("/test/data/testpattern.dzi"); } ); // ---------- QUnit.test("EventSource: addHandler without userData", function (assert) { var done = assert.async(); var openHandler = function (event) { viewer.removeHandler("open", openHandler); assert.ok(event, "Event handler received event data"); if (event) { assert.strictEqual( event.eventSource, viewer, "eventSource sent, eventSource is viewer" ); assert.strictEqual( event.userData, null, "User data defaulted to null" ); } viewer.close(); done(); }; viewer.addHandler("open", openHandler); viewer.open("/test/data/testpattern.dzi"); }); // ---------- QUnit.test("EventSource: addHandler with userData", function (assert) { var done = assert.async(); var userData = { item1: "Test user data", item2: Math.random() }, originalUserData = { item1: userData.item1, item2: userData.item2 }; var openHandler = function (event) { viewer.removeHandler("open", openHandler); assert.ok(event, "Event handler received event data"); assert.ok( event && event.userData, "Event handler received user data" ); if (event && event.userData) { assert.deepEqual( event.userData, originalUserData, "User data was untouched" ); } viewer.close(); done(); }; viewer.addHandler("open", openHandler, userData); viewer.open("/test/data/testpattern.dzi"); }); // ---------- QUnit.test("EventSource: addOnceHandler", function (assert) { var eventSource = new OpenSeadragon.EventSource(); var userData = "data"; var eventData = { foo: 1, }; var handlerCalledCount = 0; eventSource.addOnceHandler( "test-event", function (event) { handlerCalledCount++; assert.strictEqual( event.foo, eventData.foo, "Event data should be transmitted to the event." ); assert.strictEqual( event.userData, userData, "User data should be transmitted to the event." ); }, userData ); assert.strictEqual( 0, handlerCalledCount, "Handler should not have been called yet." ); eventSource.raiseEvent("test-event", eventData); assert.strictEqual( 1, handlerCalledCount, "Handler should have been called once." ); eventSource.raiseEvent("test-event", eventData); assert.strictEqual( 1, handlerCalledCount, "Handler should still have been called once." ); }); // ---------- QUnit.test("EventSource: addOnceHandler 2 times", function (assert) { var eventSource = new OpenSeadragon.EventSource(); var userData = "data"; var eventData = { foo: 1, }; var handlerCalledCount = 0; eventSource.addOnceHandler( "test-event", function (event) { handlerCalledCount++; assert.strictEqual( event.foo, eventData.foo, "Event data should be transmitted to the event." ); assert.strictEqual( event.userData, userData, "User data should be transmitted to the event." ); }, userData, 2 ); assert.strictEqual( 0, handlerCalledCount, "Handler should not have been called yet." ); eventSource.raiseEvent("test-event", eventData); assert.strictEqual( 1, handlerCalledCount, "Handler should have been called once." ); eventSource.raiseEvent("test-event", eventData); assert.strictEqual( 2, handlerCalledCount, "Handler should have been called twice." ); eventSource.raiseEvent("test-event", eventData); assert.strictEqual( 2, handlerCalledCount, "Handler should still have been called twice." ); }); // ---------- QUnit.test("Viewer: tile-drawing event", function (assert) { var done = assert.async(); var tileDrawing = function (event) { viewer.removeHandler("tile-drawing", tileDrawing); assert.ok(event, "Event handler should be invoked"); if (event) { // Make sure we have the expected elements set assert.ok(event.context, "Context should be set"); assert.ok(event.tile, "Tile should be set"); assert.ok(event.rendered, "Rendered should be set"); } viewer.close(); done(); }; viewer.addHandler("tile-drawing", tileDrawing); viewer.open("/test/data/testpattern.dzi"); }); // tile-loaded event tests QUnit.test( "Viewer: tile-loaded event without callback.", function (assert) { var done = assert.async(); function tileLoaded(event) { viewer.removeHandler("tile-loaded", tileLoaded); var tile = event.tile; assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); setTimeout(function () { assert.notOk( tile.loading, "The tile should not be marked as loading." ); assert.ok( tile.loaded, "The tile should be marked as loaded." ); done(); }, 0); } viewer.addHandler("tile-loaded", tileLoaded); viewer.open("/test/data/testpattern.dzi"); } ); QUnit.test("Viewer: tile-loaded event with 1 callback.", function (assert) { var done = assert.async(); function tileLoaded(event) { viewer.removeHandler("tile-loaded", tileLoaded); var tile = event.tile; var callback = event.getCompletionCallback(); assert.ok(tile.loading, "The tile should be marked as loading."); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); assert.ok(callback, "The event should have a callback."); setTimeout(function () { assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); callback(); assert.notOk( tile.loading, "The tile should not be marked as loading." ); assert.ok(tile.loaded, "The tile should be marked as loaded."); done(); }, 0); } viewer.addHandler("tile-loaded", tileLoaded); viewer.open("/test/data/testpattern.dzi"); }); QUnit.test( "Viewer: tile-loaded event with 2 callbacks.", function (assert) { var done = assert.async(); function tileLoaded(event) { viewer.removeHandler("tile-loaded", tileLoaded); var tile = event.tile; var callback1 = event.getCompletionCallback(); var callback2 = event.getCompletionCallback(); assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); setTimeout(function () { assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); callback1(); assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); setTimeout(function () { assert.ok( tile.loading, "The tile should be marked as loading." ); assert.notOk( tile.loaded, "The tile should not be marked as loaded." ); callback2(); assert.notOk( tile.loading, "The tile should not be marked as loading." ); assert.ok( tile.loaded, "The tile should be marked as loaded." ); done(); }, 0); }, 0); } viewer.addHandler("tile-loaded", tileLoaded); viewer.open("/test/data/testpattern.dzi"); } ); QUnit.test("Viewer: tile-unloaded event.", function (assert) { var tiledImage; var tile; var done = assert.async(); function tileLoaded(event) { viewer.removeHandler("tile-loaded", tileLoaded); tiledImage = event.tiledImage; tile = event.tile; setTimeout(function () { tiledImage.reset(); }, 0); } function tileUnloaded(event) { viewer.removeHandler("tile-unloaded", tileUnloaded); assert.equal( tile, event.tile, "The unloaded tile should be the same than the loaded one." ); assert.equal( tiledImage, event.tiledImage, "The tiledImage of the unloaded tile should be the same than the one of the loaded one." ); done(); } viewer.addHandler("tile-loaded", tileLoaded); viewer.addHandler("tile-unloaded", tileUnloaded); viewer.open("/test/data/testpattern.dzi"); }); })();