;;; -*- Mode: LISP; Syntax: COMMON-LISP; Base: 10 -*- ;;; ;;; Copyright (c) 2007, Ury Marshak ;;; The code comes with a BSD-style license, so you can basically do ;;; with it whatever you want. See the file LICENSE for details. ;;; (in-package #:ht-ajax) (declaim #.*optimization*) ;; ;; Common functions ;; (defun make-safe-js-name (function-name) "Primitive function to try to turn rich lisp names into suitable for Javascript" (loop for c across "-<>" do (setf function-name (substitute #\_ c function-name)) finally (return function-name))) (defun prepare-js-debug-function (processor) "Output the debugging function." (concatenate 'string " function debug_alert(text) {" (when (js-debug processor) " alert(\"HT-AJAX: \" + text);" ) "} ")) ;; (defun js-string-to-boolean (str) ;; (when str ;; (not (or (string= str "") ;; (string= str "null") ;; (string= str "false") ;; (string= str "0")) ;; ))) ;; (defun entity-escape (s) ;; (setf s (regex-replace-all "(?s)&" s "&")) ;; (setf s (regex-replace-all "(?s)<" s "<")) ;; (setf s (regex-replace-all "(?s)>" s ">")) ;; ) (defun prepare-js-collect-varargs-to-array (num-standard-args &optional (array-name "args")) (let ((start_args (symbol-name (gensym))) (end_args (symbol-name (gensym))) (i (symbol-name (gensym)))) (concatenate 'string " var " start_args " = " (princ-to-string num-standard-args) "; var " end_args " = arguments.length; var " array-name " = new Array(); var " i " = " start_args "; for (var " i "=" start_args "; " i " < " end_args "; ++" i ") " array-name ".push(arguments[" i "]); " ))) (defun prepare-js-ajax-encode-args () ;; " function ajax_encode_args(func, args) { var res = 'ajax-fun=' + encodeURIComponent(func); var i; if (args) for (i = 0; i < args.length; ++i) { res = res + '&ajax-arg' + i + '=' + encodeURIComponent(args[i]); } res = res + '&ajax-num-args=' + args.length; res = res + '&ajax-xml=false'; return res; } ") (defun wrap-js-in-script-tags (js) (concatenate 'string " " )) (defun prepare-js-file-include (js-file-uri) (concatenate 'string "")) (defun prepare-js-parse-callbacks () "Create a Javascript function that receives a specification for callbacks and returns an array of two functions, the first is the success callback and the second is the error callback. The callback specification may be: Function. It is assumed to be the success callback, the error callback is assumed to be null Array. Returned as is, i.e. it should be [success_callback, error_callback] Object. If the object has a success property it is used as success callback. The error property if present becomes the error callback." ;; " function ajax_parse_callbacks(obj) { if (typeof obj === 'function') { return [obj, null]; } if (typeof obj === 'object' && typeof obj.length === 'number') { // array return obj; } var error_callback = null; var success_callback = null; if (obj.error !== undefined) { error_callback = obj.error; } if (obj.success !== undefined) { success_callback = obj.success; } return [success_callback, error_callback]; } ") (defun json-content-type () "Official IANA http://www.iana.org/assignments/media-types/application/" ;; "application/json") (defun prepare-js-ajax-is-json () (concatenate 'string " function ajax_trim_CR(s) { if (s.charCodeAt(s.length-1)==13) { s = s.substring(0,s.length-1) } return s; } function ajax_is_json(content_type) { content_type = ajax_trim_CR(content_type); // YUI under IE needs this return (content_type == '" (json-content-type) "'); } ")) (defun prepare-js-ajax-call-maybe-evaluate-json () (concatenate 'string " function ajax_call_maybe_evaluate_json(callback, data, content_type) { if (ajax_is_json(content_type)) { try { data = eval('(' + data + ')'); } catch (e) { debug_alert(e.message); } } callback(data); } ")) (defun prepare-js-ajax-function-definitions(request-func fun-name js-fun-name &key method &allow-other-keys) "Output a string containing the appropriate Javascript for accessing fun-name on server-uri." (concatenate 'string " function " js-fun-name "_callback(callback) { " (prepare-js-collect-varargs-to-array 1 "args") " " request-func "('" fun-name "', callback, args); } " " function " js-fun-name "_set_element(elem_id) { " (prepare-js-collect-varargs-to-array 1 "args") " var elem = document.getElementById(elem_id); if (!elem) { debug_alert('!elem'); } " request-func "('" fun-name "', function(res) {elem.innerHTML=res;} , args); } "))