dimmer.js 20 KB

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