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.

494 lines
14 KiB

  1. /* ******************************
  2. Semantic Module: Dimmer
  3. Author: Jack Lukic
  4. Notes: First Commit May 30, 2013
  5. Simple plug-in which maintains the state for ui dimmer
  6. ****************************** */
  7. ;(function ( $, window, document, undefined ) {
  8. $.fn.dimmer = function(parameters) {
  9. var
  10. $allModules = $(this),
  11. settings = ( $.isPlainObject(parameters) )
  12. ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
  13. : $.fn.dimmer.settings,
  14. selector = settings.selector,
  15. namespace = settings.namespace,
  16. className = settings.className,
  17. error = settings.error,
  18. eventNamespace = '.' + namespace,
  19. moduleNamespace = 'module-' + namespace,
  20. moduleSelector = $allModules.selector || '',
  21. time = new Date().getTime(),
  22. performance = [],
  23. query = arguments[0],
  24. methodInvoked = (typeof query == 'string'),
  25. queryArguments = [].slice.call(arguments, 1),
  26. invokedResponse
  27. ;
  28. $allModules
  29. .each(function() {
  30. var
  31. $module = $(this),
  32. $dimmer = $module.children(selector.dimmer).first(),
  33. element = this,
  34. instance = $dimmer.data(moduleNamespace),
  35. module
  36. ;
  37. module = {
  38. initialize: function() {
  39. if( module.is.dimmer() ) {
  40. $dimmer = $module;
  41. $module = $dimmer.parent();
  42. module.debug('Module initialized as dimmer');
  43. }
  44. else {
  45. if( module.has.dimmer() ) {
  46. $dimmer = $module.find(selector.dimmer);
  47. module.debug('Module initialized with found dimmer');
  48. }
  49. else {
  50. $dimmer = settings.template.dimmer();
  51. $dimmer
  52. .appendTo($module)
  53. ;
  54. module.debug('Module initialized with created dimmer');
  55. }
  56. if(settings.on == 'hover') {
  57. $module
  58. .on('mouseenter' + eventNamespace, module.show)
  59. .on('mouseleave' + eventNamespace, module.hide)
  60. ;
  61. }
  62. else if(settings.on == 'click') {
  63. $module
  64. .on('click' + eventNamespace, module.toggle)
  65. ;
  66. }
  67. }
  68. $module
  69. .addClass(className.dimmable)
  70. ;
  71. if(settings.closable) {
  72. $dimmer
  73. .on('click', module.event.click)
  74. ;
  75. }
  76. module.instantiate();
  77. },
  78. instantiate: function() {
  79. module.verbose('Storing instance of module');
  80. instance = module;
  81. $dimmer
  82. .data(moduleNamespace, instance)
  83. ;
  84. },
  85. destroy: function() {
  86. module.verbose('Destroying previous module');
  87. $module
  88. .off(namespace)
  89. ;
  90. },
  91. event: {
  92. click: function(event) {
  93. module.verbose('Determining if event occured on dimmer', event);
  94. if( $dimmer.find(event.target).size() === 0 || $(event.target).is(selector.content) ) {
  95. module.hide();
  96. }
  97. }
  98. },
  99. animate: {
  100. show: function() {
  101. module.set.dimmed();
  102. if(settings.animation.show == 'css') {
  103. module.verbose('Showing dimmer animation with css');
  104. $dimmer
  105. .one(module.get.animationEndEvent(), function() {
  106. module.set.active();
  107. $dimmer.removeClass(className.show);
  108. })
  109. .addClass(className.show)
  110. ;
  111. }
  112. else if(settings.animation.show == 'fade') {
  113. module.verbose('Showing dimmer animation with javascript');
  114. $dimmer
  115. .stop()
  116. .css({
  117. opacity : 0,
  118. width : '100%',
  119. height : '100%'
  120. })
  121. .fadeTo(settings.duration, 1, function() {
  122. $dimmer.removeAttr('style');
  123. module.set.active();
  124. })
  125. ;
  126. }
  127. },
  128. hide: function() {
  129. module.remove.dimmed();
  130. if(settings.animation.hide == 'css') {
  131. module.verbose('Hiding dimmer with css');
  132. $dimmer
  133. .one(module.get.animationEndEvent(), function(){
  134. module.remove.active();
  135. $dimmer.removeClass(className.hide);
  136. })
  137. .addClass(className.hide)
  138. ;
  139. }
  140. else if(settings.animation.hide == 'fade') {
  141. module.verbose('Hiding dimmer with javascript');
  142. $dimmer
  143. .stop()
  144. .fadeOut( (settings.duration * 0.75) , function() {
  145. $dimmer.removeAttr('style');
  146. module.remove.active();
  147. })
  148. ;
  149. }
  150. else if( $.isFunction(settings.animation.hide) ) {
  151. $.proxy(settings.animation.hide, $dimmer)();
  152. }
  153. }
  154. },
  155. get: {
  156. animationEndEvent: function() {
  157. var
  158. element = document.createElement('element'),
  159. animations = {
  160. 'animation' : 'animationend',
  161. 'OAnimation' : 'oAnimationEnd',
  162. 'MozAnimation' : 'animationend',
  163. 'WebkitAnimation' : 'webkitAnimationEnd'
  164. },
  165. animation
  166. ;
  167. for(animation in animations){
  168. if( element.style[animation] !== undefined ){
  169. return animations[animation];
  170. }
  171. }
  172. }
  173. },
  174. has: {
  175. dimmer: function() {
  176. return ( $module.children(selector.dimmer).size() > 0 );
  177. }
  178. },
  179. is: {
  180. animating: function() {
  181. return ( $dimmer.hasClass(className.show) || $dimmer.hasClass(className.hide) || $dimmer.is(':animated') );
  182. },
  183. dimmer: function() {
  184. return $module.is(selector.dimmer);
  185. },
  186. pageDimmer: function() {
  187. return $module.is(selector.pageDimmer);
  188. },
  189. dimmable: function() {
  190. return $module.is(selector.dimmable);
  191. },
  192. enabled: function() {
  193. return !$module.hasClass(className.disabled);
  194. },
  195. disabled: function() {
  196. return $module.hasClass(className.disabled);
  197. },
  198. active: function() {
  199. return $dimmer.hasClass(className.active);
  200. }
  201. },
  202. can: {
  203. show: function() {
  204. return !$dimmer.hasClass(className.disabled);
  205. }
  206. },
  207. set: {
  208. active: function() {
  209. $dimmer.addClass(className.active);
  210. },
  211. dimmed: function() {
  212. $module.addClass(className.dimmed);
  213. },
  214. disabled: function() {
  215. $dimmer.addClass(className.disabled);
  216. }
  217. },
  218. remove: {
  219. active: function() {
  220. $dimmer.removeClass(className.active);
  221. },
  222. dimmed: function() {
  223. $module.removeClass(className.dimmed);
  224. },
  225. disabled: function() {
  226. $dimmer.removeClass(className.disabled);
  227. }
  228. },
  229. show: function() {
  230. module.debug('Showing dimmer', $dimmer);
  231. if( (!module.is.active() || module.is.animating() ) && module.is.enabled() ) {
  232. module.animate.show();
  233. $.proxy(settings.onShow, element)();
  234. $.proxy(settings.onChange, element)();
  235. }
  236. else {
  237. module.debug('Dimmer is already shown or disabled');
  238. }
  239. },
  240. hide: function() {
  241. if( module.is.active() || module.is.animating() ) {
  242. module.debug('Hiding dimmer', $dimmer);
  243. module.animate.hide();
  244. $.proxy(settings.onHide, element)();
  245. $.proxy(settings.onChange, element)();
  246. }
  247. else {
  248. module.debug('Dimmer is not visible');
  249. }
  250. },
  251. toggle: function() {
  252. module.verbose('Toggling dimmer visibility', $dimmer);
  253. if( module.is.hidden() ) {
  254. module.show();
  255. }
  256. else {
  257. module.hide();
  258. }
  259. },
  260. setting: function(name, value) {
  261. if(value !== undefined) {
  262. if( $.isPlainObject(name) ) {
  263. $.extend(true, settings, name);
  264. }
  265. else {
  266. settings[name] = value;
  267. }
  268. }
  269. else {
  270. return settings[name];
  271. }
  272. },
  273. internal: function(name, value) {
  274. if(value !== undefined) {
  275. if( $.isPlainObject(name) ) {
  276. $.extend(true, module, name);
  277. }
  278. else {
  279. module[name] = value;
  280. }
  281. }
  282. else {
  283. return module[name];
  284. }
  285. },
  286. debug: function() {
  287. if(settings.debug) {
  288. if(settings.performance) {
  289. module.performance.log(arguments);
  290. }
  291. else {
  292. module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  293. }
  294. }
  295. },
  296. verbose: function() {
  297. if(settings.verbose && settings.debug) {
  298. if(settings.performance) {
  299. module.performance.log(arguments);
  300. }
  301. else {
  302. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  303. }
  304. }
  305. },
  306. error: function() {
  307. module.error = Function.prototype.bind.call(console.log, console, settings.moduleName + ':');
  308. },
  309. performance: {
  310. log: function(message) {
  311. var
  312. currentTime,
  313. executionTime,
  314. previousTime
  315. ;
  316. if(settings.performance) {
  317. currentTime = new Date().getTime();
  318. previousTime = time || currentTime;
  319. executionTime = currentTime - previousTime;
  320. time = currentTime;
  321. performance.push({
  322. 'Element' : element,
  323. 'Name' : message[0],
  324. 'Arguments' : [].slice.call(message, 1) || '',
  325. 'Execution Time' : executionTime
  326. });
  327. }
  328. clearTimeout(module.performance.timer);
  329. module.performance.timer = setTimeout(module.performance.display, 100);
  330. },
  331. display: function() {
  332. var
  333. title = settings.moduleName + ':',
  334. totalTime = 0
  335. ;
  336. time = false;
  337. clearTimeout(module.performance.timer);
  338. $.each(performance, function(index, data) {
  339. totalTime += data['Execution Time'];
  340. });
  341. title += ' ' + totalTime + 'ms';
  342. if(moduleSelector) {
  343. title += ' \'' + moduleSelector + '\'';
  344. }
  345. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  346. console.groupCollapsed(title);
  347. if(console.table) {
  348. console.table(performance);
  349. }
  350. else {
  351. $.each(performance, function(index, data) {
  352. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  353. });
  354. }
  355. console.groupEnd();
  356. }
  357. performance = [];
  358. }
  359. },
  360. invoke: function(query, passedArguments, context) {
  361. var
  362. maxDepth,
  363. found
  364. ;
  365. passedArguments = passedArguments || queryArguments;
  366. context = element || context;
  367. if(typeof query == 'string' && instance !== undefined) {
  368. query = query.split(/[\. ]/);
  369. maxDepth = query.length - 1;
  370. $.each(query, function(depth, value) {
  371. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  372. instance = instance[value];
  373. }
  374. else if( instance[value] !== undefined ) {
  375. found = instance[value];
  376. }
  377. else {
  378. module.error(error.method);
  379. }
  380. });
  381. }
  382. if ( $.isFunction( found ) ) {
  383. return found.apply(context, passedArguments);
  384. }
  385. return found || false;
  386. }
  387. };
  388. if(methodInvoked) {
  389. if(instance === undefined) {
  390. module.initialize();
  391. }
  392. invokedResponse = module.invoke(query);
  393. }
  394. else {
  395. if(instance !== undefined) {
  396. module.destroy();
  397. }
  398. module.initialize();
  399. }
  400. })
  401. ;
  402. return (invokedResponse)
  403. ? invokedResponse
  404. : this
  405. ;
  406. };
  407. $.fn.dimmer.settings = {
  408. moduleName : 'Dimmer',
  409. namespace : 'dimmer',
  410. verbose : true,
  411. debug : true,
  412. performance : true,
  413. animation : {
  414. show: 'css',
  415. hide: 'css'
  416. },
  417. on : false,
  418. closable : true,
  419. duration : 500,
  420. onChange : function(){},
  421. onShow : function(){},
  422. onHide : function(){},
  423. error : {
  424. method : 'The method you called is not defined.'
  425. },
  426. selector: {
  427. dimmable : '.ui.dimmable',
  428. dimmer : '.ui.dimmer',
  429. content : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
  430. },
  431. template: {
  432. dimmer: function() {
  433. return $('<div />').attr('class', 'ui dimmer');
  434. }
  435. },
  436. className : {
  437. active : 'active',
  438. animating : 'animating',
  439. dimmable : 'ui dimmable',
  440. dimmed : 'dimmed',
  441. disabled : 'disabled',
  442. hide : 'hide',
  443. show : 'show'
  444. }
  445. };
  446. })( jQuery, window , document );