538
538
return str.substr(str.length - substring.length) == substring;
541
/** Equivalent to Python's repr.
542
* Gets the JavaScript string representation.
543
* Actually just calls JSON.stringify.
547
return JSON.stringify(str);
550
541
/** Removes all occurences of a value from an array.
552
543
Array.prototype.removeall = function(val)
620
611
return str.join('');
623
/** Makes an asynchronous XMLHttpRequest call to the server.
614
/** Makes an XMLHttpRequest call to the server.
624
615
* Sends the XMLHttpRequest object containing the completed response to a
625
616
* specified callback function.
627
618
* \param callback A callback function. Will be called when the response is
628
619
* complete. Passed 1 parameter, an XMLHttpRequest object containing the
629
* completed response.
620
* completed response. If callback is null this is a syncronous request
621
* otherwise this is an asynchronous request.
630
622
* \param app IVLE app to call (such as "fileservice").
631
623
* \param path URL path to make the request to, within the application.
632
624
* \param args Argument object, as described in parse_url and friends.
633
* \param method String; "GET" or "POST"
634
* \param content_type String, optional. Only applies if method is "POST".
635
* May be "application/x-www-form-urlencoded" or "multipart/form-data".
625
* \param method String; "GET", "POST", "PUT", or "PATCH"
626
* \param content_type String, optional.
636
627
* Defaults to "application/x-www-form-urlencoded".
638
629
function ajax_call(callback, app, path, args, method, content_type)
640
if (content_type != "multipart/form-data")
641
632
content_type = "application/x-www-form-urlencoded";
642
633
path = app_path(app, path);
646
637
* used within this function) */
647
638
var boundary = random_string(20);
648
639
var xhr = new_xmlhttprequest();
649
xhr.onreadystatechange = function()
651
if (xhr.readyState == 4)
640
var asyncronous = callback != null;
643
xhr.onreadystatechange = function()
645
if (xhr.readyState == 4)
656
651
if (method == "GET")
658
653
/* GET sends the args in the URL */
659
654
url = build_url({"path": path, "args": args});
660
655
/* open's 3rd argument = true -> asynchronous */
661
xhr.open(method, url, true);
656
xhr.open(method, url, asyncronous);
666
/* POST sends the args in application/x-www-form-urlencoded */
661
/* POST & PUT & PATCH sends the args in the request body */
667
662
url = encodeURI(path);
668
xhr.open(method, url, true);
663
xhr.open(method, url, asyncronous);
670
665
if (content_type == "multipart/form-data")
673
668
"multipart/form-data; boundary=" + boundary);
674
669
message = make_multipart_formdata(args, boundary);
671
else if (content_type == "application/x-www-form-urlencoded")
678
673
xhr.setRequestHeader("Content-Type", content_type);
679
674
message = make_query_string(args);
676
else if (content_type == "application/json")
678
xhr.setRequestHeader("Content-Type", content_type);
679
message = JSON.stringify(args);
683
xhr.setRequestHeader("Content-Type", content_type);
681
686
xhr.send(message);
688
/* Only return the XHR for syncronous requests */
695
/** Attempts to JSON decodes a response object
696
* If a non-200 response or the JSON decode fails then returns null
698
function decode_response(response)
700
if (response.status == 200)
704
var responseText = response.responseText;
705
return JSON.parse(responseText);