{"version":3,"file":"~~jquery-menu-aim.78dc82bb.js","mappings":"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","sources":["webpack://@ultradent/upi-dev-frontend/./src/scripts/plugins/jquery.menuaim.js"],"sourcesContent":["/**\n * THIS IS A FORK IN ORDER TO PROVIDE A NPM PACKAGE OF IT!\n *\n * ORIGINAL:\n * Copyright © 2016 Ben Kamens | MIT license | https://github.com/kamens/jQuery-menu-aim\n *\n * menu-aim is a jQuery plugin for dropdown menus that can differentiate\n * between a user trying hover over a dropdown item vs trying to navigate into\n * a submenu's contents.\n *\n * menu-aim assumes that you have are using a menu with submenus that expand\n * to the menu's right. It will fire events when the user's mouse enters a new\n * dropdown item *and* when that item is being intentionally hovered over.\n *\n * __________________________\n * | Monkeys >| Gorilla |\n * | Gorillas >| Content |\n * | Chimps >| Here |\n * |___________|____________|\n *\n * In the above example, \"Gorillas\" is selected and its submenu content is\n * being shown on the right. Imagine that the user's cursor is hovering over\n * \"Gorillas.\" When they move their mouse into the \"Gorilla Content\" area, they\n * may briefly hover over \"Chimps.\" This shouldn't close the \"Gorilla Content\"\n * area.\n *\n * This problem is normally solved using timeouts and delays. menu-aim tries to\n * solve this by detecting the direction of the user's mouse movement. This can\n * make for quicker transitions when navigating up and down the menu. The\n * experience is hopefully similar to amazon.com/'s \"Shop by Department\"\n * dropdown.\n *\n * Use like so:\n *\n * $(\"#menu\").menuAim({\n * activate: $.noop, // fired on row activation\n * deactivate: $.noop // fired on row deactivation\n * });\n *\n * ...to receive events when a menu's row has been purposefully (de)activated.\n *\n * The following options can be passed to menuAim. All functions execute with\n * the relevant row's HTML element as the execution context ('this'):\n *\n * .menuAim({\n * // Function to call when a row is purposefully activated. Use this\n * // to show a submenu's content for the activated row.\n * activate: function() {},\n *\n * // Function to call when a row is deactivated.\n * deactivate: function() {},\n *\n * // Function to call when mouse enters a menu row. Entering a row\n * // does not mean the row has been activated, as the user may be\n * // mousing over to a submenu.\n * enter: function() {},\n *\n * // Function to call when mouse exits a menu row.\n * exit: function() {},\n *\n * // Selector for identifying which elements in the menu are rows\n * // that can trigger the above events. Defaults to \"> li\".\n * rowSelector: \"> li\",\n *\n * // You may have some menu rows that aren't submenus and therefore\n * // shouldn't ever need to \"activate.\" If so, filter submenu rows w/\n * // this selector. Defaults to \"*\" (all elements).\n * submenuSelector: \"*\",\n *\n * // Direction the submenu opens relative to the main menu. Can be\n * // left, right, above, or below. Defaults to \"right\".\n * submenuDirection: \"right\"\n * });\n *\n */\n$.fn.menuAim = function ( opts ) {\n // Initialize menu-aim for all elements in jQuery collection\n this.each( function () {\n init.call( this, opts );\n } );\n\n return this;\n};\n\nfunction init ( opts ) {\n var $menu = $( this ),\n activeRow = null,\n mouseLocs = [],\n lastDelayLoc = null,\n timeoutId = null,\n options = $.extend( {\n rowSelector: '> li',\n submenuSelector: '*',\n submenuDirection: 'right',\n tolerance: 75, // bigger = more forgivey when entering submenu\n enter: $.noop,\n exit: $.noop,\n activate: $.noop,\n deactivate: $.noop,\n exitMenu: $.noop\n }, opts );\n\n var MOUSE_LOCS_TRACKED = 3, // number of past mouse locations to track\n DELAY = 300; // ms delay when user appears to be entering submenu\n\n /**\n * Keep track of the last few locations of the mouse.\n */\n var mousemoveDocument = function ( e ) {\n mouseLocs.push( {x: e.pageX, y: e.pageY} );\n\n if ( mouseLocs.length > MOUSE_LOCS_TRACKED ) {\n mouseLocs.shift();\n }\n };\n\n /**\n * Cancel possible row activations when leaving the menu entirely\n */\n var mouseleaveMenu = function () {\n if ( timeoutId ) {\n clearTimeout( timeoutId );\n }\n\n // If exitMenu is supplied and returns true, deactivate the\n // currently active row on menu exit.\n if ( options.exitMenu( this ) ) {\n if ( activeRow ) {\n options.deactivate( activeRow );\n }\n\n activeRow = null;\n }\n };\n\n /**\n * Trigger a possible row activation whenever entering a new row.\n */\n var mouseenterRow = function () {\n if ( timeoutId ) {\n // Cancel any previous activation delays\n clearTimeout( timeoutId );\n }\n\n options.enter( this );\n possiblyActivate( this );\n },\n mouseleaveRow = function () {\n options.exit( this );\n };\n\n /*\n * Immediately activate a row if the user clicks on it.\n */\n var clickRow = function () {\n activate( this );\n };\n\n /**\n * Activate a menu row.\n */\n var activate = function ( row ) {\n if ( row == activeRow ) {\n return;\n }\n\n if ( activeRow ) {\n options.deactivate( activeRow );\n }\n\n options.activate( row );\n activeRow = row;\n };\n\n /**\n * Possibly activate a menu row. If mouse movement indicates that we\n * shouldn't activate yet because user may be trying to enter\n * a submenu's content, then delay and check again later.\n */\n var possiblyActivate = function ( row ) {\n var delay = activationDelay();\n\n if ( delay ) {\n timeoutId = setTimeout( function () {\n possiblyActivate( row );\n }, delay );\n }\n else {\n activate( row );\n }\n };\n\n /**\n * Return the amount of time that should be used as a delay before the\n * currently hovered row is activated.\n *\n * Returns 0 if the activation should happen immediately. Otherwise,\n * returns the number of milliseconds that should be delayed before\n * checking again to see if the row should be activated.\n */\n var activationDelay = function () {\n if ( !activeRow || !$( activeRow ).is( options.submenuSelector ) ) {\n // If there is no other submenu row already active, then\n // go ahead and activate immediately.\n return 0;\n }\n\n var offset = $menu.offset(),\n upperLeft = {\n x: offset.left,\n y: offset.top - options.tolerance\n },\n upperRight = {\n x: offset.left + $menu.outerWidth(),\n y: upperLeft.y\n },\n lowerLeft = {\n x: offset.left,\n y: offset.top + $menu.outerHeight() + options.tolerance\n },\n lowerRight = {\n x: offset.left + $menu.outerWidth(),\n y: lowerLeft.y\n },\n loc = mouseLocs[mouseLocs.length - 1],\n prevLoc = mouseLocs[0];\n\n if ( !loc ) {\n return 0;\n }\n\n if ( !prevLoc ) {\n prevLoc = loc;\n }\n\n if ( prevLoc.x < offset.left || prevLoc.x > lowerRight.x ||\n prevLoc.y < offset.top || prevLoc.y > lowerRight.y ) {\n // If the previous mouse location was outside of the entire\n // menu's bounds, immediately activate.\n return 0;\n }\n\n if ( lastDelayLoc &&\n loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y ) {\n // If the mouse hasn't moved since the last time we checked\n // for activation status, immediately activate.\n return 0;\n }\n\n // Detect if the user is moving towards the currently activated\n // submenu.\n //\n // If the mouse is heading relatively clearly towards\n // the submenu's content, we should wait and give the user more\n // time before activating a new row. If the mouse is heading\n // elsewhere, we can immediately activate a new row.\n //\n // We detect this by calculating the slope formed between the\n // current mouse location and the upper/lower right points of\n // the menu. We do the same for the previous mouse location.\n // If the current mouse location's slopes are\n // increasing/decreasing appropriately compared to the\n // previous's, we know the user is moving toward the submenu.\n //\n // Note that since the y-axis increases as the cursor moves\n // down the screen, we are looking for the slope between the\n // cursor and the upper right corner to decrease over time, not\n // increase (somewhat counterintuitively).\n function slope ( a, b ) {\n return (b.y - a.y) / (b.x - a.x);\n };\n\n var decreasingCorner = upperRight,\n increasingCorner = lowerRight;\n\n // Our expectations for decreasing or increasing slope values\n // depends on which direction the submenu opens relative to the\n // main menu. By default, if the menu opens on the right, we\n // expect the slope between the cursor and the upper right\n // corner to decrease over time, as explained above. If the\n // submenu opens in a different direction, we change our slope\n // expectations.\n if ( options.submenuDirection == 'left' ) {\n decreasingCorner = lowerLeft;\n increasingCorner = upperLeft;\n }\n else if ( options.submenuDirection == 'below' ) {\n decreasingCorner = lowerRight;\n increasingCorner = lowerLeft;\n }\n else if ( options.submenuDirection == 'above' ) {\n decreasingCorner = upperLeft;\n increasingCorner = upperRight;\n }\n\n var decreasingSlope = slope( loc, decreasingCorner ),\n increasingSlope = slope( loc, increasingCorner ),\n prevDecreasingSlope = slope( prevLoc, decreasingCorner ),\n prevIncreasingSlope = slope( prevLoc, increasingCorner );\n\n if ( decreasingSlope < prevDecreasingSlope &&\n increasingSlope > prevIncreasingSlope ) {\n // Mouse is moving from previous location towards the\n // currently activated submenu. Delay before activating a\n // new menu row, because user may be moving into submenu.\n lastDelayLoc = loc;\n return DELAY;\n }\n\n lastDelayLoc = null;\n return 0;\n };\n\n /**\n * Hook up initial menu events\n */\n $menu\n .mouseleave( mouseleaveMenu )\n .find( options.rowSelector )\n .mouseenter( mouseenterRow )\n .mouseleave( mouseleaveRow )\n .click( clickRow );\n\n $( document ).mousemove( mousemoveDocument );\n\n};\n"],"names":["init","opts","$menu","$","this","activeRow","mouseLocs","lastDelayLoc","timeoutId","options","extend","rowSelector","submenuSelector","submenuDirection","tolerance","enter","noop","exit","activate","deactivate","exitMenu","row","possiblyActivate","delay","activationDelay","setTimeout","is","offset","upperLeft","x","left","y","top","upperRight","outerWidth","lowerLeft","outerHeight","lowerRight","loc","length","prevLoc","slope","a","b","decreasingCorner","increasingCorner","decreasingSlope","increasingSlope","prevDecreasingSlope","prevIncreasingSlope","mouseleave","clearTimeout","find","mouseenter","click","document","mousemove","e","push","pageX","pageY","shift","fn","menuAim","each","call"],"sourceRoot":""}