1 /* 2 Copyright 2008-2022 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Andreas Walter, 8 Alfred Wassermann, 9 Peter Wilfahrt 10 11 This file is part of JSXGraph. 12 13 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 14 15 You can redistribute it and/or modify it under the terms of the 16 17 * GNU Lesser General Public License as published by 18 the Free Software Foundation, either version 3 of the License, or 19 (at your option) any later version 20 OR 21 * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT 22 23 JSXGraph is distributed in the hope that it will be useful, 24 but WITHOUT ANY WARRANTY; without even the implied warranty of 25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 GNU Lesser General Public License for more details. 27 28 You should have received a copy of the GNU Lesser General Public License and 29 the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/> 30 and <http://opensource.org/licenses/MIT/>. 31 */ 32 33 /*global JXG: true, document: true*/ 34 /*jslint nomen: true, plusplus: true, regexp: true*/ 35 36 /** 37 * JSXGraph namespace. Holds all classes, objects, functions and variables belonging to JSXGraph 38 * to reduce the risk of interfering with other JavaScript code. 39 * @namespace 40 */ 41 var JXG = {}, 42 define; 43 44 (function () { 45 "use strict"; 46 47 ////////////////////////////////////////////////////////////////////////// 48 //// Set this constant to 'true' to add an timestamp to each imported //// 49 //// file. This ensures that the most up-to-date files are always //// 50 //// used during development. //// 51 //// //// 52 //// Attention! Slows down the loading time! //// 53 ////////////////////////////////////////////////////////////////////////// 54 var preventCachingFiles = true, 55 // check and table are initialized at the end of the life 56 table, 57 waitlist = [], 58 checkwaitlist = true, 59 checkJXG = function () { 60 return JXG; 61 }, 62 makeCheck = function (s) { 63 var a = s.split("."); 64 65 return function () { 66 var i, 67 r = JXG; 68 69 if (!r) { 70 return r; 71 } 72 73 for (i = 0; i < a.length; i++) { 74 r = r[a[i]]; 75 if (!r) { 76 break; 77 } 78 } 79 80 return r; 81 }; 82 }; 83 84 define = function (deps, factory) { 85 var i, 86 oldlength, 87 undef, 88 resDeps = [], 89 inc = true; 90 91 if (deps === undef) { 92 deps = []; 93 } 94 95 window.wait = waitlist; 96 97 if (factory === undef) { 98 factory = function () {}; 99 } 100 101 for (i = 0; i < deps.length; i++) { 102 resDeps.push(table[deps[i]]()); 103 if (!resDeps[i]) { 104 inc = false; 105 break; 106 } 107 } 108 109 if (inc) { 110 factory.apply(this, resDeps); 111 } else if (checkwaitlist) { 112 waitlist.push([deps, factory]); 113 } 114 115 if (checkwaitlist) { 116 // don't go through the waitlist while we're going through the waitlist 117 checkwaitlist = false; 118 oldlength = 0; 119 120 // go through the waitlist until no more modules can be loaded 121 while (oldlength !== waitlist.length) { 122 oldlength = waitlist.length; 123 124 // go through the waitlist, look if another module can be initialized 125 for (i = 0; i < waitlist.length; i++) { 126 if (define.apply(this, waitlist[i])) { 127 waitlist.splice(i, 1); 128 } 129 } 130 } 131 132 checkwaitlist = true; 133 } 134 135 return inc; 136 }; 137 138 JXG.isMetroApp = function () { 139 return ( 140 typeof window === "object" && 141 window.clientInformation && 142 window.clientInformation.appVersion && 143 window.clientInformation.appVersion.indexOf("MSAppHost") > -1 144 ); 145 }; 146 147 //////////////////////////////////////////////////////////////////////////////// 148 /////////////////////// this exists also in sketchometry /////////////////////// 149 //////////////////////////////////////////////////////////////////////////////// 150 151 JXG.Load = (function () { 152 var requirePathLocation = "href", 153 allowDocumentWrite = true; 154 155 function createHTMLElement(tagName, attr) { 156 var el = document.createElement(tagName), 157 i, 158 a_name, 159 a_value, 160 a_object; 161 162 for (i = 0; i < Object.keys(attr).length; i++) { 163 a_name = Object.keys(attr)[i]; 164 a_value = attr[a_name]; 165 166 a_object = document.createAttribute(a_name); 167 a_object.nodeValue = a_value; 168 el.setAttributeNode(a_object); 169 } 170 171 return el; 172 } 173 174 window.onload = function () { 175 allowDocumentWrite = false; 176 }; 177 178 return { 179 requirePath: window.location.href, 180 181 getPathOfScriptFile: function (filename) { 182 var scripts, 183 reg, 184 i, 185 s, 186 requirePath = ""; 187 188 scripts = document.getElementsByTagName("script"); 189 reg = new RegExp(filename + "(\\?.*)?$"); 190 191 for (i = 0; i < scripts.length; i++) { 192 s = scripts[i]; 193 if (s.src && s.src.match(reg)) { 194 requirePath = s.src.replace(reg, ""); 195 break; 196 } 197 } 198 199 return requirePath; 200 }, 201 202 setRequirePathToScriptFile: function (filename) { 203 if (requirePathLocation === filename) { 204 return; 205 } 206 207 JXG.Load.requirePath = JXG.Load.getPathOfScriptFile(filename); 208 requirePathLocation = filename; 209 }, 210 211 setRequirePathToHref: function () { 212 JXG.Load.requirePath = window.location.href; 213 requirePathLocation = "href"; 214 }, 215 216 JSfiles: function (fileArray, preventCaching, root, strictOrder) { 217 var postfix = "", 218 i, 219 file; 220 221 preventCaching = preventCaching || false; 222 if (preventCaching) { 223 postfix = "?v=" + new Date().getTime(); 224 } 225 root = root || JXG.Load.requirePath; 226 if (root.substr(-1) !== "/") { 227 root += "/"; 228 } 229 strictOrder = strictOrder || false; 230 231 for (i = 0; i < fileArray.length; i++) { 232 file = fileArray[i]; 233 234 if (file.substr(-2) !== "js") { 235 file += ".js"; 236 } 237 (function (include) { 238 var src = root + include + postfix, 239 el, 240 head; 241 if (JXG.isMetroApp() || !allowDocumentWrite) { 242 el = createHTMLElement("script", { 243 type: "text/javascript", 244 src: src 245 }); 246 if(strictOrder) { 247 el.defer = true; 248 el.async = false; 249 } 250 head = document.getElementsByTagName("head")[0]; 251 head.appendChild(el); 252 } else { 253 // avoid inline code manipulation 254 document.write( 255 '<script type="text/javascript" src="' + src + '"></script>' 256 ); 257 } 258 })(file); 259 } 260 }, 261 262 CSSfiles: function (fileArray, preventCaching, root) { 263 var postfix = "", 264 i, 265 file; 266 267 preventCaching = preventCaching || false; 268 if (preventCaching) { 269 postfix = "?v=" + new Date().getTime(); 270 } 271 root = root || JXG.Load.requirePath; 272 if (root.substr(-1) !== "/") { 273 root += "/"; 274 } 275 276 for (i = 0; i < fileArray.length; i++) { 277 file = fileArray[i]; 278 279 if (file.substr(-3) !== "css") { 280 file += ".css"; 281 } 282 (function (include) { 283 var href = root + include + postfix, 284 el = createHTMLElement("link", { 285 rel: "stylesheet", 286 type: "text/javascript", 287 href: href, 288 }), 289 head = document.getElementsByTagName("head")[0]; 290 head.appendChild(el); 291 })(file); 292 } 293 }, 294 295 HTMLfileASYNC: function ( 296 file, 297 innerHTMLof, 298 doAfter, 299 preventCaching, 300 root 301 ) { 302 var postfix = ""; 303 304 doAfter = doAfter || function () {}; 305 preventCaching = preventCaching || false; 306 if (preventCaching) { 307 postfix = "?v=" + new Date().getTime(); 308 } 309 root = root || JXG.Load.requirePath; 310 if (root.substr(-1) !== "/") { 311 root += "/"; 312 } 313 314 if (file.substr(-4) !== "html") { 315 file += ".html"; 316 } 317 (function (include) { 318 var url = root + include + postfix; 319 320 var xhr = new XMLHttpRequest(); 321 xhr.onreadystatechange = function () { 322 if (xhr.readyState === 4) { 323 if (xhr.status === 200) { 324 innerHTMLof.innerHTML = xhr.responseText; 325 doAfter(); 326 } 327 } 328 }; 329 330 xhr.open("POST", url, true); 331 xhr.send(); 332 })(file); 333 }, 334 }; 335 })(); 336 337 //////////////////////////////////////////////////////////////////////////////// 338 ///////////////////////////////////// end ////////////////////////////////////// 339 //////////////////////////////////////////////////////////////////////////////// 340 341 // Has to be a String for Makefile! 342 JXG.Load.baseFiles = 'jxg,base/constants,utils/type,utils/xml,utils/env,utils/event,utils/expect,utils/color,math/probfuncs,math/math,math/ia,math/extrapolate,math/numerics,math/nlp,math/plot,math/metapost,math/statistics,math/symbolic,math/geometry,math/clip,math/poly,math/complex,renderer/abstract,renderer/no,reader/file,parser/geonext,base/board,options,jsxgraph,base/element,base/coordselement,base/coords,base/point,base/line,base/group,base/circle,element/conic,base/polygon,base/curve,element/arc,element/sector,base/composition,element/composition,base/text,base/image,element/slider,element/measure,base/chart,base/transformation,base/turtle,base/ticks,utils/zip,utils/base64,utils/uuid,utils/encoding,server/server,element/locus,parser/datasource,parser/ca,parser/jessiecode,utils/dump,renderer/svg,renderer/vml,renderer/canvas,renderer/no,element/comb,element/slopetriangle,math/qdt,element/checkbox,element/input,element/button,base/foreignobject,options3d,3d/view3d,3d/element3d,3d/point3d,3d/curve3d,3d/surface3d,3d/linspace3d,3d/box3d'; 343 JXG.Load.setRequirePathToScriptFile("loadjsxgraph.js"); 344 JXG.Load.JSfiles(JXG.Load.baseFiles.split(","), preventCachingFiles); 345 JXG.Load.baseFiles = null; 346 JXG.serverBase = JXG.Load.requirePath + "server/"; 347 348 // This is a table with functions which check the availability 349 // of certain namespaces, functions and classes. With this structure 350 // we are able to get a rough check if a specific dependency is available. 351 table = { 352 jsxgraph: checkJXG, 353 jxg: checkJXG, 354 options: makeCheck("Options"), 355 356 "base/board": makeCheck("Board"), 357 "base/chart": checkJXG, 358 "base/circle": checkJXG, 359 "base/composition": makeCheck("Composition"), 360 "base/constants": checkJXG, 361 "base/coords": makeCheck("Coords"), 362 "base/coordselement": makeCheck("CoordsElement"), 363 "base/curve": checkJXG, 364 "base/element": makeCheck("GeometryElement"), 365 "base/group": checkJXG, 366 "base/image": checkJXG, 367 "base/line": checkJXG, 368 "base/point": checkJXG, 369 "base/polygon": checkJXG, 370 "base/text": checkJXG, 371 "base/ticks": checkJXG, 372 "base/transformation": checkJXG, 373 "base/turtle": checkJXG, 374 375 "element/arc": checkJXG, 376 "element/centroid": checkJXG, 377 "element/composition": checkJXG, 378 "element/conic": checkJXG, 379 "element/locus": checkJXG, 380 "element/measure": checkJXG, 381 "element/sector": checkJXG, 382 "element/slider": checkJXG, 383 "element/square": checkJXG, 384 "element/triangle": checkJXG, 385 "element/checkbox": checkJXG, 386 "element/input": checkJXG, 387 "element/button": checkJXG, 388 "element/foreignobject": checkJXG, 389 390 "math/bst": makeCheck("Math.BST"), 391 "math/qdt": makeCheck("Math.Quadtree"), 392 "math/complex": makeCheck("Complex"), 393 "math/geometry": makeCheck("Math.Geometry"), 394 "math/math": makeCheck("Math"), 395 "math/probfuncs": makeCheck("Math.ProbFuncs"), 396 "math/ia": makeCheck("Math.IntervalArithmetic"), 397 "math/extrapolate": makeCheck("Math.Extrapolate"), 398 "math/metapost": makeCheck("Math.Metapost"), 399 "math/numerics": makeCheck("Math.Numerics"), 400 "math/nlp": makeCheck("Math.Nlp"), 401 "math/plot": makeCheck("Math.Plot"), 402 "math/poly": makeCheck("Math.Poly"), 403 "math/statistics": makeCheck("Math.Statistics"), 404 "math/symbolic": makeCheck("Math.Symbolic"), 405 406 "parser/datasource": makeCheck("DataSource"), 407 "parser/geonext": makeCheck("GeonextParser"), 408 "parser/ca": makeCheck("CA"), 409 "parser/jessiecode": makeCheck("JessieCode"), 410 411 "reader/cinderella": makeCheck("CinderellaReader"), 412 "reader/file": makeCheck("FileReader"), 413 "reader/geogebra": makeCheck("GeogebraReader"), 414 "reader/geonext": makeCheck("GeonextReader"), 415 "reader/graph": makeCheck("GraphReader"), 416 "reader/intergeo": makeCheck("IntergeoReader"), 417 "reader/sketch": makeCheck("SketchReader"), 418 "reader/tracenpoche": makeCheck("TracenpocheReader"), 419 420 "renderer/abstract": makeCheck("AbstractRenderer"), 421 "renderer/canvas": makeCheck("CanvasRenderer"), 422 "renderer/no": makeCheck("NoRenderer"), 423 "renderer/svg": makeCheck("SVGRenderer"), 424 "renderer/vml": makeCheck("VMLRenderer"), 425 426 "server/server": makeCheck("Server"), 427 428 "utils/base64": makeCheck("Util.Base64"), 429 "utils/color": checkJXG, 430 "utils/dump": makeCheck("Dump"), 431 "utils/encoding": makeCheck("Util.UTF8"), 432 "utils/env": checkJXG, 433 "utils/event": makeCheck("EventEmitter"), 434 "utils/expect": makeCheck("Expect"), 435 "utils/type": checkJXG, 436 "utils/uuid": makeCheck("Util"), 437 "utils/xml": makeCheck("XML"), 438 "utils/zip": makeCheck("Util"), 439 440 "3d/threed": checkJXG, 441 "3d/view3d": checkJXG, 442 "3d/point3d": checkJXG, 443 "3d/curve3d": checkJXG, 444 "3d/surface3d": checkJXG, 445 "3d/linspace3d": checkJXG, 446 }; 447 })(); 448