jQueryServer.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /**
  2. * jQuery Server Plugin
  3. *
  4. * Server-side Ajax requests supporting jQuery manipulations
  5. * before sending content to the browser.
  6. *
  7. * Example:
  8. * $.server({url: ${URL})
  9. * .find('.my-class')
  10. * .client(${CALLBACK});
  11. *
  12. * @version 0.5.1
  13. * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
  14. * @link http://code.google.com/p/phpquery/wiki/jQueryServer
  15. * @link http://code.google.com/p/phpquery/
  16. */
  17. jQuery.extend({
  18. serverConfig: function() {
  19. if (typeof jQueryServerConfig != 'undefined')
  20. return jQueryServerConfig;
  21. return {};
  22. }(),
  23. server: function(options){
  24. // set default url
  25. if (! jQuery.serverConfig.url)
  26. jQuery.serverConfig.url = jQuery('script[src$=jquery.js]')
  27. .attr('src').replace(/jquery\.js$/, '')
  28. +'jQueryServer.php';
  29. // this is cache object
  30. var objectCache = {};
  31. // dump all jQuery methods, but only once
  32. // $.each doesn't work ?
  33. for( var i in jQuery.fn) {
  34. // closure to preserve loop iterator in scope
  35. (function(){
  36. var name = i;
  37. // create dummy method
  38. objectCache[name] = function(){
  39. // create method data object
  40. var data = {
  41. method: name,
  42. arguments: []
  43. };
  44. // collect arguments
  45. $.each(arguments, function(k, v){
  46. data.arguments.push(v);
  47. });
  48. // push data into stack
  49. this.stack.push(data);
  50. // preserve chain
  51. return this;
  52. }
  53. })();
  54. }
  55. /**
  56. * Fetches results from phpQuery.
  57. *
  58. * @param {Function} callback Optional. Turns on async request.
  59. * First parameter for callback is usually an JSON array of mathed elements. Use $(result) to append it to DOM.
  60. * It can also be a boolean value or string, depending on last method called.
  61. */
  62. objectCache.client = function(success, error){
  63. // console.log(this.stack.toSource());
  64. // success = success || function(){
  65. // return $result;
  66. // };
  67. $.ajax({
  68. type: 'POST',
  69. data: {data: $.toJSON(this.stack)},
  70. async: false,
  71. // jQuery.server.config ???
  72. url: jQuery.serverConfig.url,
  73. // success: function(response){
  74. // var $result = jQuery();
  75. // $.each(response, function(v) {
  76. // $result.add(v);
  77. // })
  78. // success.call(null, $result);
  79. // },
  80. // success: success,
  81. success: function(response){
  82. if (options['dataType'] == 'json')
  83. response = $.parseJSON(response);
  84. success(response);
  85. },
  86. error: error
  87. })
  88. }
  89. // replace orginal method with generated method using cache (lazy-load)
  90. jQuery.server = function(options){
  91. // clone cache object
  92. var myCache = jQuery.extend({}, objectCache);
  93. myCache.stack = [options];
  94. return myCache;
  95. }
  96. // returen result from new method (only done for first call)
  97. return jQuery.server(options);
  98. }
  99. });
  100. // toJSON by Mark Gibson
  101. if (typeof $.toJSON == 'undefined') {
  102. (function ($) {
  103. var m = {
  104. '\b': '\\b',
  105. '\t': '\\t',
  106. '\n': '\\n',
  107. '\f': '\\f',
  108. '\r': '\\r',
  109. '"' : '\\"',
  110. '\\': '\\\\'
  111. },
  112. s = {
  113. 'array': function (x) {
  114. var a = ['['], b, f, i, l = x.length, v;
  115. for (i = 0; i < l; i += 1) {
  116. v = x[i];
  117. f = s[typeof v];
  118. if (f) {
  119. v = f(v);
  120. if (typeof v == 'string') {
  121. if (b) {
  122. a[a.length] = ',';
  123. }
  124. a[a.length] = v;
  125. b = true;
  126. }
  127. }
  128. }
  129. a[a.length] = ']';
  130. return a.join('');
  131. },
  132. 'boolean': function (x) {
  133. return String(x);
  134. },
  135. 'null': function (x) {
  136. return "null";
  137. },
  138. 'number': function (x) {
  139. return isFinite(x) ? String(x) : 'null';
  140. },
  141. 'object': function (x) {
  142. if (x) {
  143. if (x instanceof Array) {
  144. return s.array(x);
  145. }
  146. var a = ['{'], b, f, i, v;
  147. for (i in x) {
  148. v = x[i];
  149. f = s[typeof v];
  150. if (f) {
  151. v = f(v);
  152. if (typeof v == 'string') {
  153. if (b) {
  154. a[a.length] = ',';
  155. }
  156. a.push(s.string(i), ':', v);
  157. b = true;
  158. }
  159. }
  160. }
  161. a[a.length] = '}';
  162. return a.join('');
  163. }
  164. return 'null';
  165. },
  166. 'string': function (x) {
  167. if (/["\\\x00-\x1f]/.test(x)) {
  168. x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
  169. var c = m[b];
  170. if (c) {
  171. return c;
  172. }
  173. c = b.charCodeAt();
  174. return '\\u00' +
  175. Math.floor(c / 16).toString(16) +
  176. (c % 16).toString(16);
  177. });
  178. }
  179. return '"' + x + '"';
  180. }
  181. };
  182. $.toJSON = function(v) {
  183. var f = isNaN(v) ? s[typeof v] : s['number'];
  184. if (f) return f(v);
  185. };
  186. $.parseJSON = function(v, safe) {
  187. if (JSON)
  188. return JSON.parse(v);
  189. if (safe === undefined)
  190. safe = $.parseJSON.safe;
  191. if (safe && !/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))
  192. return undefined;
  193. return eval('('+v+')');
  194. };
  195. $.parseJSON.safe = false;
  196. })(jQuery);
  197. }