PHP Classes

File: engine/modules/contrib/foundation/js/plugins/foundation.dropdown.js

Recommend this page to a friend!
  Classes of Aldo Tripiciano   Quanta CMS   engine/modules/contrib/foundation/js/plugins/foundation.dropdown.js   Download  
File: engine/modules/contrib/foundation/js/plugins/foundation.dropdown.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Quanta CMS
Manage content that works without a database
Author: By
Last change:
Date: 5 years ago
Size: 15,288 bytes
 

Contents

Class file image Download
'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } !function ($) { /** * Dropdown module. * @module foundation.dropdown * @requires foundation.util.keyboard * @requires foundation.util.box * @requires foundation.util.triggers */ var Dropdown = function () { /** * Creates a new instance of a dropdown. * @class * @param {jQuery} element - jQuery object to make into a dropdown. * Object should be of the dropdown panel, rather than its anchor. * @param {Object} options - Overrides to the default plugin settings. */ function Dropdown(element, options) { _classCallCheck(this, Dropdown); this.$element = element; this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options); this._init(); Foundation.registerPlugin(this, 'Dropdown'); Foundation.Keyboard.register('Dropdown', { 'ENTER': 'open', 'SPACE': 'open', 'ESCAPE': 'close' }); } /** * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor. * @function * @private */ _createClass(Dropdown, [{ key: '_init', value: function _init() { var $id = this.$element.attr('id'); this.$anchor = $('[data-toggle="' + $id + '"]').length ? $('[data-toggle="' + $id + '"]') : $('[data-open="' + $id + '"]'); this.$anchor.attr({ 'aria-controls': $id, 'data-is-focus': false, 'data-yeti-box': $id, 'aria-haspopup': true, 'aria-expanded': false }); if (this.options.parentClass) { this.$parent = this.$element.parents('.' + this.options.parentClass); } else { this.$parent = null; } this.options.positionClass = this.getPositionClass(); this.counter = 4; this.usedPositions = []; this.$element.attr({ 'aria-hidden': 'true', 'data-yeti-box': $id, 'data-resize': $id, 'aria-labelledby': this.$anchor[0].id || Foundation.GetYoDigits(6, 'dd-anchor') }); this._events(); } /** * Helper function to determine current orientation of dropdown pane. * @function * @returns {String} position - string value of a position class. */ }, { key: 'getPositionClass', value: function getPositionClass() { var verticalPosition = this.$element[0].className.match(/(top|left|right|bottom)/g); verticalPosition = verticalPosition ? verticalPosition[0] : ''; var horizontalPosition = /float-(\S+)/.exec(this.$anchor[0].className); horizontalPosition = horizontalPosition ? horizontalPosition[1] : ''; var position = horizontalPosition ? horizontalPosition + ' ' + verticalPosition : verticalPosition; return position; } /** * Adjusts the dropdown panes orientation by adding/removing positioning classes. * @function * @private * @param {String} position - position class to remove. */ }, { key: '_reposition', value: function _reposition(position) { this.usedPositions.push(position ? position : 'bottom'); //default, try switching to opposite side if (!position && this.usedPositions.indexOf('top') < 0) { this.$element.addClass('top'); } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) { this.$element.removeClass(position); } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) { this.$element.removeClass(position).addClass('right'); } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) { this.$element.removeClass(position).addClass('left'); } //if default change didn't work, try bottom or left first else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) { this.$element.addClass('left'); } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) { this.$element.removeClass(position).addClass('left'); } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) { this.$element.removeClass(position); } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) { this.$element.removeClass(position); } //if nothing cleared, set to bottom else { this.$element.removeClass(position); } this.classChanged = true; this.counter--; } /** * Sets the position and orientation of the dropdown pane, checks for collisions. * Recursively calls itself if a collision is detected, with a new position class. * @function * @private */ }, { key: '_setPosition', value: function _setPosition() { if (this.$anchor.attr('aria-expanded') === 'false') { return false; } var position = this.getPositionClass(), $eleDims = Foundation.Box.GetDimensions(this.$element), $anchorDims = Foundation.Box.GetDimensions(this.$anchor), _this = this, direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top', param = direction === 'top' ? 'height' : 'width', offset = param === 'height' ? this.options.vOffset : this.options.hOffset; if ($eleDims.width >= $eleDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.$element, this.$parent)) { var newWidth = $eleDims.windowDims.width, parentHOffset = 0; if (this.$parent) { var $parentDims = Foundation.Box.GetDimensions(this.$parent), parentHOffset = $parentDims.offset.left; if ($parentDims.width < newWidth) { newWidth = $parentDims.width; } } this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, 'center bottom', this.options.vOffset, this.options.hOffset + parentHOffset, true)).css({ 'width': newWidth - this.options.hOffset * 2, 'height': 'auto' }); this.classChanged = true; return false; } this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, position, this.options.vOffset, this.options.hOffset)); while (!Foundation.Box.ImNotTouchingYou(this.$element, this.$parent, true) && this.counter) { this._reposition(position); this._setPosition(); } } /** * Adds event listeners to the element utilizing the triggers utility library. * @function * @private */ }, { key: '_events', value: function _events() { var _this = this; this.$element.on({ 'open.zf.trigger': this.open.bind(this), 'close.zf.trigger': this.close.bind(this), 'toggle.zf.trigger': this.toggle.bind(this), 'resizeme.zf.trigger': this._setPosition.bind(this) }); if (this.options.hover) { this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () { var bodyData = $('body').data(); if (typeof bodyData.whatinput === 'undefined' || bodyData.whatinput === 'mouse') { clearTimeout(_this.timeout); _this.timeout = setTimeout(function () { _this.open(); _this.$anchor.data('hover', true); }, _this.options.hoverDelay); } }).on('mouseleave.zf.dropdown', function () { clearTimeout(_this.timeout); _this.timeout = setTimeout(function () { _this.close(); _this.$anchor.data('hover', false); }, _this.options.hoverDelay); }); if (this.options.hoverPane) { this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () { clearTimeout(_this.timeout); }).on('mouseleave.zf.dropdown', function () { clearTimeout(_this.timeout); _this.timeout = setTimeout(function () { _this.close(); _this.$anchor.data('hover', false); }, _this.options.hoverDelay); }); } } this.$anchor.add(this.$element).on('keydown.zf.dropdown', function (e) { var $target = $(this), visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element); Foundation.Keyboard.handleKey(e, 'Dropdown', { open: function () { if ($target.is(_this.$anchor)) { _this.open(); _this.$element.attr('tabindex', -1).focus(); e.preventDefault(); } }, close: function () { _this.close(); _this.$anchor.focus(); } }); }); } /** * Adds an event handler to the body to close any dropdowns on a click. * @function * @private */ }, { key: '_addBodyHandler', value: function _addBodyHandler() { var $body = $(document.body).not(this.$element), _this = this; $body.off('click.zf.dropdown').on('click.zf.dropdown', function (e) { if (_this.$anchor.is(e.target) || _this.$anchor.find(e.target).length) { return; } if (_this.$element.find(e.target).length) { return; } _this.close(); $body.off('click.zf.dropdown'); }); } /** * Opens the dropdown pane, and fires a bubbling event to close other dropdowns. * @function * @fires Dropdown#closeme * @fires Dropdown#show */ }, { key: 'open', value: function open() { // var _this = this; /** * Fires to close other open dropdowns * @event Dropdown#closeme */ this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id')); this.$anchor.addClass('hover').attr({ 'aria-expanded': true }); // this.$element/*.show()*/; this._setPosition(); this.$element.addClass('is-open').attr({ 'aria-hidden': false }); if (this.options.autoFocus) { var $focusable = Foundation.Keyboard.findFocusable(this.$element); if ($focusable.length) { $focusable.eq(0).focus(); } } if (this.options.closeOnClick) { this._addBodyHandler(); } if (this.options.trapFocus) { Foundation.Keyboard.trapFocus(this.$element); } /** * Fires once the dropdown is visible. * @event Dropdown#show */ this.$element.trigger('show.zf.dropdown', [this.$element]); } /** * Closes the open dropdown pane. * @function * @fires Dropdown#hide */ }, { key: 'close', value: function close() { if (!this.$element.hasClass('is-open')) { return false; } this.$element.removeClass('is-open').attr({ 'aria-hidden': true }); this.$anchor.removeClass('hover').attr('aria-expanded', false); if (this.classChanged) { var curPositionClass = this.getPositionClass(); if (curPositionClass) { this.$element.removeClass(curPositionClass); } this.$element.addClass(this.options.positionClass) /*.hide()*/.css({ height: '', width: '' }); this.classChanged = false; this.counter = 4; this.usedPositions.length = 0; } this.$element.trigger('hide.zf.dropdown', [this.$element]); if (this.options.trapFocus) { Foundation.Keyboard.releaseFocus(this.$element); } } /** * Toggles the dropdown pane's visibility. * @function */ }, { key: 'toggle', value: function toggle() { if (this.$element.hasClass('is-open')) { if (this.$anchor.data('hover')) return; this.close(); } else { this.open(); } } /** * Destroys the dropdown. * @function */ }, { key: 'destroy', value: function destroy() { this.$element.off('.zf.trigger').hide(); this.$anchor.off('.zf.dropdown'); Foundation.unregisterPlugin(this); } }]); return Dropdown; }(); Dropdown.defaults = { /** * Class that designates bounding container of Dropdown (Default: window) * @option * @example 'dropdown-parent' */ parentClass: null, /** * Amount of time to delay opening a submenu on hover event. * @option * @example 250 */ hoverDelay: 250, /** * Allow submenus to open on hover events * @option * @example false */ hover: false, /** * Don't close dropdown when hovering over dropdown pane * @option * @example true */ hoverPane: false, /** * Number of pixels between the dropdown pane and the triggering element on open. * @option * @example 1 */ vOffset: 1, /** * Number of pixels between the dropdown pane and the triggering element on open. * @option * @example 1 */ hOffset: 1, /** * Class applied to adjust open position. JS will test and fill this in. * @option * @example 'top' */ positionClass: '', /** * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands. * @option * @example false */ trapFocus: false, /** * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening. * @option * @example true */ autoFocus: false, /** * Allows a click on the body to close the dropdown. * @option * @example false */ closeOnClick: false }; // Window exports Foundation.plugin(Dropdown, 'Dropdown'); }(jQuery);