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.

692 lines
20 KiB

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