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