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.

870 lines
28 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
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
9 years ago
10 years ago
9 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
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*!
  2. * # Semantic UI 1.11.3 - 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 ) {
  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. input: function() {
  187. return $module.is('input');
  188. },
  189. loading: function() {
  190. return (module.request && module.request.state() == 'pending');
  191. }
  192. },
  193. was: {
  194. cancelled: function() {
  195. return (module.cancelled || false);
  196. },
  197. succesful: function() {
  198. return (module.request && module.request.state() == 'resolved');
  199. },
  200. failure: function() {
  201. return (module.request && module.request.state() == 'rejected');
  202. },
  203. complete: function() {
  204. return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
  205. }
  206. },
  207. add: {
  208. urlData: function(url, urlData) {
  209. var
  210. requiredVariables,
  211. optionalVariables
  212. ;
  213. if(url) {
  214. requiredVariables = url.match(settings.regExp.required);
  215. optionalVariables = url.match(settings.regExp.optional);
  216. urlData = urlData || settings.urlData;
  217. if(requiredVariables) {
  218. module.debug('Looking for required URL variables', requiredVariables);
  219. $.each(requiredVariables, function(index, templatedString) {
  220. var
  221. // allow legacy {$var} style
  222. variable = (templatedString.indexOf('$') !== -1)
  223. ? templatedString.substr(2, templatedString.length - 3)
  224. : templatedString.substr(1, templatedString.length - 2),
  225. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  226. ? urlData[variable]
  227. : ($module.data(variable) !== undefined)
  228. ? $module.data(variable)
  229. : ($context.data(variable) !== undefined)
  230. ? $context.data(variable)
  231. : urlData[variable]
  232. ;
  233. // remove value
  234. if(value === undefined) {
  235. module.error(error.requiredParameter, variable, url);
  236. url = false;
  237. return false;
  238. }
  239. else {
  240. module.verbose('Found required variable', variable, value);
  241. url = url.replace(templatedString, value);
  242. }
  243. });
  244. }
  245. if(optionalVariables) {
  246. module.debug('Looking for optional URL variables', requiredVariables);
  247. $.each(optionalVariables, function(index, templatedString) {
  248. var
  249. // allow legacy {/$var} style
  250. variable = (templatedString.indexOf('$') !== -1)
  251. ? templatedString.substr(3, templatedString.length - 4)
  252. : templatedString.substr(2, templatedString.length - 3),
  253. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  254. ? urlData[variable]
  255. : ($module.data(variable) !== undefined)
  256. ? $module.data(variable)
  257. : ($context.data(variable) !== undefined)
  258. ? $context.data(variable)
  259. : urlData[variable]
  260. ;
  261. // optional replacement
  262. if(value !== undefined) {
  263. module.verbose('Optional variable Found', variable, value);
  264. url = url.replace(templatedString, value);
  265. }
  266. else {
  267. module.verbose('Optional variable not found', variable);
  268. // remove preceding slash if set
  269. if(url.indexOf('/' + templatedString) !== -1) {
  270. url = url.replace('/' + templatedString, '');
  271. }
  272. else {
  273. url = url.replace(templatedString, '');
  274. }
  275. }
  276. });
  277. }
  278. }
  279. return url;
  280. }
  281. },
  282. event: {
  283. trigger: function(event) {
  284. module.query();
  285. if(event.type == 'submit' || event.type == 'click') {
  286. event.preventDefault();
  287. }
  288. },
  289. xhr: {
  290. always: function() {
  291. // calculate if loading time was below minimum threshold
  292. },
  293. done: function(response) {
  294. var
  295. context = this,
  296. elapsedTime = (new Date().getTime() - time),
  297. timeLeft = (settings.loadingDuration - elapsedTime)
  298. ;
  299. timeLeft = (timeLeft > 0)
  300. ? timeLeft
  301. : 0
  302. ;
  303. setTimeout(function() {
  304. module.request.resolveWith(context, [response]);
  305. }, timeLeft);
  306. },
  307. fail: function(xhr, status, httpMessage) {
  308. var
  309. context = this,
  310. elapsedTime = (new Date().getTime() - time),
  311. timeLeft = (settings.loadingDuration - elapsedTime)
  312. ;
  313. timeLeft = (timeLeft > 0)
  314. ? timeLeft
  315. : 0
  316. ;
  317. // page triggers abort on navigation, dont show error
  318. setTimeout(function() {
  319. if(status !== 'abort') {
  320. module.request.rejectWith(context, [xhr, status, httpMessage]);
  321. }
  322. else {
  323. module.reset();
  324. }
  325. }, timeLeft);
  326. }
  327. },
  328. request: {
  329. complete: function(response) {
  330. module.remove.loading();
  331. settings.onComplete.call(context, response, $module);
  332. },
  333. done: function(response) {
  334. module.debug('API Response Received', response);
  335. if(settings.dataType == 'json') {
  336. if( $.isFunction(settings.successTest) ) {
  337. module.debug('Checking JSON returned success', settings.successTest, response);
  338. if( settings.successTest(response) ) {
  339. settings.onSuccess.call(context, response, $module);
  340. }
  341. else {
  342. module.debug('JSON test specified by user and response failed', response);
  343. settings.onFailure.call(context, response, $module);
  344. }
  345. }
  346. else {
  347. settings.onSuccess.call(context, response, $module);
  348. }
  349. }
  350. else {
  351. settings.onSuccess.call(context, response, $module);
  352. }
  353. },
  354. error: function(xhr, status, httpMessage) {
  355. var
  356. errorMessage = (settings.error[status] !== undefined)
  357. ? settings.error[status]
  358. : httpMessage,
  359. response
  360. ;
  361. // let em know unless request aborted
  362. if(xhr !== undefined) {
  363. // readyState 4 = done, anything less is not really sent
  364. if(xhr.readyState !== undefined && xhr.readyState == 4) {
  365. // if http status code returned and json returned error, look for it
  366. if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
  367. module.error(error.statusMessage + httpMessage, ajaxSettings.url);
  368. }
  369. else {
  370. if(status == 'error' && settings.dataType == 'json') {
  371. try {
  372. response = $.parseJSON(xhr.responseText);
  373. if(response && response.error !== undefined) {
  374. errorMessage = response.error;
  375. }
  376. }
  377. catch(e) {
  378. module.error(error.JSONParse);
  379. }
  380. }
  381. }
  382. module.remove.loading();
  383. module.set.error();
  384. // show error state only for duration specified in settings
  385. if(settings.errorDuration) {
  386. setTimeout(module.remove.error, settings.errorDuration);
  387. }
  388. module.debug('API Request error:', errorMessage);
  389. settings.onError.call(context, errorMessage, $module);
  390. }
  391. else {
  392. settings.onAbort.call(context, errorMessage, $module);
  393. module.debug('Request Aborted (Most likely caused by page change or CORS Policy)', status, httpMessage);
  394. }
  395. }
  396. }
  397. }
  398. },
  399. create: {
  400. request: function() {
  401. return $.Deferred()
  402. .always(module.event.request.complete)
  403. .done(module.event.request.done)
  404. .fail(module.event.request.error)
  405. ;
  406. },
  407. xhr: function() {
  408. return $.ajax(ajaxSettings)
  409. .always(module.event.xhr.always)
  410. .done(module.event.xhr.done)
  411. .fail(module.event.xhr.fail)
  412. ;
  413. }
  414. },
  415. set: {
  416. error: function() {
  417. module.verbose('Adding error state to element', $context);
  418. $context.addClass(className.error);
  419. },
  420. loading: function() {
  421. module.verbose('Adding loading state to element', $context);
  422. $context.addClass(className.loading);
  423. }
  424. },
  425. remove: {
  426. error: function() {
  427. module.verbose('Removing error state from element', $context);
  428. $context.removeClass(className.error);
  429. },
  430. loading: function() {
  431. module.verbose('Removing loading state from element', $context);
  432. $context.removeClass(className.loading);
  433. }
  434. },
  435. get: {
  436. request: function() {
  437. return module.request || false;
  438. },
  439. xhr: function() {
  440. return module.xhr || false;
  441. },
  442. settings: function() {
  443. var
  444. runSettings
  445. ;
  446. runSettings = settings.beforeSend.call($module, settings);
  447. if(runSettings) {
  448. if(runSettings.success !== undefined) {
  449. module.debug('Legacy success callback detected', runSettings);
  450. module.error(error.legacyParameters, runSettings.success);
  451. runSettings.onSuccess = runSettings.success;
  452. }
  453. if(runSettings.failure !== undefined) {
  454. module.debug('Legacy failure callback detected', runSettings);
  455. module.error(error.legacyParameters, runSettings.failure);
  456. runSettings.onFailure = runSettings.failure;
  457. }
  458. if(runSettings.complete !== undefined) {
  459. module.debug('Legacy complete callback detected', runSettings);
  460. module.error(error.legacyParameters, runSettings.complete);
  461. runSettings.onComplete = runSettings.complete;
  462. }
  463. }
  464. if(runSettings === undefined) {
  465. module.error(error.noReturnedValue);
  466. }
  467. return (runSettings !== undefined)
  468. ? runSettings
  469. : settings
  470. ;
  471. },
  472. defaultData: function() {
  473. var
  474. data = {}
  475. ;
  476. if( !$.isWindow(element) ) {
  477. if( module.is.input() ) {
  478. data.value = $module.val();
  479. }
  480. else if( !module.is.form() ) {
  481. }
  482. else {
  483. data.text = $module.text();
  484. }
  485. }
  486. return data;
  487. },
  488. event: function() {
  489. if( $.isWindow(element) || settings.on == 'now' ) {
  490. module.debug('API called without element, no events attached');
  491. return false;
  492. }
  493. else if(settings.on == 'auto') {
  494. if( $module.is('input') ) {
  495. return (element.oninput !== undefined)
  496. ? 'input'
  497. : (element.onpropertychange !== undefined)
  498. ? 'propertychange'
  499. : 'keyup'
  500. ;
  501. }
  502. else if( $module.is('form') ) {
  503. return 'submit';
  504. }
  505. else {
  506. return 'click';
  507. }
  508. }
  509. else {
  510. return settings.on;
  511. }
  512. },
  513. formData: function() {
  514. var
  515. formData
  516. ;
  517. if($module.serializeObject !== undefined) {
  518. formData = $form.serializeObject();
  519. }
  520. else {
  521. module.error(error.missingSerialize);
  522. formData = $form.serialize();
  523. }
  524. module.debug('Retrieved form data', formData);
  525. return formData;
  526. },
  527. templateURL: function(action) {
  528. var
  529. url
  530. ;
  531. action = action || $module.data(metadata.action) || settings.action || false;
  532. if(action) {
  533. module.debug('Looking up url for action', action, settings.api);
  534. if(settings.api[action] !== undefined) {
  535. url = settings.api[action];
  536. module.debug('Found template url', url);
  537. }
  538. else if( !module.is.form() ) {
  539. module.error(error.missingAction, settings.action, settings.api);
  540. }
  541. }
  542. return url;
  543. }
  544. },
  545. abort: function() {
  546. var
  547. xhr = module.get.xhr()
  548. ;
  549. if( xhr && xhr.state() !== 'resolved') {
  550. module.debug('Cancelling API request');
  551. xhr.abort();
  552. module.request.rejectWith(settings.apiSettings);
  553. }
  554. },
  555. // reset state
  556. reset: function() {
  557. module.remove.error();
  558. module.remove.loading();
  559. },
  560. setting: function(name, value) {
  561. module.debug('Changing setting', name, value);
  562. if( $.isPlainObject(name) ) {
  563. $.extend(true, settings, name);
  564. }
  565. else if(value !== undefined) {
  566. settings[name] = value;
  567. }
  568. else {
  569. return settings[name];
  570. }
  571. },
  572. internal: function(name, value) {
  573. if( $.isPlainObject(name) ) {
  574. $.extend(true, module, name);
  575. }
  576. else if(value !== undefined) {
  577. module[name] = value;
  578. }
  579. else {
  580. return module[name];
  581. }
  582. },
  583. debug: function() {
  584. if(settings.debug) {
  585. if(settings.performance) {
  586. module.performance.log(arguments);
  587. }
  588. else {
  589. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  590. module.debug.apply(console, arguments);
  591. }
  592. }
  593. },
  594. verbose: function() {
  595. if(settings.verbose && settings.debug) {
  596. if(settings.performance) {
  597. module.performance.log(arguments);
  598. }
  599. else {
  600. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  601. module.verbose.apply(console, arguments);
  602. }
  603. }
  604. },
  605. error: function() {
  606. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  607. module.error.apply(console, arguments);
  608. },
  609. performance: {
  610. log: function(message) {
  611. var
  612. currentTime,
  613. executionTime,
  614. previousTime
  615. ;
  616. if(settings.performance) {
  617. currentTime = new Date().getTime();
  618. previousTime = time || currentTime;
  619. executionTime = currentTime - previousTime;
  620. time = currentTime;
  621. performance.push({
  622. 'Name' : message[0],
  623. 'Arguments' : [].slice.call(message, 1) || '',
  624. //'Element' : element,
  625. 'Execution Time' : executionTime
  626. });
  627. }
  628. clearTimeout(module.performance.timer);
  629. module.performance.timer = setTimeout(module.performance.display, 100);
  630. },
  631. display: function() {
  632. var
  633. title = settings.name + ':',
  634. totalTime = 0
  635. ;
  636. time = false;
  637. clearTimeout(module.performance.timer);
  638. $.each(performance, function(index, data) {
  639. totalTime += data['Execution Time'];
  640. });
  641. title += ' ' + totalTime + 'ms';
  642. if(moduleSelector) {
  643. title += ' \'' + moduleSelector + '\'';
  644. }
  645. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  646. console.groupCollapsed(title);
  647. if(console.table) {
  648. console.table(performance);
  649. }
  650. else {
  651. $.each(performance, function(index, data) {
  652. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  653. });
  654. }
  655. console.groupEnd();
  656. }
  657. performance = [];
  658. }
  659. },
  660. invoke: function(query, passedArguments, context) {
  661. var
  662. object = instance,
  663. maxDepth,
  664. found,
  665. response
  666. ;
  667. passedArguments = passedArguments || queryArguments;
  668. context = element || context;
  669. if(typeof query == 'string' && object !== undefined) {
  670. query = query.split(/[\. ]/);
  671. maxDepth = query.length - 1;
  672. $.each(query, function(depth, value) {
  673. var camelCaseValue = (depth != maxDepth)
  674. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  675. : query
  676. ;
  677. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  678. object = object[camelCaseValue];
  679. }
  680. else if( object[camelCaseValue] !== undefined ) {
  681. found = object[camelCaseValue];
  682. return false;
  683. }
  684. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  685. object = object[value];
  686. }
  687. else if( object[value] !== undefined ) {
  688. found = object[value];
  689. return false;
  690. }
  691. else {
  692. module.error(error.method, query);
  693. return false;
  694. }
  695. });
  696. }
  697. if ( $.isFunction( found ) ) {
  698. response = found.apply(context, passedArguments);
  699. }
  700. else if(found !== undefined) {
  701. response = found;
  702. }
  703. if($.isArray(returnedValue)) {
  704. returnedValue.push(response);
  705. }
  706. else if(returnedValue !== undefined) {
  707. returnedValue = [returnedValue, response];
  708. }
  709. else if(response !== undefined) {
  710. returnedValue = response;
  711. }
  712. return found;
  713. }
  714. };
  715. if(methodInvoked) {
  716. if(instance === undefined) {
  717. module.initialize();
  718. }
  719. module.invoke(query);
  720. }
  721. else {
  722. if(instance !== undefined) {
  723. instance.invoke('destroy');
  724. }
  725. module.initialize();
  726. }
  727. })
  728. ;
  729. return (returnedValue !== undefined)
  730. ? returnedValue
  731. : this
  732. ;
  733. };
  734. $.api.settings = {
  735. name : 'API',
  736. namespace : 'api',
  737. debug : true,
  738. verbose : false,
  739. performance : true,
  740. // event binding
  741. on : 'auto',
  742. filter : '.disabled',
  743. stateContext : false,
  744. // state
  745. loadingDuration : 0,
  746. errorDuration : 2000,
  747. // templating
  748. action : false,
  749. url : false,
  750. base : '',
  751. // data
  752. urlData : {},
  753. // ui
  754. defaultData : true,
  755. serializeForm : false,
  756. throttle : 0,
  757. // jQ ajax
  758. method : 'get',
  759. data : {},
  760. dataType : 'json',
  761. // callbacks
  762. beforeSend : function(settings) { return settings; },
  763. beforeXHR : function(xhr) {},
  764. onRequest : function(promise, xhr) {},
  765. onSuccess : function(response, $module) {},
  766. onComplete : function(response, $module) {},
  767. onFailure : function(errorMessage, $module) {},
  768. onError : function(errorMessage, $module) {},
  769. onAbort : function(errorMessage, $module) {},
  770. successTest : false,
  771. // errors
  772. error : {
  773. beforeSend : 'The before send function has aborted the request',
  774. error : 'There was an error with your request',
  775. exitConditions : 'API Request Aborted. Exit conditions met',
  776. JSONParse : 'JSON could not be parsed during error handling',
  777. legacyParameters : 'You are using legacy API success callback names',
  778. method : 'The method you called is not defined',
  779. missingAction : 'API action used but no url was defined',
  780. missingSerialize : 'Required dependency jquery-serialize-object missing, using basic serialize',
  781. missingURL : 'No URL specified for api event',
  782. noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
  783. parseError : 'There was an error parsing your request',
  784. requiredParameter : 'Missing a required URL parameter: ',
  785. statusMessage : 'Server gave an error: ',
  786. timeout : 'Your request timed out'
  787. },
  788. regExp : {
  789. required: /\{\$*[A-z0-9]+\}/g,
  790. optional: /\{\/\$*[A-z0-9]+\}/g,
  791. },
  792. className: {
  793. loading : 'loading',
  794. error : 'error'
  795. },
  796. selector: {
  797. form: 'form'
  798. },
  799. metadata: {
  800. action : 'action'
  801. }
  802. };
  803. $.api.settings.api = {};
  804. })( jQuery, window , document );