You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
11 KiB

2 years ago
  1. /**
  2. * Toolbar.js
  3. *
  4. * @fileoverview jQuery plugin that creates tooltip style toolbars.
  5. * @link http://paulkinzett.github.com/toolbar/
  6. * @author Paul Kinzett (http://kinzett.co.nz/)
  7. * @version 1.1.0
  8. * @requires jQuery 1.7+
  9. *
  10. * @license jQuery Toolbar Plugin v1.1.0
  11. * http://paulkinzett.github.com/toolbar/
  12. * Copyright 2013 - 2015 Paul Kinzett (http://kinzett.co.nz/)
  13. * Released under the MIT license.
  14. * <https://raw.github.com/paulkinzett/toolbar/master/LICENSE.txt>
  15. */
  16. if (typeof Object.create !== 'function') {
  17. Object.create = function (obj) {
  18. function F() { }
  19. F.prototype = obj;
  20. return new F();
  21. };
  22. }
  23. (function ($, window, document, undefined) {
  24. var ToolBar = {
  25. init: function (options, elem) {
  26. var self = this;
  27. self.elem = elem;
  28. self.$elem = $(elem);
  29. self.options = $.extend({}, $.fn.toolbar.options, options);
  30. self.metadata = self.$elem.data();
  31. self.overrideOptions();
  32. self.toolbar = $('<div class="tool-container" />')
  33. .addClass('tool-' + self.options.position)
  34. .addClass('toolbar-' + self.options.style)
  35. .append('<div class="tool-items" />')
  36. .append('<div class="arrow" />')
  37. .appendTo('body')
  38. .css('opacity', 0)
  39. .hide();
  40. self.toolbar_arrow = self.toolbar.find('.arrow');
  41. self.initializeToolbar();
  42. },
  43. overrideOptions: function () {
  44. var self = this;
  45. $.each(self.options, function ($option) {
  46. if (typeof (self.$elem.data('toolbar-' + $option)) != "undefined") {
  47. self.options[$option] = self.$elem.data('toolbar-' + $option);
  48. }
  49. });
  50. },
  51. initializeToolbar: function () {
  52. var self = this;
  53. self.populateContent();
  54. self.setTrigger();
  55. self.toolbarWidth = self.toolbar.width();
  56. },
  57. setTrigger: function () {
  58. var self = this;
  59. if (self.options.event != 'click') {
  60. var moveTime;
  61. function decideTimeout() {
  62. if (self.$elem.hasClass('pressed')) {
  63. moveTime = setTimeout(function () {
  64. self.hide();
  65. }, 150);
  66. } else {
  67. clearTimeout(moveTime);
  68. };
  69. };
  70. self.$elem.on({
  71. mouseenter: function (event) {
  72. if (self.$elem.hasClass('pressed')) {
  73. clearTimeout(moveTime);
  74. } else {
  75. self.show();
  76. }
  77. }
  78. });
  79. self.$elem.parent().on({
  80. mouseleave: function (event) { decideTimeout(); }
  81. });
  82. self.$elem.on({
  83. mouseleave: function (event) {
  84. decideTimeout();
  85. }
  86. });
  87. $('.tool-container').on({
  88. mouseenter: function (event) { clearTimeout(moveTime); },
  89. mouseleave: function (event) { decideTimeout(); }
  90. });
  91. }
  92. if (self.options.event == 'click') {
  93. self.$elem.on('click', function (event) {
  94. event.preventDefault();
  95. if (self.$elem.hasClass('pressed')) {
  96. self.hide();
  97. } else {
  98. self.show();
  99. }
  100. });
  101. if (self.options.hideOnClick) {
  102. $('html').on("click.toolbar", function (event) {
  103. if (event.target != self.elem &&
  104. self.$elem.has(event.target).length === 0 &&
  105. self.toolbar.has(event.target).length === 0 &&
  106. self.toolbar.is(":visible")) {
  107. self.hide();
  108. }
  109. });
  110. }
  111. }
  112. if (self.options.hover) {
  113. var moveTime;
  114. function decideTimeout() {
  115. if (self.$elem.hasClass('pressed')) {
  116. moveTime = setTimeout(function () {
  117. self.hide();
  118. }, 150);
  119. } else {
  120. clearTimeout(moveTime);
  121. };
  122. };
  123. self.$elem.on({
  124. mouseenter: function (event) {
  125. if (self.$elem.hasClass('pressed')) {
  126. clearTimeout(moveTime);
  127. } else {
  128. self.show();
  129. }
  130. }
  131. });
  132. self.$elem.parent().on({
  133. mouseleave: function (event) { decideTimeout(); }
  134. });
  135. self.$elem.on({
  136. mouseleave: function (event) {
  137. decideTimeout();
  138. }
  139. });
  140. $('.tool-container').on({
  141. mouseenter: function (event) { clearTimeout(moveTime); },
  142. mouseleave: function (event) { decideTimeout(); }
  143. });
  144. }
  145. $(window).resize(function (event) {
  146. event.stopPropagation();
  147. if (self.toolbar.is(":visible")) {
  148. self.toolbarCss = self.getCoordinates(self.options.position, 20);
  149. self.collisionDetection();
  150. self.toolbar.css(self.toolbarCss);
  151. self.toolbar_arrow.css(self.arrowCss);
  152. }
  153. });
  154. },
  155. populateContent: function () {
  156. var self = this;
  157. var location = self.toolbar.find('.tool-items');
  158. var content = $(self.options.content).clone(true).find('a').addClass('tool-item');
  159. location.html(content);
  160. location.find('.tool-item').on('click', function (event) {
  161. event.preventDefault();
  162. self.$elem.trigger('toolbarItemClick', this);
  163. });
  164. },
  165. calculatePosition: function () {
  166. var self = this;
  167. self.arrowCss = {};
  168. self.toolbarCss = self.getCoordinates(self.options.position, self.options.adjustment);
  169. self.toolbarCss.position = 'absolute';
  170. self.toolbarCss.zIndex = self.options.zIndex;
  171. self.collisionDetection();
  172. self.toolbar.css(self.toolbarCss);
  173. self.toolbar_arrow.css(self.arrowCss);
  174. },
  175. getCoordinates: function (position, adjustment) {
  176. var self = this;
  177. self.coordinates = self.$elem.offset();
  178. if (self.options.adjustment && self.options.adjustment[self.options.position]) {
  179. adjustment = self.options.adjustment[self.options.position] + adjustment;
  180. }
  181. switch (self.options.position) {
  182. case 'top':
  183. return {
  184. left: self.coordinates.left - (self.toolbar.width() / 2) + (self.$elem.outerWidth() / 2),
  185. top: self.coordinates.top - self.$elem.outerHeight() - adjustment,
  186. right: 'auto'
  187. };
  188. case 'left':
  189. return {
  190. left: self.coordinates.left - (self.toolbar.width() / 2) - (self.$elem.outerWidth() / 2) - adjustment,
  191. top: self.coordinates.top - (self.toolbar.height() / 2) + (self.$elem.outerHeight() / 2),
  192. right: 'auto'
  193. };
  194. case 'right':
  195. return {
  196. left: self.coordinates.left + (self.toolbar.width() / 2) + (self.$elem.outerWidth() / 2) + adjustment,
  197. top: self.coordinates.top - (self.toolbar.height() / 2) + (self.$elem.outerHeight() / 2),
  198. right: 'auto'
  199. };
  200. case 'bottom':
  201. return {
  202. left: self.coordinates.left - (self.toolbar.width() / 2) + (self.$elem.outerWidth() / 2),
  203. top: self.coordinates.top + self.$elem.outerHeight() + adjustment,
  204. right: 'auto'
  205. };
  206. }
  207. },
  208. collisionDetection: function () {
  209. var self = this;
  210. var edgeOffset = 20;
  211. if (self.options.position == 'top' || self.options.position == 'bottom') {
  212. self.arrowCss = { left: '50%', right: '50%' };
  213. if (self.toolbarCss.left < edgeOffset) {
  214. self.toolbarCss.left = edgeOffset;
  215. self.arrowCss.left = self.$elem.offset().left + self.$elem.width() / 2 - (edgeOffset);
  216. }
  217. else if (($(window).width() - (self.toolbarCss.left + self.toolbarWidth)) < edgeOffset) {
  218. self.toolbarCss.right = edgeOffset;
  219. self.toolbarCss.left = 'auto';
  220. self.arrowCss.left = 'auto';
  221. self.arrowCss.right = ($(window).width() - self.$elem.offset().left) - (self.$elem.width() / 2) - (edgeOffset) - 5;
  222. }
  223. }
  224. },
  225. show: function () {
  226. var self = this;
  227. self.$elem.addClass('pressed');
  228. self.calculatePosition();
  229. self.toolbar.show().css({ 'opacity': 1 }).addClass('animate-' + self.options.animation);
  230. self.$elem.trigger('toolbarShown');
  231. },
  232. hide: function () {
  233. var self = this;
  234. var animation = { 'opacity': 0 };
  235. self.$elem.removeClass('pressed');
  236. switch (self.options.position) {
  237. case 'top':
  238. animation.top = '+=20';
  239. break;
  240. case 'left':
  241. animation.left = '+=20';
  242. break;
  243. case 'right':
  244. animation.left = '-=20';
  245. break;
  246. case 'bottom':
  247. animation.top = '-=20';
  248. break;
  249. }
  250. self.toolbar.animate(animation, 200, function () {
  251. self.toolbar.hide();
  252. });
  253. self.$elem.trigger('toolbarHidden');
  254. },
  255. getToolbarElement: function () {
  256. return this.toolbar.find('.tool-items');
  257. }
  258. };
  259. $.fn.toolbar = function (options) {
  260. if ($.isPlainObject(options)) {
  261. return this.each(function () {
  262. var toolbarObj = Object.create(ToolBar);
  263. toolbarObj.init(options, this);
  264. $(this).data('toolbarObj', toolbarObj);
  265. });
  266. } else if (typeof options === 'string' && options.indexOf('_') !== 0) {
  267. var toolbarObj = $(this).data('toolbarObj');
  268. var method = toolbarObj[options];
  269. return method.apply(toolbarObj, $.makeArray(arguments).slice(1));
  270. }
  271. };
  272. $.fn.toolbar.options = {
  273. content: '#myContent',
  274. position: 'top',
  275. hideOnClick: false,
  276. zIndex: 120,
  277. hover: false,
  278. style: 'default',
  279. animation: 'standard',
  280. adjustment: 10
  281. };
  282. })(jQuery, window, document);