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.

1119 lines
36 KiB

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