1 2class SizeSelectPanel 3{ 4 constructor(panel) 5 { 6 this.panel = panel; 7 8 this.events = {}; 9 10 this.items = $('.size-dialog-item', panel); 11 12 const _ = this; 13 14 _.selectedValue = null; 15 16 $(this.items).click(function() 17 { 18 if($(this).hasClass('inactive')) 19 return false; 20 21 const v = parseInt($(this).attr('data-value')); 22 23 $(this).addClass('selected').parent().children(). 24 not(this).removeClass('selected'); 25 26 _.selectedValue = v; 27 28 if(_.events.onclick) 29 _.events.onclick(v); 30 }); 31 } 32 33 setVisible(values) 34 { 35 const items = this.items.addClass('inactive'); 36 37 for(const k in values) 38 { 39 this.items. 40 filter(`[data-value="${k}"]`). 41 removeClass('inactive'); 42 } 43 } 44 45 setSelected(value) 46 { 47 this.selectedValue = value; 48 49 this.items.removeClass('selected'). 50 filter(`[data-value="${value}"]`). 51 addClass('selected'); 52 } 53 54 setPreselected(value) 55 { 56 this.items.removeClass('preselected'). 57 filter(`[data-value="${value}"]`). 58 addClass('preselected'); 59 } 60 61 setLoading(loading) 62 { 63 this.panel.toggleClass('loading', loading); 64 } 65 66 hasSelected() 67 { 68 return this.selectedValue > 0; 69 } 70 71 getValue() 72 { 73 return this.selectedValue; 74 } 75 76 onClick(callback) 77 { 78 this.events.onclick = callback; 79 } 80} 81 82class SizeSelectDialog 83{ 84 constructor(options) 85 { 86 this.options = options || {}; 87 } 88 89 setSelected(idsize) 90 { 91 if(this.simple_selector) 92 { 93 94 } 95 else 96 { 97 if(idsize === null) 98 { 99 this.panels.w.setSelected(null); 100 this.panels.d.setSelected(null); 101 102 this.otherSizes.removeClass('selected'); 103 } 104 else 105 { 106 const selected = this.sizes.values[idsize] || {}; 107 108 this.otherSizes.removeClass('selected'); 109 110 if(selected.other) 111 { 112 this.panels.w.setSelected(null); 113 this.panels.d.setSelected(null); 114 115 this.otherSizes. 116 filter(`[data-value="${selected.id}"]`). 117 addClass('selected'); 118 } 119 else if(selected.w && selected.d) 120 { 121 this.panels.w.setSelected(selected.w); 122 this.panels.d.setSelected(selected.d); 123 } 124 } 125 } 126 } 127 128 setPreselected(selected) 129 { 130 if(this.simple_selector) 131 { 132 if(selected === null) 133 { 134 $(`.size-dialog-item`, this.modal).removeClass('preselected'); 135 } 136 else 137 { 138 $(`.size-dialog-item[data-value="${selected.id}"]`, this.modal).addClass('preselected'); 139 } 140 } 141 else 142 { 143 if(selected === null) 144 { 145 [this.panels.w.items, this.panels.d.items, this.otherSizes]. 146 forEach((v) => $(v).removeClass('preselected')); 147 } 148 else 149 { 150 if(selected.other) 151 { 152 this.otherSizes.removeClass('preselected'). 153 filter(`[data-value="${selected.id}"]`). 154 addClass('preselected'); 155 } 156 else if(selected.w && selected.d) 157 { 158 this.panels.w.setPreselected(selected.w); 159 this.panels.d.setPreselected(selected.d); 160 } 161 } 162 } 163 } 164 165 buildBodyHtml() 166 { 167 if(this.simple_selector) 168 { 169 return `<div class=size-dialog-body-outer> 170 ${this.buildSimpleInnerHtml(0)} 171 </div>`; 172 } 173 else 174 { 175 const otherHtml = Object.keys(this.sizes.other).length ? this.buildOtherHtml(this.sizes.other) : ''; 176 177 return `<div class=size-dialog-body-outer> 178 ${this.buildInnerHtml(Object.keys(this.variants.w), 'w', 'Øèðèíà, ñì')} 179 ${this.buildInnerHtml(Object.keys(this.variants.d), 'd', 'Äëèíà, ñì')} 180 ${otherHtml} 181 </div>`; 182 } 183 } 184 185 setupSelectorPanels(selector) 186 { 187 if(this.simple_selector) 188 { 189 const _ = this; 190 191 $('.size-dialog-item', _.modal).click(function() 192 { 193 const value = $(this).attr('data-value'); 194 _.onSizeSelectedInternal(_.sizes.values[value], true); 195 }); 196 } 197 else 198 { 199 this.panels = {}; 200 201 this.panels.w = new SizeSelectPanel($('.size-dialog-w-body-outer', selector)); 202 this.panels.d = new SizeSelectPanel($('.size-dialog-d-body-outer', selector)); 203 204 this.otherSizes = $('.size-dialog-other-body-outer .size-dialog-item', selector); 205 206 const _ = this; 207 208 this.panels.w.onClick((value) => 209 { 210 _.setPreselected(null); 211 212 _._onSelectValue({w: value, d: null}, _.panels.d); 213 }); 214 215 this.panels.d.onClick((value) => 216 { 217 _.setPreselected(null); 218 219 _._onSelectValue({w: null, d: value}, _.panels.w); 220 }); 221 222 $('.size-dialog-other-body-outer .size-dialog-item', selector).click(function() 223 { 224 const value = $(this).attr('data-value'); 225 _.onSizeSelectedInternal(_.sizes.other[value], true); 226 }); 227 } 228 } 229 230 buildModal() 231 { 232 const modal = $('.size-select-dialog-modal'); 233 234 if(modal.length && modal.hasClass('is-loader')) 235 { 236 const _ = this; 237 238 _.modal = modal; 239 240 modal.removeClass('is-loader'); 241 242 $('.modal-body', modal). 243 html('<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>' + 244 this.buildBodyHtml()); 245 246 modal.on('hidden.bs.modal', function() 247 { 248 modal.remove(); 249 }); 250 } 251 else 252 { 253 $('.size-select-dialog-modal').remove(); 254 255 const src = `<div id=size-select-dialog class="modal fade size-select-dialog-modal" tabindex="-1" role="dialog"> 256 <div class="modal-dialog"> 257 <div class=loading-overlay></div> 258 <div class="modal-content"> 259 <div class="modal-body"> 260 <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button> 261 ${this.buildBodyHtml()} 262 </div> 263 </div> 264 </div> 265 </div>`; 266 267 $('body').append(src); 268 269 const _ = this; 270 271 _.modal = $('#size-select-dialog'); 272 273 _.modal.on('hidden.bs.modal', function() 274 { 275 _.modal.remove(); 276 }); 277 } 278 279 this.setupSelectorPanels(this.modal); 280 } 281 282 initializeModal() 283 { 284 if(this.modalInitialized) 285 return; 286 287 this.modalInitialized = true; 288 289 this.buildModal(); 290 } 291 292 isModalVisible() 293 { 294 return $('.size-select-dialog-modal').length; 295 } 296 297 onSizeSelectedInternal(size) 298 { 299 const _ = this; 300 301 _.setPreselected(null); 302 303 if(_.modal) 304 _.modal.modal('hide'); 305 306 _.onSizeSelected(size); 307 308 if(!this.simple_selector) 309 { 310 _.panels.w.setSelected(0); 311 _.panels.d.setSelected(0); 312 } 313 } 314 315 needLoaderAnimation() 316 { 317 return false; 318 } 319 320 getVariants(w, d, callback) 321 { 322 if(w) 323 { 324 callback(this.variants.w[w]); 325 } 326 else if(d) 327 { 328 callback(this.variants.d[d]); 329 } 330 } 331 332 getSelectedSize() 333 { 334 const w = this.panels.w.getValue(); 335 const d = this.panels.d.getValue(); 336 337 return this.sizes.values[this.variants.w[w][d]]; 338 } 339 340 getSize(size) 341 { 342 if(size !== null) 343 return this.sizes.values[size] || ((this.sizes.other || {})[size]); 344 } 345 346 getSizeByWD(w, d) 347 { 348 const idsize = this.variants.w[w][d]; 349
350 return idsize ? this.sizes.values[idsize] : null; 351 } 352 353 getSizeByIdOrWD(size, w, d) 354 { 355 return this.getSize(size) || this.getSizeByWD(w, d); 356 } 357 358 updateSizeInputs(size) 359 { 360 361 } 362 363 onSizeSelected(size) 364 { 365 } 366 367 _onSelectValue(data, panel) 368 { 369 const _ = this; 370 371 if(_.panels.w.hasSelected() && _.panels.d.hasSelected()) 372 { 373 _.onSizeSelectedInternal(this.getSelectedSize()); 374 return; 375 } 376 377 if(_.needLoaderAnimation()) 378 panel.setLoading(true); 379 380 _.getVariants(data.w, data.d, function(variants) 381 { 382 if(_.needLoaderAnimation()) 383 panel.setLoading(false); 384 385 panel.setVisible(variants); 386 }); 387 } 388 389 buildSimpleInnerHtml(selected) 390 { 391 const buildSizeItem = (s) => `<div class="size-dialog-item${s.id === selected ? ' preselected' : ''}" data-value="${s.id}"> 392 <div class="size-dialog-item-inner">${s.name}</div> 393 </div>`; 394 395 const sizes = Object.values(this.sizes.values); 396 397 sizes.sort((a, b) => a.ord - b.ord); 398 399 return `<div class=size-dialog-simple-body-outer> 400 <div class="size-dialog-body-name">Ðàçìåð:</div> 401 <div class=size-dialog-simple-body> 402 <div class="size-dialog-block"> 403 ${sizes.map(buildSizeItem).join('')} 404 </div> 405 </div> 406 </div>`; 407 } 408 409 buildInnerHtml(sizes, cls, name, selected) 410 { 411 if(sizes.length === 0) 412 return ''; 413 414 const buildSizeItem = (s) => `<div class="size-dialog-item${s === selected ? ' preselected' : ''}" data-value="${s}"> 415 <div class="size-dialog-item-inner">${s}</div> 416 </div>`; 417 418 return `<div class=size-dialog-${cls}-body-outer> 419 <div class=size-dialog-body-name>${name}</div> 420 <div class=size-dialog-${cls}-body> 421 <div class="size-dialog-block"> 422 ${sizes.map(buildSizeItem).join('')} 423 </div> 424 </div> 425 </div>`; 426 } 427 428 buildOtherHtml(sizes, selected) 429 { 430 const buildSizeItem = (s) => `<div class="size-dialog-item${s.id === selected ? ' preselected' : ''}" data-value="${s.id}"> 431 <div class="size-dialog-item-inner">${s.name}</div> 432 </div>`; 433 434 return `<div class=size-dialog-other-body-outer> 435 <div class="size-dialog-body-name">Êðóãëûå ðàçìåðû</div> 436 <div class="size-dialog-block"> 437 ${Object.values(sizes).map(buildSizeItem).join('')} 438 </div> 439 </div>`; 440 } 441 442 sizesToVariants(sizes) 443 { 444 const variants = {w: {}, d: {}}; 445 446 for(let i = 0; i < sizes.length; i++) 447 { 448 const s = sizes[i]; 449 450 if(!s || !s.w || !s.d) 451 continue; 452 453 const w = s.w; 454 const d = s.d; 455 456 if(!w || !d) 457 continue; 458 459 variants.w[w] = (variants.w[w] || {}); 460 variants.d[d] = (variants.d[d] || {}); 461 462 variants.w[w][d] = s.id; 463 variants.d[d][w] = s.id; 464 } 465 466 for(let i = 0; i < sizes.length; i++) 467 { 468 const s = sizes[i]; 469 470 if(!s || !s.w || !s.d) 471 continue; 472 473 const w = s.w; 474 const d = s.d; 475 476 if(!w || !d) 477 continue; 478 479 480 variants.d[w] = (variants.d[w] || {}); 481 variants.w[d] = (variants.w[d] || {}); 482 483 if(!variants.d[w][d]) 484 variants.d[w][d] = s.id; 485 486 if(!variants.w[d][w]) 487 variants.w[d][w] = s.id; 488 } 489 490 return variants;
491 } 492 493 getSizeData(s) 494 { 495 if(!s.round && !s.dimensions) 496 return null; 497 498 if(s.round) 499 { 500 return { 501 id: s.id || s.idsize, 502 name: s.size || s.name, 503 other: true, 504 size: s 505 }; 506 } 507 else if(s.dimensions) 508 { 509 return { 510 id: s.id || s.idsize, 511 name: s.size || s.name, 512 w: s.dimensions[0], 513 d: s.dimensions[1], 514 size: s 515 }; 516 } 517 } 518 519 prepareData(input) 520 { 521 let sizes = input.sizes; 522 523 if($.isPlainObject(sizes)) 524 sizes = Object.values(sizes); 525 526 this.sizes = {values: {}, other: {}}; 527 this.variants = {w: {}, d: {}}; 528 529 if(true) 530 { 531 if(sizes.length <= 6) 532 { 533 this.simple_selector = true; 534 } 535 else 536 { 537 let size_w = {}; 538 let size_d = {}; 539 540 for(let i = 0; i < sizes.length; i++) 541 { 542 const s = sizes[i]; 543 544 if(s.dimensions) 545 { 546 const w = s.dimensions[0]; 547 const d = s.dimensions[1]; 548 549 size_w[w] = size_w[w] || 0; 550 size_d[d] = size_d[d] || 0; 551 552 size_w[w]++; 553 size_d[d]++; 554 } 555 } 556 557 size_w = Object.values(size_w); 558 size_d = Object.values(size_d); 559 560 if(size_w.length === 1 || size_d.length === 1) 561 { 562 this.simple_selector = true; 563 } 564 else if(sizes.length < size_w.length + size_d.length) 565 { 566 this.simple_selector = true; 567 } 568 569 //this.simple_selector = true; 570 } 571 } 572 573 if(this.simple_selector) 574 { 575 for(let i = 0; i < sizes.length; i++) 576 { 577 const s = sizes[i]; 578 579 const data = this.getSizeData(s); 580 581 data.ord = i; 582 583 const match = data.name.match(/(\d+) [õx] (\d+)/); 584 585 if(match) 586 data.name = `${match[1]} × ${match[2]} ñì`; 587 588 this.sizes.values[data.id] = data; 589 } 590 } 591 else 592 { 593 for(let i = 0; i < sizes.length; i++) 594 { 595 const s = sizes[i]; 596 597 const data = this.getSizeData(s); 598 599 if(!data || (!(data.w && data.d) && !data.other)) 600 continue; 601 602 if(data.other) 603 { 604 this.sizes.other[data.id] = data; 605 } 606 else 607 { 608 this.sizes.values[data.id] = data; 609 } 610 } 611 612 this.variants = this.sizesToVariants(Object.values(this.sizes.values)); 613 } 614 } 615 616 initialize() 617 { 618 } 619 620 showModal() 621 { 622 const _ = this; 623 624 _.buildModal(); 625 626 _.setSelected(null); 627 628 if($.fn.modal_bring_to_front) 629 { 630 _.modal.modal_bring_to_front(); 631 } 632 else 633 { 634 _splited_size_selector_show_modal(_.modal); 635 } 636 } 637} 638 639 640class ExpandedSelectDialog extends SizeSelectDialog 641{ 642 constructor(selector, options) 643 { 644 super(options); 645 646 this.selector = selector; 647 } 648 649 getSizeIntValue() 650 { 651 652 } 653 654 initialize() 655 { 656 super.initialize(); 657 658 this.prepareData(___sizes_json); 659 660 this.selector.html(this.buildBodyHtml()); 661 662 this.setupSelectorPanels(this.selector); 663 } 664 665 updateSizeInputs(size) 666 { 667 668 } 669 670 onSizeSelected(size) 671 {
672 if(this.getSizeIntValue() != size.id) 673 { 674 this.updateSizeInputs(size); 675 676 return true; 677 } 678 679 return false; 680 } 681} 682 683class SimpleSelectDialog extends SizeSelectDialog 684{ 685 constructor(selector, options) 686 { 687 super(options); 688 689 this.selector = $(selector); 690 } 691 692 show() 693 { 694 const selected = this.getSize($('.splited-size-value', this.selector).val()); 695 696 this.showModal(); 697 698 if(selected) 699 this.setPreselected(selected); 700 } 701 702 setupOverlay(new_selector) 703 { 704 const _ = this; 705 706 if($(this.selector).is(new_selector)) 707 return; 708 709 if(new_selector) 710 this.selector = new_selector; 711 712 $('.splited-size-overlay', this.selector).off('click.splited_selector'); 713 714 $('.splited-size-overlay', this.selector).click('click.splited_selector', function() 715 { 716 if(_.isModalVisible()) 717 return false; 718 719 _.show(); 720 }); 721 } 722 723 getData() 724 { 725 var data_id = $(this.selector).attr('data-id'); 726 727 if(window[`___sizes_json${data_id}`]) 728 return window[`___sizes_json${data_id}`]; 729 730 return ___sizes_json; 731 } 732 733 initialize() 734 { 735 super.initialize(); 736 737 this.prepareData(this.getData()); 738 739 this.setupOverlay(); 740 } 741 742 updateSizeInputs(size) 743 { 744 $('.splited-size-value', this.selector).val(size.id); 745 746 const size_w_select = $('.splited-size-w-text > span', this.selector); 747 const size_d_select = $('.splited-size-d-text > span', this.selector); 748 749 const container = $(this.selector).is('.splited-size') ? 750 $(this.selector) : $('.splited-size', this.selector); 751 752 container.removeClass('empty-size'); 753 754 if(size.other) 755 { 756 size_w_select.text(size.name); 757 size_d_select.text(''); 758 759 container.addClass('round-size'); 760 } 761 else 762 { 763 size_w_select.text(size.w); 764 size_d_select.text(size.d); 765 766 container.removeClass('round-size'); 767 } 768 } 769 770 onSizeSelected(size) 771 { 772 if($('.splited-size-value', this.selector).val() != size.id) 773 { 774 this.updateSizeInputs(size); 775 776 return true; 777 } 778 779 return false; 780 } 781} 782 783 784class TextAjaxSelectDialog extends SizeSelectDialog 785{ 786 constructor(context, options) 787 { 788 super(options); 789 790 this.context = $(context); 791 } 792 793 getSizeIntValue() 794 { 795 } 796 797 getSizeTextElement() 798 { 799 } 800
801 getAjaxUrl() 802 { 803 } 804 805 show() 806 { 807 const _ = this; 808 809 if(_.is_loading) 810 return; 811 812 function show_popup() 813 { 814 _.showModal(); 815 816 _.setPreselected(_.getSize(_.getSizeIntValue())); 817 } 818 819 if(this.sizes) 820 { 821 show_popup(); 822 } 823 else 824 { 825 _.is_loading = true; 826 827 $.get(this.getAjaxUrl(), function(res) 828 { 829 _.is_loading = false; 830 831 _.prepareData(res); 832 833 show_popup(); 834 }); 835 } 836 } 837 838 onSizeSelected(size) 839 { 840 if(this.getSizeIntValue() != size.id) 841 { 842 const text = this.getSizeTextElement(); 843 844 if(text) 845 text.html(size.name); 846 847 return true; 848 } 849 850 return false; 851 } 852}
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.