Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[event] Add `wheel` event #1556

Open
wants to merge 5 commits into from

2 participants

@juandopazo
Collaborator

This PR modifies the mousewheel and adds a wheel event (basically mousewheel becomes an alias of wheel) that matches the W3C spec.

The wheel event has a deltaY payload that requires some math to get right across browsers. But simulating the event would require to do the math in the reverse order if I wanted to make an assertion over it. Does it make sense to do that or should I not test deltaY?

I'm sending the PR to get some early feedback. I still need to:

  • Figure out why tests fail in Phantomjs
  • Update the User Guide
  • Add manual test
  • Test in older browsers
@triptych

@juandopazo would this need to be updated/modified if @tilomitra adds Hammer.js ?

@juandopazo
Collaborator

@triptych I don't think Hammer.js covers the wheel event.

@triptych

Yes, but since the api may change, would that mean you'll need to update this code to be compatible. @juandopazo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
96 src/event/js/mousewheel.js
@@ -4,42 +4,74 @@
* @submodule event-mousewheel
*/
var DOM_MOUSE_SCROLL = 'DOMMouseScroll',
- fixArgs = function(args) {
- var a = Y.Array(args, 0, true), target;
- if (Y.UA.gecko) {
- a[0] = DOM_MOUSE_SCROLL;
- target = Y.config.win;
- } else {
- target = Y.config.doc;
+ win = Y.config.win,
+ doc = Y.config.doc,
+ eventDef = {
+ detach: function (node, sub) {
+ sub._handle.detach();
+ },
+ _createFacade: function (domEvent, node, deltaY) {
+ var facade = new Y.DOMEventFacade(domEvent, node);
+ facade.type = 'wheel';
+ facade.deltaX = 0;
+ facade.deltaY = deltaY;
+ facade.deltaZ = 0;
+ facade.deltaMode = 1;
+ return facade;
}
+ };
- if (a.length < 3) {
- a[2] = target;
- } else {
- a.splice(2, 0, target);
- }
+function attach() {
+ return Y.Event._attach(arguments, {
+ facade: false
+ });
+}
- return a;
+if (win.WheelEvent) {
+ eventDef.on = function (node, sub, notifier) {
+ var self = this;
+ sub._handle = attach('wheel', function (domEvent) {
+ notifier.fire(self._createFacade(domEvent, node, domEvent.deltaY));
+ }, win);
+ };
+} else if ('onmousewheel' in doc) {
+ eventDef.on = function (node, sub, notifier) {
+ var self = this;
+ sub._handle = attach('mousewheel', function (domEvent) {
+ notifier.fire(self._createFacade(domEvent, node,
+ - 1/40 * ('wheelDeltaX' in domEvent ? domEvent.wheelDeltaX : domEvent.wheelDelta)));
+ }, doc);
+ };
+} else {
+ eventDef.on = function (node, sub, notifier) {
+ var self = this;
+ sub._handle = attach('MozMousePixelScroll', function (domEvent) {
+ notifier.fire(self._createFacade(domEvent, node, domEvent.detail));
+ }, win);
};
+}
/**
- * Mousewheel event. This listener is automatically attached to the
- * correct target, so one should not be supplied. Mouse wheel
- * direction and velocity is stored in the 'wheelDelta' field.
- * @event mousewheel
- * @param type {string} 'mousewheel'
- * @param fn {function} the callback to execute
- * @param context optional context object
- * @param args 0..n additional arguments to provide to the listener.
- * @return {EventHandle} the detach handle
- * @for YUI
- */
-Y.Env.evt.plugins.mousewheel = {
- on: function() {
- return Y.Event._attach(fixArgs(arguments));
- },
+Mousewheel event. Alias for the `wheel` event
+
+@event mousewheel
+@for YUI
+@see wheel
+@param {String} type Set to `'wheel'`.
+**/
+Y.Event.define('mousewheel', eventDef, true);
+
+/**
+The W3C `wheel` event. This listener is automatically attached to the correct
+target, so one should not be supplied/
- detach: function() {
- return Y.Event.detach.apply(Y.Event, fixArgs(arguments));
- }
-};
+@event wheel
+@for YUI
+@param {Number} deltaX Set to 0.
+@param {Number} deltaY Expected amount that the page will scroll along the
+ y-axis according to the deltaMode units.
+@param {Number} deltaZ Set to 0.
+@param {Number} deltaMode Set to 1. Unit indicator (pixels, lines, or pages) for
+ the deltaY attribute.
+**/
+Y.Event.define('wheel', eventDef, true);
View
2  src/event/meta/event.json
@@ -53,7 +53,7 @@
},
"event-mousewheel": {
"requires": [
- "node-base"
+ "event-synthetic"
]
},
"event-resize": {
View
23 src/event/tests/manual/wheel.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Wheel Event Tests</title>
+ <link rel="stylesheet" type="text/css" href="../../../../build/cssnormalize/cssnormalize-min.css">
+</head>
+<body class="yui3-skin-sam">
+ <h1>Wheel Event Tests</h1>
+ <script type="text/javascript" src="../../../../build/yui/yui.js"></script>
+ <script type="text/javascript">
+YUI({
+ filter: 'raw'
+}).use('event', 'console', function (Y) {
+ new Y.Console().render();
+
+ Y.on('wheel', function (e) {
+ Y.log('wheel event - deltaY = ' + e.deltaY, 'info', 'event-mousewheel');
+ });
+});
+ </script>
+</body>
+</html>
View
2  src/event/tests/unit/assets/mousewheel-tests.js
@@ -13,6 +13,8 @@ YUI.add('mousewheel-tests', function(Y) {
}
}));
+ Y.MouseWheelSuite = suite;
+
Y.Test.Runner.add(suite);
});
View
147 src/event/tests/unit/assets/wheel-tests.js
@@ -0,0 +1,147 @@
+YUI.add('wheel-tests', function (Y) {
+
+ var win = Y.config.win,
+ doc = Y.config.doc,
+ Assert = Y.Assert,
+ node = Y.one('#tester'),
+ domNode = node.getDOMNode();
+
+ var createWheelEvent;
+
+ // Chrome
+ if ((function () {
+ try {
+ return !!doc.createEvent('WheelEvent').initWebKitWheelEvent;
+ } catch (e) {
+ return false;
+ }
+ }())) {
+ createWheelEvent = function (deltaY) {
+ var evt = doc.createEvent('WheelEvent');
+ evt.initWebKitWheelEvent(
+ 0, /* deltaX*/
+ -deltaY, /* deltaY */
+ window, /* view */
+ 0, /* screenX */
+ 0, /* screenY */
+ 0, /* clientX */
+ 0, /* clientY */
+ false, /* ctrlKey */
+ false, /* altKey */
+ false, /* shiftKey */
+ false /* metaKey */);
+ return evt;
+ };
+ // Modern IE
+ } else if ((function () {
+ try {
+ return !!doc.createEvent('WheelEvent').initWheelEvent;
+ } catch (e) {
+ return false;
+ }
+ }())) {
+ createWheelEvent = function (deltaY) {
+ var evt = doc.createEvent('WheelEvent');
+ evt.initWheelEvent('wheel', /* type */
+ true, /* bubbles */
+ true, /* cancelable */
+ window, /* view */
+ 0, /* detail */
+ 1, /* screenX */
+ 2, /* screenY */
+ 3, /* clientX */
+ 4, /* clientY */
+ 5, /* button */
+ null, /* relatedTarget */
+ "", /* modifiers */
+ 6, /* deltaX*/
+ 7, /* deltaY */
+ 8, /* deltaZ*/
+ 9 /* deltaMode */ );
+ return evt;
+ };
+ } else if (doc.createEventObject) {
+ createWheelEvent = function (deltaY) {
+ var evt = doc.createEventObject();
+ evt.type = 'wheelevent';
+ return evt;
+ };
+ } else {
+ createWheelEvent = function (deltaY) {
+ var evt = doc.createEvent('MouseScrollEvents');
+ evt.initMouseEvent('wheel', /* type */
+ true, /* bubbles */
+ true, /* cancelable */
+ window, /* view */
+ 0, /* detail */
+ 0, /* screenX */
+ 0, /* screenY */
+ 0, /* clientX */
+ 0, /* clientY */
+ false, /* ctrlKey */
+ false, /* altKey */
+ false, /* shiftKey */
+ false, /* metaKey */
+ 0, /* button */
+ null /* related target */
+ );
+ return evt;
+ };
+ }
+
+ Y.MouseWheelSuite.add(new Y.Test.Case({
+ name: 'W3C wheel event',
+
+ _should: {
+ ignore: {
+ 'test wheel implementation': !win.WheelEvent,
+ 'test mousewheel implementation': !!win.WheelEvent
+ }
+ },
+
+ // Modern IE
+ 'test wheel implementation': function () {
+ var deltaY = 50,
+ mouseEvent = createWheelEvent(deltaY),
+ test = this;
+
+ node.once('wheel', function (e) {
+ test.resume(function () {
+ Assert.areSame(0, e.deltaX, 'Wrong deltaX event payloed');
+ Assert.areSame(0, e.deltaZ, 'Wrong deltaZ event payloed');
+ Assert.areSame(1, e.deltaMode, 'Wrong deltaMode event payloed');
+ });
+ });
+
+ setTimeout(function () {
+ domNode.dispatchEvent(mouseEvent);
+ }, 0);
+
+ test.wait();
+ },
+
+ 'test mousewheel implementation': function () {
+ var mouseEvent = createWheelEvent(50),
+ test = this;
+
+ node.once('wheel', function (e) {
+ test.resume(function () {
+ Assert.areSame(0, e.deltaX, 'Wrong deltaX event payloed');
+ Assert.areSame(0, e.deltaZ, 'Wrong deltaZ event payloed');
+ Assert.areSame(1, e.deltaMode, 'Wrong deltaMode event payloed');
+ });
+ });
+
+ setTimeout(function () {
+ if (domNode.dispatchEvent) {
+ domNode.dispatchEvent(mouseEvent);
+ } else {
+ domNode.fireEvent('onmousewheel', mouseEvent);
+ }
+ }, 0);
+
+ test.wait();
+ }
+ }));
+
+});
View
6 src/event/tests/unit/event-mousewheel.html
@@ -18,9 +18,13 @@
'mousewheel-tests': {
fullpath: './assets/mousewheel-tests.js',
requires: [ 'event-mousewheel', 'test-console', 'test' ]
+ },
+ 'wheel-tests': {
+ fullpath: './assets/wheel-tests.js',
+ requires: ['mousewheel-tests']
}
}
-}).use('mousewheel-tests', function(Y) {
+}).use('wheel-tests', function(Y) {
(new Y.Test.Console()).render('#log');
Y.Test.Runner.setName('Event: Mousewheel');
Something went wrong with that request. Please try again.