diff --git a/docs/app/js/preload.js b/docs/app/js/preload.js deleted file mode 100644 index e48022d8259..00000000000 --- a/docs/app/js/preload.js +++ /dev/null @@ -1,2 +0,0 @@ -// Used only to optionally test -// jQuery w/ docs (see docs/gulpfile#docs-js) diff --git a/src/components/fabSpeedDial/fabController.js b/src/components/fabSpeedDial/fabController.js index 9240a237932..4178a4dd4c2 100644 --- a/src/components/fabSpeedDial/fabController.js +++ b/src/components/fabSpeedDial/fabController.js @@ -46,7 +46,7 @@ function setupListeners() { var eventTypes = [ - 'click', 'focusin', 'focusout' + 'mousedown', 'mouseup', 'click', 'touchstart', 'touchend', 'focusin', 'focusout' ]; // Add our listeners @@ -111,17 +111,55 @@ }); } - var lastSrc; function parseEvents(latestEvent) { - if (latestEvent.srcEvent && latestEvent.srcEvent == lastSrc) return; - if (latestEvent.type == 'click') { + events.push(latestEvent.type); + + // Handle desktop click + if (equalsEvents(['mousedown', 'focusout?', 'focusin?', 'mouseup', 'click'])) { + handleItemClick(latestEvent); + resetEvents(); + return; + } + + // Handle mobile click/tap (and keyboard enter) + if (equalsEvents(['touchstart?', 'touchend?', 'click'])) { handleItemClick(latestEvent); - } else if (latestEvent.type == 'focusin') { + resetEvents(); + return; + } + + // Handle tab keys (focusin) + if (equalsEvents(['focusin'])) { vm.open(); - } else if (latestEvent.type == 'focusout') { + resetEvents(); + return; + } + + // Handle tab keys (focusout) + if (equalsEvents(['focusout'])) { vm.close(); + resetEvents(); + return; } - lastSrc = latestEvent.srcEvent; + + eventUnhandled(); + } + + /* + * No event was handled, so setup a timeout to clear the events + * + * TODO: Use $mdUtil.debounce()? + */ + var resetEventsTimeout; + + function eventUnhandled() { + if (resetEventsTimeout) { + window.clearTimeout(resetEventsTimeout); + } + + resetEventsTimeout = window.setTimeout(function() { + resetEvents(); + }, 250); } function resetActionIndex() { diff --git a/src/components/tooltip/tooltip.js b/src/components/tooltip/tooltip.js index e0677b18346..8ccb70fdcc5 100644 --- a/src/components/tooltip/tooltip.js +++ b/src/components/tooltip/tooltip.js @@ -168,13 +168,13 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe elementFocusedOnWindowBlur = false; return; } - parent.on('blur mouseleave touchcancel', leaveHandler ); + parent.on('blur mouseleave touchend touchcancel', leaveHandler ); setVisible(true); }; - var leaveHandler = function (e) { + var leaveHandler = function () { var autohide = scope.hasOwnProperty('autohide') ? scope.autohide : attr.hasOwnProperty('mdAutohide'); if (autohide || mouseActive || ($document[0].activeElement !== parent[0]) ) { - parent.off('blur mouseleave touchcancel', leaveHandler ); + parent.off('blur mouseleave touchend touchcancel', leaveHandler ); parent.triggerHandler("blur"); setVisible(false); } diff --git a/src/core/services/gesture/gesture.js b/src/core/services/gesture/gesture.js index cbcede7e221..db07cc5d709 100644 --- a/src/core/services/gesture/gesture.js +++ b/src/core/services/gesture/gesture.js @@ -81,55 +81,16 @@ }; if (self.isHijackingClicks) { - var maxClickDistance = 6; self.handler('click', { options: { - maxDistance: maxClickDistance + maxDistance: 6 }, - onEnd: checkDistanceAndEmit('click') - }); - - self.handler('focus', { - options: { - maxDistance: maxClickDistance - }, - onEnd: function(ev, pointer) { + onEnd: function (ev, pointer) { if (pointer.distance < this.state.options.maxDistance) { - if (canFocus(ev.target)) { - this.dispatchEvent(ev, 'focus', pointer); - ev.target.focus(); - } - } - - function canFocus(element) { - return element.hasAttribute('href') || - (( element.nodeName == 'INPUT' || element.nodeName == 'BUTTON' || - element.nodeName == 'SELECT' || element.nodeName == 'TEXTAREA' ) && !element.hasAttribute('DISABLED')) || - ( element.hasAttribute('tabindex') && element.getAttribute('tabindex') != '-1' ); + this.dispatchEvent(ev, 'click'); } } }); - - self.handler('mouseup', { - options: { - maxDistance: maxClickDistance - }, - onEnd: checkDistanceAndEmit('mouseup') - }); - - self.handler('mousedown', { - onStart: function(ev) { - this.dispatchEvent(ev, 'mousedown'); - } - }); - } - - function checkDistanceAndEmit(eventName) { - return function(ev, pointer) { - if (pointer.distance < this.state.options.maxDistance) { - this.dispatchEvent(ev, eventName, pointer); - } - }; } /* @@ -446,10 +407,10 @@ eventPointer = eventPointer || pointer; var eventObj; - if (eventType === 'click' || eventType == 'mouseup' || eventType == 'mousedown' ) { + if (eventType === 'click') { eventObj = document.createEvent('MouseEvents'); eventObj.initMouseEvent( - eventType, true, true, window, srcEvent.detail, + 'click', true, true, window, srcEvent.detail, eventPointer.x, eventPointer.y, eventPointer.x, eventPointer.y, srcEvent.ctrlKey, srcEvent.altKey, srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button, srcEvent.relatedTarget || null @@ -505,33 +466,6 @@ } } }, true); - - document.addEventListener('mouseup', function clickHijacker(ev) { - var isKeyClick = !ev.clientX && !ev.clientY; - if (!isKeyClick && !ev.$material && !ev.isIonicTap - && !isInputEventFromLabelClick(ev)) { - ev.preventDefault(); - ev.stopPropagation(); - } - }, true); - - document.addEventListener('mousedown', function clickHijacker(ev) { - var isKeyClick = !ev.clientX && !ev.clientY; - if (!isKeyClick && !ev.$material && !ev.isIonicTap - && !isInputEventFromLabelClick(ev)) { - ev.preventDefault(); - ev.stopPropagation(); - } - }, true); - - document.addEventListener('focus', function clickHijacker(ev) { - var isKeyClick = !ev.clientX && !ev.clientY; - if (!isKeyClick && !ev.$material && !ev.isIonicTap - && !isInputEventFromLabelClick(ev)) { - ev.preventDefault(); - ev.stopPropagation(); - } - }, true); isInitialized = true; }