1 /* 2 Copyright 2008, 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software: you can redistribute it and/or modify 13 it under the terms of the GNU Lesser General Public License as published by 14 the Free Software Foundation, either version 3 of the License, or 15 (at your option) any later version. 16 17 JSXGraph is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU Lesser General Public License for more details. 21 22 You should have received a copy of the GNU Lesser General Public License 23 along with JSXGraph. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 26 JXG.FileReader = new function() { 27 28 this.parseFileContent = function(url, board, format) { 29 this.request = false; 30 var e; 31 try { 32 //this.request = new ActiveXObject("Msxml2.XMLHTTP"); 33 this.request = new XMLHttpRequest(); 34 if(format.toLowerCase()=='raw') 35 this.request.overrideMimeType('text/plain; charset=iso-8859-1'); 36 else 37 this.request.overrideMimeType('text/xml; charset=iso-8859-1'); 38 } catch (e) { 39 try { 40 this.request = new ActiveXObject("Msxml2.XMLHTTP"); 41 } catch (e) { 42 try { 43 this.request = new ActiveXObject("Microsoft.XMLHTTP"); 44 } catch (e) { 45 this.request = false; 46 } 47 } 48 } 49 if (!this.request) { 50 alert("AJAX not activated!"); 51 return; 52 } 53 this.request.open("GET", url, true); 54 if(format.toLowerCase()=='raw') { 55 this.cbp = function() { 56 var request = this.request; 57 if (request.readyState == 4) { 58 board(request.responseText); 59 } 60 }; //).bind(this); 61 } else { 62 this.cbp = function() { 63 var request = this.request; 64 if (request.readyState == 4) { 65 var text = ''; 66 67 if (typeof request.responseStream!='undefined' && 68 (request.responseText.slice(0,2) == "PK" // ZIP -> Geogebra 69 || JXG.Util.asciiCharCodeAt(request.responseText.slice(0,1),0)==31) // gzip -> Cinderella 70 ) { 71 //text = (new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(BinFileReader(request)))).unzip(); 72 //text = text[0][0]; 73 //text = BinFileReader(request); 74 text = JXG.Util.Base64.decode(BinFileReader(request)); // After this, text contains the base64 encoded, zip-compressed string 75 } else { 76 text = request.responseText; 77 } 78 this.parseString(text, board, format, false); 79 } 80 }; //).bind(this); 81 } 82 this.cb = JXG.bind(this.cbp,this); 83 this.request.onreadystatechange = this.cb; 84 85 try { 86 this.request.send(null); 87 } catch (e) { 88 throw new Error("JSXGraph: problems opening " + url + " !"); 89 } 90 }; // end: this.parseFileContent 91 92 this.cleanWhitespace = function(el) { 93 var cur = el.firstChild; 94 while ( cur != null ) { 95 if ( cur.nodeType == 3 && ! /\S/.test(cur.nodeValue) ) { 96 el.removeChild( cur ); 97 } else if ( cur.nodeType == 1 ) { 98 this.cleanWhitespace( cur ); 99 } 100 cur = cur.nextSibling; 101 } 102 }; 103 104 this.stringToXMLTree = function(fileStr) { 105 // The string "fileStr" is converted into a XML tree. 106 if(typeof DOMParser == "undefined") { 107 // IE workaround, since there is no DOMParser 108 DOMParser = function () {}; 109 DOMParser.prototype.parseFromString = function (str, contentType) { 110 if (typeof ActiveXObject != "undefined") { 111 var d = new ActiveXObject("MSXML.DomDocument"); 112 d.loadXML(str); 113 return d; 114 } 115 }; 116 } 117 var parser=new DOMParser(); 118 119 var tree = parser.parseFromString(fileStr,"text/xml"); 120 this.cleanWhitespace(tree); 121 return tree; 122 }; 123 124 this.parseString = function(fileStr, board, format, isString) { 125 var tree, graph; 126 127 if (format.toLowerCase()=='cdy' || format.toLowerCase()=='cinderella') { 128 // if isString is true, fileStr is the base64 encoded zip file, otherwise it's just the zip file 129 if(isString) 130 fileStr = JXG.Util.Base64.decode(fileStr); 131 fileStr = JXG.CinderellaReader.readCinderella(fileStr, board); 132 board.xmlString = fileStr; 133 return; 134 } 135 if (format.toLowerCase()=='graph') { 136 //if(isString) 137 fileStr = JXG.GraphReader.readGraph(fileStr, board, false); 138 return; 139 } 140 if (format.toLowerCase()=='digraph') { 141 //if(isString) 142 fileStr = JXG.GraphReader.readGraph(fileStr, board, true); 143 return; 144 } 145 146 // fileStr is a string containing the XML code of the construction 147 if (format.toLowerCase()=='geonext') { 148 fileStr = JXG.GeonextReader.prepareString(fileStr); 149 } 150 if (format.toLowerCase()=='geogebra') { 151 isString = fileStr.slice(0, 2) !== "PK"; 152 153 // if isString is true, fileStr is a base64 encoded string, otherwise it's the zipped file 154 fileStr = JXG.GeogebraReader.prepareString(fileStr, isString); 155 } 156 if (format.toLowerCase()=='intergeo') { 157 if(isString) 158 fileStr = JXG.Util.Base64.decode(fileStr); 159 fileStr = JXG.IntergeoReader.prepareString(fileStr); 160 } 161 162 board.xmlString = fileStr; 163 tree = this.stringToXMLTree(fileStr); 164 // Now, we can walk through the tree 165 this.readElements(tree, board, format); 166 }; // end this.parse 167 168 /** 169 * Reading the elements of a geonext or geogebra file 170 * @param {} tree expects the content of the parsed geonext file returned by function parseFromString 171 * @param {Object} board board object 172 */ 173 this.readElements = function(tree, board, format) { 174 if (format.toLowerCase()=='geonext') { 175 board.suspendUpdate(); 176 if(tree.getElementsByTagName('GEONEXT').length != 0) { 177 JXG.GeonextReader.readGeonext(tree, board); 178 } 179 board.unsuspendUpdate(); 180 } 181 else if(tree.getElementsByTagName('geogebra').length != 0) { 182 JXG.GeogebraReader.readGeogebra(tree, board); 183 } 184 else if(format.toLowerCase()=='intergeo') { 185 JXG.IntergeoReader.readIntergeo(tree, board); 186 } 187 // cdy is already parsed in parseString() 188 }; // end: this.readElements() 189 190 }; // end: FileReader() 191 192 if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { 193 document.write('<script type="text/vbscript">\n\ 194 Function Base64Encode(inData)\n\ 195 Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"\n\ 196 Dim cOut, sOut, I\n\ 197 For I = 1 To LenB(inData) Step 3\n\ 198 Dim nGroup, pOut, sGroup\n\ 199 nGroup = &H10000 * AscB(MidB(inData, I, 1)) + _\n\ 200 &H100 * MyASC(MidB(inData, I + 1, 1)) + MyASC(MidB(inData, I + 2, 1))\n\ 201 nGroup = Oct(nGroup)\n\ 202 nGroup = String(8 - Len(nGroup), "0") & nGroup\n\ 203 pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) + _\n\ 204 Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) + _\n\ 205 Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) + _\n\ 206 Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1)\n\ 207 sOut = sOut + pOut\n\ 208 Next\n\ 209 Select Case LenB(inData) Mod 3\n\ 210 Case 1: \'8 bit final\n\ 211 sOut = Left(sOut, Len(sOut) - 2) + "=="\n\ 212 Case 2: \'16 bit final\n\ 213 sOut = Left(sOut, Len(sOut) - 1) + "="\n\ 214 End Select\n\ 215 Base64Encode = sOut\n\ 216 End Function\n\ 217 \n\ 218 Function MyASC(OneChar)\n\ 219 If OneChar = "" Then MyASC = 0 Else MyASC = AscB(OneChar)\n\ 220 End Function\n\ 221 \n\ 222 Function BinFileReader(xhr)\n\ 223 Dim byteString\n\ 224 Dim b64String\n\ 225 Dim i\n\ 226 byteString = xhr.responseBody\n\ 227 ReDim byteArray(LenB(byteString))\n\ 228 For i = 1 To LenB(byteString)\n\ 229 byteArray(i-1) = AscB(MidB(byteString, i, 1))\n\ 230 Next\n\ 231 b64String = Base64Encode(byteString)\n\ 232 BinFileReader = b64String\n\ 233 End Function\n\ 234 </script>\n'); 235 } 236