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