1/*! PHP-JS | @link https://github.com/kvz/phpjs | @copyright Kevin van Zonneveld | @license MIT and GPL */ 2function count (mixed_var, mode) { 3 // http://kevin.vanzonneveld.net 4 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 5 // + input by: Waldo Malqui Silva 6 // + bugfixed by: Soren Hansen 7 // + input by: merabi 8 // + improved by: Brett Zamir (http://brett-zamir.me) 9 // + bugfixed by: Olivier Louvignes (http://mg-crea.com/) 10 // + improved by: Obinwanne Hill on 22-03-2013 (https://about.me/obinwanne.hill) 11 // + dependencies: isArray() and isObject() 12 // * example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE'); 13 // * returns 1: 6 14 // * example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE'); 15 // * returns 2: 6 16 var key, nvld = false, cnt = 0; 17 18 switch(true) 19 { 20 case (mixed_var === null || typeof mixed_var === 'undefined'): 21 return 0; 22 break; 23 24 case (!isArray(mixed_var) && !isObject(mixed_var)): 25 nvld = true; 26 break; 27 } 28 29 switch(true) 30 { 31 case (mixed_var.hasOwnProperty('length')): 32 return mixed_var.length; 33 break; 34 } 35 36 //Return 1 if !isArray && !Object && does not have .length 37 switch(true) 38 { 39 case (nvld): 40 return 1; 41 break; 42 } 43 44 switch(true) 45 { 46 case (mode === 'COUNT_RECURSIVE'): 47 mode = 1; 48 break; 49 } 50 51 switch(true) 52 { 53 case (mode != 1): 54 mode = 0; 55 break; 56 } 57 58 for (key in mixed_var) { 59 switch(true) 60 { 61 case (mixed_var.hasOwnProperty(key)): 62 cnt++; 63 switch(true) 64 { 65 case (mode == 1 && mixed_var[key] && (isArray(mixed_var[key]) || isObject(mixed_var[key]))): 66 cnt += this.count(mixed_var[key], 1); 67 break; 68 } 69 break; 70 } 71 } 72 73 return cnt; 74} 75 76function in_array (needle, haystack, argStrict) { 77 // http://kevin.vanzonneveld.net 78 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 79 // + improved by: vlado houba 80 // + input by: Billy 81 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 82 // * example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']); 83 // * returns 1: true 84 // * example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'}); 85 // * returns 2: false 86 // * example 3: in_array(1, ['1', '2', '3']); 87 // * returns 3: true 88 // * example 3: in_array(1, ['1', '2', '3'], false); 89 // * returns 3: true 90 // * example 4: in_array(1, ['1', '2', '3'], true); 91 // * returns 4: false 92 var key = '', 93 strict = !! argStrict; 94 95 if (strict) { 96 for (key in haystack) { 97 if (haystack[key] === needle) { 98 return true; 99 } 100 } 101 } else { 102 for (key in haystack) { 103 if (haystack[key] == needle) { 104 return true; 105 } 106 } 107 } 108 109 return false; 110} 111 112function array_search (needle, haystack, argStrict) { 113 // http://kevin.vanzonneveld.net 114 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 115 // + input by: Brett Zamir (http://brett-zamir.me) 116 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 117 // * example 1: array_search('zonneveld', {firstname: 'kevin', middle: 'van', surname: 'zonneveld'}); 118 // * returns 1: 'surname' 119 // * example 2: ini_set('phpjs.return_phpjs_arrays', 'on'); 120 // * example 2: var ordered_arr = array({3:'value'}, {2:'value'}, {'a':'value'}, {'b':'value'}); 121 // * example 2: var key = array_search(/val/g, ordered_arr); // or var key = ordered_arr.search(/val/g); 122 // * returns 2: '3' 123 124 var strict = !!argStrict, 125 key = ''; 126 127 if (haystack && typeof haystack === 'object' && haystack.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array 128 return haystack.search(needle, argStrict); 129 } 130 if (typeof needle === 'object' && needle.exec) { // Duck-type for RegExp 131 if (!strict) { // Let's consider case sensitive searches as
vendor: 4,380 bytes, lines 131-263
131strict 132 var flags = 'i' + (needle.global ? 'g' : '') + 133 (needle.multiline ? 'm' : '') + 134 (needle.sticky ? 'y' : ''); // sticky is FF only 135 needle = new RegExp(needle.source, flags); 136 } 137 for (key in haystack) { 138 if (needle.test(haystack[key])) { 139 return key; 140 } 141 } 142 return false; 143 } 144 145 for (key in haystack) { 146 if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) { 147 return key; 148 } 149 } 150 151 return false; 152} 153 154function array_keys (input, search_value, argStrict) { 155 // http://kevin.vanzonneveld.net 156 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 157 // + input by: Brett Zamir (http://brett-zamir.me) 158 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 159 // + improved by: jd 160 // + improved by: Brett Zamir (http://brett-zamir.me) 161 // + input by: P 162 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 163 // * example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} ); 164 // * returns 1: {0: 'firstname', 1: 'surname'} 165 166 var search = typeof search_value !== 'undefined', 167 tmp_arr = [], 168 strict = !!argStrict, 169 include = true, 170 key = ''; 171 172 if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array 173 return input.keys(search_value, argStrict); 174 } 175 176 for (key in input) { 177 if (input.hasOwnProperty(key)) { 178 include = true; 179 if (search) { 180 if (strict && input[key] !== search_value) { 181 include = false; 182 } 183 else if (input[key] != search_value) { 184 include = false; 185 } 186 } 187 188 if (include) { 189 tmp_arr[tmp_arr.length] = key; 190 } 191 } 192 } 193 194 return tmp_arr; 195} 196 197function array_values (input) { 198 // http://kevin.vanzonneveld.net 199 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 200 // + improved by: Brett Zamir (http://brett-zamir.me) 201 // * example 1: array_values( {firstname: 'Kevin', surname: 'van Zonneveld'} ); 202 // * returns 1: {0: 'Kevin', 1: 'van Zonneveld'} 203 var tmp_arr = [], 204 key = ''; 205 206 if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array 207 return input.values(); 208 } 209 210 for (key in input) { 211 tmp_arr[tmp_arr.length] = input[key]; 212 } 213 214 return tmp_arr; 215} 216 217function array_combine (keys, values) { 218 // http://kevin.vanzonneveld.net 219 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 220 // + improved by: Brett Zamir (http://brett-zamir.me) 221 // * example 1: array_combine([0,1,2], ['kevin','van','zonneveld']); 222 // * returns 1: {0: 'kevin', 1: 'van', 2: 'zonneveld'} 223 var new_array = {}, 224 keycount = keys && keys.length, 225 i = 0; 226 227 // input sanitation 228 if (typeof keys !== 'object' || typeof values !== 'object' || // Only accept arrays or array-like objects 229 typeof keycount !== 'number' || typeof values.length !== 'number' || !keycount) { // Require arrays to have a count 230 return false; 231 } 232 233 // number of elements does not match 234 if (keycount != values.length) { 235 return false; 236 } 237 238 for (i = 0; i < keycount; i++) { 239 new_array[keys[i]] = values[i]; 240 } 241 242 return new_array; 243} 244 245function implode (glue, pieces) { 246 // http://kevin.vanzonneveld.net 247 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 248 // + improved by: Waldo Malqui Silva 249 // + improved by: Itsacon (http://www.itsacon.net/) 250 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 251 // * example 1: implode(' ', ['Kevin', 'van', 'Zonneveld']); 252 // * returns 1: 'Kevin van Zonneveld' 253 // * example 2: implode(' ', {first:'Kevin', last: 'van Zonneveld'}); 254 // * returns 2: 'Kevin van Zonneveld' 255 var i = '', 256 retVal = '', 257 tGlue = ''; 258 if (arguments.length === 1) { 259 pieces = glue; 260 glue = ''; 261 } 262 if (typeof(pieces) === 'object') { 263 for (i in pieces) {
264 retVal += tGlue + pieces[i]; 265 tGlue = glue; 266 } 267 return retVal; 268 } 269 return pieces; 270} 271 272function explode (delimiter, string, limit) { 273 274 if ( arguments.length < 2 || typeof delimiter == 'undefined' || typeof string == 'undefined' ) return null; 275 if ( delimiter === '' || delimiter === false || delimiter === null) return false; 276 if ( typeof delimiter == 'function' || typeof delimiter == 'object' || typeof string == 'function' || typeof string == 'object'){ 277 return { 0: '' }; 278 } 279 if ( delimiter === true ) delimiter = '1'; 280 281 // Here we go... 282 delimiter += ''; 283 string += ''; 284 285 var s = string.split( delimiter ); 286 287 288 if ( typeof limit === 'undefined' ) return s; 289 290 // Support for limit 291 if ( limit === 0 ) limit = 1; 292 293 // Positive limit 294 if ( limit > 0 ){ 295 if ( limit >= s.length ) return s; 296 return s.slice( 0, limit - 1 ).concat( [ s.slice( limit - 1 ).join( delimiter ) ] ); 297 } 298 299 // Negative limit 300 if ( -limit >= s.length ) return []; 301 302 s.splice( s.length + limit ); 303 return s; 304} 305 306function urlencode (str) { 307 // http://kevin.vanzonneveld.net 308 // + original by: Philip Peterson 309 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 310 // + input by: AJ 311 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 312 // + improved by: Brett Zamir (http://brett-zamir.me) 313 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 314 // + input by: travc 315 // + input by: Brett Zamir (http://brett-zamir.me) 316 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 317 // + improved by: Lars Fischer 318 // + input by: Ratheous 319 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 320 // + bugfixed by: Joris 321 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 322 // % note 1: This reflects PHP 5.3/6.0+ behavior 323 // % note 2: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on 324 // % note 2: pages served as UTF-8 325 // * example 1: urlencode('Kevin van Zonneveld!'); 326 // * returns 1: 'Kevin+van+Zonneveld%21' 327 // * example 2: urlencode('http://kevin.vanzonneveld.net/'); 328 // * returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' 329 // * example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); 330 // * returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' 331 str = (str + '').toString(); 332 333 // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current 334 // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. 335 return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28'). 336 replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); 337} 338 339function strrpos (haystack, needle, offset) { 340 // http://kevin.vanzonneveld.net 341 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 342 // + bugfixed by: Onno Marsman 343 // + input by: saulius 344 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 345 // * example 1: strrpos('Kevin van Zonneveld', 'e'); 346 // * returns 1: 16 347 // * example 2: strrpos('somepage.com', '.', false); 348 // * returns 2: 8 349 // * example 3: strrpos('baa', 'a', 3); 350 // * returns 3: false 351 // * example 4: strrpos('baa', 'a', 2); 352 // * returns 4: 2 353 var i = -1; 354 if (offset) { 355 i = (haystack + '').slice(offset).lastIndexOf(needle); // strrpos' offset indicates starting point of range till end, 356 // while lastIndexOf's optional 2nd argument indicates ending point of range from the beginning 357 if (i !== -1) { 358 i += offset; 359 } 360 } else { 361 i = (haystack + '').lastIndexOf(needle); 362 } 363 return i >= 0 ? i : false; 364} 365 366function uasort (inputArr, sorter) { 367 // http://kevin.vanzonneveld.net 368 // + original by: Brett Zamir (http://brett-zamir.me) 369 // + improved by: Brett Zamir (http://brett-zamir.me) 370 // + improved by: Theriault 371 // % note 1: This function deviates from PHP in returning a copy of the array instead
372 // % note 1: of acting by reference and returning true; this was necessary because 373 // % note 1: IE does not allow deleting and re-adding of properties without caching 374 // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to 375 // % note 1: get the PHP behavior, but use this only if you are in an environment 376 // % note 1: such as Firefox extensions where for-in iteration order is fixed and true 377 // % note 1: property deletion is supported. Note that we intend to implement the PHP 378 // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since 379 // % note 1: is by reference in PHP anyways 380 // * example 1: fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'}; 381 // * example 1: fruits = uasort(fruits, function (a, b) { if (a > b) {return 1;}if (a < b) {return -1;} return 0;}); 382 // * results 1: fruits == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'} 383 var valArr = [], 384 tempKeyVal, tempValue, ret, k = '', 385 i = 0, 386 strictForIn = false, 387 populateArr = {}; 388 389 if (typeof sorter === 'string') { 390 sorter = this[sorter]; 391 } else if (Object.prototype.toString.call(sorter) === '[object Array]') { 392 sorter = this[sorter[0]][sorter[1]]; 393 } 394 395 // BEGIN REDUNDANT 396 this.php_js = this.php_js || {}; 397 this.php_js.ini = this.php_js.ini || {}; 398 // END REDUNDANT 399 strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off'; 400 populateArr = strictForIn ? inputArr : populateArr; 401 402 403 for (k in inputArr) { // Get key and value arrays 404 if (inputArr.hasOwnProperty(k)) { 405 valArr.push([k, inputArr[k]]); 406 if (strictForIn) { 407 delete inputArr[k]; 408 } 409 } 410 } 411 valArr.sort(function (a, b) { 412 return sorter(a[1], b[1]); 413 }); 414 415 for (i = 0; i < valArr.length; i++) { // Repopulate the old array 416 populateArr[valArr[i][0]] = valArr[i][1]; 417 } 418 419 return strictForIn || populateArr; 420} 421 422function microtime (get_as_float) { 423 // http://kevin.vanzonneveld.net 424 // + original by: Paulo Freitas 425 // * example 1: timeStamp = microtime(true); 426 // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000 427 var now = new Date().getTime() / 1000; 428 var s = parseInt(now, 10); 429 430 return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s; 431} 432 433/*! md5.js - MD5 Message-Digest - v2.0.0 | @copyright 1999,2002 Masanao Izumo <[email protected]> */ 434/* md5.js - MD5 Message-Digest 435 * Copyright (C) 1999,2002 Masanao Izumo <[email protected]> 436 * Version: 2.0.0 437 * LastModified: May 13 2002 438 * 439 * This program is free software. You can redistribute it and/or modify 440 * it without any warranty. This library calculates the MD5 based on RFC1321. 441 * See RFC1321 for more information and algorithm. 442 */ 443 444/* Interface: 445 * md5_hexstr = md5(data); 446 */ 447 448/* ChangeLog 449 * 2013/07/20: Updated by Obinwanne Ugwuh 450 * 2002/05/13: Version 2.0.0 released 451 * NOTICE: API is changed. 452 * 2002/04/15: Bug fix about MD5 length. 453 */ 454(function() { 455 var MD5_T = new Array(0x00000000, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391); 456 457 var MD5_round1 = new Array(new Array(0, 7, 1), new Array(1, 12, 2), new Array(2, 17, 3), new Array(3, 22, 4), new Array(4, 7, 5), new Array(5, 12, 6), new Array(6, 17, 7), new Array(7, 22, 8), new Array(8, 7, 9), new Array(9, 12, 10), new Array(10, 17, 11), new Array(11, 22, 12), new Array(12, 7, 13), new Array(13, 12, 14), new Array(14, 17, 15), new Array(15, 22, 16)); 458 459 var MD5_round2 = new Array(new Array(1, 5, 17), new Array(6, 9, 18), new Array(11, 14, 19), new Array(0, 20, 20), new Array(5, 5, 21), new Array(10, 9, 22), new Array(15, 14, 23), new Array(4, 20, 24), new Array(9, 5, 25), new Array(14, 9, 26), new Array(3, 14, 27), new Array(8, 20, 28), new Array(13, 5, 29), new Array(2, 9, 30), new Array(7, 14, 31), new Array(12, 20, 32)); 460 461 var MD5_round3 = new Array(new Array(5, 4, 33), new Array(8, 11, 34), new Array(11, 16, 35), new Array(14, 23, 36), new Array(1, 4, 37), new Array(4, 11, 38), new Array(7, 16, 39), new Array(10, 23, 40), new Array(13, 4, 41), new Array(0, 11, 42), new Array(3, 16, 43), new Array(6, 23, 44), new Array(9, 4, 45), new Array(12, 11, 46), new Array(15, 16, 47), new Array(2, 23, 48)); 462 463 var MD5_round4 = new Array(new Array(0, 6, 49), new Array(7, 10, 50), new Array(14, 15, 51), new Array(5, 21, 52), new Array(12, 6, 53), new Array(3, 10, 54), new Array(10, 15, 55), new Array(1, 21, 56), new Array(8, 6, 57), new Array(15, 10, 58), new Array(6, 15, 59), new Array(13, 21, 60), new Array(4, 6, 61), new Array(11, 10, 62), new Array(2, 15, 63), new Array(9, 21, 64)); 464 465 function MD5_F(x, y, z) { 466 return (x & y) | (~x & z); 467 } 468 469 function MD5_G(x, y, z) { 470 return (x & z) | (y & ~z); 471 } 472 473 function MD5_H(x, y, z) { 474 return x ^ y ^ z; 475 } 476 477 function MD5_I(x, y, z) { 478 return y ^ (x | ~z); 479 } 480 481 var MD5_round = new Array(new Array(MD5_F, MD5_round1), new Array(MD5_G, MD5_round2), new Array(MD5_H, MD5_round3), new Array(MD5_I, MD5_round4)); 482 483 function MD5_pack(n32) { 484 return String.fromCharCode(n32 & 0xff) + String.fromCharCode((n32 >>> 8) & 0xff) + String.fromCharCode((n32 >>> 16) & 0xff) + String.fromCharCode((n32 >>> 24) & 0xff); 485 } 486 487 function MD5_unpack(s4) { 488 return s4.charCodeAt(0) | (s4.charCodeAt(1) << 8) | (s4.charCodeAt(2) << 16) | (s4.charCodeAt(3) << 24); 489 } 490 491 function MD5_number(n) { 492 while (n < 0) 493 n += 4294967296; 494 while (n > 4294967295) 495 n -= 4294967296; 496 return n; 497 } 498 499 function MD5_apply_round(x, s, f, abcd, r) { 500 var a, b, c, d; 501 var kk, ss, ii; 502 var t, u; 503 504 a = abcd[0]; 505 b = abcd[1]; 506 c = abcd[2]; 507 d = abcd[3]; 508 kk = r[0]; 509 ss = r[1]; 510 ii = r[2]; 511 512 u = f(s[b], s[c], s[d]); 513 t = s[a] + u + x[kk] + MD5_T[ii]; 514 t = MD5_number(t); 515 t = ((t << ss) | (t >>> (32 - ss))); 516 t += s[b]; 517 s[a] = MD5_number(t); 518 } 519 520 function utf8_encode(s) 521 { 522 for(var c, i = -1, l = (s = s.split("")).length, o = String.fromCharCode; ++i < l;
523 s[i] = (c = s[i].charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) + o(0x80 | (c & 0x3f)) : s[i] 524 ); 525 return s.join(""); 526 } 527 528 function MD5_hash(data) { 529 var abcd, x, state, s; 530 var len, index, padLen, f, r; 531 var i, j, k; 532 var tmp; 533 534 if (/[\x80-\xFF]/.test(data)) { 535 data = utf8_encode(data); 536 537 } 538 539 state = new Array(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476); 540 len = data.length; 541 index = len & 0x3f; 542 padLen = (index < 56) ? (56 - index) : (120 - index); 543 if (padLen > 0) { 544 data += "\x80"; 545 for (i = 0; i < padLen - 1; i++) 546 data += "\x00"; 547 } 548 data += MD5_pack(len * 8); 549 data += MD5_pack(0); 550 len += padLen + 8; 551 abcd = new Array(0, 1, 2, 3); 552 x = new Array(16); 553 s = new Array(4); 554 555 for (k = 0; k < len; k += 64) { 556 for (i = 0, j = k; i < 16; i++, j += 4) { 557 x[i] = data.charCodeAt(j) | (data.charCodeAt(j + 1) << 8) | (data.charCodeAt(j + 2) << 16) | (data.charCodeAt(j + 3) << 24); 558 } 559 for (i = 0; i < 4; i++) 560 s[i] = state[i]; 561 for (i = 0; i < 4; i++) { 562 f = MD5_round[i][0]; 563 r = MD5_round[i][1]; 564 for (j = 0; j < 16; j++) { 565 MD5_apply_round(x, s, f, abcd, r[j]); 566 tmp = abcd[0]; 567 abcd[0] = abcd[3]; 568 abcd[3] = abcd[2]; 569 abcd[2] = abcd[1]; 570 abcd[1] = tmp; 571 } 572 } 573 574 for (i = 0; i < 4; i++) { 575 state[i] += s[i]; 576 state[i] = MD5_number(state[i]); 577 } 578 } 579 580 return MD5_pack(state[0]) + MD5_pack(state[1]) + MD5_pack(state[2]) + MD5_pack(state[3]); 581 } 582 583 function MD5_hexhash(data) { 584 var i, out, c; 585 var bit128; 586 587 bit128 = MD5_hash(data); 588 out = ""; 589 for (i = 0; i < 16; i++) { 590 c = bit128.charCodeAt(i); 591 out += "0123456789abcdef".charAt((c >> 4) & 0xf); 592 out += "0123456789abcdef".charAt(c & 0xf); 593 } 594 return out; 595 } 596 597 md5 = function (s) { 598 return MD5_hexhash(s); 599 } 600})(); 601 602/*! json2.js | @link https://github.com/douglascrockford/JSON-js | @copyright Douglas Crockford <[email protected]> */ 603 604// Create a JSON object only if one does not already exist. We create the 605// methods in a closure to avoid creating global variables. 606 607if (typeof JSON !== 'object') { 608 JSON = {}; 609} 610 611(function () { 612 'use strict'; 613 614 function f(n) { 615 // Format integers to have at least two digits. 616 return n < 10 ? '0' + n : n; 617 } 618 619 if (typeof Date.prototype.toJSON !== 'function') { 620 621 Date.prototype.toJSON = function () { 622 623 return isFinite(this.valueOf()) 624 ? this.getUTCFullYear() + '-' + 625 f(this.getUTCMonth() + 1) + '-' + 626 f(this.getUTCDate()) + 'T' + 627 f(this.getUTCHours()) + ':' + 628 f(this.getUTCMinutes()) + ':' + 629 f(this.getUTCSeconds()) + 'Z' 630 : null; 631 }; 632 633 String.prototype.toJSON = 634 Number.prototype.toJSON = 635 Boolean.prototype.toJSON = function () { 636 return this.valueOf(); 637 }; 638 } 639 640 var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 641 escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 642 gap, 643 indent, 644 meta = { // table of character substitutions 645 '\b': '\\b', 646 '\t': '\\t', 647 '\n': '\\n', 648 '\f': '\\f', 649 '\r': '\\r', 650 '"' : '\\"', 651 '\\': '\\\\' 652 }, 653 rep; 654 655 656 function quote(string) { 657 658// If the string contains no control characters, no quote characters, and no 659// backslash characters, then we can safely slap some quotes around it. 660// Otherwise we must also replace the offending characters with safe escape 661// sequences. 662 663 escapable.lastIndex = 0; 664 return escapable.test(string) ? '"' + string.replace(escapable, function (a) { 665 var c = meta[a]; 666 return typeof c === 'string' 667 ? c
vendor: 8,717 bytes, lines 668-915
668 : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 669 }) + '"' : '"' + string + '"'; 670 } 671 672 673 function str(key, holder) { 674 675// Produce a string from holder[key]. 676 677 var i, // The loop counter. 678 k, // The member key. 679 v, // The member value. 680 length, 681 mind = gap, 682 partial, 683 value = holder[key]; 684 685// If the value has a toJSON method, call it to obtain a replacement value. 686 687 if (value && typeof value === 'object' && 688 typeof value.toJSON === 'function') { 689 value = value.toJSON(key); 690 } 691 692// If we were called with a replacer function, then call the replacer to 693// obtain a replacement value. 694 695 if (typeof rep === 'function') { 696 value = rep.call(holder, key, value); 697 } 698 699// What happens next depends on the value's type. 700 701 switch (typeof value) { 702 case 'string': 703 return quote(value); 704 705 case 'number': 706 707// JSON numbers must be finite. Encode non-finite numbers as null. 708 709 return isFinite(value) ? String(value) : 'null'; 710 711 case 'boolean': 712 case 'null': 713 714// If the value is a boolean or null, convert it to a string. Note: 715// typeof null does not produce 'null'. The case is included here in 716// the remote chance that this gets fixed someday. 717 718 return String(value); 719 720// If the type is 'object', we might be dealing with an object or an array or 721// null. 722 723 case 'object': 724 725// Due to a specification blunder in ECMAScript, typeof null is 'object', 726// so watch out for that case. 727 728 if (!value) { 729 return 'null'; 730 } 731 732// Make an array to hold the partial results of stringifying this object value. 733 734 gap += indent; 735 partial = []; 736 737// Is the value an array? 738 739 if (Object.prototype.toString.apply(value) === '[object Array]') { 740 741// The value is an array. Stringify every element. Use null as a placeholder 742// for non-JSON values. 743 744 length = value.length; 745 for (i = 0; i < length; i += 1) { 746 partial[i] = str(i, value) || 'null'; 747 } 748 749// Join all of the elements together, separated with commas, and wrap them in 750// brackets. 751 752 v = partial.length === 0 753 ? '[]' 754 : gap 755 ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' 756 : '[' + partial.join(',') + ']'; 757 gap = mind; 758 return v; 759 } 760 761// If the replacer is an array, use it to select the members to be stringified. 762 763 if (rep && typeof rep === 'object') { 764 length = rep.length; 765 for (i = 0; i < length; i += 1) { 766 if (typeof rep[i] === 'string') { 767 k = rep[i]; 768 v = str(k, value); 769 if (v) { 770 partial.push(quote(k) + (gap ? ': ' : ':') + v); 771 } 772 } 773 } 774 } else { 775 776// Otherwise, iterate through all of the keys in the object. 777 778 for (k in value) { 779 if (Object.prototype.hasOwnProperty.call(value, k)) { 780 v = str(k, value); 781 if (v) { 782 partial.push(quote(k) + (gap ? ': ' : ':') + v); 783 } 784 } 785 } 786 } 787 788// Join all of the member texts together, separated with commas, 789// and wrap them in braces. 790 791 v = partial.length === 0 792 ? '{}' 793 : gap 794 ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' 795 : '{' + partial.join(',') + '}'; 796 gap = mind; 797 return v; 798 } 799 } 800 801// If the JSON object does not yet have a stringify method, give it one. 802 803 if (typeof JSON.stringify !== 'function') { 804 JSON.stringify = function (value, replacer, space) { 805 806// The stringify method takes a value and an optional replacer, and an optional 807// space parameter, and returns a JSON text. The replacer can be a function 808// that can replace values, or an array of strings that will select the keys. 809// A default replacer method can be provided. Use of the space parameter can 810// produce text that is more easily readable. 811 812 var i; 813 gap = ''; 814 indent = ''; 815 816// If the space parameter is a number, make an indent string containing that 817// many spaces. 818 819 if (typeof space === 'number') { 820 for (i = 0; i < space; i += 1) { 821 indent += ' '; 822 } 823 824// If the space parameter is a string, it will be used as the indent string. 825 826 } else if (typeof space === 'string') { 827 indent = space; 828 } 829 830// If there is a replacer, it must be a function or an array. 831// Otherwise, throw an error. 832 833 rep = replacer; 834 if (replacer && typeof replacer !== 'function' && 835 (typeof replacer !== 'object' || 836 typeof replacer.length !== 'number')) { 837 throw new Error('JSON.stringify'); 838 } 839 840// Make a fake root object containing our value under the key of ''. 841// Return the result of stringifying the value. 842 843 return str('', {'': value}); 844 }; 845 } 846 847 848// If the JSON object does not yet have a parse method, give it one. 849 850 if (typeof JSON.parse !== 'function') { 851 JSON.parse = function (text, reviver) { 852 853// The parse method takes a text and an optional reviver function, and returns 854// a JavaScript value if the text is a valid JSON text. 855 856 var j; 857 858 function walk(holder, key) { 859 860// The walk method is used to recursively walk the resulting structure so 861// that modifications can be made. 862 863 var k, v, value = holder[key]; 864 if (value && typeof value === 'object') { 865 for (k in value) { 866 if (Object.prototype.hasOwnProperty.call(value, k)) { 867 v = walk(value, k); 868 if (v !== undefined) { 869 value[k] = v; 870 } else { 871 delete value[k]; 872 } 873 } 874 } 875 } 876 return reviver.call(holder, key, value); 877 } 878 879 880// Parsing happens in four stages. In the first stage, we replace certain 881// Unicode characters with escape sequences. JavaScript handles many characters 882// incorrectly, either silently deleting them, or treating them as line endings. 883 884 text = String(text); 885 cx.lastIndex = 0; 886 if (cx.test(text)) { 887 text = text.replace(cx, function (a) { 888 return '\\u' + 889 ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 890 }); 891 } 892 893// In the second stage, we run the text against regular expressions that look 894// for non-JSON patterns. We are especially concerned with '()' and 'new' 895// because they can cause invocation, and '=' because it can cause mutation. 896// But just to be safe, we want to reject all unexpected forms. 897 898// We split the second stage into 4 regexp operations in order to work around 899// crippling inefficiencies in IE's and Safari's regexp engines. First we 900// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 901// replace all simple value tokens with ']' characters. Third, we delete all 902// open brackets that follow a colon or comma or that begin the text. Finally, 903// we look to see that the remaining characters are only whitespace or ']' or 904// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 905 906 if (/^[\],:{}\s]*$/ 907 .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') 908 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 909 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 910 911// In the third stage we use the eval function to compile the text into a 912// JavaScript structure. The '{' operator is subject to a syntactic ambiguity 913// in JavaScript: it can begin a block or an object literal. We wrap the text 914// in parens to eliminate the ambiguity. 915
916 j = eval('(' + text + ')'); 917 918// In the optional fourth stage, we recursively walk the new structure, passing 919// each name/value pair to a reviver function for possible transformation. 920 921 return typeof reviver === 'function' 922 ? walk({'': j}, '') 923 : j; 924 } 925 926// If the text is not JSON parseable, then a SyntaxError is thrown. 927 928 throw new SyntaxError('JSON.parse'); 929 }; 930 } 931}()); 932 933/*! AmplifyJS-Store - v1.1.0 | @link http://amplifyjs.com/api/store/ | @copyright 2012 AppendTo <http://appendto.com/contact> | @license MIT and GPL V2 */ 934(function( amplify, undefined ) { 935 936 var store = amplify.store = function( key, value, options ) { 937 var type = store.type; 938 if ( options && options.type && options.type in store.types ) { 939 type = options.type; 940 } 941 return store.types[ type ]( key, value, options || {} ); 942 }; 943 944 store.types = {}; 945 store.type = null; 946 store.addType = function( type, storage ) { 947 if ( !store.type ) { 948 store.type = type; 949 } 950 951 store.types[ type ] = storage; 952 store[ type ] = function( key, value, options ) { 953 options = options || {}; 954 options.type = type; 955 return store( key, value, options ); 956 }; 957 }; 958 store.error = function() { 959 return "amplify.store quota exceeded"; 960 }; 961 962 var rprefix = /^__amplify__/; 963 function createFromStorageInterface( storageType, storage ) { 964 store.addType( storageType, function( key, value, options ) { 965 var storedValue, parsed, i, remove, 966 ret = value, 967 now = (new Date()).getTime(); 968 969 if ( !key ) { 970 ret = {}; 971 remove = []; 972 i = 0; 973 try { 974 // accessing the length property works around a localStorage bug 975 // in Firefox 4.0 where the keys don't update cross-page 976 // we assign to key just to avoid Closure Compiler from removing 977 // the access as "useless code" 978 // https://bugzilla.mozilla.org/show_bug.cgi?id=662511 979 key = storage.length; 980 981 while ( key = storage.key( i++ ) ) { 982 if ( rprefix.test( key ) ) { 983 parsed = JSON.parse( storage.getItem( key ) ); 984 if ( parsed.expires && parsed.expires <= now ) { 985 remove.push( key ); 986 } else { 987 ret[ key.replace( rprefix, "" ) ] = parsed.data; 988 } 989 } 990 } 991 while ( key = remove.pop() ) { 992 storage.removeItem( key ); 993 } 994 } catch ( error ) {} 995 return ret; 996 } 997 998 // protect against name collisions with direct storage 999 key = "__amplify__" + key; 1000 1001 if ( value === undefined ) { 1002 storedValue = storage.getItem( key ); 1003 parsed = storedValue ? JSON.parse( storedValue ) : { expires: -1 }; 1004 if ( parsed.expires && parsed.expires <= now ) { 1005 storage.removeItem( key ); 1006 } else { 1007 return parsed.data; 1008 } 1009 } else { 1010 if ( value === null ) { 1011 storage.removeItem( key ); 1012 } else { 1013 parsed = JSON.stringify({ 1014 data: value, 1015 expires: options.expires ? now + options.expires : null 1016 }); 1017 try { 1018 storage.setItem( key, parsed ); 1019 // quota exceeded 1020 } catch( error ) { 1021 // expire old data and try again 1022 store[ storageType ](); 1023 try { 1024 storage.setItem( key, parsed ); 1025 } catch( error ) { 1026 throw store.error(); 1027 } 1028 } 1029 } 1030 } 1031 1032 return ret; 1033 }); 1034 } 1035 1036// localStorage + sessionStorage 1037// IE 8+, Firefox 3.5+, Safari 4+, Chrome 4+, Opera 10.5+, iPhone 2+, Android 2+ 1038 for ( var webStorageType in { localStorage: 1, sessionStorage: 1 } ) { 1039 // try/catch for file protocol in Firefox and Private Browsing in Safari 5 1040 try { 1041 // Safari 5 in Private Browsing mode exposes localStorage 1042 // but doesn't allow storing data, so we attempt to store and remove an item. 1043 // This will unfortunately give us a false negative if we're at the limit. 1044 window[ webStorageType ].setItem( "__amplify__", "x" ); 1045 window[ webStorageType ].removeItem( "__amplify__" ); 1046 createFromStorageInterface( webStorageType, window[ webStorageType ] ); 1047 } catch( e ) {} 1048 } 1049 1050// globalStorage 1051// non-standard: Firefox 2+ 1052// https://developer.mozilla.org/en/dom/storage#globalStorage 1053 if ( !store.types.localStorage && window.globalStorage ) { 1054 // try/catch for file protocol in Firefox 1055 try { 1056 createFromStorageInterface( "globalStorage", 1057 window.globalStorage[ window.location.hostname ] ); 1058 // Firefox 2.0 and 3.0 have sessionStorage and globalStorage 1059 // make sure we default to globalStorage 1060 // but don't default to globalStorage in 3.5+ which also has localStorage 1061 if ( store.type === "sessionStorage" ) { 1062 store.type = "globalStorage"; 1063 } 1064 } catch( e ) {} 1065 } 1066 1067// userData 1068// non-standard: IE 5+
1069// http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx 1070 (function() { 1071 // IE 9 has quirks in userData that are a huge pain 1072 // rather than finding a way to detect these quirks 1073 // we just don't register userData if we have localStorage 1074 if ( store.types.localStorage ) { 1075 return; 1076 } 1077 1078 // append to html instead of body so we can do this from the head 1079 var div = document.createElement( "div" ), 1080 attrKey = "amplify"; 1081 div.style.display = "none"; 1082 document.getElementsByTagName( "head" )[ 0 ].appendChild( div ); 1083 1084 // we can't feature detect userData support 1085 // so just try and see if it fails 1086 // surprisingly, even just adding the behavior isn't enough for a failure 1087 // so we need to load the data as well 1088 try { 1089 div.addBehavior( "#default#userdata" ); 1090 div.load( attrKey ); 1091 } catch( e ) { 1092 div.parentNode.removeChild( div ); 1093 return; 1094 } 1095 1096 store.addType( "userData", function( key, value, options ) { 1097 div.load( attrKey ); 1098 var attr, parsed, prevValue, i, remove, 1099 ret = value, 1100 now = (new Date()).getTime(); 1101 1102 if ( !key ) { 1103 ret = {}; 1104 remove = []; 1105 i = 0; 1106 while ( attr = div.XMLDocument.documentElement.attributes[ i++ ] ) { 1107 parsed = JSON.parse( attr.value ); 1108 if ( parsed.expires && parsed.expires <= now ) { 1109 remove.push( attr.name ); 1110 } else { 1111 ret[ attr.name ] = parsed.data; 1112 } 1113 } 1114 while ( key = remove.pop() ) { 1115 div.removeAttribute( key ); 1116 } 1117 div.save( attrKey ); 1118 return ret; 1119 } 1120 1121 // convert invalid characters to dashes 1122 // http://www.w3.org/TR/REC-xml/#NT-Name 1123 // simplified to assume the starting character is valid 1124 // also removed colon as it is invalid in HTML attribute names 1125 key = key.replace( /[^\-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g, "-" ); 1126 // adjust invalid starting character to deal with our simplified sanitization 1127 key = key.replace( /^-/, "_-" ); 1128 1129 if ( value === undefined ) { 1130 attr = div.getAttribute( key ); 1131 parsed = attr ? JSON.parse( attr ) : { expires: -1 }; 1132 if ( parsed.expires && parsed.expires <= now ) { 1133 div.removeAttribute( key ); 1134 } else { 1135 return parsed.data; 1136 } 1137 } else { 1138 if ( value === null ) { 1139 div.removeAttribute( key ); 1140 } else { 1141 // we need to get the previous value in case we need to rollback 1142 prevValue = div.getAttribute( key ); 1143 parsed = JSON.stringify({ 1144 data: value, 1145 expires: (options.expires ? (now + options.expires) : null) 1146 }); 1147 div.setAttribute( key, parsed ); 1148 } 1149 } 1150 1151 try { 1152 div.save( attrKey ); 1153 // quota exceeded 1154 } catch ( error ) { 1155 // roll the value back to the previous value 1156 if ( prevValue === null ) { 1157 div.removeAttribute( key ); 1158 } else { 1159 div.setAttribute( key, prevValue ); 1160 } 1161 1162 // expire old data and try again 1163 store.userData(); 1164 try { 1165 div.setAttribute( key, parsed ); 1166 div.save( attrKey ); 1167 } catch ( error ) { 1168 // roll the value back to the previous value 1169 if ( prevValue === null ) { 1170 div.removeAttribute( key ); 1171 } else { 1172 div.setAttribute( key, prevValue ); 1173 } 1174 throw store.error(); 1175 } 1176 } 1177 return ret; 1178 }); 1179 }() ); 1180 1181// in-memory storage 1182// fallback for all browsers to enable the API even if we can't persist data 1183 (function() { 1184 var memory = {}, 1185 timeout = {}; 1186 1187 function copy( obj ) { 1188 return obj === undefined ? undefined : JSON.parse( JSON.stringify( obj ) ); 1189 } 1190 1191 store.addType( "memory", function( key, value, options ) { 1192 if ( !key ) { 1193 return copy( memory ); 1194 } 1195 1196 if ( value === undefined ) { 1197 return copy( memory[ key ] ); 1198 } 1199 1200 if ( timeout[ key ] ) { 1201 clearTimeout( timeout[ key ] ); 1202 delete timeout[ key ]; 1203 } 1204 1205 if ( value === null ) { 1206 delete memory[ key ]; 1207 return null; 1208 } 1209 1210 memory[ key ] = value; 1211 if ( options.expires ) { 1212 timeout[ key ] = setTimeout(function() { 1213 delete memory[ key ]; 1214 delete timeout[ key ]; 1215 }, options.expires ); 1216 } 1217 1218 return value; 1219 }); 1220 }() ); 1221 1222}( this.amplify = this.amplify || {} ) ); 1223 1224/*! ios-orientationchange-fix.js | Script by @scottjehl rebound by @wilto, modified by Peter Wooster | @link https://github.com/scottjehl/iOS-Orientationchange-Fix | @copyright Scott Jehl <@scottjehl> | @license MIT / GPLV2 */ 1225(function(w){ 1226 1227 // This fix addresses an Mobile Safari iOS bug, so return early if the UA claims it's something else. 1228 var ua = navigator.userAgent.toLowerCase(); 1229 if( !( /iphone|ipad|ipod/.test( navigator.platform.toLowerCase() ) 1230 && /os [1-5]_[0-9_]* like mac os x/i.test(ua) 1231 && ua.indexOf( "applewebkit" ) > -1 1232 && ua.indexOf( "crios") == -1 // chrome for iOS doesn't have the bug 1233 )){ 1234 return; 1235 } 1236 1237 var doc = w.document; 1238 1239 if( !doc.querySelector ){ return; } 1240 var meta = doc.querySelector( "meta[name=viewport]" ); 1241 if( !meta ){ return; } 1242 var initialContent = meta && meta.getAttribute( "content" ); 1243 var disabledZoom = initialContent + ",maximum-scale=1"; 1244 var enabledZoom = initialContent + ",maximum-scale=10"; 1245 var enabled = true; 1246 var x, y, z, aig; 1247 function restoreZoom(){ 1248 meta.setAttribute( "content", enabledZoom ); 1249 enabled = true; 1250 } 1251 1252 function disableZoom(){ 1253 meta.setAttribute( "content", disabledZoom ); 1254 enabled = false;
1255 } 1256 1257 function checkTilt( e ){ 1258 var ori = w.orientation; 1259 // if it's landscape we're out of here 1260 if(90 == Math.abs(w.orientation)) { 1261 if(enabled)restoreZoom(); 1262 return; 1263 } 1264 1265 aig = e.accelerationIncludingGravity; 1266 x = Math.abs( aig.x ); 1267 y = Math.abs( aig.y ); 1268 1269 // If in the danger zone where x is much greater than y turn off zoom 1270 if(y == 0 || (x/y) > 1.2){ 1271 if(enabled)disableZoom(); 1272 }else if( !enabled )restoreZoom(); 1273 } 1274 1275 w.addEventListener( "orientationchange", restoreZoom, false ); 1276 w.addEventListener( "devicemotion", checkTilt, false ); 1277 1278})( this ); 1279 1280 1281/*! jQuery resize event - v1.1 | @link http://benalman.com/projects/jquery-resize-plugin/ | Copyright (c) 2010 "Cowboy" Ben Alman | @license MIT/GPL */ 1282// Script: jQuery resize event 1283// 1284// *Version: 1.1, Last updated: 3/14/2010* 1285// 1286// Project Home - http://benalman.com/projects/jquery-resize-plugin/ 1287// GitHub - http://github.com/cowboy/jquery-resize/ 1288// Source - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.js 1289// (Minified) - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.min.js (1.0kb) 1290// 1291// About: License 1292// 1293// Copyright (c) 2010 "Cowboy" Ben Alman, 1294// Dual licensed under the MIT and GPL licenses. 1295// http://benalman.com/about/license/ 1296// 1297// About: Examples 1298// 1299// This working example, complete with fully commented code, illustrates a few 1300// ways in which this plugin can be used. 1301// 1302// resize event - http://benalman.com/code/projects/jquery-resize/examples/resize/ 1303// 1304// About: Support and Testing 1305// 1306// Information about what version or versions of jQuery this plugin has been 1307// tested with, what browsers it has been tested in, and where the unit tests 1308// reside (so you can test it yourself). 1309// 1310// jQuery Versions - 1.3.2, 1.4.1, 1.4.2 1311// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1. 1312// Unit Tests - http://benalman.com/code/projects/jquery-resize/unit/ 1313// 1314// About: Release History 1315// 1316// 1.1 - (3/14/2010) Fixed a minor bug that was causing the event to trigger 1317// immediately after bind in some circumstances. Also changed $.fn.data 1318// to $.data to improve performance. 1319// 1.0 - (2/10/2010) Initial release 1320 1321(function($,window,undefined){ 1322 '$:nomunge'; // Used by YUI compressor. 1323 1324 // A jQuery object containing all non-window elements to which the resize 1325 // event is bound. 1326 var elems = $([]), 1327 1328 // Extend $.resize if it already exists, otherwise create it. 1329 jq_resize = $.resizecontainer = $.extend( $.resize, {} ), 1330 1331 timeout_id, 1332 1333 // Reused strings. 1334 str_setTimeout = 'setTimeout', 1335 str_resize = 'resizecontainer', 1336 str_data = str_resize + '-special-event', 1337 str_delay = 'delay', 1338 str_throttle = 'throttleWindow'; 1339 1340 // Property: jQuery.resize.delay 1341 // 1342 // The numeric interval (in milliseconds) at which the resize event polling 1343 // loop executes. Defaults to 250. 1344 1345 jq_resize[ str_delay ] = 250; 1346 1347 // Property: jQuery.resize.throttleWindow 1348 // 1349 // Throttle the native window object resize event to fire no more than once 1350 // every <jQuery.resize.delay> milliseconds. Defaults to true. 1351 // 1352 // Because the window object has its own resize event, it doesn't need to be 1353 // provided by this plugin, and its execution can be left entirely up to the 1354 // browser. However, since certain browsers fire the resize event continuously 1355 // while others do not, enabling this will throttle the window resize event, 1356 // making event behavior consistent across all elements in all browsers. 1357 // 1358 // While setting this property to false will disable window object resize 1359 // event throttling, please note that this property must be changed before any 1360 // window object resize event callbacks are bound. 1361
1362 jq_resize[ str_throttle ] = true; 1363 1364 // Event: resize event 1365 // 1366 // Fired when an element's width or height changes. Because browsers only 1367 // provide this event for the window element, for other elements a polling 1368 // loop is initialized, running every <jQuery.resize.delay> milliseconds 1369 // to see if elements' dimensions have changed. You may bind with either 1370 // .resize( fn ) or .bind( "resize", fn ), and unbind with .unbind( "resize" ). 1371 // 1372 // Usage: 1373 // 1374 // > jQuery('selector').bind( 'resize', function(e) { 1375 // > // element's width or height has changed! 1376 // > ... 1377 // > }); 1378 // 1379 // Additional Notes: 1380 // 1381 // * The polling loop is not created until at least one callback is actually 1382 // bound to the 'resize' event, and this single polling loop is shared 1383 // across all elements. 1384 // 1385 // Double firing issue in jQuery 1.3.2: 1386 // 1387 // While this plugin works in jQuery 1.3.2, if an element's event callbacks 1388 // are manually triggered via .trigger( 'resize' ) or .resize() those 1389 // callbacks may double-fire, due to limitations in the jQuery 1.3.2 special 1390 // events system. This is not an issue when using jQuery 1.4+. 1391 // 1392 // > // While this works in jQuery 1.4+ 1393 // > $(elem).css({ width: new_w, height: new_h }).resize(); 1394 // > 1395 // > // In jQuery 1.3.2, you need to do this: 1396 // > var elem = $(elem); 1397 // > elem.css({ width: new_w, height: new_h }); 1398 // > elem.data( 'resize-special-event', { width: elem.width(), height: elem.height() } ); 1399 // > elem.resize(); 1400 1401 $.event.special[ str_resize ] = { 1402 1403 // Called only when the first 'resize' event callback is bound per element. 1404 setup: function() { 1405 // Since window has its own native 'resize' event, return false so that 1406 // jQuery will bind the event using DOM methods. Since only 'window' 1407 // objects have a .setTimeout method, this should be a sufficient test. 1408 // Unless, of course, we're throttling the 'resize' event for window. 1409 if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } 1410 1411 var elem = $(this); 1412 1413 // Add this element to the list of internal elements to monitor. 1414 elems = elems.add( elem ); 1415 1416 // Initialize data store on the element. 1417 $.data( this, str_data, { w: elem.width(), h: elem.height() } ); 1418 1419 // If this is the first element added, start the polling loop. 1420 if ( elems.length === 1 ) { 1421 loopy(); 1422 } 1423 }, 1424 1425 // Called only when the last 'resize' event callback is unbound per element. 1426 teardown: function() { 1427 // Since window has its own native 'resize' event, return false so that 1428 // jQuery will unbind the event using DOM methods. Since only 'window' 1429 // objects have a .setTimeout method, this should be a sufficient test. 1430 // Unless, of course, we're throttling the 'resize' event for window. 1431 if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } 1432 1433 var elem = $(this); 1434 1435 // Remove this element from the list of internal elements to monitor. 1436 elems = elems.not( elem ); 1437 1438 // Remove any data stored on the element. 1439 elem.removeData( str_data ); 1440 1441 // If this is the last element removed, stop the polling loop. 1442 if ( !elems.length ) { 1443 clearTimeout( timeout_id ); 1444 } 1445 }, 1446 1447 // Called every time a 'resize' event callback is bound per element (new in 1448 // jQuery 1.4). 1449 add: function( handleObj ) { 1450 // Since window has its own native 'resize' event, return false so that 1451 // jQuery doesn't modify the event object. Unless, of course, we're 1452 // throttling the 'resize' event for window. 1453 if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } 1454 1455 var old_handler; 1456 1457 // The new_handler function is executed every time the event is triggered. 1458 // This is used to update the internal element data store with the width 1459 // and height when the event is triggered manually, to avoid double-firing 1460 // of the event callback. See the "Double firing issue in jQuery 1.3.2" 1461 // comments above for more information. 1462 1463 function new_handler( e, w, h ) { 1464 var elem = $(this), 1465 data = $.data( this, str_data ); 1466 1467 // If called from the polling loop, w and h will be passed in as 1468 // arguments. If called manually, via .trigger( 'resize' ) or .resize(), 1469 // those values will need to be computed. 1470 data.w = w !== undefined ? w : elem.width(); 1471 data.h = h !== undefined ? h : elem.height(); 1472 1473 old_handler.apply( this, arguments ); 1474 } 1475 1476 // This may seem a little complicated, but it normalizes the special event 1477 // .add method between jQuery 1.4/1.4.1 and 1.4.2+ 1478 if ( $.isFunction( handleObj ) ) { 1479 // 1.4, 1.4.1 1480 old_handler = handleObj; 1481 return new_handler; 1482 } else { 1483 // 1.4.2+ 1484 old_handler = handleObj.handler; 1485 handleObj.handler = new_handler; 1486 } 1487 } 1488 1489 }; 1490 1491 function loopy() { 1492 1493 // Start the polling loop, asynchronously. 1494 timeout_id = window[ str_setTimeout ](function(){ 1495 1496 // Iterate over all elements to which the 'resize' event is bound. 1497 elems.each(function(){ 1498 var elem = $(this), 1499 width = elem.width(), 1500 height = elem.height(), 1501 data = $.data( this, str_data ); 1502 1503 // If element size has changed since the last time, update the element 1504 // data store and trigger the 'resize' event. 1505 if ( width !== data.w || height !== data.h ) { 1506 elem.trigger( str_resize, [ data.w = width, data.h = height ] ); 1507 } 1508 1509 }); 1510 1511 // Loop. 1512 loopy(); 1513 1514 }, jq_resize[ str_delay ] ); 1515 1516 } 1517 1518})(jQuery, window); 1519 1520/** 1521 * Count the number of substring occurrences 1522 * @param haystack {String} the string to search in 1523 * @param needle {String} the substring to search for 1524 * @return {Number} 1525 */ 1526function substr_count(haystack, needle) 1527{ 1528 var needle_esc = needle.replace(/(?=[\\^$*+?.\(\)|{\}[\]])/g, "\\"); 1529 var pattern = new RegExp(""+needle_esc+"", "g"); 1530 var count = haystack.match(pattern); 1531 return count ? count.length : 0; 1532} 1533 1534/** 1535 * Checks if a variable is a String 1536 * @param str {*} The variable to test 1537 * @return {Boolean} 1538 */ 1539function isString(str) 1540{ 1541 return typeof str == "string"; 1542} 1543 1544/** 1545 * Checks if a variable is a Number 1546 * @param num {*} The variable to test 1547 * @return {Boolean} 1548 */ 1549function isNumber(num) 1550{ 1551 return (!isNaN(parseFloat(num)) && isFinite(num)); 1552} 1553 1554/** 1555 * Checks if a variable is a Boolean 1556 * @param bool {*} The variable to test 1557 * @return {Boolean} 1558 */ 1559function isBool(bool) 1560{ 1561 return (bool === true || bool === false); 1562} 1563 1564/** 1565 * Checks if the variable is an array 1566 * @param arr {*} The variable to test 1567 * @return {Boolean} 1568 */ 1569function isArray(arr) { 1570 return Object.prototype.toString.call(arr) === "[object Array]"; 1571} 1572
1573/** 1574 * Checks if a variable is an Object 1575 * @param obj {*} The variable to test 1576 * @return {Boolean} 1577 */ 1578function isObject(obj) 1579{ 1580 switch(true) 1581 { 1582 case (isArray(obj)): 1583 return false; 1584 break; 1585 } 1586 1587 var is_empty_obj_bool; 1588 for ( var p in obj ) 1589 { 1590 if (obj.hasOwnProperty(p)) 1591 { 1592 is_empty_obj_bool = false; 1593 break; 1594 } 1595 } 1596 is_empty_obj_bool = (isBool(is_empty_obj_bool)) ? is_empty_obj_bool: true; 1597 1598 switch(true) 1599 { 1600 case (typeof obj === "object" && is_empty_obj_bool === false): 1601 return true; 1602 break; 1603 } 1604 1605 return false; 1606} 1607 1608/** 1609 * Checks if a variable is a Function 1610 * @param obj {*} The variable to test 1611 * @return {Boolean} 1612 */ 1613function isFunction(obj) { 1614 return !!(obj && obj.constructor && obj.call && obj.apply); 1615} 1616 1617/** 1618 * Converts a string array to an integer array 1619 * It converts all the string values of an array into their integer equivalents 1620 * @param str_arr {Array} The array to convert 1621 * @return {Array} 1622 */ 1623function arrayToInteger(str_arr) 1624{ 1625 var int_arr_item_int, 1626 array_count_int, 1627 keys_arr = [], 1628 values_arr = [], 1629 values_int_arr = [], 1630 final_int_arr = []; 1631 1632 keys_arr = array_keys(str_arr); 1633 values_arr = array_values(str_arr); 1634 1635 array_count_int = count(str_arr); 1636 for(var i = 0; i < array_count_int; i++) 1637 { 1638 int_arr_item_int = parseInt(values_arr[i]); 1639 values_int_arr.push(int_arr_item_int); 1640 } 1641 1642 final_int_arr = array_combine(keys_arr, values_int_arr); 1643 return final_int_arr; 1644} 1645 1646/** 1647 * Checks to see if array has duplicate values 1648 * @param arr {Array} the array to check 1649 * @return {Boolean} 1650 */ 1651function arrayHasDuplicates(arr) { 1652 var valuesSoFar = {}, 1653 array_count_int = count(arr); 1654 1655 for (var i = 0; i < array_count_int; ++i) { 1656 var value = arr[i]; 1657 if (Object.prototype.hasOwnProperty.call(valuesSoFar, value)) { 1658 return true; 1659 } 1660 valuesSoFar[value] = true; 1661 } 1662 return false; 1663} 1664 1665/** 1666 * Gets a value from an array derived after a tokenized string is exploded 1667 * @param str {String} the tokenized string that will be exploded to an array 1668 * @param delim {String} the delimiter 1669 * @param key {Integer} the position of the array to return 1670 * @return {String} 1671 */ 1672function getValueAfterExplode(str, delim, key) 1673{ 1674 var arr = explode(delim, str); 1675 return arr[key]; 1676} 1677 1678/** 1679 * Sorts an array in numerical order and returns an array containing the keys of the array in the new sorted order 1680 * @param values_arr {Array} The array to sort 1681 * @return {Array} 1682 */ 1683function getSortedKeys(values_arr) 1684{ 1685 var array_with_keys = []; 1686 for (var i = 0; i < values_arr.length; i++) { 1687 array_with_keys.push({ key: i, value: values_arr[i] }); 1688 } 1689 1690 array_with_keys.sort(function(a, b) { 1691 if (a.value < b.value) { return -1; } 1692 if (a.value > b.value) { return 1; } 1693 return 0; 1694 }); 1695 1696 var keys = []; 1697 for (var i = 0; i < array_with_keys.length; i++) { 1698 keys.push(array_with_keys[i].key); 1699 } 1700 1701 return keys; 1702} 1703 1704/** 1705 * Finds the nearest matching number in an array containing integers 1706 * It is recommended that you sort the array in order before using it with this function 1707 * @param haystack_arr {Array} The array containing the integer values 1708 * @param needle_int {Number} The reference integer which is used to find the match 1709 * @param return_key_only_bool {Boolean} If true, will return the key position of the nearest match. Default is false. 1710 * @param is_ceil_bool {Boolean} If true, will return the nearest highest number even if a lower number is technically 'closer'. Default value is true. 1711 * @param disable_ceil_offset_int {Number} Please see explanation below. 1712 * For example, let's say needle_int is 120 and the nearest matching numbers are 115 on the lower end and 140 on the higher end 1713 * Being the is_ceil_bool is true by default, 140 would ordinarily be the nearest number selected. However, if disable_ceil_offset is set to 5, this will set is_ceil_bool to false, and 115 will be returned as the nearest number selected because the difference between it (the true nearest matching number) and 120 (needle_int) is 5 or less, even though needle_int is higher and under normal circumstances 120 would have been returned instead 1714 * @return {Number} 1715 */ 1716function getClosestNumberMatchArray(haystack_arr, needle_int) 1717{ 1718 var myArgs = Array.prototype.slice.call(arguments), 1719 return_key_only_bool = (isBool(myArgs[2])) ? myArgs[2]: false, 1720 is_ceil_bool = (isBool(myArgs[3])) ? myArgs[3]: true, 1721 disable_ceil_offset_int = (isNumber(myArgs[4])) ? myArgs[4] : 0, 1722 value_diff_int, 1723 value_diff_keys_sort_arr = [], 1724 value_diff_values_arr = [], 1725 key_final_int, 1726 value_final_int, 1727 value_final_needle_diff_int 1728 ; 1729 1730 haystack_arr = arrayToInteger(haystack_arr); 1731 needle_int = parseInt(needle_int); 1732 1733 for(var i = 0; i < count(haystack_arr); i++) 1734 { 1735 value_diff_int = needle_int - haystack_arr[i]; 1736 value_diff_int = Math.abs(value_diff_int); 1737 value_diff_values_arr.push(value_diff_int); 1738 } 1739 1740 value_diff_keys_sort_arr = getSortedKeys(value_diff_values_arr); 1741 key_final_int = value_diff_keys_sort_arr[0]; 1742 value_final_int = haystack_arr[key_final_int]; 1743 1744 value_final_needle_diff_int = value_final_int - needle_int; 1745 value_final_needle_diff_int = Math.abs(value_final_needle_diff_int); 1746 1747 //Manage for when needle_int is higher than nearest matching number, and highest matching number is required 1748 switch(true) 1749 { 1750 case (value_final_int < needle_int): 1751 is_ceil_bool = (value_final_needle_diff_int <= disable_ceil_offset_int) ? false : is_ceil_bool;
1752 key_final_int = (is_ceil_bool) ? key_final_int + 1 : key_final_int; 1753 break; 1754 } 1755 1756 //return value or key 1757 value_final_int = haystack_arr[key_final_int]; 1758 return (return_key_only_bool) ? key_final_int: value_final_int; 1759} 1760 1761/** 1762 * This function checks if a number is an integer decimal and if the integral part of the decimal is even 1763 * For example, 640.123 will be true, 641.123 will be false 1764 * @param number_int {Number} The Integer Decimal 1765 * @param allow_negative_bool {Boolean} This will allow negative numbers to be considered 1766 * @return {Boolean} 1767 */ 1768function isEvenDecimal(number_int) 1769{ 1770 var myArgs = Array.prototype.slice.call(arguments), 1771 allow_negative_bool = (isBool(myArgs[1])) ? myArgs[1]: false, 1772 number_temp_int, 1773 number_temp_mod_int; 1774 1775 number_temp_int = (number_int < 0 && allow_negative_bool) ? number_int * -1 : number_int; 1776 number_temp_mod_int = number_temp_int % 1; 1777 1778 //return false if Number is less than one or is not a decimal integer 1779 switch(true) 1780 { 1781 case (!isNumber(number_temp_int) || number_temp_int < 1 || number_temp_mod_int == 0): 1782 return false; 1783 break; 1784 } 1785 1786 //Check if integral part is even number 1787 number_temp_int = Math.floor(number_temp_int); 1788 number_temp_mod_int = number_temp_int % 2; 1789 1790 return !!((number_temp_mod_int == 0)); 1791} 1792 1793/** 1794 * Retrieves the current and full URL of the document 1795 * @param option_flag_str {String} If present, specifies a specific part of the URL to return 1796 * The two options flags available are: 1797 * 1. bp [basepath] - Will return 'http://restive.io/index.html' if current URL is 'http://restive.io/index.html?id=1234' 1798 * 2. bd [basedir] - Will return 'http://restive.io/test' if current URL is 'http://restive.io/test/index.html?id=4' 1799 * 3. q [query] - Will return 'id=1234' if current URL is 'http://restive.io/index.html?id=1234' 1800 * @param url_str {String} By default, this function uses document.URL to capture the URL. You may provide your own url using this parameter 1801 * @return {String} 1802 */ 1803function getUrl() 1804{ 1805 var myArgs = Array.prototype.slice.call(arguments), 1806 option_flag_str = (isString(myArgs[0]) && myArgs[0] != '') ? myArgs[0]: '', 1807 url_str = (isString(myArgs[1]) && myArgs[1] != '') ? myArgs[1] : document.URL, 1808 url_temp_str, 1809 url_temp_arr = [], 1810 is_url_has_q_bool = /\?+/.test(url_str), 1811 url_match_arr = url_str.match(/^([h|f]{1}[t]{0,1}tp[s]{0,1}\:\/\/)([^ ]+?)\?([^ ]*)/i); 1812 1813 switch(true) 1814 { 1815 case (option_flag_str == 'basepath' || option_flag_str == 'bp'): 1816 return (is_url_has_q_bool) ? url_match_arr[1]+url_match_arr[2] : url_str; 1817 break; 1818 1819 case (option_flag_str == 'basedir' || option_flag_str == 'bd'): 1820 url_temp_str = (is_url_has_q_bool) ? url_match_arr[1]+url_match_arr[2] : url_str; 1821 url_temp_arr = explode('/', url_temp_str); 1822 url_temp_arr.pop(); 1823 1824 return implode('/', url_temp_arr); 1825 break; 1826 1827 case (option_flag_str == 'query' || option_flag_str == 'q'): 1828 return (is_url_has_q_bool) ? url_match_arr[3]: ""; 1829 break; 1830 1831 default: 1832 return url_str; 1833 } 1834} 1835 1836(function($){ 1837 1838 /** 1839 * Determines if a given element is a child or descendant of another 1840 * @param {String} $elem_sel_parent_str The selector of the parent object 1841 * @param {String} $elem_sel_child_str The selector of the suspected child object 1842 * @return {Boolean} 1843 */ 1844 window.elementIsChildOf = function($elem_sel_parent_str, $elem_sel_child_str){ 1845 var result_bool = false, 1846 elem_parent = $(''+$elem_sel_parent_str+''), 1847 elem_child = $(''+$elem_sel_child_str+''); 1848 1849 switch(true) 1850 { 1851 case ($(elem_child).parents().index(elem_parent) != -1): 1852 result_bool = true; 1853 break; 1854 } 1855 1856 return result_bool; 1857 }; 1858 1859 /** 1860 * Retrieves the text value of a JQuery Selector 1861 * @param {Object} el the JQuery Object/Element 1862 * @return {String} 1863 */ 1864 window.getSelector = function(el){ 1865 var $el = $(el); 1866 1867 var id = $el.attr("id"); 1868 if (id) { //"should" only be one of these if theres an ID 1869 return "#"+ id; 1870 } 1871 1872 var node = $el[0].nodeName.toLowerCase(); 1873 if(node == 'html' || node == 'body'){ 1874 return node; 1875 } 1876 1877 var selector = $el.parents() 1878 .map(function() { return this.tagName; }) 1879 .get().reverse().join(" "); 1880 1881 if (selector) { 1882 selector += " "+ $el[0].nodeName; 1883 } 1884 1885 var classNames = $el.attr("class"); 1886 if (classNames) { 1887 selector += "." + $.trim(classNames).replace(/\s/gi, "."); 1888 } 1889 1890 var name = $el.attr('name'); 1891 if (name) { 1892 selector += "[name='" + name + "']"; 1893 } 1894 if (!name){ 1895 var index = $el.index(); 1896 if (index) { 1897 index = index + 1; 1898 selector += ":nth-child(" + index + ")"; 1899 } 1900 } 1901 return selector; 1902 }; 1903 1904})(jQuery); 1905 1906 1907/*! Restive.JS | @copyright 2013 Obinwanne Hill */ 1908var Restive = (function(window, document, $) { 1909 1910 //Check for Dependency 1911 switch(true) 1912 { 1913 case (typeof $ != 'function'): 1914 //exit gracefully if missing 1915 throw 'Restive.JS requires JQuery to run!'; 1916 break; 1917 } 1918 1919 //Define local vars 1920 var root = this, 1921 Restive, 1922 win = window, 1923 docElem = document.documentElement, 1924 $win = $(win), 1925 screen = win.screen, 1926 vSpan, vPitch, cSpan, cPitch, dSpan, dPitch, eSpan, ePitch, 1927 media = win.matchMedia || win.msMatchMedia || Object 1928 ; 1929 1930 //Create window storage 1931 window.rstv_store = {'main': {}}; 1932 window.parent.rstv_store = {'main': {}}; 1933 1934 //Create window storage function 1935 window.rstv_store.storage = function(){ 1936 var myArgs = Array.prototype.slice.call(arguments), 1937 key_str = myArgs[0], 1938 value_res = myArgs[1], 1939 is_value_valid_bool = !!((typeof value_res !== "undefined" && value_res !== null) && ((isString(value_res) && value_res != "") || isNumber(value_res) || (isArray(value_res) && count(value_res) > 0) || isBool(value_res) || isObject(value_res))), 1940 is_value_null_bool = !!((value_res === null)) 1941 ; 1942 1943 switch(true) 1944 { 1945 case (is_value_valid_bool): 1946 window.rstv_store.main[""+key_str+""] = value_res; 1947 return; 1948 break; 1949 1950 case (is_value_null_bool): 1951 window.rstv_store.main[""+key_str+""] = null; 1952 return; 1953 break; 1954 1955 default: 1956 return window.rstv_store.main[""+key_str+""]; 1957 } 1958 }; 1959 1960 /** 1961 * Initialize and store some important default values. 1962 * Return false if initialization has already been performed in same session. 1963 * @return {Boolean} 1964 */ 1965 var init = function () { 1966 //detect private browsing 1967 window.rstv_store.main["rstv_is_priv_browsing"] = !!((_detectPrivateBrowsing())); 1968 1969 var is_init_bool = store("rstv_is_init"), 1970 retr; 1971 1972 switch (true) { 1973 case (is_init_bool): 1974 store("rstv_timestamp_curr", microtime(true)); 1975 1976 store("rstv_url", getUrl('bp')); 1977 1978 //load counter 1979 _loadCounter(); 1980 1981 /** FIX FOR LOCAL BROWSER-BASED EMULATORS **/ 1982 _fixForLocalDev(); 1983 1984 //update the dimension and orientation info storage-wide 1985 _initDimensionVars(); 1986 _updateDimensionStore(); 1987 _updateOrientationStore(); 1988 1989 retr = false;
1990 break; 1991 1992 default: 1993 //flag that defaults are set 1994 store("rstv_timestamp_curr", microtime(true)); 1995 store("rstv_timestamp_init", store("rstv_timestamp_curr")); 1996 store("rstv_loaded_count", 0, '', {expires: 1500}); 1997 1998 store("rstv_is_init", true); 1999 2000 store("rstv_url", getUrl('bp')); 2001 store("rstv_url_hash", md5(getUrl('bp'))); 2002 2003 _initDimensionVars(); 2004 _updateDimensionStore(); 2005 store("rstv_ort_init", getOrientation()); 2006 store("rstv_ort_curr", getOrientation()); 2007 2008 //load counter 2009 _loadCounter(); 2010 2011 retr = true; 2012 } 2013 2014 return retr; 2015 }; 2016 2017 /** 2018 * Reinitializes the Restive Class on Demand 2019 * It resets Dimension, Orientation, and Timestamp Info 2020 * The Restive Class is initialized as soon as Restive.JS is called via <script\> tag. In certain circumstances 2021 * this might bring out a slight change in Dimension and Orientation Data especially for PCs. 2022 * Re-initialization will usually correct any discrepancies 2023 * NOTE: It is advised that you use this function only once, within document.ready, and before any other Restive-related methods 2024 */ 2025 function reInit() 2026 { 2027 //reset timestamps 2028 store("rstv_timestamp_curr", microtime(true)); 2029 store("rstv_timestamp_init", store("rstv_timestamp_curr")); 2030 2031 //update the dimension and orientation info storage-wide 2032 _initDimensionVars(); 2033 _updateDimensionStore(); 2034 store("rstv_ort_init", getOrientation()); 2035 store("rstv_ort_curr", getOrientation()); 2036 } 2037 2038 /** 2039 * Initializes important dimension variables to Local storage 2040 * @private 2041 */ 2042 function _initDimensionVars() 2043 { 2044 store("rstv_var_doc_client_w", docElem.clientWidth); 2045 store("rstv_var_doc_client_h", docElem.clientHeight); 2046 store("rstv_var_win_outer_w", window.outerWidth); 2047 store("rstv_var_win_outer_h", window.outerHeight); 2048 store("rstv_var_win_screen_w", screen.width); 2049 store("rstv_var_win_screen_h", screen.height); 2050 } 2051 2052 /** 2053 * Keeps track of how many times Restive.JS is loaded in rapid succession in a single browser session 2054 * @private 2055 */ 2056 function _loadCounter() 2057 { 2058 var load_count_int = parseInt(store("rstv_loaded_count")); 2059 switch(true) 2060 { 2061 case (!isNumber(load_count_int)): 2062 load_count_int = 0; 2063 break; 2064 } 2065 load_count_int++; 2066 store("rstv_loaded_count", load_count_int, '', {expires: 1500}); 2067 } 2068 2069 /** 2070 * This is a special function to deal with certain issues experienced when using Restive.JS in Chrome Ripple 2071 * and other Browser Based Mobile Device emulators that load scripts more than once in rapid succession 2072 * when they are being initialized 2073 * @private 2074 */ 2075 function _fixForLocalDev() 2076 { 2077 var load_count_int = parseInt(store("rstv_loaded_count")), 2078 ffld_is_init_bool = store("rstv_ffld_is_init"); 2079 2080 switch(true) 2081 { 2082 case (load_count_int > 1): 2083 store("rstv_viewportW rstv_viewportW_dip rstv_viewportH rstv_viewportH_dip rstv_screenW rstv_screenH", null); 2084 store("rstv_is_ios rstv_is_android rstv_is_blackberry rstv_is_symbian rstv_is_windows rstv_is_windows_phone", null); 2085 store("rstv_is_android_1_ rstv_is_android_2_ rstv_is_android_3_", null); 2086 store("rstv_is_phone rstv_is_tablet rstv_is_tv rstv_is_pc", null); 2087 store("rstv_ort_curr rstv_timestamp_curr rstv_is_portrait rstv_is_landscape", null); 2088 store("rstv_multi_count rstv_multi_bpm_idx rstv_cache_bpm rstv_cache_bpm_lock rstv_cache_req rstv_cache_bpm_viewport_diff", null); 2089 store("rstv_user_agent", null); 2090 2091 store("rstv_timestamp_curr", microtime(true)); 2092 store("rstv_ort_curr", getOrientation()); 2093 2094 switch(true) 2095 { 2096 case (!ffld_is_init_bool): 2097 2098 store("rstv_timestamp_init", store("rstv_timestamp_curr")); 2099 store("rstv_ort_init", getOrientation()); 2100 2101 //Mark that this function has been executed 2102 store("rstv_ffld_is_init", true); 2103 break; 2104 } 2105 2106 break; 2107 } 2108 } 2109 2110 /** 2111 * Detects whether private browsing is active or not 2112 * @return {Boolean} 2113 */ 2114 function _detectPrivateBrowsing() 2115 { 2116 try { 2117 localStorage.setItem("__test", "data"); 2118 } 2119 catch (e) 2120 { 2121 if (/QUOTA_?EXCEEDED/i.test(e.name)) { 2122 return true; 2123 } 2124 } 2125 return false;
2126 } 2127 2128 /** 2129 * Stores a value in LocalStorage [or other storage type], or retrieves previously stored value 2130 * Leverages AmplifyJS Store 2131 * @param key_str The identifier for the value being stored 2132 * @param value_res The value to store [optional] 2133 * @param type_str The type of storage format to be used 2134 * @param options_res A set of key/value pairs that relate to settings for storing the value 2135 * @return {*} 2136 */ 2137 function store() 2138 { 2139 var myArgs = Array.prototype.slice.call(arguments); 2140 var is_priv_browsing_bool = window.rstv_store.main["rstv_is_priv_browsing"], 2141 key_str = myArgs[0], 2142 value_res = myArgs[1], 2143 type_str = ((typeof myArgs[2] !== "undefined" && myArgs[2] !== null) && (isString(myArgs[2]) && myArgs[2] != "")) ? myArgs[2] : 'ss', 2144 options_res = myArgs[3], 2145 store_func_name, 2146 store_func, 2147 list_del_key_arr = [], 2148 is_getall_bool = (isString(key_str) && key_str != "") ? false: true, 2149 is_value_valid_bool = !!((typeof value_res !== "undefined" && value_res !== null) && ((isString(value_res) && value_res != "") || isNumber(value_res) || (isArray(value_res) && count(value_res) > 0) || isBool(value_res) || isObject(value_res))), 2150 is_value_null_bool = !!((value_res === null)); 2151 2152 try 2153 { 2154 switch(true) 2155 { 2156 case (is_priv_browsing_bool): 2157 //Private Browsing Detected, Use Windows Store 2158 store_func_name = 'storage'; 2159 store_func = window.rstv_store[store_func_name]; 2160 break; 2161 2162 default: 2163 //Use AmplifyJS Store 2164 switch(true) 2165 { 2166 case (type_str == 'ls'): 2167 store_func_name = 'localStorage'; 2168 break; 2169 2170 default: 2171 store_func_name = 'sessionStorage'; 2172 } 2173 store_func = amplify.store[store_func_name]; 2174 2175 //if sessionStorage is not supported, default to amplifyJS 2176 switch(true) 2177 { 2178 case (!window.sessionStorage || !window.localStorage): 2179 store_func = amplify.store; 2180 break; 2181 } 2182 2183 //return all values if no key is provided 2184 switch(true) 2185 { 2186 case (is_getall_bool): 2187 return store_func(); 2188 break; 2189 } 2190 } 2191 2192 //return stored value if empty value argument and value is not null 2193 switch(true) 2194 { 2195 case (!is_value_valid_bool && !is_value_null_bool): 2196 return store_func(key_str); 2197 break; 2198 } 2199 2200 //delete object if value is null 2201 switch(true) 2202 { 2203 case (is_value_null_bool): 2204 //delete stored object(s) 2205 list_del_key_arr = explode(" ", key_str); 2206 for (var i = 0; i < count(list_del_key_arr); i++) 2207 { 2208 store_func(list_del_key_arr[i], null); 2209 } 2210 return null; 2211 break; 2212 } 2213 2214 //store value 2215 store_func(key_str, null); 2216 store_func(key_str, value_res, options_res); 2217 } 2218 catch(e){ 2219 alert(e); 2220 2221 } 2222 } 2223 2224 /** 2225 * This function is used to track specific String values in a storage system 2226 * The two possible storage options are (1) Cookies, and (2) Local Storage 2227 * It will store individual values as a tokenized string. 2228 * For example, if you call this function on two strings 'trial' and 'error', the stored value will be 'trial|error' 2229 * 2230 * @param key_str {String} The identifier of the value being stored 2231 * @param value_str {String} The individual value to store and track 2232 * @param store_type_str {String} The storage type of the container that will hold the stored value. 'ck' represents 'Cookie', and 'ls' represents 'LocalStorage' 2233 * @param unique_bool {Boolean} The setting that determines if the individual values should be unique. If this is true, no two string values will be identical 2234 * @param expires_ck_int|expires_ls_int {Number} Expiry setting 2235 * @param reverse_order_bool {Boolean} This affects the order with which data is stored. If true, data will be stored in a LIFO (Last In - First Out) format. If false, data will be store in a FIFO (First In - First Out) format 2236 * @param delim_str {String} The character that will be used to delimit the stored string 2237 * @param data_count_int {Number} The number of individual 2238 * @return {Boolean} 2239 */ 2240 function storeVarTracker(key_str, value_str) 2241 { 2242 /** 2243 * This function saves the current Restive.JS settings tracking code to history 2244 */ 2245 var myArgs = Array.prototype.slice.call(arguments), 2246 store_type_str = (isString(myArgs[2]) && myArgs[2] != "") ? myArgs[2] : 'ck',
2247 unique_bool = (isBool(myArgs[3])) ? myArgs[3]: false, 2248 expires_ls_int = (isNumber(myArgs[4]) || isString(myArgs[4])) ? parseInt(myArgs[4]): '', 2249 expires_ck_int = (isNumber(myArgs[4]) || isString(myArgs[4])) ? parseInt(myArgs[4]): 30, 2250 reverse_order_bool = (isBool(myArgs[5])) ? myArgs[5]: true, 2251 delim_str = (isString(myArgs[6]) && myArgs[6] != "") ? myArgs[6]: '-!', 2252 data_count_int = (isNumber(myArgs[7]) || isString(myArgs[7])) ? parseInt(myArgs[7]): 60, 2253 history_tok_str, 2254 history_upd_tok_str, 2255 history_arr = [], 2256 history_upd_arr = [] 2257 ; 2258 2259 //check if this tracking code exists 2260 history_tok_str = (store_type_str == 'ls') ? store(key_str) : $.cookie(key_str); 2261 switch(true) 2262 { 2263 case (history_tok_str === null || typeof history_tok_str === "undefined"): 2264 (store_type_str == 'ls') ? store(key_str, value_str, 2265 '', {expires: expires_ls_int}) : $.cookie(key_str, value_str, { expires: expires_ck_int, path: '/' }); 2266 2267 return true; 2268 break; 2269 2270 case (typeof history_tok_str !== "undefined" && history_tok_str !== null && history_tok_str != ""): 2271 //get cookie info and check if tracking cookie exists 2272 history_arr = explode(delim_str, history_tok_str); 2273 switch(true) 2274 { 2275 case (in_array(value_str, history_arr) && unique_bool): 2276 return false; 2277 break; 2278 2279 default: 2280 //generate the current tracking code 2281 switch(true) 2282 { 2283 case (reverse_order_bool): 2284 history_arr.unshift(value_str); 2285 history_upd_arr = history_arr.slice(0, data_count_int); 2286 2287 history_upd_tok_str = implode(delim_str, history_upd_arr); 2288 break; 2289 2290 default: 2291 history_arr.push(value_str); 2292 history_upd_tok_str = implode(delim_str, history_arr); 2293 } 2294 2295 //store the tracking code 2296 (store_type_str == 'ls') ? store(key_str, history_upd_tok_str, '', {expires: expires_ls_int}) : $.cookie(key_str, history_upd_tok_str, { expires: expires_ck_int, path: '/' }); 2297 2298 return true; 2299 } 2300 break; 2301 } 2302 } 2303 2304 /** 2305 * This function is used to validate a string value against the tokenized string stored via storeVarTracker() 2306 * It checks to see if the string value is one of the tokenized item. If yes, it returns true; if no, it returns false 2307 * For example if needle = 'trial', and the var_key_str identifies a stored string with value = 'trial|error', then validation will be successful 2308 * @param value_needle_str {String} The string value that will be validated against the stored value 2309 * @param key_str {String} The identifier of the value that was stored via storeVarTracker() 2310 * @param store_type_str {String} The storage type of the container holding the stored value. 'ck' represents 'Cookie', and 'ls' represents 'LocalStorage' 2311 * @param delim_str {String} The character that will be used to delimit the stored string 2312 * @return {Boolean} 2313 */
2314 function storeVarValidator(value_needle_str, key_str) 2315 { 2316 var myArgs = Array.prototype.slice.call(arguments), 2317 store_type_str = (isString(myArgs[2]) && myArgs[2] != "") ? myArgs[2] : 'ck', 2318 delim_str = (isString(myArgs[3]) && myArgs[3] != "") ? myArgs[3] : '-!', 2319 value_str = (store_type_str == 'ls') ? store(key_str) : $.cookie(key_str); 2320 2321 switch(true) 2322 { 2323 case (typeof value_str !== "undefined" && value_str !== null && value_str != ""): 2324 var value_arr = []; 2325 value_arr = explode(delim_str, value_str); 2326 2327 switch(true) 2328 { 2329 case (in_array(value_needle_str, value_arr)): 2330 //tracking code is in history 2331 return true; 2332 break; 2333 2334 default: 2335 return false; 2336 } 2337 break; 2338 2339 default: 2340 return false; 2341 } 2342 } 2343 2344 /** 2345 * Checks if a value stored in LocalStorage exists and contains a value 2346 * Also stores a value if provided if the value did not previously exist or was invali
2346d 2347 * @param key_str {String} The identifier for the value that was stored 2348 * @param value_store_res {*} The value to store [optional] 2349 * @return {Boolean} 2350 */ 2351 function isStorageValueSet(key_str) 2352 { 2353 var myArgs = Array.prototype.slice.call(arguments), 2354 value_store_res = myArgs[1], 2355 value_retr_res = store(''+key_str+''), 2356 is_value_valid_bool = !!((typeof value_store_res !== "undefined" && value_store_res !== null)), 2357 is_store_value_set_bool = false 2358 ; 2359 2360 //Determine if store value exists and is valid 2361 switch(true) 2362 { 2363 case (isBool(value_retr_res) || (value_retr_res !== null && typeof value_retr_res !== "undefined" && value_retr_res != "")): 2364 is_store_value_set_bool = true; 2365 break; 2366 } 2367 2368 //Return result of check immediately if no value is provided 2369 switch(true) 2370 { 2371 case (!is_value_valid_bool): 2372 return is_store_value_set_bool; 2373 break; 2374 } 2375 2376 //Store value if it does not exist and/or is invalid. 2377 switch(true) 2378 { 2379 case (!is_store_value_set_bool): 2380 store(key_str, value_store_res); 2381 break; 2382 } 2383 } 2384 2385 /** 2386 * Increment (or Decrement) a stored variable 2387 * @param key_str {String} The identifier of the value that was stored 2388 * @param increment_value_int {Number} The size of the increment operation. Default is 1 2389 * @param is_decrement_bool {Boolean} If set to true, will decrement instead of increment 2390 * @return {Number|Boolean} 2391 */ 2392 function incrementStorageValue(key_str) 2393 { 2394 var myArgs = Array.prototype.slice.call(arguments), 2395 increment_value_int = (isNumber(myArgs[1])) ? myArgs[1]: 1, 2396 is_decrement_bool = (isBool(myArgs[2])) ? myArgs[2]: false, 2397 value_int; 2398 2399 value_int = parseInt(store(key_str)); 2400 switch(true) 2401 { 2402 case (!isNumber(value_int)): 2403 return false; 2404 break; 2405 } 2406 2407 value_int = (is_decrement_bool) ? value_int - increment_value_int: value_int + increment_value_int; 2408 store(key_str, value_int); 2409 2410 return value_int; 2411 } 2412 2413 /** 2414 * Returns a list of standard resolution dimensions 2415 * @param class_str {String} the class of dimensions to return. It could be 'w' = widths, or 'h' = heights 2416 * @return {Array} 2417 * @private 2418 */ 2419 function _getResolutionDimensionList(class_str) 2420 { 2421 var std_w_arr = [120, 128, 160, 200, 240, 272, 300, 320, 352, 360, 480, 540, 576, 600, 640, 720, 768, 800, 864, 900, 1024, 1050, 1080, 1152, 1200, 1440, 1536, 1600, 1800, 2048, 2160, 2400, 3072, 3200, 4096, 4320, 4800], 2422 std_h_arr = [160, 240, 260, 320, 400, 432, 480, 640, 720, 800, 854, 960, 1024, 1136, 1152, 1280, 1360, 1366, 1400, 1440, 1600, 1680, 1920, 2048, 2560, 2880, 3200, 3840, 4096, 5120, 6400, 7680] 2423 ; 2424 2425 switch(true) 2426 { 2427 case (class_str == 'w'): 2428 return std_w_arr; 2429 break; 2430 2431 case (class_str == 'h'): 2432 return std_h_arr; 2433 break; 2434 } 2435 } 2436 2437 /** 2438 * Get the Viewport or Screen Dimensions of the Device 2439 * @param type_str {String} The type of operation to execute 2440 * vW = viewport width, vH = viewport height, sW = screen width, sH = screen height 2441 * @param adj_screen_size_bool {Boolean} This determines if the screen size result should be adjusted to return the nearest standard resolution. For example if actual screen height is 1184, 1280 will be returned as it is the nearest standard resolution height. Default is true 2442 * @return {*} 2443 * @private 2444 */ 2445 function _getDimension(type_str) 2446 { 2447 var myArgs = Array.prototype.slice.call(arguments), 2448 adj_screen_size_bool = (isBool(myArgs[1])) ? myArgs[1]: true, 2449 dim_res, 2450 dim_res_adj, 2451 adj_dim_res_bool = false, 2452 is_pc_or_tv_bool = !!((isPC() || isTV())), 2453 pixel_ratio_device_int = getPixelRatio(), 2454 pixel_ratio_virtual_int, 2455 win_outer_w_int = store("rstv_var_win_outer_w"), 2456 win_outer_h_int = store("rstv_var_win_outer_h"), 2457 doc_client_w_int = store("rstv_var_doc_client_w"), 2458 doc_client_h_int = store("rstv_var_doc_client_h"), 2459 win_screen_w_int = store("rstv_var_win_screen_w"), 2460 win_screen_h_int = store("rstv_var_win_screen_h") 2461 ; 2462 2463 /** 2464 * Return dimensions quickly if device is PC 2465 */ 2466 switch(true) 2467 { 2468 case (is_pc_or_tv_bool): 2469 switch(true) 2470 { 2471 case (type_str == 'vW'): 2472 dim_res = doc_client_w_int; 2473 break; 2474 2475 case (type_str == 'vH'): 2476 dim_res = doc_client_h_int; 2477 break; 2478 2479 case (type_str == 'sW'): 2480 dim_res = win_screen_w_int; 2481 break; 2482 2483 case (type_str == 'sH'): 2484 dim_res = win_screen_h_int; 2485 break; 2486 } 2487 2488 switch(true) 2489 { 2490 case (type_str == 'vW' || type_str == 'vH'): 2491 dim_res = (pixel_ratio_device_int >= 1.5) ? dim_res * pixel_ratio_device_int : dim_res; 2492 break; 2493 } 2494 2495 dim_res = Math.floor(dim_res); 2496 return dim_res; 2497 2498 break; 2499 } 2500 2501 /** 2502 * If not PC, continue processing 2503 */ 2504 2505 var device_user_agent_str = getUserAgent(), 2506 is_opera_browser_bool = /opera.+(mini|mobi)/i.test(device_user_agent_str), 2507 is_ios_bool = !!((isIOS())), 2508 is_symbian_bool = !!((isSymbian())), 2509 is_windows_bool = !!((isWindows())),
2510 is_android_bool = !!((isAndroid())), 2511 is_android_1_bool = !!((isAndroid('1.'))), 2512 is_android_2_bool = !!((isAndroid('2.'))), 2513 is_special_needs_bool = !!(((is_android_1_bool || is_android_2_bool) || is_symbian_bool || is_windows_bool)), 2514 viewport_w_int, 2515 viewport_h_int, 2516 screen_w_int = win_screen_w_int, 2517 screen_h_int = win_screen_h_int, 2518 screen_w_fix_int = screen_w_int, 2519 ort_w_int, 2520 ort_h_int, 2521 viewport_w_to_screen_w_ratio_int, 2522 screen_w_to_viewport_w_diff_int, 2523 screen_w_to_h_ratio_int, 2524 fixed_screen_dim_bool, 2525 std_w_arr = _getResolutionDimensionList('w'), 2526 std_h_arr = _getResolutionDimensionList('h'), 2527 std_w_temp_arr = std_w_arr, 2528 std_h_temp_arr = std_h_arr, 2529 is_landscape_v_bool, //viewport 2530 is_landscape_s_bool, //screen 2531 is_landscape_v_extended_verify_bool 2532 ; 2533 2534 /** 2535 * Get the viewport dimensions 2536 */ 2537 switch(true) 2538 { 2539 case (is_special_needs_bool): 2540 viewport_w_int = (win_outer_w_int <= 0) ? doc_client_w_int : win_outer_w_int; 2541 viewport_h_int = (win_outer_h_int <= 0) ? doc_client_h_int : win_outer_h_int; 2542 ort_w_int = viewport_w_int; 2543 ort_h_int = viewport_h_int; 2544 break; 2545 2546 default: 2547 viewport_w_int = doc_client_w_int; 2548 viewport_h_int = doc_client_h_int; 2549 ort_w_int = doc_client_w_int; 2550 ort_h_int = doc_client_h_int; 2551 } 2552 2553 /** 2554 * Modify Screen Dimensions if Android 2 or Symbian Platform 2555 */ 2556 switch(true) 2557 { 2558 case ((is_android_2_bool || is_symbian_bool) && !is_opera_browser_bool): 2559 screen_w_int = (win_outer_w_int <= 0) ? screen_w_int : win_outer_w_int; 2560 screen_h_int = (win_outer_h_int <= 0) ? screen_h_int : win_outer_h_int; 2561 break; 2562 } 2563 2564 //Determine orientation 2565 screen_w_to_h_ratio_int = screen_w_int/screen_h_int; 2566 screen_w_to_viewport_w_diff_int = screen_w_int - viewport_w_int; 2567 screen_w_to_viewport_w_diff_int = Math.abs(screen_w_to_viewport_w_diff_int); 2568 2569 is_landscape_v_extended_verify_bool = (is_opera_browser_bool && viewport_w_int < 260) ? ((screen_w_to_viewport_w_diff_int <= 4) && (screen_w_to_h_ratio_int >= 1) ? true : false) : true; 2570 is_landscape_v_bool = !!((ort_h_int <= ort_w_int) && is_landscape_v_extended_verify_bool); 2571 is_landscape_s_bool = !!((screen_h_int <= screen_w_int)); 2572 2573 /** 2574 * Reduce resolution dimension list size if iOS 2575 * This improves the accuracy for first-generation iOS devices 2576 */ 2577 switch(true) 2578 { 2579 case (is_ios_bool): 2580 std_w_temp_arr = std_w_temp_arr.slice(7); 2581 std_h_temp_arr = std_h_temp_arr.slice(6); 2582 break; 2583 2584 case (is_android_bool): 2585 std_w_temp_arr = std_w_temp_arr.slice(4); 2586 std_h_temp_arr = std_h_temp_arr.slice(3); 2587 break; 2588 2589 case (is_symbian_bool): 2590 std_w_temp_arr = std_w_temp_arr.slice(4); 2591 break; 2592 } 2593 2594 /** 2595 * Reverse resolution dimension list when orientation changes 2596 */ 2597 switch(true) 2598 { 2599 case (is_landscape_v_bool): 2600 std_w_arr = std_h_temp_arr; 2601 std_h_arr = std_w_temp_arr; 2602 break; 2603 2604 default: 2605 std_w_arr = std_w_temp_arr; 2606 std_h_arr = std_h_temp_arr; 2607 } 2608 2609 /** 2610 * Get Dimensions 2611 */ 2612 switch(true) 2613 { 2614 case (type_str == 'vW'): 2615 dim_res = viewport_w_int; 2616 break; 2617 2618 case (type_str == 'vH'): 2619 dim_res = viewport_h_int; 2620 break; 2621 2622 case (type_str == 'sW'): 2623 /** 2624 * This aims to correct any screen dimension discrepancies that usually occur when the 2625 * raw viewport dimensions say the orientation is in one mode, but the raw screen dimensions 2626 * say it is in another mode. Certain devices e.g. iPad will not change screen dimensions as the 2627 * orientation changes. When this happens, we reverse values for screen_w and screen_h to compensate 2628 */ 2629 fixed_screen_dim_bool = !!((is_landscape_v_bool === true && is_landscape_s_bool === false) || (is_landscape_v_bool === false && is_landscape_s_bool === true)); 2630 2631 dim_res = (fixed_screen_dim_bool) ? screen_h_int : screen_w_int ; 2632 2633 //get the fixed screen width 2634 screen_w_fix_int = (fixed_screen_dim_bool) ? screen_h_int : screen_w_int ; 2635 2636 dim_res_adj = dim_res * pixel_ratio_device_int; 2637 adj_dim_res_bool = adj_screen_size_bool ? ((in_array(dim_res, std_w_arr) || in_array(dim_res_adj, std_w_arr)) ? false: true) : false;
2638 break; 2639 2640 case (type_str == 'sH'): 2641 /** 2642 * This aims to correct any screen dimension discrepancies that usually occur when the 2643 * raw viewport dimensions say the orientation is in one mode, but the raw screen dimensions 2644 * say it is in another mode. Certain devices e.g. iPad will not change screen dimensions as the 2645 * orientation changes. When this happens, we reverse values for screen_w and screen_h to compensate 2646 */ 2647 fixed_screen_dim_bool = !!((is_landscape_v_bool === true && is_landscape_s_bool === false) || (is_landscape_v_bool === false && is_landscape_s_bool === true)); 2648 2649 dim_res = (fixed_screen_dim_bool) ? screen_w_int : screen_h_int ; 2650 2651 //get the fixed screen width 2652 screen_w_fix_int = (fixed_screen_dim_bool) ? screen_h_int : screen_w_int ; 2653 2654 dim_res_adj = dim_res * pixel_ratio_device_int; 2655 adj_dim_res_bool = adj_screen_size_bool ? ((in_array(dim_res, std_h_arr) || in_array(dim_res_adj, std_h_arr)) ? false: true) : false; 2656 break; 2657 } 2658 2659 /** 2660 * Get the virtual pixel ratio i.e. screen vs viewport dimensions 2661 */ 2662 pixel_ratio_virtual_int = screen_w_fix_int/viewport_w_int; 2663 2664 /** 2665 * Return if Device Pixel Ratio is 1 or less and Virtual Pixel Ratio is less than 1.1 2666 */ 2667 switch(true) 2668 { 2669 case (pixel_ratio_device_int <= 1 && pixel_ratio_virtual_int <= 1.1): 2670 switch(true) 2671 { 2672 case (type_str == 'sW' && adj_dim_res_bool): 2673 dim_res = getClosestNumberMatchArray(std_w_arr, dim_res, '', '', 8); 2674 break; 2675 2676 case (type_str == 'sH' && adj_dim_res_bool): 2677 dim_res = getClosestNumberMatchArray(std_h_arr, dim_res, '', '', 8); 2678 break; 2679 } 2680 return dim_res; 2681 break; 2682 } 2683 2684 /** 2685 * Continue if Pixel Ratio is greater than 1 2686 */ 2687 switch(true) 2688 { 2689 case (is_ios_bool): 2690 dim_res = dim_res * pixel_ratio_device_int; 2691 break; 2692 2693 default: 2694 switch(true) 2695 { 2696 case (!is_android_2_bool): 2697 /** 2698 * Case 1: Device Pixel Ratio is 1 or less, and Virtual Pixel Ratio is greater than 1.1 2699 * Update Viewport Dimensions only. Do not update Screen Dimensions 2700 * Case 2. Device Pixel Ratio is more than 1, and Virtual Pixel Ratio is less than or equal to 1.1 2701 * Update both Viewport and Screen Dimensions 2702 * Case 3. Device Pixel Ratio is more than 1, and Virtual Pixel Ratio is greater than 1.1 2703 * Update Viewport Dimensions only. Do not update Screen Dimensions 2704 */ 2705 switch(true) 2706 { 2707 //1 2708 case (pixel_ratio_device_int <= 1 && pixel_ratio_virtual_int > 1.1): 2709 dim_res = (in_array(type_str, ['vW', 'vH'])) ? dim_res * pixel_ratio_virtual_int : dim_res; 2710 break; 2711 //2 2712 case (pixel_ratio_device_int > 1 && pixel_ratio_virtual_int <= 1.1): 2713 switch(true) 2714 { 2715 case (pixel_ratio_device_int <= 1.1): 2716 //Special Operation for some devices that report device pixel ratio slightly above one 2717 switch(true) 2718 { 2719 case (in_array(type_str, ['vW', 'vH'])): 2720 dim_res = dim_res * pixel_ratio_device_int; 2721 dim_res = (isEvenDecimal(dim_res)) ? Math.floor(dim_res) : dim_res; 2722 break; 2723 } 2724 break; 2725 2726 default: 2727 dim_res = dim_res * pixel_ratio_device_int; 2728 } 2729 break; 2730 //3 2731 case (pixel_ratio_device_int > 1 && pixel_ratio_virtual_int > 1.1): 2732 switch(true) 2733 { 2734 case (in_array(type_str, ['vW', 'vH'])): 2735 dim_res = dim_res * pixel_ratio_device_int; 2736 dim_res = (isEvenDecimal(dim_res)) ? Math.floor(dim_res) : Math.ceil(dim_res); 2737 break; 2738 } 2739 break; 2740 } 2741 break; 2742 } 2743 2744 /** 2745 * Get the nearest standard screen widths or heights 2746 */ 2747 switch(true) 2748 { 2749 case (type_str == 'sW' && adj_dim_res_bool): 2750 dim_res = getClosestNumberMatchArray(std_w_arr, dim_res, '', '', 8); 2751 break; 2752 2753 case (type_str == 'sH' && adj_dim_res_bool): 2754 dim_res = getClosestNumberMatchArray(std_h_arr, dim_res, '', '', 8); 2755 break; 2756 } 2757 } 2758 2759 dim_res = Math.floor(dim_res); 2760 return dim_res; 2761 } 2762 2763 /** 2764 * Get the Viewport dimensions in Device-Independent Pixels 2765 * @param type_str {String} The type of operation. Either 'w' for width, or 'h' for height 2766 * @return {Number} 2767 * @private 2768 */ 2769 function _getViewportDimensionDIP(type_str) 2770 { 2771 var dim_res, 2772 is_width_bool = !!((type_str == 'w')), 2773 is_pc_or_tv_bool = !!((isPC() || isTV())), 2774 pixel_ratio_int = getPixelRatio() 2775 ; 2776 2777 switch(true) 2778 { 2779 case (is_pc_or_tv_bool): 2780 //If pc or tv, moderate use of pixel ratio 2781 pixel_ratio_int = (pixel_ratio_int <= 1.5) ? 1 : pixel_ratio_int; 2782 break; 2783 } 2784 dim_res = (is_width_bool) ? viewportW()/pixel_ratio_int : viewportH()/pixel_ratio_int; 2785 return Math.round(dim_res); 2786 } 2787 2788 /** 2789 * Get the dimension of a DOM Element. 2790 * It uses the JQuery dimension functions e.g. width(), innerHeight(), etc. 2791 * @param el_obj {String} The JQuery element object 2792 * @param type_str {String} The type of operation. w = width, h = height 2793 * @param format_str {String} The dimension retrieval method to use. There are three as follows 2794 * 1: d = default = el_obj.width() or el_obj.height() 2795 * 2: i = inner = el_obj.innerWidth() or el_obj.innerHeight() 2796 * 3: o = outer = el_obj.outerWidth() or el_obj.outerHeight() 2797 * @param force_dip_bool {Boolean} Determines whether to consider the element dimensions in device-independent pixel format or not. true = do not use DIP, false [default] = use DIP 2798 * @return {Number|Boolean} 2799 * @private 2800 */ 2801 function _getElementDimension(el_obj, type_str) 2802 { 2803 var myArgs = Array.prototype.slice.call(arguments), 2804 format_str = (isString(myArgs[2]) && myArgs[2] != "") ? myArgs[2]: 'd', 2805 force_dip_bool = (isBool(myArgs[3])) ? myArgs[3]: fal
2805se, 2806 dim_final_int 2807 ; 2808 type_str = type_str.toLowerCase(); 2809 2810 switch(true) 2811 { 2812 case (type_str == 'w'): 2813 switch(true) 2814 { 2815 case (format_str == 'i'): 2816 dim_final_int = el_obj.innerWidth(); 2817 break; 2818 2819 case (format_str == 'o'): 2820 dim_final_int = el_obj.outerWidth(); 2821 break; 2822 2823 default: 2824 dim_final_int = el_obj.width(); 2825 } 2826 break; 2827 2828 case (type_str == 'h'): 2829 switch(true) 2830 { 2831 case (format_str == 'i'): 2832 dim_final_int = el_obj.innerHeight(); 2833 break; 2834 2835 case (format_str == 'o'): 2836 dim_final_int = el_obj.outerHeight(); 2837 break; 2838 2839 default: 2840 dim_final_int = el_obj.height(); 2841 } 2842 break; 2843 2844 default: 2845 dim_final_int = false; 2846 } 2847 2848 switch(true) 2849 { 2850 case (force_dip_bool === false): 2851 //Convert to Device Pixels 2852 dim_final_int = dim_final_int * getPixelRatio(); 2853 break; 2854 } 2855 2856 return dim_final_int; 2857 } 2858 2859 /** 2860 * Get the width of a DOM element 2861 * @param el_obj {Object} The JQuery Element Object 2862 * @param dim_format_str {String} The dimension retrieval method to use. 2863 * @param force_dip_bool {Boolean} Flag for forced Device-Independent Pixel consideration 2864 * @return {Number|Boolean} 2865 * @private 2866 */ 2867 function _elementW(el_obj){ 2868 var myArgs = Array.prototype.slice.call(arguments), 2869 dim_format_str = myArgs[1], 2870 force_dip_bool = myArgs[2] 2871 ; 2872 return _getElementDimension(el_obj, 'w', dim_format_str, force_dip_bool); 2873 } 2874 2875 /** 2876 * Get the height of a DOM element 2877 * @param el_obj {Object} The JQuery Element Object 2878 * @param dim_format_str {String} The dimension retrieval method to use. 2879 * @param force_dip_bool {Boolean} Flag for forced Device-Independent Pixel consideration 2880 * @return {Number|Boolean} 2881 * @private 2882 */ 2883 function _elementH(el_obj){ 2884 var myArgs = Array.prototype.slice.call(arguments), 2885 dim_format_str = myArgs[1], 2886 force_dip_bool = myArgs[2] 2887 ; 2888 return _getElementDimension(el_obj, 'h', dim_format_str, force_dip_bool); 2889 } 2890 2891 /** 2892 * Get the width of the viewport 2893 * @return {*|Number} 2894 */ 2895 function viewportW(){ 2896 return (isStorageValueSet("rstv_viewportW")) ? store("rstv_viewportW"): _getDimension('vW', store("rstv_is_getdim_screen_adj")); 2897 } 2898 2899 /** 2900 * Get the height of the viewport 2901 * @return {*|Number} 2902 */ 2903 function viewportH(){ 2904 return (isStorageValueSet("rstv_viewportH")) ? store("rstv_viewportH"): _getDimension('vH', store("rstv_is_getdim_screen_adj")); 2905 } 2906 2907 /** 2908 * Get the width of the screen i.e. device width 2909 * @return {*|Number} 2910 */ 2911 function screenW(){ 2912 return (isStorageValueSet("rstv_screenW")) ? store("rstv_screenW"): _getDimension('sW', store("rstv_is_getdim_screen_adj")); 2913 } 2914 2915 /** 2916 * Get the height of the screen i.e. device height 2917 * @return {*|Number} 2918 */ 2919 function screenH(){ 2920 return (isStorageValueSet("rstv_screenH")) ? store("rstv_screenH"): _getDimension('sH', store("rstv_is_getdim_screen_adj")); 2921 } 2922 2923 /** 2924 * Get the Device-Independent Pixel width of the viewport 2925 */ 2926 function pixelW() 2927 { 2928 return (isStorageValueSet("rstv_viewportW_dip")) ? store("rstv_viewportW_dip"): _getViewportDimensionDIP('w'); 2929 } 2930 2931 /** 2932 * Get the Device-Independent Pixel height of the viewport 2933 */ 2934 function pixelH() 2935 { 2936 return (isStorageValueSet("rstv_viewportH_dip")) ? store("rstv_viewportH_dip"): _getViewportDimensionDIP('h'); 2937 } 2938 2939 /** 2940 * Resets/Updates the cached values (localStorage) of Viewport and Screen Dimension Info 2941 * @private 2942 */ 2943 function _updateDimensionStore() 2944 { 2945 //reset 2946 store("rstv_viewportW rstv_viewportW_dip rstv_viewportH rstv_viewportH_dip rstv_screenW rstv_screenH", null); 2947 2948 //reload 2949 store("rstv_viewportW", viewportW()); 2950 store("rstv_viewportH", viewportH()); 2951 store("rstv_screenW", screenW()); 2952 store("rstv_screenH", screenH()); 2953 store("rstv_viewportW_dip", pixelW()); 2954 store("rstv_viewportH_dip", pixelH()); 2955 } 2956 2957 /** 2958 * Get the Device Pixel Ratio 2959 * @param decimal {Number} An optional number (integer or float) to check against actual pixel ratio 2960 * @return {Number|Boolean} 2961 */ 2962 function getPixelRatio(decimal) 2963 { 2964 //check if pixel ratio check has already been done. If so, return stored value 2965 switch(true) 2966 { 2967 case (isStorageValueSet("rstv_pixel_ratio")): 2968 return store("rstv_pixel_ratio"); 2969 break; 2970 } 2971 2972 var device_user_agent_str = getUserAgent(), 2973 is_opera_browser_bool = /opera.+(mini|mobi)/i.test(device_user_agent_str), 2974 doc_client_w = store("rstv_var_doc_client_w"), 2975 win_outer_w = store("rstv_var_win_outer_w"), 2976 win_screen_w = store("rstv_var_win_screen_w"), 2977 is_symbian_bool = !!(isSymbian()), 2978 is_windows_bool = !!(isWindows()), 2979 is_android_1_bool = !!((isAndroid('1.'))), 2980 is_android_2_bool = !!((isAndroid('2.'))), 2981 is_special_needs_bool = !!(((is_android_1_bool || is_android_2_bool) || is_symbian_bool || is_windows_bool)), 2982 is_windows_or_symbian_bool = !!(is_windows_bool || is_symbian_bool), 2983 viewport_w = (is_special_needs_bool) ? ((win_outer_w <= 0) ? doc_client_w : win_outer_w) : doc_client_w, 2984 screen_w = ((is_android_2_bool || is_symbian_bool) && !is_opera_browser_bool) ? ((win_outer_w <= 0) ? win_screen_w : win_outer_w) : win_screen_w, 2985 dPR, 2986 dPR_temp, 2987 dPR_virtual, 2988 dPR_retr 2989 ; 2990 2991 /** 2992 * Get the Pixel Ratio 2993 * Make Adjustments for when window.devicePixelRatio is 0 2994 */ 2995 dPR_temp = win.devicePixelRatio; 2996 switch(true) 2997 { 2998 case (dPR_temp <= 0 || typeof dPR_temp === 'undefined' || dPR_temp === null): 2999 dPR_virtual = screen_w/viewport_w; 3000 dPR = dPR_virtual; 3001 switch(true) 3002 { 3003 case (is_windows_or_symbian_bool): 3004 switch(true) 3005 { 3006 case (dPR > 0.5 && dPR < 1.2): 3007 dPR = 1; 3008 break; 3009 3010 case (dPR >= 1.2 && dPR < 2): 3011 dPR = 1.5; 3012 break; 3013 3014 case (dPR >= 2 && dPR < 3): 3015 dPR = 2; 3016 break; 3017 3018 case (dPR >= 3): 3019 dPR = 3; 3020 break; 3021 3022 default: 3023 dPR = 1; 3024 } 3025 break; 3026 } 3027 store("rstv_pixel_ratio_virtual", dPR_virtual); 3028 break; 3029 3030 default: 3031 dPR = dPR_temp; 3032 } 3033 3034 //Return Pixel Ratio variations 3035 switch(true) 3036 { 3037 case (!isNumber(decimal)): 3038 dPR_retr = dPR || (getPixelRatio(3) ? 3 : getPixelRatio(2) ? 2 : getPixelRatio(1.5) ? 1.5 : getPixelRatio(1) ? 1 : 0); 3039 store("rstv_pixel_ratio", dPR_retr); 3040 return dPR_retr; 3041 break; 3042 } 3043 3044 //Return false if not finite 3045 switch(true) 3046 { 3047 case (!isFinite(decimal)): 3048 return false;
3049 break; 3050 } 3051 3052 switch(true) 3053 { 3054 case (dPR && dPR > 0): 3055 return dPR >= decimal; 3056 break; 3057 } 3058 3059 //Revert to .matchMedia/.msMatchMedia for Gecko (FF6+) support 3060 decimal = 'only all and (min--moz-device-pixel-ratio:' + decimal + ')'; 3061 switch(true) 3062 { 3063 case (media(decimal).matches): 3064 return true; 3065 break; 3066 } 3067 3068 return !!media(decimal.replace('-moz-', '')).matches; 3069 } 3070 3071 /** 3072 * Checks if the device is a Retina-device i.e. it has a Pixel Ratio of 2 or greater 3073 * @return {Boolean} 3074 */ 3075 function isRetina() 3076 { 3077 var pixel_ratio_int = getPixelRatio(); 3078 switch(true) 3079 { 3080 case (pixel_ratio_int >= 2): 3081 return true; 3082 break; 3083 } 3084 3085 return false; 3086 } 3087 3088 /** 3089 * A comparison function for checking if a number is within a range of two other numbers 3090 * @param {Function} fn 3091 * @return {Function} 3092 */ 3093 function rangeCompare(fn) { 3094 return function(min, max) { 3095 var myArgs = Array.prototype.slice.call(arguments), 3096 bool, 3097 el = myArgs[2], 3098 el_valid_bool = !!((isObject(el) && (typeof el !== "undefined" && el !== null))), 3099 wf = myArgs[3], 3100 f_dip = myArgs[4], 3101 curr = (el_valid_bool) ? fn(el, wf, f_dip) : fn() 3102 ; 3103 3104 bool = curr >= (min || 0); 3105 return !max ? bool : bool && curr <= max; 3106 }; 3107 } 3108 3109 //Range Comparison Booleans for Viewport and Screen 3110 vSpan = rangeCompare(viewportW); 3111 vPitch = rangeCompare(viewportH); 3112 dSpan = rangeCompare(screenW); 3113 dPitch = rangeCompare(screenH); 3114 cSpan = rangeCompare(pixelW); 3115 cPitch = rangeCompare(pixelH); 3116 3117 //Range Comparison Booleans for DOM Element Containers 3118 eSpan = rangeCompare(_elementW); 3119 ePitch = rangeCompare(_elementH); 3120 3121 /** 3122 * Gets the user agent of the Device 3123 * This function makes provision for proxy-based browsers that employ X11 forwarding 3124 * @return {String} 3125 */ 3126 function getUserAgent() 3127 { 3128 //check if user agent check has been done and is in storage. If so, return stored value 3129 switch(true) 3130 { 3131 case (isStorageValueSet("rstv_user_agent")): 3132 return store("rstv_user_agent"); 3133 break; 3134 } 3135 3136 var ua = navigator.userAgent.toLowerCase(), 3137 is_proxy_bool; 3138 3139 //Check if device user agent is being updated by proxy-based browser 3140 is_proxy_bool = /mozilla.+x11/i.test(ua); 3141 3142 switch(true) 3143 { 3144 case (is_proxy_bool): 3145 $.ajax({ 3146 type: "GET", 3147 async: false, 3148 crossDomain: true, 3149 url: "http://www.restive.io/ping/ua.php", 3150 headers: { 3151 "Cache-Control":"no-cache", 3152 "Pragma":"no-cache" 3153 }, 3154 success: function(response) { 3155 ua = response; 3156 }, 3157 error: function(xhr, status, error_msg){ 3158 console.log('error');/*RemoveLogging:skip*/ 3159 } 3160 }); 3161 break; 3162 } 3163 3164 store("rstv_user_agent", ua); 3165 return ua; 3166 } 3167 3168 /** 3169 * Gets the Operating System Platform of the Device 3170 * There are six possible platforms available 3171 * (1) ios, (2) android, (3) Symbian, (4) Blackberry, (5) Windows, (6) Other 3172 * @return {String} 3173 */ 3174 function getPlatform() 3175 { 3176 switch(true) 3177 { 3178 case (_checkOS("ios")): 3179 return "ios"; 3180 break; 3181 3182 case (_checkOS("android")): 3183 return "android"; 3184 break; 3185 3186 case (_checkOS("symbian")): 3187 return "symbian"; 3188 break; 3189 3190 case (_checkOS("blackberry")): 3191 return "blackberry"; 3192 break; 3193 3194 case (_checkOS("windows")): 3195 return "windows"; 3196 break; 3197 3198 default: 3199 return "other"; 3200 } 3201 } 3202 3203 /** 3204 * Detects the Operating System [Platform] of the Device 3205 * @param os_str {String} The name of the OS 3206 * @param version_str An optional version number [Only valid for Android] 3207 * @return {Boolean} 3208 * @private 3209 */ 3210 function _checkOS(os_str) 3211 { 3212 var myArgs = Array.prototype.slice.call(arguments), 3213 is_version_valid_bool = !!((isString(myArgs[1]) && myArgs[1] != "")), 3214 version_str = '', 3215 version_regex_suffix_str = '', 3216 version_store_suffix_str = '' 3217 ; 3218 3219 //manage version string if provided 3220 switch(true) 3221 { 3222 case (is_version_valid_bool): 3223 version_str = myArgs[1]; 3224 version_str = version_str.replace(/^\s+|\s+$/g, ""); 3225 version_regex_suffix_str = ' '+version_str; 3226 version_store_suffix_str = '_'+version_str.replace(".", "_"); 3227 break; 3228 } 3229 3230 //Check if value is stored. Return if true 3231 switch(true) 3232 { 3233 case (isStorageValueSet("rstv_is_"+os_str+version_store_suffix_str)): 3234 return store("rstv_is_"+os_str+version_store_suffix_str); 3235 break; 3236 } 3237 3238 var nav = getUserAgent(), 3239 is_os_bool = false;
3240 3241 switch(true) 3242 { 3243 case (os_str == "ios"): 3244 is_os_bool = /\bipad|\biphone|\bipod/i.test(nav); 3245 break; 3246 3247 case (os_str == "android"): 3248 var pattern = new RegExp("\\bandroid"+version_regex_suffix_str, "i"); 3249 is_os_bool = pattern.test(nav); 3250 break; 3251 3252 case (os_str == "symbian"): 3253 is_os_bool = /series(4|6)0|symbian|symbos|syb-[0-9]+|\bs60\b/i.test(nav); 3254 break; 3255 3256 case (os_str == "blackberry"): 3257 is_os_bool = /bb[0-9]+|blackberry|playbook|rim +tablet/i.test(nav); 3258 break; 3259 3260 case (os_str == "windows"): 3261 is_os_bool = /window mobile|windows +(ce|phone)|windows +nt.+arm|windows +nt.+touch|xblwp7|zunewp7/i.test(nav); 3262 break; 3263 3264 case (os_str == "windows_phone"): 3265 is_os_bool = /windows +phone|xblwp7|zunewp7/i.test(nav); 3266 break; 3267 3268 default: 3269 return false; 3270 } 3271 3272 //persist to local storage and return 3273 store("rstv_is_"+os_str+version_store_suffix_str, is_os_bool); 3274 return !!((is_os_bool)); 3275 } 3276 3277 /** 3278 * Checks if the Device is based on Apple's iOS Platform 3279 * @return {Boolean} 3280 */ 3281 function isIOS() 3282 { 3283 return _checkOS("ios"); 3284 } 3285 3286 /** 3287 * Checks if the Device is based on Apple's iOS Platform 3288 * @return {Boolean} 3289 */ 3290 function isApple() 3291 { 3292 return _checkOS("ios"); 3293 } 3294 3295 /** 3296 * Checks if the Device is based on Android Platform 3297 * @return {Boolean} 3298 */ 3299 function isAndroid() 3300 { 3301 var myArgs = Array.prototype.slice.call(arguments), 3302 version_str = myArgs[0]; 3303 return _checkOS("android", version_str); 3304 } 3305 3306 /** 3307 * Checks if the Device is based on Symbian Platform 3308 * @return {Boolean} 3309 */ 3310 function isSymbian() 3311 { 3312 return _checkOS("symbian"); 3313 } 3314 3315 /** 3316 * Checks if the Device is based on Blackberry Platform 3317 * @return {Boolean} 3318 */ 3319 function isBlackberry() 3320 { 3321 return _checkOS("blackberry"); 3322 } 3323 3324 /** 3325 * Checks if the Device is based on a Windows Platform 3326 * @return {Boolean} 3327 */ 3328 function isWindows() 3329 { 3330 return _checkOS("windows"); 3331 } 3332 3333 /** 3334 * Checks if the Device is based on Windows Phone Platform 3335 * @return {Boolean} 3336 */ 3337 function isWindowsPhone() 3338 { 3339 return _checkOS("windows_phone"); 3340 } 3341 3342 /** 3343 * Mobile Browser Detection Regex 3344 * @param ua {String} User Agent String 3345 * @return {Boolean} 3346 * @private 3347 */ 3348 function _mobileDetect(ua) 3349 { 3350 return /android|android.+mobile|avantgo|bada\/|\bbb[0-9]+|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|\bip(hone|od|ad)|iris|kindle|lge |maemo|meego.+mobile|midp|mmp|motorola|mobile.+firefox|netfront|nokia|nintendo +3ds|opera m(ob|in)i|palm|palm( os)?|phone|p(ixi|re)\/|playbook|rim +tablet|playstation.+vita|plucker|pocket|psp|samsung|(gt\-|bgt\-|sgh\-|sph\-|sch\-)[a-z][0-9]+|series(4|6)0|symbian|symbos|\bs60\b|treo|up\.(browser|link)|vertu|vodafone|wap|windows (ce|phone)|windows +nt.+arm|windows +nt.+touch|xda|xiino|xblwp7|zunewp7/i.test(ua) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
3350sy(01|mb|b\-[0-9]+)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(ua.substr(0, 4)); 3351 } 3352 3353 /** 3354 * Gets the Form Factor of the device 3355 * There are only three form factors available 3356 * (1) Phone, (2) Tablet, (3) TV, (4) PC 3357 * @return {String} 3358 */ 3359 function getFormFactor() 3360 { 3361 var form_factor_str = ""; 3362 3363 switch(true) 3364 { 3365 case (isTablet()): 3366 form_factor_str = "tablet"; 3367 break; 3368 3369 case (isTV()): 3370 form_factor_str = "tv"; 3371 break; 3372 3373 default: 3374 switch(true) 3375 { 3376 case (isPhone()): 3377 form_factor_str = "phone"; 3378 break; 3379 3380 default: 3381 form_factor_str = "pc"; 3382 } 3383 } 3384 3385 return form_factor_str; 3386 } 3387 3388 /** 3389 * Check if the Device is a Phone 3390 * @return {Boolean} 3391 */ 3392 function isPhone() 3393 { 3394 //check if phone check has already been done. If so, return stored value 3395 switch(true) 3396 { 3397 case (isStorageValueSet("rstv_is_phone")): 3398 return store("rstv_is_phone"); 3399 break; 3400 } 3401 3402 //Check if Device is a Tablet 3403 switch(true) 3404 { 3405 case (isTablet(true) || isTV()): 3406 //is not phone 3407 store("rstv_is_phone", false); 3408 return false; 3409 break; 3410 } 3411 3412 //Check if it is a phone 3413 switch(true) 3414 { 3415 case (_mobileDetect(getUserAgent() || navigator.vendor.toLowerCase() || window.opera)): 3416 store("rstv_is_phone", true); 3417 return true; 3418 break; 3419 } 3420 3421 store("rstv_is_phone", false); 3422 return false; 3423 } 3424 3425 /** 3426 * Check if the Device is a Tablet 3427 * @param bypass_storage_bool {Boolean} Prevent this method from caching its result in local storage 3428 * @return {Boolean} 3429 */ 3430 function isTablet() 3431 { 3432 var myArgs = Array.prototype.slice.call(arguments), 3433 bypass_storage_bool = isBool(myArgs[0]) ? myArgs[0] : false 3434 ; 3435 3436 //check if tablet check has already been done. If so, return stored value 3437 switch(true) 3438 { 3439 case (isStorageValueSet("rstv_is_tablet")): 3440 return store("rstv_is_tablet"); 3441 break; 3442 } 3443 3444 var regex_raw_str, 3445 regex, 3446 is_tablet_bool, 3447 nav = getUserAgent(); 3448 3449 //if iPad or Blackberry Playbook, return true 3450 regex = new RegExp("ipad|playbook|rim +tablet", "i"); 3451 is_tablet_bool = regex.test(nav); 3452 switch(true) 3453 { 3454 case (is_tablet_bool): 3455 if(!bypass_storage_bool){ store("rstv_is_tablet", true); } 3456 return true; 3457 break; 3458 } 3459 3460 //if Windows Surface, return true 3461 regex = new RegExp("windows +nt.+arm|windows +nt.+touch", "i"); 3462 is_tablet_bool = regex.test(nav); 3463 switch(true) 3464 { 3465 case (is_tablet_bool): 3466 if(!bypass_storage_bool){ store("rstv_is_tablet", true); } 3467 return true; 3468 break; 3469 } 3470 3471 /** 3472 * Check Other Known Tablets 3473 * 3474 * 1. Amazon Kindle: android.+kindle|kindle +fire|android.+silk|silk.*accelerated 3475 * 2. Google Nexus Tablet: android.+nexus +(7|10) 3476 * 3. Samsung Tablet: samsung.*tablet|galaxy.*tab|sc-01c|gt-p1000|gt-p1003|gt-p1010|gt-p3105|gt-p6210|gt-p6800|gt-p6810|gt-p7100|gt-p7300|gt-p7310|gt-p7500|gt-p7510|sch-i800|sch-i815|sch-i905|sgh-i957|sgh-i987|sgh-t849|sgh-t859|sgh-t869|sph-p100|gt-p3100|gt-p3108|gt-p3110|gt-p5100|gt-p5110|gt-p6200|gt-p7320|gt-p7511|gt-n8000|gt-p8510|sgh-i497|sph-p500|sgh-t779|sch-i705|sch-i915|gt-n8013|gt-p3113|gt-p5113|gt-p8110|gt-n8010|gt-n8005|gt-n8020|gt-p1013|gt-p6201|gt-p7501|gt-n5100|gt-n5110|shv-e140k|shv-e140l|shv-e140s|shv-e150s|shv-e230k|shv-e230l|shv-e230s|shw-m180k|shw-m180l|shw-m180s|shw-m180w|shw-m300w|shw-m305w|shw-m380k|shw-m380s|shw-m380w|shw-m430w|shw-m480k|shw-m480s|shw-m480w|shw-m485w|shw-m486w|shw-m500w|gt-i9228|sch-p739|sch-i925|gt-i9200|gt-i9205|gt-p5200|gt-p5210|sm-t311|sm-t310|sm-t210|sm-t210r|sm-t211|sm-p600|sm-p601|sm-p605|sm-p900|sm-t217|sm-t217a|sm-t217s|sm-p6000|sm-t3100|sgh-i467|xe500 3477 * 4. HTC Tablet: htc flyer|htc jetstream|htc-p715a|htc evo view 4g|pg41200 3478 * 5. Motorola Tablet: xoom|sholest|mz615|mz605|mz505|mz601|mz602|mz603|mz604|mz606|mz607|mz608|mz609|mz615|mz616|mz617 3479 * 6. Asus Tablet: transformer|^.*padfone((?!mobile).)*$|tf101|tf201|tf300|tf700|tf701|tf810|me171|me301t|me302c|me371mg|me370t|me372mg|me172v|me173x|me400c|slider *sl101 3480 * 7. Nook Tablet: android.+nook|nookcolor|nook browser|bnrv200|bnrv200a|bntv250|bntv250a|bntv400|bntv600|logicpd zoom2 3481 * 8. Acer Tablet: android.*\b(a100|a101|a110|a200|a210|a211|a500|a501|a510|a511|a700|a701|w500|w500p|w501|w501p|w510|w511|w700|g100|g100w|b1-a71|b1-710|b1-711|a1-810)\b|w3-810 3482 * 9. Toshiba Tablet: android.*(at100|at105|at200|at205|at270|at275|at300|at305|at1s5|at500|at570|at700|at830)|toshiba.*folio 3483 * 10. LG Tablet: \bl-06c|lg-v900|lg-v905|lg-v909 3484 * 11. Yarvik Tablet: android.+(xenta.+tab|tab210|tab211|tab224|tab250|tab260|tab264|tab310|tab360|tab364|tab410|tab411|tab420|tab424|tab450|tab460|tab461|tab464|tab465|tab467|tab468|tab469) 3485 * 12. Medion Tablet: android.+\boyo\b|life.*(p9212|p9514|p9516|s9512)|lifetab 3486 * 13. Arnova Tablet: an10g2|an7bg3|an7fg3|an8g3|an8cg3|an7g3|an9g3|an7dg3|an7dg3st|an7dg3childpad|an10bg3|an10bg3dt 3487 * 14. Archos Tablet: android.+archos|\b(101g9|80g9|a101it)\b|qilive 97r| 3488 * 15. Ainol Tablet: novo7|novo7aurora|novo7basic|novo7paladin|novo8|novo9|novo10 3489 * 16. Sony Tablet: sony tablet|sony tablet s|sgpt12|sgpt121|sgpt122|sgpt123|sgpt111|sgpt112|sgpt113|sgpt211|sgpt213|ebrd1101|ebrd1102|ebrd1201|sgpt311|sgpt312|sonyso-03e 3490 * 17. Cube Tablet: android.*(k8gt|u9gt|u10gt|u16gt|u17gt|u18gt|u19gt|u20gt|u23gt|u30gt)|cube u8gt 3491 * 18. Coby Tablet: mid1042|mid1045|mid1125|mid1126|mid7012|mid7014|mid7034|mid7035|mid7036|mid7042|mid7048|mid7127|mid8042|mid8048|mid8127|mid9042|mid9740|mid9742|mid7022|mid7010 3492 * 19. SMiTTablet: android.*(\bmid\b|mid-560|mtv-t1200|mtv-pnd531|mtv-p1101|mtv-pnd530) 3493 * 20. RockchipTablet: android.*(rk2818|rk2808a|rk2918|rk3066)|rk2738|rk2808a 3494 * 21. TelstraTablet: t-hub2 3495 * 22. FlyTablet: iq310|fly vision 3496 * 23. bqTablet: bq.*(elcano|curie|edison|maxwell|kepler|pascal|tesla|hypatia|platon|newton|livingstone|cervantes|avant)
3497 * 24. HuaweiTablet: mediapad|ideos s7|s7-201c|s7-202u|s7-101|s7-103|s7-104|s7-105|s7-106|s7-201|s7-slim 3498 * 25. NecTablet: \bn-06d|\bn-08d 3499 * 26. Pantech: pantech.*p4100 3500 * 27. BronchoTablet: broncho.*(n701|n708|n802|a710) 3501 * 28. VersusTablet: touchpad.*[78910]|\btouchtab\b 3502 * 29. Zynctablet: z1000|z99 2g|z99|z930|z999|z990|z909|z919|z900 3503 * 30. Positivo: tb07sta|tb10sta|tb07fta|tb10fta 3504 * 31. NabiTablet: android.*\bnabi 3505 * 32. Playstation: playstation.*(portable|vita) 3506 * 33. Dell: dell.*streak 3507 * 34. Milagrow: milagrow +tab.*top 3508 * 35. Lenovo: android.+(ideapad|ideatab|lenovo +a1|s2110|s6000|k3011|a3000|a1000|a2107|a2109|a1107) 3509 * 37. UPad: android.+f8-sup 3510 * 38. Kobo: android.+(k080|arc|vox) 3511 * 39. MSI: android.*(msi.+enjoy|enjoy +7|enjoy +10) 3512 * 40. Agasio: dropad.+a8 3513 * 41. Acho: android.+c906 3514 * 42. Iberry: android.+iberry.+auxus 3515 * 43. Aigo: android.+aigopad 3516 * 44. Airpad: android.*(airpad|liquid metal) 3517 * 45. HCL: android.+hcl.+tablet|connect-3g-2.0|connect-2g-2.0|me tablet u1|me tablet u2|me tablet g1|me tablet x1|me tablet y2|me tablet sync 3518 * 46. Karbonn: android.*(a39|a37|a34|st8|st10|st7|smarttab|smart +tab) 3519 * 47. Micromax: android.*(micromax.+funbook|funbook|p250|p275|p300|p350|p362|p500|p600)|micromax.*(p250|p275|p350|p362|p500|p600)|funbook 3520 * 48. Penta: android.+penta 3521 * 49. Celkon: android.*(celkon.+ct|ct-[0-9]) 3522 * 50. Intex: android.+i-buddy 3523 * 51. Viewsonic: android.*(viewbook|viewpad) 3524 * 52: ZTE: android.*(v9|zte.+v8110|light tab|light pro|beeline|base.*tab) 3525 * 53. Pegatron: chagall 3526 * 54. Advan: android.*(vandroid|t3i) 3527 * 55. Creative: android.*(ziio7|ziio10) 3528 * 56. OlivePad: android.*(v-t100|v-tw100|v-tr200|v-t300) 3529 * 57. Vizio: android.+vtab1008 3530 * 58. Bookeen: bookeen|cybook 3531 * 59. Medion: android.*lifetab_(s9512|p9514|p9516) 3532 * 60. IRU Tablet: m702pro 3533 * 61. IRULU: irulu-al101 3534 * 62. Prestigio: pmp3170b|pmp3270b|pmp3470b|pmp7170b|pmp3370b|pmp3570c|pmp5870c|pmp3670b|pmp5570c|pmp5770d|pmp3970b|pmp3870c|pmp5580c|pmp5880d|pmp5780d|pmp5588c|pmp7280c|pmp7280|pmp7880d|pmp5597d|pmp5597|pmp7100d|per3464|per3274|per3574|per3884|per5274|per5474|pmp5097cpro|pmp5097|pmp7380d|pmp5297c|pmp5297c_quad 3535 * 63. AllView: allview.*(viva|alldro|city|speed|all tv|frenzy|quasar|shine|tx1|ax1|ax2) 3536 * 64: Megafon: megafon v9 3537 * 65: Lava: android.+(z7c|z7h|z7s) 3538 * 66: iBall: android.+iball.+slide.+(3g *7271|3g *7334|3g *7307|3g *7316|i7119|i7011)|android.+iball.+i6012 3539 * 67. Tabulet: android.+(tabulet|troy +duos) 3540 * 68. Texet Tablet: navipad|tb-772a|tm-7045|tm-7055|tm-9750|tm-7016|tm-7024|tm-7026|tm-7041|tm-7043|tm-7047|tm-8041|tm-9741|tm-9747|tm-9748|tm-9751|tm-7022|tm-7021|tm-7020|tm-7011|tm-7010|tm-7023|tm-7025|tm-7037w|tm-7038w|tm-7027w|tm-9720|tm-9725|tm-9737w|tm-1020|tm-9738w|tm-9740|tm-9743w|tb-807a|tb-771a|tb-727a|tb-725a|tb-719a|tb-823a|tb-805a|tb-723a|tb-715a|tb-707a|tb-705a|tb-709a|tb-711a|tb-890hd|tb-880hd|tb-790hd|tb-780hd|tb-770hd|tb-721hd|tb-710hd|tb-434hd|tb-860hd|tb-840hd|tb-760hd|tb-750hd|tb-740hd|tb-730hd|tb-722hd|tb-720hd|tb-700hd|tb-500hd|tb-470hd|tb-431hd|tb-430hd|tb-506|tb-504|tb-446|tb-436|tb-416|tb-146se|tb-126se 3541 * 69. GalapadTablet: android.*\bg1\b 3542 * 70. GUTablet: tx-a1301|tx-m9002|q702 3543 * 71. GT-Pad: ly-f528 3544 * 72. Danew: android.+dslide.*\b(700|701r|702|703r|704|802|970|971|972|973|974|1010|1012)\b 3545 * 73. MIDTablet: m9701|m9000|m9100|m806|m1052|m806|t703|mid701|mid713|mid710|mid727|mid760|mid830|mid728|mid933|mid125|mid810|mid732|mid120|mid930|mid800|mid731|mid900|mid100|mid820|mid735|mid980|mid130|mid833|mid737|mid960|mid135|mid860|mid736|mid140|mid930|mid835|mid733 3546 * 74. Fujitsu: android.*\b(f-01d|f-05e|f-10d|m532|q572)\b 3547 * 75. GPad: android.+casiatab8 3548 * 76. Tesco Hudl: android.+hudl 3549 * 77. Polaroid: android.*(polaroid.*tablet|pmid1000|pmid10c|pmid800|pmid700|pmid4311|pmid701c|pmid701i|pmid705|pmid706|pmi
3549d70dc|pmid70c|pmid720|pmid80c|pmid901|ptab7200|ptab4300|ptab750|midc010|midc407|midc409|midc410|midc497|midc700|midc800|midc801|midc802|midc901) 3550 * 78. Eboda: e-boda.+(supreme|impresspeed|izzycomm|essential) 3551 * 79. HP Tablet: hp slate 7|hp elitepad 900|hp-tablet|elitebook.*touch 3552 * 80. AllFineTablet: fine7 genius|fine7 shine|fine7 air|fine8 style|fine9 more|fine10 joy|fine11 wide 3553 * 81. Sanei: android.*\b(n10|n10-4core|n78|n79|n83|n90 ii)\b 3554 * 82: ProScan Tablet: \b(pem63|plt1023g|plt1041|plt1044|plt1044g|plt1091|plt4311|plt4311pl|plt4315|plt7030|plt7033|plt7033d|plt7035|plt7035d|plt7044k|plt7045k|plt7045kb|plt7071kg|plt7072|plt7223g|plt7225g|plt7777g|plt7810k|plt7849g|plt7851g|plt7852g|plt8015|plt8031|plt8034|plt8036|plt8080k|plt8082|plt8088|plt8223g|plt8234g|plt8235g|plt8816k|plt9011|plt9045k|plt9233g|plt9735|plt9760g|plt9770g)\b 3555 * 83: YonesTablet : bq1078|bc1003|bc1077|rk9702|bc9730|bc9001|it9001|bc7008|bc7010|bc708|bc728|bc7012|bc7030|bc7027|bc7026 3556 * 84: ChangJiaTablet: tpc7102|tpc7103|tpc7105|tpc7106|tpc7107|tpc7201|tpc7203|tpc7205|tpc7210|tpc7708|tpc7709|tpc7712|tpc7110|tpc8101|tpc8103|tpc8105|tpc8106|tpc8203|tpc8205|tpc8503|tpc9106|tpc9701|tpc97101|tpc97103|tpc97105|tpc97106|tpc97111|tpc97113|tpc97203|tpc97603|tpc97809|tpc97205|tpc10101|tpc10103|tpc10106|tpc10111|tpc10203|tpc10205|tpc10503 3557 * 85: RoverPad: android.*(roverpad|rp3wg70) 3558 * 86. PointofView Tablet: tab-p506|tab-navi-7-3g-m|tab-p517|tab-p-527|tab-p701|tab-p703|tab-p721|tab-p731n|tab-p741|tab-p825|tab-p905|tab-p925|tab-pr945|tab-pl1015|tab-p1025|tab-pi1045|tab-p1325|tab-protab[0-9]+|tab-protab25|tab-protab26|tab-protab27|tab-protab26xl|tab-protab2-ips9|tab-protab30-ips9|tab-protab25xxl|tab-protab26-ips10|tab-protab30-ips10 3559 * 87: Overmax: android.*ov-(steelcore|newbase|basecore|baseone|exellen|quattor|edutab|solution|action|basictab|teddytab|magictab|stream|tb-08|tb-09) 3560 * 88: DPS Tablet: dps dream 9|dps dual 7 3561 * 89: Visture Tablet: v97 hd|i75 3g|visture v4( hd)?|visture v5( hd)?|visture v10 3562 * 90: Cresta Tablet: ctp(-)?810|ctp(-)?818|ctp(-)?828|ctp(-)?838|ctp(-)?888|ctp(-)?978|ctp(-)?980|ctp(-)?987|ctp(-)?988|ctp(-)?989 3563 * 200. Generic Tablet: android.*\b97d\b|tablet(?!.*pc)|viewpad7|lg-v909|mid7015|bntv250a|logicpd zoom2|\ba7eb\b|catnova8|a1_07|ct704|ct1002|\bm721\b|rk30sdk|\bevotab\b|smarttabii10|smarttab10 3564 */ 3565 regex_raw_str = ""+ 3566 "android.+kindle|kindle +fire|android.+silk|silk.*accelerated|"+ 3567 "android.+nexus +(7|10)|"+ 3568 "samsung.*tablet|galaxy.*tab|sc-01c|gt-p1000|gt-p1003|gt-p1010|gt-p3105|gt-p6210|gt-p6800|gt-p6810|gt-p7100|gt-p7300|gt-p7310|gt-p7500|gt-p7510|sch-i800|sch-i815|sch-i905|sgh-i957|sgh-i987|sgh-t849|sgh-t859|sgh-t869|sph-p100|gt-p3100|gt-p3108|gt-p3110|gt-p5100|gt-p5110|gt-p6200|gt-p7320|gt-p7511|gt-n8000|gt-p8510|sgh-i497|sph-p500|sgh-t779|sch-i705|sch-i915|gt-n8013|gt-p3113|gt-p5113|gt-p8110|gt-n8010|gt-n8005|gt-n8020|gt-p1013|gt-p6201|gt-p7501|gt-n5100|gt-n5110|shv-e140k|shv-e140l|shv-e140s|shv-e150s|shv-e230k|shv-e230l|shv-e230s|shw-m180k|shw-m180l|shw-m180s|shw-m180w|shw-m300w|shw-m305w|shw-m380k|shw-m380s|shw-m380w|shw-m430w|shw-m480k|shw-m480s|shw-m480w|shw-m485w|shw-m486w|shw-m500w|gt-i9228|sch-p739|sch-i925|gt-i9200|gt-i9205|gt-p5200|gt-p5210|sm-t311|sm-t310|sm-t210|sm-t210r|sm-t211|sm-p600|sm-p601|sm-p605|sm-p900|sm-t217|sm-t217a|sm-t217s|sm-p6000|sm-t3100|sgh-i467|xe500|"+ 3569 "htc flyer|htc jetstream|htc-p715a|htc evo view 4g|pg41200|"+ 3570 "xoom|sholest|mz615|mz605|mz505|mz601|mz602|mz603|mz604|mz606|mz607|mz608|mz609|mz615|mz616|mz617|"+ 3571 "transformer|^.*padfone((?!mobile).)*$|tf101|tf201|tf300|tf700|tf701|tf810|me171|me301t|me302c|me371mg|me370t|me372mg|me172v|me173x|me400c|slider *sl101|"+ 3572 "android.+nook|nookcolor|nook browser|bnrv200|bnrv200a|bntv250|bntv250a|bntv400|bntv600|logicpd zoom2|"+ 3573 "android.*\\b(a100|a101|a110|a200|a210|a211|a500|a501|a510|a511|a700|a701|w500|w500p|w501|w501p|w510|w511|w700|g100|g100w|b1-a71|b1-710|b1-711|a1-810)\\b|w3-810|"+ 3574 "android.*(at100|at105|at200|at205|at270|at275|at300|at305|at1s5|at500|at570|at700|at830)|toshiba.*folio|"+ 3575 "\\bl-06c|lg-v900|lg-v905|lg-v909|"+ 3576 "android.+(xenta.+tab|tab210|tab211|tab224|tab250|tab260|tab264|tab310|tab360|tab364|tab410|tab411|tab420|tab424|tab450|tab460|tab461|tab464|tab465|tab467|tab468|tab469)|"+ 3577 "android.+\\boyo\\b|life.*(p9212|p9514|p9516|s9512)|lifetab|"+ 3578 "an10g2|an7bg3|an7fg3|an8g3|an8cg3|an7g3|an9g3|an7dg3|an7dg3st|an7dg3childpad|an10bg3|an10bg3dt|"+ 3579 "android.+archos|\\b(101g9|80g9|a101it)\\b|qilive 97r|"+ 3580 "novo7|novo7aurora|novo7basic|novo7paladin|novo8|novo9|novo10|"+ 3581 "sony tablet|sony tablet s|sgpt12|sgpt121|sgpt122|sgpt123|sgpt111|sgpt112|sgpt113|sgpt211|sgpt213|ebrd1101|ebrd1102|ebrd1201|sgpt311|sgpt312|sonyso-03e|"+ 3582 "android.*(k8gt|u9gt|u10gt|u16gt|u17gt|u18gt|u19gt|u20gt|u23gt|u30gt)|cube u8gt|"+ 3583 "mid1042|mid1045|mid1125|mid1126|mid7012|mid7014|mid7034|mid7035|mid7036|mid7042|mid7048|mid7127|mid8042|mid8048|mid8127|mid9042|mid9740|mid9742|mid7022|mid7010|"+ 3584 "android.*(\\bmid\\b|mid-560|mtv-t1200|mtv-pnd531|mtv-p1101|mtv-pnd530)|"+ 3585 "android.*(rk2818|rk2808a|rk2918|rk3066)|rk2738|rk2808a|"+ 3586 "t-hub2|"+ 3587 "iq310|fly vision|"+ 3588 "bq.*(elcano|curie|edison|maxwell|kepler|pascal|tesla|hypatia|platon|newton|livingstone|cervantes|avant)|"+
3589 "mediapad|ideos s7|s7-201c|s7-202u|s7-101|s7-103|s7-104|s7-105|s7-106|s7-201|s7-slim|"+ 3590 "\\bn-06d|\\bn-08d|"+ 3591 "pantech.*p4100|"+ 3592 "broncho.*(n701|n708|n802|a710)|"+ 3593 "touchpad.*[78910]|\\btouchtab\\b|"+ 3594 "z1000|z99 2g|z99|z930|z999|z990|z909|z919|z900|"+ 3595 "tb07sta|tb10sta|tb07fta|tb10fta|"+ 3596 "android.*\\bnabi|"+ 3597 "playstation.*(portable|vita)|"+ 3598 "dell.*streak|"+ 3599 "milagrow +tab.*top|"+ 3600 "android.+(ideapad|ideatab|lenovo +a1|s2110|s6000|k3011|a3000|a1000|a2107|a2109|a1107)|"+ 3601 "android.+f8-sup|"+ 3602 "android.*(k080|arc|vox)|"+ 3603 "android.*(msi.+enjoy|enjoy +7|enjoy +10)|"+ 3604 "dropad.+a8|"+ 3605 "android.+c906|"+ 3606 "android.+iberry.+auxus|"+ 3607 "android.+aigopad|"+ 3608 "android.*(airpad|liquid metal)|"+ 3609 "android.+hcl.+tablet|connect-3g-2.0|connect-2g-2.0|me tablet u1|me tablet u2|me tablet g1|me tablet x1|me tablet y2|me tablet sync|"+ 3610 "android.*(a39|a37|a34|st8|st10|st7|smarttab|smart +tab)|"+ 3611 "android.*(micromax.+funbook|funbook|p250|p275|p300|p350|p362|p500|p600)|micromax.*(p250|p275|p350|p362|p500|p600)|funbook|"+ 3612 "android.+penta|"+ 3613 "android.*(celkon.+ct|ct-[0-9])|"+ 3614 "android.+i-buddy|"+ 3615 "android.*(viewbook|viewpad)|"+ 3616 "android.*(v9|zte.+v8110|light tab|light pro|beeline|base.*tab)|"+ 3617 "chagall|"+ 3618 "android.*(vandroid|t3i)|"+ 3619 "android.*(ziio7|ziio10)|"+ 3620 "android.*(v-t100|v-tw100|v-tr200|v-t300)|"+ 3621 "android.+vtab1008|"+ 3622 "bookeen|cybook|"+ 3623 "android.*lifetab_(s9512|p9514|p9516)|"+ 3624 "m702pro|"+ 3625 "irulu-al101|"+ 3626 "pmp3170b|pmp3270b|pmp3470b|pmp7170b|pmp3370b|pmp3570c|pmp5870c|pmp3670b|pmp5570c|pmp5770d|pmp3970b|pmp3870c|pmp5580c|pmp5880d|pmp5780d|pmp5588c|pmp7280c|pmp7280|pmp7880d|pmp5597d|pmp5597|pmp7100d|per3464|per3274|per3574|per3884|per5274|per5474|pmp5097cpro|pmp5097|pmp7380d|pmp5297c|pmp5297c_quad|"+ 3627 "allview.*(viva|alldro|city|speed|all tv|frenzy|quasar|shine|tx1|ax1|ax2)|"+ 3628 "megafon +v9|"+ 3629 "android.+(z7c|z7h|z7s)|"+ 3630 "android.+iball.+slide.+(3g *7271|3g *7334|3g *7307|3g *7316|i7119|i7011)|android.+iball.+i6012|"+ 3631 "navipad|tb-772a|tm-7045|tm-7055|tm-9750|tm-7016|tm-7024|tm-7026|tm-7041|tm-7043|tm-7047|tm-8041|tm-9741|tm-9747|tm-9748|tm-9751|tm-7022|tm-7021|tm-7020|tm-7011|tm-7010|tm-7023|tm-7025|tm-7037w|tm-7038w|tm-7027w|tm-9720|tm-9725|tm-9737w|tm-1020|tm-9738w|tm-9740|tm-9743w|tb-807a|tb-771a|tb-727a|tb-725a|tb-719a|tb-823a|tb-805a|tb-723a|tb-715a|tb-707a|tb-705a|tb-709a|tb-711a|tb-890hd|tb-880hd|tb-790hd|tb-780hd|tb-770hd|tb-721hd|tb-710hd|tb-434hd|tb-860hd|tb-840hd|tb-760hd|tb-750hd|tb-740hd|tb-730hd|tb-722hd|tb-720hd|tb-700hd|tb-500hd|tb-470hd|tb-431hd|tb-430hd|tb-506|tb-504|tb-446|tb-436|tb-416|tb-146se|tb-126se|"+ 3632 "android.*\\bg1\\b|"+ 3633 "tx-a1301|tx-m9002|q702|"+ 3634 "ly-f528|"+ 3635 "android.+dslide.*\\b(700|701r|702|703r|704|802|970|971|972|973|974|1010|1012)\\b|"+ 3636 "m9701|m9000|m9100|m806|m1052|m806|t703|mid701|mid713|mid710|mid727|mid760|mid830|mid728|mid933|mid125|mid810|mid732|mid120|mid930|mid800|mid731|mid900|mid100|mid820|mid735|mid980|mid130|mid833|mid737|mid960|mid135|mid860|mid736|mid140|mid930|mid835|mid733|"+ 3637 "android.*\\b(f-01d|f-05e|f-10d|m532|q572)\\b|"+ 3638 "android.+casiatab8|"+ 3639 "android.+hudl|"+ 3640 "android.*(polaroid.*tablet|pmid1000|pmid10c|pmid800|pmid700|pmid4311|pmid701c|pmid701i|pmid705|pmid706|pmid70dc|pmid70c|pmid720|pmid80c|pmid901|ptab7200|ptab4300|ptab750|midc010|midc407|midc409|midc410|midc497|midc700|midc800|midc801|midc802|midc901)|"+ 3641 "e-boda.+(supreme|impresspeed|izzycomm|essential)|"+ 3642 "hp slate 7|hp elitepad 900|hp-tablet|elitebook.*touch|"+ 3643 "fine7 genius|fine7 shine|fine7 air|fine8 style|fine9 more|fine10 joy|fine11 wide|"+ 3644 "android.*\\b(n10|n10-4core|n78|n79|n83|n90 ii)\\b|"+ 3645 "\\b(pem63|plt1023g|plt1041|plt1044|plt1044g|plt1091|plt4311|plt4311pl|plt4315|plt7030|plt7033|plt7033d|plt7035|plt7035d|plt7044k|plt7045k|plt7045kb|plt7071kg|plt7072|plt7223g|plt7225g|plt7777g|plt7810k|plt7849g|plt7851g|plt7852g|plt8015|plt8031|plt8034|plt8036|plt8080k|plt8082|plt8088|plt8223g|plt8234g|plt8235g|plt8816k|plt9011|plt9045k|plt9233g|plt9735|plt9760g|plt9770g)\\b|"+ 3646 "bq1078|bc1003|bc1077|rk9702|bc9730|bc9001|it9001|bc7008|bc7010|bc708|bc728|bc7012|bc7030|bc7027|bc7026|"+ 3647 "tpc7102|tpc7103|tpc7105|tpc7106|tpc7107|tpc7201|tpc7203|tpc7205|tpc7210|tpc7708|tpc7709|tpc7712|tpc7110|tpc8101|tpc8103|tpc8105|tpc8106|tpc8203|tpc8205|tpc8503|tpc9106|tpc9701|tpc97101|tpc97103|tpc97105|tpc97106|tpc97111|tpc97113|tpc97203|tpc97603|tpc97809|tpc97205|tpc10101|tpc10103|tpc10106|tpc10111|tpc10203|tpc10205|tpc10503|"+ 3648 "android.*(roverpad|rp3wg70)|"+ 3649 "tab-p506|tab-navi-7-3g-m|tab-p517|tab-p-527|tab-p701|tab-p703|tab-p721|tab-p731n|tab-p741|tab-p825|tab-p905|tab-p925|tab-pr945|tab-pl1015|tab-p1025|tab-pi1045|tab-p1325|tab-protab[0-9]+|tab-protab25|tab-protab26|tab-protab27|tab-protab26xl|tab-protab2-ips9|tab-protab30-ips9|tab-protab25xxl|tab-protab26-ips10|tab-protab30-ips10|"+ 3650 "android.*ov-(steelcore|newbase|basecore|baseone|exellen|quattor|edutab|solution|action|basictab|teddytab|magictab|stream|tb-08|tb-09)|"+ 3651 "dps dream 9|dps dual 7|"+ 3652 "v97 hd|i75 3g|visture v4( hd)?|visture v5( hd)?|visture v10|"+ 3653 "ctp(-)?810|ctp(-)?818|ctp(-)?828|ctp(-)?838|ctp(-)?888|ctp(-)?978|ctp(-)?980|ctp(-)?987|ctp(-)?988|ctp(-)?989|"+ 3654 "android.*\\b97d\\b|tablet(?!.*pc)|viewpad7|lg-v909|mid7015|bntv250a|logicpd zoom2|\\ba7eb\\b|catnova8|a1_07|ct704|ct1002|\\bm721\\b|rk30sdk|\\bevotab\\b|smarttabii10|smarttab10"+ 3655 ""; 3656 3657 //Check Main Tablet 3658 regex = new RegExp(regex_raw_str, "i"); 3659 is_tablet_bool = regex.test(nav); 3660 switch(true) 3661 { 3662 case (is_tablet_bool): 3663 if(!bypass_storage_bool){ store("rstv_is_tablet", true); } 3664 return true; 3665 break; 3666 } 3667 3668 //Check Android Tablet 3669 var regex_1_bool = /android/i.test(nav), 3670 regex_2_bool = !/mobile/i.test(nav), 3671 pixel_w_int = parseInt(store("rstv_viewportW_dip")), 3672 pixel_h_int = parseInt(store("rstv_viewportH_dip")), 3673 pixel_dim_int = (store("rstv_is_portrait")) ? pixel_w_int : pixel_h_int 3674 ; 3675 3676 switch(true) 3677 { 3678 case (regex_1_bool): 3679 /** 3680 * if tablet has either: 3681 * 1. Device independent viewport width between 520px and 800px when in portrait 3682 * 2. Device independent viewport height between 520px and 800px when in landscape 3683 */ 3684 switch(true) 3685 { 3686 case (isNumber(pixel_dim_int) && (pixel_dim_int >= 520 && pixel_dim_int <= 800)): 3687 if(!bypass_storage_bool){ store("rstv_is_tablet", true); } 3688 return true; 3689 break; 3690 } 3691 3692 //if user agent is Android but 'mobile' keyword is absent 3693 switch(true) 3694 { 3695 case (regex_2_bool): 3696 if(!bypass_storage_bool){ store("rstv_is_tablet", true); } 3697 return true; 3698 break; 3699 } 3700 3701 break; 3702 } 3703 3704 //Return false if otherwise 3705 if(!bypass_storage_bool){ store("rstv_is_tablet", false); } 3706 return false;
3707 } 3708 3709 /** 3710 * Check if the device is a TV 3711 * @return {Boolean} 3712 */ 3713 function isTV() 3714 { 3715 //check if TV check has already been done. If so, return stored value 3716 switch(true) 3717 { 3718 case (isStorageValueSet("rstv_is_tv")): 3719 return store("rstv_is_tv"); 3720 break; 3721 } 3722 3723 //get the user agent 3724 var nav = getUserAgent(); 3725 3726 /** 3727 * Check for known TVs 3728 */ 3729 var is_tv_bool = /googletv|smart\-tv|smarttv|internet +tv|netcast|nettv|appletv|boxee|kylo|roku|vizio|dlnadoc|ce\-html|ouya|xbox|playstation *(3|4)|wii/i.test(nav); 3730 3731 switch(true) 3732 { 3733 case (is_tv_bool): 3734 store("rstv_is_tv", true); 3735 return true; 3736 break; 3737 } 3738 3739 store("rstv_is_tv", false); 3740 return false; 3741 } 3742 3743 /** 3744 * Checks if the device is a Personal Computer 3745 * @return {Boolean} 3746 */ 3747 function isPC() 3748 { 3749 //check if PC check has already been done. If so, return stored value 3750 switch(true) 3751 { 3752 case (isStorageValueSet("rstv_is_pc")): 3753 return store("rstv_is_pc"); 3754 break; 3755 } 3756 3757 switch(true) 3758 { 3759 case (isMobile() === false && isTV() === false): 3760 store("rstv_is_pc", true); 3761 return true; 3762 break; 3763 } 3764 3765 store("rstv_is_pc", false); 3766 return false; 3767 } 3768 3769 /** 3770 * Checks if the device is a mobile device 3771 * @return {Boolean} 3772 */ 3773 function isMobile() 3774 { 3775 //check if device is phone or tablet 3776 switch(true) 3777 { 3778 case (isPhone() || isTablet(true)): 3779 return true; 3780 break; 3781 3782 default: 3783 return false; 3784 } 3785 } 3786 3787 /** 3788 * Checks if the device is a non-mobile device 3789 * @return {Boolean} 3790 */ 3791 function isNonMobile() 3792 { 3793 //check if device is not phone or mobile 3794 switch(true) 3795 { 3796 case (!isMobile()): 3797 return true; 3798 break; 3799 3800 default: 3801 return false; 3802 } 3803 } 3804 3805 /** 3806 * Gets the orientation of the device 3807 * @param bypass_cache_bool {Boolean} Determines if the stored value for current orientation should be retrieved or not. True will ignore the value stored and will re-test the orientation 3808 * @return {String} 3809 */ 3810 function getOrientation() 3811 { 3812 var myArgs = Array.prototype.slice.call(arguments), 3813 bypass_cache_bool = isBool(myArgs[0]) ? myArgs[0] : false, 3814 ort_final_str; 3815 3816 //check if current orientation value is stored and bypass_cache_bool is false. If so, return stored value 3817 switch(true) 3818 { 3819 case (isStorageValueSet("rstv_ort_curr") && !bypass_cache_bool): 3820 return store("rstv_ort_curr"); 3821 break; 3822 } 3823 3824 //Reset Viewport Dimensions if bypass_cache_bool is true 3825 switch(true) 3826 { 3827 case (bypass_cache_bool): 3828 store("rstv_viewportW rstv_viewportW_dip rstv_viewportH rstv_viewportH_dip rstv_screenW rstv_screenH", null); 3829 break; 3830 } 3831 3832 //Get the Viewport Dimensions 3833 var device_user_agent_str = getUserAgent(), 3834 is_opera_mini_bool = /opera.+(mini|mobi)/i.test(device_user_agent_str), 3835 viewport_w_int = viewportW(), 3836 viewport_h_int = viewportH(), 3837 screen_w_int = screenW(), 3838 screen_h_int = screenH(), 3839 screen_w_to_h_ratio_int = screen_w_int/screen_h_int, 3840 screen_w_to_viewport_w_diff_int = screen_w_int - viewport_w_int, 3841 is_landscape_extended_verify_bool, 3842 is_landscape_bool; 3843 3844 screen_w_to_viewport_w_diff_int = Math.abs(screen_w_to_viewport_w_diff_int); 3845 is_landscape_extended_verify_bool = (is_opera_mini_bool && viewport_w_int < 260) ? ((screen_w_to_viewport_w_diff_int <= 4) && (screen_w_to_h_ratio_int >= 1) ? true : false) : true; 3846 is_landscape_bool = !!((viewport_h_int <= viewport_w_int) && is_landscape_extended_verify_bool); 3847 3848 switch(true) 3849 { 3850 case (is_landscape_bool): 3851 //landscape 3852 ort_final_str = 'landscape'; 3853 3854 //do not alter cached orientation variables if bypass_cache_bool is true 3855 switch(true) 3856 { 3857 case (!bypass_cache_bool): 3858 store("rstv_is_portrait", false); 3859 store("rstv_is_landscape", true); 3860 break; 3861 } 3862 3863 break; 3864 3865 default: 3866 //portrait 3867 ort_final_str = 'portrait'; 3868 3869 //do not alter cached orientation variables if bypass_cache_bool is true 3870 switch(true) 3871 { 3872 case (!bypass_cache_bool): 3873 store("rstv_is_portrait", true); 3874 store("rstv_is_landscape", false); 3875 break; 3876 } 3877 } 3878 3879 return ort_final_str; 3880 } 3881 3882 /** 3883 * Resets/Updates the cached values (localStorage) of Orientation Info 3884 * @private 3885 */ 3886 function _updateOrientationStore() 3887 { 3888 //reset 3889 store("rstv_ort_curr rstv_is_portrait rstv_is_landscape", null); 3890 3891 //reload 3892 store("rstv_ort_curr", getOrientation()); 3893 } 3894 3895 /** 3896 * Checks if the device is currently in Portrait mode 3897 * @return {Boolean} 3898 */ 3899 function isPortrait() 3900 { 3901 //check if portrait orientation value is stored. If so, return stored value 3902 switch(true) 3903 { 3904 case (isStorageValueSet("rstv_is_portrait")): 3905 return store("rstv_is_portrait"); 3906 break; 3907 } 3908 return !!((getOrientation() == 'portrait')); 3909 } 3910 3911 /** 3912 * Checks if the device is currently in Landscape mode 3913 * @return {Boolean} 3914 */ 3915 function isLandscape() 3916 { 3917 //check if landscape orientation value is stored. If so, return stored value 3918 switch(true) 3919 { 3920 case (isStorageValueSet("rstv_is_landscape")): 3921 return store("rstv_is_landscape"); 3922 break; 3923 } 3924 return !!((getOrientation() == 'landscape')); 3925 } 3926 3927 /**
3928 * Gets the Standard Display Resolution of the given device 3929 * @return {String} 3930 */ 3931 function getResolution() 3932 { 3933 var is_landscape_bool = isLandscape(), 3934 screen_w = screenW(), 3935 screen_h = screenH(), 3936 std_w_arr = (is_landscape_bool) ? _getResolutionDimensionList('h') :_getResolutionDimensionList('w'), 3937 std_h_arr = (is_landscape_bool) ? _getResolutionDimensionList('w'): _getResolutionDimensionList('h'), 3938 screen_w_std = getClosestNumberMatchArray(std_w_arr, screen_w), 3939 screen_h_std = getClosestNumberMatchArray(std_h_arr, screen_h), 3940 screen_res_str, 3941 screen_res_matrix_arr = _getResolutionMatrix(), 3942 screen_res_name_str 3943 ; 3944 3945 switch(true) 3946 { 3947 case (screen_w_std >= screen_h_std): 3948 screen_res_str = screen_h_std+'_'+screen_w_std; 3949 break; 3950 3951 default: 3952 screen_res_str = screen_w_std+'_'+screen_h_std; 3953 } 3954 3955 screen_res_name_str = array_search(screen_res_str, screen_res_matrix_arr); 3956 3957 return screen_res_name_str; 3958 } 3959 3960 /** 3961 * Composes and Saves a List of Standard Graphic Resolutions 3962 * @return {Array} 3963 * @private 3964 */ 3965 function _getResolutionList() 3966 { 3967 //Check if Resolution List is Stored 3968 switch(true) 3969 { 3970 case (isStorageValueSet("rstv_is_cache_res_list")): 3971 return store("rstv_cache_res_list"); 3972 break; 3973 } 3974 3975 var $res_arr = [ 3976 'qqvga', 'qqvgax1', 'hqvga', 'hqvgax1', 'hqvgax2', 'hvgax1', 'qvga', 'wqvga', 'wqvga1', 'hvga', 3977 'hvga1', 'hvga2', 'hvga3', 'hvgax1', 'hvgax2', 'vga', 'wvga', 'wvgax1', 'fwvga', 'svga', 3978 'dvga', 'dvgax1', 'wsvga', 'wsvga1', 'xga', 'wxga', 'wxga1', 'wxga2', 'wxga3', 'wxga4', 'wxga5', 3979 'xga+', 'wxga+', 'sxga', 'sxga+', 'wsxga+', 'uxga', 'wuxga', 'qwxga', 'qxga', 'wqxga', 3980 'qsxga', 'wqsxga', 'quxga', 'wquxga', 'hxga', 'whxga', 'hsxga', 'whsxga', 'huxga', 'whuxga', 3981 'nhd', 'nhdx1', 'qhd', 'hd', '720p', 'fhd', '1080p', '1080i', 'wqhd', 'mbprhd', '4kuhd', '8kuhd' 3982 ]; 3983 3984 store("rstv_is_cache_res_list", true); 3985 store("rstv_cache_res_list", $res_arr); 3986 return $res_arr; 3987 } 3988 3989 /** 3990 * Composes and Saves a Resolution Matrix (Resolution to Dimensions) 3991 * @return {Array|Object} 3992 * @private 3993 */ 3994 function _getResolutionMatrix() 3995 { 3996 //Check if Resolution Matrix is Stored 3997 switch(true) 3998 { 3999 case (isStorageValueSet("rstv_is_cache_res_matrix")): 4000 return store("rstv_cache_res_matrix"); 4001 break; 4002 } 4003 4004 var $res_matrix_arr = { 4005 'qqvga': '120_160', 'qqvgax1': '128_160', 'hqvga': '160_240', 'hqvgax1': '240_240', 'hqvgax2': '240_260', 4006 'qvga': '240_320', 'wqvga': '240_400', 'wqvga1': '240_432', 'hvga': '320_480', 4007 'hvga1': '360_480', 'hvga2': '272_480', 'hvga3': '240_640', 'hvgax1': '200_640', 'hvgax2': '300_640', 4008 'hvgax3': '360_400', 4009 'vga': '480_640', 'wvga': '480_800', 'wvgax1': '352_800', 'fwvga': '480_854', 'svga': '600_800', 4010 'dvga': '640_960', 'dvgax1': '640_1136', 'wsvga': '576_1024', 'wsvga1': '600_1024', 'xga': '768_1024', 4011 'wxga': '768_1280', 'wxga1': '720_1280', 'wxga2': '800_1280', 'wxga3': '768_1360', 'wxga4': '768_1366', 4012 'wxga5': '720_720', 4013 'xga+': '864_1152', 'wxga+': '900_1440', 'sxga': '1024_1280', 'sxga+': '1050_1400', 'wsxga+': '1050_1680', 4014 'uxga': '1200_1600', 'wuxga': '1200_1920', 'qwxga': '1152_2048', 'qxga': '1536_2048', 'wqxga': '1600_2560', 4015 'wqxga+': '1800_3200', 4016 'qsxga': '2048_2560', 'wqsxga': '2048_3200', 'quxga': '2400_3200', 'wquxga': '2400_3840', 'hxga': '3072_4096', 4017 'whxga': '3200_5120', 'hsxga': '4096_5120', 'whsxga': '4096_6400', 'huxga': '4800_6400', 'whuxga': '4800_7680', 4018 'nhd': '360_640', 'nhdx1': '320_640', 'qhd': '540_960', 'hd': '720_1280', '720p': '720_1280', 'fhd': '1080_1920', 4019 '1080p': '1080_1920', '1080i': '1080_1920', 'wqhd': '1440_2560', 'mbprhd': '1800_2880', '4kuhd': '2160_3840', 4020 '8kuhd': '4320_7680' 4021 }; 4022 4023 store("rstv_is_cache_res_matrix", true); 4024 store("rstv_cache_res_matrix", $res_matrix_arr); 4025 return $res_matrix_arr; 4026 } 4027 4028 /** 4029 * Converts various types of breakpoints into pixel breakpoints 4030 * It converts 'Device' and 'Resolution' breakpoints 4031 * @param bp_arr {Array} The breakpoints you define 4032 * @param bp_class_arr {Array} The names of CSS classes paired with breakpoints 4033 * @return {Array} 4034 * @private 4035 */
4036 function _toViewportBreakpoints(bp_arr, bp_class_arr) 4037 { 4038 try{ 4039 //Create local variables 4040 var bp_attrib_arr = [], 4041 list_dev_arr, 4042 list_res_arr, 4043 matrix_dev_arr, 4044 matrix_res_arr, 4045 ort_marker_str = '', 4046 ort_marker_key_str = '', 4047 error_marker_str = '', 4048 bp_temp_w_arr = [], 4049 bp_item_w_temp_int = '', 4050 bp_temp_h_arr = [], 4051 bp_item_h_temp_int = '', 4052 bp_temp_type_arr = [], 4053 bp_ort_marker_temp_arr = [], 4054 bp_final_arr = [], 4055 bp_item_temp_str, 4056 bp_item_res_temp_str, 4057 bp_item_final_str, 4058 bp_item_v_temp_str, 4059 bp_item_v_temp_arr = [], 4060 is_class_def_bool = false, 4061 is_attrib_def_bool = false; 4062 4063 //Create variables for counter functionality 4064 var counter_int = 0, 4065 counter_alpha_str = '', 4066 counter_alpha_arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 4067 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'ag', 'ah', 'ai', 4068 'aj', 'ak', 'al', 'am', 'an', 'ao', 'ap', 'aq', 'ar', 'as', 'at', 'au', 'av', 'aw', 'ax' 4069 ], 4070 counter_alpha_pre_arr = [], 4071 counter_alpha_post_arr = [], 4072 bp_arr_count_int = count(bp_arr), 4073 bp_class_arr_count_int = count(bp_class_arr), 4074 bp_attrib_arr_count_int = count(bp_attrib_arr), 4075 bp_item_w_temp_final_int, 4076 bp_item_h_temp_final_int; 4077 4078 //check that value in argument is array and is not empty 4079 switch(true) 4080 { 4081 case (!isArray(bp_arr)): 4082 throw new Error ("The first argument must be an array!"); 4083 break; 4084 4085 case (isArray(bp_arr) && bp_arr_count_int == 0): 4086 throw new Error ("The first argument must not be empty!"); 4087 break; 4088 } 4089 4090 //Check that only either classes or attributes are defined 4091 switch(true) 4092 { 4093 case ((bp_class_arr_count_int > 0) && (bp_attrib_arr_count_int > 0)): 4094 throw new Error("You can only define either 'Classes' or 'Attributes' settings!"); 4095 break; 4096 } 4097 4098 //If classes are defined, ensure they correspond with the number of breakpoints defined 4099 switch(true) 4100 { 4101 case (bp_class_arr_count_int > 0): 4102 //classes are defined 4103 is_class_def_bool = true; 4104 switch(true) 4105 { 4106 case (bp_class_arr_count_int !== bp_arr_count_int): 4107 throw new Error ("The number items for 'Breakpoints' and 'Classes' settings must match"); 4108 break; 4109 } 4110 break; 4111 } 4112 4113 //If attributes are defined, ensure they correspond with the number of breakpoints defined 4114 switch(true) 4115 { 4116 case (bp_attrib_arr_count_int > 0): 4117 //attributes are defined 4118 is_attrib_def_bool = true; 4119 switch(true) 4120 { 4121 case (bp_attrib_arr_count_int !== bp_arr_count_int): 4122 throw new Error ("The number items for 'Breakpoints' and 'Attributes' settings must match"); 4123 break; 4124 } 4125 break; 4126 } 4127 4128 //Get Breakpoint Reference Data 4129 list_res_arr = _getResolutionList(); 4130 matrix_res_arr = _getResolutionMatrix(); 4131 4132 //iterate over the breakpoints provided 4133 for(var i = 0; i < bp_arr_count_int; i++) 4134 { 4135 bp_item_temp_str = bp_arr[i]; 4136 4137 counter_alpha_str = counter_alpha_arr[i]; 4138 4139 //ensure that the orientation markers are valid i.e. only -p and -l if any 4140 switch(true) 4141 { 4142 case (/-+/i.test(bp_item_temp_str) && !/^[^-]*-[^-]*$/i.test(bp_item_temp_str)): 4143 //error in the way orientation markers are defined 4144 error_marker_str += '2'; 4145 break; 4146 } 4147 4148 //find out if there are any resolution markers e.g. -l or -p 4149 ort_marker_str = ''; 4150 ort_marker_key_str = ''; 4151 switch(true) 4152 { 4153 case (substr_count(bp_item_temp_str, '-p') > 0): 4154 ort_marker_str = 'p'; 4155 ort_marker_key_str = '-p'; 4156 4157 bp_ort_marker_temp_arr.push('p'); 4158 break; 4159 4160 case (substr_count(bp_item_temp_str, '-l') > 0): 4161 ort_marker_str = 'l'; 4162 ort_marker_key_str = '-l'; 4163 4164 bp_ort_marker_temp_arr.push('l'); 4165 break; 4166 4167 default: 4168 bp_ort_marker_temp_arr.push('x'); 4169 } 4170 4171 //reset the breakpoint i.e. remove any resolution markers 4172 bp_item_final_str = bp_item_temp_str.replace(''+ort_marker_key_str+'', ''); 4173 4174 //find out which class of breakpoint i.e. viewport, device, or resolution 4175 switch(true) 4176 { 4177 case (in_array(bp_item_final_str, list_res_arr)): 4178 //is resolution breakpoint. Get viewport dimensions 4179 bp_item_v_temp_str = matrix_res_arr[''+bp_item_final_str+'']; 4180 4181 bp_item_v_temp_arr = arrayToInteger(explode('_', bp_item_v_temp_str)); 4182 4183 bp_item_w_temp_int = parseInt(bp_item_v_temp_arr[0]); 4184 bp_item_h_temp_int = parseInt(bp_item_v_temp_arr[1]); 4185 4186 //consider landscape orientation markers 4187 bp_item_w_temp_final_int = bp_item_w_temp_int; 4188 bp_item_h_temp_final_int = bp_item_h_temp_int; 4189 switch(true) 4190 { 4191 case (ort_marker_str == 'l'): 4192 bp_item_w_temp_final_int = bp_item_h_temp_int; 4193 bp_item_h_temp_final_int = bp_item_w_temp_int; 4194 break; 4195 } 4196 4197 bp_temp_w_arr[counter_alpha_str] = bp_item_w_temp_final_int; 4198 bp_temp_h_arr[counter_alpha_str] = bp_item_h_temp_final_int; 4199 4200 //set breakpoint type as resolution 4201 bp_temp_type_arr.push('r'); 4202 4203 break; 4204 4205 case (/[0-9]+/i.test(bp_item_final_str)): 4206 //is viewport breakpoint 4207 bp_temp_w_arr[counter_alpha_str] = parseInt(bp_item_final_str); 4208 bp_temp_h_arr[counter_alpha_str] = parseInt(bp_item_final_str); 4209 4210 //set breakpoint type as viewport 4211 bp_temp_type_arr.push('v'); 4212 break; 4213 4214 default: 4215 //mark error 4216 error_marker_str += '1'; 4217 } 4218 4219 counter_alpha_pre_arr.push(counter_alpha_str); 4220 4221 counter_int++; 4222 } 4223 4224 //check if there are any errors. If yes, throw error 4225 switch(true) 4226 { 4227 case (/[1]+/i.test(error_marker_str)): 4228 throw new Error("There are errors in your 'Breakp
4228oints' settings!"); 4229 break; 4230 4231 case (/[2]+/i.test(error_marker_str)): 4232 throw new Error("There are errors in your 'Breakpoints' settings with regard to the way you have defined orientation markers e.g. -p or -l!"); 4233 break; 4234 } 4235 4236 //compose breakpoints 4237 var cmp = function ($a, $b) { 4238 if ($a == $b) { 4239 return 0; 4240 } 4241 return ($a < $b) ? -1 : 1; 4242 }; 4243 4244 var bp_temp_w_sort_arr = [], 4245 bp_temp_h_sort_arr = [], 4246 bp_temp_w_sort_int, 4247 bp_temp_w_sort_juxta_key_int, 4248 bp_type_arr = [], 4249 bp_temp_ort_sort_arr = [], 4250 bp_temp_class_arr = [], 4251 bp_temp_pre_attrib_arr = [], 4252 bp_temp_attrib_arr = []; 4253 4254 //reformat attribute array 4255 bp_temp_pre_attrib_arr = bp_attrib_arr; 4256 4257 //sort viewport width breakpoints 4258 bp_temp_w_sort_arr = uasort(bp_temp_w_arr, cmp); 4259 4260 //sort other arrays in an identical fashion to viewport width breakpoints 4261 counter_alpha_post_arr = array_keys(bp_temp_w_sort_arr); 4262 4263 var bp_temp_w_sort_arr_size_int = count(bp_temp_w_sort_arr); 4264 for(var i = 0; i < bp_temp_w_sort_arr_size_int; i++) 4265 { 4266 bp_temp_w_sort_int = counter_alpha_post_arr[i]; 4267 bp_temp_w_sort_juxta_key_int = array_search(bp_temp_w_sort_int, counter_alpha_pre_arr); 4268 4269 //sort breakpoint heights array 4270 bp_temp_h_sort_arr[bp_temp_w_sort_int] = bp_temp_h_arr[bp_temp_w_sort_int]; 4271 4272 //sort breakpoint type array 4273 bp_type_arr[i] = bp_temp_type_arr[bp_temp_w_sort_juxta_key_int]; 4274 4275 //sort the orientation marker array 4276 bp_temp_ort_sort_arr[i] = bp_ort_marker_temp_arr[bp_temp_w_sort_juxta_key_int]; 4277 4278 //sort the classes array 4279 bp_temp_class_arr[i] = bp_class_arr[bp_temp_w_sort_juxta_key_int]; 4280 4281 //sort the attributes array 4282 bp_temp_attrib_arr[i] = bp_temp_pre_attrib_arr[bp_temp_w_sort_juxta_key_int]; 4283 } 4284 4285 //Save Primary Results Data to Array 4286 bp_final_arr["bp_w"] = implode('|', bp_temp_w_sort_arr); //width 4287 bp_final_arr["bp_h"] = implode('|', bp_temp_h_sort_arr); //height 4288 bp_final_arr["bp_o"] = implode('|', bp_temp_ort_sort_arr); //orientation 4289 bp_final_arr["bp_t"] = implode('|', bp_type_arr); //type 4290 4291 //add data for classes if defined 4292 switch(true) 4293 { 4294 case (is_class_def_bool): 4295 var c_str = implode('|', bp_temp_class_arr); 4296 bp_final_arr["bp_c"] = c_str; //classes 4297 break; 4298 } 4299 4300 //add data for attributes if defined 4301 switch(true) 4302 { 4303 case (is_attrib_def_bool): 4304 var a_str = implode('|', bp_temp_attrib_arr); 4305 bp_final_arr["bp_a"] = a_str; //attributes 4306 break; 4307 } 4308 4309 return bp_final_arr; 4310 } 4311 catch(e){ 4312 var e_msg_str = "There was an error: "+ e.message; 4313 alert(e_msg_str); 4314 } 4315 } 4316 4317 /** 4318 * Wrapper class for _toViewportBreakpoints 4319 * @param bp_arr {Array} The list of breakpoints 4320 * @param bp_class_arr {Array} The corresponding list of classes 4321 * @return {Array} 4322 */ 4323 function getBreakpoints(bp_arr, bp_class_arr) 4324 { 4325 var data_arr = []; 4326 data_arr = _toViewportBreakpoints(bp_arr, bp_class_arr); 4327 4328 return data_arr; 4329 } 4330 4331 /** 4332 * Monitors the viewport for size and orientation changes 4333 */ 4334 function viewportMonitor() 4335 { 4336 var myArgs = Array.prototype.slice.call(arguments), 4337 trigger_suffix_str = (isNumber(myArgs[0])) ? "_"+myArgs[0]: ""; 4338 4339 var viewport_monit_fn = function(){ 4340 4341 //get viewport info before they are reset in storage 4342 var viewport_w_prev_int = store("rstv_viewportW"), 4343 viewport_h_prev_int = store("rstv_viewportH"); 4344 4345 //re-initialize dimension variables 4346 _initDimensionVars(); 4347 4348 //get current and active and define local variables 4349 var is_mobile_bool = isMobile(), 4350 ort_active_str = getOrientation(true), 4351 ort_curr_str = store("rstv_ort_curr"), 4352 viewport_w_curr_int, 4353 viewport_h_curr_int, 4354 viewport_w_diff_int, 4355 viewport_w_diff_abs_int, 4356 viewport_w_diff_pc_int, 4357 viewport_h_diff_int, 4358 viewport_h_diff_abs_int, 4359 viewport_h_diff_pc_int, 4360 is_softkey_bool = false;
4361 4362 //Update stored values for dimensions 4363 _updateDimensionStore(); 4364 4365 /** 4366 * Perform soft keyboard check 4367 * This manages for mobile devices that resize the viewport when the soft keyboard is initialized 4368 * This scenario will sometimes result in a pseudo-orientation change which is unwanted 4369 */ 4370 switch(true) 4371 { 4372 case (is_mobile_bool): 4373 viewport_w_curr_int = store("rstv_viewportW"); 4374 viewport_h_curr_int = store("rstv_viewportH"); 4375 viewport_w_diff_int = viewport_w_curr_int-viewport_w_prev_int; 4376 viewport_h_diff_int = viewport_h_curr_int-viewport_h_prev_int; 4377 viewport_w_diff_abs_int = Math.abs(viewport_w_diff_int); 4378 viewport_h_diff_abs_int = Math.abs(viewport_h_diff_int); 4379 4380 //get the percentage changes in viewport width and height 4381 viewport_w_diff_pc_int = (viewport_w_diff_abs_int/viewport_w_prev_int)*100; 4382 viewport_h_diff_pc_int = (viewport_h_diff_abs_int/viewport_h_prev_int)*100; 4383 4384 switch(true) 4385 { 4386 case (viewport_w_diff_pc_int < 1): 4387 switch(true) 4388 { 4389 case (viewport_h_diff_pc_int > 35 && viewport_h_diff_int < 0): 4390 //soft keyboard is opening 4391 is_softkey_bool = true; 4392 break; 4393 4394 case (viewport_h_diff_pc_int > 35 && viewport_h_diff_int > 0): 4395 //Soft keyboard closing - start 4396 is_softkey_bool = true; 4397 break; 4398 4399 case (viewport_h_diff_pc_int > 12 && viewport_h_diff_pc_int <= 35 && viewport_h_diff_int > 0): 4400 //Soft keyboard closing - end 4401 is_softkey_bool = true; 4402 break; 4403 4404 case (viewport_h_diff_pc_int == 0): 4405 //No movement - possible Soft keyboard action 4406 is_softkey_bool = true; 4407 break; 4408 } 4409 break; 4410 } 4411 break; 4412 } 4413 4414 /** 4415 * Trigger events only if soft keyboard action is not detected 4416 */ 4417 switch(true) 4418 { 4419 case (!is_softkey_bool): 4420 switch(true) 4421 { 4422 case ((ort_curr_str !== ort_active_str)): 4423 //orientation has changed. Update stored values for dimensions and orientation 4424 _updateOrientationStore(); 4425 4426 $(window).trigger("change_orientation"+trigger_suffix_str); 4427 break; 4428 4429 default: 4430 /** 4431 * Fire resize only for devices that are non-mobile 4432 * This eliminates resize callback functionality for mobile devices 4433 */ 4434 switch(true) 4435 { 4436 case (!is_mobile_bool): 4437 $(window).trigger("resize_viewport"+trigger_suffix_str); 4438 break; 4439 } 4440 } 4441 break; 4442 } 4443 }; 4444 resize(viewport_monit_fn); 4445 } 4446 4447 /** 4448 * Monitors a DOM element/container for size changes 4449 */ 4450 function containerMonitor(elem) 4451 { 4452 var myArgs = Array.prototype.slice.call(arguments), 4453 trigger_suffix_str = (isNumber(myArgs[1])) ? "_"+myArgs[1]: "" 4454 ; 4455 4456 var container_monit_fn = function(){ 4457 $(window).trigger("resize_container"+trigger_suffix_str); 4458 }; 4459 resizeContainer(elem, container_monit_fn); 4460 } 4461 4462 /** 4463 * Attach an event handler for the resize event 4464 * @param {Function} fn The function to execute 4465 * @return object 4466 */ 4467 function resize(fn) 4468 { 4469 $win.on('resize', fn); 4470 return Restive; 4471 } 4472 4473 /** 4474 * Attach an event handler for the resizecontainer event 4475 * @param {Function} fn The function to execute 4476 * @return object 4477 */ 4478 function resizeContainer(el, fn) 4479 { 4480 el.on('resizecontainer', fn); 4481 return Restive; 4482 } 4483 4484 //Define Restive Object 4485 Restive = { 4486 init: init(), 4487 reInit: reInit, 4488 getUserAgent: getUserAgent, 4489 isStorageValueSet: isStorageValueSet, 4490 store: store,
4491 storeVarTracker: storeVarTracker, 4492 storeVarValidator: storeVarValidator, 4493 incrementStorageValue: incrementStorageValue, 4494 getBreakpoints: getBreakpoints, 4495 viewportW: viewportW, 4496 viewportH: viewportH, 4497 screenW: screenW, 4498 screenH: screenH, 4499 pixelW: pixelW, 4500 pixelH: pixelH, 4501 vSpan: vSpan, 4502 vPitch: vPitch, 4503 dSpan: dSpan, 4504 dPitch: dPitch, 4505 cSpan: cSpan, 4506 cPitch: cPitch, 4507 eSpan: eSpan, 4508 ePitch: ePitch, 4509 isRetina: isRetina, 4510 getPixelRatio: getPixelRatio, 4511 getPlatform: getPlatform, 4512 getFormFactor: getFormFactor, 4513 getOrientation: getOrientation, 4514 getResolution: getResolution, 4515 isPortrait: isPortrait, 4516 isLandscape: isLandscape, 4517 viewportMonitor: viewportMonitor, 4518 containerMonitor: containerMonitor, 4519 isMobile: isMobile, 4520 isNonMobile: isNonMobile, 4521 isPhone: isPhone, 4522 isTablet: isTablet, 4523 isPC: isPC, 4524 isTV: isTV, 4525 isIOS: isIOS, 4526 isApple: isApple, 4527 isAndroid: isAndroid, 4528 isSymbian: isSymbian, 4529 isBlackberry: isBlackberry, 4530 isWindows: isWindows, 4531 isWindowsPhone: isWindowsPhone, 4532 resize: resize, 4533 resizeContainer: resizeContainer 4534 }; 4535 return Restive; 4536 4537})(window, document, jQuery); 4538 4539/* 4540 * Restive.JS Plugin v1.3.0 4541 * http://restivejs.com 4542 * 4543 * Copyright 2013 Obinwanne Hill <https://about.me/obinwanne.hill> 4544 * Released under MIT License 4545 */ 4546(function (window, document, $, undefined) { 4547 //Gets the content of a function 4548 Function.prototype.getFuncBody = function() 4549 { 4550 // Get content between first { and last } 4551 var m = this.toString().match(/\{([\s\S]*)\}/m)[1]; 4552 // Strip comments 4553 return m.replace(/^\s*\/\/.*$/mg,''); 4554 }; 4555 4556 var methods = { 4557 init : function(options){ 4558 4559 try{ 4560 4561 //Multiple Constructor Manager 4562 methods._multiConstructorCounter(); 4563 methods._multiConstructorManager(); 4564 4565 //Create plugin variables 4566 var $options = options, 4567 $valid_platform_arr = ['all', 'ios', 'android', 'symbian', 'blackberry', 'windows'], 4568 $valid_formfactor_arr = ['all', 'pc', 'tv', 'tablet', 'phone'], 4569 $platform_init_str = options.platform, 4570 $formfactor_init_str = options.formfactor, 4571 responsive_basis_str, 4572 is_resp_basis_container_bool, 4573 is_multi_start_bool = Restive.store("rstv_multi_start"), 4574 rstv_store_multi_counter_int = Restive.store("rstv_multi_count"), 4575 is_multi_abort_2_bool = Restive.store("rstv_multi_abort_2"); 4576 4577 //Ensure Platform Values are within range 4578 switch(true) 4579 { 4580 case(in_array($platform_init_str, $valid_platform_arr) === false): 4581 methods._error('rstv_error_001', '"'+$platform_init_str+'" is not a valid Platform option!'); 4582 return false; 4583 break; 4584 } 4585 4586 //Ensure Form Factor Values are within range 4587 switch(true) 4588 { 4589 case(in_array($formfactor_init_str, $valid_formfactor_arr) === false): 4590 methods._error('rstv_error_002', '"'+$formfactor_init_str+'" is not a valid Form Factor option!'); 4591 return false; 4592 break; 4593 } 4594 4595 //Abort if endMulti() is not called after startMulti() with multiple constructors 4596 switch(true) 4597 { 4598 case (is_multi_abort_2_bool): 4599 methods._error('rstv_error_003', 'If you are calling the Restive.JS Constructor more than once, you must call $.restive.endMulti() at the end!'); 4600 return false; 4601 break; 4602 } 4603 4604 //Get Initial Breakpoints 4605 var $breakpoints_arr = [], 4606 $breakpoints_init_arr = [], 4607 $classes_init_arr = []; 4608 4609 $breakpoints_init_arr = options.breakpoints; 4610 $classes_init_arr = options.classes; 4611
4612 $breakpoints_arr = methods.getBreakpoints($breakpoints_init_arr, $classes_init_arr); 4613 4614 /** 4615 * Generate Restive Core Information 4616 */ 4617 var $rstv_core_info_arr = []; 4618 4619 //A1. Get the Device Platform e.g. iOS, Android, etc. 4620 $rstv_core_info_arr["platform"] = methods.getPlatform(); 4621 4622 //A2. Get the Device Form Factor 4623 $rstv_core_info_arr["formfactor"] = methods.getFormFactor(); 4624 4625 //A3. Check if Device is a mobile device 4626 $rstv_core_info_arr["is_mobile"] = methods.isMobile(); 4627 4628 //A4. Get the Device Pixel Ratio 4629 $rstv_core_info_arr["pixelratio"] = methods.getPixelRatio(); 4630 4631 //A5. Get the Orientation and Set Orientation Marker 4632 $rstv_core_info_arr["orientation"] = methods.getOrientation(); 4633 4634 //A6. Get the Selector of the Element 4635 $rstv_core_info_arr["selector"] = getSelector(this); 4636 4637 //A7. Get the Tag Name of the Element 4638 $rstv_core_info_arr["tagname"] = this.prop("tagName").toLowerCase(); 4639 4640 //Get the Basis for Responsiveness 4641 responsive_basis_str = methods._responsiveBasis($options, $rstv_core_info_arr); 4642 is_resp_basis_container_bool = !!((responsive_basis_str == 'c')); 4643 4644 //Add Responsive Basis Indicator to Device Core Info 4645 $rstv_core_info_arr["is_resp_basis_container"] = is_resp_basis_container_bool; 4646 4647 //Set Event Handlers and Callbacks according to Responsive Basis 4648 switch(true) 4649 { 4650 case (is_resp_basis_container_bool): 4651 methods._containerMonitor($breakpoints_arr, this, $options, $rstv_core_info_arr); 4652 break; 4653 4654 default: 4655 switch(true) 4656 { 4657 case (!is_multi_start_bool): 4658 methods._viewportMonitor($breakpoints_arr, this, $options, $rstv_core_info_arr); 4659 methods._callbackManager($options, ['ready', 'init']); 4660 break; 4661 4662 default: 4663 //Store some variables required for later use 4664 window.parent.rstv_store.main["rstv_breakpoints_"+rstv_store_multi_counter_int] = $breakpoints_arr; 4665 window.parent.rstv_store.main["rstv_this_"+rstv_store_multi_counter_int] = this; 4666 window.parent.rstv_store.main["rstv_options_"+rstv_store_multi_counter_int] = $options; 4667 window.parent.rstv_store.main["rstv_core_info_"+rstv_store_multi_counter_int] = $rstv_core_info_arr; 4668 4669 window.rstv_store.main = window.parent.rstv_store.main; 4670 } 4671 } 4672 4673 //reset turbo_classes_reflow sessionStorage variable 4674 Restive.store("rstv_turbo_classes_reflow_status_in", null); 4675 4676 //set initialization marker for addclass callback 4677 Restive.store("rstv_bpm_addclass_init", false); 4678 4679 /** 4680 * Manage Breakpoints 4681 */ 4682 return this.each(function(){ 4683 var $this = $(this); 4684 methods.setBreakpoints($breakpoints_arr, $this, $options, $rstv_core_info_arr); 4685 }); 4686 } 4687 catch(e){ 4688 alert(e); 4689 console.log(e)/*RemoveLogging:skip*/; 4690 } 4691 }, 4692 _error: function(code, message){ 4693 var error_msg_is_init_bool = !!((String(Restive.store(code+"_init")).toLowerCase() === "true")); 4694 switch(true) 4695 { 4696 case (!error_msg_is_init_bool): 4697 Restive.store(code+"_init", true); 4698 throw new Error(message); 4699 break; 4700 } 4701 }, 4702 _callbackManager: function(){ 4703 4704 var myArgs = Array.prototype.slice.call(arguments), 4705 options = myArgs[0], 4706 callback_type_arr = myArgs[1], 4707 $on_func, 4708 $on_func_body_count 4709 ; 4710 4711 //Execute onReady 4712 switch(true) 4713 { 4714 case (in_array('ready', callback_type_arr)): 4715 var $on_ready = options.onReady, 4716 $on_ready_body_count = options.onReady.getFuncBody().length; 4717 switch(true) 4718 { 4719 case ($.isFunction($on_ready) && ($on_ready_body_count > 0)): 4720 //Execute Callback 4721 $on_ready(); 4722 break; 4723 } 4724 break; 4725 } 4726 4727 //Resize Callbacks 4728 switch(true) 4729 { 4730 case (in_array('resize', callback_type_arr)): 4731 var $on_resize = options.onResize, 4732 $on_resize_body_count = options.onResize.getFuncBody().length; 4733 switch(true) 4734 { 4735 case ($.isFunction($on_resize) && ($on_resize_body_count > 0)): 4736 //Execute Callback 4737 $on_resize(); 4738 break; 4739 } 4740 break; 4741 } 4742 4743 //PC Force Reflow Callbacks 4744 switch(true) 4745 { 4746 case (in_array('turboclassesreflow', callback_type_arr)): 4747 var $reflow_direction_str = callback_type_arr[1], 4748 $on_reflow = options.onTurboClassReflow, 4749 $on_reflow_body_count = options.onTurboClassReflow.getFuncBody().length; 4750 switch(true) 4751 { 4752 case ($.isFunction($on_reflow) && ($on_reflow_body_count > 0)): 4753 //Execute Callback 4754 $on_reflow(); 4755 break; 4756 } 4757 4758 var $on_reflow_in = options.onTurboClassReflowIn, 4759 $on_reflow_in_body_count = options.onTurboClassReflowIn.getFuncBody().length; 4760 switch(true) 4761 { 4762 case ($.isFunction($on_reflow_in) && ($on_reflow_in_body_count > 0)): 4763 //Execute Callback 4764 switch(true) 4765 { 4766 case ($reflow_direction_str == 'in'): 4767 $on_reflow_in(); 4768 break; 4769 } 4770 break; 4771 } 4772 4773 var $on_reflow_out = options.onTurboClassReflowOut, 4774 $on_reflow_out_body_count = options.onTurboClassReflowOut.getFuncBody().length; 4775 switch(true) 4776 { 4777 case ($.isFunction($on_reflow_out) && ($on_reflow_out_body_count > 0)): 4778 //Execute Callback 4779 switch(true) 4780 { 4781 case ($reflow_direction_str == 'out'): 4782 $on_reflow_out(); 4783 break; 4784 } 4785 break; 4786 } 4787 4788 break; 4789 } 4790 4791 //Rotate/Orientation Callbacks 4792 switch(true) 4793 { 4794 case (in_array('rotate', callback_type_arr)): 4795 var ort_curr_str = Restive.getOrientation(), 4796 $on_rotate = options.onRotate, 4797 $on_rotate_body_count = options.onRotate.getFuncBody().length; 4798 switch(true) 4799 { 4800 case ($.isFunction($on_rotate) && ($on_rotate_body_count > 0)): 4801 //Execute Callback 4802 $on_rotate(); 4803 break; 4804 } 4805 4806 //Execute onRotateToP 4807 var $on_rotate_to_p = options.onRotateToP, 4808 $on_rotate_to_p_body_count = options.onRotateToP.getFuncBody().length; 4809 switch(true) 4810 { 4811 case ($.isFunction($on_rotate_to_p) && ($on_rotate_to_p_body_count > 0)): 4812 //Execute Callback 4813 switch(true) 4814 { 4815 case (ort_curr_str == 'portrait'): 4816 $on_rotate_to_p(); 4817 break; 4818 } 4819 break; 4820 } 4821 4822 //Execute onRotateToL 4823 var $on_rotate_to_l = options.onRotateToL, 4824 $on_rotate_to_l_body_count = options.onRotateToL.getFuncBody().length; 4825 switch(true) 4826 { 4827 case ($.isFunction($on_rotate_to_l) && ($on_rotate_to_l_body_count > 0)): 4828 //Execute Callback 4829 switch(true) 4830 { 4831 case (ort_curr_str == 'landscape'): 4832 $on_rotate_to_l(); 4833 break; 4834 } 4835 break; 4836 } 4837 break; 4838 } 4839 4840 //Add/Remove Class Callbacks 4841 switch(true) 4842 { 4843 case (in_array('addclass', callback_type_arr) || in_array('removeclass', callback_type_arr)): 4844 var $callback_type_str = callback_type_arr[0], 4845 $callback_type_args = callback_type_arr[1], 4846 $callback_data_arr = {'addclass': 'onAddClass', 'removeclass': 'onRemoveClass'} 4847 ; 4848 $on_func = options[$callback_data_arr[''+$callback_type_str+'']]; 4849 $on_func_body_count = $on_func.getFuncBody().length; 4850 4851 switch(true) 4852 { 4853 case ($.isFunction($on_func) && ($on_func_body_count > 0)): 4854 //Execute Callback 4855 $on_func($callback_type_args); 4856 break; 4857 } 4858 break; 4859 } 4860 4861 //Initialization Callbacks 4862 switch(true) 4863 { 4864 case (in_array('init', callback_type_arr)): 4865 switch(true) 4866 { 4867 case (in_array('init', callback_type_arr)): 4868 var callback_name_arr = [ 4869 'onPortrait', 'onLandscape', 'onRetina', 'onPhone', 'onTablet', 'onPC', 'onTV', 'onIOS', 'onAn
4869droid', 'onSymbian', 'onBlackberry', 'onWindows', 'onWindowsPhone', 'onMobile', 'onNonMobile' 4870 ], 4871 func_name_arr = [ 4872 'isPortrait', 'isLandscape', 'isRetina', 'isPhone', 'isTablet', 'isPC', 'isTV', 'isIOS', 'isAndroid', 'isSymbian', 'isBlackberry', 'isWindows', 'isWindowsPhone', 'isMobile', 'isNonMobile' 4873 ]; 4874 4875 for(var i = 0; i < count(func_name_arr); i++) 4876 { 4877 $on_func = options[callback_name_arr[i]]; 4878 $on_func_body_count = $on_func.getFuncBody().length; 4879 4880 switch(true) 4881 { 4882 case ($.isFunction($on_func) && ($on_func_body_count > 0)): 4883 var $on_func_res = methods[func_name_arr[i]], 4884 $on_func_bool = $on_func_res(); 4885 switch(true) 4886 { 4887 case ($on_func_bool): 4888 $on_func(); 4889 break; 4890 } 4891 break; 4892 } 4893 } 4894 break; 4895 } 4896 break; 4897 } 4898 }, 4899 _URLMonitor: function(){ 4900 //monitor changes from URL to URL 4901 var $rstv_url_str = Restive.store("rstv_url"), 4902 $rstv_url_hash_prev_str = Restive.store("rstv_url_hash"), 4903 $rstv_url_hash_curr_str = md5($rstv_url_str); 4904 4905 switch(true) 4906 { 4907 case ($rstv_url_hash_curr_str != $rstv_url_hash_prev_str): 4908 //page has changed 4909 Restive.store("rstv_multi_bpm_idx rstv_cache_bpm rstv_cache_bpm_lock rstv_cache_req rstv_cache_bpm_viewport_diff", null); 4910 4911 Restive.store("rstv_url_hash", $rstv_url_hash_curr_str); 4912 break; 4913 } 4914 }, 4915 _responsiveBasis: function($options, $rstv_core_info){ 4916 /** 4917 * This determines the basis for responsive i.e. viewport or container 4918 * 1. If anchor option is 'element' and Restive.JS selector is under the body tag, basis is 'container' or 'c' 4919 * 2. If not 1, basis is 'viewport' or 'v' 4920 */ 4921 var resp_basis_str, 4922 selector_name_str = $rstv_core_info["selector"], 4923 elem_is_id_selector_bool = /^#[^\s]+$/i.test(selector_name_str), 4924 elem_is_child_of_body_bool = elementIsChildOf('body', selector_name_str), 4925 anchor_str = $options.anchor 4926 ; 4927 4928 try 4929 { 4930 switch(true) 4931 { 4932 case (elem_is_child_of_body_bool && (anchor_str == 'element' || anchor_str == 'e')): 4933 switch(true) 4934 { 4935 case (!elem_is_id_selector_bool): 4936 throw new Error("You must use only the JQuery ID selector when the 'anchor' option is set to 'e' or 'element'!"); 4937 break; 4938 } 4939 resp_basis_str = 'c'; 4940 break; 4941 4942 default: 4943 resp_basis_str = 'v'; 4944 /** 4945 * This indicates that at least one Restive.JS constructor has a Responsive Basis of 'viewport' 4946 * NOTE: It is ultimately used to prevent the viewport and callback manager from being activated if all Restive.JS constructors are determined to have a 'container' responsiveness basis 4947 */ 4948 Restive.store("rstv_resp_basis_viewport_init", true); 4949 } 4950 4951 return resp_basis_str; 4952 } 4953 catch(e){ 4954 alert(e); 4955 console.log(e);/*RemoveLogging:skip*/ 4956 } 4957 }, 4958 _viewportMonitor: function($bp_arr, $this, $options, $rstv_core_info){ 4959 //set event handler for resize 4960 var event_name_resize_str = "resize_viewport", 4961 event_name_ort_str = "change_orientation"; 4962 4963 //set event handler for viewport resize 4964 $(window).on(event_name_resize_str, function(){ 4965 methods._onResizeViewport($bp_arr, $this, $options, $rstv_core_info); 4966 }); 4967 4968 //set event handler for orientation change 4969 $(window).on(event_name_ort_str, function(){ 4970 methods._onChangeOrientation($bp_arr, $this, $options, $rstv_core_info); 4971 }); 4972 4973 //activate Viewport Monitor
4974 Restive.viewportMonitor(); 4975 }, 4976 _containerMonitor: function($bp_arr, $this, $options, $rstv_core_info){ 4977 var event_name_resize_container_str = "resizecontainer" 4978 ; 4979 4980 //set event handler for container resize 4981 $this.on(event_name_resize_container_str, function(){ 4982 methods._onResizeContainer($bp_arr, $this, $options, $rstv_core_info); 4983 }); 4984 }, 4985 _onResizeViewport: function($bp_arr, $this, $options, $rstv_core_info){ 4986 try{ 4987 return $this.each(function(){ 4988 var $_this = $(this) 4989 ; 4990 methods.setBreakpoints($bp_arr, $_this, $options, $rstv_core_info, 'rv'); 4991 4992 //call resize callbacks 4993 methods._callbackManager($options, ['resize']); 4994 }); 4995 } 4996 catch(e){ 4997 alert(e); 4998 console.log(e);/*RemoveLogging:skip*/ 4999 } 5000 }, 5001 _onResizeContainer: function($bp_arr, $this, $options, $rstv_core_info){ 5002 try{ 5003 return $this.each(function(){ 5004 var $_this = $(this) 5005 ; 5006 methods.setBreakpoints($bp_arr, $_this, $options, $rstv_core_info, 'rc'); 5007 }); 5008 } 5009 catch(e){ 5010 alert(e); 5011 console.log(e);/*RemoveLogging:skip*/ 5012 } 5013 }, 5014 _onChangeOrientation: function($bp_arr, $this, $options, $rstv_core_info){ 5015 try{ 5016 return $this.each(function(){ 5017 var $_this = $(this); 5018 methods.setBreakpoints($bp_arr, $_this, $options, $rstv_core_info, 'co'); 5019 5020 //call orientation callbacks 5021 methods._callbackManager($options, ['rotate']); 5022 }); 5023 } 5024 catch(e){ 5025 alert(e); 5026 console.log(e);/*RemoveLogging:skip*/ 5027 } 5028 }, 5029 getBreakpoints: function(bp_arr, bp_class_arr){
5030 return Restive.getBreakpoints(bp_arr, bp_class_arr); 5031 }, 5032 setBreakpoints: function(){ 5033 5034 var myArgs = Array.prototype.slice.call(arguments); 5035 var bp_arr = myArgs[0], 5036 elem = myArgs[1], 5037 rstv_options = myArgs[2], 5038 rstv_core_info = myArgs[3], 5039 rstv_event_info = myArgs[4], 5040 is_ort_change_bool = false, 5041 is_resize_viewport_bool = false, 5042 is_resize_container_bool = false, 5043 is_resp_basis_container_bool = rstv_core_info["is_resp_basis_container"], 5044 is_multi_abort_1_bool = Restive.store("rstv_multi_abort_1") 5045 ; 5046 5047 //Capture orientation change 5048 switch(true) 5049 { 5050 case (rstv_event_info == 'co'): 5051 //there has been a change in orientation. manage accordingly 5052 is_ort_change_bool = true; 5053 break; 5054 } 5055 5056 //Capture resize 5057 switch(true) 5058 { 5059 case (rstv_event_info == 'rv'): 5060 //the viewport has been resized. manage accordingly 5061 is_resize_viewport_bool = true; 5062 break; 5063 } 5064 5065 //Capture resize container 5066 switch(true) 5067 { 5068 case (rstv_event_info == 'rc'): 5069 //the selected container has been resized. manage accordingly 5070 is_resize_container_bool = true; 5071 break; 5072 } 5073 5074 //Abort Restive.JS if multiple constructor anomalies occur 5075 switch(true) 5076 { 5077 case (is_multi_abort_1_bool): 5078 methods._error('rstv_error_004', 'If you are calling the Restive.JS Constructor more than once, you must call $.restive.startMulti() before calling these constructors!'); 5079 return false; 5080 break; 5081 } 5082 5083 /** 5084 * When multiple Restive.JS Constructors are used, and a match is found, that match is saved 5085 * On successive attempts, the breakpoint conditions that previously failed are prevented from being executed further to improve overall performace 5086 * The following code manages this process 5087 * NOTE: If the Responsive Basis is 'container', this functionality is ignored 5088 */ 5089 var rstv_store_is_multi_bool = Restive.store("rstv_multi_start"), 5090 rstv_store_multi_count_int = parseInt(Restive.store("rstv_multi_count")), 5091 rstv_store_bpm_idx_int = parseInt(Restive.store("rstv_multi_bpm_idx")), 5092 rstv_store_bpm_lock_bool = Restive.store("rstv_cache_bpm_lock") 5093 ; 5094 5095 switch(true) 5096 { 5097 case (!is_resp_basis_container_bool): 5098 /** 5099 * Do only if Responsive Basis is Viewport 5100 */ 5101 switch(true) 5102 { 5103 case (rstv_store_is_multi_bool && !is_ort_change_bool && rstv_store_bpm_lock_bool): 5104 switch(true) 5105 { 5106 case (isNumber(rstv_store_multi_count_int) && isNumber(rstv_store_bpm_idx_int) && rstv_store_multi_count_int != rstv_store_bpm_idx_int): 5107 return false; 5108 break; 5109 } 5110 break; 5111 } 5112 break; 5113 } 5114 5115 //get Device and Orientation Options and Information 5116 var restive_user_agent_str = Restive.getUserAgent(), 5117 options_platform_str = rstv_options.platform, 5118 options_formfactor_str = rstv_options.formfactor, 5119 options_force_dip_str = rstv_options.force_dip, 5120 restive_platform_str = rstv_core_info["platform"], 5121 restive_formfactor_str = rstv_core_info["formfactor"], 5122 restive_pixelratio_str = rstv_core_info["pixelratio"], 5123 restive_is_mobile_str = (rstv_core_info["is_mobile"] == true) ? "true": "false", 5124 ort_init_str = Restive.store("rstv_ort_init"), 5125 ort_curr_str = Restive.store("rstv_ort_curr"), 5126 is_portrait_bool = Restive.isPortrait(), 5127 is_landscape_bool = (is_portrait_bool === true) ? false : true; 5128 5129 5130 var dim_arr = [], 5131 viewport_w_int, 5132 viewport_h_int, 5133 screen_w_int, 5134 screen_h_int, 5135 pixel_w_int, 5136 pixel_h_int, 5137 viewport_w_active_int, 5138 bp_set_arr = [], 5139 bp_class_arr = [], 5140 is_class_def_bool = false, 5141 bp_width_tok_str = bp_arr["bp_w"], 5142 bp_height_tok_str = bp_arr["bp_h"], 5143 bp_ort_tok_str = bp_arr["bp_o"], 5144 bp_type_tok_str = bp_arr["bp_t"], 5145 bp_class_tok_str = bp_arr["bp_c"], 5146 bp_width_arr = [], 5147 bp_height_arr = [], 5148 bp_ort_arr = [], 5149 bp_type_arr = []; 5150 5151 viewport_w_int = Restive.viewportW(); 5152 viewport_w_active_int = viewport_w_int; 5153 viewport_h_int = Restive.viewportH(); 5154 screen_w_int = Restive.screenW(); 5155 screen_h_int = Restive.screenH(); 5156 pixel_w_int = Restive.pixelW(); 5157 pixel_h_int = Restive.pixelH(); 5158 5159 switch(true) 5160 { 5161 case (options_force_dip_str == true): 5162 viewport_w_active_int = Restive.pixelW(); 5163 break; 5164 } 5165 5166 //Extract Data to Array
5167 bp_width_arr = arrayToInteger(explode("|", bp_width_tok_str)); 5168 bp_height_arr = arrayToInteger(explode("|", bp_height_tok_str)); 5169 bp_ort_arr = explode("|", bp_ort_tok_str); 5170 bp_type_arr = explode("|", bp_type_tok_str); 5171 5172 //Manage Classes Data 5173 switch(true) 5174 { 5175 case (typeof bp_class_tok_str !== "undefined" || bp_class_tok_str != null): 5176 is_class_def_bool = true; 5177 bp_class_arr = explode("|", bp_class_tok_str); 5178 break; 5179 } 5180 5181 var bp_width_arr_has_dupl_bool, 5182 bp_width_tok_no_dupl_str = '', 5183 bp_break_on_match_bool, 5184 bp_width_int, 5185 bp_width_prev_int, 5186 bp_width_prev_ort_marker_int, 5187 is_curr_bp_in_ort_range_bool = true, 5188 is_prev_bp_in_ort_range_bool = true, 5189 is_ort_marker_set_init_bool = false, //this indicates whether orientation markers have been used at least once 5190 bp_width_start_int, 5191 bp_width_min_int, 5192 bp_width_max_int, 5193 bp_height_int, 5194 bp_width_diff_r_int, //the difference between current viewport width and bp_width_max_int 5195 bp_width_diff_r_abs_int, //the absolute difference between current viewport width and bp_width_max_int 5196 bp_width_diff_l_int, //the difference between current viewport width and bp_width_min_int 5197 bp_width_diff_r_comp_int, 5198 bp_type_str, 5199 bp_ort_str, 5200 bp_class_str, 5201 bp_class_last_sel_str, 5202 span_range_bool, 5203 ort_range_bool, 5204 is_breakpoint_match_bool = false, 5205 is_breakpoint_match_hit_bool = false, 5206 is_breakpoint_match_os_bool = true, 5207 is_breakpoint_match_ff_bool = true, 5208 ba_usage_log_status_str = '', 5209 ba_usage_log_status_code_str = '', 5210 elem_set_data_str 5211 ; 5212 5213 var bp_width_arr_count_int = count(bp_width_arr); 5214 5215 //check if there are duplicate width values 5216 bp_width_arr_has_dupl_bool = arrayHasDuplicates(bp_width_arr); 5217 bp_break_on_match_bool = (bp_width_arr_has_dupl_bool) ? false : true; 5218 5219 /** 5220 * Iterate over individual breakpoints 5221 */ 5222 for(var i = 0; i < bp_width_arr_count_int; i++) 5223 { 5224 /** 5225 * Filter for: 5226 * 1. platform 5227 * 2. form factor 5228 * If provided in the options 5229 * Break out of for loop 5230 */ 5231 //1 5232 switch(true) 5233 { 5234 case (rstv_options.platform != 'all' && rstv_options.platform != restive_platform_str): 5235 is_breakpoint_match_os_bool = false;
5236 break; 5237 } 5238 5239 //2 5240 switch(true) 5241 { 5242 case (rstv_options.formfactor != 'all' && rstv_options.formfactor != restive_formfactor_str): 5243 is_breakpoint_match_ff_bool = false; 5244 break; 5245 } 5246 5247 //break out of for loop if match is not found 5248 if(!is_breakpoint_match_os_bool || !is_breakpoint_match_ff_bool) break; 5249 5250 var i_prev = i - 1; 5251 bp_width_int = bp_width_arr[i]; 5252 5253 //manage previous breakpoint widths 5254 switch(true) 5255 { 5256 case (i > 0): 5257 bp_width_prev_int = bp_width_arr[i_prev]; 5258 break; 5259 5260 default: 5261 bp_width_prev_int = 0; 5262 bp_width_prev_ort_marker_int = 0; 5263 } 5264 5265 bp_height_int = bp_height_arr[i]; 5266 5267 bp_type_str = bp_type_arr[i]; 5268 bp_ort_str = bp_ort_arr[i]; 5269 5270 //Consider orientation markers 5271 is_prev_bp_in_ort_range_bool = is_curr_bp_in_ort_range_bool; 5272 switch(true) 5273 { 5274 case (bp_ort_str == "p"): 5275 ort_range_bool = (is_portrait_bool) ? true : false; 5276 is_ort_marker_set_init_bool = true; 5277 5278 is_curr_bp_in_ort_range_bool = ort_range_bool; 5279 bp_width_tok_no_dupl_str = (is_prev_bp_in_ort_range_bool === false) ? bp_width_prev_ort_marker_int: bp_width_tok_no_dupl_str; 5280 break; 5281 5282 case (bp_ort_str == "l"): 5283 ort_range_bool = (is_landscape_bool) ? true : false; 5284 is_ort_marker_set_init_bool = true; 5285 5286 is_curr_bp_in_ort_range_bool = ort_range_bool; 5287 bp_width_tok_no_dupl_str = (is_prev_bp_in_ort_range_bool === false) ? bp_width_prev_ort_marker_int: bp_width_tok_no_dupl_str; 5288 break; 5289 5290 default: 5291 /** 5292 * If is_prev_bp_in_ort_range_bool is false, it means that the previous breakpoint 5293 * had an orientation marker ('-p' or '-l') that did not match the current 5294 * orientation of the viewport. 5295 * And if is_ort_marker_set_init_bool is true, then there has been a transition from a 5296 * breakpoint with an orientation marker to one without one. 5297 */ 5298 bp_width_tok_no_dupl_str = (is_ort_marker_set_init_bool === true && is_prev_bp_in_ort_range_bool === false) ? bp_width_prev_ort_marker_int: bp_width_tok_no_dupl_str; 5299 5300 bp_width_prev_ort_marker_int = (i > 0) ? bp_width_int: 0; 5301 ort_range_bool = true; 5302 is_curr_bp_in_ort_range_bool = ort_range_bool; 5303 } 5304 5305 //Manage duplicate entries 5306 switch(true) 5307 { 5308 case (i == 0): 5309 bp_width_start_int = 0; 5310 bp_width_tok_no_dupl_str = bp_width_int; 5311 break; 5312 5313 case (i >= 1): 5314 5315 switch(true) 5316 { 5317 case (bp_width_int !== bp_width_prev_int): 5318 bp_width_tok_no_dupl_str = bp_width_int+'-!'+bp_width_tok_no_dupl_str; 5319 break; 5320 } 5321 5322 bp_width_start_int = parseInt(getValueAfterExplode(bp_width_tok_no_dupl_str, '-!', 1)); 5323 5324 break; 5325 } 5326 5327 //Define classes 5328 bp_class_str = bp_class_arr[i]; 5329 5330 //set ranges for widths 5331 switch(true) 5332 { 5333 case (i == 0): 5334 bp_width_min_int = bp_width_start_int; 5335 bp_width_max_int = bp_width_int; 5336 5337 break; 5338 5339 default: 5340 bp_width_min_int = (bp_width_start_int == 0) ? bp_width_start_int : bp_width_start_int
5340+ 1; 5341 bp_width_max_int = bp_width_int; 5342 } 5343 5344 /** 5345 * Check for Matching Breakpoints 5346 * 1. Do for Container Basis 5347 * 2. Do for Viewport Basis. Make sure to consider force_dip option 5348 */ 5349 switch(true) 5350 { 5351 case (is_resp_basis_container_bool): 5352 //1 5353 span_range_bool = Restive.eSpan(bp_width_min_int, bp_width_max_int, elem, rstv_options.anchor_e_df, rstv_options.force_dip); 5354 break; 5355 5356 default: 5357 //2 5358 span_range_bool = (options_force_dip_str == true) ? Restive.cSpan(bp_width_min_int, bp_width_max_int): Restive.vSpan(bp_width_min_int, bp_width_max_int); 5359 } 5360 5361 /** 5362 * Set Breakpoints 5363 * A. For Container Basis 5364 * 5365 * B. For Viewport Basis 5366 * Status codes as follows: 5367 * 1: Viewport matched breakpoint with clean hit on initialization i.e. viewport is virtually identical to breakpoint 5368 * 2: Viewport matched breakpoint with clean hit after orientation change 5369 * 3: Viewport matched breakpoint but not with a clean hit i.e. margin between viewport width and upper limit of matched breakpoint range is significant 5370 * 4: Viewport matched breakpoint after orientation change but not with a clean hit i.e. margin between viewport width and upper limit of matched breakpoint range is significant 5371 */ 5372 switch(true) 5373 { 5374 case (span_range_bool && ort_range_bool): 5375 5376 switch(true) 5377 { 5378 case (is_resp_basis_container_bool): 5379 //A 5380 is_breakpoint_match_bool = true; 5381 break; 5382 5383 default: 5384 //B 5385 bp_width_diff_r_int = bp_width_max_int - viewport_w_active_int; 5386 bp_width_diff_r_abs_int = Math.abs(bp_width_diff_r_int); 5387 bp_width_diff_l_int = viewport_w_active_int - bp_width_min_int; 5388 5389 bp_width_diff_r_comp_int = bp_width_max_int*0.1; 5390 bp_width_diff_r_comp_int = Math.round(bp_width_diff_r_comp_int); 5391 5392 switch(true) 5393 { 5394 case (is_ort_change_bool): 5395 //capture some key metrics 5396 switch(true) 5397 { 5398 case (bp_width_diff_r_int > bp_width_diff_r_comp_int): 5399 ba_usage_log_status_code_str = "4"; 5400 break; 5401 5402 default: 5403 ba_usage_log_status_code_str = "2"; 5404 } 5405 break; 5406 5407 default: 5408 //capture some key metrics 5409 switch(true) 5410 { 5411 case (bp_width_diff_r_int > bp_width_diff_r_comp_int): 5412 ba_usage_log_status_code_str = "3"; 5413 break; 5414 5415 default: 5416 ba_usage_log_status_code_str = "1"; 5417 } 5418 } 5419 5420 is_breakpoint_match_bool = true; 5421 5422 //Capture class values of last hit 5423 switch(true) 5424 { 5425 case (is_breakpoint_match_bool): 5426 is_breakpoint_match_hit_bool = true; 5427 5428 bp_class_last_sel_str = bp_class_
5428str; 5429 5430 switch(true) 5431 { 5432 case (bp_ort_str != "x"): 5433 bp_break_on_match_bool = true; 5434 break; 5435 } 5436 break; 5437 } 5438 } 5439 5440 break; 5441 5442 default: 5443 is_breakpoint_match_bool = false; 5444 } 5445 5446 //break out of for loop if match is found 5447 if(is_breakpoint_match_bool && bp_break_on_match_bool) break; 5448 } 5449 5450 //Perform adjustment of breakpoint match value to compensate for if bp_break_on_match_bool is false 5451 switch(true) 5452 { 5453 case (is_breakpoint_match_hit_bool): 5454 is_breakpoint_match_bool = true; 5455 bp_class_str = bp_class_last_sel_str; 5456 break; 5457 } 5458 5459 //Some Breakpoint Advisory Information 5460 switch(true) 5461 { 5462 case (!is_breakpoint_match_bool): 5463 5464 //Do for Container Basis 5465 switch(true) 5466 { 5467 case (is_resp_basis_container_bool): 5468 methods.unsetElementDOM(elem, rstv_options); 5469 return; 5470 break; 5471 } 5472 5473 //Do for Viewport Basis 5474 bp_width_min_int = 0; 5475 bp_width_max_int = 0; 5476 5477 switch(true) 5478 { 5479 case (!Restive.store("rstv_multi_start") || is_ort_change_bool): 5480 methods.unsetElementDOM(elem, rstv_options); 5481 break; 5482 } 5483 5484 switch(true) 5485 { 5486 case (!is_breakpoint_match_os_bool && is_breakpoint_match_ff_bool): 5487 ba_usage_log_status_code_str = "7"; 5488 break; 5489 5490 case (!is_breakpoint_match_ff_bool && is_breakpoint_match_os_bool): 5491 ba_usage_log_status_code_str = "8"; 5492 break; 5493 5494 case (!is_breakpoint_match_ff_bool && !is_breakpoint_match_os_bool): 5495 ba_usage_log_status_code_str = "9"; 5496 break; 5497 5498 default: 5499 switch(true) 5500 { 5501 case (is_ort_change_bool): 5502 ba_usage_log_status_code_str = "6"; 5503 break; 5504 5505 default: 5506 ba_usage_log_status_code_str = "5"; 5507 } 5508 } 5509 5510 //Add Turbo Classes if any 5511 elem_set_data_str = methods._addTurboClasses('', rstv_options.turbo_classes); 5512 5513 //This if for turbo_classes_reflow option 5514 elem_set_data_str = methods._addTurboClassesReflow(elem_set_data_str, rstv_options); 5515 5516 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5517 5518 //persist 5519 Restive.store("rstv_breakpoint_match_curr", false); 5520 5521 break; 5522 5523 case (is_breakpoint_match_bool): 5524 elem_set_data_str = methods._addTurboClasses(bp_class_str, rstv_options.turbo_classes); 5525 5526 //This if for turbo_classes_reflow option 5527 elem_set_data_str = methods._addTurboClassesReflow(elem_set_data_str, rstv_options); 5528 5529 /** 5530 * Set class 5531 */ 5532 //Do for Container Basis 5533 switch(true) 5534 { 5535 case (is_resp_basis_container_bool): 5536 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5537 return; 5538 break; 5539 } 5540 5541 //Do for Viewport Basis 5542 switch(true) 5543 { 5544 case (Restive.store("rstv_multi_start")): 5545 var bpm_h_counter_int = parseInt(Restive.store("rstv_bpm_h_counter")); 5546 switch(true) 5547 { 5548 case (is_ort_change_bool): 5549 //change in orientation 5550 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5551 break; 5552 5553 default: 5554 //initialization 5555 switch(true) 5556 { 5557 case (bpm_h_counter_int > 1): 5558 //check if the current viewport offers a better match 5559 var ss_bp_width_diff_r_abs_int = parseInt(Restive.store("rstv_cache_bpm_viewport_diff")); 5560 5561 switch(true) 5562 { 5563 case (bp_width_diff_r_abs_int < ss_bp_width_diff_r_abs_int): 5564 //this is a better viewport match 5565 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5566 5567 switch(true) 5568 { 5569 case(!rstv_store_bpm_lock_bool): 5570 Restive.store("rstv_multi_bpm_idx", rstv_store_multi_count_int); 5571 break; 5572 } 5573 5574 Restive.store("rstv_cache_bpm_viewport_diff", bp_width_diff_r_abs_int); 5575 break; 5576 } 5577 5578 break; 5579 5580 default: 5581 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5582 switch(true) 5583 { 5584 case(!rstv_store_bpm_lock_bool): 5585 Restive.store("rstv_multi_bpm_idx", rstv_store_multi_count_int); 5586 break; 5587 } 5588 5589 Restive.store("rstv_cache_bpm_viewport_diff", bp_width_diff_r_abs_int); 5590 } 5591 5592 bpm_h_counter_int++; 5593 Restive.store("rstv_bpm_h_counter", bpm_h_counter_int, '', {expires: 1000}); 5594 } 5595 5596 break; 5597 5598 default: 5599 //Set the element class immediately 5600 methods.setElementDOM(elem, elem_set_data_str, rstv_options); 5601 } 5602 5603 //persist 5604 Restive.store("rstv_breakpoint_match_curr", true); 5605 break; 5606 } 5607 5608 /** 5609 * Track Breakpoint Hits and Misses in Storage 5610 * Do this incrementally when: 5611 * 1. Multi-Constructor Mode is active 5612 * 2. There has not been a change in orientation 5613 * 3. Breakpoint Match Cache Lock is not set 5614 * NOTE: For Multi-constructor Operations only 5615 */ 5616 var rstv_cache_bpm_lock_bool = Restive.store("rstv_cache_bpm_lock"); 5617 switch(true) 5618 { 5619 case (rstv_store_is_multi_bool && !is_ort_change_bool && !((isString(rstv_cache_bpm_lock_bool) && rstv_cache_bpm_lock_bool != "") || isBool(rstv_cache_bpm_lock_bool))): 5620 (Restive.store("rstv_breakpoint_match_curr")) ? methods._extVarTracker("rstv_cache_bpm", "h", "ls", false, '', false): methods._extVarTracker("rstv_cache_bpm", "m", "ls", false, '', false); 5621 break; 5622 } 5623 5624 //Exit for Matched Breakpoint 5625 switch(true) 5626 { 5627 case (is_breakpoint_match_bool): 5628 return true; 5629 break; 5630 } 5631 5632 return false;
5633 }, 5634 _addTurboClassesReflow: function(class_data_str, options){ 5635 switch(true) 5636 { 5637 case (methods.isPC()): 5638 //only do for Personal Computer environments 5639 5640 switch(true) 5641 { 5642 case (options.turbo_classes_reflow && isString(options.turbo_classes) && options.turbo_classes != ''): 5643 //only do if turbo_classes_reflow option is true and turbo_classes are populated 5644 5645 var opt_isset_is_mobile_bool, 5646 fpr_span_range_tomobile_bool, 5647 fpr_span_range_tophone_bool, 5648 fpr_span_range_totablet_bool, 5649 fpr_limits_tablet_int, 5650 fpr_limits_phone_int, 5651 fpr_limits_bp_btw_phone_and_tablet_int, 5652 fpr_test_key_str, 5653 fpr_test_value_str, 5654 fpr_limits_arr = [], 5655 turbo_classes_arr = [], 5656 fpr_final_data_str = class_data_str, 5657 is_turbo_classes_reflow_match_bool = false, 5658 is_turbo_classes_reflow_status_bool = Restive.store('rstv_turbo_classes_reflow_status_in') 5659 ; 5660 5661 //get the turbo_classes_reflow_limits values 5662 fpr_limits_arr = explode(',', options.turbo_classes_reflow_limits); 5663 fpr_limits_phone_int = parseInt(fpr_limits_arr[0]); 5664 fpr_limits_tablet_int = parseInt(fpr_limits_arr[1]); 5665 5666 //ensure is_mobile turbo_classes parameter 5667 opt_isset_is_mobile_bool = /is_mobile=/i.test(options.turbo_classes); 5668 switch(true) 5669 { 5670 case (opt_isset_is_mobile_bool): 5671 //iterate over all provided turbo_classes 5672 turbo_classes_arr = explode(',', options.turbo_classes); 5673 for(var j = 0; j < count(turbo_classes_arr); j++) 5674 { 5675 fpr_test_key_str = getValueAfterExplode(turbo_classes_arr[j], "=", 0); 5676 fpr_test_value_str = getValueAfterExplode(turbo_classes_arr[j], "=", 1); 5677 5678 switch(true) 5679 { 5680 case (fpr_test_key_str == 'is_mobile'): 5681 fpr_span_range_tomobile_bool = (options.force_dip == true) ? Restive.cSpan(0, fpr_limits_tablet_int): Restive.vSpan(0, fpr_limits_tablet_int); 5682 5683 switch(true) 5684 { 5685 case (fpr_span_range_tomobile_bool): 5686 5687 fpr_final_data_str += ' '+fpr_test_value_str; 5688 is_turbo_classes_reflow_match_bool = true; 5689 switch(true) 5690 { 5691 case (!is_turbo_classes_reflow_status_bool && is_turbo_classes_reflow_match_bool): 5692 Restive.store('rstv_turbo_classes_reflow_status_in', true); 5693 5694 //add callback 5695 methods._callbackManager(options, ['turboclassesreflow', 'in']); 5696 5697 break; 5698 } 5699 5700 break; 5701 5702 default: 5703 is_turbo_classes_reflow_match_bool = false;
5704 switch(true) 5705 { 5706 case (is_turbo_classes_reflow_status_bool && !is_turbo_classes_reflow_match_bool): 5707 Restive.store('rstv_turbo_classes_reflow_status_in', false); 5708 5709 //add callback 5710 methods._callbackManager(options, ['turboclassesreflow', 'out']); 5711 5712 break; 5713 } 5714 } 5715 5716 break; 5717 } 5718 5719 switch(true) 5720 { 5721 case (fpr_test_key_str == 'is_phone'): 5722 fpr_span_range_tophone_bool = (options.force_dip == true) ? Restive.cSpan(0, fpr_limits_phone_int): Restive.vSpan(0, fpr_limits_phone_int); 5723 5724 fpr_final_data_str = (fpr_span_range_tophone_bool) ? fpr_final_data_str + ' ' + fpr_test_value_str: fpr_final_data_str; 5725 break; 5726 } 5727 5728 switch(true) 5729 { 5730 case (fpr_test_key_str == 'is_tablet'): 5731 fpr_limits_bp_btw_phone_and_tablet_int = fpr_limits_phone_int + 1; 5732 fpr_span_range_totablet_bool = (options.force_dip == true) ? Restive.cSpan(fpr_limits_bp_btw_phone_and_tablet_int, fpr_limits_tablet_int): Restive.vSpan(fpr_limits_bp_btw_phone_and_tablet_int, fpr_limits_tablet_int); 5733 fpr_final_data_str = (fpr_span_range_totablet_bool) ? fpr_final_data_str + ' ' + fpr_test_value_str: fpr_final_data_str; 5734 5735 break; 5736 } 5737 5738 } 5739 5740 return fpr_final_data_str; 5741 break; 5742 } 5743 break; 5744 } 5745 break; 5746 } 5747 5748 //Restive.store('rstv_turbo_classes_reflow_status_in', false); 5749 return class_data_str; 5750 }, 5751 _addTurboClasses: function(class_data_str, opt_turbo_classes){ 5752 //return class name only if power classes info is invalid or empty 5753 switch(true) 5754 { 5755 case (!isString(opt_turbo_classes) || opt_turbo_classes == ''): 5756 return class_data_str; 5757 break; 5758 } 5759 5760 //Define variables 5761 var opt_pc_arr = [], 5762 pc_key_str, 5763 pc_value_str, 5764 pc_temp_arr = [], 5765 pc_temp_str = '', 5766 pc_final_str = '', 5767 pc_func_arr = {'is_mobile': 'isMobile', 'is_non_mobile': 'isNonMobile', 'is_retina': 'isRetina', 'is_phone': 'isPhone', 'is_tablet': 'isTablet', 'is_tv': 'isTV', 'is_pc': 'isPC', 'is_portrait': 'isPortrait', 'is_landscape': 'isLandscape'}, 5768 pc_func_name_str, 5769 pc_func_res 5770 ; 5771 5772 opt_pc_arr = explode(',', opt_turbo_classes); 5773 for(var i = 0; i < count(opt_pc_arr); i++) 5774 { 5775 pc_key_str = getValueAfterExplode(opt_pc_arr[i], "=", 0); 5776 pc_value_str = getValueAfterExplode(opt_pc_arr[i], "=", 1); 5777 5778 pc_func_name_str = pc_func_arr[pc_key_str]; 5779 switch(true) 5780 { 5781 case (isString(pc_func_name_str) && pc_func_name_str != ''): 5782 pc_func_res = methods[pc_func_name_str]; 5783 switch(true) 5784 { 5785 case (pc_func_res()): 5786 pc_temp_arr.push(pc_value_str); 5787 break; 5788 } 5789 break; 5790 } 5791 } 5792 5793 pc_temp_str = implode(' ', pc_temp_arr); 5794 pc_final_str = (pc_temp_str != '') ? pc_temp_str+' '+class_data_str : class_data_str; 5795 return pc_final_str; 5796 }, 5797 setElementDOM: function(elem, elem_set_str, options){ 5798 var data_key_str = md5(getSelector(elem)), 5799 ds_elem_set_class_name_str = "rstv_bpm_class_"+data_key_str, 5800 ds_elem_set_str, 5801 init_addclass_bool = Restive.store("rstv_bpm_addclass_init") 5802 ; 5803 5804 ds_elem_set_str = (isString(Restive.store(ds_elem_set_class_name_str)) && Restive.store(ds_elem_set_class_name_str) != '') ? Restive.store(ds_elem_set_class_name_str): ''; 5805 5806 switch(true) 5807 {
5808 case (ds_elem_set_str != elem_set_str || init_addclass_bool == false): 5809 switch(true) 5810 { 5811 case (ds_elem_set_str != ''): 5812 elem.removeClass(ds_elem_set_str).addClass(elem_set_str); 5813 methods._callbackManager(options, ['removeclass', ''+ds_elem_set_str+'']); 5814 break; 5815 5816 default: 5817 elem.addClass(elem_set_str); 5818 } 5819 5820 Restive.store(ds_elem_set_class_name_str, elem_set_str); 5821 methods._callbackManager(options, ['addclass', ''+elem_set_str+'']); 5822 5823 Restive.store("rstv_bpm_addclass_init", true); 5824 break; 5825 } 5826 }, 5827 unsetElementDOM: function(elem, options){ 5828 var data_key_str = md5(getSelector(elem)), 5829 ds_elem_set_class_name_str = "rstv_bpm_class_"+data_key_str, 5830 ds_elem_set_str; 5831 5832 ds_elem_set_str = (isString(Restive.store(ds_elem_set_class_name_str)) && Restive.store(ds_elem_set_class_name_str) != '') ? Restive.store(ds_elem_set_class_name_str): ''; 5833 5834 elem.removeClass(ds_elem_set_str); 5835 methods._callbackManager(options, ['removeclass', ''+ds_elem_set_str+'']); 5836 }, 5837 _extVarTracker: function($track_name_str, $track_value_str) 5838 { 5839 var myArgs = Array.prototype.slice.call(arguments); 5840 var store_type_str = (isString(myArgs[2]) && myArgs[2] != "") ? myArgs[2] : 'ck'; 5841 var unique_bool = (isBool(myArgs[3])) ? myArgs[3]: false; 5842 var expires = (isNumber(myArgs[4]) || isString(myArgs[4])) ? parseInt(myArgs[4]): ''; 5843 var reverse_order_bool = (isBool(myArgs[5])) ? myArgs[5]: true; 5844 var delim_str = (isString(myArgs[6]) && myArgs[6] != "") ? myArgs[6]: '-!'; 5845 var data_count_int = (isNumber(myArgs[7]) || isString(myArgs[7])) ? parseInt(myArgs[7]): 80; 5846 5847 return Restive.storeVarTracker($track_name_str, $track_value_str, store_type_str, unique_bool, expires, reverse_order_bool, delim_str, data_count_int); 5848 }, 5849 _multiConstructorSelectPos: function(){ 5850 var bpm_val_str = Restive.store("rstv_cache_bpm"), 5851 bpm_val_arr = explode("-!", bpm_val_str), 5852 bpm_val_temp_str, 5853 bpm_idx_int = parseInt(Restive.store("rstv_multi_bpm_idx")) 5854 ; 5855 5856 bpm_val_temp_str = implode("", bpm_val_arr); 5857 5858 /** 5859 * 1. If only one hit is recorded, get it's position 5860 * 2. If all misses, get the last position i.e. length of string 5861 * 3. If more than one hit, get the value for the best match previously calculated 5862 */ 5863 var sel_constructor_pos, 5864 sel_constructor_pos_1, 5865 pattern_1 = new RegExp("^[^h]*h[^h]*$", "gi"), 5866 pattern_2 = new RegExp("^m+$", "gi"); 5867 5868 switch(true) 5869 { 5870 case (pattern_1.test(bpm_val_temp_str)): 5871 //1 5872 sel_constructor_pos = strrpos(bpm_val_temp_str, 'h'); 5873 break; 5874 5875 case (pattern_2.test(bpm_val_temp_str)): 5876 //2 5877 Restive.store("rstv_cache_bpm_all_miss", true, '', {expires: 2000}); 5878 sel_constructor_pos = strrpos(bpm_val_temp_str, 'm'); 5879 break; 5880 5881 case(substr_count(bpm_val_temp_str, "h") > 1): 5882 //3 5883 sel_constructor_pos = bpm_idx_int - 1; 5884 break; 5885 } 5886 sel_constructor_pos_1 = sel_constructor_pos + 1; 5887 Restive.store("rstv_multi_bpm_idx", sel_constructor_pos_1); 5888 5889 return sel_constructor_pos; 5890 },
5891 _multiConstructorManageEvents: function(sel_constructor_pos){ 5892 //Remove any events previously attached 5893 $(window).off('resize'); 5894 5895 //Manage Viewport Monitoring and Callbacks 5896 var $sel_pos_final_int = parseInt(sel_constructor_pos) + 1, 5897 $breakpoints_arr = window.parent.rstv_store.main["rstv_breakpoints_"+$sel_pos_final_int], 5898 $this = window.parent.rstv_store.main["rstv_this_"+$sel_pos_final_int], 5899 $options = window.parent.rstv_store.main["rstv_options_"+$sel_pos_final_int], 5900 $rstv_core_info_arr = window.parent.rstv_store.main["rstv_core_info_"+$sel_pos_final_int] 5901 ; 5902 5903 switch(true) 5904 { 5905 case (Restive.store("rstv_resp_basis_viewport_init")): 5906 methods._viewportMonitor($breakpoints_arr, $this, $options, $rstv_core_info_arr); 5907 methods._callbackManager($options, ['ready', 'init']); 5908 break; 5909 } 5910 }, 5911 _multiConstructorFinalize: function(){ 5912 5913 var sel_constructor_pos = methods._multiConstructorSelectPos(); 5914 5915 //Redo event handlers 5916 methods._multiConstructorManageEvents(sel_constructor_pos); 5917 5918 /** 5919 * Set Breakpoint Match Cache Lock 5920 * This marks that a Breakpoint Match has been determined (i.e. hit or miss) and as such this result should be stored and reused 5921 * NOTE: Only used in Multi-Constructor Operations 5922 */ 5923 Restive.store("rstv_cache_bpm_lock", true); 5924 5925 //Reset some local storage variables 5926 Restive.store("rstv_cache_req", null); 5927 Restive.store("rstv_multi_count", null); 5928 }, 5929 _multiConstructorStart: function(){ 5930 Restive.store("rstv_multi_count", 0); //counts the number of multi-constructor operations 5931 Restive.store("rstv_multi_start", true); 5932 Restive.store("rstv_multi_abort_1", false); 5933 Restive.store("rstv_multi_abort_2", false); 5934 5935 //set some expiring counters 5936 Restive.store("rstv_bpm_h_counter", 1, '', {expires: 1000}); 5937 Restive.store("rstv_bpm_m_counter", 1, '', {expires: 1000}); 5938 5939 //set some persistent counters 5940 switch(true) 5941 { 5942 case (!Restive.isStorageValueSet("rstv_multi_start_count")): 5943 Restive.store("rstv_multi_start_count", 1); 5944 Restive.store("rstv_multi_end", false); 5945 break; 5946 5947 default: 5948 Restive.incrementStorageValue("rstv_multi_start_count"); 5949 } 5950 }, 5951 _multiConstructorManager: function(){ 5952 var is_multi_start_bool = Restive.store("rstv_multi_start"), 5953 is_multi_end_bool = Restive.store("rstv_multi_end"), 5954 rstv_count_int = parseInt(Restive.store("rstv_multi_count")), 5955 rstv_multi_start_count_int = parseInt(Restive.store("rstv_multi_start_count")) 5956 ; 5957 5958 /** 5959 * Check if Restive.JS Constructor has been called multiple times 5960 */ 5961 switch(true) 5962 { 5963 case (rstv_count_int > 1): 5964 //Signal abort if startMulti() method call not used 5965 switch(true) 5966 { 5967 case (is_multi_start_bool === false): 5968 Restive.store("rstv_multi_abort_1", true); 5969 break; 5970 } 5971 break; 5972 } 5973 5974 /** 5975 * Check if Restive.JS Constructor has been called multiple times and has not been finalized properly with endMulti() method 5976 */ 5977 switch(true) 5978 { 5979 case (rstv_multi_start_count_int > 1 && is_multi_end_bool === false): 5980 Restive.store("rstv_multi_abort_2", true); 5981 break; 5982 } 5983 methods._URLMonitor(); 5984 }, 5985 _multiConstructorCounter: function(){ 5986 Restive.incrementStorageValue("rstv_multi_count"); 5987 }, 5988 _multiConstructorEnd: function(){ 5989 //reset stored variables 5990 Restive.store("rstv_multi_start_count", 0); 5991 Restive.store("rstv_multi_end", true); 5992 5993 //finalize multi constructor operations 5994 methods._multiConstructorFinalize(); 5995 }, 5996 getUserAgent: function (){ 5997 return Restive.getUserAgent(); 5998 }, 5999 getPlatform: function (){ 6000 return Restive.getPlatform(); 6001 }, 6002 getFormFactor: function(){ 6003 return Restive.getFormFactor(); 6004 }, 6005 getOrientation: function(){ 6006 return Restive.getOrientation(); 6007 }, 6008 getResolution: function(){ 6009 return Restive.getResolution(); 6010 }, 6011 getPixelRatio: function(pxl_ratio){ 6012 return Restive.getPixelRatio(pxl_ratio); 6013 }, 6014 getViewportW: function(){ 6015 return Restive.viewportW(); 6016 }, 6017 getViewportH: function(){ 6018 return Restive.viewportH(); 6019 }, 6020 getScreenW: function(){ 6021 return Restive.screenW(); 6022 }, 6023 getScreenH: function(){ 6024 return Restive.screenH(); 6025 }, 6026 getPixelW: function(){ 6027 return Restive.pixelW(); 6028 }, 6029 getPixelH: function(){ 6030 return Restive.pixelH(); 6031 }, 6032 isRetina: function(){ 6033 return Restive.isRetina(); 6034 }, 6035 isMobile: function(){ 6036 return Restive.isMobile(); 6037 }, 6038 isNonMobile: function(){ 6039 return Restive.isNonMobile(); 6040 }, 6041 isPhone: function(){ 6042 return Restive.isPhone(); 6043 }, 6044 isTablet: function(){ 6045 return Restive.isTablet(); 6046 }, 6047 isTV: function(){ 6048 return Restive.isTV(); 6049 }, 6050 isPC: function(){ 6051 return Restive.isPC(); 6052 }, 6053 isIOS: function(){ 6054 return Restive.isIOS(); 6055 }, 6056 isApple: function(){ 6057 return Restive.isApple(); 6058 }, 6059 isAndroid: function(){ 6060 return Restive.isAndroid(); 6061 }, 6062 isSymbian: function(){ 6063 return Restive.isSymbian(); 6064 }, 6065 isBlackberry: function(){ 6066 return Restive.isBlackberry(); 6067 }, 6068 isWindows: function(){ 6069 return Restive.isWindows(); 6070 }, 6071 isWindowsPhone: function(){ 6072 return Restive.isWindowsPhone(); 6073 }, 6074 isPortrait: function(){ 6075 return Restive.isPortrait(); 6076 }, 6077 isLandscape: function(){ 6078 return Restive.isLandscape(); 6079 } 6080 }; 6081 6082 /** 6083 * Plugin Initialize 6084 */ 6085 $.fn.restive = function(args){ 6086 6087 if ( methods[args] ) 6088 { 6089 //execute JQuery Plugin Method 6090 return methods[ args ].apply( this, Array.prototype.slice.call( arguments, 1 )); 6091 } 6092 else if ( typeof args === 'object' || ! args ) 6093 { 6094 //Process JQuery Plugin Options 6095 var opts = $.extend({}, $.fn.restive.defaults, args); 6096 var new_args = new Array(opts); 6097 return methods.init.apply( this, new_args ); 6098 } 6099 else 6100 { 6101 $.error( 'Method ' + args + ' does not exist on Restive.JS' ); 6102 } 6103 }; 6104 6105 /** 6106 * Plugin Defaults 6107 */ 6108 $.fn.restive.defaults = { 6109 breakpoints: [], //the breakpoints 6110 classes: [], //the corresponding classes 6111 anchor: 'window', //the basis for responsiveness 6112 anchor_e_df: 'w', //the dimension format for element-value anchor operations 6113 platform: 'all', //all, ios, android, symbian, blackberry, windows 6114 formfactor: 'all', //all, pc, tv, tablet, phone 6115 turbo_classes: '', //special class-based functionality 6116 turbo_classes_reflow: false, //this will apply specific turbo_classes based on limit settings 6117 turbo_classes_reflow_limits: '480,960', //defines thresholds for turbo_classes_reflow option 6118 force_dip: false, //force breakpoints to use device-independent pixels 6119 onReady: function(){}, 6120 onResize: function(){}, 6121 onRotate: function(){}, 6122 onRotateToP: function(){}, 6123 onRotateToL: function(){}, 6124 onPortrait: function(){}, 6125 onLandscape: function(){}, 6126 onRetina: function(){}, 6127 onPhone: function(){}, 6128 onTablet: function(){}, 6129 onPC: function(){}, 6130 onTV: function(){}, 6131 onIOS: function(){}, 6132 onAndroid: function(){}, 6133 onSymbian: function(){}, 6134 onBlackberry: function(){}, 6135 onWindows: function(){}, 6136 onWindowsPhone: function(){}, 6137 onMobile: function(){}, 6138 onNonMobile: function(){}, 6139 onTurboClassReflow: function(){}, 6140 onTurboClassReflowIn: function(){}, 6141 onTurboClassReflowOut: function(){}, 6142 onAddClass: function(){}, 6143 onRemoveClass: function(){} 6144 }; 6145 6146 /** 6147 * Plugin Methods 6148 */ 6149 var D = $.restive = function(){}; 6150 $.extend(D, { 6151 getUserAgent: function(){ 6152 return methods.getUserAgent(); 6153 }, 6154 getPlatform: function(){ 6155 return methods.getPlatform(); 6156 }, 6157 getFormFactor: function(){ 6158 return methods.getFormFactor(); 6159 }, 6160 getOrientation: function(){ 6161 return methods.getOrientation(); 6162 }, 6163 getResolution: function(){ 6164 return methods.getResolution(); 6165 }, 6166 getPixelRatio: function(pxl_ratio){ 6167 return methods.getPixelRatio(pxl_ratio); 6168 }, 6169 getViewportW: function(){ 6170 return methods.getViewportW(); 6171 }, 6172 getViewportH: function(){ 6173 return methods.getViewportH(); 6174 }, 6175 getScreenW: function(){ 6176 return methods.getScreenW(); 6177 }, 6178 getScreenH: function(){ 6179 return methods.getScreenH(); 6180 }, 6181 getPixelW: function(){ 6182 return methods.getPixelW(); 6183 }, 6184 getPixelH: function(){ 6185 return methods.getPixelH(); 6186 }, 6187 isRetina: function(){ 6188 return methods.isRetina(); 6189 }, 6190 isMobile: function(){ 6191 return methods.isMobile(); 6192 }, 6193 isNonMobile: function(){ 6194 return methods.isNonMobile(); 6195 }, 6196 isPhone: function(){ 6197 return methods.isPhone(); 6198 }, 6199 isTablet: function(){ 6200 return methods.isTablet(); 6201 }, 6202 isTV: function(){ 6203 return methods.isTV(); 6204 }, 6205 isPC: function(){ 6206 return methods.isPC(); 6207 }, 6208 isIOS: function(){ 6209 return methods.isIOS(); 6210 }, 6211 isApple: function(){ 6212 return methods.isIOS(); 6213 }, 6214 isAndroid: function(){ 6215 return methods.isAndroid(); 6216 }, 6217 isSymbian: function(){ 6218 return methods.isSymbian(); 6219 }, 6220 isBlackberry: function(){ 6221 return methods.isBlackberry(); 6222 }, 6223 isWindows: function(){ 6224 return methods.isWindows(); 6225 }, 6226 isWindowsPhone: function(){ 6227 return methods.isWindowsPhone(); 6228 }, 6229 isPortrait: function(){ 6230 return methods.isPortrait(); 6231 }, 6232 isLandscape: function(){ 6233 return methods.isLandscape(); 6234 }, 6235 startMulti: function(){ 6236 methods._multiConstructorStart(); 6237 }, 6238 endMulti: function(){ 6239 methods._multiConstructorEnd(); 6240 } 6241 }); 6242 6243}(window, document, jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.