1 /* 2 Copyright 2008-2013 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 and JSXCompressor. 11 12 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 13 JSXCompressor is free software dual licensed under the GNU LGPL or Apache 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 OR 23 * Apache License Version 2.0 24 25 JSXGraph is distributed in the hope that it will be useful, 26 but WITHOUT ANY WARRANTY; without even the implied warranty of 27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 GNU Lesser General Public License for more details. 29 30 You should have received a copy of the GNU Lesser General Public License, Apache 31 License, and the MIT License along with JSXGraph. If not, see 32 <http://www.gnu.org/licenses/>, <https://www.apache.org/licenses/LICENSE-2.0.html>, 33 and <http://opensource.org/licenses/MIT/>. 34 35 */ 36 37 38 /*global JXG: true, define: true, jQuery: true, window: true, document: true, navigator: true, require: true, module: true, console: true */ 39 /*jslint nomen:true, plusplus:true, forin:true*/ 40 41 /* depends: 42 */ 43 44 /** 45 * @fileoverview The JSXGraph object is defined in this file. JXG.JSXGraph controls all boards. 46 * It has methods to create, save, load and free boards. Additionally some helper functions are 47 * defined in this file directly in the JXG namespace. 48 */ 49 50 define([], function () { 51 52 "use strict"; 53 54 /** 55 * JXG is the top object of JSXGraph and defines the namespace 56 */ 57 var jxg = {}; 58 59 // Make sure JXG.extend is not defined 60 // If jsxgraph is loaded via loadjsxgraph.js, this is required, but JXG.extend will be undefined 61 // If jsxgraph is compiled as an amd module, it is possible that another jsxgraph version is already loaded and we 62 // therefore must not re-use the global JXG variable. But in this case JXG.extend will already be defined. 63 // This is the reason for this check. 64 if (typeof JXG === 'object' && !JXG.extend) { 65 jxg = JXG; 66 } 67 68 // We need the following two methods "extend" and "shortcut" to create the JXG object via JXG.extend. 69 70 /** 71 * Copy all properties of the <tt>extension</tt> object to <tt>object</tt>. 72 * @param {Object} object 73 * @param {Object} extension 74 * @param {Boolean} [onlyOwn=false] Only consider properties that belong to extension itself, not any inherited properties. 75 * @param {Boolean} [toLower=false] If true the keys are convert to lower case. This is needed for visProp, see JXG#copyAttributes 76 */ 77 jxg.extend = function (object, extension, onlyOwn, toLower) { 78 var e, e2; 79 80 onlyOwn = onlyOwn || false; 81 toLower = toLower || false; 82 83 // the purpose of this for...in loop is indeed to use hasOwnProperty only if the caller 84 // explicitly wishes so. 85 for (e in extension) { 86 if (!onlyOwn || (onlyOwn && extension.hasOwnProperty(e))) { 87 if (toLower) { 88 e2 = e.toLowerCase(); 89 } else { 90 e2 = e; 91 } 92 93 object[e2] = extension[e]; 94 } 95 } 96 }; 97 98 jxg.extend(jxg, /** @lends JXG */ { 99 /** 100 * Store a reference to every board in this central list. This will at some point 101 * replace JXG.JSXGraph.boards. 102 * @type Object 103 */ 104 boards: {}, 105 106 /** 107 * Store the available file readers in this structure. 108 * @type Object 109 */ 110 readers: {}, 111 112 /** 113 * Associative array that keeps track of all constructable elements registered 114 * via {@link JXG.JSXGraph.registerElement}. 115 * @type Object 116 */ 117 elements: {}, 118 119 /** 120 * This registers a new construction element to JSXGraph for the construction via the {@link JXG.Board.create} 121 * interface. 122 * @param {String} element The elements name. This is case-insensitive, existing elements with the same name 123 * will be overwritten. 124 * @param {Function} creator A reference to a function taking three parameters: First the board, the element is 125 * to be created on, a parent element array, and an attributes object. See {@link JXG.createPoint} or any other 126 * <tt>JXG.create...</tt> function for an example. 127 */ 128 registerElement: function (element, creator) { 129 element = element.toLowerCase(); 130 this.elements[element] = creator; 131 }, 132 133 /** 134 * Register a file reader. 135 * @param {function} reader A file reader. This object has to provide two methods: <tt>prepareString()</tt> 136 * and <tt>read()</tt>. 137 * @param {Array} ext 138 */ 139 registerReader: function (reader, ext) { 140 var i, e; 141 142 for (i = 0; i < ext.length; i++) { 143 e = ext[i].toLowerCase(); 144 145 if (typeof this.readers[e] !== 'function') { 146 this.readers[e] = reader; 147 } 148 } 149 }, 150 151 /** 152 * Creates a shortcut to a method, e.g. {@link JXG.Board#createElement} is a shortcut to {@link JXG.Board#create}. 153 * Sometimes the target is undefined by the time you want to define the shortcut so we need this little helper. 154 * @param {Object} object The object the method we want to create a shortcut for belongs to. 155 * @param {String} fun The method we want to create a shortcut for. 156 * @returns {Function} A function that calls the given method. 157 */ 158 shortcut: function (object, fun) { 159 return function () { 160 return object[fun].apply(this, arguments); 161 }; 162 }, 163 164 /** 165 * s may be a string containing the name or id of an element or even a reference 166 * to the element itself. This function returns a reference to the element. Search order: id, name. 167 * @param {JXG.Board} board Reference to the board the element belongs to. 168 * @param {String} s String or reference to a JSXGraph element. 169 * @returns {Object} Reference to the object given in parameter object 170 * @deprecated Use {@link JXG.Board#select} 171 */ 172 getRef: function (board, s) { 173 return board.select(s); 174 }, 175 176 /** 177 * This is just a shortcut to {@link JXG.getRef}. 178 * @deprecated Use {@link JXG.Board#select}. 179 */ 180 getReference: function (board, s) { 181 return board.select(s); 182 }, 183 184 /** 185 * Add something to the debug log. If available a JavaScript debug console is used. Otherwise 186 * we're looking for a HTML div with id "debug". If this doesn't exist, too, the output is omitted. 187 * @param s An arbitrary number of parameters. 188 * @see JXG#debugWST 189 */ 190 debugInt: function (s) { 191 var i, p; 192 193 for (i = 0; i < arguments.length; i++) { 194 p = arguments[i]; 195 if (typeof window === 'object' && window.console && console.log) { 196 console.log(p); 197 } else if (typeof document === 'object' && document.getElementById('debug')) { 198 document.getElementById('debug').innerHTML += p + "<br/>"; 199 } 200 } 201 }, 202 203 /** 204 * Add something to the debug log. If available a JavaScript debug console is used. Otherwise 205 * we're looking for a HTML div with id "debug". If this doesn't exist, too, the output is omitted. 206 * This method adds a stack trace (if available). 207 * @param s An arbitrary number of parameters. 208 * @see JXG#debug 209 */ 210 debugWST: function (s) { 211 var e = new Error(); 212 213 jxg.debugInt.apply(this, arguments); 214 215 if (e && e.stack) { 216 jxg.debugInt('stacktrace'); 217 jxg.debugInt(e.stack.split('\n').slice(1).join('\n')); 218 } 219 }, 220 221 debugLine: function (s) { 222 var e = new Error(); 223 224 jxg.debugInt.apply(this, arguments); 225 226 if (e && e.stack) { 227 jxg.debugInt('Called from', e.stack.split('\n').slice(2, 3).join('\n')); 228 } 229 }, 230 231 /** 232 * Add something to the debug log. If available a JavaScript debug console is used. Otherwise 233 * we're looking for a HTML div with id "debug". If this doesn't exist, too, the output is omitted. 234 * @param s An arbitrary number of parameters. 235 * @see JXG#debugWST 236 * @see JXG#debugLine 237 * @see JXG#debugInt 238 */ 239 debug: function (s) { 240 jxg.debugInt.apply(this, arguments); 241 } 242 }); 243 244 return jxg; 245 }); 246