1/*! 2 * mustache.js - Logic-less {{mustache}} templates with JavaScript 3 * http://github.com/janl/mustache.js 4 */ 5 6/*global define: false*/ 7 8(function (global, factory) { 9 if (typeof exports === "object" && exports) { 10 factory(exports); // CommonJS 11 } else if (typeof define === "function" && define.amd) { 12 define(['exports'], factory); // AMD 13 } else { 14 factory(global.Mustache = {}); // <script> 15 } 16}(this, function (mustache) { 17 18 var Object_toString = Object.prototype.toString; 19 var isArray = Array.isArray || function (object) { 20 return Object_toString.call(object) === '[object Array]'; 21 }; 22 23 function isFunction(object) { 24 return typeof object === 'function'; 25 } 26 27 function escapeRegExp(string) { 28 return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 29 } 30 31 // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 32 // See https://github.com/janl/mustache.js/issues/189 33 var RegExp_test = RegExp.prototype.test; 34 function testRegExp(re, string) { 35 return RegExp_test.call(re, string); 36 } 37 38 var nonSpaceRe = /\S/; 39 function isWhitespace(string) { 40 return !testRegExp(nonSpaceRe, string); 41 } 42 43 var entityMap = { 44 "&": "&", 45 "<": "<", 46 ">": ">", 47 '"': '"', 48 "'": ''', 49 "/": '/' 50 }; 51 52 function escapeHtml(string) { 53 return String(string).replace(/[&<>"'\/]/g, function (s) { 54 return entityMap[s]; 55 }); 56 } 57 58 var whiteRe = /\s*/; 59 var spaceRe = /\s+/; 60 var equalsRe = /\s*=/; 61 var curlyRe = /\s*\}/; 62 var tagRe = /#|\^|\/|>|\{|&|=|!/; 63 64 /** 65 * Breaks up the given `template` string into a tree of tokens. If the `tags` 66 * argument is given here it must be an array with two string values: the 67 * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of 68 * course, the default is to use mustaches (i.e. mustache.tags). 69 * 70 * A token is an array with at least 4 elements. The first element is the 71 * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag 72 * did not contain a symbol (i.e. {{myValue}}) this element is "name". For 73 * all text that appears outside a symbol this element is "text". 74 * 75 * The second element of a token is its "value". For mustache tags this is 76 * whatever else was inside the tag besides the opening symbol. For text tokens 77 * this is the text itself. 78 * 79 * The third and fourth elements of the token are the start and end indices, 80 * respectively, of the token in the original template. 81 * 82 * Tokens that are the root node of a subtree contain two more elements: 1) an 83 * array of tokens in the subtree and 2) the index in the original template at 84 * which the closing tag for that section begins. 85 */ 86 function parseTemplate(template, tags) { 87 if (!template) 88 return []; 89 90 var sections = []; // Stack to hold section tokens 91 var tokens = []; // Buffer to hold the tokens 92 var spaces = []; // Indices of whitespace tokens on the current line 93 var hasTag = false; // Is there a {{tag}} on the current line? 94 var nonSpace = false; // Is there a non-space char on the current line? 95 96 // Strips all whitespace tokens array for the current line 97 // if there was a {{#tag}} on it and otherwise only space. 98 function stripSpace() { 99 if (hasTag && !nonSpace) { 100 while (spaces.length) 101 delete tokens[spaces.pop()]; 102 } else { 103 spaces = []; 104 } 105 106 hasTag = false; 107 nonSpace = false; 108 } 109 110 var openingTagRe, closingTagRe, closingCurlyRe; 111 function compileTags(tags) { 112 if (typeof tags === 'string') 113 tags = tags.split(spaceRe, 2); 114 115 if (!isArray(tags) || tags.length !== 2) 116 throw new Error('Invalid tags: ' + tags); 117 118 openingTagRe = new RegExp(escapeRegExp(tags[0]) + '\\s*'); 119 closingTagRe = new RegExp('\\s*' + escapeRegExp(tags[1])); 120 closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tags[1])); 121 } 122 123 compileTags(tags || mustache.tags); 124 125 var scanner = new Scanner(template); 126 127 var start, type, value, chr, token, openSection; 128 while (!scanner.eos()) { 129 start = scanner.pos; 130 131 // Match any text between tags. 132 value = scanner.scanUntil(openingTagRe); 133 134 if (value) { 135 for (var i = 0, valueLength = value.length; i < valueLength; ++i) { 136 chr = value.charAt(i); 137 138 if (isWhitespace(chr)) {
vendor: 6,990 bytes, lines 139-414
139 spaces.push(tokens.length); 140 } else { 141 nonSpace = true; 142 } 143 144 tokens.push([ 'text', chr, start, start + 1 ]); 145 start += 1; 146 147 // Check for whitespace on the current line. 148 if (chr === '\n') 149 stripSpace(); 150 } 151 } 152 153 // Match the opening tag. 154 if (!scanner.scan(openingTagRe)) 155 break; 156 157 hasTag = true; 158 159 // Get the tag type. 160 type = scanner.scan(tagRe) || 'name'; 161 scanner.scan(whiteRe); 162 163 // Get the tag value. 164 if (type === '=') { 165 value = scanner.scanUntil(equalsRe); 166 scanner.scan(equalsRe); 167 scanner.scanUntil(closingTagRe); 168 } else if (type === '{') { 169 value = scanner.scanUntil(closingCurlyRe); 170 scanner.scan(curlyRe); 171 scanner.scanUntil(closingTagRe); 172 type = '&'; 173 } else { 174 value = scanner.scanUntil(closingTagRe); 175 } 176 177 // Match the closing tag. 178 if (!scanner.scan(closingTagRe)) 179 throw new Error('Unclosed tag at ' + scanner.pos); 180 181 token = [ type, value, start, scanner.pos ]; 182 tokens.push(token); 183 184 if (type === '#' || type === '^') { 185 sections.push(token); 186 } else if (type === '/') { 187 // Check section nesting. 188 openSection = sections.pop(); 189 190 if (!openSection) 191 throw new Error('Unopened section "' + value + '" at ' + start); 192 193 if (openSection[1] !== value) 194 throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); 195 } else if (type === 'name' || type === '{' || type === '&') { 196 nonSpace = true; 197 } else if (type === '=') { 198 // Set the tags for the next time around. 199 compileTags(value); 200 } 201 } 202 203 // Make sure there are no open sections when we're done. 204 openSection = sections.pop(); 205 206 if (openSection) 207 throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); 208 209 return nestTokens(squashTokens(tokens)); 210 } 211 212 /** 213 * Combines the values of consecutive text tokens in the given `tokens` array 214 * to a single token. 215 */ 216 function squashTokens(tokens) { 217 var squashedTokens = []; 218 219 var token, lastToken; 220 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 221 token = tokens[i]; 222 223 if (token) { 224 if (token[0] === 'text' && lastToken && lastToken[0] === 'text') { 225 lastToken[1] += token[1]; 226 lastToken[3] = token[3]; 227 } else { 228 squashedTokens.push(token); 229 lastToken = token; 230 } 231 } 232 } 233 234 return squashedTokens; 235 } 236 237 /** 238 * Forms the given array of `tokens` into a nested tree structure where 239 * tokens that represent a section have two additional items: 1) an array of 240 * all tokens that appear in that section and 2) the index in the original 241 * template that represents the end of that section. 242 */ 243 function nestTokens(tokens) { 244 var nestedTokens = []; 245 var collector = nestedTokens; 246 var sections = []; 247 248 var token, section; 249 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 250 token = tokens[i]; 251 252 switch (token[0]) { 253 case '#': 254 case '^': 255 collector.push(token); 256 sections.push(token); 257 collector = token[4] = []; 258 break; 259 case '/': 260 section = sections.pop(); 261 section[5] = token[2]; 262 collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens; 263 break; 264 default: 265 collector.push(token); 266 } 267 } 268 269 return nestedTokens; 270 } 271 272 /** 273 * A simple string scanner that is used by the template parser to find 274 * tokens in template strings. 275 */ 276 function Scanner(string) { 277 this.string = string; 278 this.tail = string; 279 this.pos = 0; 280 } 281 282 /** 283 * Returns `true` if the tail is empty (end of string). 284 */ 285 Scanner.prototype.eos = function () { 286 return this.tail === ""; 287 }; 288 289 /** 290 * Tries to match the given regular expression at the current position. 291 * Returns the matched text if it can match, the empty string otherwise. 292 */ 293 Scanner.prototype.scan = function (re) { 294 var match = this.tail.match(re); 295 296 if (!match || match.index !== 0) 297 return ''; 298 299 var string = match[0]; 300 301 this.tail = this.tail.substring(string.length); 302 this.pos += string.length; 303 304 return string; 305 }; 306 307 /** 308 * Skips all text until the given regular expression can be matched. Returns 309 * the skipped string, which is the entire tail if no match can be made. 310 */ 311 Scanner.prototype.scanUntil = function (re) { 312 var index = this.tail.search(re), match; 313 314 switch (index) { 315 case -1: 316 match = this.tail; 317 this.tail = ""; 318 break; 319 case 0: 320 match = ""; 321 break; 322 default: 323 match = this.tail.substring(0, index); 324 this.tail = this.tail.substring(index); 325 } 326 327 this.pos += match.length; 328 329 return match; 330 }; 331 332 /** 333 * Represents a rendering context by wrapping a view object and 334 * maintaining a reference to the parent context. 335 */ 336 function Context(view, parentContext) { 337 this.view = view == null ? {} : view; 338 this.cache = { '.': this.view }; 339 this.parent = parentContext; 340 } 341 342 /** 343 * Creates a new context using the given view with this context 344 * as the parent. 345 */ 346 Context.prototype.push = function (view) { 347 return new Context(view, this); 348 }; 349 350 /** 351 * Returns the value of the given name in this context, traversing 352 * up the context hierarchy if the value is absent in this context's view. 353 */ 354 Context.prototype.lookup = function (name) { 355 var cache = this.cache; 356 357 var value; 358 if (name in cache) { 359 value = cache[name]; 360 } else { 361 var context = this, names, index; 362 363 while (context) { 364 if (name.indexOf('.') > 0) { 365 value = context.view; 366 names = name.split('.'); 367 index = 0; 368 369 while (value != null && index < names.length) 370 value = value[names[index++]]; 371 } else { 372 value = context.view[name]; 373 } 374 375 if (value != null) 376 break; 377 378 context = context.parent; 379 } 380 381 cache[name] = value; 382 } 383 384 if (isFunction(value)) 385 value = value.call(this.view); 386 387 return value; 388 }; 389 390 /** 391 * A Writer knows how to take a stream of tokens and render them to a 392 * string, given a context. It also maintains a cache of templates to 393 * avoid the need to parse the same template twice. 394 */ 395 function Writer() { 396 this.cache = {}; 397 } 398 399 /** 400 * Clears all cached templates in this writer. 401 */ 402 Writer.prototype.clearCache = function () { 403 this.cache = {}; 404 }; 405 406 /** 407 * Parses and caches the given `template` and returns the array of tokens 408 * that is generated from the parse. 409 */ 410 Writer.prototype.parse = function (template, tags) { 411 var cache = this.cache; 412 var tokens = cache[template]; 413 414 if (tokens == null)
415 tokens = cache[template] = parseTemplate(template, tags); 416 417 return tokens; 418 }; 419 420 /** 421 * High-level method that is used to render the given `template` with 422 * the given `view`. 423 * 424 * The optional `partials` argument may be an object that contains the 425 * names and templates of partials that are used in the template. It may 426 * also be a function that is used to load partial templates on the fly 427 * that takes a single argument: the name of the partial. 428 */ 429 Writer.prototype.render = function (template, view, partials) { 430 var tokens = this.parse(template); 431 var context = (view instanceof Context) ? view : new Context(view); 432 return this.renderTokens(tokens, context, partials, template); 433 }; 434 435 /** 436 * Low-level method that renders the given array of `tokens` using 437 * the given `context` and `partials`. 438 * 439 * Note: The `originalTemplate` is only ever used to extract the portion 440 * of the original template that was contained in a higher-order section. 441 * If the template doesn't use higher-order sections, this argument may 442 * be omitted. 443 */ 444 Writer.prototype.renderTokens = function (tokens, context, partials, originalTemplate) { 445 var buffer = ''; 446 447 // This function is used to render an arbitrary template 448 // in the current context by higher-order sections. 449 var self = this; 450 function subRender(template) { 451 return self.render(template, context, partials); 452 } 453 454 var token, value; 455 for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { 456 token = tokens[i]; 457 458 switch (token[0]) { 459 case '#': 460 value = context.lookup(token[1]); 461 462 if (!value) 463 continue; 464 465 if (isArray(value)) { 466 for (var j = 0, valueLength = value.length; j < valueLength; ++j) { 467 buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); 468 } 469 } else if (typeof value === 'object' || typeof value === 'string') { 470 buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate); 471 } else if (isFunction(value)) { 472 if (typeof originalTemplate !== 'string') 473 throw new Error('Cannot use higher-order sections without the original template'); 474 475 // Extract the portion of the original template that the section contains. 476 value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender); 477 478 if (value != null) 479 buffer += value; 480 } else { 481 buffer += this.renderTokens(token[4], context, partials, originalTemplate); 482 } 483 484 break; 485 case '^': 486 value = context.lookup(token[1]); 487 488 // Use JavaScript's definition of falsy. Include empty arrays. 489 // See https://github.com/janl/mustache.js/issues/186 490 if (!value || (isArray(value) && value.length === 0)) 491 buffer += this.renderTokens(token[4], context, partials, originalTemplate); 492 493 break; 494 case '>': 495 if (!partials) 496 continue; 497 498 value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; 499 500 if (value != null) 501 buffer += this.renderTokens(this.parse(value), context, partials, value); 502 503 break; 504 case '&': 505 value = context.lookup(token[1]); 506 507 if (value != null) 508 buffer += value; 509 510 break; 511 case 'name': 512 value = context.lookup(token[1]); 513 514 if (value != null) 515 buffer += mustache.escape(value); 516 517 break; 518 case 'text': 519 buffer += token[1]; 520 break; 521 } 522 } 523 524 return buffer; 525 }; 526 527 mustache.name = "mustache.js"; 528 mustache.version = "0.8.1"; 529 mustache.tags = [ "{{", "}}" ]; 530 531 // All high-level mustache.* functions use this writer. 532 var defaultWriter = new Writer(); 533 534 /** 535 * Clears all cached templates in the default writer. 536 */ 537 mustache.clearCache = function () { 538 return defaultWriter.clearCache(); 539 }; 540 541 /** 542 * Parses and caches the given template in the default writer and returns the 543 * array of tokens it contains. Doing this ahead of time avoids the need to 544 * parse templates on the fly as they are rendered. 545 */ 546 mustache.parse = function (template, tags) { 547 return defaultWriter.parse(template, tags); 548 }; 549 550 /** 551 * Renders the `template` with the given `view` and `partials` using the 552 * default writer. 553 */ 554 mustache.render = function (template, view, partials) { 555 return defaultWriter.render(template, view, partials); 556 }; 557 558 // This is here for backwards compatibility with 0.4.x. 559 mustache.to_html = function (template, view, partials, send) { 560 var result = mustache.render(template, view, partials); 561 562 if (isFunction(send)) { 563 send(result); 564 } else { 565 return result; 566 } 567 }; 568 569 // Export the escaping function so that the user may override it. 570 // See https://github.com/janl/mustache.js/issues/244 571 mustache.escape = escapeHtml; 572 573 // Export these mainly for testing, but also for advanced usage. 574 mustache.Scanner = Scanner; 575 mustache.Context = Context; 576 mustache.Writer = Writer; 577 578})); 579 580var optionTemplate = '<option value="{{handle}}">{{name}}</option>'; 581$(document).ready(function () { 582 var body = $('body'); 583 /** 584 * Submit cart step processing 585 */ 586 body.on('click', '#checkout-submit', function (event) { 587 if (!getBasicParam('isAuthorized')) { 588 var loginForm = $('#js-modal-login'); 589 event.preventDefault(); 590 $.magnificPopup.open({ 591 items: {src: '#js-modal-login'}, 592 type: 'inline',
593 mainClass: 'modal-perspective', 594 removalDelay: 350, 595 midClick: true, 596 callbacks: { 597 close: function () { 598 loginForm.find('input[name="nextUrl"]').remove(); 599 } 600 } 601 }); 602 loginForm.find('form').append('<input type="hidden" name="nextUrl" value="' + 603 Routing.generate('checkout_cart', {'skip': true}) + '"/>'); 604 605 return false; 606 } 607 }); 608 609 /** 610 * Process questionnaire form, perform post request to add new nic handle for user 611 */ 612 body.on('submit', '.questionnaire-form', function (event) { 613 event.preventDefault(); 614 var thisElement = $(this); 615 $.post({ 616 url: Routing.generate('add_nic_handle'), 617 data: thisElement.serialize(), 618 dataType: 'json' 619 }).success(function (response) { 620 if(thisElement.parents('.domain-contact-wrapper').length){ 621 thisElement.parents('.domain-contact-wrapper').find('.text-error').hide(); 622 } 623 var template = $('#new-contact-template').html(); 624 var block = Mustache.render(template, response.data); 625 var descriptionContainer = $('#description-container'); 626 descriptionContainer.append(block); 627 var select = thisElement.parent().prev().find('select'); 628 select.append( 629 Mustache.render(optionTemplate, {handle: response.data.handle, name: response.data.formattedName}) 630 ); 631 select.val(response.data.handle); 632 contactFormDecorator(select); 633 initSelect2(); 634 }).fail(function (xhr) { 635 var data = xhr.responseJSON; 636 var inputs = thisElement.find('input'); 637 inputs.removeClass('form-control-error'); 638 var errorWrappers = inputs.siblings('.text-error'); 639 errorWrappers.text(''); 640 errorWrappers.hide(); 641 for (var i = 0; i < data.errorList.length; i++) { 642 var input = thisElement.find('input[name="baseQuestionnaire[' + 643 data.errorList[i].field + ']"]'); 644 input.addClass('form-control-error'); 645 var errorWrapper = input.siblings('.text-error'); 646 errorWrapper.show(); 647 errorWrapper.html(data.errorList[i].errors); 648 } 649 }); 650 }); 651 652 body.find('.domain-contact-select .select-custom').prop('disabled', false); 653 654 /** 655 * Clear questionnaire form 656 */ 657 body.on('click', '.questionnaire-form .link-btn a', function (event) { 658 event.preventDefault(); 659 if($(event.target).parents('.domain-contact-wrapper').length){ 660 $(event.target).parents('.domain-contact-wrapper').find('.text-error').hide(); 661 } 662 var form = $(this).parent().parent().parent(); 663 form.find('.text-error').hide(); 664 form.find('input').removeClass('form-control-error'); 665 form[0].reset(); 666 var select = form.parent().prev().find('select'); 667 select.val(select.find('option:first').val()); 668 initSelect2(); 669 contactFormDecorator(select); 670 }); 671 672 /** 673 * Remove validation errors 674 */ 675 body.on('keyup', '.questionnaire-form input, .single-questionnaire input, form[name="companyContactForm"] input, ' + 676 '#trademark-form input', function () { 677 removeError($(this)); 678 }); 679 680 body.on('change', '.form-control-fulldate-day', function() { 681 if ($(this).val().length === 1) { 682 $(this).val('0'+$(this).val()); 683 } 684 }); 685 686 body.on('keyup, change', '.date-pick-widget input, .date-pick-widget select', function (event) { 687 var parent = $(this).parent(); 688 var target = $(parent.data('target')); 689 target.val( 690 parent.find('input[data-type="year"]').val() + '-' + 691 parent.find('select').val() + '-' + 692 parent.find('input[data-type="day"]').val() 693 ); 694 }); 695 $.each(body.find('.date-pick-widget'), function (key, value) { 696 var $value = $(value); 697 var target = $($value.data('target')); 698 if (target.val().length > 0) { 699 var data = target.val().split('-'); 700 $value.find('input[data-type="year"]').val(data[0]); 701 $value.find('select').val(data[1]); 702 $value.find('input[data-type="day"]').val(data[2]); 703 } 704 }); 705 706 /** 707 * Hide flash message 708 */ 709 body.on('click', '.notify-remover', function (event) { 710 event.preventDefault(); 711 $(this).parent.hide(); 712 }); 713 714 /** 715 * Process bonus forms 716 */ 717 body.on('submit', '.bonus-form', function (event) { 718 event.preventDefault(); 719 $('#bonus-form-submit').prop("disabled", true); 720 var thisElement = $(this); 721 var formData = thisElement.serialize(); 722 $.post({ 723 url: Routing.generate('bonus_payment'), 724 data: formData, 725 dataType: 'json' 726 }).success(function (data) { 727 if (data.success) { 728 thisElement.parent().remove(); 729 var spanList = $('span.payment-span'); 730 var currency = $('#invoice-currency').val(); 731 $('.bonus-error-container').hide(); 732 $.each(spanList, function (key, value) { 733 $(value).html( 734 numberToCurrency(data.invoiceAmt, $(value).data('currency'), currency) 735 ); 736 }); 737 $('.receipt-header div.text-large strong:last').html( 738 numberToCurrency(data.invoiceAmt, currency, currency) 739 ); 740 var successWrapper = $('#bonus-success-box'); 741 successWrapper.show(); 742 successWrapper.find('#payment-success').html( 743 numberToCurrency(data.amount, currency, currency, true) 744 ); 745 successWrapper.find('#account-balance').html( 746 numberToCurrency(data.balance, currency, currency, true) 747 ); 748 $('#contacts-submit p.text-error').val(''); 749 } else { 750 $('.bonus-error-container').show(); 751 $('.bonus-error-container .error-wrapper').html(data.error); 752 thisElement.find('.text-muted').addClass('text-error'); 753 $('#bonus-form-submit').prop('disabled', false); 754 } 755 }) 756 }); 757 758 body.on('change', 'select.acc-switcher', function () { 759 var container = $($(this).data('form')); 760 var currency = container.find('input[name="currency"]'); 761 var option = $(this).find(':selected'); 762 $('.formatted-value-container').html(option.data('formatted-value')); 763 if (option.data('formatted-credit-value') != undefined) { 764 var creditContainer = $('.formatted-credit-value-container'); 765 if (option.data('credit-value') > 0) { 766 creditContainer.html(option.data('formatted-credit-value')); 767 creditContainer.parent().parent().show(); 768 } else { 769 creditContainer.parent().parent().hide(); 770 } 771 } 772 if ($(this).data('max-payment') != undefined) { 773 var value = null; 774 if ($(this).data('max-payment') < option.data('value')) { 775 value = $(this).data('max-payment'); 776 } else { 777 value = option.data('value'); 778 } 779 container.find('input[name="amount"]').val(value); 780 } 781 }); 782 783 body.on('click', '.bonus-hider', function (event) { 784 event.preventDefault(); 785 $(this).parent().hide(); 786 $('.bonus-opener-container').show(); 787 var amount = 1; 788 if (getCookie('bonus_hidden') !== false) { 789 amount = parseInt(getCookie('bonus_hidden')) + 1; 790 }
791 setCookie('bonus_hidden', amount, {expires: 86400 * 30}); 792 }); 793 794 body.on('click', '.bonus-opener', function (event) { 795 event.preventDefault(); 796 $('.bonus-opener-container').hide(); 797 $('.bonus-container').show(); 798 }); 799 800 /** 801 * Partial payment 802 */ 803 body.on('submit', '#partial-payment-form', function (event) { 804 event.preventDefault(); 805 var thisElement = $(this); 806 var input = thisElement.find('input[name="amount"]'); 807 var currency = thisElement.find('input[name="currency"]'); 808 if (input.val() > 0) { 809 input.removeClass('form-control-error'); 810 $.post({ 811 url: thisElement.attr('action'), 812 data: thisElement.serialize(), 813 dataType: 'json' 814 }).success(function (response) { 815 if (response.success) { 816 var ul = thisElement.parent().parent().siblings('ul'); 817 ul.find('li:first').hide(); 818 ul.find('li:last').show(); 819 ul.find('li:last strong:first').html(response.currency); 820 $('.js-checkout-pay-by-parts').hide(); 821 var spanList = $('span.payment-span'); 822 $.each(spanList, function (key, value) { 823 $(value).html( 824 numberToCurrency(input.val(), $(value).data('currency'), currency.val()) 825 ); 826 }); 827 } else { 828 input.addClass('form-control-error'); 829 } 830 }); 831 } else { 832 input.addClass('form-control-error'); 833 } 834 }); 835 836 837 /** 838 * Step "Owner'sContacts" - process select changing 839 */ 840 body.on('change', 'select.select-custom', function () { 841 contactFormDecorator($(this)); 842 var selectList = $('select.select-custom'); 843 selectList.find('option:disabled').prop('disabled', false); 844 var targetValue = ''; 845 $.each(selectList, function (key, value) { 846 value = $(value); 847 var selectedValues = [value]; 848 do { 849 var targetSelect = $('select.select-custom[data-type="' + value.val() + '"]'); 850 if (targetSelect.length > 0) { 851 selectedValues.push(targetSelect); 852 targetValue = targetSelect.val(); 853 } 854 value = targetSelect; 855 } while (targetSelect.length > 0); 856 for (var i = 0; i < selectedValues.length; i++) { 857 var select = selectedValues.pop(); 858 $.each(selectedValues, function (k, v) { 859 select.find('option[value="' + $(v).data('type') + '"]').prop('disabled', true); 860 }); 861 } 862 }); 863 initSelect2(); 864 }); 865 866 /** 867 * Process form data in Owner'sContacts step 868 */ 869 body.on('submit', '#contacts-submit', function (event) { 870 var thisElement = $(this); 871 var inputs = thisElement.find('input'); 872 $.each(inputs, function (key, value) { 873 if ($(value).attr('name') === 'contacts[payer]') { 874 var result = false;
875 var innerInput = $(value); 876 do { 877 if (innerInput !== undefined) { 878 result = innerInput.val(); 879 } 880 innerInput = $('input[name="contacts['+ innerInput.val() + ']"]'); 881 } while (innerInput[0] !== undefined); 882 if (result === DEFAULT_NIC_HANDLE) { 883 event.preventDefault(); 884 var errorWrapper = thisElement.find('p.text-error'); 885 errorWrapper.html(getTranslation('__Payer_nic_handle_error')); 886 errorWrapper.show(); 887 return false; 888 } 889 } 890 value = $(value).val(); 891 if (value === undefined || ['new', 'show_contacts'].indexOf(value) >= 0 || value.length < 1) { 892 event.preventDefault(); 893 var errorWrapper = thisElement.find('p.text-error'); 894 if (value === 'show_contacts') { 895 errorWrapper.html(getTranslation('__Invalid_contacts_value')); 896 } else { 897 errorWrapper.html(getTranslation('__Submit_contacts_error')); 898 } 899 errorWrapper.show(); 900 return false; 901 } 902 }); 903 }); 904 905 /** 906 * Trademark input toggle 907 */ 908 body.on('click', '#trademark-form input[type="checkbox"]', function () { 909 var form = $('#trademark-form'); 910 var targetInput = $(this).parent().parent().siblings('input'); 911 if ($(this).prop('checked') === true) { 912 targetInput.show(); 913 } else { 914 targetInput.hide(); 915 } 916 var similarInputs = form.find('input[type="text"]:visible'); 917 if (similarInputs.length < 1) { 918 $('#trademark-submit').hide(); 919 $('.hidden-trademark-contact').show(); 920 } else { 921 $('#trademark-submit').show(); 922 $('.hidden-trademark-contact').hide(); 923 } 924 }); 925 926 /** 927 * Trademark form preSubmitProcessing, validation 928 */ 929 body.on('submit', '#trademark-form', function (event) { 930 var thisElement = $(this); 931 var similarInputs = thisElement.find('input[type="text"]:visible'); 932 var error = getTranslation('__Trademark_required_error'); 933 var resultData = []; 934 $.each(similarInputs, function (key, value) { 935 var $value = $(value); 936 if ($value.val().length > 1) { 937 removeError($value); 938 resultData.push({ 939 domain: $value.data('domain'), 940 trademark: ($value.val().length() > 0) ? $value.val() : false 941 }); 942 return; 943 } 944 addError($value, error); 945 event.preventDefault(); 946 }); 947 }); 948 $.each($('.js-tooltip-with-content'), function (key, value) { 949 var val = $(value).siblings('.tooltip-data-container').html().trim(); 950 $(value).tooltipster({ 951 theme: 'tooltipster-light', 952 interactive: 'true', 953 maxWidth: 340, 954 content: val 955 }); 956 }); 957 958 //preload cart list content 959 $('#content-loader').show(); 960 $('.cart-list-data').empty(); 961 $.ajax({ 962 type: "GET", 963 url: Routing.generate('checkout_cart_list') 964 }) 965 .done(function (data) { 966 $('#content-loader').hide(); 967 $('.cart-list-data').append(data.body); 968 removeCardTableEmptyLines(); 969 //activate tooltips 970 var tips = $('.js-tooltip'); 971 $.each(tips, function (key, value) { 972 var object = $(value); 973 var theme = 'tooltipster-light'; 974 var options = { 975 theme: theme, 976 interactive: true, 977 content: $($(object.data('target')).html()) 978 }; 979 if (is_touch_device()) { 980 options = { 981 theme: theme, 982 interactive: true, 983 trigger: 'click', 984 content: $($(object.data('target')).html()) 985 } 986 }; 987 object.tooltipster(options); 988 }); 989 990 if (data.discount_clear) { 991 discount = false;
992 } 993 refreshTotalPrice(discount); 994 }); 995 996 body.on('change', 'select.card-select', function (e) { 997 var option = $(this).find('option:selected'); 998 var target = $($(this).data('target')); 999 if (option.data('extra') === 'new') { 1000 target.show(); 1001 } else { 1002 target.hide(); 1003 } 1004 }); 1005 1006 $('#select_default_contact').val('show_contacts').change(); 1007}); 1008 1009function is_touch_device() { 1010 return !!('ontouchstart' in window); 1011} 1012/** 1013 * Process improved select info data 1014 */ 1015function contactFormDecorator(select) { 1016 var descriptionContainer = $('#description-container'); 1017 var newFormWrapper = select.parent().parent().parent().next(); 1018 newFormWrapper.hide(); 1019 switch (select.val()) { 1020 case 'new' : 1021 newFormWrapper.show(); 1022 break; 1023 case 'show_contacts' : 1024 var errorWrapper = select.siblings('p.text-error'); 1025 var selectList = $('select.select-custom'); 1026 selectList.find('option[value="show_contacts"]').text(getTranslation('__Checkout_contacts_loader')); 1027 initSelect2(select); 1028 $.get({ 1029 url: Routing.generate('user_handles'), 1030 dataType: 'json' 1031 }).success(function (response) { 1032 var template = $('#new-contact-template').html(); 1033 var renderResult = '<optgroup label="' + getTranslation('__Checkout_regular_optgroup') + '">'; 1034 var containerAppendData = ''; 1035 $.each(response.data.regular, function (k, v) { 1036 renderResult += Mustache.render(optionTemplate, {handle: v.handle, name: v.formattedName}); 1037 containerAppendData += Mustache.render(template, v); 1038 }); 1039 renderResult += '</optgroup><optgroup label="' + getTranslation('__Checkout_legal_optgroup') + '">'; 1040 $.each(response.data.org, function (k, v) { 1041 renderResult += Mustache.render(optionTemplate, {handle: v.handle, name: v.formattedName}); 1042 containerAppendData += Mustache.render(template, v); 1043 }); 1044 renderResult += '</optgroup>'; 1045 selectList.find('optgroup[data-type="additional"]').remove(); 1046 $.each(selectList, function (k, v) { 1047 var select = $(v); 1048 select.addClass('select-custom-with-search'); 1049 if (select.attr('id') === 'select_default_contact') { 1050 select.prepend(renderResult); 1051 } else { 1052 select.append(renderResult); 1053 } 1054 }); 1055 descriptionContainer.append(containerAppendData); 1056 select.val(select.find('option:first').val()); 1057 initSelect2(select); 1058 initDescriptionBlock(select); 1059 var input = $('#contacts-submit').find('input[name="contacts[' + select.data('type') + ']"]'); 1060 input.val(select.val()); 1061 errorWrapper.hide(); 1062 }).fail(function () { 1063 errorWrapper.html(getTranslation('__Something_goes_wrong')); 1064 errorWrapper.show(); 1065 }); 1066 break; 1067 } 1068 initDescriptionBlock(select); 1069 var input = $('#contacts-submit').find('input[name="contacts[' + select.data('type') + ']"]'); 1070 input.val(select.val()); 1071} 1072 1073function initSelect2(selectedObject) { 1074 $('select.select-custom').select2('destroy'); 1075 $('select.select-custom:not(select-custom-with-search)').select2({ 1076 minimumResultsForSearch: Infinity, 1077 width: 'resolve' 1078 }); 1079 $('select.select-custom-with-search').select2({ 1080 minimumResultsForSearch: 1 1081 }); 1082 if (selectedObject !== undefined) { 1083 selectedObject.select2('open'); 1084 } 1085} 1086 1087function initDescriptionBlock(select) { 1088 var descriptionContainer = $('#description-container'); 1089 var dataList = [select]; 1090 dataList = dataList.concat($('select.select-custom').toArray()); 1091 $.each(dataList, function (key, value) { 1092 var select = $(value); 1093 var targetSelect = select; 1094 do { 1095 targetSelect = $('select[data-type="' + targetSelect.val() + '"]'); 1096 } while ($('select[data-type="' + targetSelect.val() + '"]').length > 0);
1097 if (targetSelect.length > 0) { 1098 select.siblings('div.domain-contact-details').html( 1099 targetSelect.siblings('div.domain-contact-details').html() 1100 ); 1101 } else { 1102 var element = descriptionContainer.find('div[data-name="' + select.val() + '"]'); 1103 select.siblings('div.domain-contact-details').html(element.clone()); 1104 } 1105 }); 1106}
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.