1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 
 25 /**
 26  * 
 27  * @private
 28  */
 29 AjxCore = function() {}
 30 
 31 AjxCore._objectIds = [null];
 32 
 33 /**
 34  * @deprecated
 35  * 
 36  * The association is now made by DwtControl using the element's ID, so a separate
 37  * unique ID is not needed.
 38  */
 39 AjxCore.assignId = 
 40 function(anObject) {
 41 	var myId = AjxCore._objectIds.length;
 42 	AjxCore._objectIds[myId]= anObject;
 43 	return myId;
 44 };
 45 
 46 /**
 47  * @deprecated
 48  */
 49 AjxCore.unassignId = 
 50 function(anId) {
 51 	AjxCore._objectIds[anId]= null;
 52 };
 53 
 54 /**
 55  * @deprecated
 56  */
 57 AjxCore.objectWithId = 
 58 function(anId) {
 59 	return AjxCore._objectIds[anId];
 60 };
 61 
 62 /**
 63  * Adds a listener to an element, for the given event name.
 64  */
 65 AjxCore.addListener = 
 66 function(eventSource, eventName, action) {
 67 	eventSource = AjxCore._getEventSource(eventSource);
 68 	var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
 69 	listenerStruct.list[listenerStruct.list.length] = action;
 70 };
 71 
 72 /**
 73  * sets a one time event handler for the given eventName.
 74  */
 75 AjxCore.setEventHandler = 
 76 function(eventSource, eventName, action) {
 77 	eventSource = AjxCore._getEventSource(eventSource);
 78 	var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
 79 	listenerStruct.single = action;
 80 };
 81 
 82 /**
 83  * removes a listener for a given event
 84  */
 85 AjxCore.removeListener = 
 86 function(eventSource, eventName, action) {
 87 	eventSource = AjxCore._getEventSource(eventSource);
 88 	var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
 89 
 90 	if (listenerStruct) {
 91 		var listenerList = listenerStruct.list;
 92 		var len = listenerList.length;
 93 		for (var i = 0; i < len; i++) {
 94 			if (listenerList[i] == action) {
 95 				listenerList[i] = null;
 96 			}
 97 		}
 98 	}
 99 };
100 
101 /**
102  * Removes all listeners for a given eventName, and source
103  */
104 AjxCore.removeAllListeners = 
105 function(eventSource, eventName) {
106 	eventSource = AjxCore._getEventSource(eventSource);
107 	var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
108 
109 	if (listenerStruct) {
110 		var listenerList = listenerStruct.list;
111 		var len = listenerList.length;
112 		for (var i = 0; i < len; i++) {
113 			listenerList[i] = null;
114 		}
115 	}
116 	AjxCore.unassignId(listenerStruct.id);
117 };
118 
119 /**
120  * notifies listeners of the event. This only needs to be called if
121  * the event is not a standard DOM event. Those types of event callbacks
122  * will be triggered by their event handlers
123  */
124 AjxCore.notifyListeners = 
125 function(eventSource, eventName, arg1) {
126 	eventSource = AjxCore._getEventSource(eventSource);
127 	var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
128 	if (listenerStruct) {
129 		eventSource[eventName](arg1);
130 	}
131 };
132 
133 AjxCore._getEventSource = 
134 function(eventSource) {
135 	if (typeof(eventSource) == 'string') {
136 		eventSource = document.getElementById(eventSource);
137 	}
138 	return eventSource;
139 };
140 
141 AjxCore.getListenerStruct = 
142 function (eventSource, eventName) {
143 	return AjxCore._getListenerStruct(eventSource, eventName);
144 };
145 
146 /**
147  * gets the existing struct for the eventSource, or creates a new one.
148  */
149 AjxCore._getListenerStruct = 
150 function(eventSource, eventName, create) {
151 	var listenerStruct = null;
152 	if (eventSource[eventName]) {
153 		var id = eventSource[eventName]._lsListenerStructId;
154 		listenerStruct = AjxCore.objectWithId(id);
155 	} else if (create) {
156 		listenerStruct = AjxCore._setupListener(eventSource, eventName);
157 	}
158 
159 	return listenerStruct;
160 };
161     
162 /**
163  * Creates a listener struct
164  */
165 AjxCore._setupListener = 
166 function(eventSource, eventName, id) {
167 	var listenerStruct = new Object();
168 	listenerStruct.list = new Array();
169 	listenerStruct.single = null;
170 	var id = listenerStruct.id = AjxCore.assignId(listenerStruct);
171 	var handler = AjxCore._createListenerClosure(id);
172 	eventSource[eventName] = handler;
173 	eventSource[eventName]._lsListenerStructId = id;
174 
175 	return listenerStruct;
176 };
177 
178 AjxCore._createListenerClosure = 
179 function(id) {
180 	var closure = function(arg1) {
181 		var listenerStruct = AjxCore.objectWithId(id);
182 		var listenerList = listenerStruct.list;
183 		var len = listenerList.length;
184 		for (var i = 0; i < len; i++) {
185 			var callback = listenerList[i];
186 			if (callback) {
187 				if (typeof(callback) == 'string') {
188 					eval(callback);
189 				} else {
190 					// handle AjxListener callbacks as well as simple functions
191 					if (callback.handleEvent) {
192 						callback.handleEvent(arg1, this);
193 					} else {
194 						callback(arg1, this);
195 					}
196 				}
197 			}
198 		}
199         if (listenerStruct.single) {
200 			var callback = listenerStruct.single;
201 			if (typeof(callback) == 'string') {
202 				eval(callback);
203 			} else {
204 				return callback.handleEvent
205 					? callback.handleEvent(arg1, this)
206 					: callback(arg1, this);
207 			}
208 		}
209 	}
210 	return closure;
211 };
212 
213 /**
214  * Convenience method for adding onload listeners
215  */
216 AjxCore.addOnloadListener = 
217 function(action) {
218 	if (window.onload && (!window.onload._lsListenerStructId)) {
219 		var priorListener = window.onload;
220 		window.onload = null;
221 		AjxCore.addListener(window, "onload", priorListener);
222 	}
223 
224 	AjxCore.addListener(window, "onload", action);
225 };
226 
227 /**
228  * Convenience method for adding onunload listeners
229  */    
230 AjxCore.addOnunloadListener = 
231 function(action) {
232 	if (window.onunload && (!window.onunload._lsListenerStructId)) {
233 		var priorListener = window.onunload;
234 		window.onunload = null;
235 		AjxCore.addListener(window, "onunload", priorListener);
236 	}
237 
238 	AjxCore.addListener(window, "onunload", action);
239 };
240