Skip to content

Commit

Permalink
Initial patch for #770
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanolson committed Apr 23, 2018
1 parent d96bbaa commit f7d0b81
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
15 changes: 13 additions & 2 deletions js/display/Display.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ define( function( require ) {
// supertype call to axon.Events (should just initialize a few properties here, notably _eventListeners and _staticEventListeners)
Events.call( this );

// Inline platform detection in maintenance release, since usually we won't need to hit phet-core
var ua = navigator.userAgent;
// Whether the browser is most likely Safari running on iOS
// See http://stackoverflow.com/questions/3007480/determine-if-user-navigated-from-mobile-safari
function isMobileSafari() {
return !!( ua.match( /(iPod|iPhone|iPad)/ ) && ua.match( /AppleWebKit/ ) );
}
var safari = isMobileSafari() || !!( ua.match( /Version\// ) && ua.match( /Safari\// ) && ua.match( /AppleWebKit/ ) );

this.options = _.extend( {
// initial display width
width: ( options && options.container && options.container.clientWidth ) || 640,
Expand All @@ -119,7 +128,8 @@ define( function( require ) {
allowWebGL: true,
accessibility: true,
isApplication: false, // adds the aria-role: 'application' when accessibility is enabled
interactive: true
interactive: true,
passiveEvents: safari ? false : null
}, options );

// The (integral, > 0) dimensions of the Display's DOM element (only updates the DOM element on updateDisplay())
Expand Down Expand Up @@ -173,6 +183,7 @@ define( function( require ) {
// will be filled in with a scenery.Input if event handling is enabled
this._input = null;
this._interactive = this.options.interactive;
this._passiveEvents = this.options.passiveEvents;

// overlays currently being displayed.
// API expected:
Expand Down Expand Up @@ -1001,7 +1012,7 @@ define( function( require ) {
var listenerTarget = parameters.listenerTarget;
var batchDOMEvents = parameters.batchDOMEvents; //OHTWO TODO: hybrid batching (option to batch until an event like 'up' that might be needed for security issues)

var input = new scenery.Input( this, listenerTarget, !!batchDOMEvents, this.options.enablePointerEvents, pointFromEvent );
var input = new scenery.Input( this, listenerTarget, !!batchDOMEvents, this.options.enablePointerEvents, pointFromEvent, this._passiveEvents );
this._input = input;

input.connectListeners();
Expand Down
20 changes: 14 additions & 6 deletions js/input/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ define( function( require ) {
var inherit = require( 'PHET_CORE/inherit' );
var platform = require( 'PHET_CORE/platform' );
var cleanArray = require( 'PHET_CORE/cleanArray' );
var Features = require( 'SCENERY/util/Features' );
var scenery = require( 'SCENERY/scenery' );

require( 'SCENERY/util/Trail' );
Expand Down Expand Up @@ -65,13 +66,14 @@ define( function( require ) {
var globalDisplay = null;

// listenerTarget is the DOM node (window/document/element) to which DOM event listeners will be attached
scenery.Input = function Input( display, listenerTarget, batchDOMEvents, enablePointerEvents, pointFromEvent ) {
scenery.Input = function Input( display, listenerTarget, batchDOMEvents, enablePointerEvents, pointFromEvent, passiveEvents ) {
this.display = display;
this.rootNode = display.rootNode;
this.listenerTarget = listenerTarget;
this.batchDOMEvents = batchDOMEvents;
this.enablePointerEvents = enablePointerEvents;
this.pointFromEvent = pointFromEvent;
this.passiveEvents = passiveEvents;
this.displayUpdateOnEvent = false;
globalDisplay = display;

Expand Down Expand Up @@ -140,7 +142,7 @@ define( function( require ) {
// http://www.html5rocks.com/en/mobile/touchandmouse/ for more information.
// Additionally, IE had some issues with skipping prevent default, see
// https://github.com/phetsims/scenery/issues/464 for mouse handling.
if ( callback !== this.mouseDown || platform.ie || platform.edge ) {
if ( !( this.passiveEvents === true ) && ( callback !== this.mouseDown || platform.ie || platform.edge ) ) {
domEvent.preventDefault();
}
}
Expand Down Expand Up @@ -218,6 +220,12 @@ define( function( require ) {

// @param addOrRemove: true if adding, false if removing
processListeners: function( addOrRemove ) {
var passDirectPassiveFlag = Features.passive && this.passiveEvents !== null;
var documentOptions = passDirectPassiveFlag ? { passive: this.passiveEvents } : false;
var mainOptions = passDirectPassiveFlag ? {
useCapture: false,
passive: this.passiveEvents
} : false;
var eventTypes = this.getUsedEventTypes();

for ( var i = 0; i < eventTypes.length; i++ ) {
Expand All @@ -226,21 +234,21 @@ define( function( require ) {
// work around iOS Safari 7 not sending touch events to Scenes contained in an iframe
if ( this.listenerTarget === window ) {
if ( addOrRemove ) {
document.addEventListener( type, this.uselessListener );
document.addEventListener( type, this.uselessListener, documentOptions );
}
else {
document.removeEventListener( type, this.uselessListener );
document.removeEventListener( type, this.uselessListener, documentOptions );
}
}

var callback = this[ 'on' + type ];
assert && assert( !!callback );

if ( addOrRemove ) {
this.listenerTarget.addEventListener( type, callback, false ); // don't use capture for now
this.listenerTarget.addEventListener( type, callback, mainOptions ); // don't use capture for now
}
else {
this.listenerTarget.removeEventListener( type, callback, false ); // don't use capture for now
this.listenerTarget.removeEventListener( type, callback, mainOptions ); // don't use capture for now
}
}
},
Expand Down
9 changes: 9 additions & 0 deletions js/util/Features.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,14 @@ define( function( require ) {
}
};

// Whether passive is a supported option for adding event listeners,
// see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners
Features.passive = false;
window.addEventListener( 'test', null, Object.defineProperty( {}, 'passive', {
get: function() {
Features.passive = true;
}
} ) );

return Features;
} );

0 comments on commit f7d0b81

Please sign in to comment.