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 setRequirePathToScriptFile: function (filename) { 175 var scripts, reg, i, s, requirePath = ''; 176 177 if (requirePathLocation === filename) { 178 return; 179 } 180 181 scripts = document.getElementsByTagName('script'); 182 reg = new RegExp(filename + '(\\?.*)?$'); 183 184 for (i = 0; i < scripts.length; i++) { 185 s = scripts[i]; 186 if (s.src && s.src.match(reg)) { 187 requirePath = s.src.replace(reg, ''); 188 JXG.Load.requirePath = requirePath; 189 requirePathLocation = filename; 190 break; 191 } 192 } 193 }, 194 195 setRequirePathToHref: function () { 196 JXG.Load.requirePath = window.location.href; 197 requirePathLocation = 'href'; 198 }, 199 200 JSfiles: function (fileArray, preventCaching, root) { 201 var postfix = '', i, file; 202 203 preventCaching = preventCaching || false; 204 if (preventCaching) { 205 postfix = '?v=' + (new Date()).getTime(); 206 } 207 root = root || JXG.Load.requirePath; 208 if (root.substr(-1) !== '/') { 209 root += '/'; 210 } 211 212 for (i = 0; i < fileArray.length; i++) { 213 file = fileArray[i]; 214 215 if (file.substr(-2) !== 'js') { 216 file += '.js'; 217 } 218 (function (include) { 219 var src = root + include + postfix, 220 el, head; 221 if (JXG.isMetroApp() || !allowDocumentWrite) { 222 el = createHTMLElement('script', { 223 type: 'text/javascript', 224 src: src, 225 }); 226 head = document.getElementsByTagName('head')[0]; 227 head.appendChild(el); 228 } else { 229 // avoid inline code manipulation 230 document.write('<script type="text/javascript" src="' + src + '"><\/script>'); 231 } 232 }(file)); 233 } 234 }, 235 236 CSSfiles: function (fileArray, preventCaching, root) { 237 var postfix = '', i, file; 238 239 preventCaching = preventCaching || false; 240 if (preventCaching) { 241 postfix = '?v=' + (new Date()).getTime(); 242 } 243 root = root || JXG.Load.requirePath; 244 if (root.substr(-1) !== '/') { 245 root += '/'; 246 } 247 248 for (i = 0; i < fileArray.length; i++) { 249 file = fileArray[i]; 250 251 if (file.substr(-3) !== 'css') { 252 file += '.css'; 253 } 254 (function (include) { 255 var href = root + include + postfix, 256 el = createHTMLElement('link', { 257 rel: 'stylesheet', 258 type: 'text/javascript', 259 href: href, 260 }), 261 head = document.getElementsByTagName('head')[0]; 262 head.appendChild(el); 263 }(file)); 264 } 265 }, 266 267 HTMLfileASYNC: function (file, innerHTMLof, doAfter, preventCaching, root) { 268 var postfix = ''; 269 270 doAfter = doAfter || function () {}; 271 preventCaching = preventCaching || false; 272 if (preventCaching) { 273 postfix = '?v=' + (new Date()).getTime(); 274 } 275 root = root || JXG.Load.requirePath; 276 if (root.substr(-1) !== '/') { 277 root += '/'; 278 } 279 280 if (file.substr(-4) !== 'html') { 281 file += '.html'; 282 } 283 (function (include) { 284 var url = root + include + postfix; 285 286 var xhr = new XMLHttpRequest(); 287 xhr.onreadystatechange = function () { 288 if (xhr.readyState === 4) { 289 if (xhr.status === 200) { 290 innerHTMLof.innerHTML = xhr.responseText; 291 doAfter(); 292 } 293 } 294 }; 295 296 xhr.open('POST', url, true); 297 xhr.send(); 298 }(file)); 299 } 300 }; 301 })(); 302 303 //////////////////////////////////////////////////////////////////////////////// 304 ///////////////////////////////////// end ////////////////////////////////////// 305 //////////////////////////////////////////////////////////////////////////////// 306 307 // Has to be a String for Makefile! 308 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/threed,3d/view3d,3d/point3d,3d/curve3d,3d/surface3d,3d/linspace3d,3d/box3d'; 309 JXG.Load.setRequirePathToScriptFile('loadjsxgraph.js'); 310 JXG.Load.JSfiles(JXG.Load.baseFiles.split(','), preventCachingFiles); 311 JXG.Load.baseFiles = null; 312 JXG.serverBase = JXG.Load.requirePath + 'server/'; 313 314 // This is a table with functions which check the availability 315 // of certain namespaces, functions and classes. With this structure 316 // we are able to get a rough check if a specific dependency is available. 317 table = { 318 'jsxgraph': checkJXG, 319 'jxg': checkJXG, 320 'options': makeCheck('Options'), 321 322 'base/board': makeCheck('Board'), 323 'base/chart': checkJXG, 324 'base/circle': checkJXG, 325 'base/composition': makeCheck('Composition'), 326 'base/constants': checkJXG, 327 'base/coords': makeCheck('Coords'), 328 'base/coordselement': makeCheck('CoordsElement'), 329 'base/curve': checkJXG, 330 'base/element': makeCheck('GeometryElement'), 331 'base/group': checkJXG, 332 'base/image': checkJXG, 333 'base/line': checkJXG, 334 'base/point': checkJXG, 335 'base/polygon': checkJXG, 336 'base/text': checkJXG, 337 'base/ticks': checkJXG, 338 'base/transformation': checkJXG, 339 'base/turtle': checkJXG, 340 341 'element/arc': checkJXG, 342 'element/centroid': checkJXG, 343 'element/composition': checkJXG, 344 'element/conic': checkJXG, 345 'element/locus': checkJXG, 346 'element/measure': checkJXG, 347 'element/sector': checkJXG, 348 'element/slider': checkJXG, 349 'element/square': checkJXG, 350 'element/triangle': checkJXG, 351 'element/checkbox': checkJXG, 352 'element/input': checkJXG, 353 'element/button': checkJXG, 354 'element/foreignobject': checkJXG, 355 356 'math/bst': makeCheck('Math.BST'), 357 'math/qdt': makeCheck('Math.Quadtree'), 358 'math/complex': makeCheck('Complex'), 359 'math/geometry': makeCheck('Math.Geometry'), 360 'math/math': makeCheck('Math'), 361 'math/probfuncs': makeCheck('Math.ProbFuncs'), 362 'math/ia': makeCheck('Math.IntervalArithmetic'), 363 'math/extrapolate': makeCheck('Math.Extrapolate'), 364 'math/metapost': makeCheck('Math.Metapost'), 365 'math/numerics': makeCheck('Math.Numerics'), 366 'math/nlp': makeCheck('Math.Nlp'), 367 'math/plot': makeCheck('Math.Plot'), 368 'math/poly': makeCheck('Math.Poly'), 369 'math/statistics': makeCheck('Math.Statistics'), 370 'math/symbolic': makeCheck('Math.Symbolic'), 371 372 'parser/datasource': makeCheck('DataSource'), 373 'parser/geonext': makeCheck('GeonextParser'), 374 'parser/ca': makeCheck('CA'), 375 'parser/jessiecode': makeCheck('JessieCode'), 376 377 'reader/cinderella': makeCheck('CinderellaReader'), 378 'reader/file': makeCheck('FileReader'), 379 'reader/geogebra': makeCheck('GeogebraReader'), 380 'reader/geonext': makeCheck('GeonextReader'), 381 'reader/graph': makeCheck('GraphReader'), 382 'reader/intergeo': makeCheck('IntergeoReader'), 383 'reader/sketch': makeCheck('SketchReader'), 384 'reader/tracenpoche': makeCheck('TracenpocheReader'), 385 386 'renderer/abstract': makeCheck('AbstractRenderer'), 387 'renderer/canvas': makeCheck('CanvasRenderer'), 388 'renderer/no': makeCheck('NoRenderer'), 389 'renderer/svg': makeCheck('SVGRenderer'), 390 'renderer/vml': makeCheck('VMLRenderer'), 391 392 'server/server': makeCheck('Server'), 393 394 'utils/base64': makeCheck('Util.Base64'), 395 'utils/color': checkJXG, 396 'utils/dump': makeCheck('Dump'), 397 'utils/encoding': makeCheck('Util.UTF8'), 398 'utils/env': checkJXG, 399 'utils/event': makeCheck('EventEmitter'), 400 'utils/expect': makeCheck('Expect'), 401 'utils/type': checkJXG, 402 'utils/uuid': makeCheck('Util'), 403 'utils/xml': makeCheck('XML'), 404 'utils/zip': makeCheck('Util'), 405 406 '3d/threed': checkJXG, 407 '3d/view3d': checkJXG, 408 '3d/point3d': checkJXG, 409 '3d/curve3d': checkJXG, 410 '3d/surface3d': checkJXG, 411 '3d/linspace3d': checkJXG 412 413 }; 414 }()); 415