Add datatables-1.9.4 and jquery-1.10.2 libraries
[proteocache.git] / webapp / resources / datatables-1.9.4 / media / src / core / core.support.js
1
2 /**
3  * Return the settings object for a particular table
4  *  @param {node} nTable table we are using as a dataTable
5  *  @returns {object} Settings object - or null if not found
6  *  @memberof DataTable#oApi
7  */
8 function _fnSettingsFromNode ( nTable )
9 {
10         for ( var i=0 ; i<DataTable.settings.length ; i++ )
11         {
12                 if ( DataTable.settings[i].nTable === nTable )
13                 {
14                         return DataTable.settings[i];
15                 }
16         }
17         
18         return null;
19 }
20
21
22 /**
23  * Return an array with the TR nodes for the table
24  *  @param {object} oSettings dataTables settings object
25  *  @returns {array} TR array
26  *  @memberof DataTable#oApi
27  */
28 function _fnGetTrNodes ( oSettings )
29 {
30         var aNodes = [];
31         var aoData = oSettings.aoData;
32         for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
33         {
34                 if ( aoData[i].nTr !== null )
35                 {
36                         aNodes.push( aoData[i].nTr );
37                 }
38         }
39         return aNodes;
40 }
41
42
43 /**
44  * Return an flat array with all TD nodes for the table, or row
45  *  @param {object} oSettings dataTables settings object
46  *  @param {int} [iIndividualRow] aoData index to get the nodes for - optional 
47  *    if not given then the return array will contain all nodes for the table
48  *  @returns {array} TD array
49  *  @memberof DataTable#oApi
50  */
51 function _fnGetTdNodes ( oSettings, iIndividualRow )
52 {
53         var anReturn = [];
54         var iCorrector;
55         var anTds, nTd;
56         var iRow, iRows=oSettings.aoData.length,
57                 iColumn, iColumns, oData, sNodeName, iStart=0, iEnd=iRows;
58         
59         /* Allow the collection to be limited to just one row */
60         if ( iIndividualRow !== undefined )
61         {
62                 iStart = iIndividualRow;
63                 iEnd = iIndividualRow+1;
64         }
65
66         for ( iRow=iStart ; iRow<iEnd ; iRow++ )
67         {
68                 oData = oSettings.aoData[iRow];
69                 if ( oData.nTr !== null )
70                 {
71                         /* get the TD child nodes - taking into account text etc nodes */
72                         anTds = [];
73                         nTd = oData.nTr.firstChild;
74                         while ( nTd )
75                         {
76                                 sNodeName = nTd.nodeName.toLowerCase();
77                                 if ( sNodeName == 'td' || sNodeName == 'th' )
78                                 {
79                                         anTds.push( nTd );
80                                 }
81                                 nTd = nTd.nextSibling;
82                         }
83
84                         iCorrector = 0;
85                         for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ )
86                         {
87                                 if ( oSettings.aoColumns[iColumn].bVisible )
88                                 {
89                                         anReturn.push( anTds[iColumn-iCorrector] );
90                                 }
91                                 else
92                                 {
93                                         anReturn.push( oData._anHidden[iColumn] );
94                                         iCorrector++;
95                                 }
96                         }
97                 }
98         }
99
100         return anReturn;
101 }
102
103
104 /**
105  * Log an error message
106  *  @param {object} oSettings dataTables settings object
107  *  @param {int} iLevel log error messages, or display them to the user
108  *  @param {string} sMesg error message
109  *  @memberof DataTable#oApi
110  */
111 function _fnLog( oSettings, iLevel, sMesg )
112 {
113         var sAlert = (oSettings===null) ?
114                 "DataTables warning: "+sMesg :
115                 "DataTables warning (table id = '"+oSettings.sTableId+"'): "+sMesg;
116         
117         if ( iLevel === 0 )
118         {
119                 if ( DataTable.ext.sErrMode == 'alert' )
120                 {
121                         alert( sAlert );
122                 }
123                 else
124                 {
125                         throw new Error(sAlert);
126                 }
127                 return;
128         }
129         else if ( window.console && console.log )
130         {
131                 console.log( sAlert );
132         }
133 }
134
135
136 /**
137  * See if a property is defined on one object, if so assign it to the other object
138  *  @param {object} oRet target object
139  *  @param {object} oSrc source object
140  *  @param {string} sName property
141  *  @param {string} [sMappedName] name to map too - optional, sName used if not given
142  *  @memberof DataTable#oApi
143  */
144 function _fnMap( oRet, oSrc, sName, sMappedName )
145 {
146         if ( sMappedName === undefined )
147         {
148                 sMappedName = sName;
149         }
150         if ( oSrc[sName] !== undefined )
151         {
152                 oRet[sMappedName] = oSrc[sName];
153         }
154 }
155
156
157 /**
158  * Extend objects - very similar to jQuery.extend, but deep copy objects, and shallow
159  * copy arrays. The reason we need to do this, is that we don't want to deep copy array
160  * init values (such as aaSorting) since the dev wouldn't be able to override them, but
161  * we do want to deep copy arrays.
162  *  @param {object} oOut Object to extend
163  *  @param {object} oExtender Object from which the properties will be applied to oOut
164  *  @returns {object} oOut Reference, just for convenience - oOut === the return.
165  *  @memberof DataTable#oApi
166  *  @todo This doesn't take account of arrays inside the deep copied objects.
167  */
168 function _fnExtend( oOut, oExtender )
169 {
170         var val;
171         
172         for ( var prop in oExtender )
173         {
174                 if ( oExtender.hasOwnProperty(prop) )
175                 {
176                         val = oExtender[prop];
177
178                         if ( typeof oInit[prop] === 'object' && val !== null && $.isArray(val) === false )
179                         {
180                                 $.extend( true, oOut[prop], val );
181                         }
182                         else
183                         {
184                                 oOut[prop] = val;
185                         }
186                 }
187         }
188
189         return oOut;
190 }
191
192
193 /**
194  * Bind an event handers to allow a click or return key to activate the callback.
195  * This is good for accessibility since a return on the keyboard will have the
196  * same effect as a click, if the element has focus.
197  *  @param {element} n Element to bind the action to
198  *  @param {object} oData Data object to pass to the triggered function
199  *  @param {function} fn Callback function for when the event is triggered
200  *  @memberof DataTable#oApi
201  */
202 function _fnBindAction( n, oData, fn )
203 {
204         $(n)
205                 .bind( 'click.DT', oData, function (e) {
206                                 n.blur(); // Remove focus outline for mouse users
207                                 fn(e);
208                         } )
209                 .bind( 'keypress.DT', oData, function (e){
210                         if ( e.which === 13 ) {
211                                 fn(e);
212                         } } )
213                 .bind( 'selectstart.DT', function () {
214                         /* Take the brutal approach to cancelling text selection */
215                         return false;
216                         } );
217 }
218
219
220 /**
221  * Register a callback function. Easily allows a callback function to be added to
222  * an array store of callback functions that can then all be called together.
223  *  @param {object} oSettings dataTables settings object
224  *  @param {string} sStore Name of the array storage for the callbacks in oSettings
225  *  @param {function} fn Function to be called back
226  *  @param {string} sName Identifying name for the callback (i.e. a label)
227  *  @memberof DataTable#oApi
228  */
229 function _fnCallbackReg( oSettings, sStore, fn, sName )
230 {
231         if ( fn )
232         {
233                 oSettings[sStore].push( {
234                         "fn": fn,
235                         "sName": sName
236                 } );
237         }
238 }
239
240
241 /**
242  * Fire callback functions and trigger events. Note that the loop over the callback
243  * array store is done backwards! Further note that you do not want to fire off triggers
244  * in time sensitive applications (for example cell creation) as its slow.
245  *  @param {object} oSettings dataTables settings object
246  *  @param {string} sStore Name of the array storage for the callbacks in oSettings
247  *  @param {string} sTrigger Name of the jQuery custom event to trigger. If null no trigger
248  *    is fired
249  *  @param {array} aArgs Array of arguments to pass to the callback function / trigger
250  *  @memberof DataTable#oApi
251  */
252 function _fnCallbackFire( oSettings, sStore, sTrigger, aArgs )
253 {
254         var aoStore = oSettings[sStore];
255         var aRet =[];
256
257         for ( var i=aoStore.length-1 ; i>=0 ; i-- )
258         {
259                 aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) );
260         }
261
262         if ( sTrigger !== null )
263         {
264                 $(oSettings.oInstance).trigger(sTrigger, aArgs);
265         }
266
267         return aRet;
268 }
269
270
271 /**
272  * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other
273  * library, then we use that as it is fast, safe and accurate. If the function isn't 
274  * available then we need to built it ourselves - the inspiration for this function comes
275  * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is
276  * not perfect and absolutely should not be used as a replacement to json2.js - but it does
277  * do what we need, without requiring a dependency for DataTables.
278  *  @param {object} o JSON object to be converted
279  *  @returns {string} JSON string
280  *  @memberof DataTable#oApi
281  */
282 var _fnJsonString = (window.JSON) ? JSON.stringify : function( o )
283 {
284         /* Not an object or array */
285         var sType = typeof o;
286         if (sType !== "object" || o === null)
287         {
288                 // simple data type
289                 if (sType === "string")
290                 {
291                         o = '"'+o+'"';
292                 }
293                 return o+"";
294         }
295
296         /* If object or array, need to recurse over it */
297         var
298                 sProp, mValue,
299                 json = [],
300                 bArr = $.isArray(o);
301         
302         for (sProp in o)
303         {
304                 mValue = o[sProp];
305                 sType = typeof mValue;
306
307                 if (sType === "string")
308                 {
309                         mValue = '"'+mValue+'"';
310                 }
311                 else if (sType === "object" && mValue !== null)
312                 {
313                         mValue = _fnJsonString(mValue);
314                 }
315
316                 json.push((bArr ? "" : '"'+sProp+'":') + mValue);
317         }
318
319         return (bArr ? "[" : "{") + json + (bArr ? "]" : "}");
320 };
321
322
323 /**
324  * From some browsers (specifically IE6/7) we need special handling to work around browser
325  * bugs - this function is used to detect when these workarounds are needed.
326  *  @param {object} oSettings dataTables settings object
327  *  @memberof DataTable#oApi
328  */
329 function _fnBrowserDetect( oSettings )
330 {
331         /* IE6/7 will oversize a width 100% element inside a scrolling element, to include the
332          * width of the scrollbar, while other browsers ensure the inner element is contained
333          * without forcing scrolling
334          */
335         var n = $(
336                 '<div style="position:absolute; top:0; left:0; height:1px; width:1px; overflow:hidden">'+
337                         '<div style="position:absolute; top:1px; left:1px; width:100px; overflow:scroll;">'+
338                                 '<div id="DT_BrowserTest" style="width:100%; height:10px;"></div>'+
339                         '</div>'+
340                 '</div>')[0];
341
342         document.body.appendChild( n );
343         oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false;
344         document.body.removeChild( n );
345 }
346