(function() { "use strict"; angular.module('raz') .service('resourcePopoverService', ['$document', function resourcePopoverService($document) { var bookPopover = { getDisplayInfo : null, closePopover : null, element: null }; var nonbookPopover = { getDisplayInfo : null, closePopover : null, element: null }; var currentPopoverTarget = { domElement : null, id: null }; var popoverState = { popoverObject: null, enteredPopover: false, wasTouched: false, popoverActive: false, eventsEnabled: false }; var _latestDisplayPopoverTimoutIds = []; var lastPopoverEnterCheckTimeoutId = null; var popoverEnterVerifyUtil = { setTimeoutToVerifyIfEnteredPopover : function(delayInMs) { lastPopoverEnterCheckTimeoutId = setTimeout(function verifyIfEnteredPopover() { if (!popoverState.enteredPopover) { dismissPopover(); } }, delayInMs); }, resetPopoverEnterVerification: function() { popoverState.enteredPopover = false; if (popoverState.popoverObject != null) { dismissPopover(); } clearTimeout(lastPopoverEnterCheckTimeoutId); } }; function registerBookPopover(getDisplayInfo, closePopover, element) { bookPopover.getDisplayInfo = getDisplayInfo; bookPopover.closePopover = closePopover; bookPopover.element = element; } function registerNonbookPopover(getDisplayInfo, closePopover, element) { nonbookPopover.getDisplayInfo = getDisplayInfo; nonbookPopover.closePopover = closePopover; nonbookPopover.element = element; } function enableEventTriggers(isBook) { disableEventTriggers(isBook); enablePopoverAreaEventTriggers(isBook); popoverState.eventsEnabled = true; } function disableEventTriggers(isBook) { var element = isBook ? bookPopover.element : nonbookPopover.element; element.off('mouseenter'); var popoverContents = element.children().first(); popoverContents.off('mouseleave'); // remember in the state that the events are disabled popoverState.eventsEnabled = false; } function enablePopoverAreaEventTriggers(isBook) { var element = isBook ? bookPopover.element : nonbookPopover.element; element.on('mouseenter', function() { popoverState.enteredPopover = true; popoverState.wasTouched = false; }); var popoverContents = element.children().first(); popoverContents.on('mouseleave', function(e) { popoverState.enteredPopover = false; var delayInMs = 200; popoverEnterVerifyUtil.setTimeoutToVerifyIfEnteredPopover(delayInMs); }); popoverState.eventsEnabled = true; } function closeIfClickedOutsidePopover() { var onDocumentMouseDown = function(event) { if (popoverState.popoverObject != null) { var isChild = popoverState.popoverObject.element.find(event.target).length > 0; var isMessageBox = angular.element(event.target).closest('.message-box').length > 0; if(!isChild && !isMessageBox) { popoverState.popoverObject.closePopover(); } } }; $document.on("mousedown " + getEventNames().startTouchEvent, onDocumentMouseDown); } function displayPopover(event, fromTouch, isBook, resourceInfo) { popoverState.popoverObject = isBook ? bookPopover : nonbookPopover; var resourceId = resourceInfo.resourceId; dismissPopover(event); var fromTouchParameter = fromTouch ? '&fromTouchDevice=y' : ''; currentPopoverTarget.domElement = event.currentTarget; currentPopoverTarget.id = resourceId; popoverState.popoverObject.getDisplayInfo(fromTouchParameter, resourceInfo).then(function (response) { var popoverDisplayTarget = $j(currentPopoverTarget.domElement).find('.thumbnail'); var foundThumbnailForDisplayTarget = popoverDisplayTarget.length !== 0; if (!foundThumbnailForDisplayTarget) { popoverDisplayTarget = $j(currentPopoverTarget.domElement).find('a'); } var displayDelay = 150; var latestTimeoutId = setTimeout(function() { fadeInPopover(popoverDisplayTarget); }, displayDelay); _latestDisplayPopoverTimoutIds.push(latestTimeoutId); }).catch(function failure(response) { console.error('couldn\'t fetch popover data\nresponse %o', response); }); } function fadeInPopover(popoverDisplayTarget) { var popoverContents = popoverState.popoverObject.element.children().first(); // "visibility maniuplation is needed for position() to work correctly popoverContents.css('visibility', 'hidden'); popoverState.popoverObject.element.show(1, function() { popoverContents.position({ my: 'left top', at: 'right+12px top', of: popoverDisplayTarget, collision: 'flipfit' }); popoverContents.hide(); popoverContents.css('visibility', 'visible'); popoverContents.fadeIn('fast'); popoverState.popoverActive = true; }); } function dismissPopover(event) { var prevDisplayPopoverTimeoutIds = _latestDisplayPopoverTimoutIds; _latestDisplayPopoverTimoutIds = []; prevDisplayPopoverTimeoutIds.forEach(function(timeoutId) { clearTimeout(timeoutId); }); popoverState.popoverObject.closePopover(); popoverState.popoverActive = false; } function getEventNames(){ if('ontouchstart' in window) return {startTouchEvent: 'touchstart', endTouchEvent: 'touchend', enterMouseEvent: 'mouseenter', leaveMouseEvent: 'mouseleave'}; else if(window.PointerEvent) return {startTouchEvent: 'pointerdown', endTouchEvent: 'pointerup', enterMouseEvent: 'pointerenter', leaveMouseEvent: 'pointerleave'}; else return {startTouchEvent: 'MSPointerDown', endTouchEvent: 'MSPointerUp', enterMouseEvent: 'mouseenter', leaveMouseEvent: 'mouseleave'}; } return { registerBookPopover: registerBookPopover, registerNonbookPopover: registerNonbookPopover, enableEventTriggers: enableEventTriggers, disableEventTriggers: disableEventTriggers, closeIfClickedOutsidePopover: closeIfClickedOutsidePopover, displayPopover: displayPopover, popoverState: popoverState, popoverEnterVerifyUtil: popoverEnterVerifyUtil }; }]); })();