Blame | Letzte Änderung | Log anzeigen | RSS feed
/*!* Bootstrap Context Menu* Author: @sydcanem* https://github.com/sydcanem/bootstrap-contextmenu** Inspired by Bootstrap's dropdown plugin.* Bootstrap (http://getbootstrap.com).** Licensed under MIT* ========================================================= */;(function($) {'use strict';/* CONTEXTMENU CLASS DEFINITION* ============================ */var toggle = '[data-toggle="context"]';var ContextMenu = function (element, options) {this.$element = $(element);this.before = options.before || this.before;this.onItem = options.onItem || this.onItem;this.scopes = options.scopes || null;if (options.target) {this.$element.data('target', options.target);}this.listen();};ContextMenu.prototype = {constructor: ContextMenu,show: function(e) {var $menu, evt, tp, items, relatedTarget = { relatedTarget: this, target: e.currentTarget };if (this.isDisabled()) return;this.closemenu();if (!this.before.call(this,e,$(e.currentTarget))) return;$menu = this.getMenu();$menu.trigger(evt = $.Event('show.bs.context', relatedTarget));tp = this.getPosition(e, $menu);items = 'li:not(.divider)';$menu.attr('style', '').css(tp).addClass('open').on('click.context.data-api', items, $.proxy(this.onItem, this, $(e.currentTarget))).trigger('shown.bs.context', relatedTarget);// Delegating the `closemenu` only on the currently opened menu.// This prevents other opened menus from closing.$('html').on('click.context.data-api', $menu.selector, $.proxy(this.closemenu, this));return false;},closemenu: function(e) {var $menu, evt, items, relatedTarget;$menu = this.getMenu();if(!$menu.hasClass('open')) return;relatedTarget = { relatedTarget: this };$menu.trigger(evt = $.Event('hide.bs.context', relatedTarget));items = 'li:not(.divider)';$menu.removeClass('open').off('click.context.data-api', items).trigger('hidden.bs.context', relatedTarget);$('html').off('click.context.data-api', $menu.selector);// Don't propagate click event so other currently// opened menus won't close.return false;},keydown: function(e) {if (e.which == 27) this.closemenu(e);},before: function(e) {return true;},onItem: function(e) {return true;},listen: function () {this.$element.on('contextmenu.context.data-api', this.scopes, $.proxy(this.show, this));$('html').on('click.context.data-api', $.proxy(this.closemenu, this));$('html').on('keydown.context.data-api', $.proxy(this.keydown, this));},destroy: function() {this.$element.off('.context.data-api').removeData('context');$('html').off('.context.data-api');},isDisabled: function() {return this.$element.hasClass('disabled') ||this.$element.attr('disabled');},getMenu: function () {var selector = this.$element.data('target'), $menu;if (!selector) {selector = this.$element.attr('href');selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7}$menu = $(selector);return $menu && $menu.length ? $menu : this.$element.find(selector);},getPosition: function(e, $menu) {var mouseX = e.clientX, mouseY = e.clientY, boundsX = $(window).width(), boundsY = $(window).height(), menuWidth = $menu.find('.dropdown-menu').outerWidth(), menuHeight = $menu.find('.dropdown-menu').outerHeight(), tp = {"position":"absolute","z-index":9999}, Y, X, parentOffset;if (mouseY + menuHeight > boundsY) {Y = {"top": mouseY - menuHeight + $(window).scrollTop()};} else {Y = {"top": mouseY + $(window).scrollTop()};}if ((mouseX + menuWidth > boundsX) && ((mouseX - menuWidth) > 0)) {X = {"left": mouseX - menuWidth + $(window).scrollLeft()};} else {X = {"left": mouseX + $(window).scrollLeft()};}// If context-menu's parent is positioned using absolute or relative positioning,// the calculated mouse position will be incorrect.// Adjust the position of the menu by its offset parent position.parentOffset = $menu.offsetParent().offset();X.left = X.left - parentOffset.left;Y.top = Y.top - parentOffset.top;return $.extend(tp, Y, X);}};/* CONTEXT MENU PLUGIN DEFINITION* ========================== */$.fn.contextmenu = function (option,e) {return this.each(function () {var $this = $(this), data = $this.data('context'), options = (typeof option == 'object') && option;if (!data) $this.data('context', (data = new ContextMenu($this, options)));if (typeof option == 'string') data[option].call(data, e);});};$.fn.contextmenu.Constructor = ContextMenu;/* APPLY TO STANDARD CONTEXT MENU ELEMENTS* =================================== */$(document).on('contextmenu.context.data-api', function() {$(toggle).each(function () {var data = $(this).data('context');if (!data) return;data.closemenu();});}).on('contextmenu.context.data-api', toggle, function(e) {$(this).contextmenu('show', e);e.preventDefault();e.stopPropagation();});}(jQuery));