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.

626 lines
18 KiB

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