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.

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