[23786] | 1 | /*
|
---|
| 2 |
|
---|
| 3 | Greenstone 3 'Client-side transformer'
|
---|
| 4 | Performs client-side transformations of XSLT, using HTML5 local storage (simulated if the browser doesn't support it).
|
---|
| 5 |
|
---|
| 6 | Currently only supports Firefox 3 and greater, since it's the only browser (at the time of writing) that can do this properly.
|
---|
| 7 |
|
---|
| 8 | @author Steven McTainsh
|
---|
| 9 | @date 14/02/2011
|
---|
| 10 |
|
---|
| 11 | */
|
---|
| 12 |
|
---|
| 13 | /* These URLs and file paths are fetched dynamically */
|
---|
| 14 | var gsweb = ""; // The file path to the Greenstone 3 web directory
|
---|
| 15 | var gsurl = ""; // The root URL for this Greenstone 3 installation
|
---|
| 16 |
|
---|
| 17 | /* Misc. switches and paths */
|
---|
| 18 | var keyUrl = ''; // Used across methods to build up query string for text retrieval (client-side transformed version)
|
---|
| 19 | var on = true; // Set to false to disable operation
|
---|
| 20 |
|
---|
| 21 | var index = 0; // Used for query array (to keep track of number of elements)
|
---|
| 22 | var deferredEls = new Array(); // Elements to defer text retrieval for until later
|
---|
| 23 | var queryArr = new Array(); // Text to query for (the text for the corresponding deferred element)
|
---|
| 24 |
|
---|
| 25 | /* Methods */
|
---|
| 26 | // This is generally only called from in-line JS in the head (i.e. var text = getText(...);)
|
---|
| 27 | function getText(key, el) {
|
---|
| 28 | if(localStorage.getItem(key) != null)
|
---|
| 29 | return localStorage.getItem(key);
|
---|
| 30 | else {
|
---|
| 31 | push(deferredEls, el);
|
---|
| 32 | queryArr[el] = key; // Have it queried for too
|
---|
| 33 | return "";
|
---|
| 34 | }
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 | function processEl(el, attr, key, append, isText, theText) {
|
---|
| 38 | // Assumes all necessary text has been loaded from the servlet
|
---|
| 39 | var displayText = (isText) ? theText : localStorage.getItem(key);
|
---|
| 40 |
|
---|
| 41 | if(el == document && attr == 'title') {
|
---|
| 42 | // Handle document titles
|
---|
| 43 | if(append)
|
---|
| 44 | document.title += displayText;
|
---|
| 45 | else
|
---|
| 46 | document.title = displayText;
|
---|
| 47 | } else if(attr == 'innerText') {
|
---|
| 48 | // Handle element 'inner text'
|
---|
| 49 | if(append)
|
---|
| 50 | $(el).html($(el).html() + displayText);
|
---|
| 51 | else
|
---|
| 52 | $(el).html(displayText);
|
---|
| 53 | } else if(attr == 'value') {
|
---|
| 54 | // Handle value attribute
|
---|
| 55 | if(append)
|
---|
| 56 | $(el).val($el.val() + displayText);
|
---|
| 57 | else
|
---|
| 58 | $(el).val(displayText);
|
---|
| 59 | } else {
|
---|
| 60 | // All other cases (generic attributes)
|
---|
| 61 | if(append)
|
---|
| 62 | $(el).attr(attr, $(el).attr(attr) + displayText);
|
---|
| 63 | else
|
---|
| 64 | $(el).attr(attr, displayText);
|
---|
| 65 | }
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | function notSupported() {
|
---|
| 69 | // Set not supported cookie here
|
---|
| 70 | document.cookie = 'supportsXSLT=false; expires=0; path=/';
|
---|
| 71 | // Fall back to server version
|
---|
| 72 | var location = window.location.search.substring(1);
|
---|
| 73 | if(location == '') {
|
---|
| 74 | // Start with a question mark
|
---|
| 75 | location = window.location + "?o=server";
|
---|
| 76 | } else {
|
---|
| 77 | // Start with an ampersand
|
---|
| 78 | location = window.location + "&o=server";
|
---|
| 79 | }
|
---|
| 80 | window.location = location;
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | $(document).ready(function() {
|
---|
| 84 | if(on && isSupported()) {
|
---|
| 85 | if(placeholder) {
|
---|
| 86 | // Need to prepare page placeholders
|
---|
| 87 | transform(false);
|
---|
| 88 | }
|
---|
| 89 | else {
|
---|
| 90 | // Need to place text into the page (placeholders ready)
|
---|
| 91 | applyText(false);
|
---|
| 92 | }
|
---|
| 93 | }
|
---|
| 94 | });
|
---|
| 95 |
|
---|
| 96 | function applyText(trial) {
|
---|
| 97 |
|
---|
| 98 | try {
|
---|
| 99 | // Wait for document to be ready before propogating this URL (otherwise undefined)
|
---|
| 100 | keyUrl = 'grabtext?i='+$('#interface').html()+'&l='+$('#language').html()+'&k='
|
---|
| 101 |
|
---|
| 102 | // First, see if the local storage should be emptied for a new language...
|
---|
| 103 | if(localStorage.getItem("_activeLanguage") != $('#language').html()) {
|
---|
| 104 | // Languages are different, clear existing strings
|
---|
| 105 | localStorage.clear();
|
---|
| 106 | localStorage.setItem("_activeLanguage", $('#language').html());
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | $('#loading').show();
|
---|
| 110 |
|
---|
| 111 | var query = '';
|
---|
| 112 |
|
---|
| 113 | $('.getTextFor').each(function() {
|
---|
| 114 |
|
---|
| 115 | // Build up query
|
---|
| 116 | // Get the three parts to the class - 'getTextFor' 'element inner text to affect' 'attributes to affect'
|
---|
| 117 | // Proper splitting on spaces
|
---|
| 118 | var parts = parseAction($(this).attr('class'), ' ')
|
---|
| 119 | // parts[1] is this element's innerText key, parts[2] may or may not contain keys
|
---|
| 120 | // Can add null to the array
|
---|
| 121 | if(!contains(queryArr, parts[1]) && localStorage.getItem(parts[1]) == null)
|
---|
| 122 | // If the key has not already been queried for and is not in local storage...
|
---|
| 123 | // NO duplicates!
|
---|
| 124 | queryArr[index++] = parts[1];
|
---|
| 125 |
|
---|
| 126 | if(parts.length == 3 && parts[2] != '') {
|
---|
| 127 | var affected = parts[2].split(',');
|
---|
| 128 |
|
---|
| 129 | for(var j = 0; j < affected.length; j++) {
|
---|
| 130 | var els = parseAction(affected[j], ".");
|
---|
| 131 | // els[2] will contain key
|
---|
| 132 | // Ignore text, and those elements with text already in local storage and that will already be queried for
|
---|
| 133 | if(els[2].indexOf('text:') != 0 && !contains(queryArr, els[2]) && localStorage.getItem(els[2]) == null)
|
---|
| 134 | queryArr[index++] = els[2].replace("[a]", "");
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
| 137 | });
|
---|
| 138 |
|
---|
| 139 | query = queryArr.join(",");
|
---|
| 140 |
|
---|
| 141 | // Fetch!
|
---|
| 142 | if(query != '') { // There is something to query for
|
---|
| 143 |
|
---|
| 144 | $.get(keyUrl + query, function(data) {
|
---|
| 145 |
|
---|
| 146 | // Process dictionary, load into local storage
|
---|
| 147 | $(data).find("item").each(function() {
|
---|
| 148 | localStorage.setItem($(this).attr('key'), $(this).attr('value'));
|
---|
| 149 | });
|
---|
| 150 |
|
---|
| 151 | assignText();
|
---|
| 152 |
|
---|
| 153 | }, 'xml');
|
---|
| 154 |
|
---|
| 155 | } else { assignText(trial); }
|
---|
| 156 | } catch (e) { if(trial) notSupportedCookie(); else notSupported(); }
|
---|
| 157 | }
|
---|
| 158 |
|
---|
| 159 | function assignText(trial) {
|
---|
| 160 |
|
---|
| 161 | try {
|
---|
| 162 | $('.getTextFor').each(function() {
|
---|
| 163 |
|
---|
| 164 | var parts = parseAction($(this).attr('class'), " ");
|
---|
| 165 | var me = parts[1];
|
---|
| 166 |
|
---|
| 167 | // Process it's own inner text first
|
---|
| 168 | processEl($(this), 'innerText', me);
|
---|
| 169 |
|
---|
| 170 | if(parts.length >= 3 && parts[2] != '') { // Otherwise 'x y ' mucks it up
|
---|
| 171 |
|
---|
| 172 | // Affecting elements are listed
|
---|
| 173 | var affectees = parts[2];
|
---|
| 174 |
|
---|
| 175 | var all = affectees.split(',');
|
---|
| 176 |
|
---|
| 177 | for(var i = 0; i < all.length; i++) {
|
---|
| 178 | var parts = parseAction(all[i], ".");
|
---|
| 179 |
|
---|
| 180 | var append = false;
|
---|
| 181 | var isText = false;
|
---|
| 182 | var theText = '';
|
---|
| 183 |
|
---|
| 184 | if(parts[2].indexOf("[a]") != -1) {
|
---|
| 185 | parts[2] = parts[2].replace("[a]", "");
|
---|
| 186 | append = true;
|
---|
| 187 | }
|
---|
| 188 |
|
---|
| 189 | if(parts[2].indexOf("text:'") != -1) {
|
---|
| 190 | // This action is plain text
|
---|
| 191 | isText = true;
|
---|
| 192 | theText = parts[2].substring(6, parts[2].length - 1);
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | if(parts[0] == 'parent') {
|
---|
| 196 | // Affects the parent
|
---|
| 197 | processEl($(this).parent(), parts[1], parts[2], append, isText, theText);
|
---|
| 198 | } else if(parts[0] == 'this') {
|
---|
| 199 | // Affects this element
|
---|
| 200 | processEl($(this), parts[1], parts[2], append, isText, theText);
|
---|
| 201 | } else if(parts[0] == 'document') {
|
---|
| 202 | // Affects document itself
|
---|
| 203 | processEl(document, parts[1], parts[2], append, isText, theText);
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 |
|
---|
| 207 | }
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | // Process deferred elements now
|
---|
| 211 | for(var def in deferredEls) {
|
---|
| 212 | $(def).html(localStorage[deferredEls[def]]); //dict[deferredEls[def]]);
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | });
|
---|
| 216 |
|
---|
| 217 | var xsltClientCapable = document.cookie.indexOf('supportsXSLT') != -1;
|
---|
| 218 |
|
---|
| 219 | // At this point, the browser has proven itself capable of XSL transformations
|
---|
| 220 | // So, modify all document links into JavaScript links that use AJAX to get content
|
---|
| 221 | if(xsltClientCapable) {
|
---|
| 222 | // Could set cookie here too?
|
---|
| 223 | $('.clientDocView').each(function() {
|
---|
| 224 | var link = $(this).attr('href');
|
---|
| 225 | var startIndex = link.indexOf("&d=");
|
---|
| 226 | var endIndex = link.indexOf('&', startIndex + 7);
|
---|
| 227 | // If the endIndex == -1, end not found; just use end index
|
---|
| 228 | endIndex = (endIndex == -1) ? link.length : endIndex;
|
---|
| 229 | var docID = link.substring(startIndex, endIndex);
|
---|
| 230 | docID = docID.replace("&d=", "");
|
---|
| 231 | $(this).attr('id', docID);
|
---|
| 232 | $(this).attr('onclick', "getNodeContent(this); return false;"); // .bind doesn't work for dynamically added HTML!
|
---|
| 233 |
|
---|
| 234 | if(typeof initialHash != 'undefined') // Prevent errors when searching
|
---|
| 235 | if(docID == initialHash) {
|
---|
| 236 | // Load it!
|
---|
| 237 | getNodeContent($(this).get()[0]); // Talk about round the houses! This was the only way that produced something!
|
---|
| 238 | }
|
---|
| 239 | });
|
---|
| 240 |
|
---|
| 241 | document.cookie = 'supportsXSLT=true; expires=0; path=/';
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 | // Also undo escaping of necessary entities
|
---|
| 245 | $('body').each(function() {
|
---|
| 246 |
|
---|
| 247 | var text = $(this).html();
|
---|
| 248 | text = text.replace(/</g, "<");
|
---|
| 249 | text = text.replace(/>/g, ">");
|
---|
| 250 | text = text.replace(/&/g, "&");
|
---|
| 251 | $(this).html(text);
|
---|
| 252 |
|
---|
| 253 | });
|
---|
| 254 |
|
---|
| 255 | // Remove dead elements
|
---|
| 256 | $('[xmlns]').each(function() {
|
---|
| 257 | if($(this).get(0).tagName.toLowerCase() != "html") {
|
---|
| 258 | // use toLower() in case of browser inconsistencies
|
---|
| 259 | $(this).hide();
|
---|
| 260 | }
|
---|
| 261 | });
|
---|
| 262 |
|
---|
| 263 | //alert('Language is: ' + $('#language').html() + ', interface is: ' + $('#interface').html());
|
---|
| 264 |
|
---|
| 265 | $('#loading').fadeOut();
|
---|
| 266 |
|
---|
| 267 | } catch (e) { if(trial) notSupportedCookie(); else notSupported(); }
|
---|
| 268 |
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | function transform(trial) {
|
---|
| 272 |
|
---|
| 273 | try {
|
---|
| 274 | var queryStr = window.location.search.substring(1);
|
---|
| 275 | var rooturl = window.location;
|
---|
| 276 | //var absolute = gsurl;
|
---|
| 277 | var lead = queryStr == '' ? '?' : '&';
|
---|
| 278 | var skinurl = rooturl+lead+"o=skinandlibdoc";
|
---|
| 279 | var xmlurl = rooturl+lead+"o=xml";
|
---|
| 280 |
|
---|
| 281 | var skindoc = "";
|
---|
| 282 | var xmldoc = "";
|
---|
| 283 |
|
---|
| 284 | $.get(rooturl + lead + "o=clientside", function(data) {
|
---|
| 285 |
|
---|
| 286 | data = data.replace(/gs3:id/g, "gs3id");
|
---|
| 287 | data = parseFromString(data, "text/xml");
|
---|
| 288 |
|
---|
| 289 | // data contains the XML and the stylesheet too!
|
---|
| 290 | var skindoc = $(data).find("xslt\\:stylesheet")[0];
|
---|
| 291 | var xmldoc = $(data).find("page")[0];
|
---|
| 292 |
|
---|
| 293 | gsurl = $($(xmldoc).find("metadata[name=siteURL]")[0]).text();
|
---|
| 294 | gsweb = new RegExp($($(xmldoc).find("param[name=filepath]")[0]).text().replace(/\\/g, "\\\\"), "g");
|
---|
| 295 |
|
---|
| 296 | // Find xsl:include elements and update hrefs accordingly
|
---|
| 297 | $(skindoc).find("xsl\\:include").each(function() {
|
---|
| 298 | $(this).attr('href', $(this).attr('href').replace(gsweb, gsurl).replace(/\\/g, "/"));
|
---|
| 299 | });
|
---|
| 300 |
|
---|
| 301 | $(xmldoc).find("xsl\\:include").each(function() {
|
---|
| 302 | $(this).attr('href', $(this).attr('href').replace(gsweb, gsurl).replace(/\\/g, "/"));
|
---|
| 303 | });
|
---|
| 304 |
|
---|
| 305 | // Convert temporarily to text here
|
---|
| 306 | skindoc = convertToString(skindoc);
|
---|
| 307 | xmldoc = convertToString(xmldoc);
|
---|
| 308 |
|
---|
| 309 | // This could just be done on the server (later)
|
---|
| 310 | //data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" /*+ "<?xml-stylesheet type=\"text/xsl\" href=\"" + skinurl + "\"?>\r\n"*/ + data;
|
---|
| 311 | // replace all!
|
---|
| 312 | // Be careful with regex syntax and the use of special characters!
|
---|
| 313 | skindoc = skindoc.replace(/util\:exists\(\$meta, ''\)/g, "$meta!=''"); // For now - use regex instead
|
---|
| 314 | skindoc = skindoc.replace(/%3A/g, ":"); // undo colon escaping
|
---|
| 315 |
|
---|
| 316 | // Convert to XML
|
---|
| 317 | xmldoc = parseFromString(xmldoc, "text/xml");
|
---|
| 318 | skindoc = parseFromString(skindoc, "text/xml");
|
---|
| 319 |
|
---|
| 320 | var output = '';
|
---|
| 321 | var library_name = $('/page/xsltparams/param[name=library_name]', xmldoc).text();
|
---|
| 322 | var interface_name = $('/page/xsltparams/param[name=interface_name]', xmldoc).text();
|
---|
| 323 |
|
---|
| 324 | // And post-process...
|
---|
| 325 | if(window.ActiveXObject) {
|
---|
| 326 | // IE
|
---|
| 327 | var procFactory = new ActiveXObject("MSXML2.XSLTemplate");
|
---|
| 328 | procFactory.stylesheet = skindoc;
|
---|
| 329 | var proc = procFactory.createProcessor();
|
---|
| 330 | proc.input = xmldoc;
|
---|
| 331 |
|
---|
| 332 | proc.addParameter('library_name', library_name);
|
---|
| 333 | proc.addParameter('interface_name', interface_name);
|
---|
| 334 |
|
---|
| 335 | proc.transform();
|
---|
| 336 | output = proc.output;
|
---|
| 337 | } else {
|
---|
| 338 | // Fx
|
---|
| 339 | xsltProc = new XSLTProcessor();
|
---|
| 340 | // The leading slash is oh-so important here
|
---|
| 341 | xsltProc.setParameter(null, 'library_name', library_name);
|
---|
| 342 | xsltProc.setParameter(null, 'interface_name', interface_name);
|
---|
| 343 | xsltProc.importStylesheet(skindoc);
|
---|
| 344 | result = xsltProc.transformToDocument(xmldoc);
|
---|
| 345 | output = (new XMLSerializer()).serializeToString(result);
|
---|
| 346 | }
|
---|
| 347 |
|
---|
| 348 | //output = output.replace('var placeholder = false;', 'var placeholder = false; var xsltClientCapable = true;');
|
---|
| 349 |
|
---|
| 350 | var doc = document.open();
|
---|
| 351 | doc.write(output);
|
---|
| 352 | doc.close();
|
---|
| 353 |
|
---|
| 354 | document.cookie = 'supportsXSLT=true; expires=0; path=/';
|
---|
| 355 |
|
---|
| 356 | }, 'html');
|
---|
| 357 | } catch (e) { if(trial) notSupportedCookie(); else notSupported(); }
|
---|
| 358 | }
|
---|
| 359 |
|
---|
| 360 | function notSupportedCookie() {
|
---|
| 361 | document.cookie = 'supportsXSLT=false; expires=0; path=/';
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | function getNodeContent(node) {
|
---|
| 365 | var hash = $(node).attr('id');
|
---|
| 366 |
|
---|
| 367 | // Some document titles appear within spans, some do not, so these adjustments are necessary
|
---|
| 368 | $('.clientDocView').next().css('font-weight', 'normal');
|
---|
| 369 | $('.clientDocView').parent().css('font-weight', 'normal');
|
---|
| 370 | $(node).parent().css('font-weight', 'bold');
|
---|
| 371 | $(node).next().css('font-weight', 'bold');
|
---|
| 372 |
|
---|
| 373 | var loadingimg = '<img src="interfaces/default/images/loading.gif" alt="Loading" />';
|
---|
| 374 |
|
---|
| 375 | // Fetch me some fresh XML
|
---|
| 376 | $('.documenttext').html(loadingimg);
|
---|
| 377 | var url = $(node).attr('href') + "&o=xml";
|
---|
| 378 | url = url.replace('&', '&');
|
---|
| 379 | $.get(url, function(data) {
|
---|
| 380 |
|
---|
[23821] | 381 | gsurl = $($(data).find("metadata[name=siteURL]")[0]).text();
|
---|
| 382 |
|
---|
| 383 | $.get(gsurl + '/interfaces/default/transform/document_text.xsl', function(text) {
|
---|
[23786] | 384 |
|
---|
| 385 | var output = '';
|
---|
| 386 | var result = '';
|
---|
| 387 |
|
---|
| 388 | try {
|
---|
| 389 | // FF only
|
---|
| 390 | xsltProc = new XSLTProcessor();
|
---|
| 391 | // The leading slash is oh-so important here
|
---|
| 392 | xsltProc.setParameter(null, 'library_name', $('/page/xsltparams/param[name=library_name]', data).text());
|
---|
| 393 | xsltProc.setParameter(null, 'interface_name', $('/page/xsltparams/param[name=interface_name]', data).text());
|
---|
| 394 | xsltProc.importStylesheet(text);
|
---|
| 395 | result = xsltProc.transformToDocument(data);
|
---|
| 396 | output = (new XMLSerializer()).serializeToString(result);
|
---|
| 397 | } catch(e) { window.location = $(node).attr('href'); } // will naturally cascade to client-side, then if necessary, server-side
|
---|
| 398 |
|
---|
| 399 | // Get the book name
|
---|
| 400 | var book = $('#documentheading').text();
|
---|
| 401 | var title_arr = new Array();
|
---|
| 402 | var temp_arr = new Array();
|
---|
| 403 |
|
---|
| 404 | title_arr.push(book);
|
---|
| 405 |
|
---|
| 406 | // Go up the tree, until you reach the 'Table of Contents' node
|
---|
| 407 | $(node).parentsUntil('#tocstart').each(function() {
|
---|
| 408 | if($(this).get()[0].tagName == 'LI') {
|
---|
| 409 | // Only list elements...
|
---|
| 410 | // next child = a, next sibling = text node
|
---|
| 411 | temp_arr.push($(this).children('span').text());
|
---|
| 412 | }
|
---|
| 413 | });
|
---|
| 414 |
|
---|
| 415 | // Store these temporarily to reverse them and get it right
|
---|
| 416 | temp_arr = temp_arr.reverse();
|
---|
| 417 | title_arr = title_arr.concat(temp_arr);
|
---|
| 418 | document.title = title_arr.join('::');
|
---|
| 419 |
|
---|
| 420 | // Fix up entity encoding first
|
---|
| 421 | output = output.replace(/&/g, '&');
|
---|
| 422 | output = output.replace(/</g, '<');
|
---|
| 423 | output = output.replace(/>/g, '>');
|
---|
| 424 | $('.documenttext').html(output);
|
---|
| 425 |
|
---|
| 426 | }, 'xml');
|
---|
| 427 |
|
---|
| 428 | }, 'xml');
|
---|
| 429 | }
|
---|
| 430 |
|
---|
| 431 | function parseAction(str, chr) {
|
---|
| 432 |
|
---|
| 433 | // Problem with split - seems to discard the rest of string if it encounters splitable characters but doesn't split on them
|
---|
| 434 | // But, then all the split characters are missing from the array! So, need to slice the substring out.
|
---|
| 435 | // Get additional text
|
---|
| 436 | var parts = str.split(chr, 3);
|
---|
| 437 |
|
---|
| 438 | var trimIndex = parts[0].length + parts[1].length + 2;
|
---|
| 439 | parts[2] = str.substring(trimIndex);
|
---|
| 440 |
|
---|
| 441 | return parts;
|
---|
| 442 |
|
---|
| 443 | }
|
---|
| 444 |
|
---|
| 445 | // Method equivalent to PHP's in_array method
|
---|
| 446 | function contains(array, value) {
|
---|
| 447 |
|
---|
| 448 | for(var val in array)
|
---|
| 449 | if(array[val] == value)
|
---|
| 450 | return true;
|
---|
| 451 |
|
---|
| 452 | return false;
|
---|
| 453 | }
|
---|
| 454 |
|
---|
| 455 | // Method equivalent to PHP's own
|
---|
| 456 | function print_r(arr) {
|
---|
| 457 |
|
---|
| 458 | var result = "";
|
---|
| 459 |
|
---|
| 460 | for(var a in arr) {
|
---|
| 461 | result += a + " => " + arr[a] + "\r\n";
|
---|
| 462 | }
|
---|
| 463 |
|
---|
| 464 | return result;
|
---|
| 465 | }
|
---|
| 466 |
|
---|
| 467 | function convertToString(content) {
|
---|
| 468 | try {
|
---|
| 469 | // If this fails, it's another indication that the browser doesn't have the support we need
|
---|
| 470 | if(typeof XMLSerializer != 'undefined') {
|
---|
| 471 | return (new XMLSerializer()).serializeToString(content);
|
---|
| 472 | } else {
|
---|
| 473 | return content.xml;
|
---|
| 474 | }
|
---|
| 475 | } catch (e) { notSupported(); }
|
---|
| 476 | }
|
---|
| 477 |
|
---|
| 478 | function parseFromString(content, contentType) {
|
---|
| 479 | try {
|
---|
| 480 | var retobj;
|
---|
| 481 |
|
---|
| 482 | if(typeof window.DOMParser != 'undefined') {
|
---|
| 483 | // Fx
|
---|
| 484 | retobj = (new DOMParser()).parseFromString(content, contentType);
|
---|
| 485 | } else {
|
---|
| 486 | // IE
|
---|
| 487 | var retobj = new ActiveXObject("Microsoft.XMLDOM");
|
---|
| 488 | retobj.async = "false";
|
---|
| 489 | retobj.loadXML(content);
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | return retobj;
|
---|
| 493 | } catch(e) { var obj = new ActiveXObject('MSXML.DomDocument'); obj.async = false; obj.loadXML(content); return obj; }
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | function isSupported() {
|
---|
| 497 | // Are cookies enabled?
|
---|
| 498 | if(navigator.cookieEnabled && typeof navigator.cookieEnabled != 'undefined') {
|
---|
| 499 | // Is there a cookie?
|
---|
| 500 | if(document.cookie.indexOf('supportsXSLT=') > -1) {
|
---|
| 501 | // Cookie exists - don't try the transformation, as the server will
|
---|
| 502 | // read the cookie and determine which version to serve up.
|
---|
| 503 | // If it happens to be client-side, allow transformation to proceed
|
---|
| 504 | return (document.cookie.indexOf('supportsXSLT=true') > -1);
|
---|
| 505 | } else {
|
---|
| 506 | // Cookie doesn't exist - test!
|
---|
| 507 | transform(true);
|
---|
| 508 | applyText(true);
|
---|
| 509 | return (document.cookie.indexOf('supportsXSLT=true') > -1);
|
---|
| 510 | }
|
---|
| 511 | } else {
|
---|
| 512 | return false;
|
---|
| 513 | }
|
---|
| 514 | }
|
---|
| 515 |
|
---|
| 516 | /* Simulating web storage for browsers that don't support it */
|
---|
| 517 | /* Credit: http://www.thewojogroup.com/2010/01/simulating-html5-local-storage/ */
|
---|
| 518 | (function(){var k=this;if(!k.localStorage&&navigator.cookieEnabled){var x="storageData_",y="++",z="::",l=function(a,c,b){var e=new Date;e.setTime(e.getTime()+b);b="; expires="+e.toGMTString();document.cookie=a+"="+c+b+"; path=/"},h=function(a){a=a+"=";for(var c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];d.charAt(0)==" ";)d=d.substring(1,d.length);if(d.indexOf(a)===0)return d.substring(a.length,d.length)}return null},m=function(a){l(a,"",-1)},i=function(){for(var a="",c=0;h(y+c)!==null;)a+=h(y+
|
---|
| 519 | c++);return a==""?[]:a.split(y)},n=function(a){for(var c=Math.ceil(a.length/4E3),b=0;b<c||h(y+b)!==null;){b<c?l(y+b,a.substr(b*4E3,(b+1)*4E3>a.length?a.length-b*4E3:4E3),2592E3):m(y+b);b++}},f=k.localStorage={length:0,setItem:function(a,c){var b=i(),e=0,d=b.length,g=false;for(e=0;e<d;e++){var j=b[e].split(z);if(j[0]==a){j[1]=c;g=true;b[e]=j.join(z);e=d}}if(!g){b.push(a+z+c.replace(/::/g,": :").replace(/\+\+/g,"+ +"));this.a.push(a);this.length++}n(b.join(y))},
|
---|
| 520 | getItem:function(a){var c=i(),b=0,e=c.length;for(b=0;b<e;b++){var d=c[b].split(z);if(d[0]==a&&d[1])return d[1]}return null},removeItem:function(a){var c=i(),b=0,e=c.length,d=false,g=[];for(b=0;b<e;b++)if(c[b].split(z)[0]!=a)g.push(c[b]);else d=true;if(d){n(g.join(y));o()}},clear:function(){for(var a=0;h(y+a)!==null;)m(y+a++);this.a=[];this.length=0},key:function(a){return a<this.length?this.a[a]:null},a:[]},o=function(){f.a=i();for(var a=0;f.a[a];)f.a[a]=f.a[a++].split(z)[0];
|
---|
| 521 | f.length=f.a.length};o()}})(); |
---|