Changeset 3452321
- Timestamp:
- 02/02/2026 06:17:32 PM (3 weeks ago)
- Location:
- spelhubben-weather
- Files:
-
- 8 edited
- 1 copied
-
tags/1.9.8 (copied) (copied from spelhubben-weather/trunk)
-
tags/1.9.8/assets/map.js (modified) (10 diffs)
-
tags/1.9.8/includes/class-assets.php (modified) (7 diffs)
-
tags/1.9.8/readme.txt (modified) (3 diffs)
-
tags/1.9.8/spelhubben-weather.php (modified) (2 diffs)
-
trunk/assets/map.js (modified) (10 diffs)
-
trunk/includes/class-assets.php (modified) (7 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/spelhubben-weather.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
spelhubben-weather/tags/1.9.8/assets/map.js
r3435228 r3452321 32 32 function initMap(el){ 33 33 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 34 44 el.dataset.inited = '1'; 35 45 … … 37 47 if (typeof L === 'undefined' || !L.map) { 38 48 console.warn('Leaflet not loaded yet, retrying...', el); 39 // Try again in a moment40 49 setTimeout(() => { 50 el.dataset.svvLeafletTries = String(tries + 1); 41 51 delete el.dataset.inited; 42 52 initMap(el); … … 70 80 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom:19 }).addTo(map); 71 81 72 // NOTE: No L.marker here — the pin is never placed.73 82 setTimeout(()=>map.invalidateSize(), 200); 74 83 } catch (e) { … … 83 92 if (!maps.length) return; 84 93 85 // If IntersectionObserver supported, observe and init when visible86 94 if ('IntersectionObserver' in window) { 87 95 const io = new IntersectionObserver(function(entries){ … … 95 103 96 104 maps.forEach(function(m){ 97 // If already inited, skip98 105 if (m.dataset.inited) return; 99 106 io.observe(m); … … 102 109 } 103 110 104 // Fallback: initialize immediately (keeps previous behavior)105 111 maps.forEach(initMap); 106 112 } … … 116 122 if (!('ResizeObserver' in window)) return; 117 123 118 // Support both old (.sv-vader) and new (.spelhubben-weather) container classes119 124 document.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]').forEach(function(card){ 120 125 if (card._svvObserved) return; … … 136 141 const ro = new ResizeObserver(debounce(applyScale, 60)); 137 142 ro.observe(card); 138 139 // Store observer reference for cleanup 143 140 144 card._svvResizeObserver = ro; 141 145 }); … … 146 150 } else { attachRO(); } 147 151 148 // Single persistent MutationObserver instead of creating new ones149 152 const mutationObserver = new MutationObserver(function(mutations){ 150 // Cleanup removed cards151 153 mutations.forEach(function(m){ 152 154 if (m.removedNodes.length) { 153 155 m.removedNodes.forEach(function(node){ 154 if (node.nodeType === 1) { // Element node156 if (node.nodeType === 1) { 155 157 const cards = node.querySelectorAll ? node.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]') : []; 156 158 cards.forEach(function(card){ … … 171 173 attachRO(); 172 174 }); 173 175 174 176 mutationObserver.observe(document.documentElement, { childList:true, subtree: true }); 175 177 })(); -
spelhubben-weather/tags/1.9.8/includes/class-assets.php
r3438808 r3452321 7 7 /** 8 8 * 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. 10 10 */ 11 11 public function enqueue_public_assets() { 12 12 13 // Core plugin stylesheet - register, enqueue only when used on the page 13 14 // Prefer minified file when present and WP_DEBUG is not enabled 14 15 $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 16 20 if ( ! ( defined('WP_DEBUG') && WP_DEBUG ) ) { 17 21 if ( file_exists( $base_dir . 'assets' . DIRECTORY_SEPARATOR . 'style.min.css' ) ) { … … 19 23 } 20 24 } 25 21 26 wp_register_style('sv-vader-style', SV_VADER_URL . $style_file, [], SV_VADER_VER); 22 27 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 27 36 // Prefer minified map script when available 28 37 $map_file = 'assets/map.js'; … … 30 39 $map_file = 'assets/map.min.js'; 31 40 } 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 33 45 // Small helper to rotate wind direction arrows when inline styles are stripped 34 46 wp_register_script('sv-vader-wind', SV_VADER_URL . 'assets/wind.js', [], SV_VADER_VER, true); … … 40 52 } 41 53 42 // Localized data for JS will be added only when the map script is enqueued43 44 54 // Load Leaflet assets only if shortcode is present or Gutenberg block is used 45 55 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'); 48 58 wp_enqueue_script('sv-vader-map'); 49 59 … … 53 63 ]); 54 64 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 */ 57 70 } 58 71 } … … 62 75 */ 63 76 private function should_load_leaflet() { 64 global $post , $wp_registered_sidebars;77 global $post; 65 78 66 79 // Check for shortcodes in post content … … 116 129 return false; 117 130 } 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 handles124 $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 }130 131 } -
spelhubben-weather/tags/1.9.8/readme.txt
r3450708 r3452321 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1.9. 77 Stable tag: 1.9.8 8 8 Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU 9 9 … … 92 92 93 93 If `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 94 rontend assets are registered 95 95 = What fields can I show/hide? = 96 96 Use `show="temp,wind,icon"` (comma separated). Defaults are set in settings. Add `wind_dir` to show wind direction arrow and label. … … 213 213 214 214 == 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 215 222 - = 1.9.7 = 216 223 - **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 3 3 * Plugin Name: Spelhubben Weather 4 4 * 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. 75 * Version: 1.9.8 6 6 * Author: Spelhubben 7 7 * Text Domain: spelhubben-weather … … 24 24 // ── Constants (kept for backward compatibility). 25 25 if ( ! defined( 'SV_VADER_VER' ) ) { 26 define( 'SV_VADER_VER', '1.9. 7' );26 define( 'SV_VADER_VER', '1.9.8' ); 27 27 } 28 28 if ( ! defined( 'SV_VADER_DIR' ) ) { -
spelhubben-weather/trunk/assets/map.js
r3435228 r3452321 32 32 function initMap(el){ 33 33 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 34 44 el.dataset.inited = '1'; 35 45 … … 37 47 if (typeof L === 'undefined' || !L.map) { 38 48 console.warn('Leaflet not loaded yet, retrying...', el); 39 // Try again in a moment40 49 setTimeout(() => { 50 el.dataset.svvLeafletTries = String(tries + 1); 41 51 delete el.dataset.inited; 42 52 initMap(el); … … 70 80 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom:19 }).addTo(map); 71 81 72 // NOTE: No L.marker here — the pin is never placed.73 82 setTimeout(()=>map.invalidateSize(), 200); 74 83 } catch (e) { … … 83 92 if (!maps.length) return; 84 93 85 // If IntersectionObserver supported, observe and init when visible86 94 if ('IntersectionObserver' in window) { 87 95 const io = new IntersectionObserver(function(entries){ … … 95 103 96 104 maps.forEach(function(m){ 97 // If already inited, skip98 105 if (m.dataset.inited) return; 99 106 io.observe(m); … … 102 109 } 103 110 104 // Fallback: initialize immediately (keeps previous behavior)105 111 maps.forEach(initMap); 106 112 } … … 116 122 if (!('ResizeObserver' in window)) return; 117 123 118 // Support both old (.sv-vader) and new (.spelhubben-weather) container classes119 124 document.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]').forEach(function(card){ 120 125 if (card._svvObserved) return; … … 136 141 const ro = new ResizeObserver(debounce(applyScale, 60)); 137 142 ro.observe(card); 138 139 // Store observer reference for cleanup 143 140 144 card._svvResizeObserver = ro; 141 145 }); … … 146 150 } else { attachRO(); } 147 151 148 // Single persistent MutationObserver instead of creating new ones149 152 const mutationObserver = new MutationObserver(function(mutations){ 150 // Cleanup removed cards151 153 mutations.forEach(function(m){ 152 154 if (m.removedNodes.length) { 153 155 m.removedNodes.forEach(function(node){ 154 if (node.nodeType === 1) { // Element node156 if (node.nodeType === 1) { 155 157 const cards = node.querySelectorAll ? node.querySelectorAll('.sv-vader[data-svv-ro="1"], .spelhubben-weather[data-svv-ro="1"]') : []; 156 158 cards.forEach(function(card){ … … 171 173 attachRO(); 172 174 }); 173 175 174 176 mutationObserver.observe(document.documentElement, { childList:true, subtree: true }); 175 177 })(); -
spelhubben-weather/trunk/includes/class-assets.php
r3438808 r3452321 7 7 /** 8 8 * 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. 10 10 */ 11 11 public function enqueue_public_assets() { 12 12 13 // Core plugin stylesheet - register, enqueue only when used on the page 13 14 // Prefer minified file when present and WP_DEBUG is not enabled 14 15 $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 16 20 if ( ! ( defined('WP_DEBUG') && WP_DEBUG ) ) { 17 21 if ( file_exists( $base_dir . 'assets' . DIRECTORY_SEPARATOR . 'style.min.css' ) ) { … … 19 23 } 20 24 } 25 21 26 wp_register_style('sv-vader-style', SV_VADER_URL . $style_file, [], SV_VADER_VER); 22 27 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 27 36 // Prefer minified map script when available 28 37 $map_file = 'assets/map.js'; … … 30 39 $map_file = 'assets/map.min.js'; 31 40 } 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 33 45 // Small helper to rotate wind direction arrows when inline styles are stripped 34 46 wp_register_script('sv-vader-wind', SV_VADER_URL . 'assets/wind.js', [], SV_VADER_VER, true); … … 40 52 } 41 53 42 // Localized data for JS will be added only when the map script is enqueued43 44 54 // Load Leaflet assets only if shortcode is present or Gutenberg block is used 45 55 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'); 48 58 wp_enqueue_script('sv-vader-map'); 49 59 … … 53 63 ]); 54 64 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 */ 57 70 } 58 71 } … … 62 75 */ 63 76 private function should_load_leaflet() { 64 global $post , $wp_registered_sidebars;77 global $post; 65 78 66 79 // Check for shortcodes in post content … … 116 129 return false; 117 130 } 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 handles124 $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 }130 131 } -
spelhubben-weather/trunk/readme.txt
r3450708 r3452321 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1.9. 77 Stable tag: 1.9.8 8 8 Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU 9 9 … … 92 92 93 93 If `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 94 rontend assets are registered 95 95 = What fields can I show/hide? = 96 96 Use `show="temp,wind,icon"` (comma separated). Defaults are set in settings. Add `wind_dir` to show wind direction arrow and label. … … 213 213 214 214 == 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 215 222 - = 1.9.7 = 216 223 - **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 3 3 * Plugin Name: Spelhubben Weather 4 4 * 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. 75 * Version: 1.9.8 6 6 * Author: Spelhubben 7 7 * Text Domain: spelhubben-weather … … 24 24 // ── Constants (kept for backward compatibility). 25 25 if ( ! defined( 'SV_VADER_VER' ) ) { 26 define( 'SV_VADER_VER', '1.9. 7' );26 define( 'SV_VADER_VER', '1.9.8' ); 27 27 } 28 28 if ( ! defined( 'SV_VADER_DIR' ) ) {
Note: See TracChangeset
for help on using the changeset viewer.