1/**********************************************************************/ 2/*********** Bitrix JS Core library ver 0.9.0 beta ********************/ 3/**********************************************************************/ 4 5;(function(window){ 6 7if (!!window.BX && !!window.BX.extend) 8 return; 9 10var _bxtmp; 11if (!!window.BX) 12{ 13 _bxtmp = window.BX; 14} 15 16window.BX = function(node, bCache) 17{ 18 if (BX.type.isNotEmptyString(node)) 19 { 20 var ob; 21 22 if (!!bCache && null != NODECACHE[node]) 23 ob = NODECACHE[node]; 24 ob = ob || document.getElementById(node); 25 if (!!bCache) 26 NODECACHE[node] = ob; 27 28 return ob; 29 } 30 else if (BX.type.isDomNode(node)) 31 return node; 32 else if (BX.type.isFunction(node)) 33 return BX.ready(node); 34 35 return null; 36}; 37 38BX.debugEnableFlag = true; 39 40// language utility 41BX.message = function(mess) 42{ 43 if (BX.type.isString(mess)) 44 { 45 if (typeof BX.message[mess] == "undefined") 46 { 47 BX.onCustomEvent("onBXMessageNotFound", [mess]); 48 if (typeof BX.message[mess] == "undefined") 49 { 50 BX.debug("message undefined: " + mess); 51 BX.message[mess] = ""; 52 } 53 54 } 55 56 return BX.message[mess]; 57 } 58 else 59 { 60 for (var i in mess) 61 { 62 if (mess.hasOwnProperty(i)) 63 { 64 BX.message[i] = mess[i]; 65 } 66 } 67 return true; 68 } 69}; 70 71if(!!_bxtmp) 72{ 73 for(var i in _bxtmp) 74 { 75 if(_bxtmp.hasOwnProperty(i)) 76 { 77 if(!BX[i]) 78 { 79 BX[i]=_bxtmp[i]; 80 } 81 else if(i=='message') 82 { 83 for(var j in _bxtmp[i]) 84 { 85 if(_bxtmp[i].hasOwnProperty(j)) 86 { 87 BX.message[j]=_bxtmp[i][j]; 88 } 89 } 90 } 91 } 92 } 93 94 _bxtmp = null; 95} 96 97var 98 99/* ready */ 100__readyHandler = null, 101readyBound = false, 102readyList = [], 103 104/* list of registered proxy functions */ 105proxySalt = Math.random(), 106proxyId = 1, 107proxyList = [], 108 109/* getElementById cache */ 110NODECACHE = {}, 111 112/* List of denied event handlers */ 113deniedEvents = [], 114 115/* list of registered event handlers */ 116eventsList = [], 117 118/* list of registered custom events */ 119customEvents = {}, 120 121/* list of external garbage collectors */ 122garbageCollectors = [], 123 124/* list of loaded CSS files */ 125cssList = [], 126cssInit = false, 127 128/* list of loaded JS files */ 129jsList = [], 130jsInit = false, 131 132 133/* browser detection */ 134bSafari = navigator.userAgent.toLowerCase().indexOf('webkit') != -1, 135bOpera = navigator.userAgent.toLowerCase().indexOf('opera') != -1, 136bFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') != -1, 137bChrome = navigator.userAgent.toLowerCase().indexOf('chrome') != -1, 138bIE = document.attachEvent && !bOpera, 139 140/* regexps */ 141r = { 142 script: /<script([^>]*)>/ig, 143 script_end: /<\/script>/ig, 144 script_src: /src=["\']([^"\']+)["\']/i, 145 script_type: /type=["\']([^"\']+)["\']/i, 146 space: /\s+/, 147 ltrim: /^[\s\r\n]+/g, 148 rtrim: /[\s\r\n]+$/g, 149 style: /<link.*?(rel="stylesheet"|type="text\/css")[^>]*>/i, 150 style_href: /href=["\']([^"\']+)["\']/i 151}, 152 153eventTypes = { 154 click: 'MouseEvent', 155 dblclick: 'MouseEvent', 156 mousedown: 'MouseEvent', 157 mousemove: 'MouseEvent', 158 mouseout: 'MouseEvent', 159 mouseover: 'MouseEvent', 160 mouseup: 'MouseEvent', 161 focus: 'MouseEvent', 162 blur: 'MouseEvent' 163}, 164 165lastWait = [], 166 167CHECK_FORM_ELEMENTS = {tagName: /^INPUT|SELECT|TEXTAREA|BUTTON$/i}, 168 169PRELOADING = 1, PRELOADED = 2, LOADING = 3, LOADED = 4, 170assets = {}, 171isAsync = null; 172 173BX.MSLEFT = 1; 174BX.MSMIDDLE = 2; 175BX.MSRIGHT = 4; 176 177BX.ext = function(ob) 178{ 179 for (var i in ob) 180 { 181 if(ob.hasOwnProperty(i)) 182 { 183 this[i] = ob[i]; 184 } 185 } 186}; 187 188/* OO emulation utility */ 189BX.extend = function(child, parent) 190{ 191 var f = function() {}; 192 f.prototype = parent.prototype; 193 194 child.prototype = new f(); 195 child.prototype.constructor = child; 196 197 child.superclass = parent.prototype; 198 if(parent.prototype.constructor == Object.prototype.constructor) 199 { 200 parent.prototype.constructor = parent; 201 } 202}; 203 204BX.namespace = function(namespace) 205{ 206 var parts = namespace.split("."); 207 var parent = BX; 208 209 if (parts[0] === "BX") 210 { 211 parts = parts.slice(1); 212 } 213 214 for (var i = 0; i < parts.length; i++) { 215 216 if (typeof parent[parts[i]] === "undefined") 217 { 218 parent[parts[i]] = {}; 219 } 220 parent = parent[parts[i]]; 221 } 222 223 return parent; 224}; 225 226BX.debug = function() 227{ 228 if (BX.debugStatus()) 229 { 230 if (window.console && window.console.log) 231 window.console.log('BX.debug: ', arguments.length > 0 ? arguments : arguments[0]); 232 if (window.console && window.console.trace) 233 console.trace(); 234 } 235}; 236 237BX.debugEnable = function(flag) 238{ 239 flag = typeof (flag) == 'boolean'? flag: true; 240 BX.debugEnableFlag = flag; 241}; 242 243BX.debugStatus = function() 244{ 245 return BX.debugEnableFlag || true; 246}; 247 248BX.is_subclass_of = function(ob, parent_class) 249{ 250 if (ob instanceof parent_class) 251 return true; 252 253 if (parent_class.superclass) 254 return BX.is_subclass_of(ob, parent_class.superclass); 255 256 return false;
257}; 258 259BX.clearNodeCache = function() 260{ 261 NODECACHE = {}; 262 return false; 263}; 264 265BX.bitrix_sessid = function() {return BX.message("bitrix_sessid"); }; 266 267/* DOM manipulation */ 268/** 269 * Creates the specified HTML element 270 * @param {String} tag 271 * @param {Object} [data] 272 * @param {Document} [context] 273 * @returns {Element} 274 */ 275BX.create = function(tag, data, context) 276{ 277 context = context || document; 278 279 if (null == data && typeof tag == 'object' && tag.constructor !== String) 280 { 281 data = tag; tag = tag.tag; 282 } 283 284 var elem; 285 if (BX.browser.IsIE() && !BX.browser.IsIE9() && null != data && null != data.props && (data.props.name || data.props.id)) 286 { 287 elem = context.createElement('<' + tag + (data.props.name ? ' name="' + data.props.name + '"' : '') + (data.props.id ? ' id="' + data.props.id + '"' : '') + '>'); 288 } 289 else 290 { 291 elem = context.createElement(tag); 292 } 293 294 return data ? BX.adjust(elem, data) : elem; 295}; 296 297BX.adjust = function(elem, data) 298{ 299 var j,len; 300 301 if (!elem.nodeType) 302 return null; 303 304 if (elem.nodeType == 9) 305 elem = elem.body; 306 307 if (data.attrs) 308 { 309 for (j in data.attrs) 310 { 311 if(data.attrs.hasOwnProperty(j)) 312 { 313 if (j == 'class' || j == 'className') 314 elem.className = data.attrs[j]; 315 else if (j == 'for') 316 elem.htmlFor = data.attrs[j]; 317 else if(data.attrs[j] == "") 318 elem.removeAttribute(j); 319 else 320 elem.setAttribute(j, data.attrs[j]); 321 } 322 } 323 } 324 325 if (data.style) 326 { 327 for (j in data.style) 328 { 329 if(data.style.hasOwnProperty(j)) 330 { 331 elem.style[j] = data.style[j]; 332 } 333 } 334 } 335 336 if (data.props) 337 { 338 for (j in data.props) 339 { 340 if(data.props.hasOwnProperty(j)) 341 { 342 elem[j] = data.props[j]; 343 } 344 } 345 } 346 347 if (data.events) 348 { 349 for (j in data.events) 350 { 351 if(data.events.hasOwnProperty(j)) 352 { 353 BX.bind(elem, j, data.events[j]); 354 } 355 } 356 } 357 358 if (data.dataset) 359 { 360 for (j in data.dataset) 361 { 362 if(data.dataset.hasOwnProperty(j)) 363 { 364 elem.dataset[j] = data.dataset[j] 365 } 366 } 367 } 368 369 if (data.children && data.children.length > 0) 370 { 371 for (j=0,len=data.children.length; j<len; j++) 372 { 373 if (BX.type.isNotEmptyString(data.children[j])) 374 elem.innerHTML += data.children[j]; 375 else if (BX.type.isElementNode(data.children[j])) 376 elem.appendChild(data.children[j]); 377 } 378 } 379 else if (data.text) 380 { 381 BX.cleanNode(elem); 382 elem.appendChild((elem.ownerDocument || document).createTextNode(data.text)); 383 } 384 else if (typeof data.html !== 'undefined') 385 { 386 elem.innerHTML = data.html; 387 } 388 389 return elem; 390}; 391 392BX.remove = function(ob) 393{ 394 if (ob && null != ob.parentNode) 395 ob.parentNode.removeChild(ob); 396 ob = null; 397 return null; 398}; 399 400BX.cleanNode = function(node, bSuicide) 401{ 402 node = BX(node); 403 bSuicide = !!bSuicide; 404 405 if (node && node.childNodes) 406 { 407 while(node.childNodes.length > 0) 408 node.removeChild(node.firstChild); 409 } 410 411 if (node && bSuicide) 412 { 413 node = BX.remove(node); 414 } 415 416 return node; 417}; 418 419BX.html = function(node, html, parameters) 420{ 421 if(typeof html == 'undefined') 422 return node.innerHTML; 423 424 if(typeof parameters == 'undefined') 425 parameters = {}; 426 427 html = BX.processHTML(html.toString()); 428 429 var assets = []; 430 var inlineJS = []; 431 432 if(typeof html.STYLE != 'undefined' && html.STYLE.length > 0) 433 { 434 for(var k in html.STYLE) 435 assets.push(html.STYLE[k]); 436 } 437 438 if(typeof html.SCRIPT != 'undefined' && html.SCRIPT.length > 0) 439 { 440 for(var k in html.SCRIPT) 441 { 442 if(html.SCRIPT[k].isInternal) 443 inlineJS.push(html.SCRIPT[k].JS); 444 else 445 assets.push(html.SCRIPT[k].JS); 446 } 447 } 448 449 if(parameters.htmlFirst && typeof html.HTML != 'undefined' && node) 450 { 451 node.innerHTML = html.HTML; 452 } 453 454 var p = new BX.Promise(); 455 456 var afterAsstes = function(){ 457 if(!parameters.htmlFirst && typeof html.HTML != 'undefined' && node) 458 { 459 node.innerHTML = html.HTML; 460 } 461 462 for(var k in inlineJS) 463 { 464 BX.evalGlobal(inlineJS[k]); 465 } 466 467 if(BX.type.isFunction(parameters.callback)) 468 { 469 parameters.callback(); 470 } 471 472 p.fulfill(); 473 }; 474 475 if(assets.length > 0) 476 { 477 BX.load(assets, afterAsstes); 478 } 479 else 480 { 481 afterAsstes(); 482 } 483 484 return p; 485}; 486 487BX.insertAfter = function(node, dstNode) 488{ 489 dstNode.parentNode.insertBefore(node, dstNode.nextSibling); 490}; 491 492BX.prepend = function(node, dstNode) 493{ 494 dstNode.insertBefore(node, dstNode.firstChild); 495}; 496 497BX.append = function(node, dstNode) 498{ 499 dstNode.appendChild(node); 500}; 501 502BX.addClass = function(ob, value) 503{ 504 var classNames; 505 ob = BX(ob); 506 507 value = BX.util.trim(value); 508 if (value == '') 509 return ob; 510 511 if (ob) 512 { 513 if (!ob.className) 514 { 515 ob.className = value 516 } 517 else if (!!ob.classList && value.indexOf(' ') < 0) 518 { 519 ob.classList.add(value); 520 } 521 else 522 { 523 classNames = (value || "").split(r.space); 524 525 var className = " " + ob.className + " "; 526 for (var j = 0, cl = classNames.length; j < cl; j++) 527 { 528 if (className.indexOf(" " + classNames[j] + " ") < 0) 529 { 530 ob.className += " " + classNames[j]; 531 } 532 } 533 } 534 } 535 536 return ob; 537}; 538 539BX.removeClass = function(ob, value) 540{ 541 ob = BX(ob); 542 if (ob) 543 { 544 if (ob.className && !!value) 545 { 546 if (BX.type.isString(value)) 547 { 548 if (!!ob.classList && value.indexOf(' ') < 0) 549 { 550 ob.classList.remove(value); 551 } 552 else 553 { 554 var classNames = value.split(r.space), className = " " + ob.className + " "; 555 for (var j = 0, cl = classNames.length; j < cl; j++) 556 { 557 className = className.replace(" " + classNames[j] + " ", " "); 558 } 559 560 ob.className = BX.util.trim(className); 561 } 562 } 563 else 564 {
565 ob.className = ""; 566 } 567 } 568 } 569 570 return ob; 571}; 572 573BX.toggleClass = function(ob, value) 574{ 575 var className; 576 ob = BX(ob); 577 578 if (BX.type.isArray(value)) 579 { 580 className = ' ' + ob.className + ' '; 581 for (var j = 0, len = value.length; j < len; j++) 582 { 583 if (BX.hasClass(ob, value[j])) 584 { 585 className = (' ' + className + ' ').replace(' ' + value[j] + ' ', ' '); 586 className += ' ' + value[j >= len-1 ? 0 : j+1]; 587 588 j--; 589 break; 590 } 591 } 592 593 if (j == len) 594 ob.className += ' ' + value[0]; 595 else 596 ob.className = className; 597 598 ob.className = BX.util.trim(ob.className); 599 } 600 else if (BX.type.isNotEmptyString(value)) 601 { 602 if (!!ob.classList) 603 { 604 ob.classList.toggle(value); 605 } 606 else 607 { 608 className = ob.className; 609 if (BX.hasClass(ob, value)) 610 { 611 className = (' ' + className + ' ').replace(' ' + value + ' ', ' '); 612 } 613 else 614 { 615 className += ' ' + value; 616 } 617 618 ob.className = BX.util.trim(className); 619 } 620 } 621 622 return ob; 623}; 624 625BX.hasClass = function(el, className) 626{ 627 el = BX(el); 628 if (!el || !BX.type.isDomNode(el)) 629 { 630 BX.debug(el); 631 return false; 632 } 633 634 if (!el.className || !className) 635 { 636 return false; 637 } 638 639 if (!!el.classList && !!className && className.indexOf(' ') < 0) 640 { 641 return el.classList.contains(BX.util.trim(className)); 642 } 643 else 644 return ((" " + el.className + " ").indexOf(" " + className + " ")) >= 0; 645}; 646 647BX.setOpacity = function(ob, percentage) 648{ 649 if (ob.style.filter != null) 650 { 651 //IE 652 ob.style.zoom = "100%"; 653 654 if (percentage == 100) 655 { 656 ob.style.filter = ""; 657 } 658 else 659 { 660 ob.style.filter = 'alpha(opacity=' + percentage.toString() + ')'; 661 } 662 } 663 else if (ob.style.opacity != null) 664 { 665 // W3C 666 ob.style.opacity = (percentage / 100).toString(); 667 } 668 else if (ob.style.MozOpacity != null) 669 { 670 // Mozilla 671 ob.style.MozOpacity = (percentage / 100).toString(); 672 } 673}; 674 675BX.hoverEvents = function(el) 676{ 677 if (el) 678 return BX.adjust(el, {events: BX.hoverEvents()}); 679 else 680 return {mouseover: BX.hoverEventsHover, mouseout: BX.hoverEventsHout}; 681}; 682 683BX.hoverEventsHover = function(){BX.addClass(this,'bx-hover');this.BXHOVER=true;}; 684BX.hoverEventsHout = function(){BX.removeClass(this,'bx-hover');this.BXHOVER=false;}; 685 686BX.focusEvents = function(el) 687{ 688 if (el) 689 return BX.adjust(el, {events: BX.focusEvents()}); 690 else 691 return {mouseover: BX.focusEventsFocus, mouseout: BX.focusEventsBlur}; 692}; 693 694BX.focusEventsFocus = function(){BX.addClass(this,'bx-focus');this.BXFOCUS=true;}; 695BX.focusEventsBlur = function(){BX.removeClass(this,'bx-focus');this.BXFOCUS=false;}; 696 697BX.setUnselectable = function(node) 698{ 699 node.style.userSelect = node.style.MozUserSelect = node.style.WebkitUserSelect = node.style.KhtmlUserSelect = node.style = 'none'; 700 node.setAttribute('unSelectable', 'on'); 701}; 702 703BX.setSelectable = function(node) 704{ 705 node.style.userSelect = node.style.MozUserSelect = node.style.WebkitUserSelect = node.style.KhtmlUserSelect = node.style = ''; 706 node.removeAttribute('unSelectable'); 707}; 708 709BX.styleIEPropertyName = function(name) 710{ 711 if (name == 'float') 712 name = BX.browser.IsIE() ? 'styleFloat' : 'cssFloat'; 713 else 714 { 715 var res = BX.browser.isPropertySupported(name); 716 if (res) 717 { 718 name = res; 719 } 720 else 721 { 722 var reg = /(\-([a-z]){1})/g; 723 if (reg.test(name)) 724 { 725 name = name.replace(reg, function () {return arguments[2].toUpperCase();}); 726 } 727 } 728 } 729 return name; 730}; 731 732/* CSS-notation should be used here */ 733BX.style = function(el, property, value) 734{ 735 if (!BX.type.isElementNode(el)) 736 return null; 737 738 if (value == null) 739 { 740 var res; 741 742 if(el.currentStyle) 743 res = el.currentStyle[BX.styleIEPropertyName(property)]; 744 else if(window.getComputedStyle) 745 { 746 var q = BX.browser.isPropertySupported(property, true); 747 if (!!q) 748 property = q; 749 750 res = BX.GetContext(el).getComputedStyle(el, null).getPropertyValue(property); 751 } 752 753 if(!res) 754 res = ''; 755 return res; 756 } 757 else 758 { 759 el.style[BX.styleIEPropertyName(property)] = value; 760 return el; 761 } 762}; 763 764BX.focus = function(el) 765{ 766 try 767 { 768 el.focus(); 769 return true; 770 } 771 catch (e) 772 { 773 return false; 774 } 775}; 776 777BX.firstChild = function(el) 778{ 779 var e = el.firstChild;
780 while (e && !BX.type.isElementNode(e)) 781 { 782 e = e.nextSibling; 783 } 784 785 return e; 786}; 787 788BX.lastChild = function(el) 789{ 790 var e = el.lastChild; 791 while (e && !BX.type.isElementNode(e)) 792 { 793 e = e.previousSibling; 794 } 795 796 return e; 797}; 798 799BX.previousSibling = function(el) 800{ 801 var e = el.previousSibling; 802 while (e && !BX.type.isElementNode(e)) 803 { 804 e = e.previousSibling; 805 } 806 807 return e; 808}; 809 810BX.nextSibling = function(el) 811{ 812 var e = el.nextSibling; 813 while (e && !BX.type.isElementNode(e)) 814 { 815 e = e.nextSibling; 816 } 817 818 return e; 819}; 820 821/* 822 params: { 823 obj : html node 824 className : className value 825 recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true 826 } 827 828 Search all nodes with className 829*/ 830BX.findChildrenByClassName = function(obj, className, recursive) 831{ 832 if(!obj || !obj.childNodes) return null; 833 834 var result = []; 835 if (typeof(obj.getElementsByClassName) == 'undefined') 836 { 837 recursive = recursive !== false; 838 result = BX.findChildren(obj, {className : className}, recursive); 839 } 840 else 841 { 842 var col = obj.getElementsByClassName(className); 843 for (i=0,l=col.length;i<l;i++) 844 { 845 result[i] = col[i]; 846 } 847 } 848 return result; 849}; 850 851/* 852 params: { 853 obj : html node 854 className : className value 855 recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true 856 } 857 858 Search first node with className 859*/ 860BX.findChildByClassName = function(obj, className, recursive) 861{ 862 if(!obj || !obj.childNodes) return null; 863 864 var result = null; 865 if (typeof(obj.getElementsByClassName) == 'undefined') 866 { 867 recursive = recursive !== false; 868 result = BX.findChild(obj, {className : className}, recursive); 869 } 870 else 871 { 872 var col = obj.getElementsByClassName(className); 873 if (col && typeof(col[0]) != 'undefined') 874 { 875 result = col[0]; 876 } 877 else 878 { 879 result = null; 880 } 881 } 882 return result; 883}; 884 885/* 886 params: { 887 tagName|tag : 'tagName', 888 className|class : 'className', 889 attribute : {attribute : value, attribute : value} | attribute | [attribute, attribute....], 890 property : {prop: value, prop: value} | prop | [prop, prop] 891 } 892 893 all values can be RegExps or strings 894*/ 895BX.findChildren = function(obj, params, recursive) 896{ 897 return BX.findChild(obj, params, recursive, true); 898}; 899 900BX.findChild = function(obj, params, recursive, get_all) 901{ 902 if(!obj || !obj.childNodes) return null; 903 904 recursive = !!recursive; get_all = !!get_all; 905 906 var n = obj.childNodes.length, result = []; 907 908 for (var j=0; j<n; j++) 909 { 910 var child = obj.childNodes[j]; 911 912 if (_checkNode(child, params)) 913 { 914 if (get_all) 915 result.push(child); 916 else 917 return child; 918 } 919 920 if(recursive == true) 921 { 922 var res = BX.findChild(child, params, recursive, get_all); 923 if (res) 924 { 925 if (get_all) 926 result = BX.util.array_merge(result, res); 927 else 928 return res; 929 } 930 } 931 } 932 933 if (get_all || result.length > 0) 934 return result; 935 else 936 return null; 937}; 938 939BX.findParent = function(obj, params, maxParent) 940{ 941 if(!obj) 942 return null; 943 944 var o = obj; 945 while(o.parentNode) 946 { 947 var parent = o.parentNode; 948 949 if (_checkNode(parent, params)) 950 return parent; 951 952 o = parent; 953 954 if (!!maxParent && 955 (BX.type.isFunction(maxParent) 956 || typeof maxParent == 'object')) 957 { 958 if (BX.type.isElementNode(maxParent)) 959 { 960 if (o == maxParent) 961 break; 962 } 963 else 964 { 965 if (_checkNode(o, maxParent)) 966 break; 967 } 968 } 969 } 970 return null; 971}; 972 973BX.findNextSibling = function(obj, params) 974{ 975 if(!obj) 976 return null; 977 var o = obj; 978 while(o.nextSibling) 979 { 980 var sibling = o.nextSibling; 981 if (_checkNode(sibling, params)) 982 return sibling; 983 o = sibling; 984 } 985 return null; 986}; 987 988BX.findPreviousSibling = function(obj, params) 989{ 990 if(!obj) 991 return null; 992 993 var o = obj; 994 while(o.previousSibling) 995 { 996 var sibling = o.previousSibling; 997 if(_checkNode(sibling, params)) 998 return sibling; 999 o = sibling; 1000 } 1001 return null; 1002}; 1003 1004BX.checkNode = function(obj, params) 1005{ 1006 return _checkNode(obj, params); 1007}; 1008 1009BX.findFormElements = function(form) 1010{ 1011 if (BX.type.isString(form)) 1012 form = document.forms[form]||BX(form); 1013 1014 var res = []; 1015 1016 if (BX.type.isElementNode(form)) 1017 { 1018 if (form.tagName.toUpperCase() == 'FORM') 1019 { 1020 res = form.elements; 1021 } 1022 else 1023 { 1024 res = BX.findChildren(form, CHECK_FORM_ELEMENTS, true); 1025 } 1026 } 1027 1028 return res; 1029}; 1030 1031BX.isParentForNode = function(whichNode, forNode) 1032{ 1033
1034 if(!BX.type.isDomNode(whichNode) || !BX.type.isDomNode(forNode)) 1035 return false; 1036 1037 while(true){ 1038 1039 if(whichNode == forNode) 1040 return true; 1041 1042 if(forNode && forNode.parentNode) 1043 forNode = forNode.parentNode; 1044 else 1045 break; 1046 } 1047 1048 return false; 1049}; 1050 1051BX.clone = function(obj, bCopyObj) 1052{ 1053 var _obj, i, l; 1054 if (bCopyObj !== false) 1055 bCopyObj = true; 1056 1057 if (obj === null) 1058 return null; 1059 1060 if (BX.type.isDomNode(obj)) 1061 { 1062 _obj = obj.cloneNode(bCopyObj); 1063 } 1064 else if (typeof obj == 'object') 1065 { 1066 if (BX.type.isArray(obj)) 1067 { 1068 _obj = []; 1069 for (i=0,l=obj.length;i<l;i++) 1070 { 1071 if (typeof obj[i] == "object" && bCopyObj) 1072 _obj[i] = BX.clone(obj[i], bCopyObj); 1073 else 1074 _obj[i] = obj[i]; 1075 } 1076 } 1077 else 1078 { 1079 _obj = {}; 1080 if (obj.constructor) 1081 { 1082 if (BX.type.isDate(obj)) 1083 _obj = new Date(obj); 1084 else 1085 _obj = new obj.constructor(); 1086 } 1087 1088 for (i in obj) 1089 { 1090 if (typeof obj[i] == "object" && bCopyObj) 1091 _obj[i] = BX.clone(obj[i], bCopyObj); 1092 else 1093 _obj[i] = obj[i]; 1094 } 1095 } 1096 1097 } 1098 else 1099 { 1100 _obj = obj; 1101 } 1102 1103 return _obj; 1104}; 1105 1106// access private. use BX.mergeEx instead. 1107// todo: refactor BX.merge, make it work through BX.mergeEx 1108BX.merge = function(){ 1109 var arg = Array.prototype.slice.call(arguments); 1110 1111 if(arg.length < 2) 1112 return {}; 1113 1114 var result = arg.shift(); 1115 1116 for(var i = 0; i < arg.length; i++) 1117 { 1118 for(var k in arg[i]){ 1119 1120 if(typeof arg[i] == 'undefined' || arg[i] == null) 1121 continue; 1122 1123 if(arg[i].hasOwnProperty(k)){ 1124 1125 if(typeof arg[i][k] == 'undefined' || arg[i][k] == null) 1126 continue; 1127 1128 if(typeof arg[i][k] == 'object' && !BX.type.isDomNode(arg[i][k]) && (typeof arg[i][k]['isUIWidget'] == 'undefined')){ 1129 1130 // go deeper 1131 1132 var isArray = 'length' in arg[i][k]; 1133 1134 if(typeof result[k] != 'object') 1135 result[k] = isArray ? [] : {}; 1136 1137 if(isArray) 1138 BX.util.array_merge(result[k], arg[i][k]); 1139 else 1140 BX.merge(result[k], arg[i][k]); 1141 1142 }else 1143 result[k] = arg[i][k]; 1144 } 1145 } 1146 } 1147 1148 return result; 1149}; 1150 1151BX.mergeEx = function() 1152{ 1153 var arg = Array.prototype.slice.call(arguments); 1154 if(arg.length < 2) 1155 { 1156 return {}; 1157 } 1158 1159 var result = arg.shift(); 1160 for (var i = 0; i < arg.length; i++) 1161 { 1162 for (var k in arg[i]) 1163 { 1164 if (typeof arg[i] == "undefined" || arg[i] == null || !arg[i].hasOwnProperty(k)) 1165 { 1166 continue; 1167 } 1168 1169 if (BX.type.isPlainObject(arg[i][k]) && BX.type.isPlainObject(result[k])) 1170 { 1171 BX.mergeEx(result[k], arg[i][k]); 1172 } 1173 else 1174 { 1175 result[k] = BX.type.isPlainObject(arg[i][k]) ? BX.clone(arg[i][k]) : arg[i][k]; 1176 } 1177 } 1178 } 1179 1180 return result; 1181}; 1182 1183/* events */ 1184BX.bind = function(el, evname, func) 1185{ 1186 if (!el) 1187 { 1188 return; 1189 } 1190 1191 if (evname === 'mousewheel') 1192 { 1193 BX.bind(el, 'DOMMouseScroll', func); 1194 } 1195 else if (evname === 'transitionend') 1196 { 1197 BX.bind(el, 'webkitTransitionEnd', func); 1198 BX.bind(el, 'msTransitionEnd', func); 1199 BX.bind(el, 'oTransitionEnd', func); 1200 // IE8-9 doesn't support this feature! 1201 } 1202 else if (evname === 'bxchange') 1203 { 1204 BX.bind(el, "change", func); 1205 BX.bind(el, "cut", func); 1206 BX.bind(el, "paste", func); 1207 BX.bind(el, "drop", func); 1208 BX.bind(el, "keyup", func); 1209 1210 return; 1211 } 1212 else if (evname === 'fullscreenchange') 1213 { 1214 if (document.cancelFullScreen) 1215 BX.bind(el, "fullscreenchange", func); 1216 else if (document.mozCancelFullScreen) 1217 BX.bind(el, "mozfullscreenchange", func); 1218 else if (document.webkitCancelFullScreen) 1219 BX.bind(el, "webkitfullscreenchange", func); 1220 } 1221 1222 if (el.addEventListener) // Gecko / W3C 1223 { 1224 el.addEventListener(evname, func, false); 1225 } 1226 else if (el.attachEvent) // IE 1227 { 1228 el.attachEvent("on" + evname, BX.proxy(func, el)); 1229 } 1230 else 1231 { 1232 try 1233 { 1234 el["on" + evname] = func; 1235 } 1236 catch(e) 1237 { 1238 BX.debug(e) 1239 } 1240 } 1241 1242 eventsList[eventsList.length] = {'element': el, 'event': evname, 'fn': func}; 1243}; 1244 1245BX.unbind = function(el, evname, func) 1246{ 1247 if (!el) 1248 { 1249 return; 1250 } 1251 1252 if (evname === 'mousewheel') 1253 { 1254 BX.unbind(el, 'DOMMouseScroll', func); 1255 } 1256 else if (evname === 'transitionend') 1257 { 1258 BX.unbind(el, 'webkitTransitionEnd', func); 1259 BX.unbind(el, 'msTransitionEnd', func); 1260 BX.unbind(el, 'oTransitionEnd', func); 1261 } 1262 else if (evname === 'bxchange') 1263 { 1264 BX.unbind(el, "change", func); 1265 BX.unbind(el, "cut", func); 1266 BX.unbind(el, "paste", func); 1267 BX.unbind(el, "drop", func); 1268 BX.unbind(el, "keyup", func); 1269 1270 return; 1271 } 1272 1273 if(el.removeEventListener) // Gecko / W3C 1274 { 1275 el.removeEventListener(evname, func, false); 1276 } 1277 else if(el.detachEvent) // IE 1278 { 1279 el.detachEvent("on" + evname, BX.proxy(func, el)); 1280 } 1281 else 1282 { 1283 el["on" + evname] = null; 1284 } 1285}; 1286 1287BX.getEventButton = function(e) 1288{ 1289 e = e || window.event; 1290 1291 var flags = 0; 1292 1293 if (typeof e.which != 'undefined') 1294 { 1295 switch (e.which) 1296 { 1297 case 1: flags = flags|BX.MSLEFT; break; 1298 case 2: flags = flags|BX.MSMIDDLE; break; 1299 case 3: flags = flags|BX.MSRIGHT; break; 1300 } 1301 } 1302 else if (typeof e.button != 'undefined') 1303 { 1304 flags = event.button; 1305 } 1306 1307 return flags || BX.MSLEFT; 1308}; 1309 1310BX.unbindAll = function(el) 1311{ 1312 if (!el) 1313 return; 1314 1315 for (var i=0,len=eventsList.length; i<len; i++) 1316 { 1317 try 1318 { 1319 if (eventsList[i] && (null==el || el==eventsList[i].element)) 1320 { 1321 BX.unbind(eventsList[i].element, eventsList[i].event, eventsList[i].fn); 1322 eventsList[i] = null; 1323 } 1324 } 1325 catch(e){} 1326 } 1327 1328 if (null==el) 1329 { 1330 eventsList = []; 1331 } 1332}; 1333 1334var captured_events = null, _bind = null; 1335BX.CaptureEvents = function(el_c, evname_c) 1336{ 1337 if (_bind) 1338 return; 1339 1340 _bind = BX.bind; 1341 captured_events = []; 1342 1343 BX.bind = function(el, evname, func) 1344 { 1345 if (el === el_c && evname === evname_c) 1346 captured_events.push(func); 1347 1348 _bind.apply(this, arguments); 1349 } 1350}; 1351 1352BX.CaptureEventsGet = function() 1353{ 1354 if (_bind) 1355 { 1356 BX.bind = _bind; 1357 1358 var captured = captured_events; 1359 1360 _bind = null; 1361 captured_events = null; 1362 return captured; 1363 } 1364 return null; 1365}; 1366 1367// Don't even try to use it for submit event! 1368BX.fireEvent = function(ob,ev) 1369{ 1370 var result = false, e = null; 1371 if (BX.type.isDomNode(ob)) 1372 { 1373 result = true; 1374 if (document.createEventObject) 1375 { 1376 // IE 1377 if (eventTypes[ev] != 'MouseEvent') 1378 { 1379 e = document.createEventObject(); 1380 e.type = ev; 1381 result = ob.fireEvent('on' + ev, e); 1382 } 1383 1384 if (ob[ev]) 1385 { 1386 ob[ev](); 1387 } 1388 } 1389 else 1390 { 1391 // non-IE 1392 e = null; 1393 1394 switch (eventTypes[ev]) 1395 { 1396 case 'MouseEvent': 1397 e = document.createEvent('MouseEvent'); 1398 try 1399 { 1400 e.initMouseEvent(ev, true, true, top, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); 1401 } 1402 catch (initException) 1403 { 1404 e.initMouseEvent(ev, true, true, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); 1405 } 1406 1407 break; 1408 default: 1409 e = document.createEvent('Event'); 1410 e.initEvent(ev, true, true); 1411 } 1412 1413 result = ob.dispatchEvent(e); 1414 } 1415 } 1416 1417 return result; 1418}; 1419 1420BX.getWheelData = function(e) 1421{ 1422 e = e || window.event; 1423 e.wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40; 1424 return e.wheelData; 1425}; 1426 1427BX.proxy_context = null; 1428 1429BX.delegate = function (func, thisObject) 1430{ 1431 if (!func || !thisObject) 1432 return func; 1433 1434 return function() { 1435 var cur = BX.proxy_context; 1436 BX.proxy_context = this; 1437 var res = func.apply(thisObject, arguments); 1438 BX.proxy_context = cur; 1439 return res; 1440 } 1441}; 1442 1443BX.delegateLater = function (func_name, thisObject, contextObject) 1444{ 1445 return function() 1446 { 1447 if (thisObject[func_name]) 1448 { 1449 var cur = BX.proxy_context; 1450 BX.proxy_context = this; 1451 var res = thisObject[func_name].apply(contextObject||thisObject, arguments); 1452 BX.proxy_context = cur; 1453 return res; 1454 } 1455 return null; 1456 } 1457}; 1458 1459BX._initObjectProxy = function(thisObject) 1460{ 1461 if (typeof thisObject['__proxy_id_' + proxySalt] == 'undefined') 1462 { 1463 thisObject['__proxy_id_' + proxySalt] = proxyList.length; 1464 proxyList[thisObject['__proxy_id_' + proxySalt]] = {}; 1465 } 1466}; 1467 1468BX.proxy = function(func, thisObject) 1469{ 1470 if (!func || !thisObject) 1471 return func; 1472 1473 BX._initObjectProxy(thisObject); 1474 1475 if (typeof func['__proxy_id_' + proxySalt] == 'undefined') 1476 func['__proxy_id_' + proxySalt] = proxyId++; 1477 1478 if (!proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]]) 1479 proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]] = BX.delegate(func, thisObject); 1480 1481 return proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]]; 1482}; 1483 1484BX.defer = function(func, thisObject) 1485{ 1486 if (!!thisObject) 1487 return BX.defer_proxy(func, thisObject); 1488 else 1489 return function() { 1490 var arg = arguments; 1491 setTimeout(function(){func.apply(this,arg)}, 10); 1492 }; 1493}; 1494 1495BX.defer_proxy = function(func, thisObject) 1496{ 1497 if (!func || !thisObject) 1498 return func; 1499 1500 BX.proxy(func, thisObject); 1501 1502 this._initObjectProxy(thisObject); 1503 1504 if (typeof func['__defer_id_' + proxySalt] == 'undefined') 1505 func['__defer_id_' + proxySalt] = proxyId++; 1506 1507 if (!proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]]) 1508 { 1509 proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]] = BX.defer(
1509BX.delegate(func, thisObject)); 1510 } 1511 1512 return proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]]; 1513}; 1514 1515BX.once = function(el, evname, func) 1516{ 1517 if (typeof func['__once_id_' + evname + '_' + proxySalt] == 'undefined') 1518 { 1519 func['__once_id_' + evname + '_' + proxySalt] = proxyId++; 1520 } 1521 1522 this._initObjectProxy(el); 1523 1524 if (!proxyList[el['__proxy_id_' + proxySalt]][func['__once_id_' + evname + '_' + proxySalt]]) 1525 { 1526 var g = function() 1527 { 1528 BX.unbind(el, evname, g); 1529 func.apply(this, arguments); 1530 }; 1531 1532 proxyList[el['__proxy_id_' + proxySalt]][func['__once_id_' + evname + '_' + proxySalt]] = g; 1533 } 1534 1535 return proxyList[el['__proxy_id_' + proxySalt]][func['__once_id_' + evname + '_' + proxySalt]]; 1536}; 1537 1538BX.bindDelegate = function (elem, eventName, isTarget, handler) 1539{ 1540 var h = BX.delegateEvent(isTarget, handler); 1541 BX.bind(elem, eventName, h); 1542 return h; 1543}; 1544 1545BX.delegateEvent = function(isTarget, handler) 1546{ 1547 return function(e) 1548 { 1549 e = e || window.event; 1550 var target = e.target || e.srcElement; 1551 1552 while (target != this) 1553 { 1554 if (_checkNode(target, isTarget)) 1555 { 1556 return handler.call(target, e); 1557 } 1558 if (target && target.parentNode) 1559 target = target.parentNode; 1560 else 1561 break; 1562 } 1563 return null; 1564 } 1565}; 1566 1567BX.False = function() {return false;}; 1568BX.DoNothing = function() {}; 1569 1570// TODO: also check event handlers set via BX.bind() 1571BX.denyEvent = function(el, ev) 1572{ 1573 deniedEvents.push([el, ev, el['on' + ev]]); 1574 el['on' + ev] = BX.DoNothing; 1575}; 1576 1577BX.allowEvent = function(el, ev) 1578{ 1579 for(var i=0, len=deniedEvents.length; i<len; i++) 1580 { 1581 if (deniedEvents[i][0] == el && deniedEvents[i][1] == ev) 1582 { 1583 el['on' + ev] = deniedEvents[i][2]; 1584 BX.util.deleteFromArray(deniedEvents, i); 1585 return; 1586 } 1587 } 1588}; 1589 1590BX.fixEventPageXY = function(event) 1591{ 1592 BX.fixEventPageX(event); 1593 BX.fixEventPageY(event); 1594 return event; 1595}; 1596 1597BX.fixEventPageX = function(event) 1598{ 1599 if (event.pageX == null && event.clientX != null) 1600 { 1601 event.pageX = 1602 event.clientX + 1603 (document.documentElement && document.documentElement.scrollLeft || document.body && document.body.scrollLeft || 0) - 1604 (document.documentElement.clientLeft || 0); 1605 } 1606 1607 return event; 1608}; 1609 1610BX.fixEventPageY = function(event) 1611{ 1612 if (event.pageY == null && event.clientY != null) 1613 { 1614 event.pageY = 1615 event.clientY + 1616 (document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0) - 1617 (document.documentElement.clientTop || 0); 1618 } 1619 1620 return event; 1621}; 1622 1623/** 1624 * @deprecated 1625 * @see e.preventDefault() 1626 */ 1627BX.PreventDefault = function(e) 1628{ 1629 if(!e) e = window.event; 1630 if(e.stopPropagation) 1631 { 1632 e.preventDefault(); 1633 e.stopPropagation(); 1634 } 1635 else 1636 { 1637 e.cancelBubble = true; 1638 e.returnValue = false; 1639 } 1640 return false; 1641}; 1642 1643BX.eventReturnFalse = function(e) 1644{ 1645 e=e||window.event; 1646 if (e && e.preventDefault) e.preventDefault(); 1647 else e.returnValue = false; 1648 return false; 1649}; 1650 1651BX.eventCancelBubble = function(e) 1652{ 1653 e=e||window.event; 1654 if(e && e.stopPropagation) 1655 e.stopPropagation(); 1656 else 1657 e.cancelBubble = true; 1658}; 1659 1660/* custom events */ 1661/* 1662 BX.addCustomEvent(eventObject, eventName, eventHandler) - set custom event handler for particular object 1663 BX.addCustomEvent(eventName, eventHandler) - set custom event handler for all objects 1664*/ 1665BX.addCustomEvent = function(eventObject, eventName, eventHandler) 1666{ 1667 /* shift parameters for short version */ 1668 if (BX.type.isString(eventObject)) 1669 { 1670 eventHandler = eventName; 1671 eventName = eventObject; 1672 eventObject = window; 1673 } 1674 1675 eventName = eventName.toUpperCase(); 1676 1677 if (!customEvents[eventName]) 1678 customEvents[eventName] = []; 1679 1680 customEvents[eventName].push( 1681 { 1682 handler: eventHandler, 1683 obj: eventObject 1684 } 1685 ); 1686}; 1687 1688BX.removeCustomEvent = function(eventObject, eventName, eventHandler) 1689{ 1690 /* shift parameters for short version */ 1691 if (BX.type.isString(eventObject)) 1692 { 1693 eventHandler = eventName; 1694 eventName = eventObject; 1695 eventObject = window; 1696 } 1697 1698 eventName = eventName.toUpperCase(); 1699 1700 if (!customEvents[eventName]) 1701 return; 1702 1703 for (var i = 0, l = customEvents[eventName].length; i < l; i++) 1704 { 1705 if (!customEvents[eventName][i]) 1706 continue; 1707 if (customEvents[eventName][i].handler == eventHandler && customEvents[eventName][i].obj == eventObject) 1708 { 1709 delete customEvents[eventName][i]; 1710 return; 1711 } 1712 } 1713}; 1714 1715// Warning! Don't use secureParams with DOM nodes in arEventParam
1715s 1716BX.onCustomEvent = function(eventObject, eventName, arEventParams, secureParams) 1717{ 1718 /* shift parameters for short version */ 1719 if (BX.type.isString(eventObject)) 1720 { 1721 secureParams = arEventParams; 1722 arEventParams = eventName; 1723 eventName = eventObject; 1724 eventObject = window; 1725 } 1726 1727 eventName = eventName.toUpperCase(); 1728 1729 if (!customEvents[eventName]) 1730 return; 1731 1732 if (!arEventParams) 1733 arEventParams = []; 1734 1735 var h; 1736 for (var i = 0, l = customEvents[eventName].length; i < l; i++) 1737 { 1738 h = customEvents[eventName][i]; 1739 if (!h || !h.handler) 1740 continue; 1741 1742 if (h.obj == window || /*eventObject == window || */h.obj == eventObject) //- only global event handlers will be called 1743 { 1744 h.handler.apply(eventObject, !!secureParams ? BX.clone(arEventParams) : arEventParams); 1745 } 1746 } 1747}; 1748 1749BX.bindDebouncedChange = function(node, fn, fnInstant, timeout, ctx) 1750{ 1751 ctx = ctx || window; 1752 timeout = timeout || 300; 1753 1754 var dataTag = 'bx-dc-previous-value'; 1755 BX.data(node, dataTag, node.value); 1756 1757 var act = function(fn, val){ 1758 1759 var pVal = BX.data(node, dataTag); 1760 1761 if(typeof pVal == 'undefined' || pVal != val){ 1762 if(typeof ctx != 'object') 1763 fn(val); 1764 else 1765 fn.apply(ctx, [val]); 1766 } 1767 }; 1768 1769 var actD = BX.debounce(function(){ 1770 var val = node.value; 1771 act(fn, val); 1772 BX.data(node, dataTag, val); 1773 }, timeout); 1774 1775 BX.bind(node, 'keyup', actD); 1776 BX.bind(node, 'change', actD); 1777 BX.bind(node, 'input', actD); 1778 1779 if(BX.type.isFunction(fnInstant)){ 1780 1781 var actI = function(){ 1782 act(fnInstant, node.value); 1783 }; 1784 1785 BX.bind(node, 'keyup', actI); 1786 BX.bind(node, 'change', actI); 1787 BX.bind(node, 'input', actI); 1788 } 1789}; 1790 1791BX.parseJSON = function(data, context) 1792{ 1793 var result = null; 1794 if (BX.type.isString(data)) 1795 { 1796 try { 1797 if (data.indexOf("\n") >= 0) 1798 eval('result = ' + data); 1799 else 1800 result = (new Function("return " + data))(); 1801 } catch(e) { 1802 BX.onCustomEvent(context, 'onParseJSONFailure', [data, context]) 1803 } 1804 } 1805 else if(BX.type.isPlainObject(data)) 1806 { 1807 return data; 1808 } 1809 1810 return result; 1811}; 1812 1813/* ready */ 1814BX.isReady = false; 1815BX.ready = function(handler) 1816{ 1817 bindReady(); 1818 1819 if (!BX.type.isFunction(handler)) 1820 { 1821 BX.debug('READY: not a function! ', handler); 1822 } 1823 else 1824 { 1825 if (BX.isReady) 1826 handler.call(document); 1827 else if (readyList) 1828 readyList.push(handler); 1829 } 1830}; 1831 1832BX.submit = function(obForm, action_name, action_value, onAfterSubmit) 1833{ 1834 action_name = action_name || 'save'; 1835 if (!obForm['BXFormSubmit_' + action_name]) 1836 { 1837 obForm['BXFormSubmit_' + action_name] = obForm.appendChild(BX.create('INPUT', { 1838 'props': { 1839 'type': 'submit', 1840 'name': action_name, 1841 'value': action_value || 'Y' 1842 }, 1843 'style': { 1844 'display': 'none' 1845 } 1846 })); 1847 } 1848 1849 if (obForm.sessid) 1850 obForm.sessid.value = BX.bitrix_sessid(); 1851 1852 setTimeout(BX.delegate(function() {BX.fireEvent(this, 'click'); if (onAfterSubmit) onAfterSubmit();}, obForm['BXFormSubmit_' + action_name]), 10); 1853}; 1854 1855// returns function which runs fn in timeout ms after returned function is finished being called 1856BX.debounce = function(fn, timeout, ctx) 1857{ 1858 var timer = 0; 1859 1860 return function() 1861 { 1862 ctx = ctx || this; 1863 var args = arguments; 1864 1865 clearTimeout(timer); 1866 1867 timer = setTimeout(function() 1868 { 1869 fn.apply(ctx, args); 1870 }, timeout); 1871 } 1872}; 1873 1874// returns function which runs fn and repeats every timeout ms while returned function is being called 1875BX.throttle = function(fn, timeout, ctx) 1876{ 1877 1878 var timer = 0, 1879 args = null, 1880 invoke; 1881 1882 return function() 1883 { 1884 ctx = ctx || this; 1885 args = arguments; 1886 invoke = true; 1887 1888 if(!timer) 1889 { 1890 var q = function() 1891 { 1892 if(invoke) 1893 { 1894 fn.apply(ctx, args); 1895 invoke = false; 1896 timer = setTimeout(q, timeout); 1897 } 1898 else 1899 { 1900 timer = null; 1901 } 1902 }; 1903 q(); 1904 } 1905 }; 1906}; 1907 1908/* browser detection */ 1909BX.browser = { 1910 1911 IsIE: function() 1912 { 1913 return bIE; 1914 }, 1915 1916 IsIE6: function() 1917 { 1918 return (/MSIE 6/i.test(navigator.userAgent)); 1919 }, 1920 1921 IsIE7: function() 1922 { 1923 return (/MSIE 7/i.test(navigator.userAgent)); 1924 }, 1925 1926 IsIE8: function() 1927 { 1928 return (/MSIE 8/i.test(navigator.userAgent)); 1929 }, 1930 1931 IsIE9: function() 1932 { 1933 return !!document.documentMode && document.documentMode >= 9; 1934 }, 1935 1936 IsIE10: function() 1937 { 1938 return !!document.documentMode && document.documentMode >= 10; 1939 }, 1940 1941 IsIE11: function() 1942 { 1943 return BX.browser.DetectIeVersion() >= 11; 1944 }, 1945 1946 IsOpera: function() 1947 { 1948 return bOpera; 1949 }, 1950 1951 IsSafari: function() 1952 { 1953 return bSafari; 1954 }, 1955 1956 IsFirefox: function() 1957 { 1958 return bFirefox; 1959 }, 1960 1961 IsChrome: function() 1962 { 1963 return bChrome; 1964 }, 1965 1966 IsMac: function() 1967 { 1968 return (/Macintosh/i.test(navigator.userAgent)); 1969 }, 1970 1971 IsAndroid: function() 1972 { 1973 return (/Android/i.test(navigator.userAgent)); 1974 }, 1975 1976 IsIOS: function() 1977 { 1978 return (/(iPad;)|(iPhone;)/i.test(navigator.userAgent)); 1979 }, 1980 1981 IsMobile: function() 1982 { 1983 return (/(ipad|iphone|android|mobile|touch)/i.test(navigator.userAgent)); 1984 }, 1985 1986 DetectIeVersion: function() 1987 { 1988 if(BX.browser.IsOpera() || BX.browser.IsSafari() || BX.browser.IsFirefox() || BX.browser.IsChrome()) 1989 { 1990 return -1; 1991 } 1992 1993 var rv = -1; 1994 if (!!(window.MSStream) && !(window.ActiveXObject) && ("ActiveXObject" in window)) 1995 { 1996 //Primary check for IE 11 based on ActiveXObject behaviour (please see http://msdn.microsoft.com/en-us
1996/library/ie/dn423948%28v=vs.85%29.aspx) 1997 rv = 11; 1998 } 1999 else if (BX.browser.IsIE10()) 2000 { 2001 rv = 10; 2002 } 2003 else if (BX.browser.IsIE9()) 2004 { 2005 rv = 9; 2006 } 2007 else if (BX.browser.IsIE()) 2008 { 2009 rv = 8; 2010 } 2011 2012 if (rv == -1 || rv == 8) 2013 { 2014 var re; 2015 if (navigator.appName == "Microsoft Internet Explorer") 2016 { 2017 re = new RegExp("MSIE ([0-9]+[\.0-9]*)"); 2018 if (re.exec(navigator.userAgent) != null) 2019 rv = parseFloat( RegExp.$1 ); 2020 } 2021 else if (navigator.appName == "Netscape") 2022 { 2023 //Alternative check for IE 11 2024 rv = 11; 2025 re = new RegExp("Trident/.*rv:([0-9]+[\.0-9]*)"); 2026 if (re.exec(navigator.userAgent) != null) 2027 rv = parseFloat( RegExp.$1 ); 2028 } 2029 } 2030 2031 return rv; 2032 }, 2033 2034 IsDoctype: function(pDoc) 2035 { 2036 pDoc = pDoc || document; 2037 2038 if (pDoc.compatMode) 2039 return (pDoc.compatMode == "CSS1Compat"); 2040 2041 return (pDoc.documentElement && pDoc.documentElement.clientHeight); 2042 }, 2043 2044 SupportLocalStorage: function() 2045 { 2046 return !!BX.localStorage && !!BX.localStorage.checkBrowser() 2047 }, 2048 2049 addGlobalClass: function() { 2050 2051 var globalClass = "bx-core"; 2052 if (BX.hasClass(document.documentElement, globalClass)) 2053 { 2054 return; 2055 } 2056 2057 //Mobile 2058 if (BX.browser.IsIOS()) 2059 { 2060 globalClass += " bx-ios"; 2061 } 2062 else if (BX.browser.IsMac()) 2063 { 2064 globalClass += " bx-mac"; 2065 } 2066 else if (BX.browser.IsAndroid()) 2067 { 2068 globalClass += " bx-android"; 2069 } 2070 2071 globalClass += (BX.browser.IsMobile() ? " bx-touch" : " bx-no-touch"); 2072 globalClass += (BX.browser.isRetina() ? " bx-retina" : " bx-no-retina"); 2073 2074 //Desktop 2075 var ieVersion = -1; 2076 if (/AppleWebKit/.test(navigator.userAgent)) 2077 { 2078 globalClass += " bx-chrome"; 2079 } 2080 else if ((ieVersion = BX.browser.DetectIeVersion()) > 0) 2081 { 2082 globalClass += " bx-ie bx-ie" + ieVersion; 2083 if (ieVersion > 7 && ieVersion < 10 && !BX.browser.IsDoctype()) 2084 { 2085 // it seems IE10 doesn't have any specific bugs like others event in quirks mode 2086 globalClass += " bx-quirks"; 2087 } 2088 } 2089 else if (/Opera/.test(navigator.userAgent)) 2090 { 2091 globalClass += " bx-opera"; 2092 } 2093 else if (/Gecko/.test(navigator.userAgent)) 2094 { 2095 globalClass += " bx-firefox"; 2096 } 2097 2098 BX.addClass(document.documentElement, globalClass); 2099 }, 2100 2101 isPropertySupported: function(jsProperty, bReturnCSSName) 2102 { 2103 if (!BX.type.isNotEmptyString(jsProperty)) 2104 return false; 2105 2106 var property = jsProperty.indexOf("-") > -1 ? getJsName(jsProperty) : jsProperty; 2107 bReturnCSSName = !!bReturnCSSName; 2108 2109 var ucProperty = property.charAt(0).toUpperCase() + property.slice(1); 2110 var properties = (property + ' ' + ["Webkit", "Moz", "O", "ms"].join(ucProperty + " ") + ucProperty).split(" "); 2111 var obj = document.body || document.documentElement; 2112 2113 for (var i = 0; i < properties.length; i++) 2114 { 2115 var prop = properties[i]; 2116 if (obj.style[prop] !== undefined) 2117 { 2118 var prefix = prop == property 2119 ? "" 2120 : "-" + prop.substr(0, prop.length - property.length).toLowerCase() + "-"; 2121 return bReturnCSSName ? prefix + getCssName(property) : prop; 2122 } 2123 } 2124 2125 function getCssName(propertyName) 2126 { 2127 return propertyName.replace(/([A-Z])/g, function() { return "-" + arguments[1].toLowerCase(); } ) 2128 } 2129 2130 function getJsName(cssName) 2131 { 2132 var reg = /(\-([a-z]){1})/g; 2133 if (reg.test(cssName)) 2134 return cssName.replace(reg, function () {return arguments[2].toUpperCase();}); 2135 else 2136 return cssName; 2137 } 2138 2139 return false; 2140 }, 2141 2142 addGlobalFeatures : function(features, prefix) 2143 { 2144 if (!BX.type.isArray(features)) 2145 return; 2146 2147 var classNames = []; 2148 for (var i = 0; i < features.length; i++) 2149 { 2150 var support = !!BX.browser.isPropertySupported(features[i]); 2151 classNames.push( "bx-" + (support ? "" : "no-") + features[i].toLowerCase()); 2152 } 2153 BX.addClass(document.documentElement, classNames.join(" ")); 2154 }, 2155 2156 isRetina : function() 2157 { 2158 return window.devicePixelRatio && window.devicePixelRatio >= 2; 2159 } 2160}; 2161 2162/* low-level fx funcitons*/ 2163BX.show = function(ob, displayType) 2164{ 2165 if (ob.BXDISPLAY || !_checkDisplay(ob, displayType)) 2166 { 2167 ob.style.display = ob.BXDISPLAY; 2168 } 2169}; 2170 2171BX.hide = function(ob, displayType) 2172{ 2173 if (!ob.BXDISPLAY) 2174 _checkDisplay(ob, displayType); 2175 2176 ob.style.display = 'none'; 2177}; 2178 2179BX.toggle = function(ob, values) 2180{ 2181 if (!values && BX.type.isElementNode(ob)) 2182 { 2183 var bShow = true; 2184 if (ob.BXDISPLAY) 2185 bShow = !_checkDisplay(ob); 2186 else 2187 bShow = ob.style.display == 'none'; 2188 2189 if (bShow) 2190 BX.show(ob); 2191 else 2192 BX.hide(ob); 2193 } 2194 else if (BX.type.isArray(values)) 2195 { 2196 for (var i=0,len=values.length; i<len; i++) 2197 { 2198 if (ob == values[i]) 2199 { 2200 ob = values[i==len-1 ? 0 : i+1]; 2201 break; 2202 } 2203 } 2204 if (i==len) 2205 ob = values[0]; 2206 } 2207 2208 return ob; 2209}; 2210 2211/* some useful util functions */ 2212 2213BX.util = { 2214 array_values: function(ar) 2215 { 2216 if (!BX.type.isArray(ar)) 2217 return BX.util._array_values_ob(ar); 2218 var arv = []; 2219 for(var i=0,l=ar.length;i<l;i++)
2220 if (ar[i] !== null && typeof ar[i] != 'undefined') 2221 arv.push(ar[i]); 2222 return arv; 2223 }, 2224 2225 _array_values_ob: function(ar) 2226 { 2227 var arv = []; 2228 for(var i in ar) 2229 if (ar[i] !== null && typeof ar[i] != 'undefined') 2230 arv.push(ar[i]); 2231 return arv; 2232 }, 2233 2234 array_keys: function(ar) 2235 { 2236 if (!BX.type.isArray(ar)) 2237 return BX.util._array_keys_ob(ar); 2238 var arv = []; 2239 for(var i=0,l=ar.length;i<l;i++) 2240 if (ar[i] !== null && typeof ar[i] != 'undefined') 2241 arv.push(i); 2242 return arv; 2243 }, 2244 2245 _array_keys_ob: function(ar) 2246 { 2247 var arv = []; 2248 for(var i in ar) 2249 if (ar[i] !== null && typeof ar[i] != 'undefined') 2250 arv.push(i); 2251 return arv; 2252 }, 2253 2254 object_keys: function(obj) 2255 { 2256 var arv = []; 2257 for(var k in obj) 2258 { 2259 if(obj.hasOwnProperty(k)) 2260 { 2261 arv.push(k); 2262 } 2263 } 2264 return arv; 2265 }, 2266 2267 array_merge: function(first, second) 2268 { 2269 if (!BX.type.isArray(first)) first = []; 2270 if (!BX.type.isArray(second)) second = []; 2271 2272 var i = first.length, j = 0; 2273 2274 if (typeof second.length === "number") 2275 { 2276 for (var l = second.length; j < l; j++) 2277 { 2278 first[i++] = second[j]; 2279 } 2280 } 2281 else 2282 { 2283 while (second[j] !== undefined) 2284 { 2285 first[i++] = second[j++]; 2286 } 2287 } 2288 2289 first.length = i; 2290 2291 return first; 2292 }, 2293 2294 array_flip: function ( object ) 2295 { 2296 var newObject = {}; 2297 2298 for (var key in object) 2299 { 2300 newObject[object[key]] = key; 2301 } 2302 2303 return newObject; 2304 }, 2305 2306 array_unique: function(ar) 2307 { 2308 var i=0,j,len=ar.length; 2309 if(len<2) return ar; 2310 2311 for (; i<len-1;i++) 2312 { 2313 for (j=i+1; j<len;j++) 2314 { 2315 if (ar[i]==ar[j]) 2316 { 2317 ar.splice(j--,1); len--; 2318 } 2319 } 2320 } 2321 2322 return ar; 2323 }, 2324 2325 in_array: function(needle, haystack) 2326 { 2327 for(var i=0; i<haystack.length; i++) 2328 { 2329 if(haystack[i] == needle) 2330 return true; 2331 } 2332 return false; 2333 }, 2334 2335 array_search: function(needle, haystack) 2336 { 2337 for(var i=0; i<haystack.length; i++) 2338 { 2339 if(haystack[i] == needle) 2340 return i; 2341 } 2342 return -1; 2343 }, 2344 2345 object_search_key: function(needle, haystack) 2346 { 2347 if (typeof haystack[needle] != 'undefined') 2348 return haystack[needle]; 2349 2350 for(var i in haystack) 2351 { 2352 if (typeof haystack[i] == "object") 2353 { 2354 var result = BX.util.object_search_key(needle, haystack[i]); 2355 if (result !== false) 2356 return result; 2357 } 2358 } 2359 return false; 2360 }, 2361 2362 trim: function(s) 2363 { 2364 if (BX.type.isString(s)) 2365 return s.replace(r.ltrim, '').replace(r.rtrim, ''); 2366 else 2367 return s; 2368 }, 2369 2370 urlencode: function(s){return encodeURIComponent(s);}, 2371 2372 // it may also be useful. via sVD. 2373 deleteFromArray: function(ar, ind) {return ar.slice(0, ind).concat(ar.slice(ind + 1));}, 2374 insertIntoArray: function(ar, ind, el) {return ar.slice(0, ind).concat([el]).concat(ar.slice(ind));}, 2375 2376 htmlspecialchars: function(str) 2377 { 2378 if(!str.replace) return str; 2379 2380 return str.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>'); 2381 }, 2382 2383 htmlspecialcharsback: function(str) 2384 { 2385 if(!str.replace) return str; 2386 2387 return str.replace(/\"/g, '"').replace(/'/g, "'").replace(/\</g, '<').replace(/\>/g, '>').replace(/\&/g, '&'); 2388 }, 2389 2390 // Quote regular expression characters plus an optional character 2391 preg_quote: function(str, delimiter) 2392 { 2393 if(!str.replace) 2394 return str; 2395 return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&'); 2396 }, 2397 2398 jsencode: function(str) 2399 { 2400 if (!str || !str.replace) 2401 return str; 2402 2403 var escapes = 2404 [ 2405 { c: "\\\\", r: "\\\\" }, // should be first 2406 { c: "\\t", r: "\\t" }, 2407 { c: "\\n", r: "\\n" }, 2408 { c: "\\r", r: "\\r" }, 2409 { c: "\"", r: "\\\"" }, 2410 { c: "'", r: "\\'" }, 2411 { c: "<", r: "\\x3C" }, 2412 { c: ">", r: "\\x3E" }, 2413 { c: "\\u2028", r: "\\u2028" }, 2414 { c: "\\u2029", r: "\\u2029" } 2415 ]; 2416 for (var i = 0; i < escapes.length; i++) 2417 str = str.replace(new RegExp(escapes[i].c, 'g'), escapes[i].r); 2418 return str; 2419 }, 2420 2421 nl2br: function(str) 2422 { 2423 if (!str || !str.replace) 2424 return str; 2425 2426 return str.replace(/([^>])\n/g, '$1<br/>'); 2427 }, 2428 2429 str_pad: function(input, pad_length, pad_string, pad_type) 2430 { 2431 pad_string = pad_string || ' '; 2432 pad_type = pad_type || 'right'; 2433 input = input.toString(); 2434 2435 if (pad_type == 'left') 2436 return BX.util.str_pad_left(input, pad_length, pad_string); 2437 else 2438 return BX.util.str_pad_right(input, pad_length, pad_string); 2439 2440 }, 2441 2442 str_pad_left: function(input, pad_length, pad_string) 2443 { 2444 var i = input.length, q=pad_string.length; 2445 if (i >= pad_length) return input; 2446 2447 for(;i<pad_length;i+=q) 2448 input = pad_string + input; 2449 2450 return input; 2451 }, 2452 2453 str_pad_right: function(input, pad_length, pad_string) 2454 { 2455 var i = input.length, q=pad_string.length; 2456 if (i >= pad_length) return input; 2457 2458 for(;i<pad_length;i+=q) 2459 input += pad_string; 2460 2461 return input; 2462 }, 2463 2464 strip_tags: function(str) 2465 { 2466 return str.split(/<[^>]+>/g).join(''); 2467 }, 2468 2469 strip_php_tags: function(str) 2470 { 2471 return str.replace(/<\?(.|[\r\n])*?\?>/g, ''); 2472 }, 2473 2474 popup: function(url, width, height) 2475 { 2476 var w, h; 2477 if(BX.browser.IsOpera()) 2478 { 2479 w = document.body.offsetWidth; 2480 h = document.body.offsetHeight; 2481 } 2482 else 2483 { 2484 w = screen.width; 2485 h = screen.height; 2486 } 2487 return window.open(url, '', 'status=no,scrollbars=yes,resizable=yes,width='+width+',height='+height+',top='+Math.floor((h - height)/2-14)+',left='+Math.floor((w - width)/2-5)); 2488 }, 2489 2490 shuffle: function(array) 2491 { 2492 var temporaryValue, randomIndex; 2493 var currentIndex = array.length; 2494 2495 while (0 !== currentIndex) 2496 { 2497 randomIndex = Math.floor(Math.random() * currentIndex); 2498 currentIndex -= 1; 2499 2500 temporaryValue = array[currentIndex]; 2501 array[currentIndex] = array[randomIndex]; 2502 array[randomIndex] = temporaryValue; 2503 } 2504 2505 return array; 2506 }, 2507 2508 // BX.util.objectSort(object, sortBy, sortDir) - Sort object by property 2509 // function params: 1 - object for sort, 2 - sort by property, 3 - sort direction (asc/desc) 2510 // return: sort array [[objectElement], [objectElement]] in sortDir direction 2511 2512 // example: BX.util.objectSort({'L1': {'name': 'Last'}, 'F1': {'name': 'First'}}, 'name', 'asc'); 2513 // return: [{'name' : 'First'}, {'name' : 'Last'}] 2514 objectSort: function(object, sortBy, sortDir) 2515 { 2516 sortDir = sortDir == 'asc'? 'asc': 'desc'; 2517 2518 var arItems = [], i; 2519 for (i in object) 2520 { 2521 if (object.hasOwnProperty(i) && object[i][sortBy]) 2522 { 2523 arItems.push([i, object[i][sortBy]]); 2524 } 2525 } 2526 2527 if (sortDir == 'asc') 2528 { 2529 arItems.sort(function(i, ii) { 2530 var s1, s2; 2531 if (!isNaN(i[1]) && !isNaN(ii[1])) 2532 { 2533 s1 = parseInt(i[1]); 2534 s2 = parseInt(ii[1]); 2535 } 2536 else 2537 { 2538 s1 = i[1].toString().toLowerCase(); 2539 s2 = ii[1].toString().toLowerCase(); 2540 } 2541 2542 if (s1 > s2) 2543 return 1; 2544 else if (s1 < s2) 2545 return -1; 2546 else 2547 return 0; 2548 }); 2549 } 2550 else 2551 { 2552 arItems.sort(function(i, ii) { 2553 var s1, s2; 2554 if (!isNaN(i[1]) && !isNaN(ii[1])) 2555 { 2556 s1 = parseInt(i[1]); 2557 s2 = parseInt(ii[1]); 2558 } 2559 else 2560 { 2561 s1 = i[1].toString().toLowerCase(); 2562 s2 = ii[1].toString().toLowerCase(); 2563 } 2564 if (s1 < s2) 2565 return 1; 2566 else if (s1 > s2) 2567 return -1; 2568 else 2569 return 0; 2570 }); 2571 } 2572 2573 var arReturnArray = Array(); 2574 for (i = 0; i < arItems.length; i++) 2575 { 2576 arReturnArray.push(object[arItems[i][0]]); 2577 } 2578 2579 return arReturnArray; 2580 }, 2581 2582 // #fdf9e5 => {r=253, g=249, b=229} 2583 hex2rgb: function(color) 2584 { 2585 var rgb = color.replace(/[# ]/g,"").replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3').match(/.{2}/g); 2586 for (var i=0; i<3; i++) 2587 { 2588 rgb[i] = parseInt(rgb[i], 16); 2589 } 2590 return {'r':rgb[0],'g':rgb[1],'b':rgb[2]}; 2591 }, 2592 2593 remove_url_param: function(url, param) 2594 { 2595 if (BX.type.isArray(param)) 2596 { 2597 for (var i=0; i<param.length; i++) 2598 { 2599 url = BX.util.remove_url_param(url, param[i]); 2600 } 2601 } 2602 else 2603 { 2604 var pos, params; 2605 if((pos = url.indexOf('?')) >= 0 && pos != url.length-1) 2606 { 2607 params = url.substr(pos + 1); 2608 url = url.substr(0, pos + 1); 2609 2610 params = params.replace(new RegExp('(^|&)'+param+'=[^&#]*', 'i'), ''); 2611 params = params.replace(/^&/, ''); 2612 2613 if(BX.type.isNotEmptyString(params)) 2614 { 2615 url = url + params; 2616 } 2617 else 2618 { 2619 //remove trailing question character 2620 url = url.substr(0, url.length - 1); 2621 } 2622 } 2623 } 2624 return url; 2625 }, 2626 2627 /* 2628 {'param1': 'value1', 'param2': 'value2'} 2629 */ 2630 add_url_param: function(url, params) 2631 { 2632 var param; 2633 var additional = ''; 2634 var hash = ''; 2635 var pos; 2636 2637 for(param in params) 2638 { 2639 url = this.remove_url_param(url, param); 2640 additional += (additional != ''? '&':'') + param + '=' + params[param]; 2641 } 2642 2643 if((pos = url.indexOf('#')) >= 0) 2644 { 2645 hash = url.substr(pos); 2646 url = url.substr(0, pos); 2647 } 2648 2649 if((pos = url.indexOf('?')) >= 0) 2650 { 2651 url = url + (pos != url.length-1? '&' : '') + additional + hash; 2652 } 2653 else 2654 { 2655 url = url + '?' + additional + hash; 2656 } 2657 2658 return url; 2659 }, 2660 2661 even: function(digit) 2662 { 2663 return (parseInt(digit) % 2 == 0); 2664 }, 2665 2666 hashCode: function(str) 2667 { 2668 if(!BX.type.isNotEmptyString(str)) 2669 { 2670 return 0; 2671 } 2672 2673 var hash = 0; 2674 for (var i = 0; i < str.length; i++) 2675 { 2676 var c = str.charCodeAt(i); 2677 hash = ((hash << 5) - hash) + c; 2678 hash = hash & hash; 2679 } 2680 return hash; 2681 }, 2682 2683 getRandomString: function (length) 2684 { 2685 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; 2686 var charQty = chars.length; 2687 2688 length = parseInt(length); 2689 if(isNaN(length) || length <= 0) 2690 { 2691 length = 8; 2692 } 2693 2694 var result = ""; 2695 for (var i = 0; i < length; i++) 2696 { 2697 result += chars.charAt(Math.floor(Math.random() * charQty)); 2698 } 2699 return result; 2700 }, 2701 2702 number_format: function(number, decimals, dec_point, thousands_sep) 2703 { 2704 var i, j, kw, kd, km, sign = ''; 2705 decimals = Math.abs(decimals); 2706 if (isNaN(decimals) || decimals < 0) 2707 { 2708 decimals = 2; 2709 } 2710 dec_point = dec_point || ','; 2711 if (typeof thousands_sep === 'undefined') 2712 thousands_sep = '.'; 2713 2714 number = (+number || 0).toFixed(decimals); 2715 if (number < 0) 2716 { 2717 sign = '-'; 2718 number = -number; 2719 } 2720 2721 i = parseInt(number, 10) + ''; 2722 j = (i.length > 3 ? i.length % 3 : 0); 2723 2724 km = (j ? i.substr(0, j) + thousands_sep : ''); 2725 kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep); 2726 kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, '0').slice(2) : ''); 2727 2728 return sign + km + kw + kd; 2729 }, 2730 2731 getExtension: function (url) 2732 { 2733 url = url || ""; 2734 var items = url.split("?")[0].split("."); 2735 return items[items.length-1].toLowerCase(); 2736 }, 2737 addObjectToForm: function(object, form, prefix) 2738 { 2739 if(!BX.type.isString(prefix)) 2740 { 2741 prefix = ""; 2742 } 2743 2744 for(var key in object) 2745 { 2746 if(!object.hasOwnProperty(key)) 2747 { 2748 continue; 2749 } 2750 2751 var value = object[key]; 2752 var name = prefix !== "" ? (prefix + "[" + key + "]") : key; 2753 if(BX.type.isArray(value)) 2754 { 2755 for(var i = 0; i < value.length; i++) 2756 { 2757 BX.util.addObjectToForm(value[i], form, (name + "[" + i.toString() + "]")); 2758 } 2759 } 2760 else if(BX.type.isPlainObject(value)) 2761 { 2762 BX.util.addObjectToForm(value, form, name); 2763 } 2764 else 2765 {
2766 value = BX.type.isFunction(value.toString) ? value.toString() : ""; 2767 if(value !== "") 2768 { 2769 form.appendChild(BX.create("INPUT", { attrs: { type: "hidden", name: name, value: value } })); 2770 } 2771 } 2772 } 2773 }, 2774 2775 observe: function(object, enable) 2776 { 2777 if (!BX.browser.IsChrome() || typeof(object) != 'object') 2778 return false; 2779 2780 enable = enable !== false; 2781 2782 var observer = function(options) 2783 { 2784 options.forEach(function(option){ 2785 var groupName = option.name + ' changed'; 2786 console.groupCollapsed(groupName); 2787 console.log('Old value: ', option.oldValue); 2788 console.log('New value: ', option.object[option.name]); 2789 console.groupEnd(groupName); 2790 }); 2791 } 2792 if (enable) 2793 { 2794 Object.observe(object, observer); 2795 } 2796 else 2797 { 2798 Object.unobserve(object, observer); 2799 } 2800 2801 return enable; 2802 }, 2803 2804 escapeRegExp: function(str) 2805 { 2806 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 2807 } 2808}; 2809 2810BX.type = { 2811 isString: function(item) { 2812 return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false); 2813 }, 2814 isNotEmptyString: function(item) { 2815 return BX.type.isString(item) ? item.length > 0 : false; 2816 }, 2817 isBoolean: function(item) { 2818 return item === true || item === false; 2819 }, 2820 isNumber: function(item) { 2821 return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false); 2822 }, 2823 isFunction: function(item) { 2824 return item === null ? false : (typeof (item) == "function" || item instanceof Function); 2825 }, 2826 isElementNode: function(item) { 2827 //document.body.ELEMENT_NODE; 2828 return item && typeof (item) == "object" && "nodeType" in item && item.nodeType == 1 && item.tagName && item.tagName.toUpperCase() != 'SCRIPT' && item.tagName.toUpperCase() != 'STYLE' && item.tagName.toUpperCase() != 'LINK'; 2829 }, 2830 isDomNode: function(item) { 2831 return item && typeof (item) == "object" && "nodeType" in item; 2832 }, 2833 isArray: function(item) { 2834 return item && Object.prototype.toString.call(item) == "[object Array]"; 2835 }, 2836 isDate : function(item) { 2837 return item && Object.prototype.toString.call(item) == "[object Date]"; 2838 }, 2839 isPlainObject: function(item) 2840 { 2841 if(!item || typeof(item) !== "object" || item.nodeType) 2842 { 2843 return false; 2844 } 2845 2846 var hasProp = Object.prototype.hasOwnProperty; 2847 try 2848 { 2849 if (item.constructor && !hasProp.call(item, "constructor") && !hasProp.call(item.constructor.prototype, "isPrototypeOf") ) 2850 { 2851 return false; 2852 } 2853 } 2854 catch (e) 2855 { 2856 return false; 2857 } 2858 2859 var key; 2860 for (key in item) 2861 { 2862 } 2863 return typeof(key) === "undefined" || hasProp.call(item, key); 2864 } 2865}; 2866 2867BX.isNodeInDom = function(node, doc) 2868{ 2869 return node === (doc || document) ? true : 2870 (node.parentNode ? BX.isNodeInDom(node.parentNode) : false); 2871}; 2872 2873BX.isNodeHidden = function(node) 2874{ 2875 if (node === document) 2876 return false; 2877 else if (BX.style(node, 'display') == 'none') 2878 return true; 2879 else 2880 return (node.parentNode ? BX.isNodeHidden(node.parentNode) : true); 2881}; 2882 2883BX.evalPack = function(code) 2884{ 2885 while (code.length > 0) 2886 { 2887 var c = code.shift(); 2888 2889 if (c.TYPE == 'SCRIPT_EXT' || c.TYPE == 'SCRIPT_SRC') 2890 { 2891 BX.loadScript(c.DATA, function() {BX.evalPack(code)}); 2892 return; 2893 } 2894 else if (c.TYPE == 'SCRIPT') 2895 { 2896 BX.evalGlobal(c.DATA); 2897 } 2898 } 2899}; 2900 2901BX.evalGlobal = function(data) 2902{ 2903 if (data) 2904 { 2905 var head = document.getElementsByTagName("head")[0] || document.documentElement, 2906 script = document.createElement("script"); 2907 2908 script.type = "text/javascript"; 2909 2910 if (!BX.browser.IsIE()) 2911 { 2912 script.appendChild(document.createTextNode(data)); 2913 } 2914 else 2915 { 2916 script.text = data; 2917 } 2918 2919 head.insertBefore(script, head.firstChild); 2920 head.removeChild(script); 2921 } 2922}; 2923 2924BX.processHTML = function(data, scriptsRunFirst) 2925{ 2926 var matchScript, matchStyle, matchSrc, matchHref, matchType, scripts = [], styles = []; 2927 var textIndexes = []; 2928 var lastIndex = r.script.lastIndex = r.script_end.lastIndex = 0; 2929 2930 while ((matchScript = r.script.exec(data)) !== null) 2931 { 2932 r.script_end.lastIndex = r.script.lastIndex; 2933 var matchScriptEnd = r.script_end.exec(data); 2934 if (matchScriptEnd === null) 2935 { 2936 break; 2937 } 2938
2939 // skip script tags of special types 2940 var skipTag = false; 2941 if ((matchType = matchScript[1].match(r.script_type)) !== null) 2942 { 2943 if(matchType[1] == 'text/html' || matchType[1] == 'text/template') 2944 skipTag = true; 2945 } 2946 2947 if(skipTag) 2948 { 2949 textIndexes.push([lastIndex, r.script_end.lastIndex - lastIndex]); 2950 } 2951 else 2952 { 2953 textIndexes.push([lastIndex, matchScript.index - lastIndex]); 2954 2955 var bRunFirst = scriptsRunFirst || (matchScript[1].indexOf('bxrunfirst') != '-1'); 2956 2957 if ((matchSrc = matchScript[1].match(r.script_src)) !== null) 2958 { 2959 scripts.push({"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]}); 2960 } 2961 else 2962 { 2963 var start = matchScript.index + matchScript[0].length; 2964 var js = data.substr(start, matchScriptEnd.index-start); 2965 2966 scripts.push({"bRunFirst": bRunFirst, "isInternal": true, "JS": js}); 2967 } 2968 } 2969 2970 lastIndex = matchScriptEnd.index + 9; 2971 r.script.lastIndex = lastIndex; 2972 } 2973 2974 textIndexes.push([lastIndex, lastIndex === 0 ? data.length : data.length - lastIndex]); 2975 var pureData = ""; 2976 for (var i = 0, length = textIndexes.length; i < length; i++) 2977 { 2978 pureData += data.substr(textIndexes[i][0], textIndexes[i][1]); 2979 } 2980 2981 while ((matchStyle = pureData.match(r.style)) !== null) 2982 { 2983 if ((matchHref = matchStyle[0].match(r.style_href)) !== null && matchStyle[0].indexOf('media="') < 0) 2984 { 2985 styles.push(matchHref[1]); 2986 } 2987 2988 pureData = pureData.replace(matchStyle[0], ''); 2989 } 2990 2991 return {'HTML': pureData, 'SCRIPT': scripts, 'STYLE': styles}; 2992}; 2993 2994BX.garbage = function(call, thisObject) 2995{ 2996 garbageCollectors.push({callback: call, context: thisObject}); 2997}; 2998 2999/* window pos functions */ 3000 3001BX.GetDocElement = function (pDoc) 3002{ 3003 pDoc = pDoc || document; 3004 return (BX.browser.IsDoctype(pDoc) ? pDoc.documentElement : pDoc.body); 3005}; 3006 3007BX.GetContext = function(node) 3008{ 3009 if (BX.type.isElementNode(node)) 3010 return node.ownerDocument.parentWindow || node.ownerDocument.defaultView || window; 3011 else if (BX.type.isDomNode(node)) 3012 return node.parentWindow || node.defaultView || window; 3013 else 3014 return window; 3015}; 3016 3017BX.GetWindowInnerSize = function(pDoc) 3018{ 3019 var width, height; 3020 3021 pDoc = pDoc || document; 3022 3023 if (window.innerHeight) // all except Explorer 3024 { 3025 width = BX.GetContext(pDoc).innerWidth; 3026 height = BX.GetContext(pDoc).innerHeight; 3027 } 3028 else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode 3029 { 3030 width = pDoc.documentElement.clientWidth; 3031 height = pDoc.documentElement.clientHeight; 3032 } 3033 else if (pDoc.body) // other Explorers 3034 { 3035 width = pDoc.body.clientWidth; 3036 height = pDoc.body.clientHeight; 3037 } 3038 return {innerWidth : width, innerHeight : height}; 3039}; 3040 3041BX.GetWindowScrollPos = function(pDoc) 3042{ 3043 var left, top; 3044 3045 pDoc = pDoc || document; 3046 3047 if (window.pageYOffset) // all except Explorer 3048 { 3049 left = BX.GetContext(pDoc).pageXOffset; 3050 top = BX.GetContext(pDoc).pageYOffset; 3051 } 3052 else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict 3053 { 3054 left = pDoc.documentElement.scrollLeft; 3055 top = pDoc.documentElement.scrollTop; 3056 } 3057 else if (pDoc.body) // all other Explorers 3058 { 3059 left = pDoc.body.scrollLeft; 3060 top = pDoc.body.scrollTop; 3061 } 3062 return {scrollLeft : left, scrollTop : top}; 3063}; 3064 3065BX.GetWindowScrollSize = function(pDoc) 3066{ 3067 var width, height; 3068 if (!pDoc) 3069 pDoc = document; 3070 3071 if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat")) 3072 { 3073 width = pDoc.documentElement.scrollWidth; 3074 height = pDoc.documentElement.scrollHeight; 3075 } 3076 else 3077 { 3078 if (pDoc.body.scrollHeight > pDoc.body.offsetHeight) 3079 height = pDoc.body.scrollHeight; 3080 else 3081 height = pDoc.body.offsetHeight; 3082 3083 if (pDoc.body.scrollWidth > pDoc.body.offsetWidth || 3084 (pDoc.compatMode && pDoc.compatMode == "BackCompat") || 3085 (pDoc.documentElement && !pDoc.documentElement.clientWidth) 3086 ) 3087 width = pDoc.body.scrollWidth; 3088 else 3089 width = pDoc.body.offsetWidth; 3090 } 3091 return {scrollWidth : width, scrollHeight : height}; 3092}; 3093 3094BX.GetWindowSize = function(pDoc) 3095{ 3096 var innerSize = this.GetWindowInnerSize(pDoc); 3097 var scrollPos = this.GetWindowScrollPos(pDoc); 3098 var scrollSize = this.GetWindowScrollSize(pDoc); 3099 3100 return {
3101 innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight, 3102 scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop, 3103 scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight 3104 }; 3105}; 3106 3107BX.scrollTop = function(node, val){ 3108 if(typeof val != 'undefined'){ 3109 3110 if(node == window){ 3111 throw new Error('scrollTop() for window is not implemented'); 3112 }else 3113 node.scrollTop = parseInt(val); 3114 3115 }else{ 3116 3117 if(node == window) 3118 return BX.GetWindowScrollPos().scrollTop; 3119 3120 return node.scrollTop; 3121 } 3122} 3123 3124BX.scrollLeft = function(node, val){ 3125 if(typeof val != 'undefined'){ 3126 3127 if(node == window){ 3128 throw new Error('scrollLeft() for window is not implemented'); 3129 }else 3130 node.scrollLeft = parseInt(val); 3131 3132 }else{ 3133 3134 if(node == window) 3135 return BX.GetWindowScrollPos().scrollLeft; 3136 3137 return node.scrollLeft; 3138 } 3139} 3140 3141BX.hide_object = function(ob) 3142{ 3143 ob = BX(ob); 3144 ob.style.position = 'absolute'; 3145 ob.style.top = '-1000px'; 3146 ob.style.left = '-1000px'; 3147 ob.style.height = '10px'; 3148 ob.style.width = '10px'; 3149}; 3150 3151BX.is_relative = function(el) 3152{ 3153 var p = BX.style(el, 'position'); 3154 return p == 'relative' || p == 'absolute'; 3155}; 3156 3157BX.is_float = function(el) 3158{ 3159 var p = BX.style(el, 'float'); 3160 return p == 'right' || p == 'left'; 3161}; 3162 3163BX.is_fixed = function(el) 3164{ 3165 var p = BX.style(el, 'position'); 3166 return p == 'fixed'; 3167}; 3168 3169BX.pos = function(el, bRelative) 3170{ 3171 var r = { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }; 3172 bRelative = !!bRelative; 3173 if (!el) 3174 return r; 3175 if (typeof (el.getBoundingClientRect) != "undefined" && el.ownerDocument == document && !bRelative) 3176 { 3177 var clientRect = {}; 3178 3179 // getBoundingClientRect can return undefined and generate exception in some cases in IE8. 3180 try 3181 { 3182 clientRect = el.getBoundingClientRect(); 3183 } 3184 catch(e) 3185 { 3186 clientRect = 3187 { 3188 top: el.offsetTop, 3189 left: el.offsetLeft, 3190 width: el.offsetWidth, 3191 height: el.offsetHeight, 3192 right: el.offsetLeft + el.offsetWidth, 3193 bottom: el.offsetTop + el.offsetHeight 3194 }; 3195 } 3196 3197 var root = document.documentElement; 3198 var body = document.body; 3199 3200 r.top = clientRect.top + (root.scrollTop || body.scrollTop); 3201 r.left = clientRect.left + (root.scrollLeft || body.scrollLeft); 3202 r.width = clientRect.right - clientRect.left; 3203 r.height = clientRect.bottom - clientRect.top; 3204 r.right = clientRect.right + (root.scrollLeft || body.scrollLeft); 3205 r.bottom = clientRect.bottom + (root.scrollTop || body.scrollTop); 3206 } 3207 else 3208 { 3209 var x = 0, y = 0, w = el.offsetWidth, h = el.offsetHeight; 3210 var first = true; 3211 for (; el != null; el = el.offsetParent) 3212 { 3213 if (!first && bRelative && BX.is_relative(el)) 3214 break; 3215 3216 x += el.offsetLeft; 3217 y += el.offsetTop; 3218 if (first) 3219 { 3220 first = false; 3221 continue; 3222 } 3223 3224 var elBorderLeftWidth = parseInt(BX.style(el, 'border-left-width')), 3225 elBorderTopWidth = parseInt(BX.style(el, 'border-top-width')); 3226 3227 if (!isNaN(elBorderLeftWidth) && elBorderLeftWidth > 0) 3228 x += elBorderLeftWidth; 3229 if (!isNaN(elBorderTopWidth) && elBorderTopWidth > 0) 3230 y += elBorderTopWidth; 3231 } 3232 3233 r.top = y; 3234 r.left = x; 3235 r.width = w; 3236 r.height = h; 3237 r.right = r.left + w; 3238 r.bottom = r.top + h; 3239 } 3240 3241 for(var i in r) 3242 { 3243 if(r.hasOwnProperty(i)) 3244 { 3245 r[i] = Math.round(r[i]); 3246 } 3247 } 3248 3249 return r; 3250}; 3251 3252BX.width = function(node, val){ 3253 if(typeof val != 'undefined') 3254 BX.style(node, 'width', parseInt(val)+'px'); 3255 else{ 3256 3257 if(node == window) 3258 return window.innerWidth; 3259 3260 //return parseInt(BX.style(node, 'width')); 3261 return BX.pos(node).width; 3262 } 3263} 3264 3265BX.height = function(node, val){ 3266 if(typeof val != 'undefined') 3267 BX.style(node, 'height', parseInt(val)+'px'); 3268 else{ 3269 3270 if(node == window) 3271 return window.innerHeight; 3272 3273 //return parseInt(BX.style(node, 'height')); 3274 return BX.pos(node).height; 3275 } 3276} 3277 3278BX.align = function(pos, w, h, type) 3279{ 3280 if (type) 3281 type = type.toLowerCase(); 3282 else 3283 type = ''; 3284 3285 var pDoc = document; 3286 if (BX.type.isElementNode(pos)) 3287 { 3288 pDoc = pos.ownerDocument; 3289 pos = BX.pos(pos); 3290 } 3291 3292 var x = pos["left"], y = pos["bottom"]; 3293 3294 var scroll = BX.GetWindowScrollPos(pDoc); 3295 var size = BX.GetWindowInnerSize(pDoc); 3296 3297 if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0) 3298 { 3299 if(pos["right"] - w >= 0 ) 3300 x = pos["right"] - w; 3301 else 3302 x = scroll.scrollLeft; 3303 } 3304
3305 if(((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0) || ~type.indexOf('top')) 3306 { 3307 if(pos["top"] - h >= 0 || ~type.indexOf('top')) 3308 y = pos["top"] - h; 3309 else 3310 y = scroll.scrollTop; 3311 } 3312 3313 return {'left':x, 'top':y}; 3314}; 3315 3316BX.scrollToNode = function(node) 3317{ 3318 var obNode = BX(node); 3319 3320 if (obNode.scrollIntoView) 3321 obNode.scrollIntoView(true); 3322 else 3323 { 3324 var arNodePos = BX.pos(obNode); 3325 window.scrollTo(arNodePos.left, arNodePos.top); 3326 } 3327}; 3328 3329/* non-xhr loadings */ 3330BX.showWait = function(node, msg) 3331{ 3332 node = BX(node) || document.body || document.documentElement; 3333 msg = msg || BX.message('JS_CORE_LOADING'); 3334 3335 var container_id = node.id || Math.random(); 3336 3337 var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', { 3338 props: { 3339 id: 'wait_' + container_id 3340 }, 3341 style: { 3342 background: 'url("/bitrix/js/main/core/images/wait.gif") no-repeat scroll 10px center #fcf7d1', 3343 border: '1px solid #E1B52D', 3344 color: 'black', 3345 fontFamily: 'Verdana,Arial,sans-serif', 3346 fontSize: '11px', 3347 padding: '10px 30px 10px 37px', 3348 position: 'absolute', 3349 zIndex:'10000', 3350 textAlign:'center' 3351 }, 3352 text: msg 3353 })); 3354 3355 setTimeout(BX.delegate(_adjustWait, node), 10); 3356 3357 lastWait[lastWait.length] = obMsg; 3358 return obMsg; 3359}; 3360 3361BX.closeWait = function(node, obMsg) 3362{ 3363 if(node && !obMsg) 3364 obMsg = node.bxmsg; 3365 if(node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow')) 3366 obMsg = node; 3367 if(node && !obMsg) 3368 obMsg = BX('wait_' + node.id); 3369 if(!obMsg) 3370 obMsg = lastWait.pop(); 3371 3372 if (obMsg && obMsg.parentNode) 3373 { 3374 for (var i=0,len=lastWait.length;i<len;i++) 3375 { 3376 if (obMsg == lastWait[i]) 3377 { 3378 lastWait = BX.util.deleteFromArray(lastWait, i); 3379 break; 3380 } 3381 } 3382 3383 obMsg.parentNode.removeChild(obMsg); 3384 if (node) node.bxmsg = null; 3385 BX.cleanNode(obMsg, true); 3386 } 3387}; 3388 3389BX.setJSList = function(scripts) 3390{ 3391 if (BX.type.isArray(scripts)) 3392 { 3393 jsList = scripts; 3394 } 3395}; 3396 3397BX.getJSList = function() 3398{ 3399 initJsList(); 3400 return jsList; 3401}; 3402 3403BX.setCSSList = function(scripts) 3404{ 3405 if (BX.type.isArray(scripts)) 3406 { 3407 cssList = scripts; 3408 } 3409}; 3410 3411BX.getCSSList = function() 3412{ 3413 initCssList(); 3414 return cssList; 3415}; 3416 3417BX.getJSPath = function(js) 3418{ 3419 return js.replace(/^(http[s]*:)*\/\/[^\/]+/i, ''); 3420}; 3421 3422BX.getCSSPath = function(css) 3423{ 3424 return css.replace(/^(http[s]*:)*\/\/[^\/]+/i, ''); 3425}; 3426 3427BX.getCDNPath = function(path) 3428{ 3429 return path; 3430}; 3431 3432BX.loadScript = function(script, callback, doc) 3433{ 3434 if (BX.type.isString(script)) 3435 { 3436 script = [script]; 3437 } 3438 3439 return BX.load(script, callback, doc); 3440}; 3441 3442BX.loadCSS = function(css, doc, win) 3443{ 3444 if (BX.type.isString(css)) 3445 { 3446 css = [css]; 3447 } 3448 3449 if (BX.type.isArray(css)) 3450 { 3451 css = css.map(function(url) { 3452 return { url: url, ext: "css" } 3453 }); 3454 3455 BX.load(css, null, doc); 3456 } 3457}; 3458 3459BX.load = function(items, callback, doc) 3460{ 3461 if (!BX.isReady) 3462 { 3463 var _args = arguments; 3464 BX.ready(function() { 3465 BX.load.apply(this, _args); 3466 }); 3467 return null; 3468 } 3469 3470 doc = doc || document; 3471 if (isAsync === null) 3472 { 3473 isAsync = "async" in doc.createElement("script") || "MozAppearance" in doc.documentElement.style || window.opera; 3474 } 3475 3476 return isAsync ? loadAsync(items, callback, doc) : loadAsyncEmulation(items, callback, doc); 3477}; 3478 3479BX.convert = 3480{ 3481 nodeListToArray: function(nodes) 3482 { 3483 try 3484 { 3485 return (Array.prototype.slice.call(nodes, 0)); 3486 } 3487 catch (ex) 3488 { 3489 var ary = []; 3490 for(var i = 0, l = nodes.length; i < l; i++) 3491 { 3492 ary.push(nodes[i]); 3493 } 3494 return ary; 3495 } 3496 } 3497}; 3498 3499function loadAsync(items, callback, doc) 3500{ 3501 if (!BX.type.isArray(items)) 3502 { 3503 return; 3504 } 3505 3506 function allLoaded(items) 3507 { 3508 items = items || assets; 3509 for (var name in items) 3510 { 3511 if (items.hasOwnProperty(name) && items[name].state !== LOADED) 3512 { 3513 return false; 3514 } 3515 } 3516 3517 return true; 3518 } 3519 3520 if (!BX.type.isFunction(callback)) 3521 { 3522 callback = null; 3523 } 3524 3525 var itemSet = {}, item, i; 3526 for (i = 0; i < items.length; i++) 3527 { 3528 item = items[i]; 3529 item = getAsset(item); 3530 itemSet[item.name] = item; 3531 } 3532 3533 var callbackWasCalled = false; 3534 for (i = 0; i < items.length; i++) 3535 { 3536 item = items[i]; 3537 item = getAsset(item); 3538 load(item, function () { 3539 if (allLoaded(itemSet)) 3540 { 3541 if (!callbackWasCalled) 3542 { 3543 callback && callback(); 3544 callbackWasCalled = true; 3545 } 3546 3547 } 3548 }, doc); 3549 } 3550} 3551 3552function loadAsyncEmulation(items, callback, doc) 3553{ 3554 function onPreload(asset) 3555 { 3556 asset.state = PRELOADED;
3557 if (BX.type.isArray(asset.onpreload) && asset.onpreload) 3558 { 3559 for (var i = 0; i < asset.onpreload.length; i++) 3560 { 3561 asset.onpreload[i].call(); 3562 } 3563 } 3564 } 3565 3566 function preLoad(asset) 3567 { 3568 if (asset.state === undefined) 3569 { 3570 asset.state = PRELOADING; 3571 asset.onpreload = []; 3572 3573 loadAsset( 3574 { url: asset.url, type: "cache", ext: asset.ext}, 3575 function () { onPreload(asset); }, 3576 doc 3577 ); 3578 } 3579 } 3580 3581 if (!BX.type.isArray(items)) 3582 { 3583 return; 3584 } 3585 3586 if (!BX.type.isFunction(callback)) 3587 { 3588 callback = null; 3589 } 3590 3591 var rest = [].slice.call(items, 1); 3592 for (var i = 0; i < rest.length; i++) 3593 { 3594 preLoad(getAsset(rest[i])); 3595 } 3596 3597 load(getAsset(items[0]), items.length === 1 ? callback : function () { 3598 loadAsyncEmulation.apply(null, [rest, callback, doc]); 3599 }, doc); 3600} 3601 3602function load(asset, callback, doc) 3603{ 3604 callback = callback || BX.DoNothing; 3605 3606 if (asset.state === LOADED) 3607 { 3608 callback(); 3609 return; 3610 } 3611 3612 if (asset.state === PRELOADING) 3613 { 3614 asset.onpreload.push(function () { 3615 load(asset, callback, doc); 3616 }); 3617 return; 3618 } 3619 3620 asset.state = LOADING; 3621 3622 loadAsset( 3623 asset, 3624 function () { 3625 asset.state = LOADED; 3626 callback(); 3627 }, 3628 doc 3629 ); 3630} 3631 3632function loadAsset(asset, callback, doc) 3633{ 3634 callback = callback || BX.DoNothing; 3635 3636 function error(event) 3637 { 3638 ele.onload = ele.onreadystatechange = ele.onerror = null; 3639 callback(); 3640 } 3641 3642 function process(event) 3643 { 3644 event = event || window.event; 3645 if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9))) 3646 { 3647 window.clearTimeout(asset.errorTimeout); 3648 window.clearTimeout(asset.cssTimeout); 3649 ele.onload = ele.onreadystatechange = ele.onerror = null; 3650 callback(); 3651 } 3652 } 3653 3654 function isCssLoaded() 3655 { 3656 if (asset.state !== LOADED && asset.cssRetries <= 20) 3657 { 3658 for (var i = 0, l = doc.styleSheets.length; i < l; i++) 3659 { 3660 if (doc.styleSheets[i].href === ele.href) 3661 { 3662 process({"type": "load"}); 3663 return; 3664 } 3665 } 3666 3667 asset.cssRetries++; 3668 asset.cssTimeout = window.setTimeout(isCssLoaded, 250); 3669 } 3670 } 3671 3672 var ele; 3673 var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url); 3674 3675 if (ext === "css") 3676 { 3677 ele = doc.createElement("link"); 3678 ele.type = "text/" + (asset.type || "css"); 3679 ele.rel = "stylesheet"; 3680 ele.href = asset.url; 3681 3682 asset.cssRetries = 0; 3683 asset.cssTimeout = window.setTimeout(isCssLoaded, 500); 3684 } 3685 else 3686 { 3687 ele = doc.createElement("script"); 3688 ele.type = "text/" + (asset.type || "javascript"); 3689 ele.src = asset.url; 3690 } 3691 3692 ele.onload = ele.onreadystatechange = process; 3693 ele.onerror = error; 3694 3695 ele.async = false; 3696 ele.defer = false; 3697 3698 asset.errorTimeout = window.setTimeout(function () { 3699 error({type: "timeout"}); 3700 }, 7000); 3701 3702 if (ext === "css") 3703 { 3704 cssList.push(normalizeMinUrl(normalizeUrl(asset.url))); 3705 } 3706 else 3707 { 3708 jsList.push(normalizeMinUrl(normalizeUrl(asset.url))); 3709 } 3710 3711 var templateLink = null; 3712 var head = doc.head || doc.getElementsByTagName("head")[0]; 3713 if (ext === "css" && (templateLink = getTemplateLink(head)) !== null) 3714 { 3715 templateLink.parentNode.insertBefore(ele, templateLink); 3716 } 3717 else 3718 { 3719 head.insertBefore(ele, head.lastChild); 3720 } 3721} 3722 3723function getAsset(item) 3724{ 3725 var asset = {}; 3726 if (typeof item === "object") 3727 { 3728 asset = item; 3729 asset.name = asset.name ? asset.name : BX.util.hashCode(item.url); 3730 } 3731 else 3732 { 3733 asset = { name: BX.util.hashCode(item), url : item }; 3734 } 3735 3736 var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url); 3737 if ((ext === "css" && isCssLoaded(asset.url)) || isScriptLoaded(asset.url)) 3738 { 3739 asset.state = LOADED; 3740 } 3741 3742 var existing = assets[asset.name]; 3743 if (existing && existing.url === asset.url) 3744 { 3745 return existing; 3746 } 3747 3748 assets[asset.name] = asset; 3749 return asset; 3750} 3751 3752function normalizeUrl(url) 3753{ 3754 if (!BX.type.isNotEmptyString(url)) 3755 { 3756 return ""; 3757 } 3758 3759 url = BX.getJSPath(url); 3760 url = url.replace(/\?[0-9]*$/, ""); 3761 3762 return url; 3763} 3764 3765function normalizeMinUrl(url) 3766{ 3767 if (!BX.type.isNotEmptyString(url)) 3768 { 3769 return ""; 3770 } 3771 3772 var minPos = url.indexOf(".min"); 3773 return minPos >= 0 ? url.substr(0, minPos) + url.substr(minPos + 4) : url; 3774} 3775 3776function isCssLoaded(fileSrc) 3777{ 3778 initCssList(); 3779 3780 fileSrc = normalizeUrl(fileSrc); 3781 var fileSrcMin = normalizeMinUrl(fileSrc); 3782 3783 return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, cssList)) || BX.util.in_array(fileSrc, cssList); 3784} 3785 3786function initCssList() 3787{ 3788 if(!cssInit) 3789 { 3790 var linksCol = document.getElementsByTagName('link'); 3791 3792 if(!!linksCol && linksCol.length > 0) 3793 { 3794 for(var i = 0; i < linksCol.length; i++) 3795 { 3796 var href = linksCol[i].getAttribute('href'); 3797 if (BX.type.isNotEmptyString(href)) 3798 { 3799 href = normalizeMinUrl(normalizeUrl(href)); 3800 cssList.push(href); 3801 } 3802 } 3803 } 3804 cssInit = true; 3805 } 3806} 3807 3808function getTemplateLink(head) 3809{ 3810 var findLink = function(tag) 3811 { 3812 var links = head.getElementsByTagName(tag); 3813 for (var i = 0, length = links.length; i < length; i++) 3814 { 3815 var templateStyle = links[i].getAttribute("data-template-style"); 3816 if (BX.type.isNotEmptyString(templateStyle) && templateStyle == "true") 3817 { 3818 return links[i]; 3819 } 3820 } 3821 3822 return null; 3823 }; 3824 3825 var link = findLink("link"); 3826 if (link === null) 3827 { 3828 link = findLink("style"); 3829 } 3830 3831 return link; 3832} 3833 3834function isScriptLoaded(fileSrc) 3835{ 3836 initJsList(); 3837 3838 fileSrc = normalizeUrl(fileSrc); 3839 var fileSrcMin = normalizeMinUrl(fileSrc); 3840 3841 return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, jsList)) || BX.util.in_array(fileSrc, jsList); 3842} 3843 3844function initJsList() 3845{ 3846 if(!jsInit) 3847 { 3848 var scriptCol = document.getElementsByTagName('script'); 3849 3850 if(!!scriptCol && scriptCol.length > 0) 3851 { 3852 for(var i=0; i<scriptCol.length; i++) 3853 { 3854 var src = scriptCol[i].getAttribute('src'); 3855 3856 if (BX.type.isNotEmptyString(src)) 3857 { 3858 src = normalizeMinUrl(normalizeUrl(src)); 3859 jsList.push(src); 3860 } 3861 } 3862 } 3863 jsInit = true; 3864 } 3865} 3866 3867BX.reload = function(back_url, bAddClearCache) 3868{ 3869 if (back_url === true) 3870 { 3871 bAddClearCache = true; 3872 back_url = null; 3873 } 3874 3875 var new_href = back_url || top.location.href; 3876 3877 var hashpos = new_href.indexOf('#'), hash = ''; 3878 3879 if (hashpos != -1) 3880 { 3881 hash = new_href.substr(hashpos); 3882 new_href = new_href.substr(0, hashpos); 3883 } 3884 3885 if (bAddClearCache && new_href.indexOf('clear_cache=Y') < 0) 3886 new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + 'clear_cache=Y'; 3887 3888 if (hash) 3889 { 3890 // hack for clearing cache in ajax mode components with history emulation 3891 if (bAddClearCache && (hash.substr(0, 5) == 'view/' || hash.substr(0, 6) == '#view/') && hash.indexOf('clear_cache%3DY') < 0) 3892 hash += (hash.indexOf('%3F') == -1 ? '%3F' : '%26') + 'clear_cache%3DY'; 3893 3894 new_href = new_href.replace(/(\?|\&)_r=[\d]*/, ''); 3895 new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + '_r='+Math.round(Math.random()*10000) + hash; 3896 } 3897 3898 top.location.href = new_href; 3899}; 3900 3901BX.clearCache = function() 3902{ 3903 BX.showWait(); 3904 BX.reload(true); 3905}; 3906 3907BX.template = function(tpl, callback, bKillTpl) 3908{ 3909 BX.ready(function() { 3910 _processTpl(BX(tpl), callback, bKillTpl); 3911 }); 3912}; 3913 3914BX.isAmPmMode = function() 3915{ 3916 return (BX.message('FORMAT_DATETIME').match('T') != null); 3917}; 3918 3919BX.formatDate = function(date, format) 3920{ 3921 date = date || new Date(); 3922 3923 var bTime = date.getHours() || date.getMinutes() || date.getSeconds(), 3924 str = !!format 3925 ? format : 3926 (bTime ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE') 3927 ); 3928 3929 return str.replace(/YYYY/ig, date.getFullYear()) 3930 .replace(/MMMM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0')) 3931 .replace(/MM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0')) 3932 .replace(/DD/ig, BX.util.str_pad_left(date.getDate().toString(), 2, '0')) 3933 .replace(/HH/ig, BX.util.str_pad_left(date.getHours().toString(), 2, '0')) 3934 .replace(/MI/ig, BX.util.str_pad_left(date.getMinutes().toString(), 2, '0')) 3935 .replace(/SS/ig, BX.util.str_pad_left(date.getSeconds().toString(), 2, '0')); 3936}; 3937BX.formatName = function(user, template, login) 3938{ 3939 user = user || {}; 3940 template = (template || ''); 3941 var replacement = { 3942 TITLE : (user["TITLE"] || ''),
3943 NAME : (user["NAME"] || ''), 3944 LAST_NAME : (user["LAST_NAME"] || ''), 3945 SECOND_NAME : (user["SECOND_NAME"] || ''), 3946 LOGIN : (user["LOGIN"] || ''), 3947 NAME_SHORT : user["NAME"] ? user["NAME"].substr(0, 1) + '.' : '', 3948 LAST_NAME_SHORT : user["LAST_NAME"] ? user["LAST_NAME"].substr(0, 1) + '.' : '', 3949 SECOND_NAME_SHORT : user["SECOND_NAME"] ? user["SECOND_NAME"].substr(0, 1) + '.' : '', 3950 EMAIL : (user["EMAIL"] || ''), 3951 ID : (user["ID"] || ''), 3952 NOBR : "", 3953 '/NOBR' : "" 3954 }, result = template; 3955 for (var ii in replacement) 3956 { 3957 if (replacement.hasOwnProperty(ii)) 3958 { 3959 result = result.replace("#" + ii+ "#", replacement[ii]) 3960 } 3961 } 3962 result = result.replace(/([\s]+)/gi, " ").trim(); 3963 if (result == "") 3964 { 3965 result = (login == "Y" ? replacement["LOGIN"] : ""); 3966 result = (result == "" ? "Noname" : result); 3967 } 3968 return result; 3969}; 3970 3971BX.getNumMonth = function(month) 3972{ 3973 var wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; 3974 var wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; 3975 3976 var q = month.toUpperCase(); 3977 for (i = 1; i <= 12; i++) 3978 { 3979 if (q == BX.message('MON_'+i).toUpperCase() || q == BX.message('MONTH_'+i).toUpperCase() || q == wordMonthCut[i-1].toUpperCase() || q == wordMonth[i-1].toUpperCase()) 3980 { 3981 return i; 3982 } 3983 } 3984 return month; 3985}; 3986 3987BX.parseDate = function(str, bUTC, formatDate, formatDatetime) 3988{ 3989 if (BX.type.isNotEmptyString(str)) 3990 { 3991 if (!formatDate) 3992 formatDate = BX.message('FORMAT_DATE'); 3993 if (!formatDatetime) 3994 formatDatetime = BX.message('FORMAT_DATETIME'); 3995 3996 var regMonths = ''; 3997 for (i = 1; i <= 12; i++) 3998 { 3999 regMonths = regMonths + '|' + BX.message('MON_'+i); 4000 } 4001
4002 var expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig'); 4003 var aDate = str.match(expr), 4004 aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig), 4005 i, cnt, 4006 aDateArgs=[], aFormatArgs=[], 4007 aResult={}; 4008 4009 if (!aDate) 4010 return null; 4011 4012 if(aDate.length > aFormat.length) 4013 { 4014 aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig); 4015 } 4016 4017 for(i = 0, cnt = aDate.length; i < cnt; i++) 4018 { 4019 if(BX.util.trim(aDate[i]) != '') 4020 { 4021 aDateArgs[aDateArgs.length] = aDate[i]; 4022 } 4023 } 4024 4025 for(i = 0, cnt = aFormat.length; i < cnt; i++) 4026 { 4027 if(BX.util.trim(aFormat[i]) != '') 4028 { 4029 aFormatArgs[aFormatArgs.length] = aFormat[i]; 4030 } 4031 } 4032 4033 4034 var m = BX.util.array_search('MMMM', aFormatArgs); 4035 if (m > 0) 4036 { 4037 aDateArgs[m] = BX.getNumMonth(aDateArgs[m]); 4038 aFormatArgs[m] = "MM"; 4039 } 4040 else 4041 { 4042 m = BX.util.array_search('M', aFormatArgs); 4043 if (m > 0) 4044 { 4045 aDateArgs[m] = BX.getNumMonth(aDateArgs[m]); 4046 aFormatArgs[m] = "MM"; 4047 } 4048 } 4049 4050 for(i = 0, cnt = aFormatArgs.length; i < cnt; i++) 4051 { 4052 var k = aFormatArgs[i].toUpperCase(); 4053 aResult[k] = k == 'T' || k == 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10); 4054 } 4055 4056 if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0) 4057 { 4058 var d = new Date(); 4059 4060 if(bUTC) 4061 { 4062 d.setUTCDate(1); 4063 d.setUTCFullYear(aResult['YYYY']); 4064 d.setUTCMonth(aResult['MM'] - 1); 4065 d.setUTCDate(aResult['DD']); 4066 d.setUTCHours(0, 0, 0); 4067 } 4068 else 4069 { 4070 d.setDate(1); 4071 d.setFullYear(aResult['YYYY']); 4072 d.setMonth(aResult['MM'] - 1); 4073 d.setDate(aResult['DD']); 4074 d.setHours(0, 0, 0); 4075 } 4076 4077 if( 4078 (!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G'])) 4079 && !isNaN(aResult['MI']) 4080 ) 4081 { 4082 if (!isNaN(aResult['H']) || !isNaN(aResult['G'])) 4083 { 4084 var bPM = (aResult['T']||aResult['TT']||'am').toUpperCase()=='PM'; 4085 var h = parseInt(aResult['H']||aResult['G']||0, 10); 4086 if(bPM) 4087 { 4088 aResult['HH'] = h + (h == 12 ? 0 : 12); 4089 } 4090 else 4091 { 4092 aResult['HH'] = h < 12 ? h : 0; 4093 } 4094 } 4095 else 4096 { 4097 aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10); 4098 } 4099 4100 if (isNaN(aResult['SS'])) 4101 aResult['SS'] = 0; 4102 4103 if(bUTC) 4104 { 4105 d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']); 4106 } 4107 else 4108 { 4109 d.setHours(aResult['HH'], aResult['MI'], aResult['SS']); 4110 } 4111 } 4112 4113 return d; 4114 } 4115 } 4116 4117 return null; 4118}; 4119 4120BX.selectUtils = 4121{ 4122 addNewOption: function(oSelect, opt_value, opt_name, do_sort, check_unique) 4123 { 4124 oSelect = BX(oSelect); 4125 if(oSelect) 4126 { 4127 var n = oSelect.length; 4128 if(check_unique !== false) 4129 { 4130 for(var i=0;i<n;i++) 4131 { 4132 if(oSelect[i].value==opt_value) 4133 { 4134 return; 4135 } 4136 } 4137 } 4138 4139 oSelect.options[n] = new Option(opt_name, opt_value, false, false); 4140 } 4141 4142 if(do_sort === true) 4143 { 4144 this.sortSelect(oSelect); 4145 } 4146 }, 4147 4148 deleteOption: function(oSelect, opt_value) 4149 { 4150 oSelect = BX(oSelect); 4151 if(oSelect) 4152 { 4153 for(var i=0;i<oSelect.length;i++) 4154 { 4155 if(oSelect[i].value==opt_value) 4156 { 4157 oSelect.remove(i); 4158 break; 4159 } 4160 } 4161 } 4162 }, 4163 4164 deleteSelectedOptions: function(oSelect) 4165 { 4166 oSelect = BX(oSelect); 4167 if(oSelect) 4168 { 4169 var i=0; 4170 while(i<oSelect.length) 4171 { 4172 if(oSelect[i].selected) 4173 { 4174 oSelect[i].selected=false; 4175 oSelect.remove(i); 4176 } 4177 else 4178 { 4179 i++; 4180 } 4181 } 4182 } 4183 }, 4184 4185 deleteAllOptions: function(oSelect) 4186 { 4187 oSelect = BX(oSelect); 4188 if(oSelect) 4189 { 4190 for(var i=oSelect.length-1; i>=0; i--) 4191 { 4192 oSelect.remove(i); 4193 } 4194 } 4195 }, 4196 4197 optionCompare: function(record1, record2) 4198 { 4199 var value1 = record1.optText.toLowerCase(); 4200 var value2 = record2.optText.toLowerCase(); 4201 if (value1 > value2) return(1); 4202 if (value1 < value2) return(-1); 4203 return(0); 4204 }, 4205 4206 sortSelect: function(oSelect) 4207 { 4208 oSelect = BX(oSelect); 4209 if(oSelect) 4210 { 4211 var myOptions = []; 4212 var n = oSelect.options.length; 4213 var i; 4214 for (i=0;i<n;i++) 4215 { 4216 myOptions[i] = { 4217 optText:oSelect[i].text, 4218 optValue:oSelect[i].value 4219 }; 4220 } 4221 myOptions.sort(this.optionCompare); 4222 oSelect.length=0; 4223 n = myOptions.length; 4224 for(i=0;i<n;i++) 4225 { 4226 oSelect[i] = new Option(myOptions[i].optText, myOptions[i].optValue, false, false); 4227 } 4228 } 4229 }, 4230 4231 selectAllOptions: function(oSelect) 4232 { 4233 oSelect = BX(oSelect); 4234 if(oSelect) 4235 { 4236 var n = oSelect.length; 4237 for(var i=0;i<n;i++) 4238 { 4239 oSelect[i].selected=true; 4240 } 4241 } 4242 }, 4243 4244 selectOption: function(oSelect, opt_value) 4245 { 4246 oSelect = BX(oSelect); 4247 if(oSelect) 4248 { 4249 var n = oSelect.length; 4250 for(var i=0;i<n;i++) 4251 { 4252 oSelect[i].selected = (oSelect[i].value == opt_value); 4253 } 4254 } 4255 }, 4256 4257 addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort) 4258 { 4259 oSelect = BX(oSelect); 4260 if(!oSelect) 4261 return; 4262 var n = oSelect.length; 4263 for(var i=0; i<n; i++) 4264 if(oSelect[i].selected) 4265 this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique); 4266 }, 4267 4268 moveOptionsUp: function(oSelect) 4269 { 4270 oSelect = BX(oSelect); 4271 if(!oSelect) 4272 return; 4273 var n = oSelect.length; 4274 for(var i=0; i<n; i++) 4275 { 4276 if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false) 4277 { 4278 var option = new Option(oSelect[i].text, oSelect[i].value); 4279 oSelect[i] = new Option(oSelect[i-1].text, oSelect[i-1].value); 4280 oSelect[i].selected = false;
4281 oSelect[i-1] = option; 4282 oSelect[i-1].selected = true; 4283 } 4284 } 4285 }, 4286 4287 moveOptionsDown: function(oSelect) 4288 { 4289 oSelect = BX(oSelect); 4290 if(!oSelect) 4291 return; 4292 var n = oSelect.length; 4293 for(var i=n-1; i>=0; i--) 4294 { 4295 if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false) 4296 { 4297 var option = new Option(oSelect[i].text, oSelect[i].value); 4298 oSelect[i] = new Option(oSelect[i+1].text, oSelect[i+1].value); 4299 oSelect[i].selected = false; 4300 oSelect[i+1] = option; 4301 oSelect[i+1].selected = true; 4302 } 4303 } 4304 } 4305}; 4306 4307BX.getEventTarget = function(e) 4308{ 4309 if(e.target) 4310 { 4311 return e.target; 4312 } 4313 else if(e.srcElement) 4314 { 4315 return e.srcElement; 4316 } 4317 return null; 4318}; 4319 4320/******* HINT ***************/ 4321// if function has 2 params - the 2nd one is hint html. otherwise hint_html is third and hint_title - 2nd; 4322// '<div onmouseover="BX.hint(this, 'This is <b>Hint</b>')"'>; 4323// BX.hint(el, 'This is <b>Hint</b>') - this won't work, use constructor 4324BX.hint = function(el, hint_title, hint_html, hint_id) 4325{ 4326 if (null == hint_html) 4327 { 4328 hint_html = hint_title; 4329 hint_title = ''; 4330 } 4331 4332 if (null == el.BXHINT) 4333 { 4334 el.BXHINT = new BX.CHint({ 4335 parent: el, hint: hint_html, title: hint_title, id: hint_id 4336 }); 4337 el.BXHINT.Show(); 4338 } 4339}; 4340 4341BX.hint_replace = function(el, hint_title, hint_html) 4342{ 4343 if (null == hint_html) 4344 { 4345 hint_html = hint_title; 4346 hint_title = ''; 4347 } 4348 4349 if (!el || !el.parentNode || !hint_html) 4350 return null; 4351 4352 var obHint = new BX.CHint({ 4353 hint: hint_html, 4354 title: hint_title 4355 }); 4356 4357 obHint.CreateParent(); 4358 4359 el.parentNode.insertBefore(obHint.PARENT, el); 4360 el.parentNode.removeChild(el); 4361 4362 obHint.PARENT.style.marginLeft = '5px'; 4363 4364 return el; 4365}; 4366 4367BX.CHint = function(params) 4368{ 4369 this.PARENT = BX(params.parent); 4370 4371 this.HINT = params.hint; 4372 this.HINT_TITLE = params.title; 4373 4374 this.PARAMS = {}; 4375 for (var i in this.defaultSettings) 4376 { 4377 if (null == params[i]) 4378 this.PARAMS[i] = this.defaultSettings[i]; 4379 else 4380 this.PARAMS[i] = params[i]; 4381 } 4382 4383 if (null != params.id) 4384 this.ID = params.id; 4385 4386 this.timer = null; 4387 this.bInited = false; 4388 this.msover = true; 4389 4390 if (this.PARAMS.showOnce) 4391 { 4392 this.__show(); 4393 this.msover = false; 4394 this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout); 4395 } 4396 else if (this.PARENT) 4397 { 4398 BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this)); 4399 BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this)); 4400 } 4401 4402 BX.addCustomEvent('onMenuOpen', BX.delegate(this.disable, this)); 4403 BX.addCustomEvent('onMenuClose', BX.delegate(this.enable, this)); 4404}; 4405 4406BX.CHint.prototype.defaultSettings = { 4407 show_timeout: 1000, 4408 hide_timeout: 500, 4409 dx: 2, 4410 showOnce: false, 4411 preventHide: true, 4412 min_width: 250 4413}; 4414 4415BX.CHint.prototype.CreateParent = function(element, params) 4416{ 4417 if (this.PARENT) 4418 { 4419 BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this)); 4420 BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this)); 4421 } 4422 4423 if (!params) params = {}; 4424 var type = 'icon'; 4425 4426 if (params.type && (params.type == "link" || params.type == "icon")) 4427 type = params.type; 4428 4429 if (element) 4430 type = "element"; 4431 4432 if (type == "icon") 4433 { 4434 element = BX.create('IMG', { 4435 props: { 4436 src: params.iconSrc 4437 ? params.iconSrc 4438 : "/bitrix/js/main/core/images/hint.gif" 4439 } 4440 }); 4441 } 4442 else if (type == "link") 4443 { 4444 element = BX.create("A", { 4445 props: {href: 'javascript:void(0)'}, 4446 html: '[?]' 4447 }); 4448 } 4449 4450 this.PARENT = element; 4451 4452 BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this)); 4453 BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this)); 4454 4455 return this.PARENT; 4456}; 4457 4458BX.CHint.prototype.Show = function() 4459{ 4460 this.msover = true; 4461 4462 if (null != this.timer) 4463 clearTimeout(this.timer); 4464 4465 this.timer = setTimeout(BX.proxy(this.__show, this), this.PARAMS.show_timeout); 4466}; 4467 4468BX.CHint.prototype.Hide = function() 4469{ 4470 this.msover = false; 4471 4472 if (null != this.timer) 4473 clearTimeout(this.timer); 4474 4475 this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout); 4476}; 4477 4478BX.CHint.prototype.__show = function() 4479{ 4480 if (!this.msover || this.disabled) return; 4481 if (!this.bInited) this.Init(); 4482 4483 if (this.prepareAdjustPos()) 4484 { 4485 this.DIV.style.display = 'block'; 4486 this.adjustPos(); 4487 4488 BX.bind(window, 'scroll', BX.proxy(this.__onscroll, this)); 4489 4490 if (this.PARAMS.showOnce) 4491 { 4492 this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout); 4493 } 4494 } 4495}; 4496 4497BX.CHint.prototype.__onscroll = function() 4498{ 4499 if (!BX.admin || !BX.admin.panel || !BX.admin.panel.isFixed()) return; 4500 4501 if (this.scrollTimer) clearTimeout(this.scrollTimer); 4502 4503 this.DIV.style.display = 'none'; 4504 this.scrollTimer = setTimeout(BX.proxy(this.Reopen, this), this.PARAMS.show_timeout); 4505}; 4506 4507BX.CHint.prototype.Reopen = function() 4508{ 4509 if (null != this.timer) clearTimeout(this.timer); 4510 this.timer = setTimeout(BX.proxy(this.__show, this), 50); 4511}; 4512 4513BX.CHint.prototype.__hide = function() 4514{ 4515 if (this.msover) return; 4516 if (!this.bInited) return; 4517 4518 BX.unbind(window, 'scroll', BX.proxy(this.Reopen, this)); 4519 4520 if (this.PARAMS.showOnce) 4521 { 4522 this.Destroy(); 4523 } 4524 else 4525 { 4526 this.DIV.style.display = 'none'; 4527 } 4528}; 4529 4530BX.CHint.prototype.__hide_immediately = function() 4531{ 4532 this.msover = false;
4533 this.__hide(); 4534}; 4535 4536BX.CHint.prototype.Init = function() 4537{ 4538 this.DIV = document.body.appendChild(BX.create('DIV', { 4539 props: {className: 'bx-panel-tooltip'}, 4540 style: {display: 'none'}, 4541 children: [ 4542 BX.create('DIV', { 4543 props: {className: 'bx-panel-tooltip-top-border'}, 4544 html: '<div class="bx-panel-tooltip-corner bx-panel-tooltip-left-corner"></div><div class="bx-panel-tooltip-border"></div><div class="bx-panel-tooltip-corner bx-panel-tooltip-right-corner"></div>' 4545 }), 4546 (this.CONTENT = BX.create('DIV', { 4547 props: {className: 'bx-panel-tooltip-content'}, 4548 children: [ 4549 BX.create('DIV', { 4550 props: {className: 'bx-panel-tooltip-underlay'}, 4551 children: [ 4552 BX.create('DIV', {props: {className: 'bx-panel-tooltip-underlay-bg'}}) 4553 ] 4554 }) 4555 ] 4556 })), 4557 4558 BX.create('DIV', { 4559 props: {className: 'bx-panel-tooltip-bottom-border'}, 4560 html: '<div class="bx-panel-tooltip-corner bx-panel-tooltip-left-corner"></div><div class="bx-panel-tooltip-border"></div><div class="bx-panel-tooltip-corner bx-panel-tooltip-right-corner"></div>' 4561 }) 4562 ] 4563 })); 4564 4565 if (this.ID) 4566 { 4567 this.CONTENT.insertBefore(BX.create('A', { 4568 attrs: {href: 'javascript:void(0)'}, 4569 props: {className: 'bx-panel-tooltip-close'}, 4570 events: {click: BX.delegate(this.Close, this)} 4571 }), this.CONTENT.firstChild) 4572 } 4573 4574 if (this.HINT_TITLE) 4575 { 4576 this.CONTENT.appendChild( 4577 BX.create('DIV', { 4578 props: {className: 'bx-panel-tooltip-title'}, 4579 text: this.HINT_TITLE 4580 }) 4581 ) 4582 } 4583 4584 if (this.HINT) 4585 { 4586 this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT})); 4587 } 4588 4589 if (this.PARAMS.preventHide) 4590 { 4591 BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this)); 4592 BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this)); 4593 } 4594 4595 this.bInited = true; 4596}; 4597 4598BX.CHint.prototype.setContent = function(content) 4599{ 4600 this.HINT = content; 4601 4602 if (this.CONTENT_TEXT) 4603 this.CONTENT_TEXT.innerHTML = this.HINT; 4604 else 4605 this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT})); 4606}; 4607 4608BX.CHint.prototype.prepareAdjustPos = function() 4609{ 4610 this._wnd = {scrollPos: BX.GetWindowScrollPos(),scrollSize:BX.GetWindowScrollSize()}; 4611 return BX.style(this.PARENT, 'display') != 'none'; 4612}; 4613 4614BX.CHint.prototype.getAdjustPos = function() 4615{ 4616 var res = {}, pos = BX.pos(this.PARENT), min_top = 0; 4617 4618 res.top = pos.bottom + this.PARAMS.dx; 4619 4620 if (BX.admin && BX.admin.panel.DIV) 4621 { 4622 min_top = BX.admin.panel.DIV.offsetHeight + this.PARAMS.dx; 4623 4624 if (BX.admin.panel.isFixed()) 4625 { 4626 min_top += this._wnd.scrollPos.scrollTop; 4627 } 4628 } 4629 4630 if (res.top < min_top) 4631 res.top = min_top; 4632 else 4633 { 4634 if (res.top + this.DIV.offsetHeight > this._wnd.scrollSize.scrollHeight) 4635 res.top = pos.top - this.PARAMS.dx - this.DIV.offsetHeight; 4636 } 4637 4638 res.left = pos.left; 4639 if (pos.left < this.PARAMS.dx) 4640 pos.left = this.PARAMS.dx; 4641 else 4642 { 4643 var floatWidth = this.DIV.offsetWidth; 4644 4645 var max_left = this._wnd.scrollSize.scrollWidth - floatWidth - this.PARAMS.dx; 4646 4647 if (res.left > max_left) 4648 res.left = max_left; 4649 } 4650 4651 return res; 4652}; 4653 4654BX.CHint.prototype.adjustWidth = function() 4655{ 4656 if (this.bWidthAdjusted) return; 4657 4658 var w = this.DIV.offsetWidth, h = this.DIV.offsetHeight; 4659 4660 if (w > this.PARAMS.min_width) 4661 w = Math.round(Math.sqrt(1.618*w*h)); 4662 4663 if (w < this.PARAMS.min_width) 4664 w = this.PARAMS.min_width; 4665 4666 this.DIV.style.width = w + "px"; 4667 4668 if (this._adjustWidthInt) 4669 clearInterval(this._adjustWidthInt); 4670 this._adjustWidthInt = setInterval(BX.delegate(this._adjustWidthInterval, this), 5); 4671 4672 this.bWidthAdjusted = true; 4673}; 4674 4675BX.CHint.prototype._adjustWidthInterval = function() 4676{ 4677 if (!this.DIV || this.DIV.style.display == 'none') 4678 clearInterval(this._adjustWidthInt); 4679 4680 var 4681 dW = 20, 4682 maxWidth = 1500, 4683 w = this.DIV.offsetWidth, 4684 w1 = this.CONTENT_TEXT.offsetWidth; 4685 4686 if (w > 0 && w1 > 0 && w - w1 < dW && w < maxWidth) 4687 { 4688 this.DIV.style.width = (w + dW) + "px"; 4689 return; 4690 } 4691 4692 clearInterval(this._adjustWidthInt); 4693}; 4694 4695BX.CHint.prototype.adjustPos = function() 4696{ 4697 this.adjustWidth(); 4698 4699 var pos = this.getAdjustPos(); 4700 4701 this.DIV.style.top = pos.top + 'px'; 4702 this.DIV.style.left = pos.left + 'px'; 4703}; 4704 4705BX.CHint.prototype.Close = function() 4706{ 4707 if (this.ID && BX.WindowManager) 4708 BX.WindowManager.saveWindowOptions(this.ID, {display: 'off'}); 4709 this.__hide_immediately(); 4710 this.Destroy(); 4711}; 4712
4713BX.CHint.prototype.Destroy = function() 4714{ 4715 if (this.PARENT) 4716 { 4717 BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this)); 4718 BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this)); 4719 } 4720 4721 if (this.DIV) 4722 { 4723 BX.unbind(this.DIV, 'mouseover', BX.proxy(this.Show, this)); 4724 BX.unbind(this.DIV, 'mouseout', BX.proxy(this.Hide, this)); 4725 4726 BX.cleanNode(this.DIV, true); 4727 } 4728}; 4729 4730BX.CHint.prototype.enable = function(){this.disabled = false;}; 4731BX.CHint.prototype.disable = function(){this.__hide_immediately(); this.disabled = true;}; 4732 4733/* ready */ 4734if (document.addEventListener) 4735{ 4736 __readyHandler = function() 4737 { 4738 document.removeEventListener("DOMContentLoaded", __readyHandler, false); 4739 runReady(); 4740 } 4741} 4742else if (document.attachEvent) 4743{ 4744 __readyHandler = function() 4745 { 4746 if (document.readyState === "complete") 4747 { 4748 document.detachEvent("onreadystatechange", __readyHandler); 4749 runReady(); 4750 } 4751 } 4752} 4753 4754function bindReady() 4755{ 4756 if (!readyBound) 4757 { 4758 readyBound = true; 4759 4760 if (document.readyState === "complete") 4761 { 4762 return runReady(); 4763 } 4764 4765 if (document.addEventListener) 4766 { 4767 document.addEventListener("DOMContentLoaded", __readyHandler, false); 4768 window.addEventListener("load", runReady, false); 4769 } 4770 else if (document.attachEvent) // IE 4771 { 4772 document.attachEvent("onreadystatechange", __readyHandler); 4773 window.attachEvent("onload", runReady); 4774 4775 var toplevel = false; 4776 try {toplevel = (window.frameElement == null);} catch(e) {} 4777 4778 if (document.documentElement.doScroll && toplevel) 4779 doScrollCheck(); 4780 } 4781 } 4782 4783 return null; 4784} 4785 4786 4787function runReady() 4788{ 4789 if (!BX.isReady) 4790 { 4791 if (!document.body) 4792 return setTimeout(runReady, 15); 4793 4794 BX.isReady = true; 4795 4796 if (readyList && readyList.length > 0) 4797 { 4798 var fn, i = 0; 4799 while (readyList && (fn = readyList[i++])) 4800 { 4801 try{ 4802 fn.call(document); 4803 } 4804 catch(e){ 4805 BX.debug('BX.ready error: ', e); 4806 } 4807 } 4808 4809 readyList = null; 4810 } 4811 4812 // TODO: check ready handlers binded some other way; 4813 } 4814 return null; 4815} 4816 4817// hack for IE 4818function doScrollCheck() 4819{ 4820 if (BX.isReady) 4821 return; 4822 4823 try {document.documentElement.doScroll("left");} catch( error ) {setTimeout(doScrollCheck, 1); return;} 4824 4825 runReady(); 4826} 4827/* \ready */ 4828 4829function _adjustWait() 4830{ 4831 if (!this.bxmsg) return; 4832 4833 var arContainerPos = BX.pos(this), 4834 div_top = arContainerPos.top; 4835 4836 if (div_top < BX.GetDocElement().scrollTop) 4837 div_top = BX.GetDocElement().scrollTop + 5; 4838 4839 this.bxmsg.style.top = (div_top + 5) + 'px'; 4840 4841 if (this == BX.GetDocElement()) 4842 { 4843 this.bxmsg.style.right = '5px'; 4844 } 4845 else 4846 { 4847 this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px'; 4848 } 4849} 4850 4851function _checkDisplay(ob, displayType) 4852{ 4853 if (typeof displayType != 'undefined') 4854 ob.BXDISPLAY = displayType; 4855 4856 var d = ob.style.display || BX.style(ob, 'display'); 4857 if (d != 'none') 4858 { 4859 ob.BXDISPLAY = ob.BXDISPLAY || d; 4860 return true; 4861 } 4862 else 4863 { 4864 ob.BXDISPLAY = ob.BXDISPLAY || 'block'; 4865 return false; 4866 } 4867} 4868 4869function _processTpl(tplNode, cb, bKillTpl) 4870{ 4871 if (tplNode) 4872 { 4873 if (bKillTpl) 4874 tplNode.parentNode.removeChild(tplNode); 4875 4876 var res = {}, nodes = BX.findChildren(tplNode, {attribute: 'data-role'}, true); 4877 4878 for (var i = 0, l = nodes.length; i < l; i++) 4879 { 4880 res[nodes[i].getAttribute('data-role')] = nodes[i]; 4881 } 4882 4883 cb.apply(tplNode, [res]); 4884 } 4885} 4886 4887function _checkNode(obj, params) 4888{ 4889 params = params || {}; 4890 4891 if (BX.type.isFunction(params)) 4892 return params.call(window, obj); 4893 4894 if (!params.allowTextNodes && !BX.type.isElementNode(obj)) 4895 return false; 4896 var i,j,len; 4897 for (i in params) 4898 { 4899 if(params.hasOwnProperty(i)) 4900 { 4901 switch(i) 4902 { 4903 case 'tag': 4904 case 'tagName': 4905 if (BX.type.isString(params[i])) 4906 { 4907 if (obj.tagName.toUpperCase() != params[i].toUpperCase()) 4908 return false; 4909 } 4910 else if (params[i] instanceof RegExp) 4911 { 4912 if (!params[i].test(obj.tagName)) 4913 return false; 4914 } 4915 break; 4916 4917 case 'class': 4918 case 'className': 4919 if (BX.type.isString(params[i])) 4920 { 4921 if (!BX.hasClass(obj, params[i])) 4922 return false; 4923 } 4924 else if (params[i] instanceof RegExp) 4925 { 4926 if (!BX.type.isString(obj.className) || !params[i].test(obj.className)) 4927 return false;
4928 } 4929 break; 4930 4931 case 'attr': 4932 case 'attrs': 4933 case 'attribute': 4934 if (BX.type.isString(params[i])) 4935 { 4936 if (!obj.getAttribute(params[i])) 4937 return false; 4938 } 4939 else if (BX.type.isArray(params[i])) 4940 { 4941 for (j = 0, len = params[i].length; j < len; j++) 4942 { 4943 if (params[i] && !obj.getAttribute(params[i])) 4944 return false; 4945 } 4946 } 4947 else 4948 { 4949 for (j in params[i]) 4950 { 4951 if(params[i].hasOwnProperty(j)) 4952 { 4953 var q = obj.getAttribute(j); 4954 if (params[i][j] instanceof RegExp) 4955 { 4956 if (!BX.type.isString(q) || !params[i][j].test(q)) 4957 { 4958 return false; 4959 } 4960 } 4961 else 4962 { 4963 if (q != '' + params[i][j]) 4964 { 4965 return false; 4966 } 4967 } 4968 } 4969 } 4970 } 4971 break; 4972 4973 case 'property': 4974 case 'props': 4975 if (BX.type.isString(params[i])) 4976 { 4977 if (!obj[params[i]]) 4978 return false; 4979 } 4980 else if (BX.type.isArray(params[i])) 4981 { 4982 for (j = 0, len = params[i].length; j < len; j++) 4983 { 4984 if (params[i] && !obj[params[i]]) 4985 return false; 4986 } 4987 } 4988 else 4989 { 4990 for (j in params[i]) 4991 { 4992 if (BX.type.isString(params[i][j])) 4993 { 4994 if (obj[j] != params[i][j]) 4995 return false; 4996 } 4997 else if (params[i][j] instanceof RegExp) 4998 { 4999 if (!BX.type.isString(obj[j]) || !params[i][j].test(obj[j])) 5000 return false; 5001 } 5002 } 5003 } 5004 break; 5005 5006 case 'callback': 5007 return params[i](obj); 5008 } 5009 } 5010 } 5011 5012 return true; 5013} 5014 5015/* garbage collector */ 5016function Trash() 5017{ 5018 var i,len; 5019 5020 for (i = 0, len = garbageCollectors.length; i<len; i++) 5021 { 5022 try { 5023 garbageCollectors[i].callback.apply(garbageCollectors[i].context || window); 5024 delete garbageCollectors[i]; 5025 garbageCollectors[i] = null; 5026 } catch (e) {} 5027 } 5028 5029 try {BX.unbindAll();} catch(e) {} 5030/* 5031 for (i = 0, len = proxyList.length; i < len; i++) 5032 { 5033 try { 5034 delete proxyList[i]; 5035 proxyList[i] = null; 5036 } catch (e) {} 5037 } 5038*/ 5039} 5040 5041if(window.attachEvent) // IE 5042 window.attachEvent("onunload", Trash); 5043else if(window.addEventListener) // Gecko / W3C 5044 //window.addEventListener('unload', Trash, false); 5045 window.addEventListener('pagehide', Trash, false); 5046else 5047 window.onunload = Trash; 5048/* \garbage collector */ 5049 5050// set empty ready handler 5051BX(BX.DoNothing); 5052window.BX = BX; 5053BX.browser.addGlobalClass(); 5054 5055/* data storage */ 5056BX.data = function(node, key, value) 5057{ 5058 if(typeof node == 'undefined') 5059 return undefined; 5060 5061 if(typeof key == 'undefined') 5062 return undefined; 5063 5064 if(typeof value != 'undefined') 5065 { 5066 // write to manager 5067 dataStorage.set(node, key, value); 5068 } 5069 else 5070 { 5071 var data; 5072 5073 // from manager 5074 if((data = dataStorage.get(node, key)) != undefined) 5075 { 5076 return data; 5077 } 5078 else 5079 { 5080 // from attribute data-* 5081 if('getAttribute' in node) 5082 { 5083 data = node.getAttribute('data-'+key.toString()); 5084 if(data === null) 5085 { 5086 return undefined; 5087 } 5088 return data; 5089 } 5090 } 5091 5092 return undefined; 5093 } 5094}; 5095 5096BX.DataStorage = function() 5097{ 5098 5099 this.keyOffset = 1; 5100 this.data = {}; 5101 this.uniqueTag = 'BX-'+Math.random(); 5102 5103 this.resolve = function(owner, create){ 5104 if(typeof owner[this.uniqueTag] == 'undefined') 5105 if(create) 5106 { 5107 try 5108 { 5109 Object.defineProperty(owner, this.uniqueTag, { 5110 value: this.keyOffset++ 5111 }); 5112 } 5113 catch(e) 5114 { 5115 owner[this.uniqueTag] = this.keyOffset++; 5116 } 5117 } 5118 else 5119 return undefined; 5120 5121 return owner[this.uniqueTag]; 5122 }; 5123 this.get = function(owner, key){ 5124 if((owner != document && !BX.type.isElementNode(owner)) || typeof key == 'undefined') 5125 return undefined; 5126 5127 owner = this.resolve(owner, false); 5128 5129 if(typeof owner == 'undefined' || typeof this.data[owner] == 'undefined') 5130 return undefined; 5131 5132 return this.data[owner][key]; 5133 }; 5134 this.set = function(owner, key, value){ 5135 5136 if((owner != document && !BX.type.isElementNode(owner)) || typeof value == 'undefined') 5137 return; 5138 5139 var o = this.resolve(owner, true); 5140 5141 if(typeof this.data[o] == 'undefined') 5142 this.data[o] = {}; 5143 5144 this.data[o][key] = value; 5145 }; 5146}; 5147 5148// some internal variables for new logic 5149var dataStorage = new BX.DataStorage(); // manager which BX.data() uses to keep data 5150 5151BX.LazyLoad = { 5152 images: [], 5153 imageStatus: { 5154 hidden: -2, 5155 error: -1, 5156 "undefined": 0, 5157 inited: 1, 5158 loaded: 2 5159 }, 5160 imageTypes: { 5161 image: 1, 5162 background: 2 5163 }, 5164 5165 registerImage: function(id, isImageVisibleCallback) 5166 { 5167 if (BX.type.isNotEmptyString(id)) 5168 { 5169 this.images.push({ 5170 id: id, 5171 node: null, 5172 src: null, 5173 type: null, 5174 func: BX.type.isFunction(isImageVisibleCallback) ? isImageVisibleCallback : null, 5175 status: this.imageStatus.undefined 5176 }); 5177 } 5178 }, 5179 5180 registerImages: function(ids, isImageVisibleCallback) 5181 { 5182 if (BX.type.isArray(ids)) 5183 { 5184 for (var i = 0, length = ids.length; i < length; i++) 5185 { 5186 this.registerImage(ids[i], isImageVisibleCallback); 5187 } 5188 } 5189 }, 5190 5191 showImages: function(checkOwnVisibility) 5192 { 5193 var image = null; 5194 var isImageVisible = false;
5195 5196 checkOwnVisibility = (checkOwnVisibility !== false); 5197 for (var i = 0, length = this.images.length; i < length; i++) 5198 { 5199 image = this.images[i]; 5200 5201 if (image.status == this.imageStatus.undefined) 5202 { 5203 this.initImage(image); 5204 } 5205 5206 if (image.status !== this.imageStatus.inited) 5207 { 5208 continue; 5209 } 5210 5211 if ( 5212 !image.node 5213 || !image.node.parentNode 5214 ) 5215 { 5216 image.node = null; 5217 image.status = this.imageStatus.error; 5218 continue; 5219 } 5220 5221 isImageVisible = true; 5222 if (checkOwnVisibility && image.func) 5223 { 5224 isImageVisible = image.func(image); 5225 } 5226 5227 if ( 5228 isImageVisible === true 5229 && this.isElementVisibleOnScreen(image.node) 5230 ) 5231 { 5232 if (image.type == this.imageTypes.image) 5233 { 5234 image.node.src = image.src; 5235 } 5236 else 5237 { 5238 image.node.style.backgroundImage = "url('" + image.src + "')"; 5239 } 5240 5241 image.node.setAttribute("data-src", ""); 5242 image.status = this.imageStatus.loaded; 5243 } 5244 } 5245 }, 5246 5247 initImage: function(image) 5248 { 5249 image.status = this.imageStatus.error; 5250 var node = BX(image.id); 5251 if (node) 5252 { 5253 var src = node.getAttribute("data-src"); 5254 if (BX.type.isNotEmptyString(src)) 5255 { 5256 image.node = node; 5257 image.src = src; 5258 image.status = this.imageStatus.inited; 5259 image.type = (image.node.tagName.toLowerCase() == "img" 5260 ? this.imageTypes.image 5261 : this.imageTypes.background 5262 ); 5263 } 5264 } 5265 }, 5266 5267 isElementVisibleOnScreen: function (element) 5268 { 5269 var coords = this.getElementCoords(element); 5270 5271 var windowTop = window.pageYOffset || document.documentElement.scrollTop; 5272 var windowBottom = windowTop + document.documentElement.clientHeight; 5273 5274 coords.bottom = coords.top + element.offsetHeight; 5275 5276 var topVisible = coords.top > windowTop && coords.top < windowBottom; 5277 var bottomVisible = coords.bottom < windowBottom && coords.bottom > windowTop; 5278 5279 return topVisible || bottomVisible; 5280 }, 5281 5282 isElementVisibleOn2Screens: function(element) 5283 { 5284 var coords = this.getElementCoords(element); 5285 5286 var windowHeight = document.documentElement.clientHeight; 5287 var windowTop = window.pageYOffset || document.documentElement.scrollTop; 5288 var windowBottom = windowTop + windowHeight; 5289 5290 coords.bottom = coords.top + element.offsetHeight; 5291 5292 windowTop -= windowHeight; 5293 windowBottom += windowHeight; 5294 5295 var topVisible = coords.top > windowTop && coords.top < windowBottom; 5296 var bottomVisible = coords.bottom < windowBottom && coords.bottom > windowTop; 5297 5298 return topVisible || bottomVisible; 5299 }, 5300 5301 getElementCoords: function(element) 5302 { 5303 var box = element.getBoundingClientRect(); 5304 5305 return { 5306 originTop: box.top, 5307 originLeft: box.left, 5308 top: box.top + window.pageYOffset, 5309 left: box.left + window.pageXOffset 5310 }; 5311 }, 5312 5313 onScroll: function() 5314 { 5315 BX.LazyLoad.showImages(); 5316 }, 5317 5318 clearImages: function () 5319 { 5320 this.images = []; 5321 } 5322 5323}; 5324 5325BX.getCookie = function (name) 5326{ 5327 var matches = document.cookie.match(new RegExp( 5328 "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" 5329 )); 5330 5331 return matches ? decodeURIComponent(matches[1]) : undefined; 5332}; 5333 5334BX.setCookie = function (name, value, options) 5335{ 5336 options = options || {}; 5337 5338 var expires = options.expires; 5339 if (typeof(expires) == "number" && expires) 5340 { 5341 var currentDate = new Date(); 5342 currentDate.setTime(currentDate.getTime() + expires * 1000); 5343 expires = options.expires = currentDate; 5344 } 5345 5346 if (expires && expires.toUTCString) 5347 { 5348 options.expires = expires.toUTCString(); 5349 } 5350 5351 value = encodeURIComponent(value); 5352 5353 var updatedCookie = name + "=" + value; 5354 5355 for (var propertyName in options) 5356 { 5357 if (!options.hasOwnProperty(propertyName)) 5358 { 5359 continue; 5360 } 5361 updatedCookie += "; " + propertyName; 5362 var propertyValue = options[propertyName]; 5363 if (propertyValue !== true) 5364 { 5365 updatedCookie += "=" + propertyValue; 5366 } 5367 } 5368 5369 document.cookie = updatedCookie; 5370 5371 return true; 5372}; 5373 5374BX.FixFontSize = function(params) 5375{ 5376 var widthNode, computedStyles, width; 5377 5378 this.node = null; 5379 this.prevWindowSize = 0; 5380 this.prevWrapperSize = 0; 5381 this.mainWrapper = null; 5382 this.textWrapper = null; 5383 this.objList = params.objList; 5384 this.minFontSizeList = []; 5385 this.minFontSize = 0; 5386 5387 if (params.onresize) 5388 { 5389 this.prevWindowSize = window.innerWidth || document.documentElement.clientWidth; 5390 BX.bind(window, 'resize', BX.proxy(BX.throttle(this.onResize, 350),this)); 5391 } 5392 5393 if (params.onAdaptiveResize) 5394 { 5395 widthNode = this.objList[0].scaleBy || this.objList[0].node; 5396 computedStyles = getComputedStyle(widthNode); 5397 this.prevWrapperSize = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]); 5398 BX.bind(window, 'resize', BX.proxy(BX.throttle(this.onAdaptiveResize, 350),this)); 5399 } 5400 5401 this.createTestNodes(); 5402 this.decrease(); 5403}; 5404 5405BX.FixFontSize.prototype = 5406{ 5407 createTestNodes: function() 5408 { 5409 this.textWrapper = BX.create('div',{ 5410 style : { 5411 display : 'inline-block', 5412 whiteSpace : 'nowrap' 5413 } 5414 }); 5415 5416 this.mainWrapper = BX.create('div',{ 5417 style : { 5418 height : 0, 5419 overflow : 'hidden' 5420 }, 5421 children : [this.textWrapper] 5422 }); 5423 5424 }, 5425 insertTestNodes: function() 5426 { 5427 document.body.appendChild(this.mainWrapper); 5428 }, 5429 removeTestNodes: function() 5430 { 5431 document.body.removeChild(this.mainWrapper); 5432 }, 5433 decrease: function() 5434 { 5435 var width, 5436 fontSize, 5437 widthNode, 5438 computedStyles; 5439 5440 this.insertTestNodes(); 5441 5442 for(var i=this.objList.length-1; i>=0; i--) 5443 { 5444 widthNode = this.objList[i].scaleBy || this.objList[i].node; 5445 computedStyles = getComputedStyle(widthNode); 5446 width = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]); 5447 fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]); 5448 5449 this.textWrapperSetStyle(this.objList[i].node); 5450 5451 if(this.textWrapperInsertText(this.objList[i].node)) 5452 { 5453 while(this.textWrapper.offsetWidth > width && fontSize > 0) 5454 { 5455 this.textWrapper.style.fontSize = --fontSize + 'px'; 5456 } 5457 5458 if(this.objList[i].smallestValue) 5459 { 5460 this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize; 5461 5462 this.minFontSizeList.push(this.objList[i].node) 5463 } 5464 else 5465 { 5466 this.objList[i].node.style.fontSize = fontSize + 'px'; 5467 } 5468 } 5469 } 5470 5471 if(this.minFontSizeList.length > 0) 5472 this.setMinFont(); 5473 5474 this.removeTestNodes(); 5475 5476 }, 5477 increase: function() 5478 { 5479 this.insertTestNodes(); 5480 var width, 5481 fontSize, 5482 widthNode, 5483 computedStyles; 5484 5485 this.insertTestNodes(); 5486 5487 for(var i=this.objList.length-1; i>=0; i--) 5488 { 5489 widthNode = this.objList[i].scaleBy || this.objList[i].node; 5490 computedStyles = getComputedStyle(widthNode); 5491 width = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]); 5492 fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]); 5493 5494 this.textWrapperSetStyle(this.objList[i].node); 5495 5496 if(this.textWrapperInsertText(this.objList[i].node)) 5497 { 5498 while(this.textWrapper.offsetWidth < width && fontSize < this.objList[i].maxFontSize) 5499 { 5500 this.textWrapper.style.fontSize = ++fontSize + 'px'; 5501 } 5502 5503 fontSize--; 5504 5505 if(this.objList[i].smallestValue) 5506 { 5507 this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize; 5508 5509 this.minFontSizeList.push(this.objList[i].node) 5510 } 5511 else 5512 { 5513 this.objList[i].node.style.fontSize = fontSize + 'px'; 5514 } 5515 } 5516 } 5517 5518 if(this.minFontSizeList.length > 0) 5519 this.setMinFont(); 5520 5521 this.removeTestNodes(); 5522 }, 5523 setMinFont : function() 5524 { 5525 for(var i = this.minFontSizeList.length-1; i>=0; i--) 5526 { 5527 this.minFontSizeList[i].style.fontSize = this.minFontSize + 'px'; 5528 } 5529 5530 this.minFontSize = 0; 5531 }, 5532 onResize : function() 5533 { 5534 var width = window.innerWidth || document.documentElement.clientWidth; 5535 5536 if(this.prevWindowSize > width) 5537 this.decrease(); 5538 5539 else if (this.prevWindowSize < width) 5540 this.increase(); 5541 5542 this.prevWindowSize = width; 5543 }, 5544 onAdaptiveResize : function() 5545 { 5546 var widthNode = this.objList[0].scaleBy || this.objList[0].node, 5547 computedStyles = getComputedStyle(widthNode), 5548 width = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]); 5549 5550 if (this.prevWrapperSize > width) 5551 this.decrease(); 5552 else if (this.prevWrapperSize < width) 5553 this.increase(); 5554 5555 this.prevWrapperSize = width; 5556 }, 5557 textWrapperInsertText : function(node) 5558 { 5559 if(node.textContent){ 5560 this.textWrapper.textContent = node.textContent; 5561 return true; 5562 } 5563 else if(node.innerText) 5564 { 5565 this.textWrapper.innerText = node.innerText; 5566 return true; 5567 } 5568 else { 5569 return false;
5570 } 5571 }, 5572 textWrapperSetStyle : function(node) 5573 { 5574 this.textWrapper.style.fontFamily = getComputedStyle(node)["font-family"]; 5575 this.textWrapper.style.fontSize = getComputedStyle(node)["font-size"]; 5576 this.textWrapper.style.fontStyle = getComputedStyle(node)["font-style"]; 5577 this.textWrapper.style.fontWeight = getComputedStyle(node)["font-weight"]; 5578 this.textWrapper.style.lineHeight = getComputedStyle(node)["line-height"]; 5579 } 5580}; 5581 5582BX.FixFontSize.init = function(params) 5583{ 5584 return new BX.FixFontSize(params); 5585}; 5586 5587if(typeof(BX.ParamBag) === "undefined") 5588{ 5589 BX.ParamBag = function() 5590 { 5591 this._params = {}; 5592 }; 5593 5594 BX.ParamBag.prototype = 5595 { 5596 initialize: function(params) 5597 { 5598 this._params = params ? params : {}; 5599 }, 5600 getParam: function(name, defaultvalue) 5601 { 5602 var p = this._params; 5603 return typeof(p[name]) != "undefined" ? p[name] : defaultvalue; 5604 }, 5605 setParam: function(name, value) 5606 { 5607 this._params[name] = value; 5608 }, 5609 clear: function() 5610 { 5611 this._params = {}; 5612 } 5613 }; 5614 5615 BX.ParamBag.create = function(params) 5616 { 5617 var self = new BX.ParamBag(); 5618 self.initialize(params); 5619 return self; 5620 } 5621} 5622 5623if(typeof(BX.Promise) === "undefined") 5624{ 5625 BX.Promise = function(fn, ctx) // fn is future-reserved 5626 { 5627 this.state = null; 5628 this.value = null; 5629 this.reason = null; 5630 this.next = null; 5631 this.ctx = ctx || this; 5632 5633 this.onFulfilled = []; 5634 this.onRejected = []; 5635 }; 5636 BX.Promise.prototype.fulfill = function(value) 5637 { 5638 this.checkState(); 5639 5640 this.value = value; 5641 this.state = true; 5642 this.execute(); 5643 }; 5644 BX.Promise.prototype.reject = function(reason) 5645 { 5646 this.checkState(); 5647 5648 this.reason = reason; 5649 this.state = false; 5650 this.execute(); 5651 }; 5652 BX.Promise.prototype.then = function(onFulfilled, onRejected) 5653 { 5654 if(BX.type.isFunction(onFulfilled)) 5655 { 5656 this.onFulfilled.push(onFulfilled); 5657 } 5658 if(BX.type.isFunction(onRejected)) 5659 { 5660 this.onRejected.push(onRejected); 5661 } 5662 5663 if(this.next === null) 5664 { 5665 this.next = new BX.Promise(null, this.ctx); 5666 } 5667 5668 if(this.state !== null) // if promise was already resolved, execute immediately 5669 { 5670 this.execute(); 5671 } 5672 5673 return this.next; 5674 }; 5675 5676 BX.Promise.prototype.catch = function(onRejected) 5677 { 5678 if(BX.type.isFunction(onRejected)) 5679 { 5680 this.onRejected.push(onRejected); 5681 } 5682 5683 if(this.next === null) 5684 { 5685 this.next = new BX.Promise(null, this.ctx); 5686 } 5687 5688 if(this.state !== null) // if promise was already resolved, execute immediately 5689 { 5690 this.execute(); 5691 } 5692 5693 return this.next; 5694 }; 5695 5696 BX.Promise.prototype.setAutoResolve = function(way, ms) 5697 { 5698 this.timer = setTimeout(BX.delegate(function(){ 5699 if(this.state === null) 5700 { 5701 this[way ? 'fulfill' : 'reject'](); 5702 } 5703 }, this), ms || 15); 5704 }; 5705 BX.Promise.prototype.cancelAutoResolve = function() 5706 { 5707 clearTimeout(this.timer); 5708 }; 5709 /** 5710 * Resolve function. This function allows promise chaining, like ..then().then()... 5711 * Typical usage: 5712 *
5713 * var p = new Promise(); 5714 * 5715 * p.then(function(value){ 5716 * return someValue; // next promise in the chain will be fulfilled with someValue 5717 * }).then(function(value){ 5718 * 5719 * var p1 = new Promise(); 5720 * *** some async code here, that eventually resolves p1 *** 5721 * 5722 * return p1; // chain will resume when p1 resolved (fulfilled or rejected) 5723 * }).then(function(value){ 5724 * 5725 * // you can also do 5726 * var e = new Error(); 5727 * throw e; 5728 * // it will cause next promise to be rejected with e 5729 * 5730 * return someOtherValue; 5731 * }).then(function(value){ 5732 * ... 5733 * }, function(reason){ 5734 * // promise was rejected with reason 5735 * })...; 5736 * 5737 * p.fulfill('let`s start this chain'); 5738 * 5739 * @param x 5740 */ 5741 BX.Promise.prototype.resolve = function(x) 5742 { 5743 var this_ = this; 5744 5745 if(this === x) 5746 { 5747 this.reject(new TypeError('Promise cannot fulfill or reject itself')); // avoid recursion 5748 } 5749 // allow "pausing" promise chaining until promise x is fulfilled or rejected 5750 else if(x instanceof BX.Promise) 5751 { 5752 x.then(function(value){ 5753 this_.fulfill(value); 5754 }, function(reason){ 5755 this_.reject(reason); 5756 }); 5757 } 5758 else // auto-fulfill this promise 5759 { 5760 this.fulfill(x); 5761 } 5762 }; 5763 BX.Promise.prototype.execute = function() 5764 { 5765 if(this.state === null) 5766 { 5767 //then() must not be called before BX.Promise resolve() happens 5768 return; 5769 } 5770 5771 var value = undefined; 5772 var reason = undefined; 5773 var x = undefined; 5774 var k; 5775 if(this.state === true) // promise was fulfill()-ed 5776 { 5777 if(this.onFulfilled.length) 5778 { 5779 try 5780 { 5781 for(k = 0; k < this.onFulfilled.length; k++) 5782 {
5783 x = this.onFulfilled[k].apply(this.ctx, [this.value]); 5784 if(typeof x != 'undefined') 5785 { 5786 value = x; 5787 } 5788 } 5789 } 5790 catch(e) 5791 { 5792 if('console' in window) 5793 { 5794 console.dir(e); 5795 } 5796 BX.debug(e); 5797 5798 reason = e; // reject next 5799 } 5800 } 5801 else 5802 { 5803 value = this.value; // resolve next 5804 } 5805 } 5806 else if(this.state === false) // promise was reject()-ed 5807 { 5808 if(this.onRejected.length) 5809 { 5810 try 5811 { 5812 for(k = 0; k < this.onRejected.length; k++) 5813 { 5814 x = this.onRejected[k].apply(this.ctx, [this.reason]); 5815 if(typeof x != 'undefined') 5816 { 5817 value = x; 5818 } 5819 } 5820 } 5821 catch(e) 5822 { 5823 if('console' in window) 5824 { 5825 console.dir(e); 5826 } 5827 BX.debug(e); 5828 5829 reason = e; // reject next 5830 } 5831 } 5832 else 5833 { 5834 reason = this.reason; // reject next 5835 } 5836 } 5837 5838 if(this.next !== null) 5839 { 5840 if(typeof reason != 'undefined') 5841 { 5842 this.next.reject(reason); 5843 } 5844 else if(typeof value != 'undefined') 5845 { 5846 this.next.resolve(value); 5847 } 5848 } 5849 }; 5850 BX.Promise.prototype.checkState = function() 5851 { 5852 if(this.state !== null) 5853 { 5854 throw new Error('You can not do fulfill() or reject() multiple times'); 5855 } 5856 }; 5857} 5858 5859})(window); 5860
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.