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.

975 lines
32 KiB

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