1 /*
  2     Copyright 2008-2016
  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 dual licensed under the GNU LGPL or MIT License.
 13 
 14     You can redistribute it and/or modify it under the terms of the
 15 
 16       * GNU Lesser General Public License as published by
 17         the Free Software Foundation, either version 3 of the License, or
 18         (at your option) any later version
 19       OR
 20       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
 21 
 22     JSXGraph is distributed in the hope that it will be useful,
 23     but WITHOUT ANY WARRANTY; without even the implied warranty of
 24     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25     GNU Lesser General Public License for more details.
 26 
 27     You should have received a copy of the GNU Lesser General Public License and
 28     the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
 29     and <http://opensource.org/licenses/MIT/>.
 30  */
 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     // check and table are initialized at the end of the iife
 52     var i, s, n, arr, table,
 53         waitlist = [],
 54         checkwaitlist = true,
 55         checkJXG = function () {
 56             return JXG;
 57         },
 58         makeCheck = function (s) {
 59             var a = s.split('.');
 60 
 61             return function () {
 62                 var i, r = JXG;
 63 
 64                 if (!r) {
 65                     return r;
 66                 }
 67 
 68                 for (i = 0; i < a.length; i++) {
 69                     r = r[a[i]];
 70                     if (!r) {
 71                         break;
 72                     }
 73                 }
 74 
 75                 return r;
 76             };
 77         };
 78 
 79     define = function (deps, factory) {
 80         var i, oldlength, undef,
 81             resDeps = [],
 82             inc = true;
 83 
 84         if (deps === undef) {
 85             deps = [];
 86         }
 87 
 88         window.wait = waitlist;
 89 
 90         if (factory === undef) {
 91             factory = function () {};
 92         }
 93 
 94         for (i = 0; i < deps.length; i++) {
 95             resDeps.push(table[deps[i]]());
 96             if (!resDeps[i]) {
 97                 inc = false;
 98                 break;
 99             }
100         }
101 
102         if (inc) {
103             factory.apply(this, resDeps);
104         } else if (checkwaitlist) {
105             waitlist.push([deps, factory]);
106         }
107 
108         if (checkwaitlist) {
109             // don't go through the waitlist while we're going through the waitlist
110             checkwaitlist = false;
111             oldlength = 0;
112 
113             // go through the waitlist until no more modules can be loaded
114             while (oldlength !== waitlist.length) {
115                 oldlength = waitlist.length;
116 
117                 // go through the waitlist, look if another module can be initialized
118                 for (i = 0; i < waitlist.length; i++) {
119                     if (define.apply(this, waitlist[i])) {
120                         waitlist.splice(i, 1);
121                     }
122                 }
123             }
124 
125             checkwaitlist = true;
126         }
127 
128         return inc;
129     };
130 
131     JXG.isMetroApp = function () {
132         return typeof window === 'object' && window.clientInformation && window.clientInformation.appVersion && window.clientInformation.appVersion.indexOf('MSAppHost') > -1;
133     };
134 
135     JXG.require = function (libraryName) {
136        if (JXG.isMetroApp()) { // avoid inline code manipulation in Windows apps -- isMetroApp can't be used it is not yet available at this point
137             var scriptElement = document.createElement("script");
138             var typeAttribute = document.createAttribute("type");
139             typeAttribute.nodeValue = "text/javascript";
140             var srcAttribute = document.createAttribute("src");
141             srcAttribute.nodeValue = libraryName;
142             scriptElement.setAttributeNode(typeAttribute);
143             scriptElement.setAttributeNode(srcAttribute);
144             var headElement = document.getElementsByTagName("head")[0];
145             headElement.appendChild(scriptElement);
146         } else {
147             document.write('<script type="text/javascript" src="' + libraryName + '"><\/script>');
148         }
149     };
150 
151     JXG.baseFiles = 'jxg,base/constants,utils/type,utils/xml,utils/env,utils/event,utils/expect,math/math,math/numerics,math/statistics,math/symbolic,math/geometry,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,utils/color,base/ticks,utils/zip,utils/base64,utils/uuid,utils/encoding,server/server,element/locus,parser/datasource,parser/jessiecode,utils/dump,renderer/svg,renderer/vml,renderer/canvas,renderer/no,element/slopetriangle,math/qdt,element/checkbox,element/input,element/button';
152     JXG.requirePath = '';
153 
154     for (i = 0; i < document.getElementsByTagName("script").length; i++) {
155         s = document.getElementsByTagName("script")[i];
156         if (s.src && s.src.match(/loadjsxgraph\.js(\?.*)?$/)) {
157             JXG.requirePath = s.src.replace(/loadjsxgraph\.js(\?.*)?$/, '');
158             arr = JXG.baseFiles.split(',');
159             for (n = 0; n < arr.length; n++) {
160                 JXG.require(JXG.requirePath + arr[n] + '.js');
161             }
162         }
163     }
164 
165     JXG.baseFiles = null;
166     JXG.serverBase = JXG.requirePath + 'server/';
167 
168     // This is a table with functions which check the availability
169     // of certain namespaces, functions and classes. With this structure
170     // we are able to get a rough check if a specific dependency is available.
171     table = {
172         'jsxgraph': checkJXG,
173         'jxg': checkJXG,
174         'options': makeCheck('Options'),
175 
176         'base/board': makeCheck('Board'),
177         'base/chart': checkJXG,
178         'base/circle': checkJXG,
179         'base/composition': makeCheck('Composition'),
180         'base/constants': checkJXG,
181         'base/coords': makeCheck('Coords'),
182         'base/coordselement': makeCheck('CoordsElement'),
183         'base/curve': checkJXG,
184         'base/element': makeCheck('GeometryElement'),
185         'base/group': checkJXG,
186         'base/image': checkJXG,
187         'base/line': checkJXG,
188         'base/point': checkJXG,
189         'base/polygon': checkJXG,
190         'base/text': checkJXG,
191         'base/ticks': checkJXG,
192         'base/transformation': checkJXG,
193         'base/turtle': checkJXG,
194 
195         'element/arc': checkJXG,
196         'element/centroid': checkJXG,
197         'element/composition': checkJXG,
198         'element/conic': checkJXG,
199         'element/locus': checkJXG,
200         'element/measure': checkJXG,
201         'element/sector': checkJXG,
202         'element/slider': checkJXG,
203         'element/square': checkJXG,
204         'element/triangle': checkJXG,
205         'element/checkbox': checkJXG,
206         'element/input': checkJXG,
207         'element/button': checkJXG,
208 
209         'math/bst': makeCheck('Math.BST'),
210         'math/qdt': makeCheck('Math.Quadtree'),
211         'math/complex': makeCheck('Complex'),
212         'math/geometry': makeCheck('Math.Geometry'),
213         'math/math': makeCheck('Math'),
214         'math/numerics': makeCheck('Math.Numerics'),
215         'math/poly': makeCheck('Math.Poly'),
216         'math/statistics': makeCheck('Math.Statistics'),
217         'math/symbolic': makeCheck('Math.Symbolic'),
218 
219         'parser/datasource': makeCheck('DataSource'),
220         'parser/geonext': makeCheck('GeonextParser'),
221         'parser/jessiecode': makeCheck('JessieCode'),
222 
223         'reader/cinderella': makeCheck('CinderellaReader'),
224         'reader/file': makeCheck('FileReader'),
225         'reader/geogebra': makeCheck('GeogebraReader'),
226         'reader/geonext': makeCheck('GeonextReader'),
227         'reader/graph': makeCheck('GraphReader'),
228         'reader/intergeo': makeCheck('IntergeoReader'),
229         'reader/sketch': makeCheck('SketchReader'),
230         'reader/tracenpoche': makeCheck('TracenpocheReader'),
231 
232         'renderer/abstract': makeCheck('AbstractRenderer'),
233         'renderer/canvas': makeCheck('CanvasRenderer'),
234         'renderer/no': makeCheck('NoRenderer'),
235         'renderer/svg': makeCheck('SVGRenderer'),
236         'renderer/vml': makeCheck('VMLRenderer'),
237 
238         'server/server': makeCheck('Server'),
239 
240         'utils/base64': makeCheck('Util.Base64'),
241         'utils/color': checkJXG,
242         'utils/dump': makeCheck('Dump'),
243         'utils/encoding': makeCheck('Util.UTF8'),
244         'utils/env': checkJXG,
245         'utils/event': makeCheck('EventEmitter'),
246         'utils/expect': makeCheck('Expect'),
247         'utils/type': checkJXG,
248         'utils/uuid': makeCheck('Util'),
249         'utils/xml': makeCheck('XML'),
250         'utils/zip': makeCheck('Util')
251     };
252 }());
253