UNPKG

136 kBHTMLView Raw
1<!DOCTYPE html>
2
3<html lang="en">
4<head>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width">
7 <title>CrossBrowdy API documentation Source: CrossBase/general/CB_Elements.js</title>
8
9 <!--[if lt IE 9]>
10 <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">
13
14 <link type="text/css" rel="stylesheet" href="styles/site.cosmo.css">
15
16</head>
17
18<body style="min-width:800px; overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; line-break:strict; hyphens:none; -webkit-hyphens:none; -moz-hyphens:none;">
19
20<div class="navbar navbar-default navbar-fixed-top ">
21<div class="container">
22 <div class="navbar-header">
23 <a class="navbar-brand" href="index.html">CrossBrowdy API documentation</a>
24 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#topNavigation">
25 <span class="icon-bar"></span>
26 <span class="icon-bar"></span>
27 <span class="icon-bar"></span>
28 </button>
29 </div>
30 <div class="navbar-collapse collapse" id="topNavigation">
31 <ul class="nav navbar-nav">
32
33 <li class="dropdown">
34 <a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b class="caret"></b></a>
35 <ul class="dropdown-menu inline">
36 <li><a href="CB_Arrays.html">CB_Arrays</a></li><li><a href="CB_AudioDetector.html">CB_AudioDetector</a></li><li><a href="CB_baseSymbols.html">CB_baseSymbols</a></li><li><a href="CB_Client.html">CB_Client</a></li><li><a href="CB_Collisions.html">CB_Collisions</a></li><li><a href="CB_Configuration.html">CB_Configuration</a></li><li><a href="CB_Configuration.CrossBase.html">CB_Configuration.CrossBase</a></li><li><a href="CB_Configuration.CrossBrowdy.html">CB_Configuration.CrossBrowdy</a></li><li><a href="CB_Controllers.html">CB_Controllers</a></li><li><a href="CB_Controllers_Proprietary.html">CB_Controllers_Proprietary</a></li><li><a href="CB_Controllers_Proprietary.WII.html">CB_Controllers_Proprietary.WII</a></li><li><a href="CB_Controllers_Proprietary.WII_U.html">CB_Controllers_Proprietary.WII_U</a></li><li><a href="CB_Device.html">CB_Device</a></li><li><a href="CB_Device.AmbientLight.html">CB_Device.AmbientLight</a></li><li><a href="CB_Device.Battery.html">CB_Device.Battery</a></li><li><a href="CB_Device.Location.html">CB_Device.Location</a></li><li><a href="CB_Device.Motion.html">CB_Device.Motion</a></li><li><a href="CB_Device.Orientation.html">CB_Device.Orientation</a></li><li><a href="CB_Device.Proximity.html">CB_Device.Proximity</a></li><li><a href="CB_Device.Vibration.html">CB_Device.Vibration</a></li><li><a href="CB_Elements.html">CB_Elements</a></li><li><a href="CB_Events.html">CB_Events</a></li><li><a href="CB_Keyboard.html">CB_Keyboard</a></li><li><a href="CB_Keyboard.chars.html">CB_Keyboard.chars</a></li><li><a href="CB_Keyboard.extended.html">CB_Keyboard.extended</a></li><li><a href="CB_Keyboard.keys.html">CB_Keyboard.keys</a></li><li><a href="CB_Modules.html">CB_Modules</a></li><li><a href="CB_Mouse.html">CB_Mouse</a></li><li><a href="CB_Mouse.CursorImage.html">CB_Mouse.CursorImage</a></li><li><a href="CB_Net.html">CB_Net</a></li><li><a href="CB_Net.Fetch.html">CB_Net.Fetch</a></li><li><a href="CB_Net.REST.html">CB_Net.REST</a></li><li><a href="CB_Net.Sockets.html">CB_Net.Sockets</a></li><li><a href="CB_Net.Sockets.SockJS.html">CB_Net.Sockets.SockJS</a></li><li><a href="CB_Net.XHR.html">CB_Net.XHR</a></li><li><a href="CB_Pointer.html">CB_Pointer</a></li><li><a href="CB_Screen.html">CB_Screen</a></li><li><a href="CB_Speaker.html">CB_Speaker</a></li><li><a href="CB_Touch.html">CB_Touch</a></li>
37 </ul>
38 </li>
39
40 <li class="dropdown">
41 <a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b class="caret"></b></a>
42 <ul class="dropdown-menu inline">
43 <li><a href="CB_AudioFile.html">CB_AudioFile</a></li><li><a href="CB_AudioFile_API.AAPI.html">CB_AudioFile_API.AAPI</a></li><li><a href="CB_AudioFile_API.ACMP.html">CB_AudioFile_API.ACMP</a></li><li><a href="CB_AudioFile_API.SM2.html">CB_AudioFile_API.SM2</a></li><li><a href="CB_AudioFile_API.WAAPI.html">CB_AudioFile_API.WAAPI</a></li><li><a href="CB_AudioFileCache.html">CB_AudioFileCache</a></li><li><a href="CB_AudioFileSprites.html">CB_AudioFileSprites</a></li><li><a href="CB_AudioFileSpritesPool.html">CB_AudioFileSpritesPool</a></li><li><a href="CB_Canvas.html">CB_Canvas</a></li><li><a href="CB_GraphicSprites.html">CB_GraphicSprites</a></li><li><a href="CB_GraphicSpritesScene.html">CB_GraphicSpritesScene</a></li>
44 </ul>
45 </li>
46
47 <li class="dropdown">
48 <a href="global.html" class="dropdown-toggle" data-toggle="dropdown">Global<b class="caret"></b></a>
49 <ul class="dropdown-menu inline">
50 <li><a href="global.html#CB_addCredits">CB_addCredits</a></li><li><a href="global.html#CB_BASE_NAME">CB_BASE_NAME</a></li><li><a href="global.html#CB_baseToBase">CB_baseToBase</a></li><li><a href="global.html#CB_baseToInt">CB_baseToInt</a></li><li><a href="global.html#CB_br2nl">CB_br2nl</a></li><li><a href="global.html#CB_brToNl">CB_brToNl</a></li><li><a href="global.html#CB_combineArraysOrObjects">CB_combineArraysOrObjects</a></li><li><a href="global.html#CB_combineAutomatically">CB_combineAutomatically</a></li><li><a href="global.html#CB_combineJSON">CB_combineJSON</a></li><li><a href="global.html#CB_combineURIParameters">CB_combineURIParameters</a></li><li><a href="global.html#CB_combineURLParameters">CB_combineURLParameters</a></li><li><a href="global.html#CB_console">CB_console</a></li><li><a href="global.html#CB_copyObject">CB_copyObject</a></li><li><a href="global.html#CB_countDecimalDigits">CB_countDecimalDigits</a></li><li><a href="global.html#CB_countDecimalPart">CB_countDecimalPart</a></li><li><a href="global.html#CB_countDecimals">CB_countDecimals</a></li><li><a href="global.html#CB_countIntegerDigits">CB_countIntegerDigits</a></li><li><a href="global.html#CB_countIntegerPart">CB_countIntegerPart</a></li><li><a href="global.html#CB_credits">CB_credits</a></li><li><a href="global.html#CB_CREDITS_DEFAULT">CB_CREDITS_DEFAULT</a></li><li><a href="global.html#CB_forceString">CB_forceString</a></li><li><a href="global.html#CB_forEach">CB_forEach</a></li><li><a href="global.html#CB_getBase64StringObject">CB_getBase64StringObject</a></li><li><a href="global.html#CB_getCookie">CB_getCookie</a></li><li><a href="global.html#CB_getDatum">CB_getDatum</a></li><li><a href="global.html#CB_getJSONPropertyValue">CB_getJSONPropertyValue</a></li><li><a href="global.html#CB_getLZStringObject">CB_getLZStringObject</a></li><li><a href="global.html#CB_getValueIndex">CB_getValueIndex</a></li><li><a href="global.html#CB_getValuePath">CB_getValuePath</a></li><li><a href="global.html#CB_includeJSFile">CB_includeJSFile</a></li><li><a href="global.html#CB_indexOf">CB_indexOf</a></li><li><a href="global.html#CB_init">CB_init</a></li><li><a href="global.html#CB_intToBase">CB_intToBase</a></li><li><a href="global.html#CB_isArray">CB_isArray</a></li><li><a href="global.html#CB_isEmail">CB_isEmail</a></li><li><a href="global.html#CB_isFileLocal">CB_isFileLocal</a></li><li><a href="global.html#CB_isString">CB_isString</a></li><li><a href="global.html#CB_lastIndexOf">CB_lastIndexOf</a></li><li><a href="global.html#CB_ltrim">CB_ltrim</a></li><li><a href="global.html#CB_NAME">CB_NAME</a></li><li><a href="global.html#CB_nl2br">CB_nl2br</a></li><li><a href="global.html#CB_nlToBr">CB_nlToBr</a></li><li><a href="global.html#CB_numberFormat">CB_numberFormat</a></li><li><a href="global.html#CB_numberOfDecimalDigits">CB_numberOfDecimalDigits</a></li><li><a href="global.html#CB_numberOfDecimals">CB_numberOfDecimals</a></li><li><a href="global.html#CB_numberOfIntegerDigits">CB_numberOfIntegerDigits</a></li><li><a href="global.html#CB_OPTIONS">CB_OPTIONS</a></li><li><a href="global.html#CB_parseJSON">CB_parseJSON</a></li><li><a href="global.html#CB_parseString">CB_parseString</a></li><li><a href="global.html#CB_regularExpressionString">CB_regularExpressionString</a></li><li><a href="global.html#CB_renderString">CB_renderString</a></li><li><a href="global.html#CB_replaceAll">CB_replaceAll</a></li><li><a href="global.html#CB_rtrim">CB_rtrim</a></li><li><a href="global.html#CB_scriptPath">CB_scriptPath</a></li><li><a href="global.html#CB_scriptPathCalculate">CB_scriptPathCalculate</a></li><li><a href="global.html#CB_setCookie">CB_setCookie</a></li><li><a href="global.html#CB_setDatum">CB_setDatum</a></li><li><a href="global.html#CB_sizeof">CB_sizeof</a></li><li><a href="global.html#CB_sizeOf">CB_sizeOf</a></li><li><a href="global.html#CB_stringifyJSON">CB_stringifyJSON</a></li><li><a href="global.html#CB_symmetricCall">CB_symmetricCall</a></li><li><a href="global.html#CB_symmetricCallClear">CB_symmetricCallClear</a></li><li><a href="global.html#CB_this">CB_this</a></li><li><a href="global.html#CB_trim">CB_trim</a></li><li><a href="global.html#CB_VERSION">CB_VERSION</a></li>
51 </ul>
52 </li>
53
54 </ul>
55
56 <div class="col-sm-3 col-md-3">
57 <form class="navbar-form" role="search">
58 <div class="input-group">
59 <input type="text" class="form-control" placeholder="Search" name="q" id="search-input">
60 <div class="input-group-btn">
61 <button class="btn btn-default" id="search-submit"><i class="glyphicon glyphicon-search"></i></button>
62 </div>
63 </div>
64 </form>
65 </div>
66
67 </div>
68
69</div>
70</div>
71
72
73<div class="container" id="toc-content" style="width:100%;">
74<div class="row" style="width:100%;">
75
76
77 <div class="col-md-12">
78
79 <div id="main">
80
81
82 <h1 class="page-title">Source: CrossBase/general/CB_Elements.js</h1>
83
84<section>
85 <article>
86 <pre
87 class="sunlight-highlight-javascript linenums">/**
88 * @file DOM elements management. Contains the {@link CB_Elements} static class.
89 * @author Joan Alba Maldonado &lt;workindalian@gmail.com>
90 * @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}.
91 */
92
93
94/**
95 * Static class to manage DOM elements. It will return itself if it is tried to be instantiated.
96 * @namespace
97 * @todo Think about creating a function called "add" or "create" to create a new element (it could accept "tagName", "id" and "content" parameters).
98 * @todo Think about creating "setStyle" and "setStyleById" methods to add a given style attribute and also supporting a boolean parameter to also add the style attribute with vendor prefixes (webkit, moz, ms, o, khtml) if we want to.
99 */
100var CB_Elements = function() { return CB_Elements; };
101{
102 CB_Elements.initialized = false; //It will tells whether the object has been initialized or not.
103
104
105 //Initializes all values:
106 CB_Elements.init = function()
107 {
108 //If this is the fist time:
109 if (CB_Elements.initialized) { return CB_Elements; }
110
111 //The object has been initialized:
112 CB_Elements.initialized = true;
113
114 //TODO.
115
116 if (!document.body)
117 {
118 var tagBody = CB_Elements.tag("body", document);
119 if (typeof(tagBody) !== "undefined" &amp;&amp; tagBody !== null &amp;&amp; typeof(tagBody[0]) !== "undefined" &amp;&amp; tagBody[0] !== null)
120 {
121 document.body = tagBody[0];
122 }
123 }
124
125 return CB_Elements;
126 }
127
128
129 CB_Elements._tagCache = {};
130 /**
131 * Returns elements by their tag name.
132 * @function
133 * @param {string} [tagName='*'] - The name of the tag whose elements we want to find. Use asterisk ("*") in the case that we want all the elements.
134 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
135 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_tag_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
136 * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client).
137 */
138 CB_Elements.tag = function(tagName, baseElement, useCache)
139 {
140 if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } //Uses document as default base element.
141 if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_tag_USE_CACHE; }
142
143 //If no tag name is sent, uses "*" (all) by default:
144 tagName = CB_trim(tagName).toLowerCase();
145 if (tagName === "") { tagName = "*"; }
146
147 if (!useCache || typeof(CB_Elements._tagCache[baseElement]) === "undefined" || CB_Elements._tagCache[baseElement] === null || typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null)
148 {
149 if (typeof(CB_Elements._tagCache[baseElement]) === "undefined" || CB_Elements._tagCache[baseElement] === null)
150 {
151 CB_Elements._tagCache[baseElement] = {};
152 }
153
154 if (typeof(baseElement.getElementsByTagName) !== "undefined" &amp;&amp; baseElement.getElementsByTagName !== null)
155 {
156 CB_Elements._tagCache[baseElement][tagName] = baseElement.getElementsByTagName(tagName);
157 if (tagName === "*" &amp;&amp; CB_Elements._tagCache[baseElement][tagName].length === 0 &amp;&amp; typeof(document.all) !== "undefined" &amp;&amp; document.all !== null)
158 {
159 CB_Elements._tagCache[baseElement][tagName] = document.all;
160 }
161 }
162 else if (baseElement.querySelectorAll)
163 {
164 CB_Elements._tagCache[baseElement][tagName] = baseElement.querySelectorAll(tagName);
165 }
166 else if (document.querySelectorAll)
167 {
168 CB_Elements._tagCache[baseElement][tagName] = document.querySelectorAll(tagName);
169 }
170 else if (typeof(baseElement.all) !== "undefined" &amp;&amp; baseElement.all !== null)
171 {
172 if (tagName === "*")
173 {
174 CB_Elements._tagCache[baseElement][tagName] = baseElement.all;
175 }
176 else
177 {
178 CB_Elements._tagCache[baseElement][tagName] = baseElement.all.tags(tagName);
179 }
180 }
181 else if (typeof(document.all) !== "undefined" &amp;&amp; document.all !== null)
182 {
183 if (tagName === "*")
184 {
185 CB_Elements._tagCache[baseElement][tagName] = document.all;
186 }
187 else
188 {
189 CB_Elements._tagCache[baseElement][tagName] = document.all.tags(tagName);
190 }
191 }
192 else if (baseElement.layers || document.layers)
193 {
194 if (typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null)
195 {
196 CB_Elements._tagCache[baseElement][tagName] = [];
197 }
198
199 var allElements = baseElement.layers || document.layers;
200
201 //If we want all elements, then we get all of them:
202 if (tagName === "*") { CB_Elements._tagCache[baseElement][tagName] = allElements; }
203 //...otherwise, obtains all elements with the given tag name:
204 else
205 {
206 //If any elements were obtained, we select just the ones with the desired tag name:
207 var allElementsLength = allElements.length;
208
209 var elementCurrent;
210 for (var x = 0; x &lt; allElementsLength; x++)
211 {
212 elementCurrent = allElements[x];
213 if (elementCurrent !== null &amp;&amp; typeof(elementCurrent.tagName) !== "undefined")
214 {
215 if (CB_trim(elementCurrent.tagName).toLowerCase() === tagName)
216 {
217 CB_Elements._tagCache[baseElement][tagName].push(elementCurrent);
218 }
219 }
220 }
221 //CB_Elements._tagCache[baseElement][tagName] = baseElement.layers[tagName];
222 }
223 }
224 else if (typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null)
225 {
226 CB_Elements._tagCache[baseElement][tagName] = [];
227 }
228
229 /*
230 else if (baseElement.layers)
231 {
232 CB_Elements._tagCache[baseElement][tagName] = baseElement.layers[tagName];
233 }
234 else if (document.layers)
235 {
236 CB_Elements._tagCache[baseElement][tagName] = document.layers[tagName];
237 }*/
238
239 //If we used "*" and there is no elements, we try to use document.all instead (for old web clients):
240 //if (tagName === "*" &amp;&amp; CB_Elements._tagCache[baseElement][tagName].length === 0)
241 //{
242 //if (all in document) { CB_Elements._tagCache[baseElement][tagName] = document.all; }
243 //}
244 CB_Elements._tagCache[baseElement][tagName] = CB_Elements._tagCache[baseElement][tagName] || [];
245 }
246
247 return CB_Elements._tagCache[baseElement][tagName];
248 }
249
250
251 /**
252 * Returns elements by their tag name, updating (or creating) the internal cache. Calls the {@link CB_Elements.tag} function internally, with the "useCache" parameter set to false.
253 * @function
254 * @param {string} [tagName='*'] - The name of the tag whose elements we want to find. Use asterisk ("*") in the case that we want all the elements.
255 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
256 * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client).
257 */
258 CB_Elements.tagCacheUpdate = function(tagName, baseElement)
259 {
260 return CB_Elements.tag(tagName, baseElement, false);
261 }
262
263
264 /**
265 * Clears the internal cache user by {@link CB_Elements.tag} and others. If no parameter is given, whole internal cache will be cleared.
266 * @function
267 * @param {string} [tagName] - The name of the tag whose internal cache we want to clear. Use asterisk ("*") in the case that we want to clear the internal cache for {@link CB_Elements.tag} which is used when it is called with this exact parameter. If not provided, it will clear the whole internal cache or the internal cache that belongs to the "baseElement" given (if provided).
268 * @param {Node} [baseElement] - The node element parent whose internal cache we want to clear. If not provided but "tagName" is provided, it will clear the internal cache which matches the given "tagName" for any nodes. If it is provided but "tagName" is not, it will clear all the internal cache that belongs to this node element.
269 * @returns {Object} Returns the current internal cache after clearing it (if it is has been possible), which is an associative array of two dimensions (JavaScript object) whose first index belongs to the nodes, the second and last index belongs to the tag name and the value belongs to the returning value of the {@link CB_Elements.tag} function when it was called for those parameters.
270 */
271 CB_Elements.tagCacheClear = function(tagName, baseElement)
272 {
273 tagName = CB_trim(tagName).toLowerCase();
274
275 //If no base element and no tag name are defined, we clean all the array:
276 if (typeof(baseElement) === "undefined" &amp;&amp; tagName === "" || baseElement === null &amp;&amp; (typeof(tagName) === "undefined" || tagName === null))
277 {
278 CB_Elements._tagCache = {};
279 }
280 //...otherwise, if both base element and tag name are defined, we clear the elements of that base element:
281 else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null &amp;&amp; tagName !== "")
282 {
283 if (typeof(CB_Elements._tagCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement] !== null)
284 {
285 if (typeof(CB_Elements._tagCache[baseElement][tagName]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement][tagName] !== null)
286 {
287 CB_Elements._tagCache[baseElement][tagName] = null;
288 }
289 }
290 }
291 //...otherwise, if a base element is defined (but not a tagName), we clear all elements of that base element:
292 else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null)
293 {
294 if (typeof(CB_Elements._tagCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement] !== null)
295 {
296 CB_Elements._tagCache[baseElement] = {};
297 }
298 }
299 //...otherwise, if a tag name is defined (but not a base element), we clear all the elements of that tag name from all the element bases:
300 else if (tagName !== "")
301 {
302 for (var currentBaseElement in CB_Elements._tagCache)
303 {
304 if (typeof(CB_Elements._tagCache[currentBaseElement][tagName]) !== "undefined" &amp;&amp; CB_Elements._tagCache[currentBaseElement][tagName] !== null)
305 {
306 CB_Elements._tagCache[currentBaseElement][tagName] = null;
307 }
308 }
309 }
310
311 return CB_Elements._tagCache;
312 }
313
314
315 /**
316 * Alias for {@link CB_Elements.tagRemove}.
317 * @function CB_Elements.removeByTagName
318 * @see {@link CB_Elements.tagRemove}
319 */
320 /**
321 * Removes elements by their tag name.
322 * @function
323 * @param {string} [tagName='*'] - The name of the tag whose elements we want to delete. Use asterisk ("*") in the case that we want all the elements.
324 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
325 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_tag_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
326 */
327 CB_Elements.tagRemove = CB_Elements.removeByTagName = function(tagName, baseElement, useCache)
328 {
329 if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } //Uses document as default base element.
330 tagName = CB_trim(tagName);
331 if (tagName === "") { tagName = "*"; }
332
333 var elementsOriginal = CB_Elements.tag(tagName, baseElement, useCache);
334 if (typeof(elementsOriginal) !== "undefined" &amp;&amp; elementsOriginal !== null &amp;&amp; typeof(elementsOriginal.length) !== "undefined" &amp;&amp; elementsOriginal.length !== null &amp;&amp; elementsOriginal.length > 0)
335 {
336 var elements = [];
337 var elementsLength = elementsOriginal.length;
338 for (var x = 0; x &lt; elementsLength; x++) { elements[x] = elementsOriginal[x]; }
339
340 elementsLength = elements.length;
341 for (var x = 0; x &lt; elementsLength; x++)
342 {
343 //elements[x].parentNode.removeChild(elements[x]);
344 CB_Elements.remove(elements[x]);
345 }
346 CB_Elements._tagCache[baseElement][tagName] = null;
347 }
348 }
349
350
351 CB_Elements._classesCache = {};
352 /**
353 * Returns elements by their class or classes name.
354 * @function
355 * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to find. The order of the classes is just important for the internal cache.
356 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
357 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_classes_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
358 * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client).
359 */
360 CB_Elements.classes = function(classNames, baseElement, useCache)
361 {
362 if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_classes_USE_CACHE; }
363 if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; }
364
365 //If no class name is sent, returns am empty array:
366 classNames = CB_trim(classNames);//.toLowerCase();
367 if (classNames === "") { return []; }
368
369 if (!useCache || typeof(CB_Elements._classesCache[baseElement]) === "undefined" || CB_Elements._classesCache[baseElement] === null || typeof(CB_Elements._classesCache[baseElement][classNames]) === "undefined" || CB_Elements._classesCache[baseElement][classNames] === null)
370 {
371 if (typeof(CB_Elements._classesCache[baseElement]) === "undefined" || CB_Elements._classesCache[baseElement] === null)
372 {
373 CB_Elements._classesCache[baseElement] = {};
374 }
375
376 //CB_Elements._classesCache[baseElement][classNames] = baseElement.getElementsByClassName(classNames);
377 if (typeof(baseElement.getElementsByClassName) !== "undefined" &amp;&amp; baseElement.getElementsByClassName !== null)
378 {
379 CB_Elements._classesCache[baseElement][classNames] = baseElement.getElementsByClassName(classNames);
380 }
381 else if (baseElement.querySelectorAll)
382 {
383 CB_Elements._classesCache[baseElement][classNames] = baseElement.querySelectorAll("." + classNames.replace(/ /g, "."));
384 }
385 else if (document.querySelectorAll)
386 {
387 CB_Elements._classesCache[baseElement][classNames] = document.querySelectorAll("." + classNames.replace(/ /g, "."));
388 }
389 else
390 {
391 //Obtains all elements:
392 var allElements = CB_Elements.tag("*", baseElement, useCache);
393
394 //If any elements were obtained, we select just the ones with the desired class name:
395 var allElementsLength = allElements.length;
396 if (allElementsLength > 0)
397 {
398 if (typeof(CB_Elements._classesCache[baseElement][classNames]) === "undefined" || CB_Elements._classesCache[baseElement][classNames] === null)
399 {
400 CB_Elements._classesCache[baseElement][classNames] = [];
401 }
402
403 /*
404 //classNames = classNames.toLowerCase();
405 var elementCurrent;
406 var classes;
407 var classesLength;
408 for (var x = 0; x &lt; allElementsLength; x++)
409 {
410 elementCurrent = allElements[x];
411 if (elementCurrent !== null)
412 {
413 classes = elementCurrent.className.split(" ");
414 classesLength = classes.length;
415 for (var y = 0; y &lt; classesLength; y++)
416 {
417 classes[y] = CB_trim(classes[y]).toLowerCase();
418 //TODO: make it compatible with regular expressions (be careful with web clients not compatible with RegExp!).
419 if (classes[y] === classNames)
420 {
421 CB_Elements._classesCache[baseElement][classNames].push(elementCurrent);
422 break;
423 }
424 }
425 }
426 }
427 */
428 //TODO: make it compatible with regular expressions (be careful with web clients not compatible with RegExp!).
429 var classesDesired = classNames.split(" ");
430 var classesDesiredLength = classesDesired.length;
431 for (var x = 0; x &lt; classesDesiredLength; x++)
432 {
433 classesDesired[x] = CB_trim(classesDesired[x]);//.toLowerCase();
434 }
435
436 var elementCurrent;
437 var elementCurrentClass;
438 var classes;
439 var classesLength;
440 var y, z;
441 var allClassesFound;
442 for (x = 0; x &lt; allElementsLength; x++)
443 {
444 elementCurrent = allElements[x];
445 if (elementCurrent !== null)
446 {
447 elementCurrentClass = CB_trim(elementCurrent.className);
448 if (elementCurrentClass === "") { continue; }
449 classes = elementCurrentClass.split(" ");
450 classesLength = classes.length;
451 for (y = 0; y &lt; classesLength; y++)
452 {
453 classes[y] = CB_trim(classes[y]);//.toLowerCase();
454 }
455
456 allClassesFound = true;
457 for (z = 0; z &lt; classesDesiredLength; z++)
458 {
459 if (CB_indexOf(classes, classesDesired[z]) === -1)
460 {
461 allClassesFound = false;
462 break;
463 }
464 }
465
466 if (allClassesFound)
467 {
468 CB_Elements._classesCache[baseElement][classNames].push(elementCurrent);
469 //elements[elements.length] = elementCurrent;
470 }
471 }
472 }
473 }
474
475
476 }
477 /*
478 else if (typeof(baseElement.all) !== "undefined" &amp;&amp; baseElement.all !== null)
479 {
480 //allElements = baseElement.all;
481 allElements = CB_Elements.tag("*", baseElement, useCache);
482 }
483 else if (typeof(document.all) !== "undefined" &amp;&amp; document.all !== null)
484 {
485 //allElements = document.all;
486 allElements = CB_Elements.tag("*", document, useCache);
487 }
488 */
489 /*
490 else if (baseElement.layers)
491 {
492 CB_Elements._classesCache[baseElement][classNames] = baseElement.layers[classNames];
493 }
494 else if (document.layers)
495 {
496 CB_Elements._classesCache[baseElement][classNames] = document.layers[classNames];
497 }*/
498
499 CB_Elements._classesCache[baseElement][classNames] = CB_Elements._classesCache[baseElement][classNames] || [];
500 }
501
502 return CB_Elements._classesCache[baseElement][classNames];
503 }
504
505
506 /**
507 * Returns elements by their class or classes name, updating (or creating) the internal cache. Calls the {@link CB_Elements.classes} function internally, with the "useCache" parameter set to false.
508 * @function
509 * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to find. The order of the classes is just important for the internal cache.
510 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
511 * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client).
512 */
513 CB_Elements.classesCacheUpdate = function(classNames, baseElement)
514 {
515 return CB_Elements.classes(classNames, baseElement, false);
516 }
517
518
519 /**
520 * Clears the internal cache used by {@link CB_Elements.classes} and others. If no parameter is given, whole internal cache will be cleared.
521 * @function
522 * @param {string} [classNames] - The name of the class or classes (separated by a blank space) whose internal cache we want to clear. The order of the classes is important for the internal cache. If not provided, it will clear the whole internal cache or the internal cache that belongs to the "baseElement" given (if provided).
523 * @param {Node} [baseElement] - The node element parent whose internal cache we want to clear. If not provided but "classNames" is provided, it will clear the internal cache which matches the given "classNames" for any nodes. If it is provided but "classNames" is not, it will clear all the internal cache that belongs to this node element.
524 * @returns {Object} Returns the current internal cache after cleaning it (if it is has been possible), which is an associative array of two dimensions (JavaScript object) whose first index belongs to the nodes, the second and last index belongs to the class name or class names and the value belongs to the returning value of the {@link CB_Elements.classes} function when it was called for those parameters.
525 */
526 CB_Elements.classesCacheClear = function(classNames, baseElement)
527 {
528 classNames = CB_trim(classNames);//.toLowerCase();
529
530 //If no base element and no class name are defined, we clean all the array:
531 if (typeof(baseElement) === "undefined" &amp;&amp; classNames === "" || baseElement === null &amp;&amp; (typeof(classNames) === "undefined" || classNames === null))
532 {
533 CB_Elements._classesCache = {};
534 }
535 //...otherwise, if both base element and class name are defined, we clear the elements of that base element:
536 else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null &amp;&amp; classNames !== "")
537 {
538 if (typeof(CB_Elements._classesCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement] !== null)
539 {
540 if (typeof(CB_Elements._classesCache[baseElement][classNames]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement][classNames] !== null)
541 {
542 CB_Elements._classesCache[baseElement][classNames] = null;
543 }
544 }
545 }
546 //...otherwise, if a base element is defined (but not a classNames), we clear all elements of that base element:
547 else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null)
548 {
549 if (typeof(CB_Elements._classesCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement] !== null)
550 {
551 CB_Elements._classesCache[baseElement] = {};
552 }
553 }
554 //...otherwise, if a class name is defined (but not a base element), we clear all the elements of that class name from all the element bases:
555 else if (classNames !== "")
556 {
557 for (var currentBaseElement in CB_Elements._classesCache)
558 {
559 if (typeof(CB_Elements._classesCache[currentBaseElement][classNames]) !== "undefined" &amp;&amp; CB_Elements._classesCache[currentBaseElement][classNames] !== null)
560 {
561 CB_Elements._classesCache[currentBaseElement][classNames] = null;
562 }
563 }
564 }
565
566 return CB_Elements._classesCache;
567 }
568
569
570 /**
571 * Alias for {@link CB_Elements.classesRemove}.
572 * @function CB_Elements.removeByClasses
573 * @see {@link CB_Elements.classesRemove}
574 */
575 /**
576 * Removes elements by their class or classes name.
577 * @function
578 * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to delete. The order of the classes is just important for the internal cache.
579 * @param {Node} [baseElement=document] - The node element parent where we want to focus our search.
580 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_classes_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
581 */
582 CB_Elements.classesRemove = CB_Elements.removeByClasses = function(classNames, baseElement, useCache)
583 {
584 if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; }
585 classNames = CB_trim(classNames);//.toLowerCase();
586 if (classNames === "") { return; }
587
588 var elementsOriginal = CB_Elements.classes(classNames, baseElement, useCache);
589 if (typeof(elementsOriginal) !== "undefined" &amp;&amp; elementsOriginal !== null &amp;&amp; typeof(elementsOriginal.length) !== "undefined" &amp;&amp; elementsOriginal.length !== null &amp;&amp; elementsOriginal.length > 0)
590 {
591 var elements = [];
592 var elementsLength = elementsOriginal.length;
593 for (var x = 0; x &lt; elementsLength; x++) { elements[x] = elementsOriginal[x]; }
594
595 var elementsLength = elements.length;
596 for (var x = 0; x &lt; elementsLength; x++)
597 {
598 //elements[x].parentNode.removeChild(elements[x]);
599 CB_Elements.remove(elements[x]);
600 }
601 CB_Elements._classesCache[baseElement][classNames] = null;
602 }
603 }
604
605
606 CB_Elements._idCache = {};
607 /**
608 * Alias for {@link CB_Elements.id}.
609 * @function CB_Elements.byId
610 * @see {@link CB_Elements.id}
611 */
612 /**
613 * Alias for {@link CB_Elements.id}.
614 * @function CB_Elements.get
615 * @see {@link CB_Elements.id}
616 */
617 /**
618 * Alias for {@link CB_Elements.id}.
619 * @function CB_Elements.getById
620 * @see {@link CB_Elements.id}
621 */
622 /**
623 * Returns an element by its ID.
624 * @function
625 * @param {string} id - The identifier of the element that we want to find.
626 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_id_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
627 * @returns {Node|Object|null} Returns the elements (Node or object, depending on the web client). It will return null when not found.
628 */
629 CB_Elements.id = CB_Elements.byId = CB_Elements.get = CB_Elements.getById = function(id, useCache)
630 {
631 if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_id_USE_CACHE; }
632
633 id = CB_trim(id);//.toLowerCase();
634
635 //If no id is sent, returns null:
636 if (id === "") { return null; }
637
638 if (!useCache || typeof(CB_Elements._idCache[id]) === "undefined" || CB_Elements._idCache[id] === null)
639 {
640 if (document.getElementById)
641 {
642 CB_Elements._idCache[id] = document.getElementById(id);
643 }
644 else if (document.querySelector)
645 {
646 CB_Elements._idCache[id] = document.querySelector("#" + id);
647 }
648 else if (document.all)
649 {
650 if (typeof(document.all) !== "function")
651 {
652 CB_Elements._idCache[id] = document.all[id];
653 }
654 else { CB_Elements._idCache[id] = document.all(id); }
655 }
656 else if (document.layers)
657 {
658 CB_Elements._idCache[id] = document.layers[id];
659 }
660 else { CB_Elements._idCache[id] = null; }
661
662 CB_Elements._idCache[id] = CB_Elements._idCache[id] || null;
663 }
664
665 return CB_Elements._idCache[id];
666 }
667
668
669 /**
670 * Returns an element by its ID, updating (or creating) the internal cache. Calls the {@link CB_Elements.id} function internally, with the "useCache" parameter set to false.
671 * @function
672 * @param {string} id - The identifier of the element that we want to find.
673 * @returns {node|Object|null} Returns the elements (Node or object, depending on the web client). It will return null when not found.
674 */
675 CB_Elements.idCacheUpdate = function(id)
676 {
677 return CB_Elements.id(id, false);
678 }
679
680
681 /**
682 * Clears the internal cache used by {@link CB_Elements.id} and others. If no parameter is given, whole internal cache will be cleared.
683 * @function
684 * @param {string} [id] - The identifier of the element whose internal cache we want to clear. If not provided, it will clear the whole internal cache.
685 * @returns {Object} Returns the current internal cache after cleaning it (if it is has been possible), which is an associative array of one dimension (JavaScript object) whose first and unique index belongs to the identifier and the value belongs to each element.
686 */
687 CB_Elements.idCacheClear = function(id)
688 {
689 id = CB_trim(id);
690 if (id === "") { CB_Elements._idCache = {}; }
691 else { CB_Elements._idCache[id] = null; }
692 return CB_Elements._idCache;
693 }
694
695
696 /**
697 * Alias for {@link CB_Elements.idRemove}.
698 * @function CB_Elements.removeById
699 * @see {@link CB_Elements.idRemove}
700 */
701 /**
702 * Removes an element by its ID.
703 * @function
704 * @param {string} id - The identifier of the element that we want to delete.
705 * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_id_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before.
706 */
707 CB_Elements.idRemove = CB_Elements.removeById = function(id, useCache)
708 {
709 id = CB_trim(id);
710 if (id === "") { return; }
711 var element = CB_Elements.id(id, useCache);
712 //if (typeof(CB_Elements._idCache[id]) !== "undefined" &amp;&amp; CB_Elements._idCache[id] !== null)
713 //{
714 CB_Elements._idCache[id] = null;
715 //}
716 return CB_Elements.remove(element);
717 }
718
719
720 /**
721 * Removes an element given.
722 * @function
723 * @param {Node} element - The element that we want to delete.
724 */
725 CB_Elements.remove = function(element)
726 {
727 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
728 {
729 var elementParent = CB_Elements.getParent(element);
730 if (typeof(elementParent) !== "undefined" &amp;&amp; elementParent !== null &amp;&amp; typeof(elementParent.removeChild) !== "undefined" &amp;&amp; elementParent.removeChild !== null)
731 {
732 ///////return elementParent.removeChild(element);
733 elementParent.removeChild(element);
734 }
735 else if (typeof(element.removeNode) !== "undefined" &amp;&amp; element.removeNode !== null)
736 {
737 ///////return element.removeNode(true);
738 element.removeNode(true);
739 }
740 else if (document.all)
741 {
742 if (typeof(document.all) !== "function" &amp;&amp; element.id &amp;&amp; typeof(document.all[element.id]) !== "undefined" &amp;&amp; document.all[element.id] !== null)
743 {
744 document.all[element.id].innerHTML = document.all[element.id].outerHTML = "";
745 }
746 else if (element.id)
747 {
748 //Uses try-catch because otherwise it fails on IE 8:
749 try
750 {
751 document.all(element.id).innerHTML = document.all(element.id).outerHTML = "";
752 } catch(E) {}
753 }
754 }
755 else if (document.layers &amp;&amp; element.id)
756 {
757 document.layers[element.id].visibility = "hide";
758 delete document.layers[element.id];
759 }
760
761 if (typeof(element.remove) !== "undefined") { element.remove(); }
762 ///////////////delete(element); //Just in case (for some strange web clients). NOTE: commented since it gives problems with JSDoc ("ERROR: Unable to parse CB_Elements.js: Deleting local variable in strict mode").
763 element = null;
764 element = undefined;
765 }
766 }
767
768
769 /**
770 * Returns an array with the parents of a given element, with the topmost parent in the highest index:
771 * @function
772 * @param {Node} element - The element whose parents we want to get.
773 * @returns {array}
774 */
775 CB_Elements.getParents = function(element)
776 {
777 var elementParents = [];
778 var x = 0;
779 var currentParent;
780 while (currentParent = CB_Elements.getParent(element))
781 {
782 elementParents[x++] = currentParent;
783 element = currentParent;
784 }
785 return elementParents;
786 }
787
788
789 /**
790 * Returns an array with the parents of a given element (by its identifier), with the topmost parent in the highest index:
791 * @function
792 * @param {string} elementId - The identifier of the element whose parents we want to get.
793 * @returns {array}
794 */
795 CB_Elements.getParentsById = function(elementId)
796 {
797 return CB_Elements.getParents(CB_Elements.id(elementId));
798 }
799
800
801 /**
802 * Returns the first parent of a given element:
803 * @function
804 * @param {Node} element - The element whose parent we want to get.
805 * @returns {Node|null} Returns null if the parent cannot be found.
806 */
807 CB_Elements.getParent = function(element)
808 {
809 if (typeof(element) === "undefined" || element === null) { return null; }
810 var elementParent = null;
811 if (typeof(element.parentNode) !== "undefined" &amp;&amp; element.parentNode !== null)
812 {
813 elementParent = element.parentNode;
814 }
815 else if (typeof(element.parentElement) !== "undefined" &amp;&amp; element.parentElement !== null)
816 {
817 elementParent = element.parentElement;
818 }
819 return elementParent;
820 }
821
822
823 /**
824 * Returns the first parent of a given element (by its identifier):
825 * @function
826 * @param {string} elementId - The identifier of the element whose parent we want to get.
827 * @returns {Node|null} Returns null if the parent cannot be found.
828 */
829 CB_Elements.getParentById = function(elementId)
830 {
831 return CB_Elements.getParent(CB_Elements.id(elementId));
832 }
833
834
835 /**
836 * Changes a desired element property with the given value.
837 * @function
838 * @param {Node} element - The element whose property we want to modify.
839 * @param {string} property - The name of the property that we want to modify.
840 * @param {*} propertyValue - The value desired for the property.
841 * @param {boolean} [checkValues=false] - If set to true, it will only modify the property if the current value is different from the given one.
842 * @param {function} [onSetProperty] - Callback function that will be called if the property of the element has been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
843 * @returns {Node|null} Returns the given element again or null.
844 */
845 CB_Elements.setProperty = function(element, property, propertyValue, checkValues, onSetProperty)
846 {
847 if (typeof(element) === "undefined" || element === null) { return null; }
848 if (!checkValues || element[property] !== propertyValue)
849 {
850 element[property] = propertyValue;
851 if (typeof(onSetProperty) === "function") { onSetProperty(element); }
852 }
853 return element;
854 }
855
856
857 /**
858 * Changes a desired element property with the given value (by its identifier).
859 * @function
860 * @param {string} elementId - The identifier of the element whose property we want to modify.
861 * @param {string} property - The name of the property that we want to modify.
862 * @param {*} propertyValue - The value desired for the property.
863 * @param {boolean} [checkValues=false] - If set to true, it will only modify the property if the current value is different from the given one.
864 * @param {function} [onSetProperty] - Callback function that will be called if the property of the element has been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
865 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
866 */
867 CB_Elements.setPropertyById = function(elementId, property, propertyValue, checkValues, onSetProperty)
868 {
869 return CB_Elements.setProperty(CB_Elements.id(elementId), property, propertyValue, checkValues, onSetProperty);
870 }
871
872
873 /**
874 * Inserts the desired content inside a given element (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}).
875 * @function
876 * @param {Node} container - The element whose content we want to modify.
877 * @param {string} content - The content that we want to add.
878 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
879 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
880 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
881 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the container itself.
882 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
883 * @param {boolean} [append=false] - If set to true, it will append the given content to the existing one instead of overwritten it. By default, it appends it at the end unless that the "appendAtBeginning" is set to true.
884 * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it.
885 * @returns {Node} Returns the given container again.
886 */
887 CB_Elements.insertContent = function(container, content, displayValue, checkValues, computed, onContentWritten, onShow, append, appendAtBeginning)
888 {
889 if (container !== null)
890 {
891 if (!checkValues || append || container.innerHTML !== content)
892 {
893 if (append)
894 {
895 container.innerHTML = appendAtBeginning ? content + container.innerHTML : container.innerHTML + content;
896 }
897 else { container.innerHTML = content; }
898 if (typeof(onContentWritten) === "function") { onContentWritten(container); }
899 }
900 if (displayValue) { CB_Elements.show(container, displayValue, checkValues, computed, onShow); }
901 }
902 return container;
903 }
904
905
906 /**
907 * Appends the desired content inside a given element, keeping the existing one (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}). Calls the {@link CB_Elements.insertContent} internally.
908 * @function
909 * @param {Node} container - The element whose content we want to modify.
910 * @param {string} content - The content that we want to add.
911 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
912 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
913 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
914 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the container itself.
915 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
916 * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it.
917 * @returns {Node} Returns the given container again.
918 */
919 CB_Elements.appendContent = function(container, content, displayValue, checkValues, computed, onContentWritten, onShow, appendAtBeginning)
920 {
921 return CB_Elements.insertContent(container, content, displayValue, checkValues, computed, onContentWritten, onShow, true, appendAtBeginning);
922 }
923
924
925 /**
926 * Appends the desired content inside a given element at the beginning, keeping the existing one (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}). Calls the {@link CB_Elements.insertContent} internally.
927 * @function
928 * @param {Node} container - The element whose content we want to modify.
929 * @param {string} content - The content that we want to add.
930 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
931 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
932 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
933 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the container itself.
934 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
935 * @returns {Node} Returns the given container again.
936 */
937 CB_Elements.appendContentBeginning = function(container, content, displayValue, checkValues, computed, onContentWritten, onShow)
938 {
939 return CB_Elements.insertContent(container, content, displayValue, checkValues, computed, onContentWritten, onShow, true, true);
940 }
941
942
943 /**
944 * Inserts the desired content inside a given element (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}), by its identifier.
945 * @function
946 * @param {string} containerId - The identifier of the element whose content we want to modify.
947 * @param {string} content - The content that we want to add.
948 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
949 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
950 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
951 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the affected container itself.
952 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
953 * @param {boolean} [append=false] - If set to true, it will append the given content to the existing one instead of overwritten it. By default, it appends it at the end unless that the "appendAtBeginning" is set to true.
954 * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it.
955 * @returns {Node|null} Returns the affected container (if any) or null otherwise.
956 */
957 CB_Elements.insertContentById = function(containerId, content, displayValue, checkValues, computed, onContentWritten, onShow, append, appendAtBeginning)
958 {
959 return CB_Elements.insertContent(CB_Elements.id(containerId), content, displayValue, checkValues, computed, onContentWritten, onShow, append, appendAtBeginning);
960 }
961
962
963 /**
964 * Appends the desired content inside a given element, keeping the existing one (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}), by its identifier. Calls the {@link CB_Elements.insertContent} internally.
965 * @function
966 * @param {string} containerId - The identifier of the element whose content we want to modify.
967 * @param {string} content - The content that we want to add.
968 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
969 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
970 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
971 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the affected container itself.
972 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
973 * @param {boolean} [append=false] - If set to true, it will append the given content to the existing one instead of overwritten it. By default, it appends it at the end unless that the "appendAtBeginning" is set to true.
974 * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it.
975 * @returns {Node|null} Returns the affected container (if any) or null otherwise.
976 */
977 CB_Elements.appendContentById = function(containerId, content, displayValue, checkValues, computed, onContentWritten, onShow, appendAtBeginning)
978 {
979 return CB_Elements.insertContent(CB_Elements.id(containerId), content, displayValue, checkValues, computed, onContentWritten, onShow, true, appendAtBeginning);
980 }
981
982
983 /**
984 * Appends the desired content inside a given element at the beginning, keeping the existing one (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}), by its identifier. Calls the {@link CB_Elements.insertContent} internally.
985 * @function
986 * @param {string} containerId - The identifier of the element whose content we want to modify.
987 * @param {string} content - The content that we want to add.
988 * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element.
989 * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
990 * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given).
991 * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the affected container itself.
992 * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally.
993 * @param {boolean} [append=false] - If set to true, it will append the given content to the existing one instead of overwritten it. By default, it appends it at the end unless that the "appendAtBeginning" is set to true.
994 * @returns {Node|null} Returns the affected container (if any) or null otherwise.
995 */
996 CB_Elements.appendContentByIdBeginning = function(containerId, content, displayValue, checkValues, computed, onContentWritten, onShow)
997 {
998 return CB_Elements.insertContent(CB_Elements.id(containerId), content, displayValue, checkValues, computed, onContentWritten, onShow, true, true);
999 }
1000
1001
1002 /**
1003 * Returns the style of an element, computed or static:
1004 * @function
1005 * @param {Node} element - The element whose style property we want to get.
1006 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1007 * @returns {Object|null} Returns an associative array (JavaScript object) with all the styles retrieved or null if nothing can be retrieved.
1008 */
1009 CB_Elements.getStyle = function(element, computed)
1010 {
1011 if (typeof(element) === "undefined" || element === null) { return null; }
1012
1013 if (computed)
1014 {
1015 if ("getComputedStyle" in window &amp;&amp; window.getComputedStyle)
1016 {
1017 return window.getComputedStyle(element, null);
1018 }
1019 else if (element.currentStyle)
1020 {
1021 return element.currentStyle;
1022 }
1023 }
1024
1025 if (element.style)
1026 {
1027 return element.style;
1028 }
1029
1030 return null;
1031 }
1032
1033
1034 /**
1035 * Returns the style of an element, computed or static (by its identifier):
1036 * @function
1037 * @param {string} elementId - The identifier of the element whose style property we want to get.
1038 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1039 * @returns {Object|null} Returns an associative array (JavaScript object) with all the styles retrieved or null if nothing can be retrieved.
1040 */
1041 CB_Elements.getStyleById = function(elementId, computed)
1042 {
1043 return CB_Elements.getStyle(CB_Elements.id(elementId), computed);
1044 }
1045
1046
1047 /**
1048 * Returns the desired attribute value from the style of an element, computed or static:
1049 * @function
1050 * @param {Node} element - The element whose attribute value from its style we want to get.
1051 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1052 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1053 * @returns {*} Returns null if nothing can be retrieved.
1054 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1055 */
1056 CB_Elements.getStyleProperty = function(element, attribute, computed)
1057 {
1058 //If we have received a string instead of an element, we try to get an element with that string as id:
1059 //if (CB_isString(element)) { element = CB_Elements.id(element); }
1060
1061 var elementStyle = CB_Elements.getStyle(element, computed);
1062 if (elementStyle !== null &amp;&amp; typeof(elementStyle[attribute]) !== "undefined") { return elementStyle[attribute]; }
1063
1064 return null;
1065 }
1066
1067
1068 /**
1069 * Returns the desired attribute value from the style of an element, computed or static (by its identifier):
1070 * @function
1071 * @param {string} elementId - The identifier of the element whose attribute value from its style we want to get.
1072 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1073 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1074 * @returns {*} Returns null if nothing can be retrieved.
1075 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1076 */
1077 CB_Elements.getStylePropertyById = function(elementId, attribute, computed)
1078 {
1079 return CB_Elements.getStyleProperty(CB_Elements.id(elementId), attribute, computed);
1080 }
1081
1082
1083 /**
1084 * Returns the integer value or values (base decimal) of a desired attribute from the style of an element, computed or static:
1085 * @function
1086 * @param {Node} element - The element whose attribute value from its style we want to get.
1087 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1088 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1089 * @returns {array} Returns a numeric array with the values retrieved. If nothing could be retrieved, the first and unique index of the array will contain the value of zero (0).
1090 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1091 */
1092 CB_Elements.getStylePropertyInteger = function(element, attribute, computed)
1093 {
1094 return CB_Elements.getStylePropertyNumeric(element, attribute, computed, true);
1095 }
1096
1097
1098 /**
1099 * Returns the integer value or values (base decimal) of a desired attribute from the style of an element, computed or static (by its identifier):
1100 * @function
1101 * @param {string} elementId - The identifier of the element whose attribute value from its style we want to get.
1102 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1103 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1104 * @returns {array} Returns a numeric array with the values retrieved. If nothing could be retrieved, the first and unique index of the array will contain the value of zero (0).
1105 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1106 */
1107 CB_Elements.getStylePropertyIntegerById = function(elementId, attribute, computed)
1108 {
1109 return CB_Elements.getStylePropertyInteger(CB_Elements.id(elementId), attribute, computed);
1110 }
1111
1112
1113 /**
1114 * Returns the numeric value or values (base decimal) of a desired attribute from the style of an element, computed or static:
1115 * @function
1116 * @param {Node} element - The element whose attribute value from its style we want to get.
1117 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1118 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1119 * @param {boolean} [parseToInteger=false] - If it is set to true, the value or values will be parsed to integer.
1120 * @returns {array} Returns a numeric array with the values retrieved. If nothing could be retrieved, the first and unique index of the array will contain the value of zero (0).
1121 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1122 */
1123 CB_Elements.getStylePropertyNumeric = function(element, attribute, computed, parseToInteger)//, parseToFloat)
1124 {
1125 var propertyValue = CB_Elements.getStyleProperty(element, attribute, computed);
1126 var propertyValuesNumeric = [];
1127
1128 if (typeof(propertyValue) !== "undefined" &amp;&amp; propertyValue !== null)
1129 {
1130 var propertyValues = propertyValue.split(" ");
1131 var propertyValuesLength = propertyValues.length;
1132 var y = 0;
1133 for (x = 0; x &lt; propertyValues.length; x++)
1134 {
1135 propertyValue = parseFloat(propertyValues[x]);
1136 if (typeof(propertyValue) !== "undefined" &amp;&amp; propertyValue !== null &amp;&amp; !isNaN(propertyValue))
1137 {
1138 if (parseToInteger) { propertyValue = parseInt(propertyValue, 10); }
1139 //if (parseToFloat) { propertyValue = parseFloat(propertyValue); }
1140 //else { propertyValue = parseFloat(propertyValue); }
1141
1142 propertyValuesNumeric[y++] = propertyValue;
1143 //break;
1144 }
1145 }
1146 }
1147
1148 //if (propertyValue === null || CB_trim(propertyValue) === "") { propertyValue = 0; }
1149 if (propertyValuesNumeric.length === 0) { propertyValuesNumeric[0] = 0; } //If there are no values, it will returns 0 as the unique one.
1150 //if (isNaN(propertyValue)) { propertyValue = 0; }
1151 //if (isNaN(propertyValue)) { propertyValue = 0; }
1152
1153 //return propertyValue;
1154 return propertyValuesNumeric;
1155 }
1156
1157
1158 /**
1159 * Returns the numeric value or values (base decimal) of a desired attribute from the style of an element, computed or static (by its identifier):
1160 * @function
1161 * @param {string} elementId - The identifier of the element whose attribute value from its style we want to get.
1162 * @param {string} attribute - The name of the attribute whose value we want to get from the style.
1163 * @param {boolean} [computed=false] - If it is set to true, it will try to use the native function [window.getComputedStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle} (if available).
1164 * @param {boolean} [parseToInteger=false] - If it is set to true, the value or values will be parsed to integer.
1165 * @returns {array} Returns a numeric array with the values retrieved. If nothing could be retrieved, the first and unique index of the array will contain the value of zero (0).
1166 * @todo Think about supporting a boolean parameter to try to find the attribute having into account vendor prefixes (webkit, moz, ms, o, khtml).
1167 */
1168 CB_Elements.getStylePropertyNumericById = function(elementId, attribute, computed, parseToInteger, parseToFloat)
1169 {
1170 return CB_Elements.getStylePropertyNumeric(CB_Elements.id(elementId), attribute, computed, parseToInteger, parseToFloat);
1171 }
1172
1173
1174 /**
1175 * Toggles the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (from "none" to the desired value or vice versa) of a given element, to show or hide it.
1176 * If the element is hidden (its [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} is "none"), it will call {@link CB_Elements.show} internally to show it. Otherwise, it will call {@link CB_Elements.hide} internally. Note that these two functions will also change the [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property (setting it to either "visible" or "hidden", respectively) of the element.
1177 * @function
1178 * @param {Node} element - The element whose [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property we want to toggle.
1179 * @param {string} [displayValue='block'] - The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value when we want to show the element (it will be used only if the element is currently hidden, when it calls {@link CB_Elements.show} internally). The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value to hide the element is always "none".
1180 * @param {boolean} [checkValues=false] - This parameter will be used when it calls either {@link CB_Elements.show} or {@link CB_Elements.hide} internally.
1181 * @param {boolean} [computed=false] - This parameter will be used to get the current style and also when it calls either {@link CB_Elements.show} or {@link CB_Elements.hide} internally.
1182 * @param {function} [onToggleDisplay] - This parameter will be used when it calls either {@link CB_Elements.show} if "onShow" is not provided or {@link CB_Elements.hide} if "onHide" is not provided, internally.
1183 * @param {function} [onShow] - This parameter will be used when it calls {@link CB_Elements.show} internally. If not provided but "onToggleDisplay" is provided, it will use the latter instead.
1184 * @param {function} [onHide] - This parameter will be used when it calls {@link CB_Elements.hide} internally. If not provided but "onToggleDisplay" is provided, it will use the latter instead.
1185 * @returns {Node} Returns the given element again.
1186 */
1187 CB_Elements.showHide = function(element, displayValue, checkValues, computed, onToggleDisplay, onShow, onHide)
1188 {
1189 var style = CB_Elements.getStyle(element, computed);
1190 if (style !== null)
1191 {
1192 if (style.display === "none") { CB_Elements.show(element, displayValue, checkValues, computed, typeof(onToggleDisplay) === "function" ? onToggleDisplay : onShow); }
1193 else { CB_Elements.hide(element, checkValues, computed, typeof(onToggleDisplay) === "function" ? onToggleDisplay : onHide); }
1194 }
1195 return element;
1196 }
1197
1198
1199 /**
1200 * Toggles the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (from "none" to the desired value or vice versa) of a given element, to show or hide it (by its identifier).
1201 * If the element is hidden (its [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} is "none"), it will call {@link CB_Elements.show} internally to show it. Otherwise, it will call {@link CB_Elements.hide} internally. Note that these two functions will also change the [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property (setting it to either "visible" or "hidden", respectively) of the element.
1202 * @function
1203 * @param {string} elementId - The identifier of the element whose [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property we want to toggle.
1204 * @param {string} [displayValue='block'] - The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value when we want to show the element (it will be used only if the element is currently hidden, when it calls {@link CB_Elements.show} internally). The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value to hide the element is always "none".
1205 * @param {boolean} [checkValues=false] - This parameter will be used when it calls either {@link CB_Elements.show} or {@link CB_Elements.hide} internally.
1206 * @param {boolean} [computed=false] - This parameter will be used to get the current style and also when it calls either {@link CB_Elements.show} or {@link CB_Elements.hide} internally.
1207 * @param {function} [onToggleDisplay] - This parameter will be used when it calls either {@link CB_Elements.show} if "onShow" is not provided or {@link CB_Elements.hide} if "onHide" is not provided, internally.
1208 * @param {function} [onShow] - This parameter will be used when it calls {@link CB_Elements.show} internally. If not provided but "onToggleDisplay" is provided, it will use the latter instead.
1209 * @param {function} [onHide] - This parameter will be used when it calls {@link CB_Elements.hide} internally. If not provided but "onToggleDisplay" is provided, it will use the latter instead.
1210 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1211 */
1212 CB_Elements.showHideById = function(elementId, displayValue, checkValues, computed, onToggleDisplay, onShow, onHide)
1213 {
1214 return CB_Elements.showHide(CB_Elements.id(elementId), displayValue, checkValues, computed, onToggleDisplay, onShow, onHide);
1215 }
1216
1217
1218 /**
1219 * Changes the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the desired value of a given element, to show it. Its [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property will be set to "visible".
1220 * @function
1221 * @param {Node} element - The element whose [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property we want to change.
1222 * @param {string} [displayValue='block'] - The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value we want to set. If not provided or "none" is provided, it will use "block" instead.
1223 * @param {boolean} [checkValues=false] - If it is set to true, it will only perform the change if either the current [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property is not "visible" or the current [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property is different from the given one.
1224 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyle} internally.
1225 * @param {function} [onShow] - Callback function that will be called if the change has been performed, after doing it (this will happens always if "checkValues" is false). The first parameter passed will be the affected element itself and the second and last parameter will be the new value of the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (not computed).
1226 * @returns {Node} Returns the given element again.
1227 */
1228 CB_Elements.show = function(element, displayValue, checkValues, computed, onShow)
1229 {
1230 var style = CB_Elements.getStyle(element, computed);
1231 if (style !== null)
1232 {
1233 displayValue = CB_trim(displayValue);
1234 if (displayValue === "" || displayValue.toLowerCase() === "none") { displayValue = "block"; }
1235 if (!checkValues || style.visibility !== "visible" || style.display !== displayValue)
1236 {
1237 element.style.visibility = "visible";
1238 element.style.display = displayValue;
1239 if (typeof(onShow) === "function") { onShow(element, element.style.display); }
1240 }
1241 }
1242 return element;
1243 }
1244
1245
1246 /**
1247 * Changes the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the desired value of a given element, to show it (by its identifier). Its [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property will be set to "visible".
1248 * @function
1249 * @param {string} elementId - The identifier of the element whose [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property we want to change.
1250 * @param {string} [displayValue='block'] - The [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} value we want to set. If not provided or "none" is provided, it will use "block" instead.
1251 * @param {boolean} [checkValues=false] - If it is set to true, it will only perform the change if either the current [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property is not "visible" or the current [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property is different from the given one.
1252 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyle} internally.
1253 * @param {function} [onShow] - Callback function that will be called if the change has been performed, after doing it (this will happens always if "checkValues" is false). The first parameter passed will be the affected element itself and the second and last parameter will be the new value of the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (not computed).
1254 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1255 */
1256 CB_Elements.showById = function(elementId, displayValue, checkValues, computed, onShow)
1257 {
1258 return CB_Elements.show(CB_Elements.id(elementId), displayValue, checkValues, computed, onShow);
1259 }
1260
1261
1262 /**
1263 * Hides a given element by changing its [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to "none" and its [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} to "hidden".
1264 * @function
1265 * @param {Node} element - The element that we want to hide.
1266 * @param {boolean} [checkValues=false] - If it is set to true, it will only perform the change if either the current [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property is not "hidden" or the current [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property is not "none".
1267 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyle} internally.
1268 * @param {function} [onHide] - Callback function that will be called if the element has been hidden, after doing it (this will happens always if "checkValues" is false). The first parameter passed will be the affected element itself and the second and last parameter will be the new value of the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (not computed) which should be "none".
1269 * @returns {Node} Returns the given element again.
1270 */
1271 CB_Elements.hide = function(element, checkValues, computed, onHide)
1272 {
1273 var style = CB_Elements.getStyle(element, computed);
1274 if (style !== null)
1275 {
1276 if (!checkValues || style.visibility !== "hidden" || style.display !== "none")
1277 {
1278 element.style.visibility = "hidden";
1279 element.style.display = "none";
1280 if (typeof(onHide) === "function") { onHide(element, element.style.display); }
1281 }
1282 }
1283 return element;
1284 }
1285
1286
1287 /**
1288 * Hides a given element by changing its [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to "none" and its [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} to "hidden" (by its identifier).
1289 * @function
1290 * @param {string} elementId - The identifier of the element that we want to hide.
1291 * @param {boolean} [checkValues=false] - If it is set to true, it will only perform the change if either the current [visibility]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/visibility} property is not "hidden" or the current [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property is not "none".
1292 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyle} internally.
1293 * @param {function} [onHide] - Callback function that will be called if the element has been hidden, after doing it (this will happens always if "checkValues" is false). The first parameter passed will be the affected element itself and the second and last parameter will be the new value of the [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property (not computed) which should be "none".
1294 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1295 */
1296 CB_Elements.hideById = function(elementId, checkValues, computed, onHide)
1297 {
1298 return CB_Elements.hide(CB_Elements.id(elementId), checkValues, computed, onHide);
1299 }
1300
1301
1302 /**
1303 * Toggles the class of a given element between two given classes or adds/removes the given class. The element can contain other classes and they will be kept.
1304 * @function
1305 * @param {Node} element - The element whose class we want to toggle.
1306 * @param {string} classA - The class that will be used in the case that the element is not using it already.
1307 * @param {string} [classB=''] - The class that will be used in the case that the given "classA" is being used by the element. If not given or an empty string is given, it will just remove the "classA" in the case it is being used by the element.
1308 * @param {function} [onToggleClass] - Callback function that will be called if the class of the element has been toggled or removed, after doing it. The first parameter passed will be the affected element itself and the second and last parameter will be the class used this time (or an empty string).
1309 * @returns {Node} Returns the given element again.
1310 */
1311 CB_Elements.toggleClass = function(element, classA, classB, onToggleClass)
1312 {
1313 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1314 {
1315 classA = CB_trim(classA).toLowerCase();
1316 classB = CB_trim(classB).toLowerCase();
1317 if (classA === "" &amp;&amp; classB === "") { return element; }
1318 else if (classA === "") { classA = classB; classB = ""; }
1319
1320 var classesUsed = " " + CB_trim(element.className).toLowerCase() + " ";
1321 if (classesUsed.indexOf(" " + classA + " ") === -1)
1322 {
1323 if (classB !== "" &amp;&amp; classesUsed.indexOf(" " + classB + " ") !== -1) { classesUsed = classesUsed.replace(CB_regularExpressionString(" " + classB + " ", true, true), " " + classA + " "); }
1324 else { classesUsed += " " + classA; }
1325 element.className = CB_trim(classesUsed);
1326 if (typeof(onToggleClass) === "function") { onToggleClass(element, classA); }
1327 }
1328 else
1329 {
1330 classesUsed = classesUsed.replace(CB_regularExpressionString(" " + classA + " ", true, true), " ");
1331 if (classB !== "" &amp;&amp; classesUsed.indexOf(" " + classB + " ") === -1) { classesUsed += " " + classB; }
1332 element.className = CB_trim(classesUsed);
1333 if (typeof(onToggleClass) === "function") { onToggleClass(element, classB); }
1334 }
1335 }
1336 return element;
1337 }
1338
1339
1340 /**
1341 * Toggles the class of a given element between two given classes (by its identifier). The element can contain other classes and they will be kept.
1342 * @function
1343 * @param {string} elementId - The identifier of the element whose class we want to toggle.
1344 * @param {string} classA - The class that will be used in the case that the element is not using it already.
1345 * @param {string} [classB=''] - The class that will be used in the case that the given "classA" is being used by the element. If not given or an empty string is given, it will just remove the "classA" in the case it is being used by the element.
1346 * @param {function} [onToggleClass] - Callback function that will be called if the class of the element has been toggled or removed, after doing it. The first parameter passed will be the affected element itself and the second and last parameter will be the class used this time (or an empty string).
1347 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1348 */
1349 CB_Elements.toggleClassById = function(elementId, classA, classB, onToggleClass)
1350 {
1351 return CB_Elements.toggleClass(CB_Elements.id(elementId), classA, classB, onToggleClass);
1352 }
1353
1354
1355 /**
1356 * Removes a desired class from a given element. The element can contain other classes and they will be kept.
1357 * @function
1358 * @param {Node} element - The element whose class we want to remove.
1359 * @param {string} className - The class that will be removed if the element is using it.
1360 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to perform the action if the given "className" is being used. The result will be the same with either true or false, but depending on the client used it could gain or lose performance.
1361 * @param {function} [onRemoveClass] - Callback function that will be called if the class of the element has been tried to be removed, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1362 * @returns {Node} Returns the given element again.
1363 * @todo Think about allowing to remove more than once class at the same time, regardless of the order given and order set.
1364 */
1365 CB_Elements.removeClass = function(element, className, checkValues, onRemoveClass)
1366 {
1367 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1368 {
1369 className = CB_trim(className).toLowerCase();
1370 if (className === "") { return element; }
1371 var classesUsed = " " + CB_trim(element.className).toLowerCase() + " ";
1372 if (!checkValues || classesUsed.indexOf(" " + className + " ") !== -1)
1373 {
1374 element.className = CB_trim(classesUsed.replace(CB_regularExpressionString(" " + className + " ", true, true), " "));
1375 if (typeof(onRemoveClass) === "function") { onRemoveClass(element); }
1376 }
1377 }
1378 return element;
1379 }
1380
1381
1382 /**
1383 * Removes a desired class from a given element (by its identifier). The element can contain other classes and they will be kept.
1384 * @function
1385 * @param {string} elementId - The identifier of the element whose class we want to remove.
1386 * @param {string} className - The class that will be removed if the element is using it.
1387 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to perform the action if the given "className" is being used. The result will be the same with either true or false, but depending on the client used it could gain or lose performance.
1388 * @param {function} [onRemoveClass] - Callback function that will be called if the class of the element has been tried to be removed, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1389 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1390 * @todo Think about allowing to remove more than once class at the same time, regardless of the order given and order set.
1391 */
1392 CB_Elements.removeClassById = function(elementId, className, checkValues, onRemoveClass)
1393 {
1394 return CB_Elements.removeClass(CB_Elements.id(elementId), className, checkValues, onRemoveClass);
1395 }
1396
1397
1398 /**
1399 * Adds a desired class to a given element. The element can contain other classes and they will be kept.
1400 * @function
1401 * @param {Node} element - The element that will get the new given class.
1402 * @param {string} className - The class that will be added.
1403 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to add the given class if it is not being used already. It is recommended to use true to prevent some old clients from adding the same class multiple times.
1404 * @param {function} [onAddClass] - Callback function that will be called if the class of the element has been added, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1405 * @returns {Node} Returns the given element again.
1406 * @todo Think about allowing to use more than once class (and think how many times the "onAddClass" function should be called).
1407 */
1408 CB_Elements.addClass = function(element, className, checkValues, onAddClass)
1409 {
1410 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1411 {
1412 className = CB_trim(className).toLowerCase();
1413 if (className === "") { return element; }
1414 var classesUsed = " " + CB_trim(element.className).toLowerCase() + " ";
1415 if (!checkValues || classesUsed.indexOf(" " + className + " ") === -1)
1416 {
1417 element.className = CB_trim(CB_trim(classesUsed) + " " + className);
1418 if (typeof(onAddClass) === "function") { onAddClass(element); }
1419 }
1420 }
1421 return element;
1422 }
1423
1424
1425 /**
1426 * Adds a desired class to a given element (by its identifier). The element can contain other classes and they will be kept.
1427 * @function
1428 * @param {string} elementId - The identifier of the element that will get the new given class.
1429 * @param {string} className - The class that will be added.
1430 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to add the given class if it is not being used already. It is recommended to use true to prevent some old clients from adding the same class multiple times.
1431 * @param {function} [onAddClass] - Callback function that will be called if the class of the element has been added, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1432 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1433 * @todo Think about allowing to use more than once class (and think how many times the "onAddClass" function should be called).
1434 */
1435 CB_Elements.addClassById = function(elementId, className, checkValues, onAddClass)
1436 {
1437 return CB_Elements.addClass(CB_Elements.id(elementId), className, checkValues, onAddClass);
1438 }
1439
1440
1441 /**
1442 * Sets a desired class or classes to a given element. All previous classes (if any) will be replaced by the new one or new ones.
1443 * @function
1444 * @param {Node} element - The element that will get the new given class or classes.
1445 * @param {string} classNames - The class or classes that will be set. More than one class can be given (separated by blank spaces).
1446 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to set the given class or classes if they are not being used already.
1447 * @param {function} [onSetClass] - Callback function that will be called if the class or classes of the element have been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1448 * @returns {Node} Returns the given element again.
1449 */
1450 CB_Elements.setClass = function(element, classNames, checkValues, onSetClass)
1451 {
1452 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1453 {
1454 if (!checkValues || element.className !== classNames)
1455 {
1456 element.className = classNames;
1457 if (typeof(onSetClass) === "function") { onSetClass(element); }
1458 }
1459 }
1460 return element;
1461 }
1462
1463
1464 /**
1465 * Sets a desired class or classes to a given element (by its identifier). All previous classes (if any) will be replaced by the new one or new ones.
1466 * @function
1467 * @param {string} elementId - The identifier of the element that will get the new given class or classes.
1468 * @param {string} classNames - The class or classes that will be set. More than one class can be given (separated by blank spaces).
1469 * @param {boolean} [checkValues=false] - If it is set to true, it will only try to set the given class or classes if they are not being used already.
1470 * @param {function} [onSetClass] - Callback function that will be called if the class or classes of the element have been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself.
1471 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1472 */
1473 CB_Elements.setClassById = function(elementId, classNames, checkValues, onSetClass)
1474 {
1475 return CB_Elements.setClass(CB_Elements.id(elementId), classNames, checkValues, onSetClass);
1476 }
1477
1478
1479 /**
1480 * Returns the left position of an element (having in mind [getBoundingClientRect]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect} if available, its parents, etc.).
1481 * @function
1482 * @param {Node} element - The element whose data we are interested in.
1483 * @param {boolean} [ignoreScroll=true] - If it is set to false, it will have in mind the current scroll position to calculate the result.
1484 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1485 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyleProperty} and {@link CB_Elements.getStylePropertyInteger} internally.
1486 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1487 */
1488 CB_Elements.getLeft = function(element, ignoreScroll, returnNullOnFail, computed)
1489 {
1490 if (typeof(element) === "undefined" || element === null) { return returnNullOnFail ? null : 0; }
1491
1492 //If it's not set, we mind scroll as default:
1493 if (typeof(ignoreScroll) === "undefined" || ignoreScroll === null) { ignoreScroll = true; }
1494
1495 var elementLeft = 0;
1496 var originalElement = true;
1497
1498 if (typeof(element.getBoundingClientRect) !== "undefined" &amp;&amp; element.getBoundingClientRect !== null)
1499 {
1500 var rect = element.getBoundingClientRect();
1501 if (typeof(rect.left) !== "undefined" &amp;&amp; rect.left !== null &amp;&amp; !isNaN(rect.left))
1502 {
1503 elementLeft = rect.left;
1504 elementLeft -= CB_Client.getBoundingClientRectMargin("left");
1505 if (ignoreScroll) { elementLeft += CB_Screen.getScrollLeft(); }
1506 return elementLeft;
1507 }
1508 }
1509
1510 //Gets the left position having in mind its parents (if any) and adds them:
1511 do
1512 {
1513 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1514 {
1515 var elementPosition = CB_Elements.getStyleProperty(element, "position", computed);
1516 if (elementPosition === "absolute")
1517 {
1518 if (typeof(getComputedStyle) !== "undefined" &amp;&amp; getComputedStyle !== null)
1519 {
1520 if (element !== document &amp;&amp; !isNaN(parseInt(getComputedStyle(element, "").getPropertyValue("left"))))
1521 {
1522 elementLeft += parseInt(getComputedStyle(element, "").getPropertyValue("left"));
1523 }
1524 else if (!isNaN(parseInt(getComputedStyle(document.body, "").getPropertyValue("left"))))
1525 {
1526 elementLeft += parseInt(getComputedStyle(document.body, "").getPropertyValue("left"));
1527 }
1528
1529 ////////elementLeft += CB_Elements.getStylePropertyInteger(element, "borderLeftWidth")[0];
1530 ////////elementLeft += CB_Elements.getStylePropertyInteger(element, "paddingLeft")[0];
1531 elementLeft += CB_Elements.getStylePropertyInteger(element, "borderLeftWidth", computed)[0];
1532 elementLeft += CB_Elements.getStylePropertyInteger(element, "paddingLeft", computed)[0];
1533
1534
1535 if (originalElement)
1536 {
1537 ///////elementLeft -= CB_Elements.getStylePropertyInteger(element, "border")[0];
1538 elementLeft -= CB_Elements.getStylePropertyInteger(element, "border", computed)[0];
1539 originalElement = false;
1540 }
1541 }
1542 else if (typeof(element.offsetLeft) !== "undefined" &amp;&amp; element.offsetLeft !== null &amp;&amp; !isNaN(parseInt(element.offsetLeft)))
1543 {
1544 elementLeft += parseInt(element.offsetLeft, 10);
1545 }
1546 }
1547 else
1548 {
1549 if (typeof(element.offsetLeft) !== "undefined" &amp;&amp; element.offsetLeft !== null &amp;&amp; !isNaN(parseInt(element.offsetLeft)))
1550 {
1551 elementLeft += parseInt(element.offsetLeft, 10);
1552 }
1553 }
1554 }
1555
1556 if (typeof(element.offsetParent) !== "undefined" &amp;&amp; element.offsetParent !== null)
1557 {
1558 element = element.offsetParent;
1559 }
1560 /*
1561 else if (typeof(element.parentNode) !== "undefined" &amp;&amp; element.parentNode !== null)
1562 {
1563 element = element.parentNode;
1564 }
1565 else if (typeof(element.parentElement) !== "undefined" &amp;&amp; element.parentElement !== null)
1566 {
1567 element = element.parentElement;
1568 }
1569 */
1570 else
1571 {
1572 var elementParent = CB_Elements.getParent(element);
1573 if (typeof(elementParent) !== "undefined" &amp;&amp; elementParent !== null)
1574 {
1575 element = elementParent;
1576 }
1577 else { element = null; }
1578 }
1579
1580 } while (element)
1581
1582 if (!ignoreScroll) { elementLeft -= CB_Screen.getScrollLeft(); }
1583
1584 return isNaN(elementLeft) &amp;&amp; returnNullOnFail ? null : elementLeft;
1585 }
1586
1587
1588 /**
1589 * Returns the left position of an element (having in mind [getBoundingClientRect]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect} if available, its parents, etc.), by its identifier.
1590 * @function
1591 * @param {string} elementId - The identifier of the element whose data we are interested in.
1592 * @param {boolean} [ignoreScroll=true] - If it is set to false, it will have in mind the current scroll position to calculate the result.
1593 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1594 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyleProperty} and {@link CB_Elements.getStylePropertyInteger} internally.
1595 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1596 */
1597 CB_Elements.getLeftById = function(elementId, ignoreScroll, returnNullOnFail, computed)
1598 {
1599 return CB_Elements.getLeft(CB_Elements.id(elementId), ignoreScroll, returnNullOnFail, computed);
1600 }
1601
1602
1603 /**
1604 * Returns the top position of an element (having in mind [getBoundingClientRect]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect} if available, its parents, etc.).
1605 * @function
1606 * @param {Node} element - The element whose data we are interested in.
1607 * @param {boolean} [ignoreScroll=true] - If it is set to false, it will have in mind the current scroll position to calculate the result.
1608 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1609 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyleProperty} and {@link CB_Elements.getStylePropertyInteger} internally.
1610 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1611 */
1612 CB_Elements.getTop = function(element, ignoreScroll, returnNullOnFail, computed)
1613 {
1614 if (typeof(element) === "undefined" || element === null) { return returnNullOnFail ? null : 0; }
1615
1616 //If it's not set, we mind scroll as default:
1617 if (typeof(ignoreScroll) === "undefined" || ignoreScroll === null) { ignoreScroll = true; }
1618
1619 var elementTop = 0;
1620 var originalElement = true;
1621
1622 if (typeof(element.getBoundingClientRect) !== "undefined" &amp;&amp; element.getBoundingClientRect !== null)
1623 {
1624 var rect = element.getBoundingClientRect();
1625 if (typeof(rect.top) !== "undefined" &amp;&amp; rect.top !== null &amp;&amp; !isNaN(rect.top))
1626 {
1627 elementTop = rect.top;
1628 elementTop -= CB_Client.getBoundingClientRectMargin("top");
1629
1630 if (ignoreScroll) { elementTop += CB_Screen.getScrollTop(); }
1631
1632 return elementTop;
1633 }
1634 }
1635
1636 //Gets the top position having in mind its parents (if any) and adds them:
1637 do
1638 {
1639 if (typeof(element) !== "undefined" &amp;&amp; element !== null)
1640 {
1641 var elementPosition = CB_Elements.getStyleProperty(element, "position", computed);
1642 if (elementPosition === "absolute")
1643 {
1644 if (typeof(getComputedStyle) !== "undefined" &amp;&amp; getComputedStyle !== null)
1645 {
1646 if (element !== document &amp;&amp; !isNaN(parseInt(getComputedStyle(element, "").getPropertyValue("top"))))
1647 {
1648 elementTop += parseInt(getComputedStyle(element, "").getPropertyValue("top"));
1649 }
1650 else if (!isNaN(parseInt(getComputedStyle(document.body, "").getPropertyValue("top"))))
1651 {
1652 elementTop += parseInt(getComputedStyle(document.body, "").getPropertyValue("top"));
1653 }
1654
1655 ////////elementTop += CB_Elements.getStylePropertyInteger(element, "borderTopWidth")[0];
1656 ////////elementTop += CB_Elements.getStylePropertyInteger(element, "paddingTop")[0];
1657 elementTop += CB_Elements.getStylePropertyInteger(element, "borderTopWidth", computed)[0];
1658 elementTop += CB_Elements.getStylePropertyInteger(element, "paddingTop", computed)[0];
1659
1660 if (originalElement)
1661 {
1662 //////////elementTop -= CB_Elements.getStylePropertyInteger(element, "border")[0];
1663 elementTop -= CB_Elements.getStylePropertyInteger(element, "border", computed)[0];
1664 originalElement = false;
1665 }
1666 }
1667 else if (typeof(element.offsetTop) !== "undefined" &amp;&amp; element.offsetTop !== null &amp;&amp; !isNaN(parseInt(element.offsetTop)))
1668 {
1669 elementTop += parseInt(element.offsetTop, 10);
1670 }
1671 }
1672 else
1673 {
1674 if (typeof(element.offsetTop) !== "undefined" &amp;&amp; element.offsetTop !== null &amp;&amp; !isNaN(parseInt(element.offsetTop)))
1675 {
1676 elementTop += parseInt(element.offsetTop, 10);
1677 }
1678 }
1679 }
1680
1681 if (typeof(element.offsetParent) !== "undefined" &amp;&amp; element.offsetParent !== null)
1682 {
1683 element = element.offsetParent;
1684 }
1685 /*
1686 else if (typeof(element.parentNode) !== "undefined" &amp;&amp; element.parentNode !== null)
1687 {
1688 element = element.parentNode;
1689 }
1690 else if (typeof(element.parentElement) !== "undefined" &amp;&amp; element.parentElement !== null)
1691 {
1692 element = element.parentElement;
1693 }
1694 else { element = null; }
1695 */
1696 else
1697 {
1698 var elementParent = CB_Elements.getParent(element);
1699 if (typeof(elementParent) !== "undefined" &amp;&amp; elementParent !== null)
1700 {
1701 element = elementParent;
1702 }
1703 else { element = null; }
1704 }
1705
1706
1707 } while (element)
1708
1709 if (!ignoreScroll) { elementTop -= CB_Screen.getScrollTop(); }
1710
1711 return isNaN(elementTop) &amp;&amp; returnNullOnFail ? null : elementTop;
1712 }
1713
1714
1715 /**
1716 * Returns the top position of an element (having in mind [getBoundingClientRect]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect} if available, its parents, etc.), by its identifier.
1717 * @function
1718 * @param {string} elementId - The identifier of the element whose data we are interested in.
1719 * @param {boolean} [ignoreScroll=true] - If it is set to false, it will have in mind the current scroll position to calculate the result.
1720 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1721 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStyleProperty} and {@link CB_Elements.getStylePropertyInteger} internally.
1722 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1723 */
1724 CB_Elements.getTopById = function(elementId, ignoreScroll, returnNullOnFail, computed)
1725 {
1726 return CB_Elements.getTop(CB_Elements.id(elementId), ignoreScroll, returnNullOnFail, computed);
1727 }
1728
1729
1730 /**
1731 * Returns the width of an element (having in mind its border).
1732 * @function
1733 * @param {Node} element - The element whose data we are interested in.
1734 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1735 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStylePropertyInteger} internally.
1736 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1737 */
1738 CB_Elements.getWidth = function(element, returnNullOnFail, computed)
1739 {
1740 if (typeof(element) === "undefined" || element === null) { return returnNullOnFail ? null : 0; }
1741
1742 var elementWidth = 0;
1743
1744 if (typeof(element.getBoundingClientRect) !== "undefined" &amp;&amp; element.getBoundingClientRect !== null)
1745 {
1746 var rect = element.getBoundingClientRect();
1747 if (typeof(rect.width) !== "undefined" &amp;&amp; rect.width !== null &amp;&amp; !isNaN(rect.width))
1748 {
1749 elementWidth += rect.width;
1750 }
1751 }
1752
1753 if (typeof(elementWidth) === "undefined" || elementWidth === null || isNaN(elementWidth) || elementWidth === 0)
1754 {
1755 if (typeof(element.offsetWidth) !== "undefined" &amp;&amp; element.offsetWidth !== null &amp;&amp; !isNaN(parseInt(element.offsetWidth)))
1756 {
1757 elementWidth += parseInt(element.offsetWidth, 10);
1758 }
1759 else
1760 {
1761 /*
1762 elementWidth += CB_Elements.getStylePropertyInteger(element, "width")[0];
1763 //elementWidth += CB_Elements.getStylePropertyInteger(element, "border")[0];
1764 elementHeight += CB_Elements.getStylePropertyInteger(element, "borderLeftWidth")[0];
1765 elementHeight += CB_Elements.getStylePropertyInteger(element, "borderRightWidth")[0];
1766 elementWidth += CB_Elements.getStylePropertyInteger(element, "paddingLeft")[0];
1767 */
1768 elementWidth += CB_Elements.getStylePropertyInteger(element, "width", computed)[0];
1769 //elementWidth += CB_Elements.getStylePropertyInteger(element, "border", computed)[0];
1770 elementWidth += CB_Elements.getStylePropertyInteger(element, "borderLeftWidth", computed)[0];
1771 elementWidth += CB_Elements.getStylePropertyInteger(element, "borderRightWidth", computed)[0];
1772 elementWidth += CB_Elements.getStylePropertyInteger(element, "paddingLeft", computed)[0];
1773 }
1774 }
1775
1776 return isNaN(elementWidth) &amp;&amp; returnNullOnFail ? null : elementWidth;
1777 }
1778
1779
1780 /**
1781 * Returns the width of an element (having in mind its border), by its identifier.
1782 * @function
1783 * @param {string} elementId - The identifier of the element whose data we are interested in.
1784 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1785 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStylePropertyInteger} internally.
1786 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1787 */
1788 CB_Elements.getWidthById = function(elementId, returnNullOnFail, computed)
1789 {
1790 return CB_Elements.getWidth(CB_Elements.id(elementId));
1791 }
1792
1793
1794 /**
1795 * Returns the height of an element (having in mind its border).
1796 * @function
1797 * @param {Node} element - The element whose data we are interested in.
1798 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1799 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStylePropertyInteger} internally.
1800 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1801 */
1802 CB_Elements.getHeight = function(element, returnNullOnFail, computed)
1803 {
1804 if (typeof(element) === "undefined" || element === null) { return returnNullOnFail ? null : 0; }
1805
1806 var elementHeight = 0;
1807
1808 if (typeof(element.getBoundingClientRect) !== "undefined" &amp;&amp; element.getBoundingClientRect !== null)
1809 {
1810 var rect = element.getBoundingClientRect();
1811 if (typeof(rect.height) !== "undefined" &amp;&amp; rect.height !== null &amp;&amp; !isNaN(rect.height))
1812 {
1813 elementHeight += rect.height;
1814 }
1815 }
1816
1817 if (typeof(elementHeight) === "undefined" || elementHeight === null || isNaN(elementHeight) || elementHeight === 0)
1818 {
1819 if (typeof(element.offsetHeight) !== "undefined" &amp;&amp; element.offsetHeight !== null &amp;&amp; !isNaN(parseInt(element.offsetHeight)))
1820 {
1821 elementHeight += parseInt(element.offsetHeight, 10);
1822 }
1823 else
1824 {
1825 /*
1826 elementHeight += CB_Elements.getStylePropertyInteger(element, "height")[0];
1827 //elementHeight += CB_Elements.getStylePropertyInteger(element, "border")[0];
1828 elementWidth += CB_Elements.getStylePropertyInteger(element, "borderTopWidth")[0];
1829 elementWidth += CB_Elements.getStylePropertyInteger(element, "borderBottomWidth")[0];
1830 elementHeight += CB_Elements.getStylePropertyInteger(element, "paddingTop")[0];
1831 */
1832 elementHeight += CB_Elements.getStylePropertyInteger(element, "height", computed)[0];
1833 //elementHeight += CB_Elements.getStylePropertyInteger(element, "border", computed)[0];
1834 elementHeight += CB_Elements.getStylePropertyInteger(element, "borderTopWidth", computed)[0];
1835 elementHeight += CB_Elements.getStylePropertyInteger(element, "borderBottomWidth", computed)[0];
1836 elementHeight += CB_Elements.getStylePropertyInteger(element, "paddingTop", computed)[0];
1837 }
1838 }
1839
1840 return isNaN(elementHeight) &amp;&amp; returnNullOnFail ? null : elementHeight;
1841 }
1842
1843
1844 /**
1845 * Returns the height of an element (having in mind its border), by its identifier.
1846 * @function
1847 * @param {string} elementId - The identifier of the element whose data we are interested in.
1848 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
1849 * @param {boolean} [computed=false] - This parameter will be used when it calls {@link CB_Elements.getStylePropertyInteger} internally.
1850 * @returns {*} It could return zero (0) or even a non-numeric value if something fails (use "returnNullOnFail" set to true to return null when it fails).
1851 */
1852 CB_Elements.getHeightById = function(elementId, returnNullOnFail, computed)
1853 {
1854 return CB_Elements.getHeight(CB_Elements.id(elementId));
1855 }
1856
1857
1858 /**
1859 * Prevents or allows the possibility of selecting the content of a given element (makes it unselectable).
1860 * @function
1861 * @param {Node} element - The element which we want to affect.
1862 * @param {boolean} [avoidSelection=true] - If set to false, it will allow selecting the content. Otherwise, it will prevent it to be selected.
1863 * @returns {Node|null} Returns the given element again or null.
1864 */
1865 CB_Elements.preventSelection = function(element, avoidSelection)
1866 {
1867 if (typeof(element) === "undefined" || element === null) { return null; }
1868 if (avoidSelection !== true &amp;&amp; avoidSelection !== false) { avoidSelection = true; }
1869 if (avoidSelection)
1870 {
1871 element.unselectable = "on";
1872 element.style.MozUserSelect = "none";
1873 element.style.WebkitUserSelect = "none";
1874 element.style.userSelect = "none";
1875 element.style.KhtmlUserSelect = "none";
1876 element.style.MsUserSelect = "none";
1877 element.style.MsTouchSelect = "none";
1878 element.style.touchSelect = "none";
1879 //-webkit-tap-highlight-color:rgba(0, 0, 0, 0);
1880 //-webkit-touch-callout:none;
1881 //-ms-touch-action:none;
1882 //-touch-action:none;
1883 element.onselectstart = function() { return false; };
1884 }
1885 else
1886 {
1887 element.unselectable = undefined;
1888 element.style.MozUserSelect = undefined;
1889 element.style.WebkitUserSelect = undefined;
1890 element.style.userSelect = undefined;
1891 element.style.KhtmlUserSelect = undefined;
1892 element.style.MsUserSelect = undefined;
1893 element.style.MsTouchSelect = undefined;
1894 element.style.touchSelect = undefined;
1895 //-webkit-tap-highlight-color:rgba(0, 0, 0, 0);
1896 //-webkit-touch-callout:none;
1897 //-ms-touch-action:none;
1898 //-touch-action:none;
1899 element.onselectstart = undefined;
1900 }
1901 return element;
1902 }
1903
1904
1905 /**
1906 * Prevents or allows the possibility of selecting the content of a given element (makes it unselectable), by its ID.
1907 * @function
1908 * @param {string} elementId - The identifier of the element which we want to affect.
1909 * @param {boolean} [avoidSelection=true] - If set to false, it will allow selecting the content. Otherwise, it will prevent it to be selected.
1910 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1911 */
1912 CB_Elements.preventSelectionById = function(elementId, allowSelection)
1913 {
1914 return CB_Elements.preventSelection(CB_Elements.id(elementId), allowSelection);
1915 }
1916
1917
1918 /**
1919 * Disables or enables the contextual menu for a given element or in the whole document.
1920 * @function
1921 * @param {Node} [element=document] - The element whose contextual menu we want to disable or enable. If not given, it will affect the whole document.
1922 * @param {boolean} [disableContextMenu=true] - If set to false, it will allow showing the contextual menu. Otherwise, it will prevent it to show.
1923 * @returns {Node} Returns the affected element.
1924 */
1925 CB_Elements.contextMenuDisable = function(element, disableContextMenu)
1926 {
1927 if (typeof(element) === "undefined" || element === null) { element = document; }
1928 if (disableContextMenu !== true &amp;&amp; disableContextMenu !== false) { disableContextMenu = true; }
1929 if (disableContextMenu)
1930 {
1931 CB_Events.add(element, "contextmenu", function(e) { e = CB_Events.normalize(e); if (typeof(e.preventDefault) !== "undefined") { e.preventDefault(); } return false; }, true, true, false);
1932 }
1933 else
1934 {
1935 element.contextmenu = undefined;
1936 }
1937 return element;
1938 }
1939
1940
1941 /**
1942 * Disables or enables the contextual menu for a given element (by its identifier).
1943 * @function
1944 * @param {string} elementId - The identifier of the element whose contextual menu we want to disable or enable.
1945 * @param {boolean} [disableContextMenu=true] - If set to false, it will allow showing the contextual menu. Otherwise, it will prevent it to show.
1946 * @returns {Node|null} Returns the affected element (if any) or null otherwise.
1947 */
1948 CB_Elements.contextMenuDisableById = function(elementId, allowContextMenu)
1949 {
1950 var element = CB_Elements.id(elementId);
1951 if (element !== null)
1952 {
1953 return CB_Elements.contextMenuDisable(element, allowContextMenu);
1954 }
1955 return null;
1956 }
1957
1958
1959 /**
1960 * Tries to get the body content of an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe}. Depending on the client and the safety measures, this might fail.
1961 * @function
1962 * @param {HTMLIFrameElement} frameElement - The [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} element whose body content we want to get.
1963 * @returns {string|null} Returns null if something goes wrong.
1964 */
1965 //* Source: Jose Basilio and nekno @ http://stackoverflow.com/questions/926916/how-to-get-the-bodys-content-of-an-iframe-in-javascript
1966 CB_Elements.getFrameBodyContent = function(frameElement)
1967 {
1968 if (typeof(frameElement) !== "undefined" &amp;&amp; frameElement !== null)
1969 {
1970 var frameBody = null;
1971
1972 if (frameElement.contentDocument &amp;&amp; typeof(frameElement.contentDocument.getElementsByTagName) !== "undefined")
1973 {
1974 frameBody = frameElement.contentDocument.getElementsByTagName("body");
1975 if (frameBody !== null &amp;&amp; typeof(frameBody[0]) !== "undefined" &amp;&amp; frameBody[0] !== null)
1976 {
1977 frameBody = frameBody[0];
1978 }
1979 else { frameBody = null; }
1980 }
1981
1982 if (frameBody === null &amp;&amp; frameElement.contentWindow &amp;&amp; typeof(frameElement.contentWindow.document) !== "undefined" &amp;&amp; typeof(frameElement.contentWindow.document.getElementsByTagName) !== "undefined")
1983 {
1984 frameBody = frameElement.contentWindow.document.getElementsByTagName("body");
1985 if (frameBody !== null &amp;&amp; typeof(frameBody[0]) !== "undefined" &amp;&amp; frameBody[0] !== null)
1986 {
1987 frameBody = frameBody[0];
1988 }
1989 else { frameBody = null; }
1990 }
1991
1992 if (frameBody === null &amp;&amp; frameElement !== "" &amp;&amp; window.frames &amp;&amp; window.frames[frameElement] &amp;&amp; window.frames[frameElement].document &amp;&amp; window.frames[frameElement].document.body)
1993 {
1994 frameBody = window.frames[frameElement].document.body;
1995 }
1996
1997 if (typeof(frameBody) !== "undefined" &amp;&amp; frameBody !== null &amp;&amp; frameBody.innerHTML) { return frameBody.innerHTML; }
1998 }
1999
2000 return null;
2001 }
2002
2003
2004 /**
2005 * Tries to get the body content of an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} (by its identifier). Depending on the client and the safety measures, this might fail.
2006 * @function
2007 * @param {string} frameElementId - The identifier of the [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} element whose body content we want to get.
2008 * @returns {string|null} Returns null if something goes wrong.
2009 */
2010 CB_Elements.getFrameBodyContentById = function(frameElementId)
2011 {
2012 CB_Elements.getFrameBodyContent(CB_Elements.id(frameElementId));
2013 }
2014
2015
2016 /**
2017 * Callback that is used as the "onScrollLeftChanges" parameter for the {@link CB_Elements.getScrollLeftById} function or as the "onScrollTopChanges" parameter for the {@link CB_Elements.getScrollTopById} function. All values received should be checked since some could be not numbers.
2018 * @memberof CB_Elements
2019 * @callback CB_Elements.getScrollLeftById_getScrollTopById_ON_SCROLL_CHANGES
2020 * @param {*} scrollLeftOrTop - The scroll left or scroll top position.
2021 * @param {*} scrollLeftOrTopPrevious - The previous scroll left or scroll top position.
2022 * @param {*} scrollWidthOrHeight - The scroll width or scroll height.
2023 * @param {*} clientWidthOrHeight - The client width or client height ([element.clientWidth]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth}/[element.offsetWidth]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth} or [element.clientHeight]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight}/[element.offsetHeight]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight}, depending on the web client).
2024 * @param {*} scrollLeftOrTopRelative - The relative scroll left or scroll top position.
2025 * @param {*} scrollLeftOrTopRelativePrevious - The previous relative scroll left or scroll top position.
2026 */
2027
2028 CB_Elements._getScrollLeftByIdLastValue = {};
2029 CB_Elements._getScrollLeftByIdTimeout = {};
2030 CB_Elements._getScrollLeftByIdScrollRelativePrevious = {};
2031 /**
2032 * Returns the horizontal scroll of a given element (by its identifier) and allows running a callback function (becoming recursive if desired). Any previous interval started by a previous call to this function, for the same "elementId", will be stopped.
2033 * @function
2034 * @param {string|window} [elementId=window] - The identifier of the element whose horizontal scroll position we want to get. If a string with the identifier is not given, the unique value allowed is the window object (which is the default value when a non-valid value or no value is given).
2035 * @param {CB_Elements.getScrollLeftById_getScrollTopById_ON_SCROLL_CHANGES} [onScrollLeftChanges] - The desired callback function. It will be called as an interval if "timeoutMs" is a valid integer value.
2036 * @param {boolean} [fireFirstTime=false] - If it is set to true, it will call the callback function (if any) as soon as this function is called.
2037 * @param {boolean} [fireAlways=false] - If it is set to true, it will call the callback function (if any) every interval even if the horizontal scroll value has not changed from the last call.
2038 * @param {integer} [timeoutMs] - The number of milliseconds between one call to the callback function (if any) and the next one. If not given, it will not perform any interval.
2039 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
2040 * @returns {number|null} Returns the horizontal scroll of the given element (by its identifier). It could return zero (0) if something fails (use "returnNullOnFail" set to true to return null when it fails).
2041 */
2042 CB_Elements.getScrollLeftById = function(elementId, onScrollLeftChanges, fireFirstTime, fireAlways, timeoutMs, returnNullOnFail, timeout)
2043 {
2044 if (typeof(elementId) === "undefined" || elementId === null || elementId === window) { elementId === "_WHOLE_DOCUMENT_"; }
2045 if (typeof(CB_Elements._getScrollLeftByIdLastValue[elementId]) === "undefined") { CB_Elements._getScrollLeftByIdLastValue[elementId] = null; }
2046 if (typeof(timeout) === "undefined" || timeout === null)
2047 {
2048 if (typeof(CB_Elements._getScrollLeftByIdTimeout[elementId]) === "undefined") { CB_Elements._getScrollLeftByIdTimeout[elementId] = null; }
2049 timeout = CB_Elements._getScrollLeftByIdTimeout[elementId];
2050 }
2051
2052 clearTimeout(timeout);
2053
2054 var element = CB_isString(elementId) ? CB_Elements.id(elementId) : elementId;
2055
2056 var scrollLeftValue = returnNullOnFail ? null : 0;
2057 if (typeof(element) === "undefined" || element === null || element === window)
2058 {
2059 element = CB_Elements.tag("body", document);
2060 if (element === null || typeof(element[0]) === "undefined" || element[0] === null) { return returnNullOnFail ? null : 0; }
2061 element = element[0];
2062 if (typeof(window.pageXOffset) !== "undefined")
2063 {
2064 scrollLeftValue = window.pageXOffset;
2065 }
2066 else if (typeof(window.scrollX) !== "undefined")
2067 {
2068 scrollLeftValue = window.scrollX;
2069 }
2070 else if (typeof(document.documentElement.scrollLeft) !== "undefined" &amp;&amp; document.documentElement.scrollLeft !== null &amp;&amp; !isNaN(document.documentElement.scrollLeft) &amp;&amp; document.documentElement.scrollLeft > 0)
2071 {
2072 scrollLeftValue = document.documentElement.scrollLeft;
2073 }
2074 else if (typeof(document.body.scrollLeft) !== "undefined" &amp;&amp; document.body.scrollLeft !== null)
2075 {
2076 scrollLeftValue = document.body.scrollLeft;
2077 }
2078 }
2079 else
2080 {
2081 if (typeof(element.scrollLeft) !== "undefined" &amp;&amp; element.scrollLeft !== null &amp;&amp; !isNaN(element.scrollLeft) &amp;&amp; element.scrollLeft > 0)
2082 {
2083 scrollLeftValue = element.scrollLeft;
2084 }
2085 else if (typeof(element.scrollWidth) !== "undefined" &amp;&amp; element.scrollWidth !== null &amp;&amp; !isNaN(element.scrollWidth) &amp;&amp; element.scrollWidth > 0)
2086 {
2087 scrollLeftValue = element.scrollWidth;
2088 }
2089 }
2090
2091 if (isNaN(scrollLeftValue))
2092 {
2093 scrollLeftValue = 0;
2094 if (returnNullOnFail) { scrollLeftValue = null; }
2095 }
2096
2097 //If it's not the first time and scroll has been changed, calls the onScrollLeft function (if any):
2098 if (fireAlways || ((fireFirstTime || CB_Elements._getScrollLeftByIdLastValue[elementId] !== null) &amp;&amp; CB_Elements._getScrollLeftByIdLastValue[elementId] !== scrollLeftValue))
2099 {
2100 //If there is any defined function:
2101 if (typeof(onScrollLeftChanges) === "function")
2102 {
2103 var scrollRelative = (scrollLeftValue + (element.clientWidth || element.offsetWidth)) / element.scrollWidth * 100;
2104 if (isNaN(scrollRelative))
2105 {
2106 scrollRelative = 0;
2107 if (returnNullOnFail) { scrollRelative = null; }
2108 }
2109
2110 //Sets the new position (to avoid possible infinite recursive loop in the case fireAlways is false):
2111 CB_Elements._getScrollLeftByIdLastValue[elementId] = scrollLeftValue;
2112
2113 //Executes the function:
2114 onScrollLeftChanges(scrollLeftValue, CB_Elements._getScrollLeftByIdLastValue[elementId], element.scrollWidth, element.clientWidth || element.offsetWidth, scrollRelative, CB_Elements._getScrollLeftByIdScrollRelativePrevious[elementId]);
2115 CB_Elements._getScrollLeftByIdScrollRelativePrevious[elementId] = scrollRelative;
2116 }
2117 }
2118
2119 //Sets the new position:
2120 CB_Elements._getScrollLeftByIdLastValue[elementId] = scrollLeftValue;
2121
2122
2123 if (typeof(timeoutMs) !== "undefined" &amp;&amp; timeoutMs !== null &amp;&amp; !isNaN(timeoutMs) &amp;&amp; timeoutMs >= 0)
2124 {
2125 CB_Elements._getScrollLeftByIdTimeout[elementId] = timeout =
2126 setTimeout
2127 (
2128 function()
2129 {
2130 CB_Elements.getScrollLeftById(elementId, onScrollLeftChanges, fireFirstTime, timeoutMs, returnNullOnFail, timeout);
2131 }, timeoutMs
2132 );
2133 }
2134
2135 return scrollLeftValue;
2136 }
2137
2138
2139 CB_Elements._getScrollTopByIdLastValue = {};
2140 CB_Elements._getScrollTopByIdTimeout = {};
2141 CB_Elements._getScrollTopByIdScrollRelativePrevious = {};
2142 /**
2143 * Returns the vertical scroll of a given element (by its identifier) and allows running a callback function (becoming recursive if desired). Any previous interval started by a previous call to this function, for the same "elementId", will be stopped.
2144 * @function
2145 * @param {string|window} [elementId=window] - The identifier of the element whose vertical scroll position we want to get. If a string with the identifier is not given, the unique value allowed is the window object (which is the default value when a non-valid value or no value is given).
2146 * @param {CB_Elements.getScrollLeftById_getScrollTopById_ON_SCROLL_CHANGES} [onScrollTopChanges] - The desired callback function. It will be called as an interval if "timeoutMs" is a valid integer value.
2147 * @param {boolean} [fireFirstTime=false] - If it is set to true, it will call the callback function (if any) as soon as this function is called.
2148 * @param {boolean} [fireAlways=false] - If it is set to true, it will call the callback function (if any) every interval even if the vertical scroll value has not changed from the last call.
2149 * @param {integer} [timeoutMs] - The number of milliseconds between one call to the callback function (if any) and the next one. If not given, it will not perform any interval.
2150 * @param {function} [returnNullOnFail=false] - If it is set to true, it will return null instead of zero (0) in the case that something goes wrong.
2151 * @returns {number|null} Returns the vertical scroll of the given element (by its identifier). It could return zero (0) if something fails (use "returnNullOnFail" set to true to return null when it fails).
2152 */
2153 CB_Elements.getScrollTopById = function(elementId, onScrollTopChanges, fireFirstTime, fireAlways, timeoutMs, returnNullOnFail, timeout)
2154 {
2155 if (typeof(elementId) === "undefined" || elementId === null || elementId === window) { elementId === "_WHOLE_DOCUMENT_"; }
2156 if (typeof(CB_Elements._getScrollTopByIdLastValue[elementId]) === "undefined") { CB_Elements._getScrollTopByIdLastValue[elementId] = null; }
2157 if (typeof(timeout) === "undefined" || timeout === null)
2158 {
2159 if (typeof(CB_Elements._getScrollTopByIdTimeout[elementId]) === "undefined") { CB_Elements._getScrollTopByIdTimeout[elementId] = null; }
2160 timeout = CB_Elements._getScrollTopByIdTimeout[elementId];
2161 }
2162
2163 clearTimeout(timeout);
2164
2165 var element = CB_isString(elementId) ? CB_Elements.id(elementId) : elementId;
2166
2167 var scrollTopValue = returnNullOnFail ? null : 0;
2168 if (typeof(element) === "undefined" || element === null || element === window)
2169 {
2170 element = CB_Elements.tag("body", document);
2171 if (element === null || typeof(element[0]) === "undefined" || element[0] === null) { return returnNullOnFail ? null : 0; }
2172 element = element[0];
2173 if (typeof(window.pageYOffset) !== "undefined")
2174 {
2175 scrollTopValue = window.pageYOffset;
2176 }
2177 else if (typeof(window.scrollY) !== "undefined")
2178 {
2179 scrollTopValue = window.scrollY;
2180 }
2181 else if (typeof(document.documentElement.scrollTop) !== "undefined" &amp;&amp; document.documentElement.scrollTop !== null &amp;&amp; !isNaN(document.documentElement.scrollTop) &amp;&amp; document.documentElement.scrollTop > 0)
2182 {
2183 scrollTopValue = document.documentElement.scrollTop;
2184 }
2185 else if (typeof(document.body.scrollTop) !== "undefined" &amp;&amp; document.body.scrollTop !== null)
2186 {
2187 scrollTopValue = document.body.scrollTop;
2188 }
2189 }
2190 else
2191 {
2192 if (typeof(element.scrollTop) !== "undefined" &amp;&amp; element.scrollTop !== null &amp;&amp; !isNaN(element.scrollTop) &amp;&amp; element.scrollTop > 0)
2193 {
2194 scrollTopValue = element.scrollTop;
2195 }
2196 else if (typeof(element.scrollHeight) !== "undefined" &amp;&amp; element.scrollHeight !== null &amp;&amp; !isNaN(element.scrollHeight) &amp;&amp; element.scrollHeight > 0)
2197 {
2198 scrollTopValue = element.scrollHeight;
2199 }
2200 }
2201
2202 if (isNaN(scrollTopValue))
2203 {
2204 scrollTopValue = 0;
2205 if (returnNullOnFail) { scrollTopValue = null; }
2206 }
2207
2208 //If it's not the first time and scroll has been changed, calls the onScrollTop function (if any):
2209 if (fireAlways || ((fireFirstTime || CB_Elements._getScrollTopByIdLastValue[elementId] !== null) &amp;&amp; CB_Elements._getScrollTopByIdLastValue[elementId] !== scrollTopValue))
2210 {
2211 //If there is any defined function:
2212 if (typeof(onScrollTopChanges) === "function")
2213 {
2214 var scrollRelative = (scrollTopValue + (element.clientHeight || element.offsetHeight)) / element.scrollHeight * 100;
2215 if (isNaN(scrollRelative))
2216 {
2217 scrollRelative = 0;
2218 if (returnNullOnFail) { scrollRelative = null; }
2219 }
2220
2221 //Sets the new position (to avoid possible infinite recursive loop in the case fireAlways is false):
2222 CB_Elements._getScrollTopByIdLastValue[elementId] = scrollTopValue;
2223
2224 //Executes the function:
2225 onScrollTopChanges(scrollTopValue, CB_Elements._getScrollTopByIdLastValue[elementId], element.scrollHeight, element.clientHeight || element.offsetHeight, scrollRelative, CB_Elements._getScrollTopByIdScrollRelativePrevious[elementId]);
2226 CB_Elements._getScrollTopByIdScrollRelativePrevious[elementId] = scrollRelative;
2227 }
2228 }
2229
2230 //Sets the new position:
2231 CB_Elements._getScrollTopByIdLastValue[elementId] = scrollTopValue;
2232
2233
2234 if (typeof(timeoutMs) !== "undefined" &amp;&amp; timeoutMs !== null &amp;&amp; !isNaN(timeoutMs) &amp;&amp; timeoutMs >= 0)
2235 {
2236 CB_Elements._getScrollTopByIdTimeout[elementId] = timeout =
2237 setTimeout
2238 (
2239 function()
2240 {
2241 CB_Elements.getScrollTopById(elementId, onScrollTopChanges, fireFirstTime, timeoutMs, returnNullOnFail, timeout);
2242 }, timeoutMs
2243 );
2244 }
2245
2246 return scrollTopValue;
2247 }
2248
2249}</pre>
2250 </article>
2251</section>
2252
2253
2254
2255
2256
2257 </div>
2258 </div>
2259
2260 <div class="clearfix"></div>
2261
2262
2263
2264</div>
2265</div>
2266
2267
2268 <div class="modal fade" id="searchResults">
2269 <div class="modal-dialog">
2270 <div class="modal-content">
2271 <div class="modal-header">
2272 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2273 <h4 class="modal-title">Search results</h4>
2274 </div>
2275 <div class="modal-body"></div>
2276 <div class="modal-footer">
2277 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2278 </div>
2279 </div><!-- /.modal-content -->
2280 </div><!-- /.modal-dialog -->
2281 </div>
2282
2283
2284<footer>
2285
2286
2287 <span class="copyright">
2288 <a href="printable/" target="_blank">See a more printer-friendly version</a><hr /><span style="color:#000000">© <address style="display:inline; font-style:normal;"><a href="https://crossbrowdy.com/" target="_blank">CrossBrowdy</a> API documentation</address> by <a href="https://joanalbamaldonado.com/" target="_blank">Joan Alba Maldonado</a> - <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">Creative Commons Attribution 4.0 International</a><br />DocStrap Copyright © 2012-2015 The contributors to the JSDoc3 and DocStrap projects.</span>
2289 </span>
2290
2291<span class="jsdoc-message">
2292 Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
2293
2294 on Mon Feb 3rd 2020
2295
2296 using the <a href="https://github.com/docstrap/docstrap">DocStrap template</a>.
2297</span>
2298</footer>
2299
2300<script src="scripts/docstrap.lib.js"></script>
2301<script src="scripts/toc.js"></script>
2302
2303 <script type="text/javascript" src="scripts/fulltext-search-ui.js"></script>
2304
2305
2306<script>
2307$( function () {
2308 $( "[id*='$']" ).each( function () {
2309 var $this = $( this );
2310
2311 $this.attr( "id", $this.attr( "id" ).replace( "$", "__" ) );
2312 } );
2313
2314 $( ".tutorial-section pre, .readme-section pre, pre.prettyprint.source" ).each( function () {
2315 var $this = $( this );
2316
2317 var example = $this.find( "code" );
2318 exampleText = example.html();
2319 var lang = /{@lang (.*?)}/.exec( exampleText );
2320 if ( lang && lang[1] ) {
2321 exampleText = exampleText.replace( lang[0], "" );
2322 example.html( exampleText );
2323 lang = lang[1];
2324 } else {
2325 var langClassMatch = example.parent()[0].className.match(/lang\-(\S+)/);
2326 lang = langClassMatch ? langClassMatch[1] : "javascript";
2327 }
2328
2329 if ( lang ) {
2330
2331 $this
2332 .addClass( "sunlight-highlight-" + lang )
2333 .addClass( "linenums" )
2334 .html( example.html() );
2335
2336 }
2337 } );
2338
2339 Sunlight.highlightAll( {
2340 lineNumbers : true,
2341 showMenu : true,
2342 enableDoclinks : true
2343 } );
2344
2345 $.catchAnchorLinks( {
2346 navbarOffset: 10
2347 } );
2348 $( "#toc" ).toc( {
2349 anchorName : function ( i, heading, prefix ) {
2350 return $( heading ).attr( "id" ) || ( prefix + i );
2351 },
2352 selectors : "#toc-content h1,#toc-content h2,#toc-content h3,#toc-content h4",
2353 showAndHide : false,
2354 smoothScrolling: true
2355 } );
2356
2357 $( "#main span[id^='toc']" ).addClass( "toc-shim" );
2358 $( '.dropdown-toggle' ).dropdown();
2359
2360 $( "table" ).each( function () {
2361 var $this = $( this );
2362 $this.addClass('table');
2363 } );
2364
2365} );
2366</script>
2367
2368
2369
2370<!--Navigation and Symbol Display-->
2371
2372<script>
2373 $( function () {
2374 $( '#main' ).localScroll( {
2375 offset : { top : 60 } //offset by the height of your header (give or take a few px, see what works for you)
2376 } );
2377 $( "dt.name" ).each( function () {
2378 var $this = $( this ).find("h4");
2379 var icon = $( "<i/>" ).addClass( "icon-plus-sign" ).addClass( "pull-right" ).addClass( "icon-white" );
2380 var dt = $(this);
2381 var children = dt.next( "dd" );
2382
2383 dt.prepend( icon ).css( {cursor : "pointer"} );
2384 dt.addClass( "member-collapsed" ).addClass( "member" );
2385
2386
2387 children.hide();
2388
2389 dt.children().on( "click", function () {
2390 children = dt.next( "dd" );
2391 children.slideToggle( "fast", function () {
2392
2393 if ( children.is( ":visible" ) ) {
2394 icon.addClass( "icon-minus-sign" ).removeClass( "icon-plus-sign" ).removeClass( "icon-white" );
2395 dt.addClass( "member-open" ).animate( "member-collapsed" );
2396 } else {
2397 icon.addClass( "icon-plus-sign" ).removeClass( "icon-minus-sign" ).addClass( "icon-white" );
2398 dt.addClass( "member-collapsed" ).removeClass( "member-open" );
2399 }
2400 } );
2401 } );
2402
2403 } );
2404 } );
2405</script>
2406
2407
2408<!--Google Analytics-->
2409
2410
2411
2412 <script type="text/javascript">
2413 $(document).ready(function() {
2414 SearcherDisplay.init();
2415 });
2416 </script>
2417
2418
2419</body>
2420</html>