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