github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/semantic/dist/components/api.js (about)

     1  /*!
     2   * # Semantic UI x.x - API
     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  $.api = $.fn.api = function(parameters) {
    17  
    18    var
    19      // use window context if none specified
    20      $allModules     = $.isFunction(this)
    21          ? $(window)
    22          : $(this),
    23      moduleSelector = $allModules.selector || '',
    24      time           = new Date().getTime(),
    25      performance    = [],
    26  
    27      query          = arguments[0],
    28      methodInvoked  = (typeof query == 'string'),
    29      queryArguments = [].slice.call(arguments, 1),
    30  
    31      returnedValue
    32    ;
    33  
    34    $allModules
    35      .each(function() {
    36        var
    37          settings          = ( $.isPlainObject(parameters) )
    38            ? $.extend(true, {}, $.fn.api.settings, parameters)
    39            : $.extend({}, $.fn.api.settings),
    40  
    41          // internal aliases
    42          namespace       = settings.namespace,
    43          metadata        = settings.metadata,
    44          selector        = settings.selector,
    45          error           = settings.error,
    46          className       = settings.className,
    47  
    48          // define namespaces for modules
    49          eventNamespace  = '.' + namespace,
    50          moduleNamespace = 'module-' + namespace,
    51  
    52          // element that creates request
    53          $module         = $(this),
    54          $form           = $module.closest(selector.form),
    55  
    56          // context used for state
    57          $context        = (settings.stateContext)
    58            ? $(settings.stateContext)
    59            : $module,
    60  
    61          // request details
    62          ajaxSettings,
    63          requestSettings,
    64          url,
    65          data,
    66  
    67          // standard module
    68          element         = this,
    69          context         = $context.get(),
    70          instance        = $module.data(moduleNamespace),
    71          module
    72        ;
    73  
    74        module = {
    75  
    76          initialize: function() {
    77            var
    78              triggerEvent = module.get.event()
    79            ;
    80            // bind events
    81            if(!methodInvoked) {
    82              if( triggerEvent ) {
    83                module.debug('Attaching API events to element', triggerEvent);
    84                $module
    85                  .on(triggerEvent + eventNamespace, module.event.trigger)
    86                ;
    87              }
    88              else if(settings.on == 'now') {
    89                module.debug('Querying API now', triggerEvent);
    90                module.query();
    91              }
    92            }
    93            module.instantiate();
    94          },
    95  
    96          instantiate: function() {
    97            module.verbose('Storing instance of module', module);
    98            instance = module;
    99            $module
   100              .data(moduleNamespace, instance)
   101            ;
   102          },
   103  
   104          destroy: function() {
   105            module.verbose('Destroying previous module for', element);
   106            $module
   107              .removeData(moduleNamespace)
   108              .off(eventNamespace)
   109            ;
   110          },
   111  
   112          query: function() {
   113  
   114            if(module.is.disabled()) {
   115              module.debug('Element is disabled API request aborted');
   116              return;
   117            }
   118            // determine if an api event already occurred
   119            if(module.is.loading() && settings.throttle === 0 ) {
   120              module.debug('Cancelling request, previous request is still pending');
   121              return;
   122            }
   123  
   124            // pass element metadata to url (value, text)
   125            if(settings.defaultData) {
   126              $.extend(true, settings.urlData, module.get.defaultData());
   127            }
   128  
   129            // Add form content
   130            if(settings.serializeForm !== false || $context.is('form')) {
   131              if(settings.serializeForm == 'json') {
   132                $.extend(true, settings.data, module.get.formData());
   133              }
   134              else {
   135                settings.data = module.get.formData();
   136              }
   137            }
   138  
   139            // call beforesend and get any settings changes
   140            requestSettings         = module.get.settings();
   141  
   142            // check if before send cancelled request
   143            if(requestSettings === false) {
   144              module.cancelled = true;
   145              module.error(error.beforeSend);
   146              return;
   147            }
   148            else {
   149              module.cancelled = false;
   150            }
   151  
   152            if(settings.url) {
   153              // override with url if specified
   154              module.debug('Using specified url', url);
   155              url = module.add.urlData( settings.url );
   156            }
   157            else {
   158              // otherwise find url from api endpoints
   159              url = module.add.urlData( module.get.templateURL() );
   160              module.debug('Added URL Data to url', url);
   161            }
   162  
   163            // exit conditions reached, missing url parameters
   164            if( !url ) {
   165              if( module.is.form() ) {
   166                url = $module.attr('action') || '';
   167                module.debug('No url or action specified, defaulting to form action', url);
   168              }
   169              else {
   170                module.error(error.missingURL, settings.action);
   171                return;
   172              }
   173            }
   174  
   175            // add loading state
   176            module.set.loading();
   177  
   178            // look for jQuery ajax parameters in settings
   179            ajaxSettings = $.extend(true, {}, settings, {
   180              type       : settings.method || settings.type,
   181              data       : data,
   182              url        : settings.base + url,
   183              beforeSend : settings.beforeXHR,
   184              success    : function() {},
   185              failure    : function() {},
   186              complete   : function() {}
   187            });
   188  
   189            module.debug('Querying URL', ajaxSettings.url);
   190            module.debug('Sending data', data, ajaxSettings.method);
   191            module.verbose('Using AJAX settings', ajaxSettings);
   192  
   193            if( module.is.loading() ) {
   194              // throttle additional requests
   195              module.timer = setTimeout(function() {
   196                module.request = module.create.request();
   197                module.xhr     = module.create.xhr();
   198                settings.onRequest.call(context, module.request, module.xhr);
   199              }, settings.throttle);
   200            }
   201            else {
   202              // immediately on first request
   203              module.request = module.create.request();
   204              module.xhr     = module.create.xhr();
   205              settings.onRequest.call(context, module.request, module.xhr);
   206            }
   207  
   208          },
   209  
   210  
   211          is: {
   212            disabled: function() {
   213              return ($module.filter(settings.filter).length > 0);
   214            },
   215            form: function() {
   216              return $module.is('form');
   217            },
   218            input: function() {
   219              return $module.is('input');
   220            },
   221            loading: function() {
   222              return (module.request && module.request.state() == 'pending');
   223            }
   224          },
   225  
   226          was: {
   227            cancelled: function() {
   228              return (module.cancelled || false);
   229            },
   230            succesful: function() {
   231              return (module.request && module.request.state() == 'resolved');
   232            },
   233            failure: function() {
   234              return (module.request && module.request.state() == 'rejected');
   235            },
   236            complete: function() {
   237              return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
   238            }
   239          },
   240  
   241          add: {
   242            urlData: function(url, urlData) {
   243              var
   244                requiredVariables,
   245                optionalVariables
   246              ;
   247              if(url) {
   248                requiredVariables = url.match(settings.regExp.required);
   249                optionalVariables = url.match(settings.regExp.optional);
   250                urlData           = urlData || settings.urlData;
   251                if(requiredVariables) {
   252                  module.debug('Looking for required URL variables', requiredVariables);
   253                  $.each(requiredVariables, function(index, templatedString) {
   254                    var
   255                      // allow legacy {$var} style
   256                      variable = (templatedString.indexOf('$') !== -1)
   257                        ? templatedString.substr(2, templatedString.length - 3)
   258                        : templatedString.substr(1, templatedString.length - 2),
   259                      value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
   260                        ? urlData[variable]
   261                        : ($module.data(variable) !== undefined)
   262                          ? $module.data(variable)
   263                          : ($context.data(variable) !== undefined)
   264                            ? $context.data(variable)
   265                            : urlData[variable]
   266                    ;
   267                    // remove value
   268                    if(value === undefined) {
   269                      module.error(error.requiredParameter, variable, url);
   270                      url = false;
   271                      return false;
   272                    }
   273                    else {
   274                      module.verbose('Found required variable', variable, value);
   275                      url = url.replace(templatedString, value);
   276                    }
   277                  });
   278                }
   279                if(optionalVariables) {
   280                  module.debug('Looking for optional URL variables', requiredVariables);
   281                  $.each(optionalVariables, function(index, templatedString) {
   282                    var
   283                      // allow legacy {/$var} style
   284                      variable = (templatedString.indexOf('$') !== -1)
   285                        ? templatedString.substr(3, templatedString.length - 4)
   286                        : templatedString.substr(2, templatedString.length - 3),
   287                      value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
   288                        ? urlData[variable]
   289                        : ($module.data(variable) !== undefined)
   290                          ? $module.data(variable)
   291                          : ($context.data(variable) !== undefined)
   292                            ? $context.data(variable)
   293                            : urlData[variable]
   294                    ;
   295                    // optional replacement
   296                    if(value !== undefined) {
   297                      module.verbose('Optional variable Found', variable, value);
   298                      url = url.replace(templatedString, value);
   299                    }
   300                    else {
   301                      module.verbose('Optional variable not found', variable);
   302                      // remove preceding slash if set
   303                      if(url.indexOf('/' + templatedString) !== -1) {
   304                        url = url.replace('/' + templatedString, '');
   305                      }
   306                      else {
   307                        url = url.replace(templatedString, '');
   308                      }
   309                    }
   310                  });
   311                }
   312              }
   313              return url;
   314            }
   315          },
   316  
   317          event: {
   318            trigger: function(event) {
   319              module.query();
   320              if(event.type == 'submit' || event.type == 'click') {
   321                event.preventDefault();
   322              }
   323            },
   324            xhr: {
   325              always: function() {
   326                // calculate if loading time was below minimum threshold
   327              },
   328              done: function(response) {
   329                var
   330                  context      = this,
   331                  elapsedTime  = (new Date().getTime() - time),
   332                  timeLeft     = (settings.loadingDuration - elapsedTime)
   333                ;
   334                timeLeft = (timeLeft > 0)
   335                  ? timeLeft
   336                  : 0
   337                ;
   338                setTimeout(function() {
   339                  module.request.resolveWith(context, [response]);
   340                }, timeLeft);
   341              },
   342              fail: function(xhr, status, httpMessage) {
   343                var
   344                  context     = this,
   345                  elapsedTime = (new Date().getTime() - time),
   346                  timeLeft    = (settings.loadingDuration - elapsedTime)
   347                ;
   348                timeLeft = (timeLeft > 0)
   349                  ? timeLeft
   350                  : 0
   351                ;
   352                // page triggers abort on navigation, dont show error
   353                setTimeout(function() {
   354                  if(status !== 'abort') {
   355                    module.request.rejectWith(context, [xhr, status, httpMessage]);
   356                  }
   357                  else {
   358                    module.reset();
   359                  }
   360                }, timeLeft);
   361              }
   362            },
   363            request: {
   364              complete: function(response) {
   365                module.remove.loading();
   366                settings.onComplete.call(context, response, $module);
   367              },
   368              done: function(response) {
   369                module.debug('API Response Received', response);
   370                if(settings.dataType == 'json') {
   371                  if( $.isFunction(settings.successTest) ) {
   372                    module.debug('Checking JSON returned success', settings.successTest, response);
   373                    if( settings.successTest(response) ) {
   374                      settings.onSuccess.call(context, response, $module);
   375                    }
   376                    else {
   377                      module.debug('JSON test specified by user and response failed', response);
   378                      settings.onFailure.call(context, response, $module);
   379                    }
   380                  }
   381                  else {
   382                    settings.onSuccess.call(context, response, $module);
   383                  }
   384                }
   385                else {
   386                  settings.onSuccess.call(context, response, $module);
   387                }
   388              },
   389              error: function(xhr, status, httpMessage) {
   390                var
   391                  errorMessage = (settings.error[status] !== undefined)
   392                    ? settings.error[status]
   393                    : httpMessage,
   394                  response
   395                ;
   396                // let em know unless request aborted
   397                if(xhr !== undefined) {
   398                  // readyState 4 = done, anything less is not really sent
   399                  if(xhr.readyState !== undefined && xhr.readyState == 4) {
   400  
   401                    // if http status code returned and json returned error, look for it
   402                    if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
   403                      module.error(error.statusMessage + httpMessage, ajaxSettings.url);
   404                    }
   405                    else {
   406                      if(status == 'error' && settings.dataType == 'json') {
   407                        try {
   408                          response = $.parseJSON(xhr.responseText);
   409                          if(response && response.error !== undefined) {
   410                            errorMessage = response.error;
   411                          }
   412                        }
   413                        catch(e) {
   414                          module.error(error.JSONParse);
   415                        }
   416                      }
   417                    }
   418                    module.remove.loading();
   419                    module.set.error();
   420                    // show error state only for duration specified in settings
   421                    if(settings.errorDuration) {
   422                      setTimeout(module.remove.error, settings.errorDuration);
   423                    }
   424                    module.debug('API Request error:', errorMessage);
   425                    settings.onError.call(context, errorMessage, $module);
   426                  }
   427                  else {
   428                    settings.onAbort.call(context, errorMessage, $module);
   429                    module.debug('Request Aborted (Most likely caused by page change or CORS Policy)', status, httpMessage);
   430                  }
   431                }
   432              }
   433            }
   434          },
   435  
   436          create: {
   437            request: function() {
   438              return $.Deferred()
   439                .always(module.event.request.complete)
   440                .done(module.event.request.done)
   441                .fail(module.event.request.error)
   442              ;
   443            },
   444            xhr: function() {
   445              return $.ajax(ajaxSettings)
   446                .always(module.event.xhr.always)
   447                .done(module.event.xhr.done)
   448                .fail(module.event.xhr.fail)
   449              ;
   450            }
   451          },
   452  
   453          set: {
   454            error: function() {
   455              module.verbose('Adding error state to element', $context);
   456              $context.addClass(className.error);
   457            },
   458            loading: function() {
   459              module.verbose('Adding loading state to element', $context);
   460              $context.addClass(className.loading);
   461            }
   462          },
   463  
   464          remove: {
   465            error: function() {
   466              module.verbose('Removing error state from element', $context);
   467              $context.removeClass(className.error);
   468            },
   469            loading: function() {
   470              module.verbose('Removing loading state from element', $context);
   471              $context.removeClass(className.loading);
   472            }
   473          },
   474  
   475          get: {
   476            request: function() {
   477              return module.request || false;
   478            },
   479            xhr: function() {
   480              return module.xhr || false;
   481            },
   482            settings: function() {
   483              var
   484                runSettings
   485              ;
   486              runSettings = settings.beforeSend.call($module, settings);
   487              if(runSettings) {
   488                if(runSettings.success !== undefined) {
   489                  module.debug('Legacy success callback detected', runSettings);
   490                  module.error(error.legacyParameters, runSettings.success);
   491                  runSettings.onSuccess = runSettings.success;
   492                }
   493                if(runSettings.failure !== undefined) {
   494                  module.debug('Legacy failure callback detected', runSettings);
   495                  module.error(error.legacyParameters, runSettings.failure);
   496                  runSettings.onFailure = runSettings.failure;
   497                }
   498                if(runSettings.complete !== undefined) {
   499                  module.debug('Legacy complete callback detected', runSettings);
   500                  module.error(error.legacyParameters, runSettings.complete);
   501                  runSettings.onComplete = runSettings.complete;
   502                }
   503              }
   504              if(runSettings === undefined) {
   505                module.error(error.noReturnedValue);
   506              }
   507              return (runSettings !== undefined)
   508                ? runSettings
   509                : settings
   510              ;
   511            },
   512            defaultData: function() {
   513              var
   514                data = {}
   515              ;
   516              if( !$.isWindow(element) ) {
   517                if( module.is.input() ) {
   518                  data.value = $module.val();
   519                }
   520                else if( !module.is.form() ) {
   521  
   522                }
   523                else {
   524                  data.text = $module.text();
   525                }
   526              }
   527              return data;
   528            },
   529            event: function() {
   530              if( $.isWindow(element) || settings.on == 'now' ) {
   531                module.debug('API called without element, no events attached');
   532                return false;
   533              }
   534              else if(settings.on == 'auto') {
   535                if( $module.is('input') ) {
   536                  return (element.oninput !== undefined)
   537                    ? 'input'
   538                    : (element.onpropertychange !== undefined)
   539                      ? 'propertychange'
   540                      : 'keyup'
   541                  ;
   542                }
   543                else if( $module.is('form') ) {
   544                  return 'submit';
   545                }
   546                else {
   547                  return 'click';
   548                }
   549              }
   550              else {
   551                return settings.on;
   552              }
   553            },
   554            formData: function() {
   555              var
   556                formData
   557              ;
   558              if($module.serializeObject !== undefined) {
   559                formData = $form.serializeObject();
   560              }
   561              else {
   562                module.error(error.missingSerialize);
   563                formData = $form.serialize();
   564              }
   565              module.debug('Retrieved form data', formData);
   566              return formData;
   567            },
   568            templateURL: function(action) {
   569              var
   570                url
   571              ;
   572              action = action || $module.data(metadata.action) || settings.action || false;
   573              if(action) {
   574                module.debug('Looking up url for action', action, settings.api);
   575                if(settings.api[action] !== undefined) {
   576                  url = settings.api[action];
   577                  module.debug('Found template url', url);
   578                }
   579                else if( !module.is.form() ) {
   580                  module.error(error.missingAction, settings.action, settings.api);
   581                }
   582              }
   583              return url;
   584            }
   585          },
   586  
   587          abort: function() {
   588            var
   589              xhr = module.get.xhr()
   590            ;
   591            if( xhr && xhr.state() !== 'resolved') {
   592              module.debug('Cancelling API request');
   593              xhr.abort();
   594              module.request.rejectWith(settings.apiSettings);
   595            }
   596          },
   597  
   598          // reset state
   599          reset: function() {
   600            module.remove.error();
   601            module.remove.loading();
   602          },
   603  
   604          setting: function(name, value) {
   605            module.debug('Changing setting', name, value);
   606            if( $.isPlainObject(name) ) {
   607              $.extend(true, settings, name);
   608            }
   609            else if(value !== undefined) {
   610              settings[name] = value;
   611            }
   612            else {
   613              return settings[name];
   614            }
   615          },
   616          internal: function(name, value) {
   617            if( $.isPlainObject(name) ) {
   618              $.extend(true, module, name);
   619            }
   620            else if(value !== undefined) {
   621              module[name] = value;
   622            }
   623            else {
   624              return module[name];
   625            }
   626          },
   627          debug: function() {
   628            if(settings.debug) {
   629              if(settings.performance) {
   630                module.performance.log(arguments);
   631              }
   632              else {
   633                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
   634                module.debug.apply(console, arguments);
   635              }
   636            }
   637          },
   638          verbose: function() {
   639            if(settings.verbose && settings.debug) {
   640              if(settings.performance) {
   641                module.performance.log(arguments);
   642              }
   643              else {
   644                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
   645                module.verbose.apply(console, arguments);
   646              }
   647            }
   648          },
   649          error: function() {
   650            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
   651            module.error.apply(console, arguments);
   652          },
   653          performance: {
   654            log: function(message) {
   655              var
   656                currentTime,
   657                executionTime,
   658                previousTime
   659              ;
   660              if(settings.performance) {
   661                currentTime   = new Date().getTime();
   662                previousTime  = time || currentTime;
   663                executionTime = currentTime - previousTime;
   664                time          = currentTime;
   665                performance.push({
   666                  'Name'           : message[0],
   667                  'Arguments'      : [].slice.call(message, 1) || '',
   668                  //'Element'        : element,
   669                  'Execution Time' : executionTime
   670                });
   671              }
   672              clearTimeout(module.performance.timer);
   673              module.performance.timer = setTimeout(module.performance.display, 100);
   674            },
   675            display: function() {
   676              var
   677                title = settings.name + ':',
   678                totalTime = 0
   679              ;
   680              time = false;
   681              clearTimeout(module.performance.timer);
   682              $.each(performance, function(index, data) {
   683                totalTime += data['Execution Time'];
   684              });
   685              title += ' ' + totalTime + 'ms';
   686              if(moduleSelector) {
   687                title += ' \'' + moduleSelector + '\'';
   688              }
   689              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
   690                console.groupCollapsed(title);
   691                if(console.table) {
   692                  console.table(performance);
   693                }
   694                else {
   695                  $.each(performance, function(index, data) {
   696                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
   697                  });
   698                }
   699                console.groupEnd();
   700              }
   701              performance = [];
   702            }
   703          },
   704          invoke: function(query, passedArguments, context) {
   705            var
   706              object = instance,
   707              maxDepth,
   708              found,
   709              response
   710            ;
   711            passedArguments = passedArguments || queryArguments;
   712            context         = element         || context;
   713            if(typeof query == 'string' && object !== undefined) {
   714              query    = query.split(/[\. ]/);
   715              maxDepth = query.length - 1;
   716              $.each(query, function(depth, value) {
   717                var camelCaseValue = (depth != maxDepth)
   718                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
   719                  : query
   720                ;
   721                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
   722                  object = object[camelCaseValue];
   723                }
   724                else if( object[camelCaseValue] !== undefined ) {
   725                  found = object[camelCaseValue];
   726                  return false;
   727                }
   728                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
   729                  object = object[value];
   730                }
   731                else if( object[value] !== undefined ) {
   732                  found = object[value];
   733                  return false;
   734                }
   735                else {
   736                  module.error(error.method, query);
   737                  return false;
   738                }
   739              });
   740            }
   741            if ( $.isFunction( found ) ) {
   742              response = found.apply(context, passedArguments);
   743            }
   744            else if(found !== undefined) {
   745              response = found;
   746            }
   747            if($.isArray(returnedValue)) {
   748              returnedValue.push(response);
   749            }
   750            else if(returnedValue !== undefined) {
   751              returnedValue = [returnedValue, response];
   752            }
   753            else if(response !== undefined) {
   754              returnedValue = response;
   755            }
   756            return found;
   757          }
   758        };
   759  
   760        if(methodInvoked) {
   761          if(instance === undefined) {
   762            module.initialize();
   763          }
   764          module.invoke(query);
   765        }
   766        else {
   767          if(instance !== undefined) {
   768            instance.invoke('destroy');
   769          }
   770          module.initialize();
   771        }
   772      })
   773    ;
   774  
   775    return (returnedValue !== undefined)
   776      ? returnedValue
   777      : this
   778    ;
   779  };
   780  
   781  $.api.settings = {
   782  
   783    name            : 'API',
   784    namespace       : 'api',
   785  
   786    debug           : true,
   787    verbose         : false,
   788    performance     : true,
   789  
   790    // event binding
   791    on              : 'auto',
   792    filter          : '.disabled',
   793    stateContext    : false,
   794  
   795    // state
   796    loadingDuration : 0,
   797    errorDuration   : 2000,
   798  
   799    // templating
   800    action          : false,
   801    url             : false,
   802    base            : '',
   803  
   804    // data
   805    urlData         : {},
   806  
   807    // ui
   808    defaultData     : true,
   809    serializeForm   : false,
   810    throttle        : 0,
   811  
   812    // jQ ajax
   813    method          : 'get',
   814    data            : {},
   815    dataType        : 'json',
   816  
   817    // callbacks
   818    beforeSend  : function(settings) { return settings; },
   819    beforeXHR   : function(xhr) {},
   820  
   821    onRequest   : function(promise, xhr) {},
   822    onSuccess   : function(response, $module) {},
   823    onComplete  : function(response, $module) {},
   824    onFailure   : function(errorMessage, $module) {},
   825    onError     : function(errorMessage, $module) {},
   826    onAbort     : function(errorMessage, $module) {},
   827  
   828    successTest : false,
   829  
   830    // errors
   831    error : {
   832      beforeSend        : 'The before send function has aborted the request',
   833      error             : 'There was an error with your request',
   834      exitConditions    : 'API Request Aborted. Exit conditions met',
   835      JSONParse         : 'JSON could not be parsed during error handling',
   836      legacyParameters  : 'You are using legacy API success callback names',
   837      method            : 'The method you called is not defined',
   838      missingAction     : 'API action used but no url was defined',
   839      missingSerialize  : 'Required dependency jquery-serialize-object missing, using basic serialize',
   840      missingURL        : 'No URL specified for api event',
   841      noReturnedValue   : 'The beforeSend callback must return a settings object, beforeSend ignored.',
   842      parseError        : 'There was an error parsing your request',
   843      requiredParameter : 'Missing a required URL parameter: ',
   844      statusMessage     : 'Server gave an error: ',
   845      timeout           : 'Your request timed out'
   846    },
   847  
   848    regExp  : {
   849      required: /\{\$*[A-z0-9]+\}/g,
   850      optional: /\{\/\$*[A-z0-9]+\}/g,
   851    },
   852  
   853    className: {
   854      loading : 'loading',
   855      error   : 'error'
   856    },
   857  
   858    selector: {
   859      form: 'form'
   860    },
   861  
   862    metadata: {
   863      action  : 'action'
   864    }
   865  };
   866  
   867  
   868  $.api.settings.api = {};
   869  
   870  
   871  })( jQuery, window , document );