[Laszlo-checkins] r13233 - openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml

bargull@openlaszlo.org bargull at openlaszlo.org
Mon Mar 9 14:16:33 PDT 2009


Author: bargull
Date: 2009-03-09 14:16:30 -0700 (Mon, 09 Mar 2009)
New Revision: 13233

Modified:
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzHTTPLoader.js
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzXMLParser.js
Log:
Change 20090309-bargull-SSE by bargull at dell--p4--2-53 on 2009-03-09 20:14:50
    in /home/Admin/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: DHTML: handle invalid xml-files

New Features:

Bugs Fixed: LPP-7884 (DHTML: xml-parse errors don't send onerror-event)

Technical Reviewer: hminsky
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
LzXMLParser:
- added "getParserError()" to retrieve parser-error information from xml-document

LzHTTPLoader:
- wrap calls to XMLHttpRequest#open() and XMLHttpRequest#send() in try..catch to catch crossdomain exception
- handle parser-errors in "translateXML()"
    

Tests:
testcase from bugreport (FF3, Saf3, Opera9, IE6)
alldata (FF3)



Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzHTTPLoader.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzHTTPLoader.js	2009-03-09 20:04:30 UTC (rev 13232)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzHTTPLoader.js	2009-03-09 21:16:30 UTC (rev 13233)
@@ -1,7 +1,7 @@
 /**
   * LzHTTPLoader.js
   *
-  * @copyright Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.
+  * @copyright Copyright 2007-2009 Laszlo Systems, Inc.  All Rights Reserved.
   *            Use is subject to license terms.
   *
   * @topic Kernel
@@ -42,10 +42,17 @@
 
 /* Parse response into XML data. */ 
 LzHTTPLoader.prototype.translateXML = function () {
-    var lzxdata = null;
-    if (this.responseXML != null) {
+    var xml = this.responseXML;
+    if (xml == null || xml.childNodes.length == 0
+            || (lz.embed.browser.isFirefox && LzXMLParser.getParserError(xml) != null)) {
+        // in case of xml parser-errors:
+        // - Safari sets responseXML to null
+        // - IE, Opera don't generate childNodes
+        // - Firefox generates a <parsererror>-xml
+        this.loadError(this, null);
+    } else {
         var elt;
-        var nodes = this.responseXML.childNodes;
+        var nodes = xml.childNodes;
         // find first content (type == 1) child node
         for (var i = 0; i < nodes.length; i++) {
             var child = nodes.item(i);
@@ -54,12 +61,16 @@
                 break;
             }
         }
-        lzxdata = LzXMLTranslator.copyXML(elt,
-                                          this.options.trimwhitespace,
-                                          this.options.nsprefix);
+        if (elt != null) {
+            var lzxdata = LzXMLTranslator.copyXML(elt,
+                                                this.options.trimwhitespace,
+                                                this.options.nsprefix);
+            this.loadSuccess(this, lzxdata);
+        } else {
+            // no element-node?
+            this.loadError(this, null);
+        }
     }
-
-    this.loadSuccess(this, lzxdata);
 }
 
 /* Returns the response as a string  */
@@ -148,7 +159,7 @@
         }
         this.abort();
     }
-    
+
     {
         #pragma "passThrough=true" 
         this.req = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
@@ -157,7 +168,7 @@
     this.responseHeaders = null;
     this.responseText = null;
     this.responseXML = null;
-    
+
     this.__abort = false;
     this.__timeout = false;
     this.requesturl = url;
@@ -271,13 +282,13 @@
 LzHTTPLoader.prototype.__getAllResponseHeaders = function (xhr) {
     var re = new RegExp("^([-\\w]+):\\s*(\\S(?:.*\\S)?)\\s*$", "mg");
     var respheader = xhr.getAllResponseHeaders();
-    
+
     var allheaders = {};
     var header;
     while ((header = re.exec(respheader)) != null) {
         allheaders[header[1]] = header[2];
     }
-    
+
     return allheaders;
 }
 
@@ -300,7 +311,7 @@
                 } else {
                     self.removeTimeout(self);
                     self.req = null;
-                    
+
                     var status = -1;
                     try {
                         status = xhr.status;
@@ -308,19 +319,19 @@
                         //if you abort a request, readyState will be set to 4, 
                         //but reading status will result in an exception (at least in Firefox).
                     }
-                    
+
                     // only if "OK"
                     self.responseStatus = status;
                     if (status == 200 || status == 304) {
                         self.responseXML = xhr.responseXML;
                         self.responseText = xhr.responseText;
                         self.responseHeaders = self.__getAllResponseHeaders(xhr);
-                        
+
                         //DEBUGGING:
                         //var xmlSerializer = new XMLSerializer();
                         //var markup = xmlSerializer.serializeToString(self.responseXML);
                         //Debug.write("loadXMLDoc", markup);
-                        
+
                         // Callback with raw text string
                         self.loadContent(self, self.responseText);
                     } else {
@@ -329,8 +340,15 @@
                 }
             }
         };
-        
-        this.req.open(method, url, true);
+
+        try {
+            this.req.open(method, url, true);
+        } catch (e) {
+            // crossdomain error in Firefox, Safari
+            this.req = null;
+            this.loadError(this, null);
+            return;
+        }
         // If no content-type for POST was explicitly specified,
         // use "application/x-www-form-urlencoded"
         if ((method == "POST") && headers['content-type'] == null) {
@@ -338,8 +356,15 @@
         }
         this.__setRequestHeaders(this.req, headers);
         this.gstart = (new Date()).getTime();
-        this.req.send(postbody);
-        
+        try {
+            this.req.send(postbody);
+        } catch (e) {
+            // crossdomain error in Opera
+            this.req = null;
+            this.loadError(this, null);
+            return;
+        }
+
         // Set up the timeout
         if (isFinite(this.timeout)) {
             this.setupTimeout(this, this.timeout);

Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzXMLParser.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzXMLParser.js	2009-03-09 20:04:30 UTC (rev 13232)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzXMLParser.js	2009-03-09 21:16:30 UTC (rev 13233)
@@ -20,20 +20,28 @@
         var parser = new DOMParser();
         var doc = parser.parseFromString(str, "text/xml");
         // check for parser-errors
+        var err = this.getParserError(doc);
+        if (err) {
+            throw new Error(err);
+        } else {
+            return doc.firstChild;
+        }
+    },
+    getParserError: function (doc) {
+        // returns a String with parser-error information or undefined
         var browser = lz.embed.browser;
         if (browser.isIE) {
-            this.__checkIE(doc);
+            return this.__checkIE(doc);
         } else if (browser.isFirefox || browser.isOpera) {
-            this.__checkFirefox(doc);
+            return this.__checkFirefox(doc);
         } else if (browser.isSafari) {
-            this.__checkSafari(doc);
+            return this.__checkSafari(doc);
         }
-        return doc.firstChild;
     },
     __checkIE: function (doc) {
         var perr = doc.parseError;
         if (perr.errorCode != 0) {
-            throw new Error(perr.reason);
+            return (perr.reason);
         }
     },
     __checkFirefox: function (doc) {
@@ -42,7 +50,7 @@
             // get error information from textnode
             var msg = c.firstChild.nodeValue;
             // remove file and line information (does not provide useful info here)
-            throw new Error(msg.match(".*")[0]);
+            return (msg.match(".*")[0]);
         }
     },
     __checkSafari: function (doc) {
@@ -52,14 +60,14 @@
             // html > body > parsererror > div (with error information)
             var msg = c.firstChild.firstChild.childNodes[1].textContent;
             // remove file and line information (does not provide useful info here)
-            throw new Error(msg.match("[^:]*: (.*)")[1]);
+            return (msg.match("[^:]*: (.*)")[1]);
         } else {
             c = c.firstChild;
             if (c && c.nodeName == "parsererror") {
                 // second childNodes provides error information
                 var msg = c.childNodes[1].textContent;
                 // remove file and line information (does not provide useful info here)
-                throw new Error(msg.match("[^:]*: (.*)")[1]);
+                return (msg.match("[^:]*: (.*)")[1]);
             }
         }
     }



More information about the Laszlo-checkins mailing list