1/**********************************************************************************\ 2 * Set of common java helpers. 3 * 4 * The MIT License 5 * 6 * Copyright (c) 2008 Victor Denisenkov aka Mr.V!T 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy of 9 * this software and associated documentation files (the "Software"), to deal in 10 * the Software without restriction, including without limitation the rights to 11 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 * the Software, and to permit persons to whom the Software is furnished to do so, 13 * subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in all 16 * copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * @package vit-lib 26 * @author Victor Denisenkov aka Mr.V!T 27 * @version 1.0 28\**********************************************************************************/ 29 30/** //** ----= escapeHtmlTags =----------------------------------------------\**//** \ 31* 32* Converts common HTML chars into entities. 33* 34* @param string str - HTML code to convert. 35* @return string - Escaped HTML. 36* 37\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 38var escapeHtmlTags_chars = { 39 '&' : '&', 40 '<' : '<', 41 '>' : '>', 42 '"' : '"', 43 "'" : ''' 44} //OBJECT escapeHtmlTags_chars 45function escapeHtmlTags(str) { 46 47 //If smth wrong given, just returning it back 48 if ( typeof(str) !== 'string' ) return str; 49 50 return str.replace(/['"&<>]/g, function (c) { 51 return escapeHtmlTags_chars[c] || c; 52 }); //FUNC string.replace.callback 53} //FUNC escapeHtmlTags 54 55function decodeEntities ($str) { 56 57 for ( var $i in escapeHtmlTags_chars ) 58 $str = $str.replace(escapeHtmlTags_chars[$i], $i); 59 60 return $str; 61} //FUNC decodeEntities 62 63function getUrlHash () { 64 return location.hash.replace(/^#/, ''); 65} //FUNC getUrlHash 66 67/** //** ----= fullURL =----------------------------------------------------------------------------------------------\**//** \ 68* 69* Takes any URL and makes it full URL adding host if necesarry. 70* Uses window.location for host value and autodetected scheme. 71* 72* @param string $url - Url to check. 73* @param bool [$https] - Create https url. 74* 75* @return string - Full URL 76* 77\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 78function fullURL ($url, $https) { 79 80 // Preparing desired shceme 81 if ( isUndefined($https) ) 82 $scheme = window.location.protocol+'//'; 83 else 84 $scheme = ($https) ? 'https://' : 'http://' ; 85 86 // Checking for sceme on string begining 87 if ( $url.indexOf($scheme) !== 0 ) 88 $url = $scheme+window.location.host+'/'+$url.ltrim(' \/'); 89 90 return $url; 91} //FUNC fullURL 92 93/** //** ----= regexMatchAll =----------------------------------------------------------------------------------------------\**//** \ 94* 95* Executes regex on string multiple times, untill no further matches found. Returns array of matches. 96* Supports PREG_SET_ORDER and PREG_PATTERN_ORDER similar to php's preg_match_all. 97* 98* @param string $str - String to match. 99* @param regex $regex - Regular expression. 100* 101* @return array - All matches as array. 102* 103\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 104var PREG_PATTERN_ORDER = 1; 105var PREG_SET_ORDER = 2; 106function regexMatchAll ($regex, $str, $order) { 107 108 // Order by default is PREG_PATTERN_ORDER to mimic php 109 $order = $order || PREG_PATTERN_ORDER; 110 111 var $match; 112 var $res = []; 113 114 // Looping through results 115 // This will create results as for PREG_SET_ORDER flag 116 while ( $match = $regex.exec($str) ) { 117 118 // Removing some trash, to end up with true array 119 // It's important to allow [for var in array] code. 120 delete($match['index']); 121 delete($match['input']); 122 123 $res.push($match); 124 } //WHILE matching 125 126 // Done if no need to reorder 127 if ( $order === PREG_SET_ORDER ) 128 return $res; 129 130 // Reordering in new array if necessary 131 var $tmp = []; 132 for ( var $i in $res ) 133 for ( var $j in $res[$i] ) 134 // Pushing matches if subset exists, or creating new one if not 135 $tmp[$j] ? $tmp[$j].push($res[$i][$j]) : $tmp[$j] = [$res[$i][$j]]; 136 137 return $tmp; 138} //FUNC regexMatchAll 139 140if ( isUndefined( jQuery.fn.disableSelection ) ) { 141 142jQuery.fn.disableSelection = function() { 143 // Preparing event name, to allow selectstart or fallback to mousedown 144 var $eventName = ( isUndefined(this.selectstart) ? 'mousedown' : 'selectstart' ) + '.vDisableSelection'; 145 146 this.on( $eventName, function( $e ) { 147 $e.preventDefault(); 148 }); //FUNC onMouseDown 149 150} //FUNC disableSelection 151 152jQuery.fn.enableSelection = function() { 153 this.off('.vDisableSelection'); 154} //FUNC enableSelection 155 156} //IF no disable seleciton 157 158function isDebug () { 159 160 if ( !isEmpty( getCookie('debug') ) ) 161 return true; 162 163 if ( location.search.indexOf('debug=1') != -1 ) 164 return true; 165 166 return false; 167} //FUNC isDebug 168 169function isIframe () { 170 try { 171 return window.self !== window.top; 172 } catch (e) { 173 return true; 174 } 175} //FUNC isIframe 176 177function implode(glue, obj) { 178 179 // Faster will be call .join if array given 180 181 if ( obj instanceof Array ) 182 return obj.join(glue); 183 184 // Or doing manually for object 185 186 var res = ''; 187 188 for ( var i in obj ) { 189 if ( res ) res += glue; 190 res += obj[i]; 191 } //FOR each property 192 193 return res; 194} //FUNC implode 195 196function ucfirst ($str) { 197 return $str && $str[0].toUpperCase() + $str.slice(1); 198} //FUNC ucfirst 199 200String.prototype.capitalize = function() { 201 return ucfirst(this); 202} //FUNC capitalize 203 204if ( !String.prototype.startsWith ) { 205String.prototype.startsWith = function ($needle) { 206 return this.lastIndexOf($needle, 0) === 0; 207}} //FUNC startsWith 208 209if ( !String.prototype.endsWith ) { 210String.prototype.endsWith = function ($needle) { 211 var $lastIndex = this.lastIndexOf($needle); 212 return ( $lastIndex != -1 ) && ( $lastIndex + $needle.length == this.length ); 213}} //FUNC endsWith 214 215function strRepeat ($str, $multiplier) { 216 217 if ( !$multiplier ) 218 return ''; 219 220 var $res = ''; 221 222 for ( var $i = 0; $i < $multiplier; $i++ ) { 223 $res += $str; 224 } //FOR multiple times 225 226 return $res; 227} //FUNC strRepeat 228 229function instanceName ($var) { 230 231 // Determining instance using basic Object.toString() 232 $res = Object.prototype.toString.call($var); 233 234 // Cutting usual [object ...] from it to get clean instance name 235 $res = $res.slice(8, -1); 236 237 return $res; 238} //FUNC instanceName 239var getClassOf = instanceName; 240 241function isClass ($var, $class) { 242 return getClassOf($var) === $class; 243} // FUNC isBool 244 245function isBool ($var) { 246 return typeof($var) == 'boolean'; 247} // FUNC isBool 248 249function isNumber ($var) { 250 return typeof($var) == 'number'; 251} //FUNC isNumber 252 253function isNumeric ($var) { 254 return $var !== '' && !isNaN($var) && isFinite($var); 255} //FUNC isNumeric 256 257function isInt ($var) { 258 return !isNaN($var) && (parseInt($var) == $var); 259} //FUNC isInt 260 261function isFloat ($var) { 262 return $var !== '' && !isNaN($var) && isFinite($var) && !isInt($var); 263} //FUNC isFloat 264 265function isArray ($var) { 266 return $var instanceof Array; 267} //FUNC isArray 268 269function isObject ($var, $orArray) { 270 271 // If not object - then false anyway
272 if ( typeof($var) != 'object' ) 273 return false; 274 275 // If arrays allowed - we have result already 276 if ( $orArray ) 277 return true; 278 279 // Now need to check if it is array 280 // Should not be array for strict check 281 return ( !isArray($var) ); 282 283} //FUNC isArray 284 285var isString = isStr; 286function isStr ($var) { 287 return typeof($var) == 'string'; 288} //FUNC isStr 289 290function isIn ($var, $values) { 291 return $values.indexOf($var) > -1; 292} //FUNC isIn 293 294// Global constant for undefined type checks 295var UNDEFINED = 'undefined'; 296 297function isUndefined($var) { 298 return $var === void 0; 299} //FUNC isUndefined 300 301function isDefined($var) { 302 return !isUndefined($var); 303} //FUNC isDefined 304 305function setDefault($var, $default) { 306 return isDefined($var)? $var : $default; 307} //FUNC isDefined 308 309var isset = isSet; 310function isSet ($var) { 311 return !isUndefined($var); 312} //FUNC isSet 313 314var empty = isEmpty; 315function isEmpty ($var) { 316 317 // Fastest way to test 318 if ( !$var ) 319 return true; 320 321 // '0' means empty too 322 if ( $var === '0' ) 323 return true; 324 325 // Extra test need only for objects, so if it's not object - no need to test more 326 if ( typeof($var) !== 'object' ) 327 return false; 328 329 // Testing array first (faster test) 330 if ( isArray($var) ) 331 return $var.length == 0; 332 333 // If still here - its object and need to loop through to check properties 334 // Any existing property ($i) means it's not empty 335 for ( var $i in $var ) 336 return false; 337 338 // If not triggered above - that's empty object 339 return true; 340} //FUNC isEmpty 341 342function asBool ($var) { 343 return !isEmpty($var); 344} //FUNC asBool 345 346function isNumber ($var) { 347 return typeof($var) == 'number'; 348} //FUNC isArray 349 350function isFunction ($var) { 351 return typeof($var) == 'function'; 352} //FUNC isArray 353 354function isScalar ($var, $ex) { 355 356 // Testing common scalar types 357 if ( (/boolean|number|string/).test(typeof($var)) ) 358 return true; 359 360 // Extra test assumes that NULL and undefined are scalars 361 if ( !$ex ) 362 return false; 363 364 if ( typeof($var) == 'undefined' || $var === null ) 365 return true; 366 367 return false; 368} //FUNC isScalar 369 370function isScalarArray ($var, $ex) { 371 372 if ( !isArray($var) ) 373 return false; 374 375 // If at least one array item is not scalar - that's not scalar array 376 for ( var $i = 0; $i < $var.length; $i++ ) 377 if ( !isScalar($var[$i], $ex) ) 378 return false; 379 380 return true; 381} //FUNC isScalar 382 383/** //** ----= arrayPath =--------------------------------------------------------------------------------------\**//** \ 384* 385* Traversing array using key paths. Allows to get or set values. 386* 387* @param array $array - Array to traverse. 388* @param mixed $path - Path to navigate. Either string or array. 389* E.g.: 'key1/key2/deepvalue' or ['key1', 'key2', 'deepvalue'] 390* @param mixed [$value] - Value to set for setter mode (if omited, will return value instead) 391* @param string [$divider] - Path divider (used only if path is given as string). 392* 393* @return mixed - Target value in getter mode, or new value in setter. 394* 395\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 396function arrayPath ($array, $path, $value, $divider) { 397 398 $divider = $divider || '/'; 399 400 // Checking for setter mode 401 var $isSetter = ( !isUndefined($value) ); 402 403 // Splitting path to individual keys 404 if ( !isArray($path) ) { 405 $path = $path.split($divider); 406 } //IF not array given 407 408 // Looping down to value in array 409 // Using refs for recurcive looping 410 // Thus saving parent for last step 411 var $var = $array; 412 var $parent = $array; 413 414 for ( var $i in $path ) { 415 416 $key = $path[$i]; 417 418 // In setter mode - need to make sure that var is array 419 // In getter mode - if var is already not array - that's null return 420 if ( !isObject($var) ) 421 if ( $isSetter ) 422 $var = []; 423 else 424 return; 425 426 // Checking for key presence 427 // In getter mode unexisting key results to NULL result 428 // In setter mode - path should be created 429 // This should be done priror next iteration to avoid source array altering 430 if ( isUndefined($var[$key]) ) 431 if ( $isSetter ) 432 $var[$key] = {}; 433 else 434 return; 435 436 // Saving ref for next iteration 437 $parent = $var; 438 $var = $var[$key]; 439 } //FOR each path key 440 441 // At this point ref points to end value 442 // Can set and return it 443 if ( $isSetter ) 444 $parent[$key] = $value; 445 446 return $var; 447} //FUNC arrayPath 448 449if ( !Object.keys ) { 450 Object.keys = function (obj) { 451 var keys = [], 452 k; 453 454 for ( k in obj ) 455 if ( Object.prototype.hasOwnProperty.call(obj, k) ) 456 keys.push(k); 457 458 return keys; 459 }; //FUNC keys 460} //IF Object have no keys method 461 462/** //** ----= objSize =----------------------------------------------------------------------------------------------\**//** \ 463* 464* Returns object properties count. Usefull as analog of [].length for data objects. 465* 466* @param object $obj - Object to count. 467* 468* @return int - Object "size". 469* 470\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 471function objSize ($obj) { 472 473 var $res = 0; 474 for ( $i in $obj) 475 if ( $obj.hasOwnProperty($i) ) 476 $res++; 477 478 return $res; 479} //FUNC objSize 480 481/** //** ----= objStep =----------------------------------------------------------------------------------------------\**//** \ 482* 483* Returns object key in "step" away from given key. 484* 485* @param object $obj - Object to search key in
486* @param $key $key - Key to step from 487* @param $step $step - Step to count from given key (can be negatve to count backwards) 488* 489* @return string - Found key, or FALSE if smth failed 490* 491\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 492function objStep ($obj, $key, $step) { 493 494 // Using array for indexing keys, and then searching keys in it 495 // In case smth goes wrong - FALSE is returned 496 497 var $idx = Object.keys($obj); 498 499 if ( $idx.length == 0 ) 500 return false; 501 502 var $i = $idx.indexOf($key); 503 504 if ( $i < 0 ) 505 return false; 506 507 // Stepping from key 508 $i += $step; 509 510 if ( $i < 0 || $i >= $idx.length ) 511 return false; 512 513 return $idx[$i]; 514} //FUNC objStep 515 516/** //** ----= objNext, objPrev =--------------------------------------------------------------------------------------\**//** \ 517* 518* Common use cases of objStep for searching next/prev keys in object 519* 520* @param object $obj - Object to search key in 521* @param $key $key - Key to step from 522* 523* @return string - Found key, or FALSE if smth failed 524* 525\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 526function objPrev ($obj, $key) { 527 return objStep($obj, $key, -1); 528} //FUNC objPrev 529function objNext ($obj, $key) { 530 return objStep($obj, $key, 1); 531} //FUNC objNext 532 533/** //** ----= objFirst, objLast =------------------------------------------------------------------------------\**//** \ 534* 535* Returns first/last object key. 536* 537* @param object $obj - Object to search key in 538* 539* @return string - Found key, or FALSE if smth failed 540* 541\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 542function objFirst ($obj) { 543 544 var $idx = Object.keys($obj); 545 546 if ( $idx.length == 0 ) 547 return false; 548 549 return $idx[0]; 550} //FUNC objFirst 551function objLast ($obj) { 552 553 var $idx = Object.keys($obj); 554 555 if ( $idx.length == 0 ) 556 return false; 557 558 return $idx[$idx.length-1]; 559} //FUNC objLast 560 561/** //** ----= isSame =----------------------------------------------------------------------------------------------\**//** \ 562* 563* Compares two objects given. Designed for data objects. 564* 565* @param object x, y - Objects to compare. 566* @param bool [oneway] - Set TRUE to test only by x values (i.e y can be bigger, in other words - if X is in Y) 567* @param bool [presort] - Set TRUE to presort incoming arrays. This may 568* be necessary if comparing arrys in order 569* independent way. Usefull for values lists. 570* 571\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 572function isSame (x, y, oneway, presort) { 573 574 // Fast check for nulls / empties 575 if ( !x || !y ) { 576 577 if ( !x && y ) return false; 578 if ( x && !y ) return false; 579 580 return true; 581 } //IF some is null or empty 582 583 // IF arrays come - first better check lengths 584 if ( x instanceof Array && y instanceof Array ) { 585 586 if ( x.length != y.length ) 587 return false; 588 589 if ( presort ) { 590 x.sort(); 591 y.sort(); 592 } //IF presort seet 593 594 } //IF arrays come 595 596 // First checking properties existance. 597 // After this check full comparasions will be done in opposite direction 598 599 if ( !oneway ) { 600 for ( var p in y ) { 601 if ( typeof(x[p]) == 'undefined') 602 return false; 603 } //FOR each property in y 604 } //IF not one way comparasion 605 606 // Type based checking, in opposite comparasion direction 607 for ( var p in x ) { 608 609 // Checking self properties in oppose object, jsut existance first 610 if ( typeof(y[p]) == 'undefined' ) 611 return false; 612 613 if ( x[p] ) { // Fast symantec check, everything that is logically FALSE - no need to check by type 614 615 switch( typeof(x[p]) ) { 616 617 case 'object' : 618 619 // Checking objects recursively 620 // This allows multidimensional objects checks, 621 // But can possibly hang browser. Normally will not. 622 // ToDo: prevent possible reqursions 623 if ( !isSame(x[p], y[p], oneway, presort) ) 624 return false; 625 626 break; 627
628 case 'function' : 629 630 // Of course toString is not best way to compare functions. 631 // But normally same named funcitons should have same source code, 632 // and it's anyway better and faster than to full syntax parsing. 633 // Fast toString comparation will work in most typical cases. 634 // Just don't use this function if U need to compare functions in objects so much!. 635 if ( this[p].toString() != x[p].toString() ) 636 return false; 637 638 break; 639 default: 640 641 // At last simple check that will usually used :). 642 if ( x[p] != y[p] ) 643 return false; 644 645 } //SWITCH type of x 646 647 } else { //IF is value 648 649 // Checking same property on other object 650 if ( y[p] ) 651 return false; 652 653 } //If false value 654 655 } //FOR each property in x 656 657 return true; 658} //FUNC isSame 659 660function isXHR2 () { 661 662 if ( !window.FormData ) 663 return false; 664 665 // Testing for XMLHttpRequest Level 2 666 var xhr = new XMLHttpRequest(); 667 if ( !xhr.upload ) 668 return false; 669 670 return true; 671} //FUNC isXHR2 672 673function isFilesAPI () { 674 675 if ( !isXHR2() ) 676 return false; 677 678 if ( !(window.File && window.FileList && window.FileReader) ) 679 return false; 680 681 return true; 682} //FUNC isFilesAPI 683 684function isIos () { 685 return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; 686} //FUNC isIos 687 688/** //** ----= isTouchScreen =--------------------------------------------------------------------------------------\**//** \ 689* 690* Tests if device is touch screen enabled device. 691* 692* @return bool - TRUE if device supports touchs screen. (i.e. pointer:coarse from css4 media queries.) 693* 694\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 695function isTouchScreen () { 696 697 var $res = 'ontouchstart' in document.documentElement; 698 699 return $res; 700} //FUNC isTouchScreen 701 702/** //** ----= isJQ =----------------------------------------------------------------------------------------------\**//** \ 703* 704* Tests if given object is jQuery element 705* 706* @param MIXED $val - Value to check. 707* 708* @return bool - Check result. 709* 710\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 711function isJQ ($val) { 712 713 // Empty value is not jQuery 714 if ( !$val ) 715 return false; 716 717 return ($val instanceof jQuery || $val.jquery); 718} //FUNC isJQ 719 720/** //** ----= _jq =----------------------------------------------------------------------------------------------\**//** \ 721* 722* Ensures that given parameter is valid jQuery object. Avoids jQuery object clone. 723* 724* @param MIXED $element - jQuery selector, DOM element or jQuery object. 725* @param MIXED [$context] - Valid jQuery context. 726* 727* @return object(jQuery) - jQuery object. 728* 729\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 730function _jq ($element, $context) { 731 732 if ( !isJQ($element) ) 733 return jQuery($element, $context); 734 735 return $element; 736} //FUNC _jq 737 738function formatFileSize (bytes) { 739 740 if ( !bytes ) return bytes; 741 742 var labels = ['b','Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb']; 743 var ex = Math.floor( Math.log(bytes) / Math.log(1024) ); 744 745 var res = bytes / Math.pow(1024, ex); 746 747 return res.toFixed(2) + ' ' + labels[ex]; 748} //FUNC formatFileSize 749 750/** //** ----= setObjectOptions =--------------------------------------------------------------------------------------\**//** \ 751* 752* Initiates object properties from given data object. Sets properties directly, without test if property really existed. 753* Essentially copies one object properties into another. 754* 755* @param object $object - Object to apply options to. 756* @param array $options - Options to set. 757* 758* @return object - Returns given object. 759* 760\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 761function setObjectOptions ($object, $options) { 762 763 $options = $options || {}; 764 765 // Looping through each option given and setting it as property 766 for ( var $opt in $options ) 767 $object[$opt] = $options[$opt]; 768 769 return $object; 770} //FUNC setObjectOptions 771 772/** //** ----= borderValue =--------------------------------------------------------------------------------------\**//** \ 773* 774* Ensures that given value is within bounds. 775* 776* @param MIXED $element - jQuery selector, DOM element or jQuery object. 777* @param MIXED [$context] - Valid jQuery context. 778* 779* @return object(jQuery) - jQuery object. 780* 781\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 782function borderValue ($value, $min, $max) { 783 784 if ( $value < $min ) 785 $value = $min; 786 787 if ( $value > $max ) 788 $value = $max; 789 790 return $value; 791} //FUNC borderValue 792 793/** //** ----= vEventObject =--------------------------------------------------------------------------------------\**//** \ 794* 795* Extends given object to accept events callbacks. Allows events registering and chain calling later. Callback will 796* run within object's context and accept parameters given to event trigger. 797* 798* @param array types - List of event types to create. 799* 800* @param object obj - Object to extend. 801* 802* @return object - Modified object. 803* 804\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 805function vEventObject (types, obj) { 806 807 obj = obj || {}; 808 809 // Creating callbacks storage in parent 810 if ( isEmpty(obj['__events']) ) 811 obj['__events'] = {}; 812 813// ---- BIND/RUNNER ---- 814 815 /** //** ----= _runevent =------------------------------------------------------------------------------\**//** \ 816 * 817 * For Internal Use. Event runner, used to call events, or set new ones (in case if callback function given). 818 * 819 * @param string type - Event type to use. 820 * 821 * @return MIXED - Mixed return. 822 * SELF - If setting event. 823 * bool - Boolean FALSE in even return - interrupts chain, and also is returned. 824 * TRUE is just returned. 825 * VOID - Other cases. 826 * 827 \**//** --------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 828 obj._runevent = function ( type, args ) { 829 830 // Setting callback if given as first argument 831 if ( args[0] && typeof(args[0]) == 'function' ) { 832 this.__events[type].push(args[0]); 833 return obj; 834 } //IF callback set 835 836 var res = false;
837 838 // If no callback given (getter mode) - running all calbacks of that type, cb should contain arguments then 839 for ( var func in this.__events[type] ) { 840 var eres = this.__events[type][func].apply(obj, args); 841 842 // False in result means even chain interruption, returning it to parent also 843 if ( eres === false ) 844 return false; 845 846 // True in one of events means smth for caller, we'll return it later 847 if ( eres === true ) 848 res = true; 849 850 } //FOR each callback 851 852 // If someone return true - we notify parent about, else - undefined return 853 if ( res ) 854 return res; 855 856 } //FUNC _runevent 857 858// ---- UNBIND ---- 859 860 /** //** ----= unbind =--------------------------------------------------------------------------------------\**//** \ 861 * 862 * Event remover. Unbings given event type, or given callback if specified. If no parameters specified - 863 * unbinding all events (usefull to get clean object). 864 * 865 * @param string [type] - Event type to unbind. 866 * @param function [fn] - Callback to unbind within type. 867 * 868 * @return SELF 869 * 870 \**//** --------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 871 obj.unbind = function (type, fn) { 872 873 var $this = this; 874 875 // Event clearing helper 876 function unbindEvent (e) { 877 878 // Deleting only speciefic events, skipping body ones 879 for ( var i = 0; i < e.length; i++ ) { 880 881 // Skipping body ones 882 if ( e[i]._bodyeventfunction ) continue; 883 884 // Skipping all non given (if some given) 885 if ( fn && e[i] !== fn ) continue; 886 887 e.splice(i, 1); 888 889 } //FOR each callback 890 891 }; //FUNC unbindEvent 892 893 // If type specified - cleaning only that type, otherwise - all of them 894 if ( type ) 895 unbindEvent(this.__events[type]); 896 else 897 for ( var i in this.__events ) 898 unbindEvent(this.__events[i]); 899 900 return obj; 901 902 }; //FUNC obj.unbind 903 904// ---- SHORTCUTS ---- 905 906 // Creating shortcut for each event 907 for ( var ev in types ) { 908 909 var type = types[ev]; 910 911 // For each type we have own array with callbacks 912 if ( isEmpty(obj.__events[type]) ) 913 obj.__events[type] = []; 914 915 // Existing event functions became first events 916 if ( isFunction(obj[type]) ) { 917 918 // Skipping event functions 919 if ( obj[type]._runeventfunction ) 920 continue; 921 else { 922 // Marking as body function - those can't be unbind 923 obj[type]._bodyeventfunction = 1; 924 obj._runevent(type, [obj[type]]); 925 } //IF own function 926 927 } //IF function already exists in body 928 929 // Creating event trigger function in parent for each type 930 obj[type] = function (t) { return function () { return this._runevent(t, arguments);};}(type); 931 932 // Marking as event function to recognise later 933 obj[type]._runeventfunction = 1; 934 935 } //FOR each type 936 937 return obj; 938} //FUNC vEventObject 939 940/** //** ----= reloadCSS =--------------------------------------\**//** \ 941* 942* Forces browser to reload CSS sheets dynamically. 943* 944* @param string url - CSS sheet URL. 945* 946\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 947function reloadCSS (url) { 948 949 var salt = randomString(); 950 var salt_url = url + '?reload=' + salt; 951 952 var new_sheet = jQuery('<link rel="stylesheet" href="' + salt_url + '" type="text/css" />'); 953 var old_sheet = jQuery('LINK[href*="' + url + '"]'); 954 955 if ( document.createStyleSheet ) { 956 document.createStyleSheet(salt_url); 957 } else { //IF IE 958 jQuery('HEAD').append( new_sheet ); 959 } //IF normal browsers 960 961 // Removing old sheet if present. 962 setTimeout( function () { old_sheet.remove(); }, 1000); 963 964} //FUNC reloadCSS 965 966/** //** ----= countElements =----------------------------------------------\**//** \ 967* 968* Returns overal page's elements count. Usefull for optimization. 969* 970* @param jQuery el - Count elements within give element. 971* 972* @return int - Elements count. 973* 974\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 975function countElements (el) { 976 977 if ( !el ) 978 return document.getElementsByTagName('*').length; 979 980 return jQuery(el).find('*').length; 981} //FUNC countElements 982 983function randomString(type, length) { 984 985 if ( !type ) type = 'alnum'; 986 if ( !length ) length = 8; 987 988 var chars = ''; 989 990 switch ( type.toLowerCase() ) { 991 case 'alnum' : chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 992 break; 993 case 'alpha' : chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 994 break; 995 case 'hex' : chars = '0123456789ABCDEF'; 996 break; 997 case 'caps' : chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 998 break; 999 case 'capnum' : chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; 1000 break; 1001 case 'numeric' : chars = '0123456789'; 1002 break; 1003 case 'nozero' : chars = '123456789'; 1004 break; 1005 case 'keyb' : chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ :;,.\'"\|/?[]{}()<>~`!@#$%^&*-=_+'; 1006 break; 1007 1008 default : chars = type; 1009 } //SWITCH $type 1010 1011 if ( !chars ) return ''; 1012 1013 var str = ''; 1014 1015 for (var i = 0; i < length; i++) { 1016 var rnum = Math.floor(Math.random() * chars.length); 1017 str += chars.substring(rnum, rnum + 1); 1018 } 1019 1020 return str; 1021} //FUNC randomString 1022 1023/** //** ----= newSN =---------------------------------------------------------------------------------------------\**//** \ 1024* 1025* Generates new random SN. SN is usually capnum unique string of 16 chars, starting from give char. 1026* 1027* @param string [$prefix] - Limit SN to start only with this char. 1028* @param string [$length] - SN length, 16 by default. 1029*
1030* @return string - Random SN string. 1031* 1032\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 1033function newSN ($prefix, $length) { 1034 1035 $prefix = $prefix || ''; 1036 $length = $length || 16; 1037 1038 return ($prefix + randomString('capnum', $length)).substring(0, $length); 1039} //FUNC newSN 1040 1041/** //** ----= fileName =----------------------------------------------\**//** \ 1042* 1043* Extracts file name from full path. 1044* 1045* @param string path - Full path and file name. 1046* @return string - File name. 1047* 1048\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1049function fileName (path) { 1050 if ( !path ) return ''; 1051 return path.replace(/^.*\\/, ''); 1052} //FUNC fileName 1053 1054/** //** ----= fileExt =----------------------------------------------\**//** \ 1055* 1056* Extracts file extension from file name. 1057* 1058* @param string file - Full path and file name. 1059* @return string - File name. 1060* 1061\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1062function fileExt (file) { 1063 var tmp = file.lastIndexOf('.'); 1064 1065 if ( !tmp ) return false; 1066 1067 return file.substr(tmp+1, file.length); 1068} //FUNC fileExt 1069 1070/*--------------------------------------------------------------------------------*\ 1071| Humanize 1072|---------------------------------------------------------------------------------- 1073| Ensures that number will be displayed as normal value (fix for JavaScript numbers) 1074| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1075| Params: 1076| [base] int - Base value to round value to. 1077| Return: 1078| string - Human looking number rounded to certain base. 1079\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1080Number.prototype.Humanize = Number.prototype.humanize = function (base) { 1081 1082 base = base || 10; 1083 1084 var tmp = this.toFixed(base) + ''; 1085 return tmp; 1086 1087 var res = tmp.rtrim('0.'); 1088 if ( res == '' ) res = '0'; 1089 1090 return res; 1091} //FUNC Humanize 1092 1093/*--------------------------------------------------------------------------------*\ 1094| indexOf 1095|---------------------------------------------------------------------------------- 1096| Fixes indexOf for IE6. 1097| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1098| Params: 1099| obj MIXED - Item to search. 1100| fromIndex integer - Search starting from index. 1101| Return: 1102| integer - Item position in array, or -1 if not found. 1103\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1104/**/ 1105if ( !Array.prototype.indexOf ) 1106Array.prototype.indexOf = function (obj, fromIndex) { 1107 1108 if ( !fromIndex ) fromIndex = 0; 1109 1110 for ( var i in this ) 1111 if ( this[i] === obj ) return i; 1112 1113 return -1; 1114} //FUNC indexOf 1115/**/ 1116 1117/*--------------------------------------------------------------------------------*\ 1118| arrayJoin 1119|---------------------------------------------------------------------------------- 1120| Extended join for arrays. 1121| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1122| Params: 1123| array array - Array to process. 1124| separator string - String to use as separator. 1125| include_keys bool - Set TRUE to encode keys in result string. 1126| Return: 1127| string - Array as string. 1128\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1129function arrayJoin (array, separator, include_keys) { 1130 1131 if ( !separator ) separator = ','; 1132 1133 var res = ''; 1134 1135 var j = 0; 1136 1137 for ( var i in array ) { 1138 1139 if ( typeof(array[i]) == 'function' ) continue; 1140 1141 if ( res ) res += separator; 1142 1143 if ( include_keys ) { 1144 1145 if ( i != j ) 1146 res += i + ' = '; 1147 1148 } //IF need to include keys 1149 1150 res += array[i]; 1151 j++; 1152 1153 } //FOR each item 1154 1155 return res; 1156} //FUNC arrayJoin 1157 1158/*--------------------------------------------------------------------------------*\ 1159| arraySplit 1160|---------------------------------------------------------------------------------- 1161| Splits array. Extended version with keys support. 1162| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1163| Params: 1164| string string - String to process. 1165| separator string - String to use as separator. 1166| auto_tirm string - Allow to trim values on split. 1167| Return: 1168| array - Array with values. 1169\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1170function arraySplit (string, separator, auto_tirm) { 1171 1172 var res = []; 1173 var tmp = string.split(separator); 1174 1175 for ( var i in tmp ) { 1176 1177 var pos = tmp[i].indexOf('='); 1178 1179 if ( pos != -1 ) { 1180 1181 var key = tmp[i].substr(0, pos); 1182 if ( auto_tirm ) key = key.trim(); 1183 1184 var val = tmp[i].substr(pos+1); 1185 if ( auto_tirm ) val = val.trim(); 1186 1187 res[key] = val; 1188 1189 } else { //IF eq symbol found 1190 1191 if ( auto_tirm ) tmp[i] = tmp[i].trim(); 1192 res.push(tmp[i]); 1193 1194 } //IF single value 1195 1196 } //FOR each value 1197 1198 return res; 1199} //FUNC arraySplit 1200 1201String.prototype.limit = function(l, append) { 1202 1203 if ( this.length <= l ) 1204 return this.toString(); 1205 1206 append = append || '…'; 1207 al = append.substr(0, 1) == '&' ? 1 : append.length; 1208 1209 return this.substr(0, l - al) + append; 1210} //FUNC limit 1211 1212String.prototype.ucfirst = function() { 1213 1214 // Nothing to do with empty string 1215 if ( !this.length ) return this; 1216 1217 return this.charAt(0).toUpperCase() + this.substr(1); 1218} //FUNC ucfirst 1219 1220/*--------------------------------------------------------------------------------*\ 1221| escape 1222|---------------------------------------------------------------------------------- 1223| Escapes string for using in REGex. 1224| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1225| Params: 1226| NONE 1227| Return: 1228| NULL 1229\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1230String.prototype.escape = function() { 1231 return this.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, '\\$1'); 1232} //FUNC escape 1233 1234/*--------------------------------------------------------------------------------*\ 1235| _trim 1236|---------------------------------------------------------------------------------- 1237| Base function for trimming strings. 1238| ***TNX*** Ideas taken from phpjs.org 1239| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1240| Params: 1241| [charlist] string - Optional characteres to trim. 1242| [left] bool - Trim left. 1243| [right] bool - Trim right. 1244| Return: 1245| string - Trimmed string. 1246\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1247String.prototype._trim = function(charlist, left, right) { 1248 1249 var str = this; 1250 1251 if ( !str ) 1252 return this; 1253 1254 charlist = (charlist) ? charlist.escape() : ' \\n\\t\\s\u00A0'; 1255 1256 if ( left ) str = str.replace(new RegExp('^[' + charlist + ']+', 'gm'), ''); 1257 if ( right ) str = str.replace(new RegExp('[' + charlist + ']+$', 'gm'), ''); 1258 1259 return str; 1260} //FUNC _trim 1261 1262/*--------------------------------------------------------------------------------*\ 1263| ltrim 1264|---------------------------------------------------------------------------------- 1265| Strips whitespace from the beginning of a string. 1266| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1267| Params: 1268| [charlist] string - Optional characteres to trim. 1269| Return: 1270| string - Trimmed string. 1271\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1272String.prototype.ltrim = function(charlist) { 1273 return this._trim(charlist, 1, 0); 1274} //FUNC ltrim 1275 1276/*--------------------------------------------------------------------------------*\ 1277| rtrim 1278|---------------------------------------------------------------------------------- 1279| Removes trailing whitespace. 1280| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1281| Params: 1282| [charlist] string - Optional characteres to trim. 1283| Return: 1284| string - Trimmed string. 1285\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1286String.prototype.rtrim = function(charlist) { 1287 return this._trim(charlist, 0, 1); 1288} //FUNC rtrim 1289 1290/*--------------------------------------------------------------------------------*\ 1291| trim 1292|----------------------------------------------------------------------------------
1293| Removes whitespaces from both sides. 1294| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1295| Params: 1296| [charlist] string - Optional characteres to trim. 1297| Return: 1298| string - Trimmed string. 1299\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1300String.prototype.trim = function(charlist) { 1301 return this._trim(charlist, 1, 1); 1302} //FUNC trim 1303 1304/*--------------------------------------------------------------------------------*\ 1305| xtrim 1306|---------------------------------------------------------------------------------- 1307| Very fast function for trimming strings. 1308| ***TNX*** Big thanx for Steve at steves_list (at) hotmail.com. 1309| ***TNX*** http://blog.stevenlevithan.com/ 1310| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1311| Params: 1312| NONE 1313| Return: 1314| NULL 1315\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1316String.prototype.xtrim = function() { 1317 var str = this; 1318 str = str.replace(/^\s+/, ''); 1319 for (var i = str.length - 1; i >= 0; i--) { 1320 if (/\S/.test(str.charAt(i))) { 1321 str = str.substring(0, i + 1); 1322 break; 1323 } 1324 } 1325 return str; 1326} //FUNC xtrim 1327 1328/*--------------------------------------------------------------------------------*\ 1329| multiClean 1330|---------------------------------------------------------------------------------- 1331| Cleans double repeated characters. E.g. doublespaces. 1332| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1333| Params: 1334| [character] string - Optional character to clean. 1335| Return: 1336| string - Result string. 1337\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1338String.prototype.multiClean = function(character) { 1339 1340 character = character || ' '; 1341 1342 return this.replace(new RegExp('[' + character.escape() + ']{2,}', 'g'), character); 1343} //FUNC multiClean 1344 1345/*--------------------------------------------------------------------------------*\ 1346| toSafe 1347|---------------------------------------------------------------------------------- 1348| Generates safe value from give string. I.E. safe to use as variable names. 1349| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1350| Params: 1351| [separator] string - Optional characteres to use as word 1352| separator. 1353| Return: 1354| string - Result string. 1355\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1356String.prototype.toSafe = function(separator) { 1357 1358 if ( !separator ) 1359 separator = '_'; 1360 1361 var res = this; 1362 res = res.replace(/[^a-zA-Z0-9_]/g, separator); 1363 res = res.multiClean(separator); 1364 res = res.trim(separator); 1365 1366 return res; 1367} //FUNC toSafe 1368 1369/*--------------------------------------------------------------------------------*\ 1370| compilePath 1371|---------------------------------------------------------------------------------- 1372| Compile path from several pieces using '/' as glue. 1373| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1374| Params: 1375| * string - One or several path pieces. 1376| Return: 1377| string - Valid path. 1378\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1379function compilePath () { 1380 1381 var len = arguments.length; 1382 if ( len == 1 ) return arguments[0]; 1383 1384 var res = (arguments[0]+'').rtrim('/'); 1385 1386 for (var i = 1; i < len; i++ ) { 1387 res += '/' + (arguments[i]+'').ltrim('/'); 1388 } //FOR each argument 1389 1390 return res; 1391} //FUNC compilePath 1392var compileUrl = compilePath; 1393 1394/** //** ----= arraySelectKey =----------------------------------------------\**//** \ 1395* 1396* Chooses existing key from list given in associated array. 1397* 1398* @param array array - Source array. 1399* 1400* @param MIXED keys 1401* array - Array with possible keys. 1402* string - Single key for case insensitive search or regEx 1403* mask for possible keys (slower). 1404* 1405* @param bool [regex] - Search mode for string key. 1406* 1407* @return MIXED 1408* string - Existing key. 1409* bool - FALSE if none exists. 1410* 1411\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1412function arraySelectKey (array, keys, regex) { 1413 1414 if ( typeof(keys) == 'object' ) { 1415 1416 for ( var i = 0; i < keys.length; i++ ) { 1417 1418 if ( array[keys[i]] != undefined ) return keys[i]; 1419 1420 } //FOR each key 1421 1422 } else { //IF searching by array 1423 1424 var reg = keys; 1425 if ( !regex ) 1426 reg = new RegExp('^' + keys.escape() + '$', 'i'); 1427 1428 for ( var key in array ) { 1429 1430 // __(key); 1431 1432 if ( reg.test(key) ) return key; 1433 } //FOR each 1434 1435 } //IF searshing by regex 1436 1437 return undefined; 1438} //FUNC arraySelectKey 1439 1440/** //** ----= arraySelectValue =----------------------------------------------\**//** \ 1441*
1442* Chooses value by one of existing keys given. 1443* 1444* @param array array - Source array. 1445* @param array keys - Array with possible keys. 1446* @param MIXED [default] - Default value to use if nothing found. 1447* 1448* @return MIXED - Found value or default if none found. 1449* 1450\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1451function arraySelectValue (array, keys, def) { 1452 1453 var key = arraySelectKey(array, keys); 1454 1455 if ( !key || !array[key] == undefined ) return def; 1456 1457 return array[key]; 1458} //FUNC arraySelectValue 1459 1460/*--------------------------------------------------------------------------------*\ 1461| arrayToPost 1462|---------------------------------------------------------------------------------- 1463| Prepares multidimentional array to post in native PHP format. 1464| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1465| Params: 1466| array object - Common JavaScript array object. 1467| Return: 1468| array - Array in POST format. 1469\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1470function arrayToPost (array, prefix) { 1471 1472 var res = {}; 1473 1474 for ( i in array ) { 1475 1476 var key = ( prefix )? prefix + '[' + i + ']' : i; 1477 1478 if ( typeof(array[i]) == 'object' ) { 1479 1480 var sub = arrayToPost(array[i], key); 1481 1482 for ( j in sub ) res[j] = sub[j]; 1483 1484 } else { //IF sub array 1485 res[key] = array[i]; 1486 } //IF other type 1487 1488 } //FOR each array 1489 1490 return res; 1491} //FUNC arrayToPost 1492 1493/** //** ----= submitUrl =--------------------------------------------------------------------------------------\**//** \ 1494* 1495* Submits given data as POST/GET to given url. Literally simulates form submit. 1496* 1497* @param string $url - Url to submit to. 1498* @param object $data - Data to submit. 1499* @param string [$blank] - Set TRUE to open in new tab. 1500* 1501* @return bool - Always FALSE. 1502* 1503\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 1504function submitUrl($url, $data, $blank) { 1505 1506 $method = 'post'; // No real need to have method optional 1507 $data = $data || {}; 1508 $target = ''; 1509 1510 if ( $blank ) 1511 $target = ' target="_blank"'; 1512 1513 // Generating form html as string and appending it to body 1514 // Each data will be hidden input in form 1515 var $f = '<form method="' + $method + '" action="' + $url + '"' + $target + ' style="display:none">'; 1516 1517 for ( $i in $data ) { 1518 1519 $f += '<input type="hidden" name="' + $i + '" value="' + $data[$i] + '" />'; 1520 1521 } //FOR each data 1522 1523 $f += '</form>'; 1524 1525 // Appending form, getting it's element, and submiting 1526 var $el = jQuery($f).appendTo('BODY').submit(); 1527 1528 return false; 1529} //FUNC submitUrl 1530 1531/** //** ----= parseVariables =--------------------------------------------------------------------------------------\**//** \ 1532* 1533* Parses {varables} in a template. Supporting complex vairables like {var-sub} and {var.sub} 1534* 1535* @param string $str - Template to parse. 1536* @param object $vars - Data object with variable to parse. 1537* @param bool [$clean] - Set TRUE to cleanup unused variables from template (default behavior). 1538* @param string [$wrap] - Brackets pair to use on vairables. '{}' by default. Use '[]' for bb codes. 1539* 1540* @return string - Parsed template. 1541* 1542\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 1543function parseVariables ($str, $vars, $clean, $wrap) { 1544 1545 // Using {vars} by default 1546 $wrap = $wrap || '{}'; 1547 1548 // Nothing to do if string is empty 1549 if ( !$str ) 1550 return $str; 1551 1552 if ( isUndefined($clean) ) 1553 $clean = true; 1554 1555 // Preparing wrap pairs 1556 // Assuming 2 char pair like '{}' or '[]' 1557 if ( $wrap.length != 2 ) 1558 throw('Invalid var wrapper'); 1559 1560 // Preparing 2 wrap variants: normal and escaped one 1561 // Oftenly strings end up as url escaped strings, escaped by parsers 1562 // Thus just searching this too 1563 var $l = $wrap.charAt(0); 1564 var $r = $wrap.charAt(1); 1565 var $xl = '%' + $wrap.charCodeAt(0).toString(16).toUpperCase(); 1566 var $xr = '%' + $wrap.charCodeAt(1).toString(16).toUpperCase(); 1567 1568 // Looping though all vars and replacing given variables 1569 for ( var $i in $vars ) { 1570 1571 // Skipping anything that can't be placed on template 1572 if ( !isStr($vars[$i]) && !isNumber($vars[$i]) ) 1573 continue; 1574 1575 // Searching both vars variants 1576 $str = $str.replace( new RegExp( ($l + $i + $r).escape(), 'ig'), $vars[$i]); 1577 $str = $str.replace( new RegExp( ($xl + $i + $xr).escape(), 'ig'), $vars[$i]); 1578 1579 } //FOR each var 1580 1581 if ( $clean ) { 1582 1583 // Now cleaning unused, both normal and escaped 1584 $str = $str.replace( new RegExp( $l.escape() + '[\\w\\.-]+' + $r.escape(), 'ig'), ''); 1585 $str = $str.replace( new RegExp( $xl.escape() + '[\\w\\.-]+' + $xr.escape(), 'ig'), ''); 1586 1587 } //IF autoClean 1588 1589 return $str; 1590} //FUNC parseVariables 1591 1592/** //** ----= arrayToTemplate =--------------------------------------------------------------------------------------\**//** \ 1593* 1594* Parses {varables} in a template. PHP counterpart alias to parseVariables. 1595* 1596* @param object $vars - Data object with variable to parse. 1597* @param string $str - Template to parse.
1598* @param bool [$clean] - Set TRUE to cleanup unused variables from template (default behavior). 1599* @param string [$wrap] - Brackets pair to use on vairables. '{}' by default. Use '[]' for bb codes. 1600* 1601* @return string - Parsed template. 1602* 1603\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 1604function arrayToTemplate ($vars, $str, $clean, $wrap) { return parseVariables($str, $vars, $clean, $wrap); } 1605 1606 1607/*--------------------------------------------------------------------------------*\ 1608| isNumeric 1609|---------------------------------------------------------------------------------- 1610| Simple function for checking if given string numnber. 1611| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1612| Params: 1613| value string - Value to check. 1614| Return: 1615| bool - Check status. 1616\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1617function isNumeric (value) { 1618 1619 // Numerics are numeric o_O 1620 if ( typeof(value) == 'number' ) 1621 return true; 1622 1623 return (value - 0) == value && value.length > 0; 1624} //FUNC isNumeric 1625 1626/*--------------------------------------------------------------------------------*\ 1627| isEmail 1628|---------------------------------------------------------------------------------- 1629| Simple function for checking if given string is correct mail. 1630| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1631| Params: 1632| value string - Value to check. 1633| Return: 1634| bool - Check status. 1635\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1636function isEmail (value) { 1637 var filter = /^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9_\-]+\.)+[a-z]{2,6}$/i; 1638 return filter.test(value); 1639} //FUNC isEmail 1640 1641jQuery.fn.findExclude = function($selector, $exclude, $res){ 1642 1643 $res = $res || new jQuery(); 1644 1645 // Looping through children, saving matching ones, 1646 // and recursively traversing deeper in each 1647 // Skipping ones that match exclusions ofc 1648 this.children().each( function() { 1649 1650 var $el = jQuery(this); 1651 1652 // Checking self to be saved in result 1653 if ( $el.is($selector) ) 1654 $res.push(this); 1655 1656 // Traversing deeper if allowed 1657 if( !$el.is($exclude) ) 1658 $el.findExclude($selector, $exclude, $res); 1659 }); //jQuery each children 1660 1661 return $res; 1662} //FUNC findExclude 1663 1664/** //** ----= jQuery.align =-----------------------------------------\**//** \ 1665* 1666* Aligns selected element with another element or browser window. 1667* 1668* @param string align - Align type. 1669* @param object target - Element to align with. 1670* @param bool fit - Set TRUE to fit inside element (forced if no target) 1671* 1672* @return jQuery - Aligned element. 1673* 1674\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1675jQuery.fn.align = function (align, target, fit, fixed) { 1676 1677// ---- Preparing environment 1678 1679 // Default align is center 1680 if ( align == 'center' ) align = false; 1681 align = align || 'center-center'; 1682 1683 align = align.split('-'); 1684 1685 if ( fit === undefined ) fit = false; 1686 1687 if ( !target ) fit = true; 1688 1689 // If no target - we will use screen dimensions 1690 if ( !target ) 1691 var screen = screenSize(); 1692 1693 // Target element dimensions 1694 var tDim = { 1695 width : ( target )? target.outerWidth() : screen.width, 1696 height : ( target )? target.outerHeight() : screen.height 1697 }; //OBJECT elDim 1698 1699// ---- Little complicated logic goes next, no comments there - hard to explain :) 1700 1701 var bases = { 1702 'left' : 0, 1703 'top' : 0, 1704 'center' : 0.5, 1705 'right' : 1, 1706 'bottom' : 1 1707 } //OBJ bases 1708 1709 var ly = false; 1710 1711 if ( align[0] == 'center' ) 1712 align = align.reverse(); 1713 1714 if ( ['left', 'right'].indexOf(align[1]) !== -1 ) { 1715 ly = true; 1716 align = align.reverse(); 1717 } //IF 1718 1719 if ( ['top', 'bottom'].indexOf(align[0]) !== -1 ) { 1720 ly = true; 1721 align = align.reverse(); 1722 } //IF 1723 1724 // Sub function to process aligment separately for each dimension 1725 // Using sub func to avoid copy/paste 1726 function _alignDim (t, l, s, e) { 1727 1728 if ( fit ) l = false; 1729 1730 var d = ds = bases[t]; 1731 1732 if ( l && ds != 0.5 ) 1733 ds = ( ds )? 0 : 1; 1734 1735 return e * d - s * ds; 1736 1737 } //FUNC _alignDim 1738
1739// ---- Result CSS ---- 1740 1741 // preCompiling css 1742 var css = { 1743 'left' : _alignDim( align[0], !ly, this.outerWidth(true), tDim.width ), 1744 'top' : _alignDim( align[1], ly, this.outerHeight(true), tDim.height ) 1745 } //OBJECT css 1746 1747 // Correcting position, relating to target 1748 if ( target ) { 1749 var pos = (fixed) ? target.offset() : target.position(); 1750 1751 css.left += pos.left; 1752 css.top += pos.top; 1753 } //IF target set 1754 1755 this.css(css); 1756 1757 return this; 1758} //FUNC align 1759 1760/*--------------------------------------------------------------------------------*\ 1761| centerWindow 1762|---------------------------------------------------------------------------------- 1763| Adds function to jQuery for centering windows 1764| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1765| Params: 1766| NONE 1767| Return: 1768| SELF 1769\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1770jQuery.fn.centerWindow = function () { 1771 1772 var wnd_width = this.width(); 1773 var wnd_height = this.height(); 1774 1775 var screen = screenSize(); 1776 1777 var wnd_left = ( screen.width - wnd_width ) / 2; 1778 var wnd_top = ( screen.height - wnd_height ) / 2; 1779 1780 var css = {'top' : wnd_top, 'left' : wnd_left}; 1781 1782 this.css(css); 1783 1784 return this; 1785} //FUNC centerWindow 1786 1787jQuery.fn.maxWidth = function ($outer, $margins) { 1788 var $max = 0; 1789 this.each( function() { 1790 $max = Math.max($max, $outer ? jQuery(this).outerWidth($margins) : jQuery(this).width() ); 1791 }); //FUNC each in result 1792 return $max; 1793} //FUNC maxWidth 1794 1795jQuery.fn.maxHeight = function ($outer, $margins) { 1796 var $max = 0; 1797 this.each( function() { 1798 $max = Math.max($max, $outer ? jQuery(this).outerHeight($margins) : jQuery(this).height() ); 1799 }); //FUNC each in result 1800 return $max; 1801} //FUNC maxHeight 1802 1803jQuery.fn.screenOffset = function () { 1804 1805 var $pos = this.offset(); 1806 1807// var $top = jQuery('html, body').scrollTop(); 1808 var $top = jQuery(window).scrollTop(); 1809 1810 $pos.top -= $top; 1811 1812 return $pos; 1813} //FUNC screenOffset 1814 1815jQuery.fn.wrapAround = function ($target) { 1816 1817 // Wrapping assumes border and padding to be same around, so checking only top ones 1818 var $border = parseInt( this.css('border-top-width') ); 1819 var $padding = parseInt( this.css('padding-top') ); 1820 1821 // Supporting direct coordinates input as 4 items array: [left, top, width, height] 1822 if ( isArray($target) ) { 1823 1824 // In array mode coords are given directly 1825 var $css = { 1826 'left' : $target[0] - $border - $padding, 1827 'top' : $target[1] - $border - $padding, 1828 'width' : $target[2], 1829 'height': $target[3] 1830 }; //OBJECT $css 1831 1832 } else { //If dimensions given 1833 1834 if ( !$target.length ) 1835 return this; 1836 1837 // Initial values, huge top/left and small width/height 1838 var $x = 10000; 1839 var $y = 10000; 1840 1841 var $toX = 0; 1842 var $toY = 0; 1843 1844 // Looking through all elmements and searching for ourter max dimensions 1845 $target.each( function () { 1846 1847 var $el = jQuery(this); 1848 1849 // Not counting invisible elements 1850 if ( !$el.is(':visible') ) 1851 return; 1852 1853 // Getting offset and calculating tox/toy for element 1854 // Then comparing this to found ones already 1855 var $o = $el.screenOffset(); 1856 1857 var $tx = $o.left + $el.outerWidth(); 1858 var $ty = $o.top + $el.outerHeight(); 1859 1860 if ( $o.left < $x ) $x = $o.left; 1861 if ( $o.top < $y ) $y = $o.top; 1862 if ( $toX < $tx ) $toX = $tx; 1863 if ( $toY < $ty ) $toY = $ty; 1864 1865 }); //FUNC jQuery.each 1866 1867 // Now we can build helper box 1868 var $css = { 1869 'left' : $x - $border - $padding, 1870 'top' : $y - $border - $padding, 1871 'width' : $toX - $x, 1872 'height': $toY - $y 1873 }; //OBJECT $css 1874 1875 } //IF jQuery 1876 1877 // And apply it to self 1878 this.css($css); 1879 1880 // Continuing chain 1881 return this; 1882} //FUNC wrapAround 1883 1884jQuery.fn.hoverClass = function ($class, $allSet) { 1885 1886 var $this = this; 1887 1888 // Binding with namespaces, using class as namespace 1889 var $ns = $class.replace(/\W+/g, ''); 1890 var $enter = 'mouseenter.hoverClass.' + $ns; 1891 var $leave = 'mouseleave.hoverClass.' + $ns; 1892 1893 this.off($enter); 1894 this.off($leave); 1895 1896 // Adding class on enter to whole set, or only one hoverred 1897 this.on($enter, function ($e) { 1898 if ( $allSet ) 1899 $this.addClass($class); 1900 else 1901 jQuery(this).addClass($class); 1902 }); //FUNC onMouseenter 1903 1904 this.on($leave, function ($e) { 1905 if ( $allSet ) 1906 $this.removeClass($class); 1907 else 1908 jQuery(this).removeClass($class); 1909 }); //FUNC onMouseenter 1910 1911 return this; 1912} //FUNC hoverClass 1913 1914jQuery.fn.groupBy = function ($attribute) { 1915 1916 // Defaulting to data-group attribute. 1917 $attribute = $attribute || 'data-group'; 1918 1919 var $res = {}; // Will store groups here 1920 1921 // Looping through each element, and storing as groups 1922 this.each( function () { 1923 1924 var $el = jQuery(this); 1925 1926 // Getting groups attribute 1927 var $attr = $el.attr($attribute); 1928 1929 // Nothing to do if no attribute set (ungrouped element) 1930 if ( !$attr ) 1931 return; 1932 1933 // Parsing into groups, allowing common delimiters 1934 var $groups = strToArray($attr, ',.|'); 1935 1936 // Assigning element into each group, adding into existing, or creating new ones 1937 for ( var $i in $groups ) { 1938 var $group = $groups[$i]; 1939 1940 if ( !$res[$group] ) 1941 $res[$group] = $el; 1942 else 1943 $res[$group] = $res[$group].add($el); 1944 1945 } //FOR each group 1946 1947 }); //FUNC each.result 1948 1949 // Returning results 1950 return $res; 1951} //FUNC groupBy 1952 1953function centerWindow (el) { 1954 jQuery(el).centerWindow(); 1955} //FUNC centerWindow 1956 1957/*--------------------------------------------------------------------------------*\ 1958| jqmShowCSS 1959|---------------------------------------------------------------------------------- 1960| Apllies given css to jQM window and shows it. 1961| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1962| Params: 1963| selector string - Window to show. 1964| css string - Object with css to apply. 1965| effect string - Effect to use on displaying. 1966| Return: 1967| bool - Alwyas false. 1968\*--------------------------------------------------------------= by Mr.V!T =-----*/ 1969function jqmShowCSS (selector, css, effect) { 1970 1971 jQuery(selector).css(css); 1972 1973 if ( jqmVisible(selector) ) return false; 1974 1975 if ( !isJQM(selector) ) { 1976 1977 var opt = {}; 1978 1979 if ( effect == 'fade' ) 1980 opt = { 1981 onShow: function(h) { 1982 h.w.fadeIn(300); 1983 }, 1984 onHide: function(h) { 1985 h.w.fadeOut(300); 1986 h.o.remove(); 1987 } 1988 }; //Object o 1989 1990 jQuery(selector).jqm(opt); 1991 if ( jQuery().jqDrag ) jQuery(selector).jqDrag('.jqmHeader'); 1992 if ( jQuery().jqResize ) jQuery(selector).jqResize('.jqmResize'); 1993 } //IF element is not jqm window already 1994 1995 jQuery(selector).jqmShow(); 1996 1997 return false; 1998 1999} //FUNC jqmShowCSS 2000 2001/*--------------------------------------------------------------------------------*\ 2002| jqmShowCentered 2003|---------------------------------------------------------------------------------- 2004| Fixes coordinates of jQM window to match center. 2005| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2006| Params: 2007| selector string - Window to show. 2008| effect string - Effect to use on displaying. 2009| Return: 2010| bool - Alwyas false. 2011\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2012function jqmShowCentered (selector, effect) { 2013/**/ 2014 var wnd_width = jQuery(selector).width(); 2015 var wnd_height = jQuery(selector).height(); 2016 2017 var parent_window = screenSize(); 2018 2019 var wnd_left = ( parent_window.width - wnd_width ) / 2; 2020 var wnd_top = ( parent_window.height - wnd_height ) / 2; 2021 2022 var new_css = {'top':wnd_top,'left':wnd_left}; 2023/*/ 2024 var new_css = {'top':0,'left':0, 'margin': 'auto auto'}; 2025 2026/**/ 2027 return jqmShowCSS(selector, new_css, effect); 2028} //FUNC jqmShowCentered 2029 2030/*--------------------------------------------------------------------------------*\ 2031| jqmShowDocked 2032|---------------------------------------------------------------------------------- 2033| Fixes coordinates of jQM window to dock to given element. 2034| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2035| Params: 2036| selector string - Window to show. 2037| dock_to string - Selector of element to dock to. 2038| effect string - Effect to use on displaying. 2039| Return: 2040| bool - Alwyas false. 2041\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2042function jqmShowDocked (selector, dock_to, effect) { 2043 2044 var offset = jQuery(dock_to).offset(); 2045 if ( !offset.top ) return false; 2046 2047 var outer = jQuery(dock_to).outerHeight(); 2048 2049 var new_css = { 2050 'top' : offset.top + outer + 3, 2051 'left' : offset.left 2052 }; //New CSS 2053 2054 return jqmShowCSS(selector, new_css, effect); 2055} //FUNC jqmShowDocked 2056 2057/*--------------------------------------------------------------------------------*\ 2058| jqmHide 2059|---------------------------------------------------------------------------------- 2060| Hides JQM window. 2061| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2062| Params: 2063| selector string - Window to hide. 2064| effect string - Effect to use on hiding. 2065| Return: 2066| bool - Alwyas false. 2067\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2068function jqmHide (selector, effect) { 2069 jQuery(selector).jqmHide(); 2070 return false; 2071} //FUNC jqmHide 2072 2073/*--------------------------------------------------------------------------------*\ 2074| isJQM 2075|---------------------------------------------------------------------------------- 2076| Check if element is already jqModal window. 2077| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2078| Params: 2079| selector string - Element to check. 2080| Return: 2081| NULL 2082\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2083function isJQM (selector) { 2084 2085 var tmp = jQuery(selector).attr('class'); 2086 if ( tmp.indexOf('jqmID') < 0 ) return false; 2087 2088 return true; 2089 2090} //FUNC isJQM 2091 2092/*--------------------------------------------------------------------------------*\ 2093| jqmVisible 2094|---------------------------------------------------------------------------------- 2095| Checks if jqm window is visible. 2096| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2097| Params: 2098| selector string - Element to check. 2099| Return: 2100| NULL 2101\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2102function jqmVisible (element) { 2103 2104 if ( !(element instanceof jQuery) ) 2105 element = jQuery(element); 2106 2107 var disp = element.css('display'); 2108 2109 return (disp != 'none'); 2110} //FUNC jqmVisible 2111 2112function centerWindow (win) { 2113 var wnd_width = jQuery('#'+win).width(); 2114 var wnd_height = jQuery('#'+win).height(); 2115 2116 var parent_window = screenSize(); 2117 2118 var wnd_left = ( parent_window.width - wnd_width ) / 2; 2119 var wnd_top = ( parent_window.height - wnd_height ) / 2; 2120 2121 var new_css = {'top':wnd_top,'left':wnd_left}; 2122 jQuery('#'+win).css(new_css); 2123} //FUNC 2124 2125function getOuterHTML (el) { 2126 2127 if ( el.outerHTML ) return el.outerHTML; 2128 2129 var tmp = document.createElement(el.parentNode.tagName); 2130 tmp.appendChild(el.cloneNode(true)); 2131 2132 return tmp.innerHTML; 2133} //FUNC getOuterHTML 2134 2135function strToElement (html) { 2136 var tmp = document.createElement('div'); 2137 tmp.innerHTML = html; 2138 2139 return tmp.firstChild; 2140} //FUNC strToElement 2141 2142function setOuterHTML (el, html) { 2143 2144 if ( el.outerHTML ) return el.outerHTML = html; 2145 2146 var n = strToElement(html); 2147 2148 el.parentNode.replaceChild(n, el); 2149} //FUNC setOuterHTML 2150 2151/** //** ----= formToArray =--------------------------------------------------------------------------------------\**//** \ 2152* 2153* Collects input values as data object. Result is exactly same as one you get with $_POST. 2154* Supports nested arrays and sets in naming. E.g.: name="lvl1[lvl2][lvl3][]" 2155* 2156* @param object(HTMLFormElement) 2157* $form - Source form. 2158* 2159* @return object - Data collected from form. 2160* 2161\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 2162function formToArray ($form) { 2163 2164 // Storing results in object 2165 var $data = {}; 2166 2167// ---- 3rd parties ---- 2168 2169 // If there is tiny - forcing it to save editors 2170 if ( typeof(tinyMCE) != 'undefined' ) 2171 tinyMCE.triggerSave(); 2172 2173 // Optionally supporting jQuery elements, though shold point exactly to form 2174 if ( isJQ($form) ) { 2175 2176 // Not proceesing if not form though 2177 if ( !$form.is('form') ) 2178 return $data; 2179 2180 // Getting DOM from jQuery 2181 $form = $form.get(0); 2182 } //IF jQuery given 2183 2184// ---- Form ---- 2185 2186 // Counting inputs with same name for sets resolving 2187 var $index = {}; 2188 2189 // Looping through elements and getting values for each 2190 for ( var $i = 0; $i < $form.elements.length; $i++ ) { 2191 2192 // ---- Element ---- 2193 2194 // Getting element to work with 2195 var $el = $form.elements.item($i); 2196 2197 // Collecting value, and then storing it in data object 2198 var $val; 2199 2200 // Skipping it if it does not have name 2201 if ( !$el.name ) 2202 continue; 2203 2204 // ---- Input ---- 2205 2206 switch ( $el.type ) { 2207 case 'file' : 2208 // In HTML files are not included in post 2209 continue; 2210 2211 case 'radio' : 2212 case 'checkbox' : 2213 2214 $val = $el.value; 2215 2216 if ( $val == 'on' ) { 2217 2218 // Using slightly alternate behavior 2219 // where checkboxes without values (val == on) return 1/0 instead of 1/unset 2220 $val = ( $el.checked )? 1 : 0; 2221 2222 } //IF no value 2223 else if ( !$el.checked ) { 2224 2225 // For valued checkboxes - regular behavior 2226 continue; 2227 2228 } //IF value is set 2229 2230 break; 2231 2232 case 'select-one' : 2233 2234 // Using dedicated tool 2235 $val = getValue_Select($el); 2236 2237 break; 2238 2239 case 'select-multiple' : 2240 2241 // Using dedicated tool 2242 $val = getValue_MutliSelect($el); 2243 2244 break; 2245 2246 default : 2247 2248 // Regular inputs have just value 2249 $val = $el.value; 2250 } //SWITCH 2251 2252 // Nothing to do with null 2253 if ( isUndefined($val) ) 2254 continue; 2255 2256 // ---- Data ---- 2257 2258 var $name = $el.name; // That will be working name 2259 2260 // Expecting array to happen, so parsing as path right away 2261 var $path = regexMatchAll(/[\w\-]+/g, $name); 2262 2263 // Problematic paths are skipped too 2264 if ( !$path[0] ) 2265 continue; 2266 2267 // Full match is all we need 2268 $path = $path[0]; 2269 2270 // Indexing now, as it looks like valid name 2271 $index[$name] = isSet($index[$name]) ? ++$index[$name] : 0; 2272 2273 // Special case for sets 2274 // Those should be stored as simple array 2275 if ( $name.endsWith('[]') ) { 2276 2277 // Need to merge with existing array if one is present 2278 var $set = arrayPath($data, $path); 2279 2280 // Merging value into set, which will be set into data 2281 2282 if ( isObject($set, true) ) 2283 2284 // Adding into objectx using index 2285 $set[$index[$name]] = $val; 2286 2287 else if ( isArray($set) ) 2288 2289 // Pushing if array 2290 $set.push($val) 2291 2292 else 2293 // Non arrays are overwritten 2294 $set = [$val]; 2295 2296 // Preparing to be set back to data 2297 $val = $set; 2298 2299 } //IF set given 2300 2301 // Now we have both value and path 2302 // Just setting it 2303 arrayPath($data, $path, $val); 2304 2305 } //FOR each element 2306 2307 return $data; 2308} //FUNC formToArray 2309 2310/** //** ----= formFromArray =--------------------------------------------------------------------------------------\**//** \ 2311* 2312* Sets form inputs values from given data object. 2313* Supports arrays and sets in elements names and tinyMCE Editor if applied to textarea. 2314* 2315* @param object(HTMLFormElement) 2316* $form - Form to setup. 2317* 2318* @param object $source - Values to set. 2319* 2320\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 2321function formFromArray ($form, $source) { 2322 2323 // Resaving to do not break source 2324 var $data = jQuery.extend({}, $source); 2325 2326 // Counting inputs with same name for sets resolving 2327 var $index = {}; 2328 2329// ---- Form ---- 2330 2331 for ( var $i = 0; $i < $form.elements.length; $i++ ) { 2332 2333 // ---- Element ---- 2334 2335 // Getting form element, it's name and value that should be applied 2336 var $el = $form.elements.item($i); 2337 2338 // Skipping it if it does not have name 2339 if ( !$el.name ) 2340 continue; 2341 2342 // Getting element name 2343 var $name = $el.name; 2344 2345 // Expecting array to happen, so parsing as path right away 2346 var $path = regexMatchAll(/[\w\-]+/g, $name); 2347 2348 // Problematic paths are skipped too 2349 if ( !$path[0] ) 2350 continue; 2351 2352 // Full match is all we need 2353 $path = $path[0]; 2354 2355 // Indexing now, as it looks like valid name 2356 $index[$name] = isSet($index[$name]) ? ++$index[$name] : 0; 2357 2358 // ---- Value ---- 2359 2360 var $val = arrayPath($data, $path); 2361 2362 // Resolving set 2363 var $set = $val; 2364 if ( $set && $name.endsWith('[]') ) { 2365 2366 // Getting value by index 2367 $val = $set[$index[$name]]; 2368 2369 } //IF set given 2370 2371 // Making sure value is valid after all 2372 $val = ( isUndefined($val) || $val === false || $val === null ) ? '' : $val; 2373 2374 // Special case for date inputs 2375 if ( $val == '0000-00-00' || $val == '0000-00-00 00:00:00' ) 2376 $val = ''; 2377 2378 // ---- Inputs ---- 2379 2380 switch ($el.type) { 2381 2382 case 'checkbox' : 2383 case 'radio' : 2384 2385 // For simple checkboxes - comparing against found value 2386 // Value will be either set directly or indexed in set 2387 if ( $el.value == 'on' ) { 2388 2389 $el.checked = ( !isEmpty($val) ); 2390 break; 2391 2392 } //IF simple checkbox 2393 2394 // If not part of set - just checking values to match 2395 // Casting incoming value to string manually to ensure that match is correct for numbers
2396 // Input value is always string anyway 2397 if ( !isObject($set, true) ) { 2398 2399 $el.checked = ( $val.toString() === $el.value ); 2400 break; 2401 2402 } //IF not a set 2403 2404 // Custom behavior if part of set - checking by value presense 2405 // Looping through and checking if value is there 2406 // Doing manually instead of array's indexOf cuz assoc array or object could happen 2407 var $tmp = false; 2408 for ( var $t in $set ) 2409 if ( $t in $set && $set[$t].toString() === $el.value ) 2410 $tmp = true; 2411 2412 $el.checked = $tmp; 2413 2414 break; 2415 2416 case 'select-one' : 2417 case 'select-multiple' : 2418 2419 setValue_Select($el, $val); 2420 2421 break; 2422 2423 case 'file' : 2424 2425 // File just resetting to default. 2426 2427 // Getting input HTML, then creating new element from it, 2428 // because simple clone will not help 2429 2430 // Skipping styled forms 2431 // ToDo: capture events instead 2432 2433 if ( $el.className.indexOf('mw') !== -1 ) 2434 break; 2435 2436 var $html = getOuterHTML($el); 2437 setOuterHTML($el, $html); 2438 2439 break; 2440 2441 case 'textarea' : 2442 2443 // Checking if textarea can be tinyMCE 2444 if ( $el.style.display == 'none' && ( typeof tinyMCE != 'undefined' ) ) { 2445 2446 // Checking if tiny really applied to it 2447 var $tiny = tinyMCE.get($el.id); 2448 2449 // If it's tiny - setting values into it too. 2450 if ( $tiny ) 2451 $tiny.setContent($val); 2452 2453 }; //IF hidden and tinyMCE exists 2454 2455 $el.value = $val; 2456 2457 break; 2458 2459 case 'button' : 2460 case 'submit' : 2461 2462 break; 2463 2464 default : 2465 $el.value = $val; 2466 } //SWITCH 2467 2468 // Triggering onChange in case if some set. 2469 if ( isSet(jQuery) ) 2470 jQuery($el).change(); 2471 2472 } //FOR each element 2473 2474} //FUNC formFromArray 2475 2476/** //** ----= jQuery.asArray =--------------------------------------------------------------------------------------\**//** \ 2477* 2478* Simple jQuery wrapper for formToArray() function. 2479* 2480* @return array - Form elements valus as array. 2481* 2482\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 2483jQuery.fn.asArray = function () { 2484 2485 if ( !this.is('FORM') ) return {}; 2486 2487 return formToArray(this.get(0)); 2488} //FUNC asArray 2489 2490/** //** ----= jQuery.fromArray =--------------------------------------------------------------------------------------\**//** \ 2491* 2492* Simple jQuery wrapper for formFromArray() function. 2493* 2494* @param object data - Array with values to set to elements. 2495* @return jQuery - jQuery object for chain calls. 2496* 2497\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 2498jQuery.fn.fromArray = function (data) { 2499 2500 if ( !this.is('FORM') ) return this; 2501 2502 formFromArray( this.get(0), data ); 2503 2504 return this; 2505} //FUNC fromArray 2506 2507/*--------------------------------------------------------------------------------*\ 2508| getValue_Select 2509|---------------------------------------------------------------------------------- 2510| Returns correct value of <select> based in setted or not value attribute. IE FIX. 2511| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2512| Params: 2513| element object - DOM elemnt to get value. 2514| Return: 2515| MIXED 2516| bool - FALSE in case of error. 2517| string - Element value. 2518\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2519function getValue_Select (element) { 2520 2521 if ( element.options.selectedIndex < 0 ) return false; 2522 2523 var option = element.options[element.options.selectedIndex]; 2524 var value = getValue_Option(option); 2525 //(option.attributes.value && option.attributes.value.specified)? option.value : option.text 2526 2527 return value; 2528} //FUNC getValue_Select 2529 2530/*--------------------------------------------------------------------------------*\ 2531| getValue_MutliSelect 2532|---------------------------------------------------------------------------------- 2533| Returns values of <select> with multiple selection enabled as an array. 2534| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2535| Params: 2536| element object - DOM elemnt to get value. 2537| Return: 2538| array - Array with values. Can be emty. 2539\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2540function getValue_MutliSelect (element) { 2541 2542 var res = [] ; 2543 2544 if ( !element.options || element.options.length <= 0 ) return res; 2545 2546 for ( var i = 0; i < element.options.length; i++ ) { 2547 2548 if ( !element.options[i].selected ) continue; 2549 2550 res.push(getValue_Option(element.options[i])); 2551 } //FOR all managers 2552 2553 return res; 2554} //FUNC getValue_MutliSelect 2555 2556/*--------------------------------------------------------------------------------*\ 2557| setValue_Select 2558|---------------------------------------------------------------------------------- 2559| Correctly sets value to selector. Works in old IE. 2560| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2561| Params: 2562| element object - DOM elemnt to set value. 2563| values MIXED - Single string value or array with selected values. 2564| Return: 2565| VOID 2566\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2567function setValue_Select (element, values) { 2568 2569 if ( element.options.length <= 0 ) return; 2570 2571 if ( !values ) 2572 values = []; 2573 2574 if ( typeof(values) != 'object' ) { 2575 2576 // Converting values depending on multiple attribute 2577 // If multiple - most likely it's simple array string. 2578 if ( element.multiple || element.size ) 2579 values = strToArray(values); 2580 else 2581 // Stringifying value, cuz if integer come - indexOf will ignore it 2582 values = [values+'']; 2583 2584 } //IF not array come 2585 2586 for ( var i = 0; i < element.options.length; i++ ) { 2587 2588 var val = getValue_Option(element.options[i]); 2589 2590 element.options[i].selected = (values.indexOf(val) != -1); 2591 2592 } //FOR all elements 2593 2594} //FUNC setValue_Select 2595 2596/*--------------------------------------------------------------------------------*\ 2597| getValue_Option 2598|---------------------------------------------------------------------------------- 2599| Returns correct value of <option> based in setted or not value attribute. IE FIX. 2600| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2601| Params: 2602| element object - DOM elemnt to get value. 2603| Return: 2604| string - Element value. 2605\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2606function getValue_Option (element) { 2607 var value = (element.attributes.value && element.attributes.value.specified)? element.value : element.text; 2608 return value; 2609} //FUNC getValue_Option 2610 2611/*--------------------------------------------------------------------------------*\ 2612| getSelectorOptions 2613|---------------------------------------------------------------------------------- 2614| Returns array with selector values. 2615| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2616| Params: 2617| element object - DOM elemnt to get value. 2618| Return: 2619| array - Selector values. 2620\*--------------------------------------------------------------= by Mr.V!T =-----*/ 2621function getSelectorOptions (element) { 2622 2623 var res = [] ; 2624 2625 if ( !element.options || element.options.length <= 0 ) return res; 2626 2627 for ( var i = 0; i < element.options.length; i++ ) { 2628 2629 var option = element.options[i]; 2630 2631 if ( option.attributes.value && option.attributes.value.specified ) { 2632 res[option.value] = option.text; 2633 } else { //IF value set 2634 res.push(option.text); 2635 } //IF value not set 2636 2637 } //FOR each option 2638 2639 return res; 2640} //FUNC getSelectorOptions 2641 2642/** //** ----= strToArray =--------------------------------------\**//** \ 2643* 2644* Splits string into array with given delimeters, trimming resulting items. 2645* 2646* @param string str - String to split. 2647* @return array - Resulting array. 2648* 2649\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2650function strToArray(str, delim) { 2651 2652 delim = delim || ',|'; 2653 2654 var tmp = str.split( new RegExp('\\s*[' + delim + ']\\s*') ); 2655 2656 var res = []; 2657 2658 // Skipping empties 2659 for ( var i in tmp ) 2660 if ( tmp[i] ) res.push(tmp[i]); 2661 2662 return res; 2663} //FUNC strToArray 2664 2665/** //** ----= strToObj =----------------------------------------------\**//** \ 2666* 2667* Splits string into object array with given delimeters 2668* 2669* @param string str - String to split. 2670* @return array - Resulting array. 2671* 2672\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2673function strToObj (str, delim, auto_tirm) { 2674 2675 var res = {}; 2676 2677 if ( !str ) 2678 return res; 2679 2680 var tmp = str.split(delim); 2681 2682 var j = 0; 2683 2684 for ( var i in tmp ) { 2685 2686 var pos = tmp[i].indexOf('='); 2687 2688 if ( pos != -1 ) { 2689 var key = tmp[i].substr(0, pos); 2690 var val = tmp[i].substr(pos+1); 2691 } else { //IF eq symbol found 2692 var key = j+''; 2693 var val = tmp[i]; 2694 } //IF single value 2695 2696 key = key.trim(); 2697 2698 if ( auto_tirm ) 2699 val = val.trim(); 2700 2701 res[key] = val; 2702 2703 j++; 2704 2705 } //FOR each value 2706 2707 return res; 2708} //FUNC strToObj 2709 2710/** //** ----= cb =--------------------------------------\**//** \ 2711* 2712* Callback runner helper. Used to simplify code. Checks if funciton given. 2713* 2714* @param function func - Function to run. 2715* @param MIXED * - All next parameters will be passed to function. 2716* 2717* @return MIXED - Funciton restult. 2718* 2719\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2720function cb(func, args) { 2721 2722 // ToDo: apply is not applicable here, so think better way; 2723 2724} //FUNC cb 2725 2726/** //** ----= checkAll =--------------------------------------\**//** \ 2727* 2728* Sets value to all checkboxes in an element. 2729* 2730* @param bool value - Checkbox state. 2731* @param string element - jQuery selector. 2732* @return bool - Initial value. 2733* 2734\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2735function checkAll (value, element) { 2736 2737 jQuery(element).find('INPUT[type=checkbox]').attr('checked', value); 2738 2739 return false; 2740} //FUNC checkAll 2741 2742function ToggleDisplay(elementID, state) { 2743 element = document.getElementById(elementID); 2744 2745 if ( !element ) return; 2746 2747 if (state == undefined) { 2748 state = ( element.style.display == 'none' ); 2749 } //IF no state specified 2750 2751 element.style.display = state ? 'inline' : 'none'; 2752} //FUNC ToggleDisplay 2753 2754function screenSize() { 2755 var w, h; 2756 w = (window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth)); 2757 h = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight)); 2758 return {width:w, height:h}; 2759} 2760 2761function selectRow(row, state) { 2762 var row_class = jQuery('#'+row).attr('class'); 2763 row_class = row_class.replace('_selected',''); 2764 row_class += ( state )? '_selected' : ''; 2765 jQuery('#'+row).attr('class', row_class); 2766} //FUNC selectRow 2767 2768/*/ 2769function insert_bar (bar_place) { 2770 jQuery('#'+bar_place).html('<IMG src="/images/processing/bar.gif" alt="Loading...">'); 2771} //FUNC insert_bar 2772 2773function insert_green_bar (bar_place) { 2774 jQuery('#'+bar_place).html('<IMG src="/images/processing/bar_green.gif" alt="Loading...">'); 2775} //FUNC insert_bar 2776//*/ 2777 2778/** //** ----= getCookie =--------------------------------------\**//** \ 2779* 2780* Returns cookie with given name. 2781* 2782* @param string name - Cookie name to search. 2783* @param string [def] - Default value to return if cookie not found. 2784* 2785* @return string - Cookie value. 2786* 2787\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2788function getCookie (name, def) { 2789 2790 if ( def == undefined ) def = ''; 2791 2792 var cookieValue = def; 2793 var cookieName = name + '='; 2794 2795 if ( document.cookie.length > 0 ) { 2796 2797 offset = document.cookie.lastIndexOf(cookieName); 2798 if ( offset != -1 ) { 2799 2800 offset += cookieName.length; 2801 2802 end = document.cookie.indexOf(';', offset); 2803 if (end == -1) end = document.cookie.length; 2804 2805 cookieValue = unescape(document.cookie.substring(offset, end)) 2806 2807 } //IF found smth 2808 2809 } //IF there are cookies 2810 2811 return cookieValue; 2812} //FUNC getCookie 2813 2814/** //** ----= setCookie =----------------------------------------------\**//** \ 2815* 2816* Sets cookie with given name. 2817* 2818* @param string name - Cookie name to set. 2819* @param string value - Value of cookie. 2820* @param string [hours] - Expiration date in hours. 2821* 2822\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2823function setCookie (name, value, hours) { 2824 2825 var expire = ""; 2826 2827 if ( hours ) { 2828 expire = new Date((new Date()).getTime() + hours * 3600000); 2829 expire = "; expires=" + expire.toGMTString(); 2830 } //IF there is set expiration 2831 2832 document.cookie = name + "=" + escape(value) + expire + ';path=/;'; 2833} //FUNC setCookie 2834 2835function get_controller_views(views) { 2836 insert_bars(views);
2837 insert_views(views,0); 2838} //FUNC get_controller_views 2839 2840function mark_checkboxes(container_form,val) { 2841 for (var i = 0; i < container_form.elements.length; i++) { 2842 el = container_form.elements[i]; 2843 if (el.type=='checkbox') 2844 el.checked=val; 2845 } 2846} //FUNC mark_checkboxes 2847 2848function status_string(message,style_class,padding) { 2849 if (message == '') return ''; 2850 if (!style_class) style_class = 'status_error'; 2851 if (!padding) padding = 0; 2852 return '<div class="'+style_class+'" style="padding:'+padding+'px">'+message+'</div>'; 2853} //FUNC error_string 2854 2855function ajax_pack_data(controller_url,place_to_put, data, ajax_options) { 2856 var res = []; 2857 res['controller'] = controller_url; 2858 res['place'] = place_to_put; 2859 if (!data) data = {}; 2860 res['data'] = data; 2861 if (!ajax_options) ajax_options = {}; 2862 res['options'] = ajax_options; 2863 return res; 2864} //FUNC pack_view 2865 2866function ajax_insert_bars(views) { 2867 for (i=0; i < views.length; i++) { 2868 insert_bar(views[i]['place']); 2869 } //FOR each views 2870} //FUNC insert_bars 2871 2872function ajax_insert_views(views,num) { 2873 if (num >= views.length) return false; 2874 2875 var tdata = views[num]['data']; 2876 2877 if (views[num]['options'].onLoad) {views[num]['options'].onLoad(tdata)}; 2878 jQuery.ajax({ 2879 type : 'POST', dataType: 'html', 2880 url : views[num]['controller'], 2881 data : views[num]['data'], 2882 success : function(obj){ 2883 jQuery('#'+views[num]['place']).html(obj); 2884 ajax_insert_views(views,num+1); 2885 if (views[num]['options'].onSuccess) {views[num]['options'].onSuccess(tdata)}; 2886 },//FUNC success 2887 error : function (XMLHttpRequest, textStatus, errorThrown) { 2888 jQuery('#'+views[num]['place']).html(status_string('This section is not avaible now (Possibly under construction). Try again later.')); 2889 ajax_insert_views(views,num+1); 2890 } //FUNC error 2891 }); //ajax 2892}//FUNC insert_views 2893 2894function ajax_get_views(views) { 2895 ajax_insert_bars(views); 2896 ajax_insert_views(views,0); 2897} //FUNC get_controller_views 2898 2899function ajax_get_view(controller_url,place_to_put,data, ajax_options) { 2900 ajax_get_views([ajax_pack_data(controller_url,place_to_put,data, ajax_options)]); 2901} //FUNC get_controller_view 2902 2903function ajax_post (post_form,controller,status_place,settings) { 2904 insert_bar(status_place); 2905 var tt = document.getElementById(post_form); 2906 if (!tt) alert('no form'); 2907//*/ 2908 jQuery.ajaxUpload ({ 2909 type : 'POST', dataType : 'html', 2910 url : controller, 2911 secureuri : false, 2912 uploadform : document.getElementById(post_form), 2913 success : function (res, status) { 2914 data = res.split('<!-- CUT -->'); 2915 jQuery('#'+status_place).html(data[0]); 2916 2917 if ((data.length != 1) && (data[1] == 'success') ) { 2918 if (settings.success) settings.success(data); 2919 } else { 2920 if (settings.error) settings.error(data); 2921 } //IF returned status 2922 2923 }, //FUNC sucess 2924 error : function (res, status) { 2925 alert('error'); 2926 jQuery('#'+status_place).html(status_string('Error: '+status)); 2927 if (settings.error) settings.error(); 2928 } //FUNC error 2929 2930 }); //AJAX 2931//*/ 2932} //FUNC ajax_post 2933 2934/** //** ----= getDimensions =--------------------------------------------------------------------------------------\**//** \ 2935* 2936* Parses strings like '100x200' into [x,y] dimensions pair (with Y being optional). 2937* Returns FALSE if string does not contain valid dimensions string. 2938* 2939* @param string $dimensions - Dimensions string. 2940* @param bool [$strict] - Strict validation. Will require Y to present 2941* 2942* @return MIXED - Array with named dimensons or FALSE if failed. 2943* 2944\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 2945function getDimensions ($dimensions, $strict) { 2946 2947 // Nothing to do if notihng fiven 2948 if ( !$dimensions ) 2949 return false; 2950 2951 // Simple check for compatability with parsed dimensions, allowing mixed params in callee funcions. 2952 if ( isArray($dimensions) || isObject($dimensions) ) { 2953 2954 // Fast validation for X to be present: it's minimal requirement for valid dimensions array 2955 if ( !isSet($dimensions['x']) ) 2956 return false; 2957 2958 // Fast validation for strict mode 2959 if ( $strict && !isSet($dimensions['y']) ) 2960 return false;
2961 2962 return $dimensions; 2963 } //IF array given 2964 2965 // Parsing for dimensions, using regex. It also allows to validate dimensions stirng. 2966 // X and Y will be named in matches, which makes it easyer to return. 2967 2968 // Strict option really changes counter for second (x200) match 2969 $strict = $strict ? '+' : '?'; 2970 2971 // Capturing groups and then checking once that good 2972 var $reg = '^([0-9]+)(x([0-9]+))' + $strict + '$'; 2973 var $match = $dimensions.match( new RegExp($reg, 'i') ); 2974 2975 // Checking existing params 2976 if ( !$match ) 2977 return false; 2978 2979 // Grabbing only named matches into result (to keep result clear) 2980 var $res = {}; 2981 2982 // X always present at this step (othewise we'd returned already) 2983 $res['x'] = $match[1]; 2984 2985 // Y is optional 2986 if ( isSet($match[3]) ) 2987 $res['y'] = $match[3]; 2988 2989 // Can return now 2990 return $res; 2991} //FUNC getDimensions 2992 2993/* #### MATH ################################################################################################################ */ 2994 2995/** //** ----= asDeg =----------------------------------------------------------------------------------------------\**//** \ 2996* 2997* Converts radians to degrees. 2998* 2999* @param float $angle - Angle in radians. 3000* 3001* @return flaot - Angle in degrees. 3002* 3003\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 3004function asDeg ($angle) { 3005 return $angle * (180 / Math.PI); 3006} //FUNC asDeg 3007 3008/** //** ----= asRad =----------------------------------------------------------------------------------------------\**//** \ 3009* 3010* Converts degrees to radians. 3011* 3012* @param float $angle - Angle in degrees. 3013* 3014* @return flaot - Angle in radians. 3015* 3016\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/ 3017function asRad ($angle) { 3018 return $angle * (Math.PI / 180); 3019} //FUNC asRad
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.