1/** 2 * The following API is shared on both frontend and backend. 3 * 4 * No external libraries are loaded in this file. 5 * 6 * 1. Polyfills 7 * 2. themeComplete plugin JS API 8 * 3. themeComplete jQuery extensions 9 */ 10/*jshint bitwise: false*/ 11/** 12 * 1. Polyfills 13 * 14 * The following are required methods for 15 * the String, Number and Object prototype 16 */ 17( function() { 18 'use strict'; 19 20 /** 21 * String.prototype.isNumeric() 22 * 23 * Determines whether a string contains a numeric value 24 * 25 * https://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric 26 */ 27 if ( ! String.prototype.isNumeric ) { 28 Object.defineProperty( String.prototype, 'isNumeric', { 29 value: function() { 30 return ! isNaN( parseFloat( this ) ) && isFinite( this ); 31 } 32 } ); 33 } 34}() ); 35 36// jQuery Mask Plugin v1.14.15 37// github.com/igorescobar/jQuery-Mask-Plugin 38window.jQuery.jMaskGlobals = { 39 maskElements: '.tc-extra-product-options input' 40}; 41 42/** 43 * 2. ThemeComplete plugin JS API 44 */ 45 46( function( $ ) { 47 'use strict'; 48 49 $.epoAPI = {}; 50 $.epoAPI.error = false; 51 $.epoAPI.math = {}; 52 $.epoAPI.dom = {}; 53 $.epoAPI.util = {}; 54 $.epoAPI.locale = {}; 55 $.epoAPI.template = {}; 56 57 $.epoAPI.math.toFloat = function( s, d ) { 58 var n; 59 60 if ( ! ( typeof s === 'string' || typeof s === 'number' ) || isNaN( s ) ) { 61 return 0; 62 } 63 n = parseFloat( s ); 64 if ( isNaN( n ) ) { 65 if ( d !== undefined ) { 66 return d; 67 } 68 return s; 69 } 70 71 return n; 72 }; 73 74 $.epoAPI.math.toInt = function( s, d ) { 75 var n; 76 77 if ( ! ( typeof s === 'string' || typeof s === 'number' ) || isNaN( s ) || s === '' ) { 78 return 0; 79 } 80 n = parseInt( s, 10 ); 81 if ( isNaN( n ) ) { 82 if ( d !== undefined ) { 83 return d; 84 } 85 return s; 86 } 87 88 return n; 89 }; 90 91 /** 92 * Rounds a number 93 * modified from http://locutus.io/php/math/round/ 94 * 95 * @param {any} value the value to round. 96 * @param {int} precision the precision. 97 * @param {string} mode the rounding mode. 98 */ 99 $.epoAPI.math.round = function( value, precision, mode ) { 100 var m; 101 var f; 102 var isHalf; 103 var n; 104 var sgn; // helper variables 105 106 // making sure precision is integer 107 precision = parseInt( precision, 10 ); 108 if ( ! Number.isFinite( precision ) ) { 109 precision = 0; 110 } 111 m = Math.pow( 10, precision ); 112 value = value * m; 113 114 // sign of the number 115 if ( typeof value === 'number' ) { 116 if ( value ) { 117 if ( value < 0 ) { 118 sgn = -1; 119 } else { 120 sgn = 1; 121 } 122 } else { 123 sgn = 0; 124 } 125 } else { 126 sgn = 0; 127 } 128 129 isHalf = value % 1 === 0.5 * sgn; 130 f = Math.floor( value ); 131 132 if ( isHalf ) { 133 switch ( mode ) { 134 case 'PHP_ROUND_HALF_DOWN': 135 // rounds .5 toward zero 136 if ( sgn < 0 ) { 137 n = 1; 138 } else { 139 n = 0; 140 } 141 value = f + n; 142 break; 143 case 'PHP_ROUND_HALF_EVEN': 144 // rouds .5 towards the next even integer 145 value = f + ( ( f % 2 ) * sgn ); 146 break; 147 case 'PHP_ROUND_HALF_ODD': 148 // rounds .5 towards the next odd integer 149 n = f % 2; 150 if ( n ) { 151 n = 0; 152 } else { 153 n = 1; 154 } 155 value = f + n; 156 break; 157 default: 158 // rounds .5 away from zero 159 if ( sgn > 0 ) { 160 n = 1; 161 } else { 162 n = 0; 163 } 164 value = f + n; 165 } 166 } 167 168 if ( ! isHalf ) { 169 value = Math.round( value ); 170 } 171 172 return value / m; 173 }; 174 175 // https://locutus.io/php/misc/uniqid/index.html 176 $.epoAPI.math.uniqueid = function( prefix, moreEntropy ) { 177 var retId; 178 var _formatSeed = function( seed, reqWidth ) { 179 seed = parseInt( seed, 10 ).toString( 16 ); // to hex str 180 if ( reqWidth < seed.length ) { 181 // so long we split 182 return seed.slice( seed.length - reqWidth ); 183 } 184 if ( reqWidth > seed.length ) { 185 // so short we pad 186 return new Array( 1 + ( reqWidth - seed.length ) ).join( '0' ) + seed; 187 } 188 return seed; 189 }; 190 var radom; 191 192 if ( prefix === undefined ) { 193 prefix = ''; 194 } 195 196 $.epoAPI.php = $.epoAPI.php || {}; 197 198 if ( ! $.epoAPI.php.uniqidSeed ) { 199 // init seed with big random int 200 $.epoAPI.php.uniqidSeed = Math.floor( Math.random() * 0x75bcd15 ); 201 } 202 $.epoAPI.php.uniqidSeed += 1; 203 204 // start with prefix, add current milliseconds hex string 205 retId = prefix; 206 retId += _formatSeed( parseInt( Date.now() / 1000, 10 ), 8 ); 207 // add seed hex string 208 retId += _formatSeed( $.epoAPI.php.uniqidSeed, 5 ); 209 if ( moreEntropy ) { 210 // for more entropy we add a float lower to 10 211 radom = Math.random() * 10; 212 retId += radom.toFixed( 8 ).toString(); 213 } 214 215 return retId; 216 }; 217 218 $.epoAPI.dom.id = function( id ) { 219 if ( typeof id === 'undefined' ) { 220 return id; 221 } 222 if ( ! ( typeof id === 'string' || typeof id === 'number' ) || ( typeof id === 'number' && isNaN( id ) ) ) { 223 return id.toString(); 224 } 225 return id.toString().replace( /(%|:|\.|\[|\]|,|=)/g, '\\$1' ); 226 }; 227 228 $.epoAPI.dom.scroll = function() { 229 var scrollLeft; 230 var scrollTop; 231 232 if ( window.pageYOffset ) { 233 scrollTop = window.pageYOffset; 234 scrollLeft = window.pageXOffset; 235 } else if ( document.documentElement && document.documentElement.scrollTop ) { 236 scrollTop = document.documentElement.scrollTop; 237 scrollLeft = document.documentElement.scrollLeft; 238 } else if ( document.body ) { 239 scrollTop = document.body.scrollTop; 240 scrollLeft = document.body.scrollLeft; 241 } 242 243 return { left: scrollLeft, top: scrollTop }; 244 }; 245 246 $.epoAPI.dom.size = function() { 247 var totalDocumentHeight; 248 var totalDocumentWidth; 249 var fullHeight; 250 var fullWidth; 251 var visibleWidth; 252 var visibleHeight; 253 254 if ( window.innerHeight && window.scrollMaxY ) { 255 totalDocumentWidth = window.innerWidth + window.scrollMaxX; 256 totalDocumentHeight = window.innerHeight + window.scrollMaxY; 257 } else if ( document.body.scrollHeight > document.body.offsetHeight ) { 258 totalDocumentWidth = document.body.scrollWidth; 259 totalDocumentHeight = document.body.scrollHeight; 260 } else { 261 totalDocumentWidth = document.body.offsetWidth; 262 totalDocumentHeight = document.body.offsetHeight; 263 } 264 265 if ( window.innerHeight ) { 266 if ( document.documentElement.clientWidth ) { 267 visibleWidth = document.documentElement.clientWidth; 268 } else { 269 visibleWidth = window.innerWidth; 270 } 271 visibleHeight = window.innerHeight; 272 } else if ( document.documentElement && document.documentElement.clientHeight ) { 273 visibleWidth = document.documentElement.clientWidth; 274 visibleHeight = document.documentElement.clientHeight; 275 } else if ( document.body ) { 276 visibleWidth = document.body.clientWidth; 277 visibleHeight = document.body.clientHeight; 278 } 279 if ( totalDocumentHeight < visibleHeight ) { 280 fullHeight = visibleHeight; 281 } else { 282 fullHeight = totalDocumentHeight; 283 } 284 if ( totalDocumentWidth < visibleWidth ) { 285 fullWidth = visibleWidth; 286 } else { 287 fullWidth = totalDocumentWidth; 288 } 289 290 return { 291 fullWidth: fullWidth, 292 fullHeight: fullHeight, 293 294 visibleWidth: visibleWidth, 295 visibleHeight: visibleHeight, 296 297 totalWidth: totalDocumentWidth, 298 totalHeight: totalDocumentHeight 299 }; 300 }; 301 302 // jQuery trim is deprecated, provide a trim method based on String.prototype.trim 303 $.epoAPI.util.trim = function( str ) { 304 if ( typeof str === 'string' ) { 305 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill 306 return str.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '' ); 307 } 308 return str; 309 }; 310 311 $.epoAPI.util.parseJSON = function( s ) { 312 var parsedjson; 313 var JSON = window.JSON; 314 315 try { 316 parsedjson = JSON.parse( s + '' ); 317 if ( parsedjson && typeof parsedjson === 'object' && parsedjson !== null ) { 318 return parsedjson; 319 } 320 } catch ( err ) { 321 $.epoAPI.error = err; 322 return false;
323 } 324 325 return false; 326 }; 327 328 $.epoAPI.util.decodeHTML = function( html ) { 329 var txt = document.createElement( 'textarea' ); 330 txt.innerHTML = html; 331 return txt.value; 332 }; 333 334 $.epoAPI.util.getStorage = function( type ) { 335 var storage; 336 var x; 337 try { 338 storage = window[ type ]; 339 x = '__storage_test__'; 340 storage.setItem( x, x ); 341 storage.removeItem( x ); 342 return storage; 343 } catch ( e ) { 344 return false; 345 } 346 }; 347 348 $.epoAPI.util.basename = function( path ) { 349 return path.replace( /.*\//, '' ); 350 }; 351 352 // https://developer.mozilla.org/en-US/docs/Web/API/structuredClone 353 // https://medium.com/javascript-in-plain-english/how-to-deep-copy-objects-and-arrays-in-javascript-7c911359b089 354 $.epoAPI.util.deepCopyArray = function( inObject ) { 355 var outObject; 356 var value; 357 358 if ( window.structuredClone !== undefined ) { 359 return window.structuredClone( inObject ); 360 } 361 362 if ( typeof inObject !== 'object' || inObject === null ) { 363 return inObject; // Return the value if inObject is not an object 364 } 365 366 // Create an array or object to hold the values 367 outObject = Array.isArray( inObject ) ? [] : {}; 368 369 Object.keys( inObject ).forEach( function( key ) { 370 if ( inObject ) { 371 value = inObject[ key ]; 372 373 // Recursively (deep) copy for nested objects, including arrays 374 outObject[ key ] = typeof value === 'object' && value !== null ? $.epoAPI.util.deepCopyArray( value ) : value; 375 } 376 } ); 377 378 return outObject; 379 }; 380 381 $.epoAPI.locale.getSystemDecimalSeparator = function() { 382 var n = 1.1; 383 384 // This gets null on languages that don't return 1 in a number format. 385 n = /^1(.+)1$/.exec( n.toLocaleString() ); 386 387 if ( n ) { 388 n = n[ 1 ]; 389 } else { 390 n = ','; 391 } 392 393 return n; 394 }; 395 396 $.epoAPI.template.html = function( template, obj ) { 397 var $template_html = template( obj ); 398 399 $template_html = $template_html.replace( '/*<![CDATA[*/', '' ); 400 $template_html = $template_html.replace( '/*]]>*/', '' ); 401 402 return $template_html; 403 }; 404 405 $.epoAPI.filters = {}; 406 407 $.epoAPI.addFilter = function( $tag, $function_to_add, $priority, $accepted_args ) { 408 var $idx; 409 410 $priority = parseInt( $priority, 10 ); 411 if ( isNaN( $priority ) ) { 412 $priority = 10; 413 } 414 $accepted_args = parseInt( $accepted_args, 10 ); 415 if ( isNaN( $accepted_args ) ) { 416 $accepted_args = 1; 417 } 418 $idx = $function_to_add + '_' + $priority; 419 if ( ! $.epoAPI.filters[ $tag ] ) { 420 $.epoAPI.filters[ $tag ] = {}; 421 } 422 if ( ! $.epoAPI.filters[ $tag ][ $priority ] ) { 423 $.epoAPI.filters[ $tag ][ $priority ] = {}; 424 } 425 $.epoAPI.filters[ $tag ][ $priority ][ $idx ] = { 426 func: $function_to_add, 427 accepted_args: $accepted_args 428 }; 429 430 return true; 431 }; 432 433 $.epoAPI.removeFilter = function( $tag, $function_to_remove, $priority ) { 434 var $idx; 435 $priority = parseInt( $priority, 10 ); 436 if ( isNaN( $priority ) ) { 437 $priority = 10; 438 } 439 $idx = $function_to_remove + '_' + $priority; 440 441 if ( $.epoAPI.filters[ $tag ] && $.epoAPI.filters[ $tag ][ $priority ] && $.epoAPI.filters[ $tag ][ $priority ][ $idx ] ) { 442 delete $.epoAPI.filters[ $tag ][ $priority ][ $idx ]; 443 return true; 444 } 445 446 return false; 447 }; 448 449 $.epoAPI.applyFilter = function( $tag, $value ) { 450 var $args = $.makeArray( arguments ); 451 var priorities; 452 453 $args.splice( 0, 1 ); 454 455 if ( ! $.epoAPI.filters[ $tag ] ) { 456 return $value; 457 } 458 459 priorities = $.epoAPI.filters[ $tag ]; 460 $.each( priorities, function( i, el ) { 461 $.each( el, function( i2, el2 ) { 462 var func = el2.func; 463 464 if ( func instanceof Function ) { 465 $value = func.apply( null, $args ); 466 } else if ( window[ func ] && window[ func ] instanceof Function ) { 467 $value = window[ func ].apply( null, $args ); 468 } 469 } ); 470 } ); 471 472 return $value; 473 }; 474 475 // Backwards compatibility (to be removed in the future) 476 $.tc_add_filter = $.epoAPI.addFilter; 477 $.tc_remove_filter = $.epoAPI.removeFilter; 478 $.tc_apply_filters = $.epoAPI.applyFilter; 479}( window.jQuery ) ); 480 481/* 482 * Formatting functions 483 * 484 * Code modifiled from accounting.js 485 * http://openexchangerates.github.io/accounting.js/ 486 */ 487 488( function( $ ) { 489 'use strict'; 490 491 /** 492 * Check and normalise the value of precision (must be positive integer) 493 * 494 * @param {any} val the value to check. 495 * @param {any} base the value to return is check fails. 496 */ 497 function checkPrecision( val, base ) { 498 val = Math.round( Math.abs( val ) ); 499 return isNaN( val ) ? base : val; 500 } 501 502 /**
503 * Takes a string/array of strings, removes all formatting/cruft 504 * and returns the raw float value. 505 * 506 * @param {any} value the value to unformat. 507 * @param {any} decimal the decimal point. 508 */ 509 function unformat( value, decimal ) { 510 var regex; 511 var unformatted; 512 513 // Recursively unformat arrays: 514 if ( Array.isArray( value ) ) { 515 return value.map( value, function( val ) { 516 return unformat( val, decimal ); 517 } ); 518 } 519 520 // Fails silently (need decent errors): 521 value = value || 0; 522 523 // Return the value as-is if it's already a number: 524 if ( typeof value === 'number' ) { 525 return value; 526 } 527 528 // Default decimal point comes from settings, but could be set to eg. "," in opts: 529 decimal = decimal || '.'; 530 531 // Build regex to strip out everything except digits, decimal point and minus sign: 532 regex = new RegExp( '[^0-9-' + decimal + ']', [ 'g' ] ); 533 unformatted = parseFloat( 534 ( '' + value ) 535 .replace( regex, '' ) // strip out any cruft 536 .replace( decimal, '.' ) // make sure decimal point is standard 537 ); 538 539 // This will fail silently which may cause trouble, let's wait and see: 540 return ! isNaN( unformatted ) ? unformatted : 0; 541 } 542 543 /** 544 * Implementation of toFixed() that treats floats more like decimals 545 * 546 * Fixes binary rounding issues (eg. (0.615).toFixed(2) === "0.61") that present 547 * problems for accounting- and finance-related software. 548 * 549 * @param {any} value the value to convert. 550 * @param {int} precision the precision. 551 */ 552 function toFixed( value, precision ) { 553 var exponentialForm; 554 var rounded; 555 var finalResult; 556 557 if ( ! Number.isFinite( value ) ) { 558 return '-'; 559 } 560 561 precision = checkPrecision( precision, 2 ); 562 563 exponentialForm = Number( unformat( value ) * Math.pow( 10, precision ) ); 564 rounded = Math.round( exponentialForm ); 565 finalResult = Number( rounded / Math.pow( 10, precision ) ).toFixed( precision ); 566 return finalResult; 567 } 568 569 /** 570 * Format into currency or a number, with comma-separated thousands and custom precision/decimal places 571 * 572 * opts = { 573 * symbol: "$", // currency symbol is '$' 574 * format: "%s%v", // controls output: %s = symbol, %v = value (can be object, see docs) 575 * decimal: ".", // decimal point separator 576 * thousand: ",", // thousands separator 577 * precision: 2, // decimal places 578 * } 579 * 580 * @param {any} number the value to convert. 581 * @param {Object} opts the options for formatting. 582 */ 583 function format( number, opts ) { 584 var formats; 585 var useFormat; 586 var negative; 587 var base; 588 var mod; 589 590 // Resursively format arrays: 591 if ( Array.isArray( number ) ) { 592 return number.map( number, function( val ) { 593 return format( val, opts ); 594 } ); 595 } 596 597 // Clean up number: 598 number = unformat( number ); 599 600 // Do not format if opts are not correct or missing 601 if ( ! opts ) { 602 return number; 603 } 604 605 // Clean up precision 606 opts.precision = checkPrecision( opts.precision ); 607 608 // Format currency 609 if ( opts.format && opts.symbol ) { 610 // Check format (returns object with pos, neg and zero): 611 formats = { 612 pos: opts.format, 613 neg: opts.format.replace( '-', '' ).replace( '%v', '-%v' ), 614 zero: opts.format 615 }; 616 617 // Choose which format to use for this value: 618 useFormat = number > 0 ? formats.pos : number < 0 ? formats.neg : formats.zero; 619 620 // Return with currency symbol added: 621 opts.opts = { 622 precision: opts.precision, 623 thousand: opts.thousand, 624 decimal: opts.decimal 625 }; 626 627 number = useFormat.replace( '%s', opts.symbol ).replace( '%v', format( Math.abs( number ), opts.opts ) ); 628 629 // Format number 630 } else { 631 if ( ! Number.isFinite( number ) ) { 632 return '-'; 633 } 634 // Do some calc: 635 negative = number < 0 ? '-' : ''; 636 base = parseInt( toFixed( Math.abs( number || 0 ), opts.precision ), 10 ) + ''; 637 mod = base.length > 3 ? base.length % 3 : 0; 638 639 // Format the number: 640 number = negative + ( mod ? base.substring( 0, mod ) + opts.thousand : '' ) + base.substring( mod ).replace( /(\d{3})(?=\d)/g, '$1' + opts.thousand ) + ( opts.precision ? opts.decimal + toFixed( Math.abs( number ), opts.precision ).split( '.' )[ 1 ] : '' ); 641 } 642 643 return number; 644 } 645 646 $.epoAPI.math.unformat = unformat; 647 $.epoAPI.math.format = format; 648 $.epoAPI.math.toFixed = toFixed; 649}( window.jQuery ) ); 650 651/** 652 * 3. ThemeComplete jQuery extensions 653 * 654 * @param {Object} $ The jQuery object. 655 */ 656( function( $ ) { 657 'use strict'; 658 659 var expo; 660 var rCRLF = /\r?\n/g; 661 var rcheckableType = /^(?:checkbox|radio)$/i; 662 var rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i; 663 var rsubmittable = /^(?:input|select|textarea|keygen)/i; 664 665 // Extend jQuery easing 666 if ( ! $.easing.easeInExpo ) { 667 expo = function( p ) { 668 return Math.pow( p, 6 ); 669 }; 670 $.easing.easeInExpo = expo; 671 $.easing.easeOutExpo = function( p ) { 672 return 1 - expo( 1 - p ); 673 }; 674 $.easing.easeInOutExpo = function( p ) { 675 return p < 0.5 ? expo( p * 2 ) / 2 : 1 - ( expo( ( p * -2 ) + 2 ) / 2 ); 676 }; 677 } 678 679 // Add jQuery plugins 680 $.fn.extend( { 681 // Create checkbox switch 682 tmcheckboxes: function() { 683 var tm_settings_wrap_checkbox = this.find( ":checkbox:not('.tm-default-checkbox')" ).not( '.wp-tab-panel :checkbox, .tm-weekdays-picker-wrap :checkbox, .tm-months-picker-wrap :checkbox' ); 684 tm_settings_wrap_checkbox.wrap( '<label class="tm-epo-switch-wrapper-label"></label>' ); 685 tm_settings_wrap_checkbox.wrap( '<span class="tm-epo-switch-wrapper tc"></span>' ); 686 tm_settings_wrap_checkbox.after( '<span class="tc-label tm-epo-switch tc"></span>' ); 687 return this; 688 }, 689 690 // Encode a set of HTML elements as an array of names and values. 691 // Elements do not need to be inside a form 692 tcSerializeArray: function() { 693 return this.find( ':input' ) 694 .filter( function() { 695 var type = this.type; 696
697 // Use .is( ":disabled" ) so that fieldset[disabled] works 698 return this.name && ! $( this ).is( ':disabled' ) && rsubmittable.test( this.nodeName ) && ! rsubmitterTypes.test( type ) && ( this.checked || ! rcheckableType.test( type ) ); 699 } ) 700 .map( function( i, elem ) { 701 var val = $( this ).val(); 702 703 if ( val === null ) { 704 return null; 705 } 706 707 if ( Array.isArray( val ) ) { 708 return $.map( val, function( thisval ) { 709 return { name: elem.name, value: thisval.replace( rCRLF, '\r\n' ) }; 710 } ); 711 } 712 713 return { name: elem.name, value: val.replace( rCRLF, '\r\n' ) }; 714 } ) 715 .get(); 716 }, 717 718 // convert element to a valid JSON object 719 tcSerializeObject: function() { 720 var o = {}; 721 var a = this.tcSerializeArray(); 722 723 $.each( a, function() { 724 if ( o[ this.name ] !== undefined ) { 725 if ( this.name.endsWith( '[]' ) ) { 726 if ( ! o[ this.name ].push ) { 727 o[ this.name ] = [ o[ this.name ] ]; 728 } 729 o[ this.name ].push( this.value || '' ); 730 } else { 731 o[ this.name ] = this.value || ''; 732 } 733 } else { 734 o[ this.name ] = this.value || ''; 735 } 736 } ); 737 738 return o; 739 }, 740 741 // Scroll container to a specific element 742 tcScrollTo: function( obj, duration, offset ) { 743 var element = this; 744 745 obj = $( obj ); 746 if ( obj.length === 0 ) { 747 return this; 748 } 749 if ( ! duration ) { 750 duration = 0; 751 } 752 if ( ! offset ) { 753 offset = 0; 754 } 755 if ( element[ 0 ].self === window ) { 756 element = $( 'html, body' ); 757 } else { 758 if ( element.find( '.woodmart-scroll-content' ).length ) { 759 element = element.find( '.woodmart-scroll-content' ); 760 } 761 if ( ! element.offset() ) { 762 element = $( 'html, body' ); 763 } else { 764 offset = offset + ( element.scrollTop() - element.offset().top ); 765 } 766 } 767 768 return element.animate( 769 { 770 scrollTop: $( obj ).offset().top + offset 771 }, 772 duration 773 ); 774 }, 775 776 /** 777 * Textarea and select clone() bug workaround | Spencer Tipping 778 * Licensed under the terms of the MIT source code license 779 * https://github.com/spencertipping/jquery.fix.clone/blob/master/jquery.fix.clone.js 780 */ 781 tcClone: function() { 782 var i; 783 var l; 784 var j; 785 var m; 786 var result = $.fn.clone.apply( this, arguments ); 787 var textareas = this.find( 'textarea' ).add( this.filter( 'textarea' ) ); 788 var resultTextareas = result.find( 'textarea' ).add( result.filter( 'textarea' ) ); 789 var selects = this.find( 'select' ).add( this.filter( 'select' ) ); 790 var resultSelects = result.find( 'select' ).add( result.filter( 'select' ) ); 791 792 for ( i = 0, l = textareas.length; i < l; i += 1 ) { 793 $( resultTextareas[ i ] ).val( $( textareas[ i ] ).val() ); 794 } 795 for ( i = 0, l = selects.length; i < l; i += 1 ) { 796 for ( j = 0, m = selects[ i ].options.length; j < m; j += 1 ) { 797 if ( selects[ i ].options[ j ].selected === true ) { 798 resultSelects[ i ].options[ j ].selected = true; 799 } 800 } 801 } 802 803 return result; 804 } 805 } ); 806}( window.jQuery ) );
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.