Code Duplication    Length = 1023-1023 lines in 2 locations

public/lib/semantic/semantic.js 1 location

@@ 15663-16685 (lines=1023) @@
15660
 *
15661
 */
15662
15663
;(function ($, window, document, undefined) {
15664
15665
"use strict";
15666
15667
window = (typeof window != 'undefined' && window.Math == Math)
15668
  ? window
15669
  : (typeof self != 'undefined' && self.Math == Math)
15670
    ? self
15671
    : Function('return this')()
15672
;
15673
15674
$.fn.sidebar = function(parameters) {
15675
  var
15676
    $allModules     = $(this),
15677
    $window         = $(window),
15678
    $document       = $(document),
15679
    $html           = $('html'),
15680
    $head           = $('head'),
15681
15682
    moduleSelector  = $allModules.selector || '',
15683
15684
    time            = new Date().getTime(),
15685
    performance     = [],
15686
15687
    query           = arguments[0],
15688
    methodInvoked   = (typeof query == 'string'),
15689
    queryArguments  = [].slice.call(arguments, 1),
15690
15691
    requestAnimationFrame = window.requestAnimationFrame
15692
      || window.mozRequestAnimationFrame
15693
      || window.webkitRequestAnimationFrame
15694
      || window.msRequestAnimationFrame
15695
      || function(callback) { setTimeout(callback, 0); },
15696
15697
    returnedValue
15698
  ;
15699
15700
  $allModules
15701
    .each(function() {
15702
      var
15703
        settings        = ( $.isPlainObject(parameters) )
15704
          ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
15705
          : $.extend({}, $.fn.sidebar.settings),
15706
15707
        selector        = settings.selector,
15708
        className       = settings.className,
15709
        namespace       = settings.namespace,
15710
        regExp          = settings.regExp,
15711
        error           = settings.error,
15712
15713
        eventNamespace  = '.' + namespace,
15714
        moduleNamespace = 'module-' + namespace,
15715
15716
        $module         = $(this),
15717
        $context        = $(settings.context),
15718
15719
        $sidebars       = $module.children(selector.sidebar),
15720
        $fixed          = $context.children(selector.fixed),
15721
        $pusher         = $context.children(selector.pusher),
15722
        $style,
15723
15724
        element         = this,
15725
        instance        = $module.data(moduleNamespace),
15726
15727
        elementNamespace,
15728
        id,
15729
        currentScroll,
15730
        transitionEvent,
15731
15732
        module
15733
      ;
15734
15735
      module      = {
15736
15737
        initialize: function() {
15738
          module.debug('Initializing sidebar', parameters);
15739
15740
          module.create.id();
15741
15742
          transitionEvent = module.get.transitionEvent();
15743
15744
          // avoids locking rendering if initialized in onReady
15745
          if(settings.delaySetup) {
15746
            requestAnimationFrame(module.setup.layout);
15747
          }
15748
          else {
15749
            module.setup.layout();
15750
          }
15751
15752
          requestAnimationFrame(function() {
15753
            module.setup.cache();
15754
          });
15755
15756
          module.instantiate();
15757
        },
15758
15759
        instantiate: function() {
15760
          module.verbose('Storing instance of module', module);
15761
          instance = module;
15762
          $module
15763
            .data(moduleNamespace, module)
15764
          ;
15765
        },
15766
15767
        create: {
15768
          id: function() {
15769
            id = (Math.random().toString(16) + '000000000').substr(2,8);
15770
            elementNamespace = '.' + id;
15771
            module.verbose('Creating unique id for element', id);
15772
          }
15773
        },
15774
15775
        destroy: function() {
15776
          module.verbose('Destroying previous module for', $module);
15777
          $module
15778
            .off(eventNamespace)
15779
            .removeData(moduleNamespace)
15780
          ;
15781
          if(module.is.ios()) {
15782
            module.remove.ios();
15783
          }
15784
          // bound by uuid
15785
          $context.off(elementNamespace);
15786
          $window.off(elementNamespace);
15787
          $document.off(elementNamespace);
15788
        },
15789
15790
        event: {
15791
          clickaway: function(event) {
15792
            var
15793
              clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
15794
              clickedContext  = ($context.is(event.target))
15795
            ;
15796
            if(clickedInPusher) {
15797
              module.verbose('User clicked on dimmed page');
15798
              module.hide();
15799
            }
15800
            if(clickedContext) {
15801
              module.verbose('User clicked on dimmable context (scaled out page)');
15802
              module.hide();
15803
            }
15804
          },
15805
          touch: function(event) {
15806
            //event.stopPropagation();
15807
          },
15808
          containScroll: function(event) {
15809
            if(element.scrollTop <= 0)  {
15810
              element.scrollTop = 1;
15811
            }
15812
            if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
15813
              element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
15814
            }
15815
          },
15816
          scroll: function(event) {
15817
            if( $(event.target).closest(selector.sidebar).length === 0 ) {
15818
              event.preventDefault();
15819
            }
15820
          }
15821
        },
15822
15823
        bind: {
15824
          clickaway: function() {
15825
            module.verbose('Adding clickaway events to context', $context);
15826
            if(settings.closable) {
15827
              $context
15828
                .on('click'    + elementNamespace, module.event.clickaway)
15829
                .on('touchend' + elementNamespace, module.event.clickaway)
15830
              ;
15831
            }
15832
          },
15833
          scrollLock: function() {
15834
            if(settings.scrollLock) {
15835
              module.debug('Disabling page scroll');
15836
              $window
15837
                .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
15838
              ;
15839
            }
15840
            module.verbose('Adding events to contain sidebar scroll');
15841
            $document
15842
              .on('touchmove' + elementNamespace, module.event.touch)
15843
            ;
15844
            $module
15845
              .on('scroll' + eventNamespace, module.event.containScroll)
15846
            ;
15847
          }
15848
        },
15849
        unbind: {
15850
          clickaway: function() {
15851
            module.verbose('Removing clickaway events from context', $context);
15852
            $context.off(elementNamespace);
15853
          },
15854
          scrollLock: function() {
15855
            module.verbose('Removing scroll lock from page');
15856
            $document.off(elementNamespace);
15857
            $window.off(elementNamespace);
15858
            $module.off('scroll' + eventNamespace);
15859
          }
15860
        },
15861
15862
        add: {
15863
          inlineCSS: function() {
15864
            var
15865
              width     = module.cache.width  || $module.outerWidth(),
15866
              height    = module.cache.height || $module.outerHeight(),
15867
              isRTL     = module.is.rtl(),
15868
              direction = module.get.direction(),
15869
              distance  = {
15870
                left   : width,
15871
                right  : -width,
15872
                top    : height,
15873
                bottom : -height
15874
              },
15875
              style
15876
            ;
15877
15878
            if(isRTL){
15879
              module.verbose('RTL detected, flipping widths');
15880
              distance.left = -width;
15881
              distance.right = width;
15882
            }
15883
15884
            style  = '<style>';
15885
15886
            if(direction === 'left' || direction === 'right') {
15887
              module.debug('Adding CSS rules for animation distance', width);
15888
              style  += ''
15889
                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
15890
                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
15891
                + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15892
                + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15893
                + ' }'
15894
              ;
15895
            }
15896
            else if(direction === 'top' || direction == 'bottom') {
15897
              style  += ''
15898
                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
15899
                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
15900
                + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15901
                + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15902
                + ' }'
15903
              ;
15904
            }
15905
15906
            /* IE is only browser not to create context with transforms */
15907
            /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
15908
            if( module.is.ie() ) {
15909
              if(direction === 'left' || direction === 'right') {
15910
                module.debug('Adding CSS rules for animation distance', width);
15911
                style  += ''
15912
                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
15913
                  + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15914
                  + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15915
                  + ' }'
15916
                ;
15917
              }
15918
              else if(direction === 'top' || direction == 'bottom') {
15919
                style  += ''
15920
                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
15921
                  + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15922
                  + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15923
                  + ' }'
15924
                ;
15925
              }
15926
              /* opposite sides visible forces content overlay */
15927
              style += ''
15928
                + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
15929
                + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
15930
                + '   -webkit-transform: translate3d(0px, 0, 0);'
15931
                + '           transform: translate3d(0px, 0, 0);'
15932
                + ' }'
15933
              ;
15934
            }
15935
            style += '</style>';
15936
            $style = $(style)
15937
              .appendTo($head)
15938
            ;
15939
            module.debug('Adding sizing css to head', $style);
15940
          }
15941
        },
15942
15943
        refresh: function() {
15944
          module.verbose('Refreshing selector cache');
15945
          $context  = $(settings.context);
15946
          $sidebars = $context.children(selector.sidebar);
15947
          $pusher   = $context.children(selector.pusher);
15948
          $fixed    = $context.children(selector.fixed);
15949
          module.clear.cache();
15950
        },
15951
15952
        refreshSidebars: function() {
15953
          module.verbose('Refreshing other sidebars');
15954
          $sidebars = $context.children(selector.sidebar);
15955
        },
15956
15957
        repaint: function() {
15958
          module.verbose('Forcing repaint event');
15959
          element.style.display = 'none';
15960
          var ignored = element.offsetHeight;
15961
          element.scrollTop = element.scrollTop;
15962
          element.style.display = '';
15963
        },
15964
15965
        setup: {
15966
          cache: function() {
15967
            module.cache = {
15968
              width  : $module.outerWidth(),
15969
              height : $module.outerHeight(),
15970
              rtl    : ($module.css('direction') == 'rtl')
15971
            };
15972
          },
15973
          layout: function() {
15974
            if( $context.children(selector.pusher).length === 0 ) {
15975
              module.debug('Adding wrapper element for sidebar');
15976
              module.error(error.pusher);
15977
              $pusher = $('<div class="pusher" />');
15978
              $context
15979
                .children()
15980
                  .not(selector.omitted)
15981
                  .not($sidebars)
15982
                  .wrapAll($pusher)
15983
              ;
15984
              module.refresh();
15985
            }
15986
            if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
15987
              module.debug('Moved sidebar to correct parent element');
15988
              module.error(error.movedSidebar, element);
15989
              $module.detach().prependTo($context);
15990
              module.refresh();
15991
            }
15992
            module.clear.cache();
15993
            module.set.pushable();
15994
            module.set.direction();
15995
          }
15996
        },
15997
15998
        attachEvents: function(selector, event) {
15999
          var
16000
            $toggle = $(selector)
16001
          ;
16002
          event = $.isFunction(module[event])
16003
            ? module[event]
16004
            : module.toggle
16005
          ;
16006
          if($toggle.length > 0) {
16007
            module.debug('Attaching sidebar events to element', selector, event);
16008
            $toggle
16009
              .on('click' + eventNamespace, event)
16010
            ;
16011
          }
16012
          else {
16013
            module.error(error.notFound, selector);
16014
          }
16015
        },
16016
16017
        show: function(callback) {
16018
          callback = $.isFunction(callback)
16019
            ? callback
16020
            : function(){}
16021
          ;
16022
          if(module.is.hidden()) {
16023
            module.refreshSidebars();
16024
            if(settings.overlay)  {
16025
              module.error(error.overlay);
16026
              settings.transition = 'overlay';
16027
            }
16028
            module.refresh();
16029
            if(module.othersActive()) {
16030
              module.debug('Other sidebars currently visible');
16031
              if(settings.exclusive) {
16032
                // if not overlay queue animation after hide
16033
                if(settings.transition != 'overlay') {
16034
                  module.hideOthers(module.show);
16035
                  return;
16036
                }
16037
                else {
16038
                  module.hideOthers();
16039
                }
16040
              }
16041
              else {
16042
                settings.transition = 'overlay';
16043
              }
16044
            }
16045
            module.pushPage(function() {
16046
              callback.call(element);
16047
              settings.onShow.call(element);
16048
            });
16049
            settings.onChange.call(element);
16050
            settings.onVisible.call(element);
16051
          }
16052
          else {
16053
            module.debug('Sidebar is already visible');
16054
          }
16055
        },
16056
16057
        hide: function(callback) {
16058
          callback = $.isFunction(callback)
16059
            ? callback
16060
            : function(){}
16061
          ;
16062
          if(module.is.visible() || module.is.animating()) {
16063
            module.debug('Hiding sidebar', callback);
16064
            module.refreshSidebars();
16065
            module.pullPage(function() {
16066
              callback.call(element);
16067
              settings.onHidden.call(element);
16068
            });
16069
            settings.onChange.call(element);
16070
            settings.onHide.call(element);
16071
          }
16072
        },
16073
16074
        othersAnimating: function() {
16075
          return ($sidebars.not($module).filter('.' + className.animating).length > 0);
16076
        },
16077
        othersVisible: function() {
16078
          return ($sidebars.not($module).filter('.' + className.visible).length > 0);
16079
        },
16080
        othersActive: function() {
16081
          return(module.othersVisible() || module.othersAnimating());
16082
        },
16083
16084
        hideOthers: function(callback) {
16085
          var
16086
            $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
16087
            sidebarCount   = $otherSidebars.length,
16088
            callbackCount  = 0
16089
          ;
16090
          callback = callback || function(){};
16091
          $otherSidebars
16092
            .sidebar('hide', function() {
16093
              callbackCount++;
16094
              if(callbackCount == sidebarCount) {
16095
                callback();
16096
              }
16097
            })
16098
          ;
16099
        },
16100
16101
        toggle: function() {
16102
          module.verbose('Determining toggled direction');
16103
          if(module.is.hidden()) {
16104
            module.show();
16105
          }
16106
          else {
16107
            module.hide();
16108
          }
16109
        },
16110
16111
        pushPage: function(callback) {
16112
          var
16113
            transition = module.get.transition(),
16114
            $transition = (transition === 'overlay' || module.othersActive())
16115
              ? $module
16116
              : $pusher,
16117
            animate,
16118
            dim,
16119
            transitionEnd
16120
          ;
16121
          callback = $.isFunction(callback)
16122
            ? callback
16123
            : function(){}
16124
          ;
16125
          if(settings.transition == 'scale down') {
16126
            module.scrollToTop();
16127
          }
16128
          module.set.transition(transition);
16129
          module.repaint();
16130
          animate = function() {
16131
            module.bind.clickaway();
16132
            module.add.inlineCSS();
16133
            module.set.animating();
16134
            module.set.visible();
16135
          };
16136
          dim = function() {
16137
            module.set.dimmed();
16138
          };
16139
          transitionEnd = function(event) {
16140
            if( event.target == $transition[0] ) {
16141
              $transition.off(transitionEvent + elementNamespace, transitionEnd);
16142
              module.remove.animating();
16143
              module.bind.scrollLock();
16144
              callback.call(element);
16145
            }
16146
          };
16147
          $transition.off(transitionEvent + elementNamespace);
16148
          $transition.on(transitionEvent + elementNamespace, transitionEnd);
16149
          requestAnimationFrame(animate);
16150
          if(settings.dimPage && !module.othersVisible()) {
16151
            requestAnimationFrame(dim);
16152
          }
16153
        },
16154
16155
        pullPage: function(callback) {
16156
          var
16157
            transition = module.get.transition(),
16158
            $transition = (transition == 'overlay' || module.othersActive())
16159
              ? $module
16160
              : $pusher,
16161
            animate,
16162
            transitionEnd
16163
          ;
16164
          callback = $.isFunction(callback)
16165
            ? callback
16166
            : function(){}
16167
          ;
16168
          module.verbose('Removing context push state', module.get.direction());
16169
16170
          module.unbind.clickaway();
16171
          module.unbind.scrollLock();
16172
16173
          animate = function() {
16174
            module.set.transition(transition);
16175
            module.set.animating();
16176
            module.remove.visible();
16177
            if(settings.dimPage && !module.othersVisible()) {
16178
              $pusher.removeClass(className.dimmed);
16179
            }
16180
          };
16181
          transitionEnd = function(event) {
16182
            if( event.target == $transition[0] ) {
16183
              $transition.off(transitionEvent + elementNamespace, transitionEnd);
16184
              module.remove.animating();
16185
              module.remove.transition();
16186
              module.remove.inlineCSS();
16187
              if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
16188
                module.scrollBack();
16189
              }
16190
              callback.call(element);
16191
            }
16192
          };
16193
          $transition.off(transitionEvent + elementNamespace);
16194
          $transition.on(transitionEvent + elementNamespace, transitionEnd);
16195
          requestAnimationFrame(animate);
16196
        },
16197
16198
        scrollToTop: function() {
16199
          module.verbose('Scrolling to top of page to avoid animation issues');
16200
          currentScroll = $(window).scrollTop();
16201
          $module.scrollTop(0);
16202
          window.scrollTo(0, 0);
16203
        },
16204
16205
        scrollBack: function() {
16206
          module.verbose('Scrolling back to original page position');
16207
          window.scrollTo(0, currentScroll);
16208
        },
16209
16210
        clear: {
16211
          cache: function() {
16212
            module.verbose('Clearing cached dimensions');
16213
            module.cache = {};
16214
          }
16215
        },
16216
16217
        set: {
16218
16219
          // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
16220
          // (This is no longer necessary in latest iOS)
16221
          ios: function() {
16222
            $html.addClass(className.ios);
16223
          },
16224
16225
          // container
16226
          pushed: function() {
16227
            $context.addClass(className.pushed);
16228
          },
16229
          pushable: function() {
16230
            $context.addClass(className.pushable);
16231
          },
16232
16233
          // pusher
16234
          dimmed: function() {
16235
            $pusher.addClass(className.dimmed);
16236
          },
16237
16238
          // sidebar
16239
          active: function() {
16240
            $module.addClass(className.active);
16241
          },
16242
          animating: function() {
16243
            $module.addClass(className.animating);
16244
          },
16245
          transition: function(transition) {
16246
            transition = transition || module.get.transition();
16247
            $module.addClass(transition);
16248
          },
16249
          direction: function(direction) {
16250
            direction = direction || module.get.direction();
16251
            $module.addClass(className[direction]);
16252
          },
16253
          visible: function() {
16254
            $module.addClass(className.visible);
16255
          },
16256
          overlay: function() {
16257
            $module.addClass(className.overlay);
16258
          }
16259
        },
16260
        remove: {
16261
16262
          inlineCSS: function() {
16263
            module.debug('Removing inline css styles', $style);
16264
            if($style && $style.length > 0) {
16265
              $style.remove();
16266
            }
16267
          },
16268
16269
          // ios scroll on html not document
16270
          ios: function() {
16271
            $html.removeClass(className.ios);
16272
          },
16273
16274
          // context
16275
          pushed: function() {
16276
            $context.removeClass(className.pushed);
16277
          },
16278
          pushable: function() {
16279
            $context.removeClass(className.pushable);
16280
          },
16281
16282
          // sidebar
16283
          active: function() {
16284
            $module.removeClass(className.active);
16285
          },
16286
          animating: function() {
16287
            $module.removeClass(className.animating);
16288
          },
16289
          transition: function(transition) {
16290
            transition = transition || module.get.transition();
16291
            $module.removeClass(transition);
16292
          },
16293
          direction: function(direction) {
16294
            direction = direction || module.get.direction();
16295
            $module.removeClass(className[direction]);
16296
          },
16297
          visible: function() {
16298
            $module.removeClass(className.visible);
16299
          },
16300
          overlay: function() {
16301
            $module.removeClass(className.overlay);
16302
          }
16303
        },
16304
16305
        get: {
16306
          direction: function() {
16307
            if($module.hasClass(className.top)) {
16308
              return className.top;
16309
            }
16310
            else if($module.hasClass(className.right)) {
16311
              return className.right;
16312
            }
16313
            else if($module.hasClass(className.bottom)) {
16314
              return className.bottom;
16315
            }
16316
            return className.left;
16317
          },
16318
          transition: function() {
16319
            var
16320
              direction = module.get.direction(),
16321
              transition
16322
            ;
16323
            transition = ( module.is.mobile() )
16324
              ? (settings.mobileTransition == 'auto')
16325
                ? settings.defaultTransition.mobile[direction]
16326
                : settings.mobileTransition
16327
              : (settings.transition == 'auto')
16328
                ? settings.defaultTransition.computer[direction]
16329
                : settings.transition
16330
            ;
16331
            module.verbose('Determined transition', transition);
16332
            return transition;
16333
          },
16334
          transitionEvent: function() {
16335
            var
16336
              element     = document.createElement('element'),
16337
              transitions = {
16338
                'transition'       :'transitionend',
16339
                'OTransition'      :'oTransitionEnd',
16340
                'MozTransition'    :'transitionend',
16341
                'WebkitTransition' :'webkitTransitionEnd'
16342
              },
16343
              transition
16344
            ;
16345
            for(transition in transitions){
16346
              if( element.style[transition] !== undefined ){
16347
                return transitions[transition];
16348
              }
16349
            }
16350
          }
16351
        },
16352
16353
        is: {
16354
16355
          ie: function() {
16356
            var
16357
              isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
16358
              isIE   = ('ActiveXObject' in window)
16359
            ;
16360
            return (isIE11 || isIE);
16361
          },
16362
16363
          ios: function() {
16364
            var
16365
              userAgent      = navigator.userAgent,
16366
              isIOS          = userAgent.match(regExp.ios),
16367
              isMobileChrome = userAgent.match(regExp.mobileChrome)
16368
            ;
16369
            if(isIOS && !isMobileChrome) {
16370
              module.verbose('Browser was found to be iOS', userAgent);
16371
              return true;
16372
            }
16373
            else {
16374
              return false;
16375
            }
16376
          },
16377
          mobile: function() {
16378
            var
16379
              userAgent    = navigator.userAgent,
16380
              isMobile     = userAgent.match(regExp.mobile)
16381
            ;
16382
            if(isMobile) {
16383
              module.verbose('Browser was found to be mobile', userAgent);
16384
              return true;
16385
            }
16386
            else {
16387
              module.verbose('Browser is not mobile, using regular transition', userAgent);
16388
              return false;
16389
            }
16390
          },
16391
          hidden: function() {
16392
            return !module.is.visible();
16393
          },
16394
          visible: function() {
16395
            return $module.hasClass(className.visible);
16396
          },
16397
          // alias
16398
          open: function() {
16399
            return module.is.visible();
16400
          },
16401
          closed: function() {
16402
            return module.is.hidden();
16403
          },
16404
          vertical: function() {
16405
            return $module.hasClass(className.top);
16406
          },
16407
          animating: function() {
16408
            return $context.hasClass(className.animating);
16409
          },
16410
          rtl: function () {
16411
            if(module.cache.rtl === undefined) {
16412
              module.cache.rtl = ($module.css('direction') == 'rtl');
16413
            }
16414
            return module.cache.rtl;
16415
          }
16416
        },
16417
16418
        setting: function(name, value) {
16419
          module.debug('Changing setting', name, value);
16420
          if( $.isPlainObject(name) ) {
16421
            $.extend(true, settings, name);
16422
          }
16423
          else if(value !== undefined) {
16424
            if($.isPlainObject(settings[name])) {
16425
              $.extend(true, settings[name], value);
16426
            }
16427
            else {
16428
              settings[name] = value;
16429
            }
16430
          }
16431
          else {
16432
            return settings[name];
16433
          }
16434
        },
16435
        internal: function(name, value) {
16436
          if( $.isPlainObject(name) ) {
16437
            $.extend(true, module, name);
16438
          }
16439
          else if(value !== undefined) {
16440
            module[name] = value;
16441
          }
16442
          else {
16443
            return module[name];
16444
          }
16445
        },
16446
        debug: function() {
16447
          if(!settings.silent && settings.debug) {
16448
            if(settings.performance) {
16449
              module.performance.log(arguments);
16450
            }
16451
            else {
16452
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
16453
              module.debug.apply(console, arguments);
16454
            }
16455
          }
16456
        },
16457
        verbose: function() {
16458
          if(!settings.silent && settings.verbose && settings.debug) {
16459
            if(settings.performance) {
16460
              module.performance.log(arguments);
16461
            }
16462
            else {
16463
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
16464
              module.verbose.apply(console, arguments);
16465
            }
16466
          }
16467
        },
16468
        error: function() {
16469
          if(!settings.silent) {
16470
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
16471
            module.error.apply(console, arguments);
16472
          }
16473
        },
16474
        performance: {
16475
          log: function(message) {
16476
            var
16477
              currentTime,
16478
              executionTime,
16479
              previousTime
16480
            ;
16481
            if(settings.performance) {
16482
              currentTime   = new Date().getTime();
16483
              previousTime  = time || currentTime;
16484
              executionTime = currentTime - previousTime;
16485
              time          = currentTime;
16486
              performance.push({
16487
                'Name'           : message[0],
16488
                'Arguments'      : [].slice.call(message, 1) || '',
16489
                'Element'        : element,
16490
                'Execution Time' : executionTime
16491
              });
16492
            }
16493
            clearTimeout(module.performance.timer);
16494
            module.performance.timer = setTimeout(module.performance.display, 500);
16495
          },
16496
          display: function() {
16497
            var
16498
              title = settings.name + ':',
16499
              totalTime = 0
16500
            ;
16501
            time = false;
16502
            clearTimeout(module.performance.timer);
16503
            $.each(performance, function(index, data) {
16504
              totalTime += data['Execution Time'];
16505
            });
16506
            title += ' ' + totalTime + 'ms';
16507
            if(moduleSelector) {
16508
              title += ' \'' + moduleSelector + '\'';
16509
            }
16510
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
16511
              console.groupCollapsed(title);
16512
              if(console.table) {
16513
                console.table(performance);
16514
              }
16515
              else {
16516
                $.each(performance, function(index, data) {
16517
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
16518
                });
16519
              }
16520
              console.groupEnd();
16521
            }
16522
            performance = [];
16523
          }
16524
        },
16525
        invoke: function(query, passedArguments, context) {
16526
          var
16527
            object = instance,
16528
            maxDepth,
16529
            found,
16530
            response
16531
          ;
16532
          passedArguments = passedArguments || queryArguments;
16533
          context         = element         || context;
16534
          if(typeof query == 'string' && object !== undefined) {
16535
            query    = query.split(/[\. ]/);
16536
            maxDepth = query.length - 1;
16537
            $.each(query, function(depth, value) {
16538
              var camelCaseValue = (depth != maxDepth)
16539
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
16540
                : query
16541
              ;
16542
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
16543
                object = object[camelCaseValue];
16544
              }
16545
              else if( object[camelCaseValue] !== undefined ) {
16546
                found = object[camelCaseValue];
16547
                return false;
16548
              }
16549
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
16550
                object = object[value];
16551
              }
16552
              else if( object[value] !== undefined ) {
16553
                found = object[value];
16554
                return false;
16555
              }
16556
              else {
16557
                module.error(error.method, query);
16558
                return false;
16559
              }
16560
            });
16561
          }
16562
          if ( $.isFunction( found ) ) {
16563
            response = found.apply(context, passedArguments);
16564
          }
16565
          else if(found !== undefined) {
16566
            response = found;
16567
          }
16568
          if($.isArray(returnedValue)) {
16569
            returnedValue.push(response);
16570
          }
16571
          else if(returnedValue !== undefined) {
16572
            returnedValue = [returnedValue, response];
16573
          }
16574
          else if(response !== undefined) {
16575
            returnedValue = response;
16576
          }
16577
          return found;
16578
        }
16579
      }
16580
    ;
16581
16582
    if(methodInvoked) {
16583
      if(instance === undefined) {
16584
        module.initialize();
16585
      }
16586
      module.invoke(query);
16587
    }
16588
    else {
16589
      if(instance !== undefined) {
16590
        module.invoke('destroy');
16591
      }
16592
      module.initialize();
16593
    }
16594
  });
16595
16596
  return (returnedValue !== undefined)
16597
    ? returnedValue
16598
    : this
16599
  ;
16600
};
16601
16602
$.fn.sidebar.settings = {
16603
16604
  name              : 'Sidebar',
16605
  namespace         : 'sidebar',
16606
16607
  silent            : false,
16608
  debug             : false,
16609
  verbose           : false,
16610
  performance       : true,
16611
16612
  transition        : 'auto',
16613
  mobileTransition  : 'auto',
16614
16615
  defaultTransition : {
16616
    computer: {
16617
      left   : 'uncover',
16618
      right  : 'uncover',
16619
      top    : 'overlay',
16620
      bottom : 'overlay'
16621
    },
16622
    mobile: {
16623
      left   : 'uncover',
16624
      right  : 'uncover',
16625
      top    : 'overlay',
16626
      bottom : 'overlay'
16627
    }
16628
  },
16629
16630
  context           : 'body',
16631
  exclusive         : false,
16632
  closable          : true,
16633
  dimPage           : true,
16634
  scrollLock        : false,
16635
  returnScroll      : false,
16636
  delaySetup        : false,
16637
16638
  duration          : 500,
16639
16640
  onChange          : function(){},
16641
  onShow            : function(){},
16642
  onHide            : function(){},
16643
16644
  onHidden          : function(){},
16645
  onVisible         : function(){},
16646
16647
  className         : {
16648
    active    : 'active',
16649
    animating : 'animating',
16650
    dimmed    : 'dimmed',
16651
    ios       : 'ios',
16652
    pushable  : 'pushable',
16653
    pushed    : 'pushed',
16654
    right     : 'right',
16655
    top       : 'top',
16656
    left      : 'left',
16657
    bottom    : 'bottom',
16658
    visible   : 'visible'
16659
  },
16660
16661
  selector: {
16662
    fixed   : '.fixed',
16663
    omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
16664
    pusher  : '.pusher',
16665
    sidebar : '.ui.sidebar'
16666
  },
16667
16668
  regExp: {
16669
    ios          : /(iPad|iPhone|iPod)/g,
16670
    mobileChrome : /(CriOS)/g,
16671
    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
16672
  },
16673
16674
  error   : {
16675
    method       : 'The method you called is not defined.',
16676
    pusher       : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
16677
    movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
16678
    overlay      : 'The overlay setting is no longer supported, use animation: overlay',
16679
    notFound     : 'There were no elements that matched the specified selector'
16680
  }
16681
16682
};
16683
16684
16685
})( jQuery, window, document );
16686
16687
/*!
16688
 * # Semantic UI 2.2.11 - Sticky

public/lib/semantic/components/sidebar.js 1 location

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