Plugin Directory

Changeset 3452321


Ignore:
Timestamp:
02/02/2026 06:17:32 PM (3 weeks ago)
Author:
spelhubben
Message:

Update to version 1.9.8 from GitHub

Location:
spelhubben-weather
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • spelhubben-weather/tags/1.9.8/assets/map.js

    r3435228 r3452321  
    3232  function initMap(el){
    3333    if (el.dataset.inited) return;
     34
     35    // Retry guard (prevents infinite console spam if Leaflet never loads)
     36    const tries = parseInt(el.dataset.svvLeafletTries || '0', 10);
     37    if (tries > 20) { // ~10s total with 500ms interval
     38      console.error('Leaflet failed to load after multiple retries. Giving up for element:', el);
     39      el.dataset.svvLeafletFailed = '1';
     40      el.dataset.inited = '1'; // lock
     41      return;
     42    }
     43
    3444    el.dataset.inited = '1';
    3545
     
    3747    if (typeof L === 'undefined' || !L.map) {
    3848      console.warn('Leaflet not loaded yet, retrying...', el);
    39       // Try again in a moment
    4049      setTimeout(() => {
     50        el.dataset.svvLeafletTries = String(tries + 1);
    4151        delete el.dataset.inited;
    4252        initMap(el);
     
    7080      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom:19 }).addTo(map);
    7181
    72       // NOTE: No L.marker here — the pin is never placed.
    7382      setTimeout(()=>map.invalidateSize(), 200);
    7483    } catch (e) {
     
    8392    if (!maps.length) return;
    8493
    85     // If IntersectionObserver supported, observe and init when visible
    8694    if ('IntersectionObserver' in window) {
    8795      const io = new IntersectionObserver(function(entries){
     
    95103
    96104      maps.forEach(function(m){
    97         // If already inited, skip
    98105        if (m.dataset.inited) return;
    99106        io.observe(m);
     
    102109    }
    103110
    104     // Fallback: initialize immediately (keeps previous behavior)
    105111    maps.forEach(initMap);
    106112  }
     
    116122    if (!('ResizeObserver' in window)) return;
    117123
    118     // Support both old (.sv-vader) and new (.spelhubben-weather) container classes
    119124    document.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]').forEach(function(card){
    120125      if (card._svvObserved) return;
     
    136141      const ro = new ResizeObserver(debounce(applyScale, 60));
    137142      ro.observe(card);
    138      
    139       // Store observer reference for cleanup
     143
    140144      card._svvResizeObserver = ro;
    141145    });
     
    146150  } else { attachRO(); }
    147151
    148   // Single persistent MutationObserver instead of creating new ones
    149152  const mutationObserver = new MutationObserver(function(mutations){
    150     // Cleanup removed cards
    151153    mutations.forEach(function(m){
    152154      if (m.removedNodes.length) {
    153155        m.removedNodes.forEach(function(node){
    154           if (node.nodeType === 1) { // Element node
     156          if (node.nodeType === 1) {
    155157            const cards = node.querySelectorAll ? node.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]') : [];
    156158            cards.forEach(function(card){
     
    171173    attachRO();
    172174  });
    173  
     175
    174176  mutationObserver.observe(document.documentElement, { childList:true, subtree: true });
    175177})();
  • spelhubben-weather/tags/1.9.8/includes/class-assets.php

    r3438808 r3452321  
    77    /**
    88     * Enqueue public-facing assets (CSS/JS) for the frontend.
    9      * Only loads core stylesheet; Leaflet/map assets are loaded conditionally via filters.
     9     * Only loads core stylesheet; Leaflet/map assets are loaded conditionally.
    1010     */
    1111    public function enqueue_public_assets() {
     12
    1213        // Core plugin stylesheet - register, enqueue only when used on the page
    1314        // Prefer minified file when present and WP_DEBUG is not enabled
    1415        $style_file = 'assets/style.css';
    15         $base_dir = defined('SV_VADER_PATH') ? rtrim(SV_VADER_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : dirname(__DIR__) . DIRECTORY_SEPARATOR;
     16        $base_dir = defined('SV_VADER_PATH')
     17            ? rtrim(SV_VADER_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR
     18            : dirname(__DIR__) . DIRECTORY_SEPARATOR;
     19
    1620        if ( ! ( defined('WP_DEBUG') && WP_DEBUG ) ) {
    1721            if ( file_exists( $base_dir . 'assets' . DIRECTORY_SEPARATOR . 'style.min.css' ) ) {
     
    1923            }
    2024        }
     25
    2126        wp_register_style('sv-vader-style', SV_VADER_URL . $style_file, [], SV_VADER_VER);
    2227
    23         // Register Leaflet and map assets but don't auto-enqueue
    24         // They will be enqueued conditionally via has_shortcode() or block detection
    25         wp_register_style('leaflet-css', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.css', [], '1.9.4');
    26         wp_register_script('leaflet-js', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.js', [], '1.9.4', true);
     28        /**
     29         * IMPORTANT:
     30         * Use unique handles for Leaflet to avoid collisions with themes/other plugins.
     31         * Live sites often already register "leaflet-js" which can break our dependency chain.
     32         */
     33        wp_register_style('svv-leaflet-css', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.css', [], '1.9.4');
     34        wp_register_script('svv-leaflet-js', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.js', [], '1.9.4', true);
     35
    2736        // Prefer minified map script when available
    2837        $map_file = 'assets/map.js';
     
    3039            $map_file = 'assets/map.min.js';
    3140        }
    32         wp_register_script('sv-vader-map', SV_VADER_URL . $map_file, ['leaflet-js'], SV_VADER_VER, true);
     41
     42        // Map depends on *our* Leaflet handle (svv-leaflet-js)
     43        wp_register_script('sv-vader-map', SV_VADER_URL . $map_file, ['svv-leaflet-js'], SV_VADER_VER, true);
     44
    3345        // Small helper to rotate wind direction arrows when inline styles are stripped
    3446        wp_register_script('sv-vader-wind', SV_VADER_URL . 'assets/wind.js', [], SV_VADER_VER, true);
     
    4052        }
    4153
    42         // Localized data for JS will be added only when the map script is enqueued
    43 
    4454        // Load Leaflet assets only if shortcode is present or Gutenberg block is used
    4555        if ( $this->should_load_leaflet() ) {
    46             wp_enqueue_style('leaflet-css');
    47             wp_enqueue_script('leaflet-js');
     56            wp_enqueue_style('svv-leaflet-css');
     57            wp_enqueue_script('svv-leaflet-js');
    4858            wp_enqueue_script('sv-vader-map');
    4959
     
    5363            ]);
    5464
    55             // Add defer attribute to Leaflet/map to avoid render-blocking
    56             add_filter('script_loader_tag', [$this, 'add_script_defer_attribute'], 10, 3);
     65            /**
     66             * NOTE:
     67             * Do NOT force "defer" here. Defer/Delay/Async is best left to caching/optimization plugins,
     68             * otherwise we risk Leaflet loading after our map script on some live setups.
     69             */
    5770        }
    5871    }
     
    6275     */
    6376    private function should_load_leaflet() {
    64         global $post, $wp_registered_sidebars;
     77        global $post;
    6578
    6679        // Check for shortcodes in post content
     
    116129        return false;
    117130    }
    118 
    119     /**
    120      * Add 'defer' attribute for heavy frontend scripts so they don't block rendering.
    121      */
    122     public function add_script_defer_attribute($tag, $handle, $src) {
    123         // Only defer these handles
    124         $defer = ['leaflet-js', 'sv-vader-map'];
    125         if ( in_array($handle, $defer, true) ) {
    126             return str_replace(' src', ' defer src', $tag);
    127         }
    128         return $tag;
    129     }
    130131}
  • spelhubben-weather/tags/1.9.8/readme.txt

    r3450708 r3452321  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.9.7
     7Stable tag: 1.9.8
    88Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU
    99
     
    9292
    9393If `lat` and `lon` are provided they take precedence. Otherwise the plugin geocodes the `place` string (e.g. `place="Umeå"`). Set a global default place in settings.
    94 
     94rontend assets are registered
    9595= What fields can I show/hide? =
    9696Use `show="temp,wind,icon"` (comma separated). Defaults are set in settings. Add `wind_dir` to show wind direction arrow and label.
     
    213213
    214214== Changelog ==
     215- = 1.9.8 =
     216- **Fixed:** Fixed an issue where the Leaflet map could fail to load on live/optimized sites due to script handle conflicts with themes or other plugins.
     217- **Improved:** Renamed Leaflet asset handles to unique, plugin-specific names to prevent collisions and ensure correct dependency resolution.
     218- **Improved:** Removed forced defer handling for Leaflet/map scripts to avoid broken load order when caching/optimization plugins are active.
     219- **Improved:** Improved map initialization logic to prevent infinite retry loops and reduce console spam when Leaflet isn’t available.
     220- **Improved:** Kept Leaflet/map assets conditionally loaded only on pages where the widget/block/shortcode is actually rendered.
     221
    215222- = 1.9.7 =
    216223- **Experimental:** Tide support added for testing — opt-in feature. Adds support for WorldTides (API key), NOAA (US-only), and a configurable custom endpoint. Shortcode support via `extras="tides"` or `tides="1"`. Admin visibility can be toggled while rolling out to selected users. Responses are cached; configure TTL in Settings.
  • spelhubben-weather/tags/1.9.8/spelhubben-weather.php

    r3450708 r3452321  
    33 * Plugin Name: Spelhubben Weather
    44 * Description: Displays current weather and an optional forecast with a simple consensus across providers (Open-Meteo, SMHI, Yr/MET Norway). Supports shortcode + Gutenberg block + classic widget. Optional Leaflet map, subtle animations, daily forecast, and multiple layouts.
    5  * Version: 1.9.7
     5 * Version: 1.9.8
    66 * Author: Spelhubben
    77 * Text Domain: spelhubben-weather
     
    2424// ── Constants (kept for backward compatibility).
    2525    if ( ! defined( 'SV_VADER_VER' ) ) {
    26         define( 'SV_VADER_VER', '1.9.7' );
     26        define( 'SV_VADER_VER', '1.9.8' );
    2727    }
    2828if ( ! defined( 'SV_VADER_DIR' ) ) {
  • spelhubben-weather/trunk/assets/map.js

    r3435228 r3452321  
    3232  function initMap(el){
    3333    if (el.dataset.inited) return;
     34
     35    // Retry guard (prevents infinite console spam if Leaflet never loads)
     36    const tries = parseInt(el.dataset.svvLeafletTries || '0', 10);
     37    if (tries > 20) { // ~10s total with 500ms interval
     38      console.error('Leaflet failed to load after multiple retries. Giving up for element:', el);
     39      el.dataset.svvLeafletFailed = '1';
     40      el.dataset.inited = '1'; // lock
     41      return;
     42    }
     43
    3444    el.dataset.inited = '1';
    3545
     
    3747    if (typeof L === 'undefined' || !L.map) {
    3848      console.warn('Leaflet not loaded yet, retrying...', el);
    39       // Try again in a moment
    4049      setTimeout(() => {
     50        el.dataset.svvLeafletTries = String(tries + 1);
    4151        delete el.dataset.inited;
    4252        initMap(el);
     
    7080      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom:19 }).addTo(map);
    7181
    72       // NOTE: No L.marker here — the pin is never placed.
    7382      setTimeout(()=>map.invalidateSize(), 200);
    7483    } catch (e) {
     
    8392    if (!maps.length) return;
    8493
    85     // If IntersectionObserver supported, observe and init when visible
    8694    if ('IntersectionObserver' in window) {
    8795      const io = new IntersectionObserver(function(entries){
     
    95103
    96104      maps.forEach(function(m){
    97         // If already inited, skip
    98105        if (m.dataset.inited) return;
    99106        io.observe(m);
     
    102109    }
    103110
    104     // Fallback: initialize immediately (keeps previous behavior)
    105111    maps.forEach(initMap);
    106112  }
     
    116122    if (!('ResizeObserver' in window)) return;
    117123
    118     // Support both old (.sv-vader) and new (.spelhubben-weather) container classes
    119124    document.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]').forEach(function(card){
    120125      if (card._svvObserved) return;
     
    136141      const ro = new ResizeObserver(debounce(applyScale, 60));
    137142      ro.observe(card);
    138      
    139       // Store observer reference for cleanup
     143
    140144      card._svvResizeObserver = ro;
    141145    });
     
    146150  } else { attachRO(); }
    147151
    148   // Single persistent MutationObserver instead of creating new ones
    149152  const mutationObserver = new MutationObserver(function(mutations){
    150     // Cleanup removed cards
    151153    mutations.forEach(function(m){
    152154      if (m.removedNodes.length) {
    153155        m.removedNodes.forEach(function(node){
    154           if (node.nodeType === 1) { // Element node
     156          if (node.nodeType === 1) {
    155157            const cards = node.querySelectorAll ? node.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]') : [];
    156158            cards.forEach(function(card){
     
    171173    attachRO();
    172174  });
    173  
     175
    174176  mutationObserver.observe(document.documentElement, { childList:true, subtree: true });
    175177})();
  • spelhubben-weather/trunk/includes/class-assets.php

    r3438808 r3452321  
    77    /**
    88     * Enqueue public-facing assets (CSS/JS) for the frontend.
    9      * Only loads core stylesheet; Leaflet/map assets are loaded conditionally via filters.
     9     * Only loads core stylesheet; Leaflet/map assets are loaded conditionally.
    1010     */
    1111    public function enqueue_public_assets() {
     12
    1213        // Core plugin stylesheet - register, enqueue only when used on the page
    1314        // Prefer minified file when present and WP_DEBUG is not enabled
    1415        $style_file = 'assets/style.css';
    15         $base_dir = defined('SV_VADER_PATH') ? rtrim(SV_VADER_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : dirname(__DIR__) . DIRECTORY_SEPARATOR;
     16        $base_dir = defined('SV_VADER_PATH')
     17            ? rtrim(SV_VADER_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR
     18            : dirname(__DIR__) . DIRECTORY_SEPARATOR;
     19
    1620        if ( ! ( defined('WP_DEBUG') && WP_DEBUG ) ) {
    1721            if ( file_exists( $base_dir . 'assets' . DIRECTORY_SEPARATOR . 'style.min.css' ) ) {
     
    1923            }
    2024        }
     25
    2126        wp_register_style('sv-vader-style', SV_VADER_URL . $style_file, [], SV_VADER_VER);
    2227
    23         // Register Leaflet and map assets but don't auto-enqueue
    24         // They will be enqueued conditionally via has_shortcode() or block detection
    25         wp_register_style('leaflet-css', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.css', [], '1.9.4');
    26         wp_register_script('leaflet-js', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.js', [], '1.9.4', true);
     28        /**
     29         * IMPORTANT:
     30         * Use unique handles for Leaflet to avoid collisions with themes/other plugins.
     31         * Live sites often already register "leaflet-js" which can break our dependency chain.
     32         */
     33        wp_register_style('svv-leaflet-css', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.css', [], '1.9.4');
     34        wp_register_script('svv-leaflet-js', SV_VADER_URL . 'assets/vendor/leaflet/leaflet.js', [], '1.9.4', true);
     35
    2736        // Prefer minified map script when available
    2837        $map_file = 'assets/map.js';
     
    3039            $map_file = 'assets/map.min.js';
    3140        }
    32         wp_register_script('sv-vader-map', SV_VADER_URL . $map_file, ['leaflet-js'], SV_VADER_VER, true);
     41
     42        // Map depends on *our* Leaflet handle (svv-leaflet-js)
     43        wp_register_script('sv-vader-map', SV_VADER_URL . $map_file, ['svv-leaflet-js'], SV_VADER_VER, true);
     44
    3345        // Small helper to rotate wind direction arrows when inline styles are stripped
    3446        wp_register_script('sv-vader-wind', SV_VADER_URL . 'assets/wind.js', [], SV_VADER_VER, true);
     
    4052        }
    4153
    42         // Localized data for JS will be added only when the map script is enqueued
    43 
    4454        // Load Leaflet assets only if shortcode is present or Gutenberg block is used
    4555        if ( $this->should_load_leaflet() ) {
    46             wp_enqueue_style('leaflet-css');
    47             wp_enqueue_script('leaflet-js');
     56            wp_enqueue_style('svv-leaflet-css');
     57            wp_enqueue_script('svv-leaflet-js');
    4858            wp_enqueue_script('sv-vader-map');
    4959
     
    5363            ]);
    5464
    55             // Add defer attribute to Leaflet/map to avoid render-blocking
    56             add_filter('script_loader_tag', [$this, 'add_script_defer_attribute'], 10, 3);
     65            /**
     66             * NOTE:
     67             * Do NOT force "defer" here. Defer/Delay/Async is best left to caching/optimization plugins,
     68             * otherwise we risk Leaflet loading after our map script on some live setups.
     69             */
    5770        }
    5871    }
     
    6275     */
    6376    private function should_load_leaflet() {
    64         global $post, $wp_registered_sidebars;
     77        global $post;
    6578
    6679        // Check for shortcodes in post content
     
    116129        return false;
    117130    }
    118 
    119     /**
    120      * Add 'defer' attribute for heavy frontend scripts so they don't block rendering.
    121      */
    122     public function add_script_defer_attribute($tag, $handle, $src) {
    123         // Only defer these handles
    124         $defer = ['leaflet-js', 'sv-vader-map'];
    125         if ( in_array($handle, $defer, true) ) {
    126             return str_replace(' src', ' defer src', $tag);
    127         }
    128         return $tag;
    129     }
    130131}
  • spelhubben-weather/trunk/readme.txt

    r3450708 r3452321  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.9.7
     7Stable tag: 1.9.8
    88Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU
    99
     
    9292
    9393If `lat` and `lon` are provided they take precedence. Otherwise the plugin geocodes the `place` string (e.g. `place="Umeå"`). Set a global default place in settings.
    94 
     94rontend assets are registered
    9595= What fields can I show/hide? =
    9696Use `show="temp,wind,icon"` (comma separated). Defaults are set in settings. Add `wind_dir` to show wind direction arrow and label.
     
    213213
    214214== Changelog ==
     215- = 1.9.8 =
     216- **Fixed:** Fixed an issue where the Leaflet map could fail to load on live/optimized sites due to script handle conflicts with themes or other plugins.
     217- **Improved:** Renamed Leaflet asset handles to unique, plugin-specific names to prevent collisions and ensure correct dependency resolution.
     218- **Improved:** Removed forced defer handling for Leaflet/map scripts to avoid broken load order when caching/optimization plugins are active.
     219- **Improved:** Improved map initialization logic to prevent infinite retry loops and reduce console spam when Leaflet isn’t available.
     220- **Improved:** Kept Leaflet/map assets conditionally loaded only on pages where the widget/block/shortcode is actually rendered.
     221
    215222- = 1.9.7 =
    216223- **Experimental:** Tide support added for testing — opt-in feature. Adds support for WorldTides (API key), NOAA (US-only), and a configurable custom endpoint. Shortcode support via `extras="tides"` or `tides="1"`. Admin visibility can be toggled while rolling out to selected users. Responses are cached; configure TTL in Settings.
  • spelhubben-weather/trunk/spelhubben-weather.php

    r3450708 r3452321  
    33 * Plugin Name: Spelhubben Weather
    44 * Description: Displays current weather and an optional forecast with a simple consensus across providers (Open-Meteo, SMHI, Yr/MET Norway). Supports shortcode + Gutenberg block + classic widget. Optional Leaflet map, subtle animations, daily forecast, and multiple layouts.
    5  * Version: 1.9.7
     5 * Version: 1.9.8
    66 * Author: Spelhubben
    77 * Text Domain: spelhubben-weather
     
    2424// ── Constants (kept for backward compatibility).
    2525    if ( ! defined( 'SV_VADER_VER' ) ) {
    26         define( 'SV_VADER_VER', '1.9.7' );
     26        define( 'SV_VADER_VER', '1.9.8' );
    2727    }
    2828if ( ! defined( 'SV_VADER_DIR' ) ) {
Note: See TracChangeset for help on using the changeset viewer.