Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2019
339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Copyright © Magento, Inc. All rights reserved.
  3.  * See COPYING.txt for license details.
  4.  */
  5.  
  6. define([
  7.     'jquery',
  8.     'underscore',
  9.     'mage/template',
  10.     'mage/smart-keyboard-handler',
  11.     'mage/translate',
  12.     'priceUtils',
  13.     'jquery/ui',
  14.     'jquery/jquery.parsequery',
  15.     'mage/validation/validation'
  16. ], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) {
  17.     'use strict';
  18.  
  19.     /**
  20.      * Extend form validation to support swatch accessibility
  21.      */
  22.     $.widget('mage.validation', $.mage.validation, {
  23.         /**
  24.          * Handle form with swatches validation. Focus on first invalid swatch block.
  25.          *
  26.          * @param {jQuery.Event} event
  27.          * @param {Object} validation
  28.          */
  29.         listenFormValidateHandler: function (event, validation) {
  30.             var swatchWrapper, firstActive, swatches, swatch, successList, errorList, firstSwatch;
  31.  
  32.             this._superApply(arguments);
  33.  
  34.             swatchWrapper = '.swatch-attribute-options';
  35.             swatches = $(event.target).find(swatchWrapper);
  36.  
  37.             if (!swatches.length) {
  38.                 return;
  39.             }
  40.  
  41.             swatch = '.swatch-attribute';
  42.             firstActive = $(validation.errorList[0].element || []);
  43.             successList = validation.successList;
  44.             errorList = validation.errorList;
  45.             firstSwatch = $(firstActive).parent(swatch).find(swatchWrapper);
  46.  
  47.             keyboardHandler.focus(swatches);
  48.  
  49.             $.each(successList, function (index, item) {
  50.                 $(item).parent(swatch).find(swatchWrapper).attr('aria-invalid', false);
  51.             });
  52.  
  53.             $.each(errorList, function (index, item) {
  54.                 $(item.element).parent(swatch).find(swatchWrapper).attr('aria-invalid', true);
  55.             });
  56.  
  57.             if (firstSwatch.length) {
  58.                 $(firstSwatch).focus();
  59.             }
  60.         }
  61.     });
  62.  
  63.     /**
  64.      * Render tooltips by attributes (only to up).
  65.      * Required element attributes:
  66.      *  - option-type (integer, 0-3)
  67.      *  - option-label (string)
  68.      *  - option-tooltip-thumb
  69.      *  - option-tooltip-value
  70.      */
  71.     $.widget('mage.SwatchRendererTooltip', {
  72.         options: {
  73.             delay: 200,                             //how much ms before tooltip to show
  74.             tooltipClass: 'swatch-option-tooltip'  //configurable, but remember about css
  75.         },
  76.  
  77.         /**
  78.          * @private
  79.          */
  80.         _init: function () {
  81.             var $widget = this,
  82.                 $this = this.element,
  83.                 $element = $('.' + $widget.options.tooltipClass),
  84.                 timer,
  85.                 type = parseInt($this.attr('option-type'), 10),
  86.                 label = $this.attr('option-label'),
  87.                 thumb = $this.attr('option-tooltip-thumb'),
  88.                 value = $this.attr('option-tooltip-value'),
  89.                 $image,
  90.                 $title,
  91.                 $corner;
  92.  
  93.             if (!$element.size()) {
  94.                 $element = $('<div class="' +
  95.                     $widget.options.tooltipClass +
  96.                     '"><div class="image"></div><div class="title"></div><div class="corner"></div></div>'
  97.                 );
  98.                 $('body').append($element);
  99.             }
  100.  
  101.             $image = $element.find('.image');
  102.             $title = $element.find('.title');
  103.             $corner = $element.find('.corner');
  104.  
  105.             $this.hover(function () {
  106.                 if (!$this.hasClass('disabled')) {
  107.                     timer = setTimeout(
  108.                         function () {
  109.                             var leftOpt = null,
  110.                                 leftCorner = 0,
  111.                                 left,
  112.                                 $window;
  113.  
  114.                             if (type === 2) {
  115.                                 // Image
  116.                                 $image.css({
  117.                                     'background': 'url("' + thumb + '") no-repeat center', //Background case
  118.                                     'background-size': 'initial'
  119.                                 });
  120.                                 $image.show();
  121.                             } else if (type === 1) {
  122.                                 // Color
  123.                                 $image.css({
  124.                                     background: value
  125.                                 });
  126.                                 $image.show();
  127.                             } else if (type === 0 || type === 3) {
  128.                                 // Default
  129.                                 $image.hide();
  130.                             }
  131.  
  132.                             $title.text(label);
  133.  
  134.                             leftOpt = $this.offset().left;
  135.                             left = leftOpt + $this.width() / 2 - $element.width() / 2;
  136.                             $window = $(window);
  137.  
  138.                             // the numbers (5 and 5) is magick constants for offset from left or right page
  139.                             if (left < 0) {
  140.                                 left = 5;
  141.                             } else if (left + $element.width() > $window.width()) {
  142.                                 left = $window.width() - $element.width() - 5;
  143.                             }
  144.  
  145.                             // the numbers (6,  3 and 18) is magick constants for offset tooltip
  146.                             leftCorner = 0;
  147.  
  148.                             if ($element.width() < $this.width()) {
  149.                                 leftCorner = $element.width() / 2 - 3;
  150.                             } else {
  151.                                 leftCorner = (leftOpt > left ? leftOpt - left : left - leftOpt) + $this.width() / 2 - 6;
  152.                             }
  153.  
  154.                             $corner.css({
  155.                                 left: leftCorner
  156.                             });
  157.                             $element.css({
  158.                                 left: left,
  159.                                 top: $this.offset().top - $element.height() - $corner.height() - 18
  160.                             }).show();
  161.                         },
  162.                         $widget.options.delay
  163.                     );
  164.                 }
  165.             }, function () {
  166.                 $element.hide();
  167.                 clearTimeout(timer);
  168.             });
  169.  
  170.             $(document).on('tap', function () {
  171.                 $element.hide();
  172.                 clearTimeout(timer);
  173.             });
  174.  
  175.             $this.on('tap', function (event) {
  176.                 event.stopPropagation();
  177.             });
  178.         }
  179.     });
  180.  
  181.     /**
  182.      * Render swatch controls with options and use tooltips.
  183.      * Required two json:
  184.      *  - jsonConfig (magento's option config)
  185.      *  - jsonSwatchConfig (swatch's option config)
  186.      *
  187.      *  Tuning:
  188.      *  - numberToShow (show "more" button if options are more)
  189.      *  - onlySwatches (hide selectboxes)
  190.      *  - moreButtonText (text for "more" button)
  191.      *  - selectorProduct (selector for product container)
  192.      *  - selectorProductPrice (selector for change price)
  193.      */
  194.     $.widget('mage.SwatchRenderer', {
  195.         options: {
  196.             classes: {
  197.                 attributeClass: 'swatch-attribute',
  198.                 attributeLabelClass: 'swatch-attribute-label',
  199.                 attributeSelectedOptionLabelClass: 'swatch-attribute-selected-option',
  200.                 attributeOptionsWrapper: 'swatch-attribute-options',
  201.                 attributeInput: 'swatch-input',
  202.                 optionClass: 'swatch-option',
  203.                 selectClass: 'swatch-select',
  204.                 moreButton: 'swatch-more',
  205.                 loader: 'swatch-option-loading'
  206.             },
  207.             // option's json config
  208.             jsonConfig: {},
  209.  
  210.             // swatch's json config
  211.             jsonSwatchConfig: {},
  212.  
  213.             // selector of parental block of prices and swatches (need to know where to seek for price block)
  214.             selectorProduct: '.product-info-main',
  215.  
  216.             // selector of price wrapper (need to know where set price)
  217.             selectorProductPrice: '[data-role=priceBox]',
  218.  
  219.             //selector of product images gallery wrapper
  220.             mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',
  221.  
  222.             // selector of category product tile wrapper
  223.             selectorProductTile: '.product-item',
  224.  
  225.             // number of controls to show (false or zero = show all)
  226.             numberToShow: false,
  227.  
  228.             // show only swatch controls
  229.             onlySwatches: false,
  230.  
  231.             // enable label for control
  232.             enableControlLabel: true,
  233.  
  234.             // control label id
  235.             controlLabelId: '',
  236.  
  237.             // text for more button
  238.             moreButtonText: 'More',
  239.  
  240.             // Callback url for media
  241.             mediaCallback: '',
  242.  
  243.             // Local media cache
  244.             mediaCache: {},
  245.  
  246.             // Cache for BaseProduct images. Needed when option unset
  247.             mediaGalleryInitial: [{}],
  248.  
  249.             // Use ajax to get image data
  250.             useAjax: false,
  251.  
  252.             /**
  253.              * Defines the mechanism of how images of a gallery should be
  254.              * updated when user switches between configurations of a product.
  255.              *
  256.              * As for now value of this option can be either 'replace' or 'prepend'.
  257.              *
  258.              * @type {String}
  259.              */
  260.             gallerySwitchStrategy: 'replace',
  261.  
  262.             // whether swatches are rendered in product list or on product page
  263.             inProductList: false,
  264.  
  265.             // sly-old-price block selector
  266.             slyOldPriceSelector: '.sly-old-price',
  267.  
  268.             // tier prise selectors start
  269.             tierPriceTemplateSelector: '#tier-prices-template',
  270.             tierPriceBlockSelector: '[data-role="tier-price-block"]',
  271.             tierPriceTemplate: '',
  272.             // tier prise selectors end
  273.  
  274.             // A price label selector
  275.             normalPriceLabelSelector: '.normal-price .price-label'
  276.         },
  277.  
  278.         /**
  279.          * Get chosen product
  280.          *
  281.          * @returns int|null
  282.          */
  283.         getProduct: function () {
  284.             var products = this._CalcProducts();
  285.  
  286.             return _.isArray(products) ? products[0] : null;
  287.         },
  288.  
  289.         /**
  290.          * @private
  291.          */
  292.         _init: function () {
  293.             if (_.isEmpty(this.options.jsonConfig.images)) {
  294.                 this.options.useAjax = true;
  295.                 // creates debounced variant of _LoadProductMedia()
  296.                 // to use it in events handlers instead of _LoadProductMedia()
  297.                 this._debouncedLoadProductMedia = _.debounce(this._LoadProductMedia.bind(this), 500);
  298.             }
  299.  
  300.             if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {
  301.                 // store unsorted attributes
  302.                 this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);
  303.                 this._sortAttributes();
  304.                 this._RenderControls();
  305.                 this._setPreSelectedGallery();
  306.                 $(this.element).trigger('swatch.initialized');
  307.             } else {
  308.                 console.log('SwatchRenderer: No input data received');
  309.             }
  310.             this.options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();
  311.         },
  312.  
  313.         /**
  314.          * @private
  315.          */
  316.         _sortAttributes: function () {
  317.             this.options.jsonConfig.attributes = _.sortBy(this.options.jsonConfig.attributes, function (attribute) {
  318.                 return attribute.position;
  319.             });
  320.         },
  321.  
  322.         /**
  323.          * @private
  324.          */
  325.         _create: function () {
  326.             var options = this.options,
  327.                 gallery = $('[data-gallery-role=gallery-placeholder]', '.column.main'),
  328.                 productData = this._determineProductData(),
  329.                 $main = productData.isInProductView ?
  330.                     this.element.parents('.column.main') :
  331.                     this.element.parents('.product-item-info');
  332.  
  333.             if (productData.isInProductView) {
  334.                 gallery.data('gallery') ?
  335.                     this._onGalleryLoaded(gallery) :
  336.                     gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));
  337.             } else {
  338.                 options.mediaGalleryInitial = [{
  339.                     'img': $main.find('.product-image-photo').attr('src')
  340.                 }];
  341.             }
  342.  
  343.             this.productForm = this.element.parents(this.options.selectorProductTile).find('form:first');
  344.             this.inProductList = this.productForm.length > 0;
  345.         },
  346.  
  347.         /**
  348.          * Determine product id and related data
  349.          *
  350.          * @returns {{productId: *, isInProductView: bool}}
  351.          * @private
  352.          */
  353.         _determineProductData: function () {
  354.             // Check if product is in a list of products.
  355.             var productId,
  356.                 isInProductView = false;
  357.  
  358.             productId = this.element.parents('.product-item-details')
  359.                     .find('.price-box.price-final_price').attr('data-product-id');
  360.  
  361.             if (!productId) {
  362.                 // Check individual product.
  363.                 productId = $('[name=product]').val();
  364.                 isInProductView = productId > 0;
  365.             }
  366.  
  367.             return {
  368.                 productId: productId,
  369.                 isInProductView: isInProductView
  370.             };
  371.         },
  372.  
  373.         /**
  374.          * Render controls
  375.          *
  376.          * @private
  377.          */
  378.         _RenderControls: function () {
  379.             var $widget = this,
  380.                 container = this.element,
  381.                 classes = this.options.classes,
  382.                 chooseText = this.options.jsonConfig.chooseText;
  383.  
  384.             $widget.optionsMap = {};
  385.  
  386.             $.each(this.options.jsonConfig.attributes, function () {
  387.                 var item = this,
  388.                     controlLabelId = 'option-label-' + item.code + '-' + item.id,
  389.                     options = $widget._RenderSwatchOptions(item, controlLabelId),
  390.                     select = $widget._RenderSwatchSelect(item, chooseText),
  391.                     input = $widget._RenderFormInput(item),
  392.                     listLabel = '',
  393.                     label = '';
  394.  
  395.                 // Show only swatch controls
  396.                 if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {
  397.                     return;
  398.                 }
  399.  
  400.                 if ($widget.options.enableControlLabel) {
  401.                     label +=
  402.                         '<span id="' + controlLabelId + '" class="' + classes.attributeLabelClass + '">' +
  403.                             item.label +
  404.                         '</span>' +
  405.                         '<span class="' + classes.attributeSelectedOptionLabelClass + '"></span>';
  406.                 }
  407.  
  408.                 if ($widget.inProductList) {
  409.                     $widget.productForm.append(input);
  410.                     input = '';
  411.                     listLabel = 'aria-label="' + item.label + '"';
  412.                 } else {
  413.                     listLabel = 'aria-labelledby="' + controlLabelId + '"';
  414.                 }
  415.  
  416.                 // Create new control
  417.                 container.append(
  418.                     '<div class="' + classes.attributeClass + ' ' + item.code + '" ' +
  419.                          'attribute-code="' + item.code + '" ' +
  420.                          'attribute-id="' + item.id + '">' +
  421.                         label +
  422.                         '<div aria-activedescendant="" ' +
  423.                              'tabindex="0" ' +
  424.                              'aria-invalid="false" ' +
  425.                              'aria-required="true" ' +
  426.                              'role="listbox" ' + listLabel +
  427.                              'class="' + classes.attributeOptionsWrapper + ' clearfix">' +
  428.                             options + select +
  429.                         '</div>' + input +
  430.                     '</div>'
  431.                 );
  432.  
  433.                 $widget.optionsMap[item.id] = {};
  434.  
  435.                 // Aggregate options array to hash (key => value)
  436.                 $.each(item.options, function () {
  437.                     if (this.products.length > 0) {
  438.                         $widget.optionsMap[item.id][this.id] = {
  439.                             price: parseInt(
  440.                                 $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,
  441.                                 10
  442.                             ),
  443.                             products: this.products
  444.                         };
  445.                     }
  446.                 });
  447.             });
  448.  
  449.             // Connect Tooltip
  450.             container
  451.                 .find('[option-type="1"], [option-type="2"], [option-type="0"], [option-type="3"]')
  452.                 .SwatchRendererTooltip();
  453.  
  454.             // Hide all elements below more button
  455.             $('.' + classes.moreButton).nextAll().hide();
  456.  
  457.             // Handle events like click or change
  458.             $widget._EventListener();
  459.  
  460.             // Rewind options
  461.             $widget._Rewind(container);
  462.  
  463.             //Emulate click on all swatches from Request
  464.             $widget._EmulateSelected($.parseQuery());
  465.             $widget._EmulateSelected($widget._getSelectedAttributes());
  466.         },
  467.  
  468.         /**
  469.          * Render swatch options by part of config
  470.          *
  471.          * @param {Object} config
  472.          * @param {String} controlId
  473.          * @returns {String}
  474.          * @private
  475.          */
  476.         _RenderSwatchOptions: function (config, controlId) {
  477.             var optionConfig = this.options.jsonSwatchConfig[config.id],
  478.                 optionClass = this.options.classes.optionClass,
  479.                 moreLimit = parseInt(this.options.numberToShow, 10),
  480.                 moreClass = this.options.classes.moreButton,
  481.                 moreText = this.options.moreButtonText,
  482.                 countAttributes = 0,
  483.                 html = '';
  484.  
  485.             if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {
  486.                 return '';
  487.             }
  488.  
  489.             $.each(config.options, function () {
  490.                 var id,
  491.                     type,
  492.                     value,
  493.                     thumb,
  494.                     swap,
  495.                     label,
  496.                     attr;
  497.  
  498.                 if (!optionConfig.hasOwnProperty(this.id)) {
  499.                     return '';
  500.                 }
  501.  
  502.                 // Add more button
  503.                 if (moreLimit === countAttributes++) {
  504.                     html += '<a href="#" class="' + moreClass + '">' + moreText + '</a>';
  505.                 }
  506.  
  507.                 id = this.id;
  508.                 type = parseInt(optionConfig[id].type, 10);
  509.                 value = optionConfig[id].hasOwnProperty('value') ? optionConfig[id].value : '';
  510.                 thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : '';
  511.                 swap = optionConfig[id].hasOwnProperty('swap') ? optionConfig[id].swap : '';
  512.                 label = this.label ? this.label : '';
  513.                 attr =
  514.                     ' id="' + controlId + '-item-' + id + '"' +
  515.                     ' aria-checked="false"' +
  516.                     ' aria-describedby="' + controlId + '"' +
  517.                     ' tabindex="0"' +
  518.                     ' option-type="' + type + '"' +
  519.                     ' option-id="' + id + '"' +
  520.                     ' option-label="' + label + '"' +
  521.                     ' aria-label="' + label + '"' +
  522.                     ' option-tooltip-thumb="' + thumb + '"' +
  523.                     ' option-tooltip-swap="' + swap + '"' +
  524.                     ' option-tooltip-value="' + value + '"' +
  525.                     ' role="option"';
  526.  
  527.                 if (!this.hasOwnProperty('products') || this.products.length <= 0) {
  528.                     attr += ' option-empty="true"';
  529.                 }
  530.  
  531.                 if (type === 0) {
  532.                     // Text
  533.                     html += '<div class="' + optionClass + ' text" ' + attr + '>' + (value ? value : label) +
  534.                         '</div>';
  535.                 } else if (type === 1) {
  536.                     // Color
  537.                     html += '<div class="' + optionClass + ' color" ' + attr +
  538.                         ' style="background: ' + value +
  539.                         ' no-repeat center; background-size: initial;">' + '' +
  540.                         '</div>';
  541.                 } else if (type === 2) {
  542.                     // Image
  543.                     html += '<div class="' + optionClass + ' image" ' + attr +
  544.                         ' style="background: url(' + value + ') no-repeat center; background-size: initial;">' + '' +
  545.                         '</div>';
  546.                 } else if (type === 3) {
  547.                     // Clear
  548.                     html += '<div class="' + optionClass + '" ' + attr + '></div>';
  549.                 } else {
  550.                     // Default
  551.                     html += '<div class="' + optionClass + '" ' + attr + '>' + label + '</div>';
  552.                 }
  553.             });
  554.  
  555.             return html;
  556.         },
  557.  
  558.         /**
  559.          * Render select by part of config
  560.          *
  561.          * @param {Object} config
  562.          * @param {String} chooseText
  563.          * @returns {String}
  564.          * @private
  565.          */
  566.         _RenderSwatchSelect: function (config, chooseText) {
  567.             var html;
  568.  
  569.             if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {
  570.                 return '';
  571.             }
  572.  
  573.             html =
  574.                 '<select class="' + this.options.classes.selectClass + ' ' + config.code + '">' +
  575.                 '<option value="0" option-id="0">' + chooseText + '</option>';
  576.  
  577.             $.each(config.options, function () {
  578.                 var label = this.label,
  579.                     attr = ' value="' + this.id + '" option-id="' + this.id + '"';
  580.  
  581.                 if (!this.hasOwnProperty('products') || this.products.length <= 0) {
  582.                     attr += ' option-empty="true"';
  583.                 }
  584.  
  585.                 html += '<option ' + attr + '>' + label + '</option>';
  586.             });
  587.  
  588.             html += '</select>';
  589.  
  590.             return html;
  591.         },
  592.  
  593.         /**
  594.          * Input for submit form.
  595.          * This control shouldn't have "type=hidden", "display: none" for validation work :(
  596.          *
  597.          * @param {Object} config
  598.          * @private
  599.          */
  600.         _RenderFormInput: function (config) {
  601.             return '<input class="' + this.options.classes.attributeInput + ' super-attribute-select" ' +
  602.                 'name="super_attribute[' + config.id + ']" ' +
  603.                 'type="text" ' +
  604.                 'value="" ' +
  605.                 'data-selector="super_attribute[' + config.id + ']" ' +
  606.                 'data-validate="{required: true}" ' +
  607.                 'aria-required="true" ' +
  608.                 'aria-invalid="false">';
  609.         },
  610.  
  611.         /**
  612.          * Event listener
  613.          *
  614.          * @private
  615.          */
  616.         _EventListener: function () {
  617.             var $widget = this,
  618.                 options = this.options.classes,
  619.                 target;
  620.  
  621.             $widget.element.on('mouseenter', '.' + options.optionClass, function () {
  622.                 return $widget._OnMouseenter($(this), $widget);
  623.             });
  624.  
  625.             $widget.element.on('mouseleave', '.' + options.optionClass, function () {
  626.                 return $widget._OnMouseleave($(this), $widget);
  627.             });    
  628.  
  629.             $widget.element.on('click', '.' + options.optionClass, function () {
  630.                 return $widget._OnClick($(this), $widget);
  631.             });
  632.  
  633.             $widget.element.on('emulateClick', '.' + options.optionClass, function () {
  634.                 return $widget._OnClick($(this), $widget, 'emulateClick');
  635.             });
  636.  
  637.             $widget.element.on('change', '.' + options.selectClass, function () {
  638.                 return $widget._OnChange($(this), $widget);
  639.             });
  640.  
  641.             $widget.element.on('click', '.' + options.moreButton, function (e) {
  642.                 e.preventDefault();
  643.  
  644.                 return $widget._OnMoreClick($(this));
  645.             });
  646.  
  647.             $widget.element.on('keydown', function (e) {
  648.                 if (e.which === 13) {
  649.                     target = $(e.target);
  650.  
  651.                     if (target.is('.' + options.optionClass)) {
  652.                         return $widget._OnClick(target, $widget);
  653.                     } else if (target.is('.' + options.selectClass)) {
  654.                         return $widget._OnChange(target, $widget);
  655.                     } else if (target.is('.' + options.moreButton)) {
  656.                         e.preventDefault();
  657.  
  658.                         return $widget._OnMoreClick(target);
  659.                     }
  660.                 }
  661.             });
  662.         },
  663.  
  664.         /**
  665.          * Load media gallery using ajax or json config.
  666.          *
  667.          * @param {String|undefined} eventName
  668.          * @private
  669.          */
  670.         _loadMedia: function (eventName) {
  671.             var $main = this.inProductList ?
  672.                     this.element.parents('.product-item-info') :
  673.                     this.element.parents('.column.main'),
  674.                 images;
  675.  
  676.             if (this.options.useAjax) {
  677.                 this._debouncedLoadProductMedia();
  678.             }  else {
  679.                 images = this.options.jsonConfig.images[this.getProduct()];
  680.  
  681.                 if (!images) {
  682.                     images = this.options.mediaGalleryInitial;
  683.                 }
  684.  
  685.                 this.updateBaseImage(images, $main, !this.inProductList, eventName);
  686.             }
  687.         },
  688.  
  689.         /**
  690.          * Event for swatch options
  691.          *
  692.          * @param {Object} $this
  693.          * @param {Object} $widget
  694.          * @param {String|undefined} eventName
  695.          * @private
  696.          */
  697.         _OnClick: function ($this, $widget, eventName) {
  698.             var $parent = $this.parents('.' + $widget.options.classes.attributeClass),
  699.                 $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper),
  700.                 $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass),
  701.                 attributeId = $parent.attr('attribute-id'),
  702.                 $input = $parent.find('.' + $widget.options.classes.attributeInput);
  703.  
  704.             if ($widget.inProductList) {
  705.                 $input = $widget.productForm.find(
  706.                     '.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]'
  707.                 );
  708.             }
  709.  
  710.             if ($this.hasClass('disabled')) {
  711.                 return;
  712.             }
  713.  
  714.             if ($this.hasClass('selected')) {
  715.                 $parent.removeAttr('option-selected').find('.selected').removeClass('selected');
  716.                 $input.val('');
  717.                 $label.text('');
  718.                 $this.attr('aria-checked', false);
  719.             } else {
  720.                 $parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected');
  721.                 $label.text($this.attr('option-label'));
  722.                 $input.val($this.attr('option-id'));
  723.                 $input.attr('data-attr-name', this._getAttributeCodeById(attributeId));
  724.                 $this.addClass('selected');
  725.                 $widget._toggleCheckedAttributes($this, $wrapper);
  726.             }
  727.  
  728.             $widget._Rebuild();
  729.             if ($widget.element.parents($widget.options.selectorProduct)
  730.                     .find(this.options.selectorProductPrice).is(':data(mage-priceBox)')
  731.             ) {
  732.                 $widget._UpdatePrice();
  733.             }
  734.  
  735.             $widget._loadMedia(eventName);
  736.             $input.trigger('change');
  737.         },
  738.  
  739.         _OnMouseenter: function ($this, $widget, eventName) {
  740.             var $optionId = $this.attr('option-id');
  741.             var $parent = $this.parents('.' + $widget.options.classes.attributeClass);
  742.             var attributeId = $parent.attr('attribute-id');
  743.  
  744.             var $main = this.inProductList ?
  745.                     this.element.parents('.product-item-info') :
  746.                     $widget.element.parents('.product-item-info');
  747.             var $mainElement = $main.find('.product-image-photo');
  748.             var $imgageAdditional = $main.find('.imgage-additional');
  749.  
  750.             if ($mainElement.length) {
  751.                 if (typeof  $mainElement.attr('srcset') !== 'undefined') {
  752.                     window.mainImage = $mainElement.attr('srcset');
  753.                 } else {
  754.                     window.mainImage = $mainElement.attr('src');
  755.                 }
  756.                 window.imgageAdditional = $imgageAdditional.attr('srcset');
  757.  
  758.                 var $swapImage = this.options.jsonSwatchConfig[attributeId][$optionId] !== undefined ? this.options.jsonSwatchConfig[attributeId][$optionId].swap : '';
  759.                 if ($swapImage.length) {
  760.                     if (typeof $mainElement.attr('srcset') !== 'undefined') {
  761.                         console.log($mainElement.attr('srcset'))
  762.                         $mainElement.attr('srcset',$swapImage);
  763.                         $imgageAdditional.attr('srcset',$swapImage);
  764.                     } else {
  765.                         $mainElement.attr('src',$swapImage);
  766.                         $imgageAdditional.attr('src',$swapImage);
  767.                     }
  768.                 }
  769.             }
  770.         },
  771.  
  772.         _OnMouseleave: function ($this, $widget, eventName) {
  773.             var $main = this.inProductList ?
  774.                     this.element.parents('.product-item-info') :
  775.                     $widget.element.parents('.product-item-info');
  776.  
  777.             var $mainElement = $main.find('.product-image-photo');
  778.  
  779.             if ($mainElement.length && window.mainImage.length) {
  780.                 if (typeof $mainElement.attr('srcset') !== 'undefined') {
  781.                     $mainElement.attr('srcset',window.mainImage);
  782.                 } else {
  783.                     $mainElement.attr('src',window.mainImage);
  784.                 }
  785.             }
  786.         },
  787.  
  788.         /**
  789.          * Get human readable attribute code (eg. size, color) by it ID from configuration
  790.          *
  791.          * @param {Number} attributeId
  792.          * @returns {*}
  793.          * @private
  794.          */
  795.         _getAttributeCodeById: function (attributeId) {
  796.             var attribute = this.options.jsonConfig.mappedAttributes[attributeId];
  797.  
  798.             return attribute ? attribute.code : attributeId;
  799.         },
  800.  
  801.         /**
  802.          * Toggle accessibility attributes
  803.          *
  804.          * @param {Object} $this
  805.          * @param {Object} $wrapper
  806.          * @private
  807.          */
  808.         _toggleCheckedAttributes: function ($this, $wrapper) {
  809.             $wrapper.attr('aria-activedescendant', $this.attr('id'))
  810.                     .find('.' + this.options.classes.optionClass).attr('aria-checked', false);
  811.             $this.attr('aria-checked', true);
  812.         },
  813.  
  814.         /**
  815.          * Event for select
  816.          *
  817.          * @param {Object} $this
  818.          * @param {Object} $widget
  819.          * @private
  820.          */
  821.         _OnChange: function ($this, $widget) {
  822.             var $parent = $this.parents('.' + $widget.options.classes.attributeClass),
  823.                 attributeId = $parent.attr('attribute-id'),
  824.                 $input = $parent.find('.' + $widget.options.classes.attributeInput);
  825.  
  826.             if ($widget.productForm.length > 0) {
  827.                 $input = $widget.productForm.find(
  828.                     '.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]'
  829.                 );
  830.             }
  831.  
  832.             if ($this.val() > 0) {
  833.                 $parent.attr('option-selected', $this.val());
  834.                 $input.val($this.val());
  835.             } else {
  836.                 $parent.removeAttr('option-selected');
  837.                 $input.val('');
  838.             }
  839.  
  840.             $widget._Rebuild();
  841.             $widget._UpdatePrice();
  842.             $widget._loadMedia();
  843.             $input.trigger('change');
  844.         },
  845.  
  846.         /**
  847.          * Event for more switcher
  848.          *
  849.          * @param {Object} $this
  850.          * @private
  851.          */
  852.         _OnMoreClick: function ($this) {
  853.             $this.nextAll().show();
  854.             $this.blur().remove();
  855.         },
  856.  
  857.         /**
  858.          * Rewind options for controls
  859.          *
  860.          * @private
  861.          */
  862.         _Rewind: function (controls) {
  863.             controls.find('div[option-id], option[option-id]').removeClass('disabled').removeAttr('disabled');
  864.             controls.find('div[option-empty], option[option-empty]').attr('disabled', true).addClass('disabled');
  865.         },
  866.  
  867.         /**
  868.          * Rebuild container
  869.          *
  870.          * @private
  871.          */
  872.         _Rebuild: function () {
  873.             var $widget = this,
  874.                 controls = $widget.element.find('.' + $widget.options.classes.attributeClass + '[attribute-id]'),
  875.                 selected = controls.filter('[option-selected]');
  876.  
  877.             // Enable all options
  878.             $widget._Rewind(controls);
  879.  
  880.             // done if nothing selected
  881.             if (selected.size() <= 0) {
  882.                 return;
  883.             }
  884.  
  885.             // Disable not available options
  886.             controls.each(function () {
  887.                 var $this = $(this),
  888.                     id = $this.attr('attribute-id'),
  889.                     products = $widget._CalcProducts(id);
  890.  
  891.                 if (selected.size() === 1 && selected.first().attr('attribute-id') === id) {
  892.                     return;
  893.                 }
  894.  
  895.                 $this.find('[option-id]').each(function () {
  896.                     var $element = $(this),
  897.                         option = $element.attr('option-id');
  898.  
  899.                     if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option) ||
  900.                         $element.hasClass('selected') ||
  901.                         $element.is(':selected')) {
  902.                         return;
  903.                     }
  904.  
  905.                     if (_.intersection(products, $widget.optionsMap[id][option].products).length <= 0) {
  906.                         $element.attr('disabled', true).addClass('disabled');
  907.                     }
  908.                 });
  909.             });
  910.         },
  911.  
  912.         /**
  913.          * Get selected product list
  914.          *
  915.          * @returns {Array}
  916.          * @private
  917.          */
  918.         _CalcProducts: function ($skipAttributeId) {
  919.             var $widget = this,
  920.                 products = [];
  921.  
  922.             // Generate intersection of products
  923.             $widget.element.find('.' + $widget.options.classes.attributeClass + '[option-selected]').each(function () {
  924.                 var id = $(this).attr('attribute-id'),
  925.                     option = $(this).attr('option-selected');
  926.  
  927.                 if ($skipAttributeId !== undefined && $skipAttributeId === id) {
  928.                     return;
  929.                 }
  930.  
  931.                 if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option)) {
  932.                     return;
  933.                 }
  934.  
  935.                 if (products.length === 0) {
  936.                     products = $widget.optionsMap[id][option].products;
  937.                 } else {
  938.                     products = _.intersection(products, $widget.optionsMap[id][option].products);
  939.                 }
  940.             });
  941.  
  942.             return products;
  943.         },
  944.  
  945.         /**
  946.          * Update total price
  947.          *
  948.          * @private
  949.          */
  950.         _UpdatePrice: function () {
  951.             var $widget = this,
  952.                 $product = $widget.element.parents($widget.options.selectorProduct),
  953.                 $productPrice = $product.find(this.options.selectorProductPrice),
  954.                 options = _.object(_.keys($widget.optionsMap), {}),
  955.                 result,
  956.                 tierPriceHtml;
  957.  
  958.             $widget.element.find('.' + $widget.options.classes.attributeClass + '[option-selected]').each(function () {
  959.                 var attributeId = $(this).attr('attribute-id');
  960.  
  961.                 options[attributeId] = $(this).attr('option-selected');
  962.             });
  963.  
  964.             result = $widget.options.jsonConfig.optionPrices[_.findKey($widget.options.jsonConfig.index, options)];
  965.  
  966.             $productPrice.trigger(
  967.                 'updatePrice',
  968.                 {
  969.                     'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices)
  970.                 }
  971.             );
  972.  
  973.             if (typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount) {
  974.                 $(this.options.slyOldPriceSelector).show();
  975.             } else {
  976.                 $(this.options.slyOldPriceSelector).hide();
  977.             }
  978.  
  979.             if (typeof result != 'undefined' && result.tierPrices.length) {
  980.                 if (this.options.tierPriceTemplate) {
  981.                     tierPriceHtml = mageTemplate(
  982.                         this.options.tierPriceTemplate,
  983.                         {
  984.                             'tierPrices': result.tierPrices,
  985.                             '$t': $t,
  986.                             'currencyFormat': this.options.jsonConfig.currencyFormat,
  987.                             'priceUtils': priceUtils
  988.                         }
  989.                     );
  990.                     $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();
  991.                 }
  992.             } else {
  993.                 $(this.options.tierPriceBlockSelector).hide();
  994.             }
  995.  
  996.             $(this.options.normalPriceLabelSelector).hide();
  997.  
  998.             _.each($('.' + this.options.classes.attributeOptionsWrapper), function (attribute) {
  999.                 if ($(attribute).find('.' + this.options.classes.optionClass + '.selected').length === 0) {
  1000.                     if ($(attribute).find('.' + this.options.classes.selectClass).length > 0) {
  1001.                         _.each($(attribute).find('.' + this.options.classes.selectClass), function (dropdown) {
  1002.                             if ($(dropdown).val() === '0') {
  1003.                                 $(this.options.normalPriceLabelSelector).show();
  1004.                             }
  1005.                         }.bind(this));
  1006.                     } else {
  1007.                         $(this.options.normalPriceLabelSelector).show();
  1008.                     }
  1009.                 }
  1010.             }.bind(this));
  1011.         },
  1012.  
  1013.         /**
  1014.          * Get prices
  1015.          *
  1016.          * @param {Object} newPrices
  1017.          * @param {Object} displayPrices
  1018.          * @returns {*}
  1019.          * @private
  1020.          */
  1021.         _getPrices: function (newPrices, displayPrices) {
  1022.             var $widget = this;
  1023.  
  1024.             if (_.isEmpty(newPrices)) {
  1025.                 newPrices = $widget.options.jsonConfig.prices;
  1026.             }
  1027.  
  1028.             _.each(displayPrices, function (price, code) {
  1029.                 if (newPrices[code]) {
  1030.                     displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount;
  1031.                 }
  1032.             });
  1033.  
  1034.             return displayPrices;
  1035.         },
  1036.  
  1037.         /**
  1038.          * Gets all product media and change current to the needed one
  1039.          *
  1040.          * @private
  1041.          */
  1042.         _LoadProductMedia: function () {
  1043.             var $widget = this,
  1044.                 $this = $widget.element,
  1045.                 productData = this._determineProductData(),
  1046.                 mediaCallData,
  1047.                 mediaCacheKey,
  1048.  
  1049.                 /**
  1050.                  * Processes product media data
  1051.                  *
  1052.                  * @param {Object} data
  1053.                  * @returns void
  1054.                  */
  1055.                 mediaSuccessCallback = function (data) {
  1056.                     if (!(mediaCacheKey in $widget.options.mediaCache)) {
  1057.                         $widget.options.mediaCache[mediaCacheKey] = data;
  1058.                     }
  1059.                     $widget._ProductMediaCallback($this, data, productData.isInProductView);
  1060.                     setTimeout(function () {
  1061.                         $widget._DisableProductMediaLoader($this);
  1062.                     }, 300);
  1063.                 };
  1064.  
  1065.             if (!$widget.options.mediaCallback) {
  1066.                 return;
  1067.             }
  1068.  
  1069.             mediaCallData = {
  1070.                 'product_id': this.getProduct()
  1071.             };
  1072.  
  1073.             mediaCacheKey = JSON.stringify(mediaCallData);
  1074.  
  1075.             if (mediaCacheKey in $widget.options.mediaCache) {
  1076.                 $widget._XhrKiller();
  1077.                 $widget._EnableProductMediaLoader($this);
  1078.                 mediaSuccessCallback($widget.options.mediaCache[mediaCacheKey]);
  1079.             } else {
  1080.                 mediaCallData.isAjax = true;
  1081.                 $widget._XhrKiller();
  1082.                 $widget._EnableProductMediaLoader($this);
  1083.                 $widget.xhr = $.get(
  1084.                     $widget.options.mediaCallback,
  1085.                     mediaCallData,
  1086.                     mediaSuccessCallback,
  1087.                     'json'
  1088.                 ).done(function () {
  1089.                     $widget._XhrKiller();
  1090.                 });
  1091.             }
  1092.         },
  1093.  
  1094.         /**
  1095.          * Enable loader
  1096.          *
  1097.          * @param {Object} $this
  1098.          * @private
  1099.          */
  1100.         _EnableProductMediaLoader: function ($this) {
  1101.             var $widget = this;
  1102.  
  1103.             if ($('body.catalog-product-view').size() > 0) {
  1104.                 $this.parents('.column.main').find('.photo.image')
  1105.                     .addClass($widget.options.classes.loader);
  1106.             } else {
  1107.                 //Category View
  1108.                 $this.parents('.product-item-info').find('.product-image-photo')
  1109.                     .addClass($widget.options.classes.loader);
  1110.             }
  1111.         },
  1112.  
  1113.         /**
  1114.          * Disable loader
  1115.          *
  1116.          * @param {Object} $this
  1117.          * @private
  1118.          */
  1119.         _DisableProductMediaLoader: function ($this) {
  1120.             var $widget = this;
  1121.  
  1122.             if ($('body.catalog-product-view').size() > 0) {
  1123.                 $this.parents('.column.main').find('.photo.image')
  1124.                     .removeClass($widget.options.classes.loader);
  1125.             } else {
  1126.                 //Category View
  1127.                 $this.parents('.product-item-info').find('.product-image-photo')
  1128.                     .removeClass($widget.options.classes.loader);
  1129.             }
  1130.         },
  1131.  
  1132.         /**
  1133.          * Callback for product media
  1134.          *
  1135.          * @param {Object} $this
  1136.          * @param {String} response
  1137.          * @param {Boolean} isInProductView
  1138.          * @private
  1139.          */
  1140.         _ProductMediaCallback: function ($this, response, isInProductView) {
  1141.             var $main = isInProductView ? $this.parents('.column.main') : $this.parents('.product-item-info'),
  1142.                 $widget = this,
  1143.                 images = [],
  1144.  
  1145.                 /**
  1146.                  * Check whether object supported or not
  1147.                  *
  1148.                  * @param {Object} e
  1149.                  * @returns {*|Boolean}
  1150.                  */
  1151.                 support = function (e) {
  1152.                     return e.hasOwnProperty('large') && e.hasOwnProperty('medium') && e.hasOwnProperty('small');
  1153.                 };
  1154.  
  1155.             if (_.size($widget) < 1 || !support(response)) {
  1156.                 this.updateBaseImage(this.options.mediaGalleryInitial, $main, isInProductView);
  1157.  
  1158.                 return;
  1159.             }
  1160.  
  1161.             images.push({
  1162.                 full: response.large,
  1163.                 img: response.medium,
  1164.                 thumb: response.small,
  1165.                 isMain: true
  1166.             });
  1167.  
  1168.             if (response.hasOwnProperty('gallery')) {
  1169.                 $.each(response.gallery, function () {
  1170.                     if (!support(this) || response.large === this.large) {
  1171.                         return;
  1172.                     }
  1173.                     images.push({
  1174.                         full: this.large,
  1175.                         img: this.medium,
  1176.                         thumb: this.small
  1177.                     });
  1178.                 });
  1179.             }
  1180.  
  1181.             this.updateBaseImage(images, $main, isInProductView);
  1182.         },
  1183.  
  1184.         /**
  1185.          * Check if images to update are initial and set their type
  1186.          * @param {Array} images
  1187.          */
  1188.         _setImageType: function (images) {
  1189.             var initial = this.options.mediaGalleryInitial[0].img;
  1190.  
  1191.             if (images[0].img === initial) {
  1192.                 images = $.extend(true, [], this.options.mediaGalleryInitial);
  1193.             } else {
  1194.                 images.map(function (img) {
  1195.                     if (!img.type) {
  1196.                         img.type = 'image';
  1197.                     }
  1198.                 });
  1199.             }
  1200.  
  1201.             return images;
  1202.         },
  1203.  
  1204.         /**
  1205.          * Start update base image process based on event name
  1206.          * @param {Array} images
  1207.          * @param {jQuery} context
  1208.          * @param {Boolean} isInProductView
  1209.          * @param {String|undefined} eventName
  1210.          */
  1211.         updateBaseImage: function (images, context, isInProductView, eventName) {
  1212.             var gallery = context.find(this.options.mediaGallerySelector).data('gallery');
  1213.  
  1214.             if (eventName === undefined) {
  1215.                 this.processUpdateBaseImage(images, context, isInProductView, gallery);
  1216.             } else {
  1217.                 context.find(this.options.mediaGallerySelector).on('gallery:loaded', function (loadedGallery) {
  1218.                     loadedGallery = context.find(this.options.mediaGallerySelector).data('gallery');
  1219.                     this.processUpdateBaseImage(images, context, isInProductView, loadedGallery);
  1220.                 }.bind(this));
  1221.             }
  1222.         },
  1223.  
  1224.         /**
  1225.          * Update [gallery-placeholder] or [product-image-photo]
  1226.          * @param {Array} images
  1227.          * @param {jQuery} context
  1228.          * @param {Boolean} isInProductView
  1229.          * @param {Object} gallery
  1230.          */
  1231.         processUpdateBaseImage: function (images, context, isInProductView, gallery) {
  1232.             var justAnImage = images[0],
  1233.                 initialImages = this.options.mediaGalleryInitial,
  1234.                 imagesToUpdate,
  1235.                 isInitial;
  1236.  
  1237.             if (isInProductView) {
  1238.                 imagesToUpdate = images.length ? this._setImageType($.extend(true, [], images)) : [];
  1239.                 isInitial = _.isEqual(imagesToUpdate, initialImages);
  1240.  
  1241.                 if (this.options.gallerySwitchStrategy === 'prepend' && !isInitial) {
  1242.                     imagesToUpdate = imagesToUpdate.concat(initialImages);
  1243.                 }
  1244.  
  1245.                 imagesToUpdate = this._setImageIndex(imagesToUpdate);
  1246.                 gallery.updateData(imagesToUpdate);
  1247.  
  1248.                 if (isInitial) {
  1249.                     $(this.options.mediaGallerySelector).AddFotoramaVideoEvents();
  1250.                 } else {
  1251.                     $(this.options.mediaGallerySelector).AddFotoramaVideoEvents({
  1252.                         selectedOption: this.getProduct(),
  1253.                         dataMergeStrategy: this.options.gallerySwitchStrategy
  1254.                     });
  1255.                 }
  1256.  
  1257.                 gallery.first();
  1258.  
  1259.             } else if (justAnImage && justAnImage.img) {
  1260.                 context.find('.product-image-photo').attr('src', justAnImage.img);
  1261.             }
  1262.         },
  1263.  
  1264.         /**
  1265.          * Set correct indexes for image set.
  1266.          *
  1267.          * @param {Array} images
  1268.          * @private
  1269.          */
  1270.         _setImageIndex: function (images) {
  1271.             var length = images.length,
  1272.                 i;
  1273.  
  1274.             for (i = 0; length > i; i++) {
  1275.                 images[i].i = i + 1;
  1276.             }
  1277.  
  1278.             return images;
  1279.         },
  1280.  
  1281.         /**
  1282.          * Kill doubled AJAX requests
  1283.          *
  1284.          * @private
  1285.          */
  1286.         _XhrKiller: function () {
  1287.             var $widget = this;
  1288.  
  1289.             if ($widget.xhr !== undefined && $widget.xhr !== null) {
  1290.                 $widget.xhr.abort();
  1291.                 $widget.xhr = null;
  1292.             }
  1293.         },
  1294.  
  1295.         /**
  1296.          * Emulate mouse click on all swatches that should be selected
  1297.          * @param {Object} [selectedAttributes]
  1298.          * @private
  1299.          */
  1300.         _EmulateSelected: function (selectedAttributes) {
  1301.             $.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {
  1302.                 this.element.find('.' + this.options.classes.attributeClass +
  1303.                     '[attribute-code="' + attributeCode + '"] [option-id="' + optionId + '"]').trigger('click');
  1304.             }, this));
  1305.         },
  1306.  
  1307.         /**
  1308.          * Emulate mouse click or selection change on all swatches that should be selected
  1309.          * @param {Object} [selectedAttributes]
  1310.          * @param {String} triggerClick
  1311.          * @private
  1312.          */
  1313.         _EmulateSelectedByAttributeId: function (selectedAttributes, triggerClick) {
  1314.             $.each(selectedAttributes, $.proxy(function (attributeId, optionId) {
  1315.                 var elem = this.element.find('.' + this.options.classes.attributeClass +
  1316.                     '[attribute-id="' + attributeId + '"] [option-id="' + optionId + '"]'),
  1317.                     parentInput = elem.parent();
  1318.  
  1319.                 if (triggerClick === null || triggerClick === '') {
  1320.                     triggerClick = 'click';
  1321.                 }
  1322.  
  1323.                 if (elem.hasClass('selected')) {
  1324.                     return;
  1325.                 }
  1326.  
  1327.                 if (parentInput.hasClass(this.options.classes.selectClass)) {
  1328.                     parentInput.val(optionId);
  1329.                     parentInput.trigger('change');
  1330.                 } else {
  1331.                     elem.trigger(triggerClick);
  1332.                 }
  1333.             }, this));
  1334.         },
  1335.  
  1336.         /**
  1337.          * Get default options values settings with either URL query parameters
  1338.          * @private
  1339.          */
  1340.         _getSelectedAttributes: function () {
  1341.             var hashIndex = window.location.href.indexOf('#'),
  1342.                 selectedAttributes = {},
  1343.                 params;
  1344.  
  1345.             if (hashIndex !== -1) {
  1346.                 params = $.parseQuery(window.location.href.substr(hashIndex + 1));
  1347.  
  1348.                 selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) {
  1349.                     var attribute = this.options.jsonConfig.mappedAttributes[attributeId];
  1350.  
  1351.                     return attribute ? attribute.code : attributeId;
  1352.                 }.bind(this)));
  1353.             }
  1354.  
  1355.             return selectedAttributes;
  1356.         },
  1357.  
  1358.         /**
  1359.          * Callback which fired after gallery gets initialized.
  1360.          *
  1361.          * @param {HTMLElement} element - DOM element associated with a gallery.
  1362.          */
  1363.         _onGalleryLoaded: function (element) {
  1364.             var galleryObject = element.data('gallery');
  1365.  
  1366.             this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();
  1367.         },
  1368.  
  1369.         /**
  1370.          * Sets mediaCache for cases when jsonConfig contains preSelectedGallery on layered navigation result pages
  1371.          *
  1372.          * @private
  1373.          */
  1374.         _setPreSelectedGallery: function () {
  1375.             var mediaCallData;
  1376.  
  1377.             if (this.options.jsonConfig.preSelectedGallery) {
  1378.                 mediaCallData = {
  1379.                     'product_id': this.getProduct()
  1380.                 };
  1381.  
  1382.                 this.options.mediaCache[JSON.stringify(mediaCallData)] = this.options.jsonConfig.preSelectedGallery;
  1383.             }
  1384.         }
  1385.     });
  1386.  
  1387.     return $.mage.SwatchRenderer;
  1388. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement