1//ToDo: Redo everything!!! 2 3// Simple cache to do not monitor same values 4var upload_procesing_cache = {}; 5 6/** //** ----= setFormsSubmit =----------------------------------------------\**//** \ 7* 8* Sets forms to have submit control. Applies to forms with set onsubmit attribute. 9* 10* @param MIXED element - jQuery selector to search forms within 11* (set to speed up search). 12* 13* @return bool - Always FALSE. 14* 15\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 16function setFormsSubmit ( element ) { 17 18 if ( element && !(element instanceof jQuery) ) 19 element = jQuery(element); 20 21 // Searching for forms, only with onsubmit attribute 22 var forms = ( element )? jQuery(element).find('FORM[onsubmit]') : jQuery('FORM[onsubmit]'); 23 24 // Processing each form for submit control 25 forms.each( function() { 26 27 var form = jQuery(this); 28 var form_id = form.attr('id'); 29 30 // Checking if form has no submit already 31 // ToDo: More complex check 32 if ( form.find('[type=submit]').length ) return; 33 34 // If still here - form have no submit, but have onsubmit attribute 35 // So adding hidden submit control 36 // Adding on top, to do not mess with winContents and layout 37 form.prepend('<input type="submit" style="display: none;" />'); 38 39 if ( !form_id ) return; 40 41 // If element is window with footer buttons related to form (by id) - set them to submit form too. 42 element.find('.winFooter A[rel=' + form_id + ']') 43 .addClass('hi') 44 .unbind('click') 45 .click( function () { 46 47 jQuery('#' + form_id).submit(); 48 49 return false; 50 } ); //FUNC onClick 51 52 }); //FUNC each form 53 54 return false; 55} //FUNC setFormsSubmit 56 57/** //** ----= mwUpdateSelector =--------------------------------------------------------------------------------------\**//** \ 58* 59* Updates selector options with items given. Optionally marks certain items as selected. 60* 61\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 62function mwUpdateSelector (input, options, selected) { 63 64 input = _jq(input); 65 66 // Removing all styles from selector 67 var sel = unstyleInput(input); 68 69 // Cleanning old options 70 sel.find('OPTION').remove(); 71 72 // Adding given options 73 // Supporting maps if one is given 74 if ( isClass(options, 'Map') ) { 75 76 77 /**/ // Using method to iterate, to stay compatible with older JS parsers 78 options.forEach( function ( $val, $key ) { 79 jQuery('<option value="' + $key + '">' + $val + '</option>').appendTo(sel); 80 }); //forEach 81 82 /*/ 83 for ( var i of options ) 84 jQuery('<option value="' + i[0] + '">' + i[1] + '</option>').appendTo(sel); 85 /**/ 86 } //IF map given 87 88 else { 89 90 for ( var i in options ) 91 jQuery('<option value="' + i + '">' + options[i] + '</option>').appendTo(sel); 92 93 } //IF regular data object 94 95 // Setting selected values if given some 96 if ( selected ) 97 setValue_Select(sel.get(0), selected); 98 99 // Restyling input back 100 styleDialog( sel.parent() ); 101 102 // Triggering update 103 sel.trigger('update'); 104 105 return false; 106} //FUNC mwUpdateSelector 107 108/** //** ----= filterSelect =----------------------------------------------\**//** \ 109* 110* Filters styled selector with values. 111* 112* @param MIXED select - Valid jQuery element selector. 113* Sould point to .mwinput.List control. 114* 115* @param string filter - Comma separated filters. 116* @return bool - Always FALSE. 117* 118\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 119function filterSelect ( select, filter ) { 120 121 if ( !filter ) { 122// jQuery(select).find('.Item').fadeIn(200); 123 jQuery(select).find('.item').show(); 124 return false; 125 } //IF empty filter 126 127 // Trimming filters, and composing regex 128 var filter = strToArray(filter, ','); 129 var reg = new RegExp('(' + filter.join('|') + ')', 'i'); 130 131 jQuery(select + ' .item').each( function () { 132 var el = jQuery(this); 133 134 var title = el.find('div').first().html(); 135 136 if ( reg.test(title) ) 137 el.show(); 138 else 139 el.hide(); 140 141 }); //jQuery each 142 143 return false; 144} //FUNC filterSelect 145 146/** //** ----= selectAddItem =----------------------------------------------\**//** \ 147* 148* Adds items to target styled selector. 149* 150* @param MIXED select - Valid jQuery element selector. 151* @param string values - Comma separated values. 152* @return bool - Always FALSE. 153* 154\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 155function selectAddItem ( select, values, checked ) { 156 157 if ( !values ) return false;
158 159 var select = _jq(select); 160 161 checked = ( checked )? ' selected="selected"' : ''; 162 163 // If input given as value, it should be cleaned after all 164 var relate = false; 165 if ( values instanceof jQuery ) { 166 relate = values; 167 values = relate.val(); 168 } //IF parent element given 169 170 if ( isStr(values) ) { 171 var tmp = strToArray(values, ','); 172 173 // Reindexing to have meaningfull keys to use as values 174 // Normally associated arrays or objects should be passed 175 values = {}; 176 177 for ( var i in tmp ) 178 values[tmp[i]] = tmp[i]; 179 180 } //IF string given 181 182 // Before have to save selected inputs, cuz unstyle will reset all to beginning 183 var checks = []; 184 select.find('input:checked').each( function () { 185 checks.push( jQuery(this).val() ); 186 }); //FUNC each.callback 187 188 // Destyling select for easy add new inputs 189 select = unstyleInput(select); 190 191 // Resetting options to to new setting 192 select.find('option').each( function () { 193 194 var el = jQuery(this); 195 if ( checks.indexOf( el.val() ) != -1 ) 196 el.attr('selected', 'selected'); 197 else 198 el.removeAttr('selected'); 199 200 }); //FUNC each.callback 201 202 for ( var i in values ) { 203 select.prepend('<option value="' + i + '"' + checked + '>' + values[i] + '</option>'); 204 } //FOR each value 205 206 // Styling input back again 207 styleDialog(select.parent()); 208 209 return false; 210} //FUNC selectAddItem 211 212/** //** ----= inputClassString =----------------------------------------------\**//** \ 213* 214* Takes source element, and type classes. Prepares full class and style attributes. 215* 216* @param object el - Source input jQuery object. 217* @param string typeClass - Additional classes to add. 218* @return string - Attributes to add to element. 219 bool - FALSE if no modification necessary. 220* 221\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 222function inputClassString(el, typeClass) { 223 224 // If already styled - nothing to do again 225 if ( el.hasClass('mw') ) return false; 226 227 // Saving source to allow fast unstyle 228 el.data('source', getOuterHTML( el.get(0) )); 229 230 // Getting existing attributes 231 var cls = el.attr('class'); 232 233 // Getting other transferrable attributes 234 var $attr = {'class' : ''}; 235 var $aList = ['style', 'size', 'data-prefix', 'data-suffix']; 236 for ( var $i in $aList ) 237 $attr[ $aList[$i] ] = el.attr($aList[$i]); 238 239 var styles = el.attr('style'); 240 241 // Composing classes 242 var ctmp = ['mwInput', typeClass, cls]; 243 244 var name = el.attr('name'); 245 if ( name ) { 246 name = name.replace(/[\[\]]/g, ''); 247 ctmp.push('name-'+name); 248 } //IF name 249 250 // Storing class as attribute 251 $attr['class'] = ctmp.join(' ').trim(); 252 253 // Processing results 254 var $res = ''; 255 for ( var $i in $attr ) 256 if ( !isEmpty($attr[$i]) ) 257 $res += ' '+$i+'="'+$attr[$i]+'"'; 258 259 // Cleaning source attributes 260 el[0].className = ''; 261 262 for ( var $i in $aList ) 263 el.removeAttr($aList[$i]); 264 265 // Adding styled marker 266 el.addClass('mw'); 267 268 return $res; 269} //FUNC inputClassString 270 271/** //** ----= styleDialog =----------------------------------------------\**//** \ 272* 273* Applies style to all inputs childs to specified element. 274* 275* @param MIXED el - Valid jQuery element selector. 276* @return bool - Always FALSE. 277* 278\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 279function styleDialog ( dialog ) { 280 281 dialog = _jq(dialog); 282 283// ---- TEXT ---- 284 285 dialog.find('INPUT[type=text], INPUT[type=search], INPUT[type=password], INPUT[type=email], INPUT[type=date], INPUT[type=number], INPUT[type=tel], INPUT[type=url]').not('[data-input="table"]').each( function () { 286 287 var el = jQuery(this); 288 289 // Cleaning errors state on load 290 //el.closest('.mwInput').removeClass('Error'); 291 292 // Checking if some of subcontrol classes are set and reading sub class 293 var subs = false; 294 var $sClass = ['plus', 'go', 'ok']; 295 for ( var $i in $sClass ) 296 if ( el.is('.'+$sClass[$i]) ) 297 subs = $sClass[$i]; 298 299 // Compatabilty with renamed sub 300 if ( subs == 'go' ) 301 subs = 'ok'; 302 303 var tclass = 'text'; 304 if ( subs ) tclass += ' wSub'; 305 306 var attr = inputClassString(el, tclass); 307 if ( !attr ) return; 308 309 var wrap = jQuery('<div ' + attr + '></div>'); 310 el.wrapAll(wrap); 311 312 // Researching wrap 313 wrap = el.closest('.mwInput'); 314 315 // Adding some common subcontrols if set 316 if ( subs ) { 317 318 var sub = jQuery('<div class="subcontrol button hi icon light '+ subs+'"></div>').insertBefore(el); 319 var click = el.attr('onclick'); 320 321 if ( click ) 322 sub.attr('onclick', click); 323 324 el.removeAttr('onclick'); 325 } //IF is Plus 326 327 // Initiating date picker 328 Date.format = 'yyyy-mm-dd'; 329 if ( wrap.is('.date') ) { 330 el.datePicker({ 331 clickInput : true, 332 createButton : false, 333 verticalOffset : 26, 334 startDate : '2000-01-01' 335 }); 336 } //IF date input 337 338 // Search input is special 339 // Then adding icon and subcontrol 340 // This allows better compatability than regular search, and finer styles control 341 // Skipping manually added icons 342 if ( wrap.is('.search:not(.icon)') ) { 343 344 // Adding search icon on left (it's already search, so just adding icon class) 345 wrap.addClass('icon left'); 346 347 // Padding right is exactly same as left 348 wrap.css( 'padding-right', wrap.css('padding-left') ); 349 350 // Adding clear subcontrol 351 var $sub = jQuery('<div class="subcontrol icon right declined" style="display:none"></div>
351').appendTo(wrap); 352 353 // Adding change event on input 354 el.on('keyup.mwInput.search', function () { 355 356 if ( this.value ) 357 $sub.show(); 358 else 359 $sub.hide(); 360 361 }); //On change 362 363 // Adding clear action 364 $sub.on('click.mwInput.search.clear', function () { 365 366 el.val(''); 367 $sub.hide(); 368 369 el.trigger('keyup'); 370 371 }); //on click 372 373 374 } //IF search found 375 376 // Ensuring input size for prefix/suffix 377 if ( wrap.is('[data-prefix], [data-suffix]') ) { 378 379 } //IF pfx 380 381 // Text inputs should select on forcus 382 el.focus( function () { this.select() } ); 383 384 385 /*/ 386 // Adding required check 387 if ( wrap.hasClass('required') ) { 388 389 el.keyup( function () { 390 var e = jQuery(this); 391 if ( e.val().trim() ) 392 e.closest('.mwInput').removeClass('Error'); 393 else 394 e.closest('.mwInput').addClass('Error'); 395 }); 396 397 } //IF required 398 /**/ 399 400 }); //jQuery each text input 401 402// ---- TEXTAREA ---- 403 404 dialog.find('TEXTAREA').not('.mw, .tinyMCE, .mwTinyMCE, .richEdit').each( function () { 405 var $el = jQuery(this); 406 407 $el.addClass('multiline'); 408 409 var $attr = inputClassString($el, 'textarea'); 410 if ( !$attr ) return; 411 412 $el.wrapAll('<div ' + $attr + '></div>'); 413 414 // Researching wrapper 415 var $wrap = $el.parent(); 416 417 // 100% size inputs are marked with class instead 418 // and triggers default size for fallbacks 419 if ( $wrap.attr('size') == '100%' ) 420 $wrap.addClass('fullHeight').removeAttr('size'); 421 422 // Adding default height 423 if ( !$wrap.attr('size') ) 424 $wrap.attr('size', '3'); 425 426 }); //jQuery each textarea input 427 428 dialog.find('TEXTAREA.richEdit').not('.mw').each( function () { 429 430 // Doing nothing if no tinyMCE defined on page 431 // No fallbacks, as developer should see that smth went wrong 432 if ( typeof(tinyMCE) == 'undefined' ) 433 return; 434 435 var el = jQuery(this); 436 437 el.addClass('multiline'); 438 439 // Marking element as initiated 440 el.addClass('mw'); 441 442 // 100% size inputs are marked with class instead 443 // and triggers default size for fallbacks 444 if ( el.attr('size') == '100%' ) 445 el.addClass('fullHeight').removeAttr('size'); 446 447 // Adding default height 448 if ( !el.attr('size') ) 449 el.attr('size', '5'); 450 451 // Giving it small delay, to let freshly loaded windows to cool a bit. 452 setTimeout( function () { 453 mwTinyMCE().init(el); 454 }, 10); 455 456 }); //jQuery each textarea input 457 458// ---- BUTTONS ---- 459 460// dialog.find('BUTTON, INPUT[type=button], INPUT[type=submit]').each( function () { 461 dialog.find('INPUT[type=button], INPUT[type=submit]').each( function () { 462 463 var el = jQuery(this); 464 465 // Quickly skipping tinyMCE buttons 466 // Bit dirty, but tiny is supported natively 467 // ToDo: init styles from original input instead (would come naturally once proper mwForms are implemented) 468 if ( el.parent().is('.mce-btn') ) 469 return; 470 471 var attr = inputClassString(el, 'button'); 472 if ( !attr ) return; 473 474 el.wrapAll('<div ' + attr + '></div>'); 475 476 // Sumulating active for parent 477 el 478 .bind('mousedown', function () { 479 jQuery(this).parent().addClass('active'); 480 }) //FUNC onMouseDown 481 .bind('mouseup', function () { 482 jQuery(this).parent().removeClass('active'); 483 }) //FUNC onMouseUp 484 ; //jQuery element 485 }); //jQuery each textarea input 486 487 dialog.find('INPUT[type=image]').each( function () { 488 var el = jQuery(this); 489 490 var attr = inputClassString(el, 'button image'); 491 if ( !attr ) return; 492 493 el.wrapAll('<div ' + attr + '></div>'); 494 495 // Sumulating active for parent 496 el 497 .bind('mousedown', function () { 498 jQuery(this).parent().addClass('active'); 499 }) //FUNC onMouseDown 500 .bind('mouseup', function () { 501 jQuery(this).parent().removeClass('active'); 502 }) //FUNC onMouseUp 503 ; //jQuery element 504 }); //jQuery each textarea input 505 506// ---- SELECT ---- 507 508 dialog.find('SELECT').not('.checkList, .radioList, .browseButton, .selectEx').each( function () { 509 var el = jQuery(this); 510 511 if ( el.is('SELECT[multiple], SELECT[size]') ) { 512 513 el.addClass('multiline'); 514 515 var attr = inputClassString(el, 'multiple'); 516 if ( !attr ) return; 517 518 el.wrapAll('<div ' + attr + '></div>'); 519 520 // Researching wrapper 521 var $wrap = el.parent(); 522 523 // 100% size inputs are marked with class instead 524 // and triggers default size for fallbacks 525 if ( $wrap.attr('size') == '100%' ) 526 $wrap.addClass('fullHeight').removeAttr('size'); 527 528 // Adding default height 529 if ( !$wrap.attr('size') ) 530 $wrap.attr('size', '3'); 531 532 } //IF multiselect 533 else { 534 535 var nowidth = el.hasClass('nowidth'); 536 537 var attr = inputClassString(el, 'select'); 538 if ( !attr ) return; 539 540 // ---- Calculating selector min width ---- 541 542 var width = ''; 543 544 if ( !nowidth ) { 545 var tmp = el.clone(); 546 tmp.appendTo('BODY'); 547 width = tmp.width() + 30; 548 tmp.remove(); 549 550 width = ' style="min-width : ' + width + 'px"'; 551 } //IF need width 552 553 el.wrapAll('<div ' + attr + '></div>'); 554 el.addClass('hidden'); 555 556 var val = el.find('OPTION:selected').text(); 557 558 el.before('<div class="subcontrol icon gray dropdown"></div>'); 559 el.before('<div class="value"' + width + '>
559' + val + '</div>'); 560 561 el.on('change update', function () { 562 el.prev('.value').html( el.find('OPTION:selected').text() ); 563 }); //jQuery onChange 564 565 } //IF regular select 566 567 }); //jQuery each select input 568 569/**/ 570// ---- CHECKLIST and RADIOLIST ---- 571 572// dialog.find('SELECT.checkList, SELECT.radioList').not('.old').each( function () { 573 dialog.find('SELECT.checkList.new, SELECT.radioList.new').each( function () { 574 575 var $input = jQuery(this); 576 577 // ---- Defaults ----- 578 579 // Checklist forces multiselect 580 if ( $input.is('.checkList') ) 581 $input.attr('multiple', 'multiple'); 582 583 // Adding default height 584 if ( !$input.attr('size') ) { 585 586 if ( $input.is('[multiple], .checkList, .radioList') ) 587 $input.attr('size', '5'); 588 else 589 $input.attr('size', '1'); 590 591 // For mobiles - size is always 1 592 if ( $input.is('.noMobile') && isTouchScreen() ) 593 $input.attr('size', '1'); 594 595 } //IF autodeciding on size 596 597 // Preparing attributes 598 var $attr = inputClassString($input, ''); 599 if ( !$attr ) return; 600 601 // ---- Creating container element ---- 602 603 $input.wrapAll('<div ' + $attr + '></div>'); 604 605 // Researching wrapper, for later use 606 var $wrap = $input.parent(); 607 608 // Flagging input type: inline/multiline 609 if ( $wrap.attr('size') != '1' ) 610 $wrap.addClass('multiline'); 611 612 // 100% size inputs are marked with class instead 613 // and triggers default size for fallbacks 614 if ( $wrap.attr('size') == '100%' ) 615 $wrap.addClass('fullHeight').removeAttr('size'); 616 617 // ---- Model ---- 618 619 // Initiating selector model 620 var $select = $input.mwSelectInput(); 621 622 }); //jQuery each morweb selector input 623 624 dialog.find('SELECT.checkList, SELECT.radioList').not('.new').each( function () { 625// dialog.find('SELECT.checkList.old, SELECT.radioList.old').each( function () { 626 627 var sel = jQuery(this); 628 629 sel.addClass('multiline'); 630 631 if ( sel.is('.checkList') ) 632 sel.attr('multiple', 'multiple'); 633 634 var attr = inputClassString(sel, 'list'); 635 if ( !attr ) return; 636 637 // ---- Creating container and subcontainer elements ---- 638 639 var el = jQuery('<div ' + attr + '><div class="list"></div></div>'); 640 var items = el.find('.list'); 641 642 // 100% size inputs are marked with class instead 643 // and triggers default size for fallbacks 644 if ( el.attr('size') == '100%' ) 645 el.addClass('fullHeight').removeAttr('size'); 646 647 // Adding default height 648 if ( !el.attr('size') ) 649 el.attr('size', '5'); 650 651 // ---- Saving source ---- 652 653 // Selector itself will be replaced, so we need to save source in separate hidden element which will not affect nothing 654 655 var source_data = sel.data('source'); 656 657 var source = jQuery('<input type="hidden" class="mw">'); 658 source.data('source', source_data); 659 source.appendTo(el); 660 661 // ---- Transferring hint ---- 662 663 var hint = sel.attr('hint'); 664 if ( hint ) 665 items.attr('hint', hint); 666 667 // ---- Composing common attributes ---- 668 669 var radio = el.hasClass('radioList'); 670 var name = sel.attr('name'); 671 672 // Checkboxes should be arrays 673 // Not doing for selects that alrady had this 674 if ( !radio && name && !name.endsWith('[]') ) 675 name += '[]'; 676 677 // Input type 678 var type = ( radio )? 'radio' : 'checkbox'; 679 680 // ---- Processing sub controls ---- 681 682 sel.find('OPTION').each( function () { 683 684 var op = jQuery(this); 685 var title = op.html(); 686 687 // ---- Parsing title for special things ---- 688 689 // Column 690 var col = ''; 691 var d = title.indexOf('|'); 692 if ( d >= 0 ) { 693 col = title.substr(d + 1); 694 title = title.substr(0, d) + '<div class="col">' + col + '</div>'; 695 } //IF divider come 696 697 var $icon = op.attr('data-icon'); 698 if ( $icon ) 699 $icon = '<div class="icon" style="background-image: url(' + $icon + ');"></div>'; 700 701 702 // Value/checked 703 var val = op.val(); 704 var checked = op.attr('selected'); 705 706 title = $icon + '<div class="title">' + title + '</div>'; 707 708 var titem = jQuery(title); 709 710 var input = jQuery('<input type="' + type + '" class="meta" name="' + name + '" value="' + val + '" />'); 711 if ( checked ) input.attr('checked', 'checked'); 712 713 // Setting up actions 714 var actions = ['onclick', 'onchange', 'ondblclick']; 715 for ( var i in actions ) 716 input.attr(actions[i], sel.attr(actions[i]) ); 717 718 input.change( function () { 719 720 var check = this.checked; 721 722 var el = jQuery(this); 723 724 if ( check ) { 725 el.parent().addClass('selected icon hi left'); 726 } else { //IF checked 727 el.parent().removeClass('selected icon hi left') 728 } //IF not checked 729 730 if ( this.type == 'radio') { 731 if ( this.checked ) { 732 jQuery(this) 733 .parents('.mwInput.list') // Searching parent container 734 .find('INPUT[type="radio"][name="' + this.name + '"]') //
734Searching all items 735 .not(this) // Excluding self 736 .each( function () { // Triggering change on each 737 jQuery(this).change(); 738 }); //each radio 739 } //IF got cheked state 740 } //IF radio 741 742 }); //jQuery onChange 743 744 var $itemClass = 'item'; 745 var $itemStyle = ''; 746 747 if ( checked ) $itemClass+=' selected icon hi left'; 748/*/ 749 var $src = op.attr('data-icon'); 750 if ( $src ) { 751 $itemClass += ' icon'; 752 $itemStyle = 'background-image: url(' + $src + ');'; 753 } //IF class 754/**/ 755 756 $itemClass = $itemClass ? ' class="' + $itemClass + '"' : ''; 757 $itemStyle = $itemStyle ? ' style="' + $itemStyle + '"' : ''; 758 759 var item = jQuery('<div' + $itemClass + $itemStyle + '></div>'); 760 item.append(titem).append(input); 761 762 item.appendTo(items); 763 }); //jQuery each option 764 765 sel.replaceWith(el); 766 }); //jQuery each multiselect input 767 768 // ---- CHECKBOX and RADIO ---- 769 770 dialog.find('INPUT[type="checkbox"], INPUT[type="radio"]').not('.meta').each( function () { 771 772 var el = jQuery(this); 773 774 // Checking if custom titles are set 775 var custom = el.attr('cap'); 776 777 var attr = inputClassString(el, 'checkbox' + ((custom)? ' custom' : '')); 778 if ( !attr ) return; 779 780// ---- Processing custom titles ---- 781 782 // Webkit browsers require smth to have inside to propertly align, so setting nbsp as default 783 var on = ' '; 784 var off = ' '; 785 786 if ( custom ) { 787 788 // el.removeAttr('cap'); 789 790 custom = custom.split('|'); 791 792 var on = custom[0]; 793 var off = (custom[1])? custom[1] : custom[0]; 794 795 } //IF title set 796 797 // ---- Wrapping layout structure ---- 798 799 el.wrapAll('<div ' + attr + '></div>'); 800 el.addClass('hidden'); 801 802 el.before('<div class="icon hi left">_</div>'); 803 804 // ---- Applying change function ---- 805 806 el.change( function () { 807 808 var check = this.checked; 809 810 if ( check ) { 811 el.parent().addClass('checked'); 812 el.prev().html(on).addClass('selected'); 813 el.addClass('checked'); 814 } else { //IF checked 815 el.parent().removeClass('checked') 816 el.prev().html(off).removeClass('selected'); 817 el.removeClass('checked'); 818 } //IF not checked 819 820 }); //jQuery onChange 821 822 // Initiating first time 823 el.change(); 824 825 // ---- Radio buttins refresh fix ---- 826 827 if ( this.type == 'radio' ) { 828 829 el.change( function () { 830 831 var radio = jQuery(this); 832 833 if ( this.checked ) { 834 835 // Searching neighbours via closest parent form. Fastest way. Usually there is form around. 836 radio.closest('FORM') 837 .find('INPUT[type="radio"][name="' + this.name + '"].checked') 838 .not(this).change(); 839 840 } //IF got cheked state 841 842 }); //jQuery onChange 843 844 } //IF radio button 845 846 }); //jQuery each checbox and radio input 847 848// ---- FILES ---- 849 850 dialog.find('INPUT[type=file]').each( function () { 851 852 var el = jQuery(this); 853 854 var attr = inputClassString(el, 'file'); 855 if ( !attr ) return; 856 857 // Detecting SN if set, and applying it as uBar 858 var fid = el.attr('sn') || ''; 859 860 if ( fid ) 861 fid = ' uBar_' + fid; 862 863 // Preparing structure and layout 864 el.wrapAll('<div ' + attr + '></div>'); 865 866 // Reading input wrapper 867 var $jWrap = el.closest('.mwInput'); 868 869 // Saving some properties 870 var $size = el.attr('size') || $jWrap.attr('size') || 6; 871 var $preview = el.attr('preview') || ''; 872 873 // Preparing preview element, it goes first 874 var $jPreview = jQuery('<div class="filePreview"></div>'); 875 el.before($jPreview); 876 877 // Adding additional face wrapper for layout control 878 var $jFace = jQuery('<div class="fileFace divider"></div>'); 879 880 // Adding title progress control inside face 881 var $jProgress = jQuery('<div class="subcontrol hi fill progressFill' + fid + '"></div>').appendTo($jFace); 882 var $jTitle = jQuery('<div class="fileName"></div>').appendTo($jFace); 883 var $jNum = jQuery('<div class="num progressNum' + fid + '"> </div>').appendTo($jFace); 884 885 // Attaching face 886 el.before($jFace); 887 888 // Preparing controls 889 // Upload/browse is unconditional, goes right after the face 890 var $jUpload = jQuery('<div class="subcontrol button icon upload"></div>').insertAfter($jFace); 891 892 // Preparing download button, but not attaching it yet (this will be decided in updateFace() ) 893 var $jDownload = jQuery('<div class="subcontrol button icon download hi"></div>'); 894 895 // Delete button present only if specified 896 // Always inserted last 897 // var $jDelete = jQuery('<div class="subcontrol button icon delete red"></div>');
898 // $jDelete.insertBefore(el); 899 900 // Testing varying subcontrols count 901 // el.before('<div class="subcontrol button icon ok"></div>'); 902 // el.before('<div class="subcontrol button icon delete"></div>'); 903 // el.before('<div class="subcontrol button icon download"></div>'); 904 // el.before('<div class="subcontrol button icon search"></div>'); 905 906 // Autoconfiguring path for morweb editors 907 // This is supported only for inputs added through form editor, which are part of files section 908 // They should have gallery attribute, input should be part of window (this will indicate presence of morweb) 909 // ToDo: This validation should be done outside by forms editor/custom inputs 910 911 // Custom paths are still supported normally 912 var $fPath = el.attr('data-path'); 913 var $fGallery = el.attr('gallery'); 914 var $fPrivate = el.attr('private') || 0; 915 var $fStorage = $fPrivate ? 'download' : 'files'; 916 917 // Path for gallery files are known 918 // Checking if running inside window 919 if ( !$fPath && $fGallery && el.closest('.mwWindow').length ) { 920 921 // Default path is in gallery 922 var $fPath = '/'+$fStorage+'/galleries/'; 923 924 // Setting path as attribute 925 el.attr('data-path', $fPath); 926 927 } //If no path set 928 929 // Using dedicated face update function 930 function mwFileInputUpdateFace ($el) { 931 932 // Need jQuery 933 $el = _jq($el); 934 935 // Checking if file/path set. 936 // Both are required for preview and download 937 var $file = $el.attr('data-file'); 938 var $fileVal = fileName($el.get(0).value); 939 var $path = $el.attr('data-path'); 940 941 942 // Detecting value is present, and using as visual title 943 var $title = $fileVal || $el.attr('data-file') || $el.attr('value') || $el.attr('src') || $el.attr('img') || $el.attr('cap') || 'Select File...'; 944 945 // Setting title 946 $jTitle.html($title); 947 948 // Preparing preview url right away 949 var $previewUrl = ''; 950 951 // File and path should be just present to create download button 952 if ( $file && $path ) { 953 954 // Attaching download button 955 $jDownload.insertAfter($jUpload); 956 957 // Preparing preview with direct path 958 // Replacing /files with resizer: /getimage 959 // This way - images available for resizer will be run through resizer, 960 // and very custom images will stay as they are 961 962 // Previews are available only for images currently 963 if ( isFileImage($file) ) { 964 965 var $previewUrl = $path.replace('/'+$fStorage+'/', '/getimage/'); 966 $previewUrl += $file+'?resize='+Math.ceil( $jWrap.width() || 600 )+'x0'; 967 968 } //IF image file 969 970 } //IF file defined 971 972 else { 973 974 // Detaching download 975 $jDownload.detach(); 976 977 // Resetting preview 978 $previewUrl = ''; 979 980 } //IF no file 981 982 // ToDo: split input (hidden text with input name and name_file for file input) 983 // ToDo: delete button support. Automated for split inputs, ondelete="" event enables delete button 984 985 // For preview - need to do additional checks 986 // It's visibe when forced or when both file and path are present 987 // Previe is visible in auto mode when either URL is set, or file source is set 988 if ( !$fPrivate && (($preview == 'on') || ($preview && ($previewUrl || $fileVal))) ) { 989 990 // Filling in preview BG 991 // Using as is, even if it happen to be empty (when preview box is forced) 992 $jPreview.css({'background-image' : "url('"+$previewUrl+"')"}).show(); 993 994 // Setting input height 995 $jWrap.attr('size', $size); 996 997 } //IF file defined 998 999 else { 1000 1001 // Clearing preview 1002 $jPreview.css({'background-image' : "url('')"}).hide(); 1003 1004 $jWrap.attr('size', ''); 1005 1006 } //IF no file 1007 1008 } //FUNC mwFileInputUpdateFace 1009 1010 // Adding download click 1011 $jDownload.click( function () { 1012 1013 // Support for "view file" requires both data path and value 1014 // Supporting download only for values set through fromArray() calls. 1015 // If file was browsed - can't download anyway 1016 var $file = el.attr('data-file'); 1017 var $path = el.attr('data-path'); 1018 1019 if ( !$file || !$path ) 1020 return; 1021 1022 // If gallery specified - using it to view file 1023 if ( !isEmpty($fGallery) ) { 1024 1025 // Compiling path to gallery view in backend 1026 $path = '/site/files/'+$fGallery+'/'; 1027 1028 } //IF actual gallery specified 1029 1030 // Using virtual form to safely click into new tab 1031 submitUrl($path+$file, {}, true); 1032 1033 });
1033 //FUNC $jDownload.click 1034 1035 // Adding preview click 1036 $jPreview.click( function () { 1037 1038 // Just triggering download 1039 $jDownload.click(); 1040 1041 }); //$jPreview.click 1042 1043 // Adding update on change 1044 el.change( function () { 1045 1046 // Preparing face 1047 mwFileInputUpdateFace(this); 1048 1049 // Preloading image if defined/selected 1050 if ( $preview && this.value ) 1051 mwBackgroundPreview($jPreview, this); 1052 1053 }); //el.change 1054 1055 // Running initial update 1056 mwFileInputUpdateFace(el); 1057 1058 }); //jQuery each select input 1059 1060// ---- BROWSER ---- 1061 1062 dialog.find('SELECT.selectEx').each( function () { 1063 1064 var $el = jQuery(this); 1065 1066 $el.addClass('multiline'); 1067 1068 var $attr = inputClassString($el, ''); 1069 if ( !$attr ) return; 1070 1071 // ---- Creating container element ---- 1072 1073 $el.wrapAll('<div ' + $attr + '></div>'); 1074 1075 // Researching wrapper, for later use 1076 var $wrap = $el.parent(); 1077 1078 // 100% size inputs are marked with class instead 1079 // and triggers default size for fallbacks 1080 if ( $wrap.attr('size') == '100%' ) 1081 $wrap.addClass('fullHeight').removeAttr('size'); 1082 1083 // Adding default height 1084 if ( !$wrap.attr('size') ) 1085 $wrap.attr('size', '6'); 1086 1087 // ---- Options ---- 1088 1089 var $o = { 1090 inline : $wrap.is('.inline') 1091 }; //$o 1092 1093 if ( $el.data('title') ) 1094 $o.title = $el.data('title'); 1095 1096 // Initiating selector 1097 // Checking inline mode by resulitng wrapper class 1098 var $sx = mwSelectEx($el, $o); 1099 1100 $el.data('selectEx', $sx); 1101 1102 }); //jQuery.each select 1103 1104// ---- TABLE ---- 1105 1106 dialog.find('input[data-input="table"]').each( function () { 1107 1108 var $el = jQuery(this); 1109 var $name = $el.attr('name'); 1110 1111 var $attr = inputClassString($el, 'table'); 1112 1113 if ( !$attr ) 1114 return; 1115 1116 1117 $el.wrapAll('<div ' + $attr + '></div>'); 1118 1119 // Researching wrapper 1120 var $wrap = $el.closest('div'); 1121 1122 // Reading columns 1123 var $cols = strToArray($el.data('columns')); 1124 1125 // Generating table, replacing old one 1126 function tGen ($data) { 1127 1128 var $table = $wrap.find('table').remove(); 1129 1130 // Will try to recognize some values format 1131 var $cClass = {}; 1132 1133 // Rendering rows and headers in separate vars 1134 // Cols are rendered first, to collect data format info 1135 // Which then will allow to format headers 1136 // in the end all will be put together as table 1137 var $headHtml = ''; 1138 var $rowsHtml = ''; 1139 1140 // Rendering rows 1141 for (var $r in $data ) { 1142 var $row = $data[$r]; 1143 1144 $rowsHtml += '<tr>'; 1145 for (var $i in $cols ) { 1146 1147 var $col = $cols[$i]; 1148 var $val = $row[$col]; 1149 1150 if ( isNumeric($val) ) 1151 $cClass[$col] = 'num'; 1152 1153 // Checking if some classes are present 1154 var $class = $cClass[$col] || ''; 1155 if ( !isEmpty($class) ) 1156 $class = ' class="'+$class+'"'; 1157 1158 $rowsHtml += '<td'+$class+'>'+$val+'</td>'; 1159 } //FOR each column 1160 $rowsHtml += '</tr>'; 1161 1162 } //FOR each data row 1163 1164 // Rendering headers 1165 $headHtml += '<tr>'; 1166 for (var $i in $cols ) { 1167 1168 var $col = $cols[$i]; 1169 1170 // Checking if some classes are present 1171 var $class = $cClass[$col] || ''; 1172 if ( !isEmpty($class) ) 1173 $class = ' class="'+$class+'"'; 1174 1175 $headHtml += '<th'+$class+'>'+ucfirst($cols[$i])+'</th>'; 1176 } //FOR each column 1177 $headHtml += '</tr>'; 1178 1179 var $html = '<table>'+$headHtml+$rowsHtml+'</table>'; 1180 1181 return jQuery($html).appendTo($wrap); 1182 1183 } //FUNC tGen 1184 1185 tGen({}); 1186 1187 // Hiding source input 1188 $el.hide(); 1189 1190 // Updating table on input change 1191 $el.change( function () { 1192 1193 var $input = jQuery(this); 1194 var $data = JSON.parse($input.val() || '{}'); 1195 1196 tGen($data); 1197 1198 }); //FUNC input.change 1199 1200 }); //jQuery each table input 1201 1202// ---- COMMON ---- 1203 1204 // Tracking hovers/focus via java and classes to have extra styling options. 1205 // Unfortunately have to exclude few inputs 1206 1207 dialog.find('.mwInput').each( function () { 1208 1209 var $el = jQuery(this); 1210 1211 // Hover 1212 $el 1213 .off('mouseenter.mwInput') 1214 .on('mouseenter.mwInput', function () { 1215 $el.addClass('hover'); 1216 1217 if ( $el.parent().is('.combo') ) 1218 $el.parent().addClass('hover'); 1219 1220 }) //FUNC hoverin 1221 1222 .off('mouseleave.mwInput') 1223 .on('mouseleave.mwInput', function () { 1224 $el.removeClass('hover'); 1225 1226 if ( $el.parent().is('.combo') ) 1227 $el.parent().removeClass('hover'); 1228 1229 }) //FUNC hoverout 1230 ; //$el 1231 1232 $el.not('.selectEx') 1233 .off('focusin.mwInput') 1234 .on('focusin.mwInput', function () { 1235 $el.addClass('focus'); 1236 1237 if ( $el.parent().is('.combo') ) 1238 $el.parent().addClass('focus'); 1239 }) //FUNC hoverout 1240 1241 .off('focusout.mwInput') 1242 .on('focusout.mwInput', function () { 1243 $el.removeClass('focus'); 1244 1245 if ( $el.parent().is('.combo') ) 1246 $el.parent().removeClass('focus'); 1247 }) //FUNC hoverout 1248 ; //$el 1249 1250 }); //jQuery.each input 1251 1252 return false;
1253} //FUNC styleDialog 1254 1255/** //** ----= unstyleInput =----------------------------------------------\**//** \ 1256* 1257* Removes styles from input given. 1258* 1259* @param jQuery input - Valid jQuery input element selector. 1260* @return jQuery - New input element. 1261* 1262\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1263function unstyleInput ( input ) { 1264 1265 // All styled inputs have .mw class. 1266 // Source is stored under jQuery's .data(). 1267 input = _jq(input); 1268 1269 // Making sure that we are pointing to input itself 1270/*/ 1271 if ( !input.is('.mw') ) 1272 input = input.find('.mw'); 1273 1274 var source = input.data('source'); 1275/*/ 1276 var source = input.find('.mw').data('source'); 1277/**/ 1278 1279 if ( source ) { 1280 source = jQuery(source); 1281 input.replaceWith(source); 1282 return source; 1283 } //IF source was stored 1284 1285 return input; 1286} //FUNC unstyleInput 1287 1288/** //** ----= unstyleDialog =----------------------------------------------\**//** \ 1289* 1290* Removes styles from inputs in given element. 1291* 1292* @param MIXED el - Valid jQuery element selector. 1293* @return bool - Always FALSE. 1294* 1295\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1296function unstyleDialog ( dialog ) { 1297 1298 // All styled inputs have .mw class. 1299 // Source is stored under jQuery's .data(). 1300 dialog.find('.mw').each( function () { 1301 1302 var el = jQuery(this); 1303 1304 var source = el.data('source'); 1305 1306 if ( source ) 1307 el.closest('.mwInput', dialog).replaceWith(source); 1308 1309 }); //jQuery each .mw 1310 1311 return false; 1312} //FUNC unstyleDialog 1313 1314function setValidations (dialog, validations) { 1315 1316 if ( !dialog ) 1317 return; 1318 1319 dialog.find('INPUT, SELECT, TEXTAREA') 1320 .each( function () { 1321 1322 // Shortcuts to input and it's parent (morweb forms) 1323 var input = jQuery(this); 1324 var parent = input.closest('.mwInput'); 1325 if ( !parent.length ) 1326 parent = input; 1327 1328 // Input should have name to be validatable 1329 var name = input.attr('name'); 1330 if ( !name ) return; 1331 1332 // Shortcut to messages array to simplify code 1333 var msgs = validations[name]; 1334 1335 // Might be complex input name, so checking for that 1336 if ( isUndefined(msgs) ) { 1337 1338 // Splitting name to parts 1339 // Safe to do event if it's not complext - will end up with same name 1340 var $tmp = name.split(/\[|\]/); 1341 1342 // Clearing empties 1343 // $tmp = $tmp.filter(n => n);
1344 $tmp = $tmp.filter(Boolean); 1345 1346 // Finally - using last element 1347 name = $tmp.slice(-1)[0]; 1348 msgs = validations[name]; 1349 1350 } //IF nothing found 1351 1352 // TinyMCE support 1353 // Marking tinyEditor instead of input itself 1354 if ( input.is('.mwTinyMCE') ) { 1355 1356 // If it's tinyMCE input - there should be sibling mceEditor input 1357 input = input.siblings('.mceEditor'); 1358 parent = input; 1359 1360 // If none - smth went wrong 1361 if ( !input.length ) 1362 return; 1363 } //IF tinyMCE input 1364 1365 // Removing errors attribute if no messages 1366 if ( !msgs ) { 1367 1368 input.removeAttr('error'); 1369 1370 // Class for parent 1371 parent.removeClass('error'); 1372 1373 return; 1374 } //IF no messages 1375 1376 // Compiling messages, very simple br can be stored inside attribute 1377 var msg = implode('<br />', msgs); 1378 1379 // Setting error 1380 input.attr('error', msg); 1381 1382 // Class for parent 1383 parent.addClass('error'); 1384 1385 }); //jQuery.each.callback 1386 1387 return; 1388} //FUNC setValidations 1389 1390/** //** ----= fillViews =----------------------------------------------\**//** \ 1391* 1392* Fills fileds views within specified element. 1393* 1394* @param jQuery el - Context element. 1395* @param object obj - Data object to pull views from. 1396* 1397* @return bool - Always FALSE. 1398* 1399\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/ 1400function fillViews (el, obj) { 1401 1402 el = _jq(el); 1403 1404 for ( var i in obj ) { 1405 el.find('.view-' + i).html(obj[i]); 1406 } //FOR each field 1407 1408 return false; 1409} //FUNC fillViews
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.