You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

917 lines
30 KiB

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