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