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.

568 lines
16 KiB

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