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