github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/semantic/src/definitions/behaviors/visit.js (about)

     1  /*!
     2   * # Semantic UI - Visit
     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  
    12  ;(function ($, window, document, undefined) {
    13  
    14  "use strict";
    15  
    16  $.visit = $.fn.visit = function(parameters) {
    17    var
    18      $allModules     = $.isFunction(this)
    19          ? $(window)
    20          : $(this),
    21      moduleSelector  = $allModules.selector || '',
    22  
    23      time            = new Date().getTime(),
    24      performance     = [],
    25  
    26      query           = arguments[0],
    27      methodInvoked   = (typeof query == 'string'),
    28      queryArguments  = [].slice.call(arguments, 1),
    29      returnedValue
    30    ;
    31    $allModules
    32      .each(function() {
    33        var
    34          settings        = $.extend(true, {}, $.fn.visit.settings, parameters),
    35  
    36          error           = settings.error,
    37          namespace       = settings.namespace,
    38  
    39          eventNamespace  = '.' + namespace,
    40          moduleNamespace = namespace + '-module',
    41  
    42          $module         = $(this),
    43          $displays       = $(),
    44  
    45          element         = this,
    46          instance        = $module.data(moduleNamespace),
    47          module
    48        ;
    49        module = {
    50  
    51          initialize: function() {
    52            if(settings.count) {
    53              module.store(settings.key.count, settings.count);
    54            }
    55            else if(settings.id) {
    56              module.add.id(settings.id);
    57            }
    58            else if(settings.increment && methodInvoked !== 'increment') {
    59              module.increment();
    60            }
    61            module.add.display($module);
    62            module.instantiate();
    63          },
    64  
    65          instantiate: function() {
    66            module.verbose('Storing instance of visit module', module);
    67            instance = module;
    68            $module
    69              .data(moduleNamespace, module)
    70            ;
    71          },
    72  
    73          destroy: function() {
    74            module.verbose('Destroying instance');
    75            $module
    76              .removeData(moduleNamespace)
    77            ;
    78          },
    79  
    80          increment: function(id) {
    81            var
    82              currentValue = module.get.count(),
    83              newValue     = +(currentValue) + 1
    84            ;
    85            if(id) {
    86              module.add.id(id);
    87            }
    88            else {
    89              if(newValue > settings.limit && !settings.surpass) {
    90                newValue = settings.limit;
    91              }
    92              module.debug('Incrementing visits', newValue);
    93              module.store(settings.key.count, newValue);
    94            }
    95          },
    96  
    97          decrement: function(id) {
    98            var
    99              currentValue = module.get.count(),
   100              newValue     = +(currentValue) - 1
   101            ;
   102            if(id) {
   103              module.remove.id(id);
   104            }
   105            else {
   106              module.debug('Removing visit');
   107              module.store(settings.key.count, newValue);
   108            }
   109          },
   110  
   111          get: {
   112            count: function() {
   113              return +(module.retrieve(settings.key.count)) || 0;
   114            },
   115            idCount: function(ids) {
   116              ids = ids || module.get.ids();
   117              return ids.length;
   118            },
   119            ids: function(delimitedIDs) {
   120              var
   121                idArray = []
   122              ;
   123              delimitedIDs = delimitedIDs || module.retrieve(settings.key.ids);
   124              if(typeof delimitedIDs === 'string') {
   125                idArray = delimitedIDs.split(settings.delimiter);
   126              }
   127              module.verbose('Found visited ID list', idArray);
   128              return idArray;
   129            },
   130            storageOptions: function(data) {
   131              var
   132                options = {}
   133              ;
   134              if(settings.expires) {
   135                options.expires = settings.expires;
   136              }
   137              if(settings.domain) {
   138                options.domain = settings.domain;
   139              }
   140              if(settings.path) {
   141                options.path = settings.path;
   142              }
   143              return options;
   144            }
   145          },
   146  
   147          has: {
   148            visited: function(id, ids) {
   149              var
   150                visited = false
   151              ;
   152              ids = ids || module.get.ids();
   153              if(id !== undefined && ids) {
   154                $.each(ids, function(index, value){
   155                  if(value == id) {
   156                    visited = true;
   157                  }
   158                });
   159              }
   160              return visited;
   161            }
   162          },
   163  
   164          set: {
   165            count: function(value) {
   166              module.store(settings.key.count, value);
   167            },
   168            ids: function(value) {
   169              module.store(settings.key.ids, value);
   170            }
   171          },
   172  
   173          reset: function() {
   174            module.store(settings.key.count, 0);
   175            module.store(settings.key.ids, null);
   176          },
   177  
   178          add: {
   179            id: function(id) {
   180              var
   181                currentIDs = module.retrieve(settings.key.ids),
   182                newIDs = (currentIDs === undefined || currentIDs === '')
   183                  ? id
   184                  : currentIDs + settings.delimiter + id
   185              ;
   186              if( module.has.visited(id) ) {
   187                module.debug('Unique content already visited, not adding visit', id, currentIDs);
   188              }
   189              else if(id === undefined) {
   190                module.debug('ID is not defined');
   191              }
   192              else {
   193                module.debug('Adding visit to unique content', id);
   194                module.store(settings.key.ids, newIDs);
   195              }
   196              module.set.count( module.get.idCount() );
   197            },
   198            display: function(selector) {
   199              var
   200                $element = $(selector)
   201              ;
   202              if($element.length > 0 && !$.isWindow($element[0])) {
   203                module.debug('Updating visit count for element', $element);
   204                $displays = ($displays.length > 0)
   205                  ? $displays.add($element)
   206                  : $element
   207                ;
   208              }
   209            }
   210          },
   211  
   212          remove: {
   213            id: function(id) {
   214              var
   215                currentIDs = module.get.ids(),
   216                newIDs     = []
   217              ;
   218              if(id !== undefined && currentIDs !== undefined) {
   219                module.debug('Removing visit to unique content', id, currentIDs);
   220                $.each(currentIDs, function(index, value){
   221                  if(value !== id) {
   222                    newIDs.push(value);
   223                  }
   224                });
   225                newIDs = newIDs.join(settings.delimiter);
   226                module.store(settings.key.ids, newIDs );
   227              }
   228              module.set.count( module.get.idCount() );
   229            }
   230          },
   231  
   232          check: {
   233            limit: function(value) {
   234              value = value || module.get.count();
   235              if(settings.limit) {
   236                if(value >= settings.limit) {
   237                  module.debug('Pages viewed exceeded limit, firing callback', value, settings.limit);
   238                  settings.onLimit.call(element, value);
   239                }
   240                module.debug('Limit not reached', value, settings.limit);
   241                settings.onChange.call(element, value);
   242              }
   243              module.update.display(value);
   244            }
   245          },
   246  
   247          update: {
   248            display: function(value) {
   249              value = value || module.get.count();
   250              if($displays.length > 0) {
   251                module.debug('Updating displayed view count', $displays);
   252                $displays.html(value);
   253              }
   254            }
   255          },
   256  
   257          store: function(key, value) {
   258            var
   259              options = module.get.storageOptions(value)
   260            ;
   261            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
   262              window.localStorage.setItem(key, value);
   263              module.debug('Value stored using local storage', key, value);
   264            }
   265            else if($.cookie !== undefined) {
   266              $.cookie(key, value, options);
   267              module.debug('Value stored using cookie', key, value, options);
   268            }
   269            else {
   270              module.error(error.noCookieStorage);
   271              return;
   272            }
   273            if(key == settings.key.count) {
   274              module.check.limit(value);
   275            }
   276          },
   277          retrieve: function(key, value) {
   278            var
   279              storedValue
   280            ;
   281            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
   282              storedValue = window.localStorage.getItem(key);
   283            }
   284            // get by cookie
   285            else if($.cookie !== undefined) {
   286              storedValue = $.cookie(key);
   287            }
   288            else {
   289              module.error(error.noCookieStorage);
   290            }
   291            if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
   292              storedValue = undefined;
   293            }
   294            return storedValue;
   295          },
   296  
   297          setting: function(name, value) {
   298            if( $.isPlainObject(name) ) {
   299              $.extend(true, settings, name);
   300            }
   301            else if(value !== undefined) {
   302              settings[name] = value;
   303            }
   304            else {
   305              return settings[name];
   306            }
   307          },
   308          internal: function(name, value) {
   309            module.debug('Changing internal', name, value);
   310            if(value !== undefined) {
   311              if( $.isPlainObject(name) ) {
   312                $.extend(true, module, name);
   313              }
   314              else {
   315                module[name] = value;
   316              }
   317            }
   318            else {
   319              return module[name];
   320            }
   321          },
   322          debug: function() {
   323            if(settings.debug) {
   324              if(settings.performance) {
   325                module.performance.log(arguments);
   326              }
   327              else {
   328                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
   329                module.debug.apply(console, arguments);
   330              }
   331            }
   332          },
   333          verbose: function() {
   334            if(settings.verbose && settings.debug) {
   335              if(settings.performance) {
   336                module.performance.log(arguments);
   337              }
   338              else {
   339                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
   340                module.verbose.apply(console, arguments);
   341              }
   342            }
   343          },
   344          error: function() {
   345            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
   346            module.error.apply(console, arguments);
   347          },
   348          performance: {
   349            log: function(message) {
   350              var
   351                currentTime,
   352                executionTime,
   353                previousTime
   354              ;
   355              if(settings.performance) {
   356                currentTime   = new Date().getTime();
   357                previousTime  = time || currentTime;
   358                executionTime = currentTime - previousTime;
   359                time          = currentTime;
   360                performance.push({
   361                  'Name'           : message[0],
   362                  'Arguments'      : [].slice.call(message, 1) || '',
   363                  'Element'        : element,
   364                  'Execution Time' : executionTime
   365                });
   366              }
   367              clearTimeout(module.performance.timer);
   368              module.performance.timer = setTimeout(module.performance.display, 100);
   369            },
   370            display: function() {
   371              var
   372                title = settings.name + ':',
   373                totalTime = 0
   374              ;
   375              time = false;
   376              clearTimeout(module.performance.timer);
   377              $.each(performance, function(index, data) {
   378                totalTime += data['Execution Time'];
   379              });
   380              title += ' ' + totalTime + 'ms';
   381              if(moduleSelector) {
   382                title += ' \'' + moduleSelector + '\'';
   383              }
   384              if($allModules.length > 1) {
   385                title += ' ' + '(' + $allModules.length + ')';
   386              }
   387              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
   388                console.groupCollapsed(title);
   389                if(console.table) {
   390                  console.table(performance);
   391                }
   392                else {
   393                  $.each(performance, function(index, data) {
   394                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
   395                  });
   396                }
   397                console.groupEnd();
   398              }
   399              performance = [];
   400            }
   401          },
   402          invoke: function(query, passedArguments, context) {
   403            var
   404              object = instance,
   405              maxDepth,
   406              found,
   407              response
   408            ;
   409            passedArguments = passedArguments || queryArguments;
   410            context         = element         || context;
   411            if(typeof query == 'string' && object !== undefined) {
   412              query    = query.split(/[\. ]/);
   413              maxDepth = query.length - 1;
   414              $.each(query, function(depth, value) {
   415                var camelCaseValue = (depth != maxDepth)
   416                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
   417                  : query
   418                ;
   419                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
   420                  object = object[camelCaseValue];
   421                }
   422                else if( object[camelCaseValue] !== undefined ) {
   423                  found = object[camelCaseValue];
   424                  return false;
   425                }
   426                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
   427                  object = object[value];
   428                }
   429                else if( object[value] !== undefined ) {
   430                  found = object[value];
   431                  return false;
   432                }
   433                else {
   434                  return false;
   435                }
   436              });
   437            }
   438            if ( $.isFunction( found ) ) {
   439              response = found.apply(context, passedArguments);
   440            }
   441            else if(found !== undefined) {
   442              response = found;
   443            }
   444            if($.isArray(returnedValue)) {
   445              returnedValue.push(response);
   446            }
   447            else if(returnedValue !== undefined) {
   448              returnedValue = [returnedValue, response];
   449            }
   450            else if(response !== undefined) {
   451              returnedValue = response;
   452            }
   453            return found;
   454          }
   455        };
   456        if(methodInvoked) {
   457          if(instance === undefined) {
   458            module.initialize();
   459          }
   460          module.invoke(query);
   461        }
   462        else {
   463          if(instance !== undefined) {
   464            instance.invoke('destroy');
   465          }
   466          module.initialize();
   467        }
   468  
   469      })
   470    ;
   471    return (returnedValue !== undefined)
   472      ? returnedValue
   473      : this
   474    ;
   475  };
   476  
   477  $.fn.visit.settings = {
   478  
   479    name          : 'Visit',
   480  
   481    debug         : false,
   482    verbose       : true,
   483    performance   : true,
   484  
   485    namespace     : 'visit',
   486  
   487    increment     : false,
   488    surpass       : false,
   489    count         : false,
   490    limit         : false,
   491  
   492    delimiter     : '&',
   493    storageMethod : 'localstorage',
   494  
   495    key           : {
   496      count : 'visit-count',
   497      ids   : 'visit-ids'
   498    },
   499  
   500    expires       : 30,
   501    domain        : false,
   502    path          : '/',
   503  
   504    onLimit       : function() {},
   505    onChange      : function() {},
   506  
   507    error         : {
   508      method          : 'The method you called is not defined',
   509      missingPersist  : 'Using the persist setting requires the inclusion of PersistJS',
   510      noCookieStorage : 'The default storage cookie requires $.cookie to be included.'
   511    }
   512  
   513  };
   514  
   515  })( jQuery, window , document );