sidebar.js 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /*!
  2. * # Fomantic-UI - Sidebar
  3. * http://github.com/fomantic/Fomantic-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. $.isFunction = $.isFunction || function(obj) {
  13. return typeof obj === "function" && typeof obj.nodeType !== "number";
  14. };
  15. window = (typeof window != 'undefined' && window.Math == Math)
  16. ? window
  17. : (typeof self != 'undefined' && self.Math == Math)
  18. ? self
  19. : Function('return this')()
  20. ;
  21. $.fn.sidebar = function(parameters) {
  22. var
  23. $allModules = $(this),
  24. $window = $(window),
  25. $document = $(document),
  26. $html = $('html'),
  27. $head = $('head'),
  28. moduleSelector = $allModules.selector || '',
  29. time = new Date().getTime(),
  30. performance = [],
  31. query = arguments[0],
  32. methodInvoked = (typeof query == 'string'),
  33. queryArguments = [].slice.call(arguments, 1),
  34. requestAnimationFrame = window.requestAnimationFrame
  35. || window.mozRequestAnimationFrame
  36. || window.webkitRequestAnimationFrame
  37. || window.msRequestAnimationFrame
  38. || function(callback) { setTimeout(callback, 0); },
  39. returnedValue
  40. ;
  41. $allModules
  42. .each(function() {
  43. var
  44. settings = ( $.isPlainObject(parameters) )
  45. ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
  46. : $.extend({}, $.fn.sidebar.settings),
  47. selector = settings.selector,
  48. className = settings.className,
  49. namespace = settings.namespace,
  50. regExp = settings.regExp,
  51. error = settings.error,
  52. eventNamespace = '.' + namespace,
  53. moduleNamespace = 'module-' + namespace,
  54. $module = $(this),
  55. $context = $(settings.context),
  56. $sidebars = $module.children(selector.sidebar),
  57. $fixed = $context.children(selector.fixed),
  58. $pusher = $context.children(selector.pusher),
  59. $style,
  60. element = this,
  61. instance = $module.data(moduleNamespace),
  62. elementNamespace,
  63. id,
  64. currentScroll,
  65. transitionEvent,
  66. module
  67. ;
  68. module = {
  69. initialize: function() {
  70. module.debug('Initializing sidebar', parameters);
  71. module.create.id();
  72. transitionEvent = module.get.transitionEvent();
  73. // avoids locking rendering if initialized in onReady
  74. if(settings.delaySetup) {
  75. requestAnimationFrame(module.setup.layout);
  76. }
  77. else {
  78. module.setup.layout();
  79. }
  80. requestAnimationFrame(function() {
  81. module.setup.cache();
  82. });
  83. module.instantiate();
  84. },
  85. instantiate: function() {
  86. module.verbose('Storing instance of module', module);
  87. instance = module;
  88. $module
  89. .data(moduleNamespace, module)
  90. ;
  91. },
  92. create: {
  93. id: function() {
  94. id = (Math.random().toString(16) + '000000000').substr(2,8);
  95. elementNamespace = '.' + id;
  96. module.verbose('Creating unique id for element', id);
  97. }
  98. },
  99. destroy: function() {
  100. module.verbose('Destroying previous module for', $module);
  101. $module
  102. .off(eventNamespace)
  103. .removeData(moduleNamespace)
  104. ;
  105. if(module.is.ios()) {
  106. module.remove.ios();
  107. }
  108. // bound by uuid
  109. $context.off(elementNamespace);
  110. $window.off(elementNamespace);
  111. $document.off(elementNamespace);
  112. },
  113. event: {
  114. clickaway: function(event) {
  115. if(settings.closable){
  116. var
  117. clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
  118. clickedContext = ($context.is(event.target))
  119. ;
  120. if(clickedInPusher) {
  121. module.verbose('User clicked on dimmed page');
  122. module.hide();
  123. }
  124. if(clickedContext) {
  125. module.verbose('User clicked on dimmable context (scaled out page)');
  126. module.hide();
  127. }
  128. }
  129. },
  130. touch: function(event) {
  131. //event.stopPropagation();
  132. },
  133. containScroll: function(event) {
  134. if(element.scrollTop <= 0) {
  135. element.scrollTop = 1;
  136. }
  137. if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
  138. element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
  139. }
  140. },
  141. scroll: function(event) {
  142. if( $(event.target).closest(selector.sidebar).length === 0 ) {
  143. event.preventDefault();
  144. }
  145. }
  146. },
  147. bind: {
  148. clickaway: function() {
  149. module.verbose('Adding clickaway events to context', $context);
  150. $context
  151. .on('click' + elementNamespace, module.event.clickaway)
  152. .on('touchend' + elementNamespace, module.event.clickaway)
  153. ;
  154. },
  155. scrollLock: function() {
  156. if(settings.scrollLock) {
  157. module.debug('Disabling page scroll');
  158. $window
  159. .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
  160. ;
  161. }
  162. module.verbose('Adding events to contain sidebar scroll');
  163. $document
  164. .on('touchmove' + elementNamespace, module.event.touch)
  165. ;
  166. $module
  167. .on('scroll' + eventNamespace, module.event.containScroll)
  168. ;
  169. }
  170. },
  171. unbind: {
  172. clickaway: function() {
  173. module.verbose('Removing clickaway events from context', $context);
  174. $context.off(elementNamespace);
  175. },
  176. scrollLock: function() {
  177. module.verbose('Removing scroll lock from page');
  178. $document.off(elementNamespace);
  179. $window.off(elementNamespace);
  180. $module.off('scroll' + eventNamespace);
  181. }
  182. },
  183. add: {
  184. inlineCSS: function() {
  185. var
  186. width = module.cache.width || $module.outerWidth(),
  187. height = module.cache.height || $module.outerHeight(),
  188. isRTL = module.is.rtl(),
  189. direction = module.get.direction(),
  190. distance = {
  191. left : width,
  192. right : -width,
  193. top : height,
  194. bottom : -height
  195. },
  196. style
  197. ;
  198. if(isRTL){
  199. module.verbose('RTL detected, flipping widths');
  200. distance.left = -width;
  201. distance.right = width;
  202. }
  203. style = '<style>';
  204. if(direction === 'left' || direction === 'right') {
  205. module.debug('Adding CSS rules for animation distance', width);
  206. style += ''
  207. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  208. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  209. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  210. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  211. + ' }'
  212. ;
  213. }
  214. else if(direction === 'top' || direction == 'bottom') {
  215. style += ''
  216. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  217. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  218. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  219. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  220. + ' }'
  221. ;
  222. }
  223. /* IE is only browser not to create context with transforms */
  224. /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
  225. if( module.is.ie() ) {
  226. if(direction === 'left' || direction === 'right') {
  227. module.debug('Adding CSS rules for animation distance', width);
  228. style += ''
  229. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  230. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  231. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  232. + ' }'
  233. ;
  234. }
  235. else if(direction === 'top' || direction == 'bottom') {
  236. style += ''
  237. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  238. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  239. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  240. + ' }'
  241. ;
  242. }
  243. /* opposite sides visible forces content overlay */
  244. style += ''
  245. + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
  246. + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
  247. + ' -webkit-transform: translate3d(0, 0, 0);'
  248. + ' transform: translate3d(0, 0, 0);'
  249. + ' }'
  250. ;
  251. }
  252. style += '</style>';
  253. $style = $(style)
  254. .appendTo($head)
  255. ;
  256. module.debug('Adding sizing css to head', $style);
  257. }
  258. },
  259. refresh: function() {
  260. module.verbose('Refreshing selector cache');
  261. $context = $(settings.context);
  262. $sidebars = $context.children(selector.sidebar);
  263. $pusher = $context.children(selector.pusher);
  264. $fixed = $context.children(selector.fixed);
  265. module.clear.cache();
  266. },
  267. refreshSidebars: function() {
  268. module.verbose('Refreshing other sidebars');
  269. $sidebars = $context.children(selector.sidebar);
  270. },
  271. repaint: function() {
  272. module.verbose('Forcing repaint event');
  273. element.style.display = 'none';
  274. var ignored = element.offsetHeight;
  275. element.scrollTop = element.scrollTop;
  276. element.style.display = '';
  277. },
  278. setup: {
  279. cache: function() {
  280. module.cache = {
  281. width : $module.outerWidth(),
  282. height : $module.outerHeight(),
  283. rtl : ($module.css('direction') == 'rtl')
  284. };
  285. },
  286. layout: function() {
  287. if( $context.children(selector.pusher).length === 0 ) {
  288. module.debug('Adding wrapper element for sidebar');
  289. module.error(error.pusher);
  290. $pusher = $('<div class="pusher" />');
  291. $context
  292. .children()
  293. .not(selector.omitted)
  294. .not($sidebars)
  295. .wrapAll($pusher)
  296. ;
  297. module.refresh();
  298. }
  299. if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
  300. module.debug('Moved sidebar to correct parent element');
  301. module.error(error.movedSidebar, element);
  302. $module.detach().prependTo($context);
  303. module.refresh();
  304. }
  305. module.clear.cache();
  306. module.set.pushable();
  307. module.set.direction();
  308. }
  309. },
  310. attachEvents: function(selector, event) {
  311. var
  312. $toggle = $(selector)
  313. ;
  314. event = $.isFunction(module[event])
  315. ? module[event]
  316. : module.toggle
  317. ;
  318. if($toggle.length > 0) {
  319. module.debug('Attaching sidebar events to element', selector, event);
  320. $toggle
  321. .on('click' + eventNamespace, event)
  322. ;
  323. }
  324. else {
  325. module.error(error.notFound, selector);
  326. }
  327. },
  328. show: function(callback) {
  329. callback = $.isFunction(callback)
  330. ? callback
  331. : function(){}
  332. ;
  333. if(module.is.hidden()) {
  334. module.refreshSidebars();
  335. if(settings.overlay) {
  336. module.error(error.overlay);
  337. settings.transition = 'overlay';
  338. }
  339. module.refresh();
  340. if(module.othersActive()) {
  341. module.debug('Other sidebars currently visible');
  342. if(settings.exclusive) {
  343. // if not overlay queue animation after hide
  344. if(settings.transition != 'overlay') {
  345. module.hideOthers(module.show);
  346. return;
  347. }
  348. else {
  349. module.hideOthers();
  350. }
  351. }
  352. else {
  353. settings.transition = 'overlay';
  354. }
  355. }
  356. module.pushPage(function() {
  357. callback.call(element);
  358. settings.onShow.call(element);
  359. });
  360. settings.onChange.call(element);
  361. settings.onVisible.call(element);
  362. }
  363. else {
  364. module.debug('Sidebar is already visible');
  365. }
  366. },
  367. hide: function(callback) {
  368. callback = $.isFunction(callback)
  369. ? callback
  370. : function(){}
  371. ;
  372. if(module.is.visible() || module.is.animating()) {
  373. module.debug('Hiding sidebar', callback);
  374. module.refreshSidebars();
  375. module.pullPage(function() {
  376. callback.call(element);
  377. settings.onHidden.call(element);
  378. });
  379. settings.onChange.call(element);
  380. settings.onHide.call(element);
  381. }
  382. },
  383. othersAnimating: function() {
  384. return ($sidebars.not($module).filter('.' + className.animating).length > 0);
  385. },
  386. othersVisible: function() {
  387. return ($sidebars.not($module).filter('.' + className.visible).length > 0);
  388. },
  389. othersActive: function() {
  390. return(module.othersVisible() || module.othersAnimating());
  391. },
  392. hideOthers: function(callback) {
  393. var
  394. $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
  395. sidebarCount = $otherSidebars.length,
  396. callbackCount = 0
  397. ;
  398. callback = callback || function(){};
  399. $otherSidebars
  400. .sidebar('hide', function() {
  401. callbackCount++;
  402. if(callbackCount == sidebarCount) {
  403. callback();
  404. }
  405. })
  406. ;
  407. },
  408. toggle: function() {
  409. module.verbose('Determining toggled direction');
  410. if(module.is.hidden()) {
  411. module.show();
  412. }
  413. else {
  414. module.hide();
  415. }
  416. },
  417. pushPage: function(callback) {
  418. var
  419. transition = module.get.transition(),
  420. $transition = (transition === 'overlay' || module.othersActive())
  421. ? $module
  422. : $pusher,
  423. animate,
  424. dim,
  425. transitionEnd
  426. ;
  427. callback = $.isFunction(callback)
  428. ? callback
  429. : function(){}
  430. ;
  431. if(settings.transition == 'scale down') {
  432. module.scrollToTop();
  433. }
  434. module.set.transition(transition);
  435. module.repaint();
  436. animate = function() {
  437. module.bind.clickaway();
  438. module.add.inlineCSS();
  439. module.set.animating();
  440. module.set.visible();
  441. };
  442. dim = function() {
  443. module.set.dimmed();
  444. };
  445. transitionEnd = function(event) {
  446. if( event.target == $transition[0] ) {
  447. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  448. module.remove.animating();
  449. module.bind.scrollLock();
  450. callback.call(element);
  451. }
  452. };
  453. $transition.off(transitionEvent + elementNamespace);
  454. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  455. requestAnimationFrame(animate);
  456. if(settings.dimPage && !module.othersVisible()) {
  457. requestAnimationFrame(dim);
  458. }
  459. },
  460. pullPage: function(callback) {
  461. var
  462. transition = module.get.transition(),
  463. $transition = (transition == 'overlay' || module.othersActive())
  464. ? $module
  465. : $pusher,
  466. animate,
  467. transitionEnd
  468. ;
  469. callback = $.isFunction(callback)
  470. ? callback
  471. : function(){}
  472. ;
  473. module.verbose('Removing context push state', module.get.direction());
  474. module.unbind.clickaway();
  475. module.unbind.scrollLock();
  476. animate = function() {
  477. module.set.transition(transition);
  478. module.set.animating();
  479. module.remove.visible();
  480. if(settings.dimPage && !module.othersVisible()) {
  481. $pusher.removeClass(className.dimmed);
  482. }
  483. };
  484. transitionEnd = function(event) {
  485. if( event.target == $transition[0] ) {
  486. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  487. module.remove.animating();
  488. module.remove.transition();
  489. module.remove.inlineCSS();
  490. if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
  491. module.scrollBack();
  492. }
  493. callback.call(element);
  494. }
  495. };
  496. $transition.off(transitionEvent + elementNamespace);
  497. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  498. requestAnimationFrame(animate);
  499. },
  500. scrollToTop: function() {
  501. module.verbose('Scrolling to top of page to avoid animation issues');
  502. currentScroll = $(window).scrollTop();
  503. $module.scrollTop(0);
  504. window.scrollTo(0, 0);
  505. },
  506. scrollBack: function() {
  507. module.verbose('Scrolling back to original page position');
  508. window.scrollTo(0, currentScroll);
  509. },
  510. clear: {
  511. cache: function() {
  512. module.verbose('Clearing cached dimensions');
  513. module.cache = {};
  514. }
  515. },
  516. set: {
  517. // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
  518. // (This is no longer necessary in latest iOS)
  519. ios: function() {
  520. $html.addClass(className.ios);
  521. },
  522. // container
  523. pushed: function() {
  524. $context.addClass(className.pushed);
  525. },
  526. pushable: function() {
  527. $context.addClass(className.pushable);
  528. },
  529. // pusher
  530. dimmed: function() {
  531. $pusher.addClass(className.dimmed);
  532. },
  533. // sidebar
  534. active: function() {
  535. $module.addClass(className.active);
  536. },
  537. animating: function() {
  538. $module.addClass(className.animating);
  539. },
  540. transition: function(transition) {
  541. transition = transition || module.get.transition();
  542. $module.addClass(transition);
  543. },
  544. direction: function(direction) {
  545. direction = direction || module.get.direction();
  546. $module.addClass(className[direction]);
  547. },
  548. visible: function() {
  549. $module.addClass(className.visible);
  550. },
  551. overlay: function() {
  552. $module.addClass(className.overlay);
  553. }
  554. },
  555. remove: {
  556. inlineCSS: function() {
  557. module.debug('Removing inline css styles', $style);
  558. if($style && $style.length > 0) {
  559. $style.remove();
  560. }
  561. },
  562. // ios scroll on html not document
  563. ios: function() {
  564. $html.removeClass(className.ios);
  565. },
  566. // context
  567. pushed: function() {
  568. $context.removeClass(className.pushed);
  569. },
  570. pushable: function() {
  571. $context.removeClass(className.pushable);
  572. },
  573. // sidebar
  574. active: function() {
  575. $module.removeClass(className.active);
  576. },
  577. animating: function() {
  578. $module.removeClass(className.animating);
  579. },
  580. transition: function(transition) {
  581. transition = transition || module.get.transition();
  582. $module.removeClass(transition);
  583. },
  584. direction: function(direction) {
  585. direction = direction || module.get.direction();
  586. $module.removeClass(className[direction]);
  587. },
  588. visible: function() {
  589. $module.removeClass(className.visible);
  590. },
  591. overlay: function() {
  592. $module.removeClass(className.overlay);
  593. }
  594. },
  595. get: {
  596. direction: function() {
  597. if($module.hasClass(className.top)) {
  598. return className.top;
  599. }
  600. else if($module.hasClass(className.right)) {
  601. return className.right;
  602. }
  603. else if($module.hasClass(className.bottom)) {
  604. return className.bottom;
  605. }
  606. return className.left;
  607. },
  608. transition: function() {
  609. var
  610. direction = module.get.direction(),
  611. transition
  612. ;
  613. transition = ( module.is.mobile() )
  614. ? (settings.mobileTransition == 'auto')
  615. ? settings.defaultTransition.mobile[direction]
  616. : settings.mobileTransition
  617. : (settings.transition == 'auto')
  618. ? settings.defaultTransition.computer[direction]
  619. : settings.transition
  620. ;
  621. module.verbose('Determined transition', transition);
  622. return transition;
  623. },
  624. transitionEvent: function() {
  625. var
  626. element = document.createElement('element'),
  627. transitions = {
  628. 'transition' :'transitionend',
  629. 'OTransition' :'oTransitionEnd',
  630. 'MozTransition' :'transitionend',
  631. 'WebkitTransition' :'webkitTransitionEnd'
  632. },
  633. transition
  634. ;
  635. for(transition in transitions){
  636. if( element.style[transition] !== undefined ){
  637. return transitions[transition];
  638. }
  639. }
  640. }
  641. },
  642. is: {
  643. ie: function() {
  644. var
  645. isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
  646. isIE = ('ActiveXObject' in window)
  647. ;
  648. return (isIE11 || isIE);
  649. },
  650. ios: function() {
  651. var
  652. userAgent = navigator.userAgent,
  653. isIOS = userAgent.match(regExp.ios),
  654. isMobileChrome = userAgent.match(regExp.mobileChrome)
  655. ;
  656. if(isIOS && !isMobileChrome) {
  657. module.verbose('Browser was found to be iOS', userAgent);
  658. return true;
  659. }
  660. else {
  661. return false;
  662. }
  663. },
  664. mobile: function() {
  665. var
  666. userAgent = navigator.userAgent,
  667. isMobile = userAgent.match(regExp.mobile)
  668. ;
  669. if(isMobile) {
  670. module.verbose('Browser was found to be mobile', userAgent);
  671. return true;
  672. }
  673. else {
  674. module.verbose('Browser is not mobile, using regular transition', userAgent);
  675. return false;
  676. }
  677. },
  678. hidden: function() {
  679. return !module.is.visible();
  680. },
  681. visible: function() {
  682. return $module.hasClass(className.visible);
  683. },
  684. // alias
  685. open: function() {
  686. return module.is.visible();
  687. },
  688. closed: function() {
  689. return module.is.hidden();
  690. },
  691. vertical: function() {
  692. return $module.hasClass(className.top);
  693. },
  694. animating: function() {
  695. return $context.hasClass(className.animating);
  696. },
  697. rtl: function () {
  698. if(module.cache.rtl === undefined) {
  699. module.cache.rtl = ($module.css('direction') == 'rtl');
  700. }
  701. return module.cache.rtl;
  702. }
  703. },
  704. setting: function(name, value) {
  705. module.debug('Changing setting', name, value);
  706. if( $.isPlainObject(name) ) {
  707. $.extend(true, settings, name);
  708. }
  709. else if(value !== undefined) {
  710. if($.isPlainObject(settings[name])) {
  711. $.extend(true, settings[name], value);
  712. }
  713. else {
  714. settings[name] = value;
  715. }
  716. }
  717. else {
  718. return settings[name];
  719. }
  720. },
  721. internal: function(name, value) {
  722. if( $.isPlainObject(name) ) {
  723. $.extend(true, module, name);
  724. }
  725. else if(value !== undefined) {
  726. module[name] = value;
  727. }
  728. else {
  729. return module[name];
  730. }
  731. },
  732. debug: function() {
  733. if(!settings.silent && settings.debug) {
  734. if(settings.performance) {
  735. module.performance.log(arguments);
  736. }
  737. else {
  738. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  739. module.debug.apply(console, arguments);
  740. }
  741. }
  742. },
  743. verbose: function() {
  744. if(!settings.silent && settings.verbose && settings.debug) {
  745. if(settings.performance) {
  746. module.performance.log(arguments);
  747. }
  748. else {
  749. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  750. module.verbose.apply(console, arguments);
  751. }
  752. }
  753. },
  754. error: function() {
  755. if(!settings.silent) {
  756. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  757. module.error.apply(console, arguments);
  758. }
  759. },
  760. performance: {
  761. log: function(message) {
  762. var
  763. currentTime,
  764. executionTime,
  765. previousTime
  766. ;
  767. if(settings.performance) {
  768. currentTime = new Date().getTime();
  769. previousTime = time || currentTime;
  770. executionTime = currentTime - previousTime;
  771. time = currentTime;
  772. performance.push({
  773. 'Name' : message[0],
  774. 'Arguments' : [].slice.call(message, 1) || '',
  775. 'Element' : element,
  776. 'Execution Time' : executionTime
  777. });
  778. }
  779. clearTimeout(module.performance.timer);
  780. module.performance.timer = setTimeout(module.performance.display, 500);
  781. },
  782. display: function() {
  783. var
  784. title = settings.name + ':',
  785. totalTime = 0
  786. ;
  787. time = false;
  788. clearTimeout(module.performance.timer);
  789. $.each(performance, function(index, data) {
  790. totalTime += data['Execution Time'];
  791. });
  792. title += ' ' + totalTime + 'ms';
  793. if(moduleSelector) {
  794. title += ' \'' + moduleSelector + '\'';
  795. }
  796. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  797. console.groupCollapsed(title);
  798. if(console.table) {
  799. console.table(performance);
  800. }
  801. else {
  802. $.each(performance, function(index, data) {
  803. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  804. });
  805. }
  806. console.groupEnd();
  807. }
  808. performance = [];
  809. }
  810. },
  811. invoke: function(query, passedArguments, context) {
  812. var
  813. object = instance,
  814. maxDepth,
  815. found,
  816. response
  817. ;
  818. passedArguments = passedArguments || queryArguments;
  819. context = element || context;
  820. if(typeof query == 'string' && object !== undefined) {
  821. query = query.split(/[\. ]/);
  822. maxDepth = query.length - 1;
  823. $.each(query, function(depth, value) {
  824. var camelCaseValue = (depth != maxDepth)
  825. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  826. : query
  827. ;
  828. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  829. object = object[camelCaseValue];
  830. }
  831. else if( object[camelCaseValue] !== undefined ) {
  832. found = object[camelCaseValue];
  833. return false;
  834. }
  835. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  836. object = object[value];
  837. }
  838. else if( object[value] !== undefined ) {
  839. found = object[value];
  840. return false;
  841. }
  842. else {
  843. module.error(error.method, query);
  844. return false;
  845. }
  846. });
  847. }
  848. if ( $.isFunction( found ) ) {
  849. response = found.apply(context, passedArguments);
  850. }
  851. else if(found !== undefined) {
  852. response = found;
  853. }
  854. if(Array.isArray(returnedValue)) {
  855. returnedValue.push(response);
  856. }
  857. else if(returnedValue !== undefined) {
  858. returnedValue = [returnedValue, response];
  859. }
  860. else if(response !== undefined) {
  861. returnedValue = response;
  862. }
  863. return found;
  864. }
  865. }
  866. ;
  867. if(methodInvoked) {
  868. if(instance === undefined) {
  869. module.initialize();
  870. }
  871. module.invoke(query);
  872. }
  873. else {
  874. if(instance !== undefined) {
  875. module.invoke('destroy');
  876. }
  877. module.initialize();
  878. }
  879. });
  880. return (returnedValue !== undefined)
  881. ? returnedValue
  882. : this
  883. ;
  884. };
  885. $.fn.sidebar.settings = {
  886. name : 'Sidebar',
  887. namespace : 'sidebar',
  888. silent : false,
  889. debug : false,
  890. verbose : false,
  891. performance : true,
  892. transition : 'auto',
  893. mobileTransition : 'auto',
  894. defaultTransition : {
  895. computer: {
  896. left : 'uncover',
  897. right : 'uncover',
  898. top : 'overlay',
  899. bottom : 'overlay'
  900. },
  901. mobile: {
  902. left : 'uncover',
  903. right : 'uncover',
  904. top : 'overlay',
  905. bottom : 'overlay'
  906. }
  907. },
  908. context : 'body',
  909. exclusive : false,
  910. closable : true,
  911. dimPage : true,
  912. scrollLock : false,
  913. returnScroll : false,
  914. delaySetup : false,
  915. duration : 500,
  916. onChange : function(){},
  917. onShow : function(){},
  918. onHide : function(){},
  919. onHidden : function(){},
  920. onVisible : function(){},
  921. className : {
  922. active : 'active',
  923. animating : 'animating',
  924. dimmed : 'dimmed',
  925. ios : 'ios',
  926. pushable : 'pushable',
  927. pushed : 'pushed',
  928. right : 'right',
  929. top : 'top',
  930. left : 'left',
  931. bottom : 'bottom',
  932. visible : 'visible'
  933. },
  934. selector: {
  935. fixed : '.fixed',
  936. omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
  937. pusher : '.pusher',
  938. sidebar : '.ui.sidebar'
  939. },
  940. regExp: {
  941. ios : /(iPad|iPhone|iPod)/g,
  942. mobileChrome : /(CriOS)/g,
  943. mobile : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g
  944. },
  945. error : {
  946. method : 'The method you called is not defined.',
  947. pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
  948. movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
  949. overlay : 'The overlay setting is no longer supported, use animation: overlay',
  950. notFound : 'There were no elements that matched the specified selector'
  951. }
  952. };
  953. })( jQuery, window, document );