Skip to content

Commit

Permalink
perf(ripple): Use passive event listeners on adapter instantiation (#649
Browse files Browse the repository at this point in the history
)

Resolves #629
  • Loading branch information
trimox authored and traviskaufman committed May 18, 2017
1 parent e41b21f commit 3dd9a13
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
8 changes: 5 additions & 3 deletions packages/mdc-ripple/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import {MDCComponent} from '@material/base';
import MDCRippleFoundation from './foundation';
import {supportsCssVariables, getMatchesProperty} from './util';
import {applyPassive, supportsCssVariables, getMatchesProperty} from './util';

export {MDCRippleFoundation};

Expand All @@ -40,8 +40,10 @@ export class MDCRipple extends MDCComponent {
isSurfaceDisabled: () => instance.disabled,
addClass: (className) => instance.root_.classList.add(className),
removeClass: (className) => instance.root_.classList.remove(className),
registerInteractionHandler: (evtType, handler) => instance.root_.addEventListener(evtType, handler),
deregisterInteractionHandler: (evtType, handler) => instance.root_.removeEventListener(evtType, handler),
registerInteractionHandler: (evtType, handler) =>
instance.root_.addEventListener(evtType, handler, applyPassive()),
deregisterInteractionHandler: (evtType, handler) =>
instance.root_.removeEventListener(evtType, handler, applyPassive()),
registerResizeHandler: (handler) => window.addEventListener('resize', handler),
deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
updateCssVariable: (varName, value) => instance.root_.style.setProperty(varName, value),
Expand Down
18 changes: 18 additions & 0 deletions packages/mdc-ripple/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

let supportsPassive_;

export function supportsCssVariables(windowObj) {
const supportsFunctionPresent = windowObj.CSS && typeof windowObj.CSS.supports === 'function';
if (!supportsFunctionPresent) {
Expand All @@ -30,6 +32,22 @@ export function supportsCssVariables(windowObj) {
return explicitlySupportsCssVars || weAreFeatureDetectingSafari10plus;
}

// Determine whether the current browser supports passive event listeners, and if so, use them.
export function applyPassive(globalObj = window, forceRefresh = false) {
if (supportsPassive_ === undefined || forceRefresh) {
let isSupported = false;
try {
globalObj.document.addEventListener('test', null, {get passive() {
isSupported = true;
}});
} catch (e) { }

supportsPassive_ = isSupported;
}

return supportsPassive_ ? {passive: true} : false;
}

export function getMatchesProperty(HTMLElementPrototype) {
return [
'webkitMatchesSelector', 'msMatchesSelector', 'matches',
Expand Down
22 changes: 22 additions & 0 deletions test/unit/mdc-ripple/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,28 @@ test('#supportsCssVariables returns false when CSS is not an object', () => {
assert.isNotOk(util.supportsCssVariables(windowObj));
});

test('applyPassive returns an options object for browsers that support passive event listeners', () => {
const mockWindow = {
document: {
addEventListener: function(name, method, options) {
return options.passive;
},
},
};
assert.deepEqual(util.applyPassive(mockWindow, true), {passive: true});
});

test('applyPassive returns false for browsers that do not support passive event listeners', () => {
const mockWindow = {
document: {
addEventListener: function() {
throw new Error();
},
},
};
assert.isNotOk(util.applyPassive(mockWindow, true));
});

test('#getMatchesProperty returns the correct property for selector matching', () => {
assert.equal(util.getMatchesProperty({matches: () => {}}), 'matches');
assert.equal(util.getMatchesProperty({webkitMatchesSelector: () => {}}), 'webkitMatchesSelector');
Expand Down

0 comments on commit 3dd9a13

Please sign in to comment.