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*/ 34 /*jslint nomen: true, plusplus: true*/ 35 36 /* depends: 37 jxg 38 utils/type 39 */ 40 41 /** 42 * @fileoverview In this file the EventEmitter interface is defined. 43 */ 44 45 define(['jxg', 'utils/type'], function (JXG, Type) { 46 47 "use strict"; 48 49 /** 50 * @namespace 51 */ 52 JXG.EventEmitter = { 53 /** 54 * Holds the registered event handlers. 55 * @name JXG.EventEmitter#eventHandlers 56 * @type Object 57 */ 58 eventHandlers: {}, 59 60 /** 61 * Events can be suspended to prevent endless loops. 62 * @name JXG.EventEmitter#suspended 63 * @type Object 64 */ 65 suspended: {}, 66 67 /** 68 * Triggers all event handlers of this element for a given event. 69 * @name JXG.EventEmitter#triggerEventHandlers 70 * @function 71 * @param {Array} event 72 * @param {Array} args The arguments passed onto the event handler 73 * @returns Reference to the object. 74 */ 75 trigger: function (event, args) { 76 var i, j, h, evt, len1, len2; 77 78 len1 = event.length; 79 for (j = 0; j < len1; j++) { 80 evt = this.eventHandlers[event[j]]; 81 82 if (!this.suspended[event[j]]) { 83 this.suspended[event[j]] = true; 84 85 if (evt) { 86 len2 = evt.length; 87 88 for (i = 0; i < len2; i++) { 89 h = evt[i]; 90 h.handler.apply(h.context, args); 91 } 92 } 93 94 this.suspended[event[j]] = false; 95 } 96 } 97 98 return this; 99 }, 100 101 /** 102 * Register a new event handler. For a list of possible events see documentation of the elements and objects implementing 103 * the {@link EventEmitter} interface. 104 * @name JXG.EventEmitter#on 105 * @function 106 * @param {String} event 107 * @param {Function} handler 108 * @param {Object} [context] The context the handler will be called in, default is the element itself. 109 * @returns Reference to the object. 110 */ 111 on: function (event, handler, context) { 112 if (!Type.isArray(this.eventHandlers[event])) { 113 this.eventHandlers[event] = []; 114 } 115 116 context = Type.def(context, this); 117 118 this.eventHandlers[event].push({ 119 handler: handler, 120 context: context 121 }); 122 123 return this; 124 }, 125 126 /** 127 * Unregister an event handler. 128 * @name JXG.EventEmitter#off 129 * @function 130 * @param {String} event 131 * @param {Function} [handler] 132 * @returns Reference to the object. 133 */ 134 off: function (event, handler) { 135 var i; 136 137 if (!event || !Type.isArray(this.eventHandlers[event])) { 138 return this; 139 } 140 141 if (handler) { 142 i = Type.indexOf(this.eventHandlers[event], handler, 'handler'); 143 if (i > -1) { 144 this.eventHandlers[event].splice(i, 1); 145 } 146 147 if (this.eventHandlers[event].length === 0) { 148 delete this.eventHandlers[event]; 149 } 150 } else { 151 delete this.eventHandlers[event]; 152 } 153 154 return this; 155 }, 156 157 /** 158 * @description Implements the functionality from this interface in the given object. All objects getting their event handling 159 * capabilities from this method should document it by adding the <tt>on, off, triggerEventHandlers</tt> via the 160 * borrows tag as methods to their documentation: <pre>@borrows JXG.EventEmitter#on as this.on</pre> 161 * @name JXG.EventEmitter#eventify 162 * @function 163 * @param {Object} o 164 */ 165 eventify: function (o) { 166 o.eventHandlers = {}; 167 o.on = this.on; 168 o.off = this.off; 169 o.triggerEventHandlers = this.trigger; 170 o.trigger = this.trigger; 171 o.suspended = {}; 172 } 173 }; 174 175 return JXG.EventEmitter; 176 }); 177