cosmetic
[myslice.git] / manifold / js / manifold.js
1 // utilities 
2 function debug_dict (msg, o) {
3     var keys=[];
4     for (var k in o) keys.push(k);
5     console.log ("debug_dict: " + msg + " keys= " + keys);
6 }
7 function debug_value (msg, value) {
8     console.log ("debug_value: " + msg + " " + value);
9 }
10
11 /* ------------------------------------------------------------ */
12 // this namespace holds functions for globally managing query objects
13 var manifold = {
14
15     all_queries: {},
16
17     insert_query : function (query) { 
18         manifold.all_queries[query.query_uuid]=query; 
19    },
20     find_query : function (query_uuid) { 
21         return manifold.all_queries[query_uuid];
22     },
23     debug_all_queries : function (msg) {
24         for (var query_uuid in manifold.all_queries) {
25             console.log("manifold.debug " + msg + " " + query_uuid + " -> " + manifold.all_queries[query_uuid]);
26         }
27     },
28
29     // trigger a query asynchroneously
30     proxy_url : '/manifold/proxy/json/',
31
32     asynchroneous_debug : true,
33
34     // Executes all async. queries
35     // input queries are specified as a list of {'query_uuid': <query_uuid>, 'id': <possibly null>}
36     asynchroneous_exec : function (query_uuid_domids) {
37         // start spinners
38         jQuery('.need-spin').spin();
39         
40         // We use js function closure to be able to pass the query (array) to the
41         // callback function used when data is received
42         var success_closure = function(query, id) {
43             return function(data, textStatus) {manifold.asynchroneous_success(data, query, id);}};
44         
45         // Loop through query array and use ajax to send back query_uuid_domids (to frontend) with json
46         jQuery.each(query_uuid_domids, function(index, tuple) {
47             var query=manifold.find_query(tuple.query_uuid);
48             var hash=query.to_hash();
49             if (manifold.asynchroneous_debug) 
50                 console.log ("sending POST on " + manifold.proxy_url + " iterating on " + tuple.query_uuid + " -> " + hash);
51             jQuery.post(manifold.proxy_url, {'query': hash}, success_closure(query, tuple.id));
52         })
53             },
54
55     asynchroneous_success : function (data, query, id) {
56         if (data) {
57             if (!!id) {
58                 /* Directly inform the requestor */
59                 jQuery('#' + id).trigger('results', [data]);
60             } else {
61                 /* Publish an update announce */
62                 jQuery.publish("/results/" + query.query_uuid + "/changed", [data, query]);
63             }
64
65         }
66     },
67
68 }; // manifold object
69 /* ------------------------------------------------------------ */
70
71 // extend jQuery/$ with pubsub capabilities
72 /* https://gist.github.com/661855 */
73 (function($) {
74
75   var o = $({});
76
77   $.subscribe = function( types, selector, data, fn) {
78     /* borrowed from jQuery */
79     if ( data == null && fn == null ) {
80         // ( types, fn )
81         fn = selector;
82         data = selector = undefined;
83     } else if ( fn == null ) {
84         if ( typeof selector === "string" ) {
85             // ( types, selector, fn )
86             fn = data;
87             data = undefined;
88         } else {
89             // ( types, data, fn )
90             fn = data;
91             data = selector;
92             selector = undefined;
93         }
94     }
95     /* </ugly> */
96
97     /* We use an indirection function that will clone the object passed in
98      * parameter to the subscribe callback 
99      * 
100      * FIXME currently we only clone query objects which are the only ones
101      * supported and editable, we might have the same issue with results but
102      * the page load time will be severely affected...
103      */
104     o.on.apply(o, [types, selector, data, function() { 
105         for(i = 1; i < arguments.length; i++) {
106             if ( arguments[i].constructor.name == 'Query' )
107                 arguments[i] = arguments[i].clone();
108         }
109         fn.apply(o, arguments);
110     }]);
111   };
112
113   $.unsubscribe = function() {
114     o.off.apply(o, arguments);
115   };
116
117   $.publish = function() {
118     o.trigger.apply(o, arguments);
119   };
120
121 }(jQuery));
122
123 /* ------------------------------------------------------------ */
124
125 //http://stackoverflow.com/questions/5100539/django-csrf-check-failing-with-an-ajax-post-request
126 //make sure to expose csrf in our outcoming ajax/post requests
127 $.ajaxSetup({ 
128      beforeSend: function(xhr, settings) {
129          function getCookie(name) {
130              var cookieValue = null;
131              if (document.cookie && document.cookie != '') {
132                  var cookies = document.cookie.split(';');
133                  for (var i = 0; i < cookies.length; i++) {
134                      var cookie = jQuery.trim(cookies[i]);
135                      // Does this cookie string begin with the name we want?
136                  if (cookie.substring(0, name.length + 1) == (name + '=')) {
137                      cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
138                      break;
139                  }
140              }
141          }
142          return cookieValue;
143          }
144          if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
145              // Only send the token to relative URLs i.e. locally.
146              xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
147          }
148      } 
149 });
150