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.

525 lines
15 KiB

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