web/data/cubicweb.ajax.js
changeset 7649 ede740bd7077
parent 7623 5cc7acc7a238
child 7820 2c73fc529a20
equal deleted inserted replaced
7648:5d5d98930247 7649:ede740bd7077
    91 
    91 
    92 
    92 
    93 jQuery.extend(cw.ajax, {
    93 jQuery.extend(cw.ajax, {
    94     /* variant of jquery evalScript with cache: true in ajax call */
    94     /* variant of jquery evalScript with cache: true in ajax call */
    95     _evalscript: function ( i, elem ) {
    95     _evalscript: function ( i, elem ) {
    96        if ( elem.src ) {
    96        var src = elem.getAttribute('src');
       
    97        if (src) {
    97            jQuery.ajax({
    98            jQuery.ajax({
    98                url: elem.src,
    99                url: src,
    99                async: false,
   100                async: false,
   100                cache: true,
   101                cache: true,
   101                dataType: "script"
   102                dataType: "script"
   102            });
   103            });
   103        } else {
   104        } else {
   143                      resources.push(dataurl + this);
   144                      resources.push(dataurl + this);
   144                  }
   145                  }
   145             );
   146             );
   146         }
   147         }
   147         return resources;
   148         return resources;
       
   149     },
       
   150 
       
   151     _buildMissingResourcesUrl: function(url, loadedResources) {
       
   152         var resources = cw.ajax._listResources(url);
       
   153         var missingResources = $.grep(resources, function(resource) {
       
   154             return $.inArray(resource, loadedResources) == -1;
       
   155         });
       
   156         cw.utils.extend(loadedResources, missingResources);
       
   157         var missingResourceUrl = null;
       
   158         if (missingResources.length == 1) {
       
   159             // only one resource missing: build a node with a single resource url
       
   160             // (maybe the browser has it in cache already)
       
   161             missingResourceUrl = missingResources[0];
       
   162         } else if (missingResources.length > 1) {
       
   163             // several resources missing: build a node with a concatenated
       
   164             // resources url
       
   165             var dataurl = cw.ajax._modconcatLikeUrl(url)[1];
       
   166             var missing_path = $.map(missingResources, function(resource) {
       
   167                 return resource.substring(dataurl.length);
       
   168             });
       
   169             missingResourceUrl = dataurl + '??' + missing_path.join(',');
       
   170         }
       
   171         return missingResourceUrl;
       
   172     },
       
   173 
       
   174     _loadAjaxStylesheets: function($responseHead, $head) {
       
   175         $responseHead.find('link[href]').each(function(i) {
       
   176             var $srcnode = $(this);
       
   177             var url = $srcnode.attr('href');
       
   178             if (url) {
       
   179                 var missingStylesheetsUrl = cw.ajax._buildMissingResourcesUrl(url, cw.loaded_links);
       
   180                 // compute concat-like url for missing resources and append <link>
       
   181                 // element to $head
       
   182                 if (missingStylesheetsUrl) {
       
   183                     $srcnode.attr('href', missingStylesheetsUrl);
       
   184                     $srcnode.appendTo($head);
       
   185                 }
       
   186             }
       
   187         });
       
   188         $responseHead.find('link[href]').remove();
       
   189     },
       
   190 
       
   191     _loadAjaxScripts: function($responseHead, $head) {
       
   192         $responseHead.find('pre.script').each(function(i) {
       
   193             var $srcnode = $(this);
       
   194             var url = $srcnode.attr('src');
       
   195             if (url) {
       
   196                 var missingScriptsUrl = cw.ajax._buildMissingResourcesUrl(url, cw.loaded_scripts);
       
   197                 if (missingScriptsUrl) {
       
   198                     $srcnode.attr('src', missingScriptsUrl);
       
   199                     /* special handling of <script> tags: script nodes appended by jquery
       
   200                      * use uncached ajax calls and do not appear in the DOM
       
   201                      * (See comments in response to Syt on // http://api.jquery.com/append/),
       
   202                      * which cause undesired duplicated load in our case. We now handle
       
   203                      * a list of already loaded resources, since bare DOM api gives bugs with the
       
   204                      * server-response event, and we lose control on when the
       
   205                      * script is loaded (jQuery loads it immediately). */
       
   206                     cw.ajax.evalscripts($srcnode);
       
   207                 }
       
   208             } else {
       
   209                 // <script> contains inlined javascript code, node content
       
   210                 // must be evaluated
       
   211     	        jQuery.globalEval($srcnode.text());
       
   212     	    }
       
   213         });
       
   214         $responseHead.find('pre.script').remove();
   148     }
   215     }
   149 });
   216 });
   150 
   217 
   151 //============= utility function handling remote calls responses. ==============//
   218 //============= utility function handling remote calls responses. ==============//
   152 function _loadAjaxHtmlHead($node, $head, tag, srcattr) {
       
   153     var jqtagfilter = tag + '[' + srcattr + ']';
       
   154     if (cw['loaded_'+srcattr] === undefined) {
       
   155         cw['loaded_'+srcattr] = [];
       
   156         var loaded = cw['loaded_'+srcattr];
       
   157         jQuery('head ' + jqtagfilter).each(function(i) {
       
   158             // tab1.push.apply(tab1, tab2) <=> tab1 += tab2 (python-wise)
       
   159             loaded.push.apply(loaded, cw.ajax._listResources(this.getAttribute(srcattr)));
       
   160         });
       
   161     } else {
       
   162         var loaded = cw['loaded_'+srcattr];
       
   163     }
       
   164     $node.find(tag).each(function(i) {
       
   165         var $srcnode = jQuery(this);
       
   166         var url = $srcnode.attr(srcattr);
       
   167         if (url) {
       
   168             /* special handling of <script> tags: script nodes appended by jquery
       
   169              * use uncached ajax calls and do not appear in the DOM
       
   170              * (See comments in response to Syt on // http://api.jquery.com/append/),
       
   171              * which cause undesired duplicated load in our case. We now handle
       
   172              * a list of already loaded resources, since bare DOM api gives bugs with the
       
   173              * server-response event, and we lose control on when the
       
   174              * script is loaded (jQuery loads it immediately). */
       
   175             var resources = cw.ajax._listResources(url);
       
   176             var missingResources = $.grep(resources, function(resource) {
       
   177                 return $.inArray(resource, loaded) == -1;
       
   178             });
       
   179             loaded.push.apply(loaded, missingResources);
       
   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             } else { return ; }
       
   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         }
       
   200     });
       
   201     $node.find(jqtagfilter).remove();
       
   202 }
       
   203 
       
   204 /**
   219 /**
   205  * .. function:: function loadAjaxHtmlHead(response)
   220  * .. function:: function loadAjaxHtmlHead(response)
   206  *
   221  *
   207  * inspect dom response (as returned by getDomFromResponse), search for
   222  * inspect dom response (as returned by getDomFromResponse), search for
   208  * a <div class="ajaxHtmlHead"> node and put its content into the real
   223  * a <div class="ajaxHtmlHead"> node and put its content into the real
   214     var $responseHead = jQuery(response).find('div.ajaxHtmlHead');
   229     var $responseHead = jQuery(response).find('div.ajaxHtmlHead');
   215     // no ajaxHtmlHead found, no processing required
   230     // no ajaxHtmlHead found, no processing required
   216     if (!$responseHead.length) {
   231     if (!$responseHead.length) {
   217         return response;
   232         return response;
   218     }
   233     }
   219     _loadAjaxHtmlHead($responseHead, $head, 'script', 'src');
   234     cw.ajax._loadAjaxStylesheets($responseHead, $head);
   220     _loadAjaxHtmlHead($responseHead, $head, 'link', 'href');
   235     cw.ajax._loadAjaxScripts($responseHead, $head);
   221     // add any remaining children (e.g. meta)
   236     // add any remaining children (e.g. meta)
   222     $responseHead.children().appendTo($head);
   237     $responseHead.children().appendTo($head);
   223     // remove original container, which is now empty
   238     // remove original container, which is now empty
   224     $responseHead.remove();
   239     $responseHead.remove();
   225     // if there was only one actual node in the reponse besides
   240     // if there was only one actual node in the reponse besides
   485         extraparams['rql'] = rql;
   500         extraparams['rql'] = rql;
   486         extraparams['vid'] = vid;
   501         extraparams['vid'] = vid;
   487         $fragment.loadxhtml('json', ajaxFuncArgs('view', extraparams));
   502         $fragment.loadxhtml('json', ajaxFuncArgs('view', extraparams));
   488     }
   503     }
   489 }
   504 }
   490 
       
   491 jQuery(document).ready(function() {
       
   492     _loadDynamicFragments();
       
   493 });
       
   494 
       
   495 function unloadPageData() {
   505 function unloadPageData() {
   496     // NOTE: do not make async calls on unload if you want to avoid
   506     // NOTE: do not make async calls on unload if you want to avoid
   497     //       strange bugs
   507     //       strange bugs
   498     loadRemote('json', ajaxFuncArgs('unload_page_data'), 'GET', true);
   508     loadRemote('json', ajaxFuncArgs('unload_page_data'), 'GET', true);
   499 }
   509 }
   815     deferred = deferred.addErrback(remoteCallFailed);
   825     deferred = deferred.addErrback(remoteCallFailed);
   816     deferred = deferred.addErrback(resetCursor);
   826     deferred = deferred.addErrback(resetCursor);
   817     deferred = deferred.addCallback(resetCursor);
   827     deferred = deferred.addCallback(resetCursor);
   818     return deferred;
   828     return deferred;
   819 }
   829 }
       
   830 
       
   831 jQuery(document).ready(function() {
       
   832     _loadDynamicFragments();
       
   833     // build loaded_scripts / loaded_links lists
       
   834     cw.loaded_scripts = [];
       
   835     jQuery('head script[src]').each(function(i) {
       
   836         cw.utils.extend(cw.loaded_scripts, cw.ajax._listResources(this.getAttribute('src')));
       
   837     });
       
   838     cw.loaded_links = [];
       
   839     jQuery('head link[href]').each(function(i) {
       
   840         cw.utils.extend(cw.loaded_links, cw.ajax._listResources(this.getAttribute('href')));
       
   841     });
       
   842 });