modal.js 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. /*!
  2. * # Semantic UI 2.4.2 - Modal
  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.modal = function(parameters) {
  19. var
  20. $allModules = $(this),
  21. $window = $(window),
  22. $document = $(document),
  23. $body = $('body'),
  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. requestAnimationFrame = window.requestAnimationFrame
  31. || window.mozRequestAnimationFrame
  32. || window.webkitRequestAnimationFrame
  33. || window.msRequestAnimationFrame
  34. || function(callback) { setTimeout(callback, 0); },
  35. returnedValue
  36. ;
  37. $allModules
  38. .each(function() {
  39. var
  40. settings = ( $.isPlainObject(parameters) )
  41. ? $.extend(true, {}, $.fn.modal.settings, parameters)
  42. : $.extend({}, $.fn.modal.settings),
  43. selector = settings.selector,
  44. className = settings.className,
  45. namespace = settings.namespace,
  46. error = settings.error,
  47. eventNamespace = '.' + namespace,
  48. moduleNamespace = 'module-' + namespace,
  49. $module = $(this),
  50. $context = $(settings.context),
  51. $close = $module.find(selector.close),
  52. $allModals,
  53. $otherModals,
  54. $focusedElement,
  55. $dimmable,
  56. $dimmer,
  57. element = this,
  58. instance = $module.data(moduleNamespace),
  59. ignoreRepeatedEvents = false,
  60. elementEventNamespace,
  61. id,
  62. observer,
  63. module
  64. ;
  65. module = {
  66. initialize: function() {
  67. module.verbose('Initializing dimmer', $context);
  68. module.create.id();
  69. module.create.dimmer();
  70. module.refreshModals();
  71. module.bind.events();
  72. if(settings.observeChanges) {
  73. module.observeChanges();
  74. }
  75. module.instantiate();
  76. },
  77. instantiate: function() {
  78. module.verbose('Storing instance of modal');
  79. instance = module;
  80. $module
  81. .data(moduleNamespace, instance)
  82. ;
  83. },
  84. create: {
  85. dimmer: function() {
  86. var
  87. defaultSettings = {
  88. debug : settings.debug,
  89. variation : settings.centered
  90. ? false
  91. : 'top aligned',
  92. dimmerName : 'modals'
  93. },
  94. dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
  95. ;
  96. if($.fn.dimmer === undefined) {
  97. module.error(error.dimmer);
  98. return;
  99. }
  100. module.debug('Creating dimmer');
  101. $dimmable = $context.dimmer(dimmerSettings);
  102. if(settings.detachable) {
  103. module.verbose('Modal is detachable, moving content into dimmer');
  104. $dimmable.dimmer('add content', $module);
  105. }
  106. else {
  107. module.set.undetached();
  108. }
  109. $dimmer = $dimmable.dimmer('get dimmer');
  110. },
  111. id: function() {
  112. id = (Math.random().toString(16) + '000000000').substr(2, 8);
  113. elementEventNamespace = '.' + id;
  114. module.verbose('Creating unique id for element', id);
  115. }
  116. },
  117. destroy: function() {
  118. module.verbose('Destroying previous modal');
  119. $module
  120. .removeData(moduleNamespace)
  121. .off(eventNamespace)
  122. ;
  123. $window.off(elementEventNamespace);
  124. $dimmer.off(elementEventNamespace);
  125. $close.off(eventNamespace);
  126. $context.dimmer('destroy');
  127. },
  128. observeChanges: function() {
  129. if('MutationObserver' in window) {
  130. observer = new MutationObserver(function(mutations) {
  131. module.debug('DOM tree modified, refreshing');
  132. module.refresh();
  133. });
  134. observer.observe(element, {
  135. childList : true,
  136. subtree : true
  137. });
  138. module.debug('Setting up mutation observer', observer);
  139. }
  140. },
  141. refresh: function() {
  142. module.remove.scrolling();
  143. module.cacheSizes();
  144. if(!module.can.useFlex()) {
  145. module.set.modalOffset();
  146. }
  147. module.set.screenHeight();
  148. module.set.type();
  149. },
  150. refreshModals: function() {
  151. $otherModals = $module.siblings(selector.modal);
  152. $allModals = $otherModals.add($module);
  153. },
  154. attachEvents: function(selector, event) {
  155. var
  156. $toggle = $(selector)
  157. ;
  158. event = $.isFunction(module[event])
  159. ? module[event]
  160. : module.toggle
  161. ;
  162. if($toggle.length > 0) {
  163. module.debug('Attaching modal events to element', selector, event);
  164. $toggle
  165. .off(eventNamespace)
  166. .on('click' + eventNamespace, event)
  167. ;
  168. }
  169. else {
  170. module.error(error.notFound, selector);
  171. }
  172. },
  173. bind: {
  174. events: function() {
  175. module.verbose('Attaching events');
  176. $module
  177. .on('click' + eventNamespace, selector.close, module.event.close)
  178. .on('click' + eventNamespace, selector.approve, module.event.approve)
  179. .on('click' + eventNamespace, selector.deny, module.event.deny)
  180. ;
  181. $window
  182. .on('resize' + elementEventNamespace, module.event.resize)
  183. ;
  184. },
  185. scrollLock: function() {
  186. // touch events default to passive, due to changes in chrome to optimize mobile perf
  187. $dimmable.get(0).addEventListener('touchmove', module.event.preventScroll, { passive: false });
  188. }
  189. },
  190. unbind: {
  191. scrollLock: function() {
  192. $dimmable.get(0).removeEventListener('touchmove', module.event.preventScroll, { passive: false });
  193. }
  194. },
  195. get: {
  196. id: function() {
  197. return (Math.random().toString(16) + '000000000').substr(2, 8);
  198. }
  199. },
  200. event: {
  201. approve: function() {
  202. if(ignoreRepeatedEvents || settings.onApprove.call(element, $(this)) === false) {
  203. module.verbose('Approve callback returned false cancelling hide');
  204. return;
  205. }
  206. ignoreRepeatedEvents = true;
  207. module.hide(function() {
  208. ignoreRepeatedEvents = false;
  209. });
  210. },
  211. preventScroll: function(event) {
  212. event.preventDefault();
  213. },
  214. deny: function() {
  215. if(ignoreRepeatedEvents || settings.onDeny.call(element, $(this)) === false) {
  216. module.verbose('Deny callback returned false cancelling hide');
  217. return;
  218. }
  219. ignoreRepeatedEvents = true;
  220. module.hide(function() {
  221. ignoreRepeatedEvents = false;
  222. });
  223. },
  224. close: function() {
  225. module.hide();
  226. },
  227. click: function(event) {
  228. if(!settings.closable) {
  229. module.verbose('Dimmer clicked but closable setting is disabled');
  230. return;
  231. }
  232. var
  233. $target = $(event.target),
  234. isInModal = ($target.closest(selector.modal).length > 0),
  235. isInDOM = $.contains(document.documentElement, event.target)
  236. ;
  237. if(!isInModal && isInDOM && module.is.active()) {
  238. module.debug('Dimmer clicked, hiding all modals');
  239. module.remove.clickaway();
  240. if(settings.allowMultiple) {
  241. module.hide();
  242. }
  243. else {
  244. module.hideAll();
  245. }
  246. }
  247. },
  248. debounce: function(method, delay) {
  249. clearTimeout(module.timer);
  250. module.timer = setTimeout(method, delay);
  251. },
  252. keyboard: function(event) {
  253. var
  254. keyCode = event.which,
  255. escapeKey = 27
  256. ;
  257. if(keyCode == escapeKey) {
  258. if(settings.closable) {
  259. module.debug('Escape key pressed hiding modal');
  260. module.hide();
  261. }
  262. else {
  263. module.debug('Escape key pressed, but closable is set to false');
  264. }
  265. event.preventDefault();
  266. }
  267. },
  268. resize: function() {
  269. if( $dimmable.dimmer('is active') && ( module.is.animating() || module.is.active() ) ) {
  270. requestAnimationFrame(module.refresh);
  271. }
  272. }
  273. },
  274. toggle: function() {
  275. if( module.is.active() || module.is.animating() ) {
  276. module.hide();
  277. }
  278. else {
  279. module.show();
  280. }
  281. },
  282. show: function(callback) {
  283. callback = $.isFunction(callback)
  284. ? callback
  285. : function(){}
  286. ;
  287. module.refreshModals();
  288. module.set.dimmerSettings();
  289. module.set.dimmerStyles();
  290. module.showModal(callback);
  291. },
  292. hide: function(callback) {
  293. callback = $.isFunction(callback)
  294. ? callback
  295. : function(){}
  296. ;
  297. module.refreshModals();
  298. module.hideModal(callback);
  299. },
  300. showModal: function(callback) {
  301. callback = $.isFunction(callback)
  302. ? callback
  303. : function(){}
  304. ;
  305. if( module.is.animating() || !module.is.active() ) {
  306. module.showDimmer();
  307. module.cacheSizes();
  308. if(module.can.useFlex()) {
  309. module.remove.legacy();
  310. }
  311. else {
  312. module.set.legacy();
  313. module.set.modalOffset();
  314. module.debug('Using non-flex legacy modal positioning.');
  315. }
  316. module.set.screenHeight();
  317. module.set.type();
  318. module.set.clickaway();
  319. if( !settings.allowMultiple && module.others.active() ) {
  320. module.hideOthers(module.showModal);
  321. }
  322. else {
  323. if(settings.allowMultiple && settings.detachable) {
  324. $module.detach().appendTo($dimmer);
  325. }
  326. settings.onShow.call(element);
  327. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  328. module.debug('Showing modal with css animations');
  329. $module
  330. .transition({
  331. debug : settings.debug,
  332. animation : settings.transition + ' in',
  333. queue : settings.queue,
  334. duration : settings.duration,
  335. useFailSafe : true,
  336. onComplete : function() {
  337. settings.onVisible.apply(element);
  338. if(settings.keyboardShortcuts) {
  339. module.add.keyboardShortcuts();
  340. }
  341. module.save.focus();
  342. module.set.active();
  343. if(settings.autofocus) {
  344. module.set.autofocus();
  345. }
  346. callback();
  347. }
  348. })
  349. ;
  350. }
  351. else {
  352. module.error(error.noTransition);
  353. }
  354. }
  355. }
  356. else {
  357. module.debug('Modal is already visible');
  358. }
  359. },
  360. hideModal: function(callback, keepDimmed) {
  361. callback = $.isFunction(callback)
  362. ? callback
  363. : function(){}
  364. ;
  365. module.debug('Hiding modal');
  366. if(settings.onHide.call(element, $(this)) === false) {
  367. module.verbose('Hide callback returned false cancelling hide');
  368. return;
  369. }
  370. if( module.is.animating() || module.is.active() ) {
  371. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  372. module.remove.active();
  373. $module
  374. .transition({
  375. debug : settings.debug,
  376. animation : settings.transition + ' out',
  377. queue : settings.queue,
  378. duration : settings.duration,
  379. useFailSafe : true,
  380. onStart : function() {
  381. if(!module.others.active() && !keepDimmed) {
  382. module.hideDimmer();
  383. }
  384. if(settings.keyboardShortcuts) {
  385. module.remove.keyboardShortcuts();
  386. }
  387. },
  388. onComplete : function() {
  389. settings.onHidden.call(element);
  390. module.remove.dimmerStyles();
  391. module.restore.focus();
  392. callback();
  393. }
  394. })
  395. ;
  396. }
  397. else {
  398. module.error(error.noTransition);
  399. }
  400. }
  401. },
  402. showDimmer: function() {
  403. if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
  404. module.debug('Showing dimmer');
  405. $dimmable.dimmer('show');
  406. }
  407. else {
  408. module.debug('Dimmer already visible');
  409. }
  410. },
  411. hideDimmer: function() {
  412. if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
  413. module.unbind.scrollLock();
  414. $dimmable.dimmer('hide', function() {
  415. module.remove.clickaway();
  416. module.remove.screenHeight();
  417. });
  418. }
  419. else {
  420. module.debug('Dimmer is not visible cannot hide');
  421. return;
  422. }
  423. },
  424. hideAll: function(callback) {
  425. var
  426. $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating)
  427. ;
  428. callback = $.isFunction(callback)
  429. ? callback
  430. : function(){}
  431. ;
  432. if( $visibleModals.length > 0 ) {
  433. module.debug('Hiding all visible modals');
  434. module.hideDimmer();
  435. $visibleModals
  436. .modal('hide modal', callback)
  437. ;
  438. }
  439. },
  440. hideOthers: function(callback) {
  441. var
  442. $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating)
  443. ;
  444. callback = $.isFunction(callback)
  445. ? callback
  446. : function(){}
  447. ;
  448. if( $visibleModals.length > 0 ) {
  449. module.debug('Hiding other modals', $otherModals);
  450. $visibleModals
  451. .modal('hide modal', callback, true)
  452. ;
  453. }
  454. },
  455. others: {
  456. active: function() {
  457. return ($otherModals.filter('.' + className.active).length > 0);
  458. },
  459. animating: function() {
  460. return ($otherModals.filter('.' + className.animating).length > 0);
  461. }
  462. },
  463. add: {
  464. keyboardShortcuts: function() {
  465. module.verbose('Adding keyboard shortcuts');
  466. $document
  467. .on('keyup' + eventNamespace, module.event.keyboard)
  468. ;
  469. }
  470. },
  471. save: {
  472. focus: function() {
  473. var
  474. $activeElement = $(document.activeElement),
  475. inCurrentModal = $activeElement.closest($module).length > 0
  476. ;
  477. if(!inCurrentModal) {
  478. $focusedElement = $(document.activeElement).blur();
  479. }
  480. }
  481. },
  482. restore: {
  483. focus: function() {
  484. if($focusedElement && $focusedElement.length > 0) {
  485. $focusedElement.focus();
  486. }
  487. }
  488. },
  489. remove: {
  490. active: function() {
  491. $module.removeClass(className.active);
  492. },
  493. legacy: function() {
  494. $module.removeClass(className.legacy);
  495. },
  496. clickaway: function() {
  497. $dimmer
  498. .off('click' + elementEventNamespace)
  499. ;
  500. },
  501. dimmerStyles: function() {
  502. $dimmer.removeClass(className.inverted);
  503. $dimmable.removeClass(className.blurring);
  504. },
  505. bodyStyle: function() {
  506. if($body.attr('style') === '') {
  507. module.verbose('Removing style attribute');
  508. $body.removeAttr('style');
  509. }
  510. },
  511. screenHeight: function() {
  512. module.debug('Removing page height');
  513. $body
  514. .css('height', '')
  515. ;
  516. },
  517. keyboardShortcuts: function() {
  518. module.verbose('Removing keyboard shortcuts');
  519. $document
  520. .off('keyup' + eventNamespace)
  521. ;
  522. },
  523. scrolling: function() {
  524. $dimmable.removeClass(className.scrolling);
  525. $module.removeClass(className.scrolling);
  526. }
  527. },
  528. cacheSizes: function() {
  529. $module.addClass(className.loading);
  530. var
  531. scrollHeight = $module.prop('scrollHeight'),
  532. modalWidth = $module.outerWidth(),
  533. modalHeight = $module.outerHeight()
  534. ;
  535. if(module.cache === undefined || modalHeight !== 0) {
  536. module.cache = {
  537. pageHeight : $(document).outerHeight(),
  538. width : modalWidth,
  539. height : modalHeight + settings.offset,
  540. scrollHeight : scrollHeight + settings.offset,
  541. contextHeight : (settings.context == 'body')
  542. ? $(window).height()
  543. : $dimmable.height(),
  544. };
  545. module.cache.topOffset = -(module.cache.height / 2);
  546. }
  547. $module.removeClass(className.loading);
  548. module.debug('Caching modal and container sizes', module.cache);
  549. },
  550. can: {
  551. useFlex: function() {
  552. return (settings.useFlex == 'auto')
  553. ? settings.detachable && !module.is.ie()
  554. : settings.useFlex
  555. ;
  556. },
  557. fit: function() {
  558. var
  559. contextHeight = module.cache.contextHeight,
  560. verticalCenter = module.cache.contextHeight / 2,
  561. topOffset = module.cache.topOffset,
  562. scrollHeight = module.cache.scrollHeight,
  563. height = module.cache.height,
  564. paddingHeight = settings.padding,
  565. startPosition = (verticalCenter + topOffset)
  566. ;
  567. return (scrollHeight > height)
  568. ? (startPosition + scrollHeight + paddingHeight < contextHeight)
  569. : (height + (paddingHeight * 2) < contextHeight)
  570. ;
  571. }
  572. },
  573. is: {
  574. active: function() {
  575. return $module.hasClass(className.active);
  576. },
  577. ie: function() {
  578. var
  579. isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
  580. isIE = ('ActiveXObject' in window)
  581. ;
  582. return (isIE11 || isIE);
  583. },
  584. animating: function() {
  585. return $module.transition('is supported')
  586. ? $module.transition('is animating')
  587. : $module.is(':visible')
  588. ;
  589. },
  590. scrolling: function() {
  591. return $dimmable.hasClass(className.scrolling);
  592. },
  593. modernBrowser: function() {
  594. // appName for IE11 reports 'Netscape' can no longer use
  595. return !(window.ActiveXObject || 'ActiveXObject' in window);
  596. }
  597. },
  598. set: {
  599. autofocus: function() {
  600. var
  601. $inputs = $module.find('[tabindex], :input').filter(':visible'),
  602. $autofocus = $inputs.filter('[autofocus]'),
  603. $input = ($autofocus.length > 0)
  604. ? $autofocus.first()
  605. : $inputs.first()
  606. ;
  607. if($input.length > 0) {
  608. $input.focus();
  609. }
  610. },
  611. clickaway: function() {
  612. $dimmer
  613. .on('click' + elementEventNamespace, module.event.click)
  614. ;
  615. },
  616. dimmerSettings: function() {
  617. if($.fn.dimmer === undefined) {
  618. module.error(error.dimmer);
  619. return;
  620. }
  621. var
  622. defaultSettings = {
  623. debug : settings.debug,
  624. dimmerName : 'modals',
  625. closable : 'auto',
  626. useFlex : module.can.useFlex(),
  627. variation : settings.centered
  628. ? false
  629. : 'top aligned',
  630. duration : {
  631. show : settings.duration,
  632. hide : settings.duration
  633. }
  634. },
  635. dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
  636. ;
  637. if(settings.inverted) {
  638. dimmerSettings.variation = (dimmerSettings.variation !== undefined)
  639. ? dimmerSettings.variation + ' inverted'
  640. : 'inverted'
  641. ;
  642. }
  643. $context.dimmer('setting', dimmerSettings);
  644. },
  645. dimmerStyles: function() {
  646. if(settings.inverted) {
  647. $dimmer.addClass(className.inverted);
  648. }
  649. else {
  650. $dimmer.removeClass(className.inverted);
  651. }
  652. if(settings.blurring) {
  653. $dimmable.addClass(className.blurring);
  654. }
  655. else {
  656. $dimmable.removeClass(className.blurring);
  657. }
  658. },
  659. modalOffset: function() {
  660. var
  661. width = module.cache.width,
  662. height = module.cache.height
  663. ;
  664. $module
  665. .css({
  666. marginTop: (settings.centered && module.can.fit())
  667. ? -(height / 2)
  668. : 0,
  669. marginLeft: -(width / 2)
  670. })
  671. ;
  672. module.verbose('Setting modal offset for legacy mode');
  673. },
  674. screenHeight: function() {
  675. if( module.can.fit() ) {
  676. $body.css('height', '');
  677. }
  678. else {
  679. module.debug('Modal is taller than page content, resizing page height');
  680. $body
  681. .css('height', module.cache.height + (settings.padding * 2) )
  682. ;
  683. }
  684. },
  685. active: function() {
  686. $module.addClass(className.active);
  687. },
  688. scrolling: function() {
  689. $dimmable.addClass(className.scrolling);
  690. $module.addClass(className.scrolling);
  691. module.unbind.scrollLock();
  692. },
  693. legacy: function() {
  694. $module.addClass(className.legacy);
  695. },
  696. type: function() {
  697. if(module.can.fit()) {
  698. module.verbose('Modal fits on screen');
  699. if(!module.others.active() && !module.others.animating()) {
  700. module.remove.scrolling();
  701. module.bind.scrollLock();
  702. }
  703. }
  704. else {
  705. module.verbose('Modal cannot fit on screen setting to scrolling');
  706. module.set.scrolling();
  707. }
  708. },
  709. undetached: function() {
  710. $dimmable.addClass(className.undetached);
  711. }
  712. },
  713. setting: function(name, value) {
  714. module.debug('Changing setting', name, value);
  715. if( $.isPlainObject(name) ) {
  716. $.extend(true, settings, name);
  717. }
  718. else if(value !== undefined) {
  719. if($.isPlainObject(settings[name])) {
  720. $.extend(true, settings[name], value);
  721. }
  722. else {
  723. settings[name] = value;
  724. }
  725. }
  726. else {
  727. return settings[name];
  728. }
  729. },
  730. internal: function(name, value) {
  731. if( $.isPlainObject(name) ) {
  732. $.extend(true, module, name);
  733. }
  734. else if(value !== undefined) {
  735. module[name] = value;
  736. }
  737. else {
  738. return module[name];
  739. }
  740. },
  741. debug: function() {
  742. if(!settings.silent && settings.debug) {
  743. if(settings.performance) {
  744. module.performance.log(arguments);
  745. }
  746. else {
  747. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  748. module.debug.apply(console, arguments);
  749. }
  750. }
  751. },
  752. verbose: function() {
  753. if(!settings.silent && settings.verbose && settings.debug) {
  754. if(settings.performance) {
  755. module.performance.log(arguments);
  756. }
  757. else {
  758. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  759. module.verbose.apply(console, arguments);
  760. }
  761. }
  762. },
  763. error: function() {
  764. if(!settings.silent) {
  765. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  766. module.error.apply(console, arguments);
  767. }
  768. },
  769. performance: {
  770. log: function(message) {
  771. var
  772. currentTime,
  773. executionTime,
  774. previousTime
  775. ;
  776. if(settings.performance) {
  777. currentTime = new Date().getTime();
  778. previousTime = time || currentTime;
  779. executionTime = currentTime - previousTime;
  780. time = currentTime;
  781. performance.push({
  782. 'Name' : message[0],
  783. 'Arguments' : [].slice.call(message, 1) || '',
  784. 'Element' : element,
  785. 'Execution Time' : executionTime
  786. });
  787. }
  788. clearTimeout(module.performance.timer);
  789. module.performance.timer = setTimeout(module.performance.display, 500);
  790. },
  791. display: function() {
  792. var
  793. title = settings.name + ':',
  794. totalTime = 0
  795. ;
  796. time = false;
  797. clearTimeout(module.performance.timer);
  798. $.each(performance, function(index, data) {
  799. totalTime += data['Execution Time'];
  800. });
  801. title += ' ' + totalTime + 'ms';
  802. if(moduleSelector) {
  803. title += ' \'' + moduleSelector + '\'';
  804. }
  805. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  806. console.groupCollapsed(title);
  807. if(console.table) {
  808. console.table(performance);
  809. }
  810. else {
  811. $.each(performance, function(index, data) {
  812. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  813. });
  814. }
  815. console.groupEnd();
  816. }
  817. performance = [];
  818. }
  819. },
  820. invoke: function(query, passedArguments, context) {
  821. var
  822. object = instance,
  823. maxDepth,
  824. found,
  825. response
  826. ;
  827. passedArguments = passedArguments || queryArguments;
  828. context = element || context;
  829. if(typeof query == 'string' && object !== undefined) {
  830. query = query.split(/[\. ]/);
  831. maxDepth = query.length - 1;
  832. $.each(query, function(depth, value) {
  833. var camelCaseValue = (depth != maxDepth)
  834. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  835. : query
  836. ;
  837. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  838. object = object[camelCaseValue];
  839. }
  840. else if( object[camelCaseValue] !== undefined ) {
  841. found = object[camelCaseValue];
  842. return false;
  843. }
  844. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  845. object = object[value];
  846. }
  847. else if( object[value] !== undefined ) {
  848. found = object[value];
  849. return false;
  850. }
  851. else {
  852. return false;
  853. }
  854. });
  855. }
  856. if ( $.isFunction( found ) ) {
  857. response = found.apply(context, passedArguments);
  858. }
  859. else if(found !== undefined) {
  860. response = found;
  861. }
  862. if($.isArray(returnedValue)) {
  863. returnedValue.push(response);
  864. }
  865. else if(returnedValue !== undefined) {
  866. returnedValue = [returnedValue, response];
  867. }
  868. else if(response !== undefined) {
  869. returnedValue = response;
  870. }
  871. return found;
  872. }
  873. };
  874. if(methodInvoked) {
  875. if(instance === undefined) {
  876. module.initialize();
  877. }
  878. module.invoke(query);
  879. }
  880. else {
  881. if(instance !== undefined) {
  882. instance.invoke('destroy');
  883. }
  884. module.initialize();
  885. }
  886. })
  887. ;
  888. return (returnedValue !== undefined)
  889. ? returnedValue
  890. : this
  891. ;
  892. };
  893. $.fn.modal.settings = {
  894. name : 'Modal',
  895. namespace : 'modal',
  896. useFlex : 'auto',
  897. offset : 0,
  898. silent : false,
  899. debug : false,
  900. verbose : false,
  901. performance : true,
  902. observeChanges : false,
  903. allowMultiple : false,
  904. detachable : true,
  905. closable : true,
  906. autofocus : true,
  907. inverted : false,
  908. blurring : false,
  909. centered : true,
  910. dimmerSettings : {
  911. closable : false,
  912. useCSS : true
  913. },
  914. // whether to use keyboard shortcuts
  915. keyboardShortcuts: true,
  916. context : 'body',
  917. queue : false,
  918. duration : 500,
  919. transition : 'scale',
  920. // padding with edge of page
  921. padding : 50,
  922. // called before show animation
  923. onShow : function(){},
  924. // called after show animation
  925. onVisible : function(){},
  926. // called before hide animation
  927. onHide : function(){ return true; },
  928. // called after hide animation
  929. onHidden : function(){},
  930. // called after approve selector match
  931. onApprove : function(){ return true; },
  932. // called after deny selector match
  933. onDeny : function(){ return true; },
  934. selector : {
  935. close : '> .close',
  936. approve : '.actions .positive, .actions .approve, .actions .ok',
  937. deny : '.actions .negative, .actions .deny, .actions .cancel',
  938. modal : '.ui.modal'
  939. },
  940. error : {
  941. dimmer : 'UI Dimmer, a required component is not included in this page',
  942. method : 'The method you called is not defined.',
  943. notFound : 'The element you specified could not be found'
  944. },
  945. className : {
  946. active : 'active',
  947. animating : 'animating',
  948. blurring : 'blurring',
  949. inverted : 'inverted',
  950. legacy : 'legacy',
  951. loading : 'loading',
  952. scrolling : 'scrolling',
  953. undetached : 'undetached'
  954. }
  955. };
  956. })( jQuery, window, document );