84 }); |
87 }); |
85 |
88 |
86 |
89 |
87 var JSON_BASE_URL = baseuri() + 'json?'; |
90 var JSON_BASE_URL = baseuri() + 'json?'; |
88 |
91 |
89 /** |
92 |
90 * returns true if `url` is a mod_concat-like url |
93 jQuery.extend(cw.ajax, { |
91 * (e.g. http://..../data??resource1.js,resource2.js) |
94 /* variant of jquery evalScript with cache: true in ajax call */ |
92 */ |
95 _evalscript: function ( i, elem ) { |
93 function _modconcatLikeUrl(url) { |
96 if ( elem.src ) { |
94 var base = baseuri(); |
97 jQuery.ajax({ |
95 if (!base.endswith('/')) { |
98 url: elem.src, |
96 base += '/'; |
99 async: false, |
97 } |
100 cache: true, |
98 var modconcat_rgx = new RegExp('(' + base + 'data/([a-z0-9]+/)?)\\?\\?(.+)'); |
101 dataType: "script" |
99 return modconcat_rgx.exec(url); |
102 }); |
100 } |
103 } else { |
101 |
104 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); |
102 /** |
105 } |
103 * decomposes a mod_concat-like url into its corresponding list of |
106 if ( elem.parentNode ) { |
104 * resources' urls |
107 elem.parentNode.removeChild( elem ); |
105 * |
108 } |
106 * >>> _listResources('http://foo.com/data/??a.js,b.js,c.js') |
109 }, |
107 * ['http://foo.com/data/a.js', 'http://foo.com/data/b.js', 'http://foo.com/data/c.js'] |
110 |
108 */ |
111 evalscripts: function ( scripts ) { |
109 function _listResources(src) { |
112 if ( scripts.length ) { |
110 var resources = []; |
113 jQuery.each(scripts, cw.ajax._evalscript); |
111 var groups = _modconcatLikeUrl(src); |
114 } |
112 if (groups == null) { |
115 }, |
113 resources.push(src); |
116 |
114 } else { |
117 /** |
115 var dataurl = groups[1]; |
118 * returns true if `url` is a mod_concat-like url |
116 $.each(cw.utils.lastOf(groups).split(','), |
119 * (e.g. http://..../data??resource1.js,resource2.js) |
117 function() { |
120 */ |
118 resources.push(dataurl + this); |
121 _modconcatLikeUrl: function(url) { |
119 }); |
122 var base = baseuri(); |
120 } |
123 if (!base.endswith('/')) { base += '/'; } |
121 return resources; |
124 var modconcat_rgx = new RegExp('(' + base + 'data/([a-z0-9]+/)?)\\?\\?(.+)'); |
122 } |
125 return modconcat_rgx.exec(url); |
|
126 }, |
|
127 |
|
128 /** |
|
129 * decomposes a mod_concat-like url into its corresponding list of |
|
130 * resources' urls |
|
131 * >>> _listResources('http://foo.com/data/??a.js,b.js,c.js') |
|
132 * ['http://foo.com/data/a.js', 'http://foo.com/data/b.js', 'http://foo.com/data/c.js'] |
|
133 */ |
|
134 _listResources: function(src) { |
|
135 var resources = []; |
|
136 var groups = cw.ajax._modconcatLikeUrl(src); |
|
137 if (groups == null) { |
|
138 resources.push(src); |
|
139 } else { |
|
140 var dataurl = groups[1]; |
|
141 $.each(cw.utils.lastOf(groups).split(','), |
|
142 function() { |
|
143 resources.push(dataurl + this); |
|
144 } |
|
145 ); |
|
146 } |
|
147 return resources; |
|
148 } |
|
149 }); |
123 |
150 |
124 //============= utility function handling remote calls responses. ==============// |
151 //============= utility function handling remote calls responses. ==============// |
125 function _loadAjaxHtmlHead($node, $head, tag, srcattr) { |
152 function _loadAjaxHtmlHead($node, $head, tag, srcattr) { |
126 var jqtagfilter = tag + '[' + srcattr + ']'; |
153 var jqtagfilter = tag + '[' + srcattr + ']'; |
127 if (cw['loaded_'+srcattr] === undefined) { |
154 if (cw['loaded_'+srcattr] === undefined) { |
128 cw['loaded_'+srcattr] = []; |
155 cw['loaded_'+srcattr] = []; |
129 var loaded = cw['loaded_'+srcattr]; |
156 var loaded = cw['loaded_'+srcattr]; |
130 jQuery('head ' + jqtagfilter).each(function(i) { |
157 jQuery('head ' + jqtagfilter).each(function(i) { |
131 // tab1.push.apply(tab1, tab2) <=> tab1 += tab2 (python-wise) |
158 // tab1.push.apply(tab1, tab2) <=> tab1 += tab2 (python-wise) |
132 loaded.push.apply(loaded, _listResources(this.getAttribute(srcattr))); |
159 loaded.push.apply(loaded, cw.ajax._listResources(this.getAttribute(srcattr))); |
133 }); |
160 }); |
134 } else { |
161 } else { |
135 var loaded = cw['loaded_'+srcattr]; |
162 var loaded = cw['loaded_'+srcattr]; |
136 } |
163 } |
137 $node.find(tag).each(function(i) { |
164 $node.find(tag).each(function(i) { |
138 var srcnode = this; |
165 var $srcnode = jQuery(this); |
139 var url = srcnode.getAttribute(srcattr); |
166 var url = $srcnode.attr(srcattr); |
140 if (url) { |
167 if (url) { |
141 $.each(_listResources(url), function() { |
168 /* special handling of <script> tags: script nodes appended by jquery |
142 var resource = '' + this; // implicit object->string cast |
169 * use uncached ajax calls and do not appear in the DOM |
143 if ($.inArray(resource, loaded) == -1) { |
170 * (See comments in response to Syt on // http://api.jquery.com/append/), |
144 // take care to <script> tags: jQuery append method script nodes |
171 * which cause undesired duplicated load in our case. We now handle |
145 // don't appears in the DOM (See comments on |
172 * a list of already loaded resources, since bare DOM api gives bugs with the |
146 // http://api.jquery.com/append/), which cause undesired |
173 * server-response event, and we lose control on when the |
147 // duplicated load in our case. After trying to use bare DOM api |
174 * script is loaded (jQuery loads it immediately). */ |
148 // to avoid this, we switched to handle a list of already loaded |
175 var resources = cw.ajax._listResources(url); |
149 // stuff ourselves, since bare DOM api gives bug with the |
176 var missingResources = $.grep(resources, function(resource) { |
150 // server-response event, since we loose control on when the |
177 return $.inArray(resource, loaded) == -1; |
151 // script is loaded (jQuery load it immediatly). |
|
152 loaded.push(resource); |
|
153 } |
|
154 }); |
178 }); |
155 } |
179 loaded.push.apply(loaded, missingResources); |
156 jQuery(srcnode).appendTo($head); |
180 if (missingResources.length == 1) { |
|
181 // only one resource missing: build a node with a single resource url |
|
182 // (maybe the browser has it in cache already) |
|
183 $srcnode.attr(srcattr, missingResources[0]); |
|
184 } else if (missingResources.length > 1) { |
|
185 // several resources missing: build a node with a concatenated |
|
186 // resources url |
|
187 var dataurl = cw.ajax._modconcatLikeUrl(url)[1]; |
|
188 var missing_path = $.map(missingResources, function(resource) { |
|
189 return resource.substring(dataurl.length); |
|
190 }); |
|
191 $srcnode.attr(srcattr, dataurl + '??' + missing_path.join(',')); |
|
192 } |
|
193 // === will work if both arguments are of the same type |
|
194 if ( $srcnode.attr('type') === 'text/javascript' ) { |
|
195 cw.ajax.evalscripts($srcnode); |
|
196 } else { |
|
197 $srcnode.appendTo($head); |
|
198 } |
|
199 } |
157 }); |
200 }); |
158 $node.find(jqtagfilter).remove(); |
201 $node.find(jqtagfilter).remove(); |
159 } |
202 } |
160 |
203 |
161 /** |
204 /** |