vendor: 39,779 bytes, lines 1-1167
1/*! 2 * # Semantic UI - API 3 * http://github.com/semantic-org/semantic-ui/ 4 * 5 * 6 * Released under the MIT license 7 * http://opensource.org/licenses/MIT 8 * 9 */ 10 11;(function ($, window, document, undefined) { 12 13'use strict'; 14 15var 16 window = (typeof window != 'undefined' && window.Math == Math) 17 ? window 18 : (typeof self != 'undefined' && self.Math == Math) 19 ? self 20 : Function('return this')() 21; 22 23$.api = $.fn.api = function(parameters) { 24 25 var 26 // use window context if none specified 27 $allModules = $.isFunction(this) 28 ? $(window) 29 : $(this), 30 moduleSelector = $allModules.selector || '', 31 time = new Date().getTime(), 32 performance = [], 33 34 query = arguments[0], 35 methodInvoked = (typeof query == 'string'), 36 queryArguments = [].slice.call(arguments, 1), 37 38 returnedValue 39 ; 40 41 $allModules 42 .each(function() { 43 var 44 settings = ( $.isPlainObject(parameters) ) 45 ? $.extend(true, {}, $.fn.api.settings, parameters) 46 : $.extend({}, $.fn.api.settings), 47 48 // internal aliases 49 namespace = settings.namespace, 50 metadata = settings.metadata, 51 selector = settings.selector, 52 error = settings.error, 53 className = settings.className, 54 55 // define namespaces for modules 56 eventNamespace = '.' + namespace, 57 moduleNamespace = 'module-' + namespace, 58 59 // element that creates request 60 $module = $(this), 61 $form = $module.closest(selector.form), 62 63 // context used for state 64 $context = (settings.stateContext) 65 ? $(settings.stateContext) 66 : $module, 67 68 // request details 69 ajaxSettings, 70 requestSettings, 71 url, 72 data, 73 requestStartTime, 74 75 // standard module 76 element = this, 77 context = $context[0], 78 instance = $module.data(moduleNamespace), 79 module 80 ; 81 82 module = { 83 84 initialize: function() { 85 if(!methodInvoked) { 86 module.bind.events(); 87 } 88 module.instantiate(); 89 }, 90 91 instantiate: function() { 92 module.verbose('Storing instance of module', module); 93 instance = module; 94 $module 95 .data(moduleNamespace, instance) 96 ; 97 }, 98 99 destroy: function() { 100 module.verbose('Destroying previous module for', element); 101 $module 102 .removeData(moduleNamespace) 103 .off(eventNamespace) 104 ; 105 }, 106 107 bind: { 108 events: function() { 109 var 110 triggerEvent = module.get.event() 111 ; 112 if( triggerEvent ) { 113 module.verbose('Attaching API events to element', triggerEvent); 114 $module 115 .on(triggerEvent + eventNamespace, module.event.trigger) 116 ; 117 } 118 else if(settings.on == 'now') { 119 module.debug('Querying API endpoint immediately'); 120 module.query(); 121 } 122 } 123 }, 124 125 decode: { 126 json: function(response) { 127 if(response !== undefined && typeof response == 'string') { 128 try { 129 response = JSON.parse(response); 130 } 131 catch(e) { 132 // isnt json string 133 } 134 } 135 return response; 136 } 137 }, 138 139 read: { 140 cachedResponse: function(url) { 141 var 142 response 143 ; 144 if(window.Storage === undefined) { 145 module.error(error.noStorage); 146 return; 147 } 148 response = sessionStorage.getItem(url); 149 module.debug('Using cached response', url, response); 150 response = module.decode.json(response); 151 return response; 152 } 153 }, 154 write: { 155 cachedResponse: function(url, response) { 156 if(response && response === '') { 157 module.debug('Response empty, not caching', response); 158 return; 159 } 160 if(window.Storage === undefined) { 161 module.error(error.noStorage); 162 return; 163 } 164 if( $.isPlainObject(response) ) { 165 response = JSON.stringify(response); 166 } 167 sessionStorage.setItem(url, response); 168 module.verbose('Storing cached response for url', url, response); 169 } 170 }, 171 172 query: function() { 173 174 if(module.is.disabled()) { 175 module.debug('Element is disabled API request aborted'); 176 return; 177 } 178 179 if(module.is.loading()) { 180 if(settings.interruptRequests) { 181 module.debug('Interrupting previous request'); 182 module.abort(); 183 } 184 else { 185 module.debug('Cancelling request, previous request is still pending'); 186 return; 187 } 188 } 189 190 // pass element metadata to url (value, text) 191 if(settings.defaultData) { 192 $.extend(true, settings.urlData, module.get.defaultData()); 193 } 194 195 // Add form content 196 if(settings.serializeForm) { 197 settings.data = module.add.formData(settings.data); 198 } 199 200 // call beforesend and get any settings changes 201 requestSettings = module.get.settings(); 202 203 // check if before send cancelled request 204 if(requestSettings === false) { 205 module.cancelled = true; 206 module.error(error.beforeSend); 207 return; 208 } 209 else { 210 module.cancelled = false; 211 } 212 213 // get url 214 url = module.get.templatedURL(); 215 216 if(!url && !module.is.mocked()) { 217 module.error(error.missingURL); 218 return; 219 } 220 221 // replace variables 222 url = module.add.urlData( url ); 223 // missing url parameters 224 if( !url && !module.is.mocked()) { 225 return; 226 } 227 228 requestSettings.url = settings.base + url; 229 230 // look for jQuery ajax parameters in settings 231 ajaxSettings = $.extend(true, {}, settings, { 232 type : settings.method || settings.type, 233 data : data, 234 url : settings.base + url, 235 beforeSend : settings.beforeXHR, 236 success : function() {}, 237 failure : function() {}, 238 complete : function() {} 239 }); 240 241 module.debug('Querying URL', ajaxSettings.url); 242 module.verbose('Using AJAX settings', ajaxSettings); 243 if(settings.cache === 'local' && module.read.cachedResponse(url)) { 244 module.debug('Response returned from local cache'); 245 module.request = module.create.request(); 246 module.request.resolveWith(context, [ module.read.cachedResponse(url) ]); 247 return; 248 } 249 250 if( !settings.throttle ) { 251 module.debug('Sending request', data, ajaxSettings.method); 252 module.send.request(); 253 } 254 else { 255 if(!settings.throttleFirstRequest && !module.timer) { 256 module.debug('Sending request', data, ajaxSettings.method); 257 module.send.request(); 258 module.timer = setTimeout(function(){}, settings.throttle); 259 } 260 else { 261 module.debug('Throttling request', settings.throttle); 262 clearTimeout(module.timer); 263 module.timer = setTimeout(function() { 264 if(module.timer) { 265 delete module.timer; 266 } 267 module.debug('Sending throttled request', data, ajaxSettings.method); 268 module.send.request(); 269 }, settings.throttle); 270 } 271 } 272 273 }, 274 275 should: { 276 removeError: function() { 277 return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) ); 278 } 279 }, 280 281 is: { 282 disabled: function() { 283 return ($module.filter(selector.disabled).length > 0); 284 }, 285 expectingJSON: function() { 286 return settings.dataType === 'json' || settings.dataType === 'jsonp'; 287 }, 288 form: function() { 289 return $module.is('form') || $context.is('form'); 290 }, 291 mocked: function() { 292 return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync); 293 }, 294 input: function() { 295 return $module.is('input'); 296 }, 297 loading: function() { 298 return (module.request) 299 ? (module.request.state() == 'pending') 300 : false 301 ; 302 }, 303 abortedRequest: function(xhr) { 304 if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) { 305 module.verbose('XHR request determined to be aborted'); 306 return true; 307 } 308 else { 309 module.verbose('XHR request was not aborted'); 310 return false; 311 } 312 }, 313 validResponse: function(response) { 314 if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) { 315 module.verbose('Response is not JSON, skipping validation', settings.successTest, response); 316 return true; 317 } 318 module.debug('Checking JSON returned success', settings.successTest, response); 319 if( settings.successTest(response) ) { 320 module.debug('Response passed success test', response); 321 return true; 322 } 323 else { 324 module.debug('Response failed success test', response); 325 return false; 326 } 327 } 328 }, 329 330 was: { 331 cancelled: function() { 332 return (module.cancelled || false); 333 }, 334 succesful: function() { 335 return (module.request && module.request.state() == 'resolved'); 336 }, 337 failure: function() { 338 return (module.request && module.request.state() == 'rejected'); 339 }, 340 complete: function() { 341 return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') ); 342 } 343 }, 344 345 add: { 346 urlData: function(url, urlData) { 347 var 348 requiredVariables, 349 optionalVariables 350 ; 351 if(url) { 352 requiredVariables = url.match(settings.regExp.required); 353 optionalVariables = url.match(settings.regExp.optional); 354 urlData = urlData || settings.urlData; 355 if(requiredVariables) { 356 module.debug('Looking for required URL variables', requiredVariables); 357 $.each(requiredVariables, function(index, templatedString) { 358 var 359 // allow legacy {$var} style 360 variable = (templatedString.indexOf('$') !== -1) 361 ? templatedString.substr(2, templatedString.length - 3) 362 : templatedString.substr(1, templatedString.length - 2), 363 value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) 364 ? urlData[variable] 365 : ($module.data(variable) !== undefined) 366 ? $module.data(variable) 367 : ($context.data(variable) !== undefined) 368 ? $context.data(variable) 369 : urlData[variable] 370 ; 371 // remove value 372 if(value === undefined) { 373 module.error(error.requiredParameter, variable, url); 374 url = false; 375 return false; 376 } 377 else { 378 module.verbose('Found required variable', variable, value); 379 value = (settings.encodeParameters) 380 ? module.get.urlEncodedValue(value) 381 : value 382 ; 383 url = url.replace(templatedString, value); 384 } 385 }); 386 } 387 if(optionalVariables) { 388 module.debug('Looking for optional URL variables', requiredVariables); 389 $.each(optionalVariables, function(index, templatedString) { 390 var 391 // allow legacy {/$var} style 392 variable = (templatedString.indexOf('$') !== -1) 393 ? templatedString.substr(3, templatedString.length - 4) 394 : templatedString.substr(2, templatedString.length - 3), 395 value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) 396 ? urlData[variable] 397 : ($module.data(variable) !== undefined) 398 ? $module.data(variable) 399 : ($context.data(variable) !== undefined) 400 ? $context.data(variable) 401 : urlData[variable] 402 ; 403 // optional replacement 404 if(value !== undefined) { 405 module.verbose('Optional variable Found', variable, value); 406 url = url.replace(templatedString, value); 407 } 408 else { 409 module.verbose('Optional variable not found', variable); 410 // remove preceding slash if set 411 if(url.indexOf('/' + templatedString) !== -1) { 412 url = url.replace('/' + templatedString, ''); 413 } 414 else { 415 url = url.replace(templatedString, ''); 416 } 417 } 418 }); 419 } 420 } 421 return url; 422 }, 423 formData: function(data) { 424 var 425 canSerialize = ($.fn.serializeObject !== undefined), 426 formData = (canSerialize) 427 ? $form.serializeObject() 428 : $form.serialize(), 429 hasOtherData 430 ; 431 data = data || settings.data; 432 hasOtherData = $.isPlainObject(data); 433 434 if(hasOtherData) { 435 if(canSerialize) { 436 module.debug('Extending existing data with form data', data, formData); 437 data = $.extend(true, {}, data, formData); 438 } 439 else { 440 module.error(error.missingSerialize); 441 module.debug('Cant extend data. Replacing data with form data', data, formData); 442 data = formData; 443 } 444 } 445 else { 446 module.debug('Adding form data', formData); 447 data = formData; 448 } 449 return data; 450 } 451 }, 452 453 send: { 454 request: function() { 455 module.set.loading(); 456 module.request = module.create.request(); 457 if( module.is.mocked() ) { 458 module.mockedXHR = module.create.mockedXHR(); 459 } 460 else { 461 module.xhr = module.create.xhr(); 462 } 463 settings.onRequest.call(context, module.request, module.xhr); 464 } 465 }, 466 467 event: { 468 trigger: function(event) { 469 module.query(); 470 if(event.type == 'submit' || event.type == 'click') { 471 event.preventDefault(); 472 } 473 }, 474 xhr: { 475 always: function() { 476 // nothing special 477 }, 478 done: function(response, textStatus, xhr) { 479 var 480 context = this, 481 elapsedTime = (new Date().getTime() - requestStartTime), 482 timeLeft = (settings.loadingDuration - elapsedTime), 483 translatedResponse = ( $.isFunction(settings.onResponse) ) 484 ? module.is.expectingJSON() 485 ? settings.onResponse.call(context, $.extend(true, {}, response)) 486 : settings.onResponse.call(context, response) 487 : false 488 ; 489 timeLeft = (timeLeft > 0) 490 ? timeLeft 491 : 0 492 ; 493 if(translatedResponse) { 494 module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response); 495 response = translatedResponse; 496 } 497 if(timeLeft > 0) { 498 module.debug('Response completed early delaying state change by', timeLeft); 499 } 500 setTimeout(function() { 501 if( module.is.validResponse(response) ) { 502 module.request.resolveWith(context, [response, xhr]); 503 } 504 else { 505 module.request.rejectWith(context, [xhr, 'invalid']); 506 } 507 }, timeLeft); 508 }, 509 fail: function(xhr, status, httpMessage) { 510 var 511 context = this, 512 elapsedTime = (new Date().getTime() - requestStartTime), 513 timeLeft = (settings.loadingDuration - elapsedTime) 514 ; 515 timeLeft = (timeLeft > 0) 516 ? timeLeft 517 : 0 518 ; 519 if(timeLeft > 0) { 520 module.debug('Response completed early delaying state change by', timeLeft); 521 } 522 setTimeout(function() { 523 if( module.is.abortedRequest(xhr) ) { 524 module.request.rejectWith(context, [xhr, 'aborted', httpMessage]); 525 } 526 else { 527 module.request.rejectWith(context, [xhr, 'error', status, httpMessage]); 528 } 529 }, timeLeft); 530 } 531 }, 532 request: { 533 done: function(response, xhr) { 534 module.debug('Successful API Response', response); 535 if(settings.cache === 'local' && url) { 536 module.write.cachedResponse(url, response); 537 module.debug('Saving server response locally', module.cache); 538 } 539 settings.onSuccess.call(context, response, $module, xhr); 540 }, 541 complete: function(firstParameter, secondParameter) { 542 var 543 xhr, 544 response 545 ; 546 // have to guess callback parameters based on request success 547 if( module.was.succesful() ) { 548 response = firstParameter; 549 xhr = secondParameter; 550 } 551 else { 552 xhr = firstParameter; 553 response = module.get.responseFromXHR(xhr); 554 } 555 module.remove.loading(); 556 settings.onComplete.call(context, response, $module, xhr); 557 }, 558 fail: function(xhr, status, httpMessage) { 559 var 560 // pull response from xhr if available 561 response = module.get.responseFromXHR(xhr), 562 errorMessage = module.get.errorFromRequest(response, status, httpMessage) 563 ; 564 if(status == 'aborted') { 565 module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); 566 settings.onAbort.call(context, status, $module, xhr); 567 return true; 568 } 569 else if(status == 'invalid') { 570 module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); 571 } 572 else if(status == 'error') { 573 if(xhr !== undefined) { 574 module.debug('XHR produced a server error', status, httpMessage); 575 // make sure we have an error to display to console 576 if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') { 577 module.error(error.statusMessage + httpMessage, ajaxSettings.url); 578 } 579 settings.onError.call(context, errorMessage, $module, xhr); 580 } 581 } 582 583 if(settings.errorDuration && status !== 'aborted') { 584 module.debug('Adding error state'); 585 module.set.error(); 586 if( module.should.removeError() ) { 587 setTimeout(module.remove.error, settings.errorDuration); 588 } 589 } 590 module.debug('API Request failed', errorMessage, xhr); 591 settings.onFailure.call(context, response, $module, xhr); 592 } 593 } 594 }, 595 596 create: { 597 598 request: function() { 599 // api request promise 600 return $.Deferred() 601 .always(module.event.request.complete) 602 .done(module.event.request.done) 603 .fail(module.event.request.fail) 604 ; 605 }, 606 607 mockedXHR: function () { 608 var 609 // xhr does not simulate these properties of xhr but must return them 610 textStatus = false, 611 status = false, 612 httpMessage = false, 613 responder = settings.mockResponse || settings.response, 614 asyncResponder = settings.mockResponseAsync || settings.responseAsync, 615 asyncCallback, 616 response, 617 mockedXHR 618 ; 619 620 mockedXHR = $.Deferred() 621 .always(module.event.xhr.complete) 622 .done(module.event.xhr.done) 623 .fail(module.event.xhr.fail) 624 ; 625 626 if(responder) { 627 if( $.isFunction(responder) ) { 628 module.debug('Using specified synchronous callback', responder); 629 response = responder.call(context, requestSettings); 630 } 631 else { 632 module.debug('Using settings specified response', responder); 633 response = responder; 634 } 635 // simulating response 636 mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); 637 } 638 else if( $.isFunction(asyncResponder) ) { 639 asyncCallback = function(response) { 640 module.debug('Async callback returned response', response); 641 642 if(response) { 643 mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); 644 } 645 else { 646 mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]); 647 } 648 }; 649 module.debug('Using specified async response callback', asyncResponder); 650 asyncResponder.call(context, requestSettings, asyncCallback); 651 } 652 return mockedXHR; 653 }, 654 655 xhr: function() { 656 var 657 xhr 658 ; 659 // ajax request promise 660 xhr = $.ajax(ajaxSettings) 661 .always(module.event.xhr.always) 662 .done(module.event.xhr.done) 663 .fail(module.event.xhr.fail) 664 ; 665 module.verbose('Created server request', xhr, ajaxSettings); 666 return xhr; 667 } 668 }, 669 670 set: { 671 error: function() { 672 module.verbose('Adding error state to element', $context); 673 $context.addClass(className.error); 674 }, 675 loading: function() { 676 module.verbose('Adding loading state to element', $context); 677 $context.addClass(className.loading); 678 requestStartTime = new Date().getTime(); 679 } 680 }, 681 682 remove: { 683 error: function() { 684 module.verbose('Removing error state from element', $context); 685 $context.removeClass(className.error); 686 }, 687 loading: function() { 688 module.verbose('Removing loading state from element', $context); 689 $context.removeClass(className.loading); 690 } 691 }, 692 693 get: { 694 responseFromXHR: function(xhr) { 695 return $.isPlainObject(xhr) 696 ? (module.is.expectingJSON()) 697 ? module.decode.json(xhr.responseText) 698 : xhr.responseText 699 : false 700 ; 701 }, 702 errorFromRequest: function(response, status, httpMessage) { 703 return ($.isPlainObject(response) && response.error !== undefined) 704 ? response.error // use json error message 705 : (settings.error[status] !== undefined) // use server error message 706 ? settings.error[status] 707 : httpMessage 708 ; 709 }, 710 request: function() { 711 return module.request || false; 712 }, 713 xhr: function() { 714 return module.xhr || false; 715 }, 716 settings: function() { 717 var 718 runSettings 719 ; 720 runSettings = settings.beforeSend.call(context, settings); 721 if(runSettings) { 722 if(runSettings.success !== undefined) { 723 module.debug('Legacy success callback detected', runSettings); 724 module.error(error.legacyParameters, runSettings.success); 725 runSettings.onSuccess = runSettings.success; 726 } 727 if(runSettings.failure !== undefined) { 728 module.debug('Legacy failure callback detected', runSettings); 729 module.error(error.legacyParameters, runSettings.failure); 730 runSettings.onFailure = runSettings.failure; 731 } 732 if(runSettings.complete !== undefined) { 733 module.debug('Legacy complete callback detected', runSettings); 734 module.error(error.legacyParameters, runSettings.complete); 735 runSettings.onComplete = runSettings.complete; 736 } 737 } 738 if(runSettings === undefined) { 739 module.error(error.noReturnedValue); 740 } 741 if(runSettings === false) { 742 return runSettings; 743 } 744 return (runSettings !== undefined) 745 ? $.extend(true, {}, runSettings) 746 : $.extend(true, {}, settings) 747 ; 748 }, 749 urlEncodedValue: function(value) { 750 var 751 decodedValue = window.decodeURIComponent(value), 752 encodedValue = window.encodeURIComponent(value), 753 alreadyEncoded = (decodedValue !== value) 754 ; 755 if(alreadyEncoded) { 756 module.debug('URL value is already encoded, avoiding double encoding', value); 757 return value; 758 } 759 module.verbose('Encoding value using encodeURIComponent', value, encodedValue); 760 return encodedValue; 761 }, 762 defaultData: function() { 763 var 764 data = {} 765 ; 766 if( !$.isWindow(element) ) { 767 if( module.is.input() ) { 768 data.value = $module.val(); 769 } 770 else if( module.is.form() ) { 771 772 } 773 else { 774 data.text = $module.text(); 775 } 776 } 777 return data; 778 }, 779 event: function() { 780 if( $.isWindow(element) || settings.on == 'now' ) { 781 module.debug('API called without element, no events attached'); 782 return false; 783 } 784 else if(settings.on == 'auto') { 785 if( $module.is('input') ) { 786 return (element.oninput !== undefined) 787 ? 'input' 788 : (element.onpropertychange !== undefined) 789 ? 'propertychange' 790 : 'keyup' 791 ; 792 } 793 else if( $module.is('form') ) { 794 return 'submit'; 795 } 796 else { 797 return 'click'; 798 } 799 } 800 else { 801 return settings.on; 802 } 803 }, 804 templatedURL: function(action) { 805 action = action || $module.data(metadata.action) || settings.action || false; 806 url = $module.data(metadata.url) || settings.url || false; 807 if(url) { 808 module.debug('Using specified url', url); 809 return url; 810 } 811 if(action) { 812 module.debug('Looking up url for action', action, settings.api); 813 if(settings.api[action] === undefined && !module.is.mocked()) { 814 module.error(error.missingAction, settings.action, settings.api); 815 return; 816 } 817 url = settings.api[action]; 818 } 819 else if( module.is.form() ) { 820 url = $module.attr('action') || $context.attr('action') || false; 821 module.debug('No url or action specified, defaulting to form action', url); 822 } 823 return url; 824 } 825 }, 826 827 abort: function() { 828 var 829 xhr = module.get.xhr() 830 ; 831 if( xhr && xhr.state() !== 'resolved') { 832 module.debug('Cancelling API request'); 833 xhr.abort(); 834 } 835 }, 836 837 // reset state 838 reset: function() { 839 module.remove.error(); 840 module.remove.loading(); 841 }, 842 843 setting: function(name, value) { 844 module.debug('Changing setting', name, value); 845 if( $.isPlainObject(name) ) { 846 $.extend(true, settings, name); 847 } 848 else if(value !== undefined) { 849 if($.isPlainObject(settings[name])) { 850 $.extend(true, settings[name], value); 851 } 852 else { 853 settings[name] = value; 854 } 855 } 856 else { 857 return settings[name]; 858 } 859 }, 860 internal: function(name, value) { 861 if( $.isPlainObject(name) ) { 862 $.extend(true, module, name); 863 } 864 else if(value !== undefined) { 865 module[name] = value; 866 } 867 else { 868 return module[name]; 869 } 870 }, 871 debug: function() { 872 if(!settings.silent && settings.debug) { 873 if(settings.performance) { 874 module.performance.log(arguments); 875 } 876 else { 877 module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); 878 module.debug.apply(console, arguments); 879 } 880 } 881 }, 882 verbose: function() { 883 if(!settings.silent && settings.verbose && settings.debug) { 884 if(settings.performance) { 885 module.performance.log(arguments); 886 } 887 else { 888 module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); 889 module.verbose.apply(console, arguments); 890 } 891 } 892 }, 893 error: function() { 894 if(!settings.silent) { 895 module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); 896 module.error.apply(console, arguments); 897 } 898 }, 899 performance: { 900 log: function(message) { 901 var 902 currentTime, 903 executionTime, 904 previousTime 905 ; 906 if(settings.performance) { 907 currentTime = new Date().getTime(); 908 previousTime = time || currentTime; 909 executionTime = currentTime - previousTime; 910 time = currentTime; 911 performance.push({ 912 'Name' : message[0], 913 'Arguments' : [].slice.call(message, 1) || '', 914 //'Element' : element, 915 'Execution Time' : executionTime 916 }); 917 } 918 clearTimeout(module.performance.timer); 919 module.performance.timer = setTimeout(module.performance.display, 500); 920 }, 921 display: function() { 922 var 923 title = settings.name + ':', 924 totalTime = 0 925 ; 926 time = false; 927 clearTimeout(module.performance.timer); 928 $.each(performance, function(index, data) { 929 totalTime += data['Execution Time']; 930 }); 931 title += ' ' + totalTime + 'ms'; 932 if(moduleSelector) { 933 title += ' \'' + moduleSelector + '\''; 934 } 935 if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { 936 console.groupCollapsed(title); 937 if(console.table) { 938 console.table(performance); 939 } 940 else { 941 $.each(performance, function(index, data) { 942 console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); 943 }); 944 } 945 console.groupEnd(); 946 } 947 performance = []; 948 } 949 }, 950 invoke: function(query, passedArguments, context) { 951 var 952 object = instance, 953 maxDepth, 954 found, 955 response 956 ; 957 passedArguments = passedArguments || queryArguments; 958 context = element || context; 959 if(typeof query == 'string' && object !== undefined) { 960 query = query.split(/[\. ]/); 961 maxDepth = query.length - 1; 962 $.each(query, function(depth, value) { 963 var camelCaseValue = (depth != maxDepth) 964 ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) 965 : query 966 ; 967 if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { 968 object = object[camelCaseValue]; 969 } 970 else if( object[camelCaseValue] !== undefined ) { 971 found = object[camelCaseValue]; 972 return false; 973 } 974 else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { 975 object = object[value]; 976 } 977 else if( object[value] !== undefined ) { 978 found = object[value]; 979 return false; 980 } 981 else { 982 module.error(error.method, query); 983 return false; 984 } 985 }); 986 } 987 if ( $.isFunction( found ) ) { 988 response = found.apply(context, passedArguments); 989 } 990 else if(found !== undefined) { 991 response = found; 992 } 993 if($.isArray(returnedValue)) { 994 returnedValue.push(response); 995 } 996 else if(returnedValue !== undefined) { 997 returnedValue = [returnedValue, response]; 998 } 999 else if(response !== undefined) { 1000 returnedValue = response; 1001 } 1002 return found; 1003 } 1004 }; 1005 1006 if(methodInvoked) { 1007 if(instance === undefined) { 1008 module.initialize(); 1009 } 1010 module.invoke(query); 1011 } 1012 else { 1013 if(instance !== undefined) { 1014 instance.invoke('destroy'); 1015 } 1016 module.initialize(); 1017 } 1018 }) 1019 ; 1020 1021 return (returnedValue !== undefined) 1022 ? returnedValue 1023 : this 1024 ; 1025}; 1026 1027$.api.settings = { 1028 1029 name : 'API', 1030 namespace : 'api', 1031 1032 debug : false, 1033 verbose : false, 1034 performance : true, 1035 1036 // object containing all templates endpoints 1037 api : {}, 1038 1039 // whether to cache responses 1040 cache : true, 1041 1042 // whether new requests should abort previous requests 1043 interruptRequests : true, 1044 1045 // event binding 1046 on : 'auto', 1047 1048 // context for applying state classes 1049 stateContext : false, 1050 1051 // duration for loading state 1052 loadingDuration : 0, 1053 1054 // whether to hide errors after a period of time 1055 hideError : 'auto', 1056 1057 // duration for error state 1058 errorDuration : 2000, 1059 1060 // whether parameters should be encoded with encodeURIComponent 1061 encodeParameters : true, 1062 1063 // API action to use 1064 action : false, 1065 1066 // templated URL to use 1067 url : false, 1068 1069 // base URL to apply to all endpoints 1070 base : '', 1071 1072 // data that will 1073 urlData : {}, 1074 1075 // whether to add default data to url data 1076 defaultData : true, 1077 1078 // whether to serialize closest form 1079 serializeForm : false, 1080 1081 // how long to wait before request should occur 1082 throttle : 0, 1083 1084 // whether to throttle first request or only repeated 1085 throttleFirstRequest : true, 1086 1087 // standard ajax settings 1088 method : 'get', 1089 data : {}, 1090 dataType : 'json', 1091 1092 // mock response 1093 mockResponse : false, 1094 mockResponseAsync : false, 1095 1096 // aliases for mock 1097 response : false, 1098 responseAsync : false, 1099 1100 // callbacks before request 1101 beforeSend : function(settings) { return settings; }, 1102 beforeXHR : function(xhr) {}, 1103 onRequest : function(promise, xhr) {}, 1104 1105 // after request 1106 onResponse : false, // function(response) { }, 1107 1108 // response was successful, if JSON passed validation 1109 onSuccess : function(response, $module) {}, 1110 1111 // request finished without aborting 1112 onComplete : function(response, $module) {}, 1113 1114 // failed JSON success test 1115 onFailure : function(response, $module) {}, 1116 1117 // server error 1118 onError : function(errorMessage, $module) {}, 1119 1120 // request aborted 1121 onAbort : function(errorMessage, $module) {}, 1122 1123 successTest : false, 1124 1125 // errors 1126 error : { 1127 beforeSend : 'The before send function has aborted the request', 1128 error : 'There was an error with your request', 1129 exitConditions : 'API Request Aborted. Exit conditions met', 1130 JSONParse : 'JSON could not be parsed during error handling', 1131 legacyParameters : 'You are using legacy API success callback names', 1132 method : 'The method you called is not defined', 1133 missingAction : 'API action used but no url was defined', 1134 missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object', 1135 missingURL : 'No URL specified for api event', 1136 noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.', 1137 noStorage : 'Caching responses locally requires session storage', 1138 parseError : 'There was an error parsing your request', 1139 requiredParameter : 'Missing a required URL parameter: ', 1140 statusMessage : 'Server gave an error: ', 1141 timeout : 'Your request timed out' 1142 }, 1143 1144 regExp : { 1145 required : /\{\$*[A-z0-9]+\}/g, 1146 optional : /\{\/\$*[A-z0-9]+\}/g, 1147 }, 1148 1149 className: { 1150 loading : 'loading', 1151 error : 'error' 1152 }, 1153 1154 selector: { 1155 disabled : '.disabled', 1156 form : 'form' 1157 }, 1158 1159 metadata: { 1160 action : 'action', 1161 url : 'url' 1162 } 1163}; 1164 1165 1166 1167})( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.