Plugin Directory

Changeset 3451713


Ignore:
Timestamp:
02/02/2026 05:09:45 AM (8 weeks ago)
Author:
hasthemes
Message:

Update to version 1.4.10 from GitHub

Location:
swatchly
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • swatchly/tags/1.4.10/assets/js/frontend.js

    r3419310 r3451713  
    410410                const product = builderCompat.findProductContainer($(event.target))[0];
    411411                if (!product) return;
    412                 const productLink = product.querySelector('.woocommerce-loop-product__link') || product.querySelector('.bundled_product_permalink') || product.querySelector('a[href*="/product/"]') || product.querySelector('a'),
    413                     links = product.querySelectorAll('a');
     412
     413                // Get the product URL from data attribute (theme-agnostic approach)
     414                const variationForm = product.querySelector('.swatchly_loop_variation_form') ||
     415                    product.querySelector('.variations_form') ||
     416                    event.target.closest('.swatchly_loop_variation_form');
     417                const productUrlFromData = variationForm ? variationForm.getAttribute('data-product_url') : null;
     418
     419                // Fallback to selector-based approach for backwards compatibility
     420                const productLink = product.querySelector('.woocommerce-loop-product__link') ||
     421                    product.querySelector('.bundled_product_permalink') ||
     422                    product.querySelector('a[href*="/product/"]') ||
     423                    product.querySelector('a');
     424
     425                // Determine the product URL pathname
     426                let productUrlPathname = null;
     427                if (productUrlFromData) {
     428                    try {
     429                        productUrlPathname = new URL(productUrlFromData).pathname;
     430                    } catch (e) {
     431                        // Invalid URL from data attribute, will use fallback
     432                    }
     433                }
     434                if (!productUrlPathname && productLink) {
     435                    try {
     436                        productUrlPathname = new URL(productLink.href).pathname;
     437                    } catch (e) {
     438                        // Invalid URL from link
     439                    }
     440                }
     441
     442                const links = product.querySelectorAll('a');
    414443                Array.from(links).forEach(link => {
    415444                    if(!$(link)?.attr('href')) return;
    416                     const url = new URL(link.href),
    417                         productUrl = new URL(productLink.href);
    418                     if(url.pathname === productUrl.pathname || url.href.indexOf('/product/') !== -1) {
    419                         if(value) {
    420                             if(!url.searchParams.get(paramName)) {
    421                                 url.searchParams.append(paramName, value);
     445                    try {
     446                        const url = new URL(link.href);
     447                        // Match links by comparing pathname OR if link contains /product/ (backwards compat)
     448                        const shouldUpdate = productUrlPathname
     449                            ? (url.pathname === productUrlPathname)
     450                            : (url.href.indexOf('/product/') !== -1);
     451
     452                        if(shouldUpdate) {
     453                            if(value) {
     454                                if(!url.searchParams.get(paramName)) {
     455                                    url.searchParams.append(paramName, value);
     456                                } else {
     457                                    url.searchParams.set(paramName, value)
     458                                }
    422459                            } else {
    423                                 url.searchParams.set(paramName, value)
     460                                url.searchParams.delete(paramName)
    424461                            }
    425                         } else {
    426                             url.searchParams.delete(paramName)
     462                            link.href = url.toString();
    427463                        }
    428                         link.href = url.toString();
     464                    } catch (e) {
     465                        // Ignore invalid URLs
    429466                    }
    430467                });
     
    609646                                const isInProductLoop = e.target.closest('.products') && !e.target.closest('.summary');
    610647                                const isBundleProduct = e.target.closest('.bundled_product');
    611                                 if ((isInProductLoop || isBundleProduct) && !e.target.closest(QUICKVIEW_SELECTORS.join(', '))) {
    612                                    
     648                                // Fallback: check if inside swatchly_loop_variation_form (works regardless of theme structure)
     649                                const isInSwatchlyLoopForm = e.target.closest('.swatchly_loop_variation_form') && !e.target.closest('.summary');
     650
     651                                if ((isInProductLoop || isBundleProduct || isInSwatchlyLoopForm) && !e.target.closest(QUICKVIEW_SELECTORS.join(', '))) {
    613652                                    loopVariationUrlParams({
    614653                                        event: e,
  • swatchly/tags/1.4.10/includes/Frontend/Woo_Config.php

    r3385177 r3451713  
    701701        $variations_json = wp_json_encode( $available_variations );
    702702        $variations_attr = function_exists( 'wc_esc_json' ) ? wc_esc_json( $variations_json ) : _wp_specialchars( $variations_json, ENT_QUOTES, 'UTF-8', true );
     703        $product_url     = get_permalink( $product->get_id() );
    703704
    704705        $html = '';
    705706        ob_start();
    706707        ?>
    707             <form class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
     708            <form class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_url="<?php echo esc_url( $product_url ); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
    708709
    709710                <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
     
    772773        $variations_json = wp_json_encode( $available_variations );
    773774        $variations_attr = function_exists( 'wc_esc_json' ) ? wc_esc_json( $variations_json ) : _wp_specialchars( $variations_json, ENT_QUOTES, 'UTF-8', true );
     775        $product_url     = get_permalink( $product->get_id() );
    774776        ?>
    775             <div class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
     777            <div class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_url="<?php echo esc_url( $product_url ); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
    776778
    777779                <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
  • swatchly/tags/1.4.10/swatchly.php

    r3419310 r3451713  
    44 * Plugin URI:  https://plugindemo.hasthemes.com/swatchly/
    55 * Description: Variation Swatches for WooCommerce Products
    6  * Version:     1.4.9
     6 * Version:     1.4.10
    77 * Author:      HasThemes
    88 * Author URI:  https://hasthemes.com
     
    3030     * @since 1.0.0
    3131     */
    32     public $version = '1.4.9';
     32    public $version = '1.4.10';
    3333
    3434    /**
  • swatchly/trunk/assets/js/frontend.js

    r3419310 r3451713  
    410410                const product = builderCompat.findProductContainer($(event.target))[0];
    411411                if (!product) return;
    412                 const productLink = product.querySelector('.woocommerce-loop-product__link') || product.querySelector('.bundled_product_permalink') || product.querySelector('a[href*="/product/"]') || product.querySelector('a'),
    413                     links = product.querySelectorAll('a');
     412
     413                // Get the product URL from data attribute (theme-agnostic approach)
     414                const variationForm = product.querySelector('.swatchly_loop_variation_form') ||
     415                    product.querySelector('.variations_form') ||
     416                    event.target.closest('.swatchly_loop_variation_form');
     417                const productUrlFromData = variationForm ? variationForm.getAttribute('data-product_url') : null;
     418
     419                // Fallback to selector-based approach for backwards compatibility
     420                const productLink = product.querySelector('.woocommerce-loop-product__link') ||
     421                    product.querySelector('.bundled_product_permalink') ||
     422                    product.querySelector('a[href*="/product/"]') ||
     423                    product.querySelector('a');
     424
     425                // Determine the product URL pathname
     426                let productUrlPathname = null;
     427                if (productUrlFromData) {
     428                    try {
     429                        productUrlPathname = new URL(productUrlFromData).pathname;
     430                    } catch (e) {
     431                        // Invalid URL from data attribute, will use fallback
     432                    }
     433                }
     434                if (!productUrlPathname && productLink) {
     435                    try {
     436                        productUrlPathname = new URL(productLink.href).pathname;
     437                    } catch (e) {
     438                        // Invalid URL from link
     439                    }
     440                }
     441
     442                const links = product.querySelectorAll('a');
    414443                Array.from(links).forEach(link => {
    415444                    if(!$(link)?.attr('href')) return;
    416                     const url = new URL(link.href),
    417                         productUrl = new URL(productLink.href);
    418                     if(url.pathname === productUrl.pathname || url.href.indexOf('/product/') !== -1) {
    419                         if(value) {
    420                             if(!url.searchParams.get(paramName)) {
    421                                 url.searchParams.append(paramName, value);
     445                    try {
     446                        const url = new URL(link.href);
     447                        // Match links by comparing pathname OR if link contains /product/ (backwards compat)
     448                        const shouldUpdate = productUrlPathname
     449                            ? (url.pathname === productUrlPathname)
     450                            : (url.href.indexOf('/product/') !== -1);
     451
     452                        if(shouldUpdate) {
     453                            if(value) {
     454                                if(!url.searchParams.get(paramName)) {
     455                                    url.searchParams.append(paramName, value);
     456                                } else {
     457                                    url.searchParams.set(paramName, value)
     458                                }
    422459                            } else {
    423                                 url.searchParams.set(paramName, value)
     460                                url.searchParams.delete(paramName)
    424461                            }
    425                         } else {
    426                             url.searchParams.delete(paramName)
     462                            link.href = url.toString();
    427463                        }
    428                         link.href = url.toString();
     464                    } catch (e) {
     465                        // Ignore invalid URLs
    429466                    }
    430467                });
     
    609646                                const isInProductLoop = e.target.closest('.products') && !e.target.closest('.summary');
    610647                                const isBundleProduct = e.target.closest('.bundled_product');
    611                                 if ((isInProductLoop || isBundleProduct) && !e.target.closest(QUICKVIEW_SELECTORS.join(', '))) {
    612                                    
     648                                // Fallback: check if inside swatchly_loop_variation_form (works regardless of theme structure)
     649                                const isInSwatchlyLoopForm = e.target.closest('.swatchly_loop_variation_form') && !e.target.closest('.summary');
     650
     651                                if ((isInProductLoop || isBundleProduct || isInSwatchlyLoopForm) && !e.target.closest(QUICKVIEW_SELECTORS.join(', '))) {
    613652                                    loopVariationUrlParams({
    614653                                        event: e,
  • swatchly/trunk/includes/Frontend/Woo_Config.php

    r3385177 r3451713  
    701701        $variations_json = wp_json_encode( $available_variations );
    702702        $variations_attr = function_exists( 'wc_esc_json' ) ? wc_esc_json( $variations_json ) : _wp_specialchars( $variations_json, ENT_QUOTES, 'UTF-8', true );
     703        $product_url     = get_permalink( $product->get_id() );
    703704
    704705        $html = '';
    705706        ob_start();
    706707        ?>
    707             <form class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
     708            <form class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_url="<?php echo esc_url( $product_url ); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
    708709
    709710                <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
     
    772773        $variations_json = wp_json_encode( $available_variations );
    773774        $variations_attr = function_exists( 'wc_esc_json' ) ? wc_esc_json( $variations_json ) : _wp_specialchars( $variations_json, ENT_QUOTES, 'UTF-8', true );
     775        $product_url     = get_permalink( $product->get_id() );
    774776        ?>
    775             <div class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
     777            <div class="swatchly_loop_variation_form variations_form swatchly_align_<?php echo esc_attr($align); ?>" data-product_variations="<?php echo esc_attr( $variations_json ); ?>" data-product_id="<?php echo esc_attr(absint( $product->get_id() )); ?>" data-product_url="<?php echo esc_url( $product_url ); ?>" data-product_variations="<?php echo esc_attr($variations_attr); // WPCS: XSS ok. ?>">
    776778
    777779                <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
  • swatchly/trunk/swatchly.php

    r3419310 r3451713  
    44 * Plugin URI:  https://plugindemo.hasthemes.com/swatchly/
    55 * Description: Variation Swatches for WooCommerce Products
    6  * Version:     1.4.9
     6 * Version:     1.4.10
    77 * Author:      HasThemes
    88 * Author URI:  https://hasthemes.com
     
    3030     * @since 1.0.0
    3131     */
    32     public $version = '1.4.9';
     32    public $version = '1.4.10';
    3333
    3434    /**
Note: See TracChangeset for help on using the changeset viewer.