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