Changeset 35896


Ignore:
Timestamp:
2022-01-07T12:28:46+13:00 (2 years ago)
Author:
cstephen
Message:

Upgrade web root jQuery and fix clientside XSLT processing.

Location:
main/trunk/greenstone3/web
Files:
1 added
2 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/web/client-side-xslt.js

    r30480 r35896  
    1111
    1212*/
    13 
    1413
    1514function isSupported()
     
    3635    notSupportedCookie();
    3736
    38     // knock out 'client-' part from URL
    39     var location_href = window.location.href;
    40 
    41     var new_location_href = location_href.replace(/^(.*)\/(client-)?([^\?\#]+)(.*)$/,"$1/$3$4");
    42     console.log("Client-side XSLT not supported.  Redirecting to: " + new_location_href);
     37    // Remove the client-side XSLT output parameter
     38    var location_href = window.location.href.replace("o=xsltclient", "");
     39
     40    // location_href = location_href.replace(/^(.*)\/(client-)?([^\?\#]+)(.*)$/,"$1/$3$4");
     41    console.log("Client-side XSLT not supported.  Redirecting to: " + location_href);
    4342   
    44     window.location = new_location_href;
     43    window.location.href = location_href;
    4544}
    4645
     
    5352    for (var i = 0; i < sURLVariables.length; i++) {
    5453        var sParameterName = sURLVariables[i].split('=');
    55     paramHashmap[sParameterName[0]] = sParameterName[1];
     54        paramHashmap[sParameterName[0]] = sParameterName[1];
    5655    }
    5756
     
    8685
    8786    for (var i=textNodes.length-1; i>=0; i--) {
    88     var text_node = textNodes[i];
    89     var text = text_node.nodeValue;
    90     var html = $.parseHTML(text);
    91     $(text_node).replaceWith(html);
    92     }
    93 }
    94 
    95 
     87        var text_node = textNodes[i];
     88        var text = text_node.nodeValue;
     89        var html = $.parseHTML(text);
     90        $(text_node).replaceWith(html);
     91    }
     92}
    9693
    9794var onSaxonLoad = function() {
    98 
    9995    try {
    100     var paramHashmap = getUrlParameterHashmap();
    101    
    102     var rooturl = window.location.pathname;
    103     var queryStr = window.location.search.substring(1);
    104     queryStr = queryStr.replace(/o=.*?(&|$)/g,"");
    105     if (queryStr != '') {
    106         queryStr += "&";
    107     }
    108     queryStr += "o=clientside";
    109 
    110     paramHashmap['o']="clientside";
    111    
    112     //console.log("*** rooturl = " + rooturl);
    113     //console.log("*** queryStr = " + queryStr);
    114 
    115     var skindoc = "";
    116     var xmldoc = "";   
    117    
    118     $.get(rooturl, paramHashmap, function(data) {
    119 
    120         var toplevel_children = $(data).children().eq(0).children();
    121         var skindoc = toplevel_children[0];
    122         var xmldoc = toplevel_children[1];
    123            
    124         var library_name = $('xsltparams>param[name=library_name]', xmldoc).text();
    125         var interface_name = $('xsltparams>param[name=interface_name]', xmldoc).text();
    126         var site_name = $('xsltparams>param[name=site_name]', xmldoc).text();
    127         var use_client_side_xslt = $('xsltparams>param[name=use_client_side_xslt]', xmldoc).text();
    128        
    129         //// Convert temporarily to text here       
    130         skindoc = convertToString(skindoc);
    131         xmldoc = convertToString(xmldoc);
    132        
    133         skindoc = skindoc.replace(/<xslt:stylesheet\s+/,"<xslt:stylesheet xmlns:ixsl=\"http://saxonica.com/ns/interactiveXSLT\" xmlns:js=\"http://saxonica.com/ns/globalJS\" ");
    134         skindoc = skindoc.replace(/extension-element-prefixes="(.*?)"/,"extension-element-prefixes=\"$1 ixsl\"");
    135        
    136         skindoc = skindoc.replace(/util\:exists\(\$meta, ''\)/g, "$meta!=''"); // For now - use regex instead
    137         skindoc = skindoc.replace(/util:replace\((.*?)\)/g, "replace($1)"); // 'replace()' exists in XSLT 2.0
    138         skindoc = skindoc.replace(/util:storeString\(\s*'(.+?)'\s*,\s*'(.*?)'\s*\)/g, "js:storeString(string($1),string($2))");
    139         skindoc = skindoc.replace(/util:getString\('(.+?)'\)/g, "js:getString(string($1))");
    140         skindoc = skindoc.replace(/util:escapeNewLinesAndQuotes\(([^)]+)\)/g, "js:escapeNewLinesAndQuotes(string($1))");
    141         //attr_val = attr_val.replaceAll("util:escapeNewLinesAndQuotes\\(\\s*(.+?)\\s*\\)","$1");
    142        
    143         skindoc = skindoc.replace(/util:getDetailFromDate\((.+?),.+?,.+?\)/g, "'getDetailFromDate $1'"); // ****
    144 
    145         skindoc = skindoc.replace(/util:oidIsMatchOrParent\(([^,]+),([^)]+)\)/g,"js:oidIsMatchOrParent(string($1),string($2))");
    146         skindoc = skindoc.replace(/util:hashToDepthClass\(([^)]+)\)/g,"js:hashToDepthClass(string($1))");
    147         skindoc = skindoc.replace(/util:hashToSectionId\(([^)]+)\)/g,"js:hashToSectionId(string($1))");
    148 
    149         skindoc = skindoc.replace(/java:.*?getNumberedItem\(([^,]+),([^)]+)\)/g,"js:getNumberedItem(string($1),string($2))");
    150 
    151         // Convert to XML
    152         xmldoc = parseFromString(xmldoc, "text/xml");           
    153         skindoc = parseFromString(skindoc, "text/xml");
    154 
    155         console.log("Applying client-side XSLT");       
    156         var output = '';
    157 
    158         //var proc = Saxon.newXSLT20Processor(skindoc);
    159         var proc = Saxon.newXSLT20Processor();
    160        
    161         proc.setParameter(null, 'library_name', library_name);
    162         proc.setParameter(null, 'interface_name', interface_name);
    163         proc.setParameter(null, 'site_name', site_name);
    164         proc.setParameter(null, 'use_client_side_xslt', use_client_side_xslt);     
    165 
    166         // Consider making above XSLT20Porcessor constructor take no  arguments,
    167         // and specify transform through importStylesheet(), this combination
    168         // of code is more consistent with other XSLT systems
    169         //
    170         proc.importStylesheet(skindoc);
    171        
    172         result = proc.transformToDocument(xmldoc);
    173         //result = proc.transformToFragment(xmldoc);
    174 
    175         //proc.updateHTMLDocument(xmldoc);
    176         //return;
    177 
    178         var excerptid = paramHashmap['excerptid'];
    179         if (excerptid) {
    180         result = result.getElementById(excerptid);
    181         }
    182        
    183         applyDisableEscapingToTextNodes(result);
    184         xmlSer = new XMLSerializer();
    185         output = xmlSer.serializeToString(result);
    186        
    187         if (excerptid) {
    188         var callback = paramHashmap['callback'];
    189         parent[callback](output);       
    190         }
    191         else {
    192         var doc = document.open();
    193         doc.write(output);
    194         doc.close();
    195 
    196         // ****
    197         document.cookie = 'supportsXSLT=true; expires=0; path=/';
    198         }
    199            
    200        
    201     }, 'xml');
    202 
     96        var paramHashmap = getUrlParameterHashmap();
     97        var rooturl = window.location.pathname;
     98        var queryStr = window.location.search.substring(1);
     99
     100        queryStr = queryStr.replace(/o=.*?(&|$)/g,"");
     101        if (queryStr != '') {
     102            queryStr += "&";
     103        }
     104
     105        queryStr += "o=clientside";
     106        paramHashmap['o']="clientside";
     107       
     108        //console.log("*** rooturl = " + rooturl);
     109        //console.log("*** queryStr = " + queryStr);
     110       
     111        $.get(rooturl, paramHashmap, function(data) {
     112            var toplevel_children = $(data).children().eq(0).children();
     113            var skindoc = toplevel_children[0];
     114            var xmldoc = toplevel_children[1];
     115               
     116            var library_name = $('xsltparams>param[name=library_name]', xmldoc).text();
     117            var interface_name = $('xsltparams>param[name=interface_name]', xmldoc).text();
     118            var site_name = $('xsltparams>param[name=site_name]', xmldoc).text();
     119            var use_client_side_xslt = $('xsltparams>param[name=use_client_side_xslt]', xmldoc).text();
     120           
     121            // Convert temporarily to text so we can easily replace invalid values
     122            var xmlSerializer = new XMLSerializer();
     123            skindoc = xmlSerializer.serializeToString(skindoc);
     124            xmldoc = xmlSerializer.serializeToString(xmldoc);
     125           
     126            skindoc = skindoc.replace(/<xslt:stylesheet\s+/,"<xslt:stylesheet xmlns:ixsl=\"http://saxonica.com/ns/interactiveXSLT\" xmlns:js=\"http://saxonica.com/ns/globalJS\" ");
     127            skindoc = skindoc.replace(/extension-element-prefixes="(.*?)"/,"extension-element-prefixes=\"$1 ixsl\"");
     128           
     129            skindoc = skindoc.replace(/util\:exists\(\$meta, ''\)/g, "$meta!=''"); // For now - use regex instead
     130            skindoc = skindoc.replace(/util:replace\((.*?)\)/g, "replace($1)"); // 'replace()' exists in XSLT 2.0
     131            skindoc = skindoc.replace(/util:storeString\(\s*'(.+?)'\s*,\s*'(.*?)'\s*\)/g, "js:storeString(string($1),string($2))");
     132            skindoc = skindoc.replace(/util:getString\('(.+?)'\)/g, "js:getString(string($1))");
     133            skindoc = skindoc.replace(/util:escapeNewLinesAndQuotes\(([^)]+)\)/g, "js:escapeNewLinesAndQuotes(string($1))");
     134            skindoc = skindoc.replace(/util:escapeNewLinesQuotesAngleBracketsForJSString\(([^)]+)\)/g, "js:escapeNewLinesQuotesAngleBracketsForJSString(string($1))");
     135           
     136            skindoc = skindoc.replace(/util:getDetailFromDate\((.+?),.+?,.+?\)/g, "'getDetailFromDate $1'"); // ****
     137
     138            skindoc = skindoc.replace(/util:oidIsMatchOrParent\(([^,]+),([^)]+)\)/g,"js:oidIsMatchOrParent(string($1),string($2))");
     139            skindoc = skindoc.replace(/util:hashToDepthClass\(([^)]+)\)/g,"js:hashToDepthClass(string($1))");
     140            skindoc = skindoc.replace(/util:hashToSectionId\(([^)]+)\)/g,"js:hashToSectionId(string($1))");
     141
     142            skindoc = skindoc.replace(/java:.*?getNumberedItem\(([^,]+),([^)]+)\)/g, "js:getNumberedItem(string($1),string($2))");
     143
     144            // The XMLSerializer converts some escaping, which we undo here
     145            // so that Saxon-CE can successfully parse the document.
     146            skindoc = skindoc.replace("\"'''\"", "\"'&amp;apos;'\"");
     147
     148            // Convert back to XML
     149            xmldoc = parseFromString(xmldoc, "text/xml");           
     150            skindoc = parseFromString(skindoc, "text/xml");
     151           
     152            var proc = Saxon.newXSLT20Processor();
     153            proc.setParameter(null, 'library_name', library_name);
     154            proc.setParameter(null, 'interface_name', interface_name);
     155            proc.setParameter(null, 'site_name', site_name);
     156            proc.setParameter(null, 'use_client_side_xslt', use_client_side_xslt);
     157           
     158            console.log("Applying client-side XSLT");   
     159            proc.importStylesheet(skindoc);
     160            var result = proc.transformToDocument(xmldoc);
     161
     162            var excerptid = paramHashmap['excerptid'];
     163            if (excerptid) {
     164                result = result.getElementById(excerptid);
     165            }
     166           
     167            applyDisableEscapingToTextNodes(result);
     168            var DOMString = xmlSerializer.serializeToString(result);
     169           
     170            if (excerptid) {
     171                var callback = paramHashmap['callback'];
     172                parent[callback](DOMString);
     173            }
     174            else
     175            {
     176                /**
     177                 * NOTE (Carl - cstephen):
     178                 * This is not an ideal solution. document.open() is a slow option
     179                 * and is limited in certain browsers, wherein scripts are prevented
     180                 * from running under certain networking conditions.
     181                 *
     182                 * Ideally we'd directly replace the document with the constructed DOM.
     183                 * However, despite the replacement being successful, it wasn't being
     184                 * parsed successfully at the time of writing.
     185                 *
     186                 * If you'd like to attempt this again, the following is a good starting point:
     187                 * var processor = Saxon.newXSLT20Processor();
     188                 * var documentFragment = processor.transformToFragment(xmldoc);
     189                 * document.replaceChild(documentFragment, document.documentElement);
     190                 */
     191
     192                var newDocument = document.open("text/html");
     193                newDocument.write(DOMString);
     194                newDocument.close();
     195
     196                document.cookie = 'supportsXSLT=true; expires=0; path=/';
     197            }
     198        }, 'xml');
    203199    }
    204200    catch (e) {
    205     alert("Error occured:" + e.message + "\n======\nSee web browser console for more details");
    206     notSupported();
    207    
    208     }
    209 }
    210 
    211 
    212 function convertToString(content) {
    213     try {
    214     // If this fails, it's another indication that the browser doesn't have the support we need
    215     if(typeof XMLSerializer != 'undefined') {
    216         return (new XMLSerializer()).serializeToString(content);
    217     } else {
    218         return content.xml;
    219     }       
    220     }
    221     catch (e) {
    222     notSupported();
     201        alert("Error occured:" + e.message + "\n======\nSee web browser console for more details");
     202        notSupported();
    223203    }
    224204}
     
    226206function parseFromString(content, contentType) {
    227207    try {
    228     var retobj;
    229    
    230     if(typeof window.DOMParser != 'undefined') {
    231         // Firefox, Chrome
    232         retobj = (new DOMParser()).parseFromString(content, contentType);
    233     } else {
    234         // IE
    235         var retobj = new ActiveXObject("Microsoft.XMLDOM");
    236         retobj.async = "false";
    237         retobj.loadXML(content);
    238     }
    239    
    240     return retobj;
     208        var retobj;
     209       
     210        if (typeof window.DOMParser != 'undefined') {
     211            // Firefox, Chrome
     212            retobj = (new DOMParser()).parseFromString(content, contentType);
     213        }
     214        else {
     215            // IE
     216            var retobj = new ActiveXObject("Microsoft.XMLDOM");
     217            retobj.async = "false";
     218            retobj.loadXML(content);
     219        }
     220       
     221        return retobj;
    241222    }
    242223    catch(e) {
    243     var obj = new ActiveXObject('MSXML.DomDocument');
    244     obj.async = false; obj.loadXML(content);
    245     return obj;
     224        var obj = new ActiveXObject('MSXML.DomDocument');
     225        obj.async = false;
     226        obj.loadXML(content);
     227
     228        return obj;
    246229    }
    247230}
  • main/trunk/greenstone3/web/test.js

    r25701 r35896  
    8181}
    8282
    83 $(document).ready(function() { 
     83$(function () {
    8484    if(on && isSupported()) {       
    8585        if(placeholder) {
  • main/trunk/greenstone3/web/xslt-util.js

    r30479 r35896  
    1212
    1313
    14 // Port of methods from GSXLUtil.java and Dictionary.java to support client side XSLT
     14// Port of methods from GSXLUtil.java, XSLTUtil.java and Dictionary.java to support client side XSLT
    1515
    1616// Function for inserting args into retrieved interface string
     
    111111}
    112112
    113 
     113// public static String escapeNewLinesQuotesAngleBracketsForJSString(String str)
     114function escapeNewLinesQuotesAngleBracketsForJSString(str)
     115{
     116    // The \n and " becomes \\\n and \\\"
     117    // but the <> are escaped/encoded for html, i.e. &gt; and &lt; 
     118    if (str == null || str.length < 1)
     119    {
     120        return null;
     121    }
     122
     123    return escapeAngleBrackets(escapeNewLines(escapeQuotes(str)));
     124}
     125
     126// public static String escapeAngleBrackets(String str)
     127function escapeAngleBrackets(str)
     128{
     129    if (str == null || str.length < 1)
     130    {
     131        return null;
     132    }
     133
     134    return str.replace("<", "&lt;").replace(">", "&gt;");
     135}
    114136
    115137function getNumberedItem(list, number)
Note: See TracChangeset for help on using the changeset viewer.