Changeset 3487767
- Timestamp:
- 03/21/2026 12:39:03 PM (11 days ago)
- Location:
- muki-floating-toc
- Files:
-
- 8 edited
- 14 copied
-
tags/1.0.6 (copied) (copied from muki-floating-toc/trunk)
-
tags/1.0.6/includes/class-muki-floating-toc.php (copied) (copied from muki-floating-toc/trunk/includes/class-muki-floating-toc.php)
-
tags/1.0.6/languages/muki-floating-toc-zh_TW.mo (copied) (copied from muki-floating-toc/trunk/languages/muki-floating-toc-zh_TW.mo)
-
tags/1.0.6/languages/muki-floating-toc-zh_TW.po (copied) (copied from muki-floating-toc/trunk/languages/muki-floating-toc-zh_TW.po)
-
tags/1.0.6/muki-floating-toc.php (copied) (copied from muki-floating-toc/trunk/muki-floating-toc.php)
-
tags/1.0.6/readme-zh_TW.txt (copied) (copied from muki-floating-toc/trunk/readme-zh_TW.txt)
-
tags/1.0.6/readme.txt (copied) (copied from muki-floating-toc/trunk/readme.txt)
-
tags/1.0.7 (copied) (copied from muki-floating-toc/trunk)
-
tags/1.0.7/includes/class-muki-floating-toc.php (copied) (copied from muki-floating-toc/trunk/includes/class-muki-floating-toc.php) (2 diffs)
-
tags/1.0.7/languages/muki-floating-toc-zh_TW.mo (copied) (copied from muki-floating-toc/trunk/languages/muki-floating-toc-zh_TW.mo)
-
tags/1.0.7/languages/muki-floating-toc-zh_TW.po (copied) (copied from muki-floating-toc/trunk/languages/muki-floating-toc-zh_TW.po)
-
tags/1.0.7/muki-floating-toc.php (copied) (copied from muki-floating-toc/trunk/muki-floating-toc.php) (4 diffs)
-
tags/1.0.7/readme-zh_TW.txt (copied) (copied from muki-floating-toc/trunk/readme-zh_TW.txt) (2 diffs)
-
tags/1.0.7/readme.txt (copied) (copied from muki-floating-toc/trunk/readme.txt) (2 diffs)
-
tags/1.0.7/src/css/muki-floating-toc.css (modified) (1 diff)
-
tags/1.0.7/src/js/muki-floating-toc.js (modified) (14 diffs)
-
trunk/includes/class-muki-floating-toc.php (modified) (2 diffs)
-
trunk/muki-floating-toc.php (modified) (4 diffs)
-
trunk/readme-zh_TW.txt (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/css/muki-floating-toc.css (modified) (1 diff)
-
trunk/src/js/muki-floating-toc.js (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
muki-floating-toc/tags/1.0.7/includes/class-muki-floating-toc.php
r3355807 r3487767 17 17 public static function init() { 18 18 // Load default settings 19 self::$settings = array( 20 'position_left' => true, 21 'default_pin' => false, 22 'auto_display' => true, 23 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 24 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 25 'fixed_header_height' => 0, 26 'custom_content_selector' => '' 27 ); 19 self::$settings = muki_floating_toc_get_defaults(); 28 20 29 21 // Add settings page … … 318 310 // Further restrictive regex to allow only valid CSS selector characters 319 311 // Allows: a-z, A-Z, 0-9, #, ., ,, -, _, [, ], =, " 320 $selectors = preg_replace('/[^\w\s#., -_\[\]="]/', '', $selectors);312 $selectors = preg_replace('/[^\w\s#.,_\[\]=":-]/', '', $selectors); 321 313 322 314 return $selectors; -
muki-floating-toc/tags/1.0.7/muki-floating-toc.php
r3355807 r3487767 3 3 * Plugin Name: Muki Floating TOC 4 4 * Description: Add a floating TOC on the left or right side of articles, following scrolling and fixed at appropriate positions. 5 * Version: 1.0. 65 * Version: 1.0.7 6 6 * Author: Muki Wu 7 7 * Author URI: https://muki.tw … … 20 20 21 21 /** 22 * Load plugin text domain for internationalization 23 */ 24 function muki_floating_toc_load_textdomain() { 25 load_plugin_textdomain( 26 'muki-floating-toc', 27 false, 28 dirname(plugin_basename(__FILE__)) . '/languages/' 29 ); 30 } 31 add_action('plugins_loaded', 'muki_floating_toc_load_textdomain'); 32 33 // Register scripts and styles 34 function muki_floating_toc_scripts() { 35 // Only load on single posts 36 if (is_single()) { 37 wp_enqueue_style( 38 'muki-floating-toc-style', 39 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 40 array(), 41 '1.0.6' 42 ); 43 44 wp_enqueue_script( 45 'muki-floating-toc-script', 46 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 47 array('jquery'), 48 '1.0.6', 49 true 50 ); 51 52 // Get settings 53 $settings = get_option('muki_floating_toc_settings', array( 54 'position_left' => true, 55 'default_pin' => false, 56 'auto_display' => true, 57 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 58 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 59 'fixed_header_height' => 0, 60 'custom_content_selector' => '' 61 )); 62 63 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 64 65 // if custom_content_selector has value, use it first 66 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 67 68 // Pass settings to JavaScript 69 wp_localize_script( 70 'muki-floating-toc-script', 71 'muki_floating_toc_settings', 72 array( 73 'selectorContent' => $content_selector, 74 'positionLeft' => isset($settings['position_left']) ? (bool)$settings['position_left'] : true, 75 'defaultPin' => isset($settings['default_pin']) ? (bool)$settings['default_pin'] : false, 76 'excludeSelectors' => isset($settings['exclude_selectors']) ? $settings['exclude_selectors'] : '.single-author-box-container', 77 'fixedHeaderHeight' => isset($settings['fixed_header_height']) ? intval($settings['fixed_header_height']) : 0, 78 'headingLevels' => isset($settings['heading_levels']) ? $settings['heading_levels'] : array('h2', 'h3', 'h4') 79 ) 80 ); 81 } 82 } 83 add_action('wp_enqueue_scripts', 'muki_floating_toc_scripts'); 84 85 /** 86 * Add floating TOC HTML to the footer 87 * No longer using the_content filter to avoid content positioning issues 88 */ 89 function muki_floating_toc_add_to_footer() { 90 // Only add on single posts 91 if (!is_single()) { 92 return; 93 } 94 95 // Get settings to check if auto display is enabled 96 $settings = get_option('muki_floating_toc_settings', array( 22 * Get plugin default settings 23 */ 24 function muki_floating_toc_get_defaults() { 25 return array( 97 26 'position_left' => true, 98 27 'default_pin' => false, … … 102 31 'fixed_header_height' => 0, 103 32 'custom_content_selector' => '' 104 )); 105 106 // Only auto display if setting is enabled 107 if (!isset($settings['auto_display']) || !$settings['auto_display']) { 108 return; 109 } 110 111 // Create floating TOC HTML 112 $toc_html = muki_floating_toc_get_html(); 113 114 echo wp_kses_post($toc_html); 115 } 116 add_action('wp_footer', 'muki_floating_toc_add_to_footer', 999); // Increase priority to ensure it loads last 117 118 /** 119 * Add Dashicons support 120 */ 121 function muki_floating_toc_enqueue_dashicons() { 122 wp_enqueue_style('dashicons'); 123 } 124 add_action('wp_enqueue_scripts', 'muki_floating_toc_enqueue_dashicons'); 125 126 /** 127 * Manual TOC display function for theme developers 128 * This allows developers to place the TOC anywhere in their template files 129 */ 130 function muki_floating_toc_display() { 131 static $displayed = false; 132 133 // Prevent multiple displays 134 if ($displayed) { 135 return; 136 } 137 138 // Only work on single posts or pages 139 if (!is_single() && !is_page()) { 140 return; 141 } 142 143 // Ensure scripts and styles are loaded 144 muki_floating_toc_enqueue_assets(); 145 146 // Mark as displayed 147 $displayed = true; 148 149 // Get the TOC HTML 150 $toc_html = muki_floating_toc_get_html(); 151 152 echo wp_kses_post($toc_html); 153 } 154 155 /** 156 * Enqueue assets for manual display 157 */ 158 function muki_floating_toc_enqueue_assets() { 159 if (!wp_style_is_enqueued('muki-floating-toc-style')) { 160 wp_enqueue_style( 161 'muki-floating-toc-style', 162 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 163 array(), 164 '1.0.6' 165 ); 166 } 167 168 if (!wp_script_is_enqueued('muki-floating-toc-script')) { 169 wp_enqueue_script( 170 'muki-floating-toc-script', 171 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 172 array('jquery'), 173 '1.0.6', 174 true 175 ); 176 177 // Get settings and localize script 178 $settings = get_option('muki_floating_toc_settings', array( 179 'position_left' => true, 180 'default_pin' => false, 181 'auto_display' => true, 182 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 183 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 184 'fixed_header_height' => 0, 185 'custom_content_selector' => '' 186 )); 187 188 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 189 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 190 191 wp_localize_script( 192 'muki-floating-toc-script', 193 'muki_floating_toc_settings', 194 array( 195 'selectorContent' => $content_selector, 196 'positionLeft' => isset($settings['position_left']) ? (bool)$settings['position_left'] : true, 197 'defaultPin' => isset($settings['default_pin']) ? (bool)$settings['default_pin'] : false, 198 'excludeSelectors' => isset($settings['exclude_selectors']) ? $settings['exclude_selectors'] : '.single-author-box-container', 199 'fixedHeaderHeight' => isset($settings['fixed_header_height']) ? intval($settings['fixed_header_height']) : 0, 200 'headingLevels' => isset($settings['heading_levels']) ? $settings['heading_levels'] : array('h2', 'h3', 'h4') 201 ) 202 ); 203 } 204 205 // Ensure dashicons are loaded 206 wp_enqueue_style('dashicons'); 207 } 208 209 /** 210 * Get TOC HTML structure 211 */ 212 function muki_floating_toc_get_html() { 213 $toc_html = '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents">'; 214 $toc_html .= '<div class="muki-toc-toolbar">'; 215 $toc_html .= '<button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button>'; 216 $toc_html .= '</div>'; 217 $toc_html .= '</div>'; 218 219 return $toc_html; 220 } 221 222 /** 223 * Shortcode handler for [muki_floating_toc] 224 * This allows users to place TOC anywhere in post content using shortcode 225 */ 226 function muki_floating_toc_shortcode($atts = array()) { 227 // Only work on single posts or pages 228 if (!is_single() && !is_page()) { 229 return ''; 230 } 231 232 // Prevent multiple displays 233 static $shortcode_used = false; 234 if ($shortcode_used) { 235 return '<p><em>' . esc_html__('Note: TOC shortcode can only be used once per page.', 'muki-floating-toc') . '</em></p>'; 236 } 237 $shortcode_used = true; 238 239 // Parse shortcode attributes 240 $atts = shortcode_atts(array(), $atts, 'muki_floating_toc'); 241 242 // Mark that shortcode was used and enqueue assets in footer 243 add_action('wp_footer', 'muki_floating_toc_enqueue_shortcode_assets', 5); 244 245 // Return simple HTML structure - JavaScript will build the TOC 246 return '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents"> 247 <div class="muki-toc-toolbar"> 248 <button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button> 249 </div> 250 </div>'; 251 } 252 253 /** 254 * Enqueue assets specifically for shortcode usage 255 */ 256 function muki_floating_toc_enqueue_shortcode_assets() { 257 // Enqueue styles 258 wp_enqueue_style( 259 'muki-floating-toc-style', 260 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 261 array(), 262 '1.0.6' 263 ); 264 265 // Enqueue scripts 266 wp_enqueue_script( 267 'muki-floating-toc-script', 268 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 269 array('jquery'), 270 '1.0.6', 271 true 272 ); 273 274 // Get settings 275 $settings = get_option('muki_floating_toc_settings', array( 276 'position_left' => true, 277 'default_pin' => false, 278 'auto_display' => true, 279 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 280 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 281 'fixed_header_height' => 0, 282 'custom_content_selector' => '' 283 )); 284 33 ); 34 } 35 36 /** 37 * Get plugin settings with defaults 38 */ 39 function muki_floating_toc_get_settings() { 40 return get_option('muki_floating_toc_settings', muki_floating_toc_get_defaults()); 41 } 42 43 /** 44 * Localize script with plugin settings 45 */ 46 function muki_floating_toc_localize_settings() { 47 $settings = muki_floating_toc_get_settings(); 285 48 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 286 49 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 287 50 288 // Localize script289 51 wp_localize_script( 290 52 'muki-floating-toc-script', … … 299 61 ) 300 62 ); 301 63 } 64 65 /** 66 * Load plugin text domain for internationalization 67 */ 68 function muki_floating_toc_load_textdomain() { 69 load_plugin_textdomain( 70 'muki-floating-toc', 71 false, 72 dirname(plugin_basename(__FILE__)) . '/languages/' 73 ); 74 } 75 add_action('plugins_loaded', 'muki_floating_toc_load_textdomain'); 76 77 // Register scripts and styles 78 function muki_floating_toc_scripts() { 79 // Only load on single posts 80 if (is_single()) { 81 wp_enqueue_style( 82 'muki-floating-toc-style', 83 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 84 array(), 85 '1.0.7' 86 ); 87 88 wp_enqueue_script( 89 'muki-floating-toc-script', 90 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 91 array('jquery'), 92 '1.0.7', 93 true 94 ); 95 96 // Pass settings to JavaScript 97 muki_floating_toc_localize_settings(); 98 } 99 } 100 add_action('wp_enqueue_scripts', 'muki_floating_toc_scripts'); 101 102 /** 103 * Add floating TOC HTML to the footer 104 * No longer using the_content filter to avoid content positioning issues 105 */ 106 function muki_floating_toc_add_to_footer() { 107 // Only add on single posts 108 if (!is_single()) { 109 return; 110 } 111 112 // Get settings to check if auto display is enabled 113 $settings = muki_floating_toc_get_settings(); 114 115 // Only auto display if setting is enabled 116 if (!isset($settings['auto_display']) || !$settings['auto_display']) { 117 return; 118 } 119 120 // Create floating TOC HTML 121 $toc_html = muki_floating_toc_get_html(); 122 123 echo wp_kses_post($toc_html); 124 } 125 add_action('wp_footer', 'muki_floating_toc_add_to_footer', 999); // Increase priority to ensure it loads last 126 127 /** 128 * Add Dashicons support 129 */ 130 function muki_floating_toc_enqueue_dashicons() { 131 wp_enqueue_style('dashicons'); 132 } 133 add_action('wp_enqueue_scripts', 'muki_floating_toc_enqueue_dashicons'); 134 135 /** 136 * Manual TOC display function for theme developers 137 * This allows developers to place the TOC anywhere in their template files 138 */ 139 function muki_floating_toc_display() { 140 static $displayed = false; 141 142 // Prevent multiple displays 143 if ($displayed) { 144 return; 145 } 146 147 // Only work on single posts or pages 148 if (!is_single() && !is_page()) { 149 return; 150 } 151 152 // Ensure scripts and styles are loaded 153 muki_floating_toc_enqueue_assets(); 154 155 // Mark as displayed 156 $displayed = true; 157 158 // Get the TOC HTML 159 $toc_html = muki_floating_toc_get_html(); 160 161 echo wp_kses_post($toc_html); 162 } 163 164 /** 165 * Enqueue assets for manual display 166 */ 167 function muki_floating_toc_enqueue_assets() { 168 if (!wp_style_is_enqueued('muki-floating-toc-style')) { 169 wp_enqueue_style( 170 'muki-floating-toc-style', 171 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 172 array(), 173 '1.0.7' 174 ); 175 } 176 177 if (!wp_script_is_enqueued('muki-floating-toc-script')) { 178 wp_enqueue_script( 179 'muki-floating-toc-script', 180 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 181 array('jquery'), 182 '1.0.7', 183 true 184 ); 185 186 muki_floating_toc_localize_settings(); 187 } 188 189 // Ensure dashicons are loaded 190 wp_enqueue_style('dashicons'); 191 } 192 193 /** 194 * Get TOC HTML structure 195 */ 196 function muki_floating_toc_get_html() { 197 $toc_html = '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents">'; 198 $toc_html .= '<div class="muki-toc-toolbar">'; 199 $toc_html .= '<button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button>'; 200 $toc_html .= '</div>'; 201 $toc_html .= '</div>'; 202 203 return $toc_html; 204 } 205 206 /** 207 * Shortcode handler for [muki_floating_toc] 208 * This allows users to place TOC anywhere in post content using shortcode 209 */ 210 function muki_floating_toc_shortcode($atts = array()) { 211 // Only work on single posts or pages 212 if (!is_single() && !is_page()) { 213 return ''; 214 } 215 216 // Prevent multiple displays 217 static $shortcode_used = false; 218 if ($shortcode_used) { 219 return '<p><em>' . esc_html__('Note: TOC shortcode can only be used once per page.', 'muki-floating-toc') . '</em></p>'; 220 } 221 $shortcode_used = true; 222 223 // Parse shortcode attributes 224 $atts = shortcode_atts(array(), $atts, 'muki_floating_toc'); 225 226 // Mark that shortcode was used and enqueue assets in footer 227 add_action('wp_footer', 'muki_floating_toc_enqueue_shortcode_assets', 5); 228 229 // Return simple HTML structure - JavaScript will build the TOC 230 return '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents"> 231 <div class="muki-toc-toolbar"> 232 <button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button> 233 </div> 234 </div>'; 235 } 236 237 /** 238 * Enqueue assets specifically for shortcode usage 239 */ 240 function muki_floating_toc_enqueue_shortcode_assets() { 241 // Enqueue styles 242 wp_enqueue_style( 243 'muki-floating-toc-style', 244 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 245 array(), 246 '1.0.7' 247 ); 248 249 // Enqueue scripts 250 wp_enqueue_script( 251 'muki-floating-toc-script', 252 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 253 array('jquery'), 254 '1.0.7', 255 true 256 ); 257 258 muki_floating_toc_localize_settings(); 259 302 260 // Enqueue dashicons 303 261 wp_enqueue_style('dashicons'); -
muki-floating-toc/tags/1.0.7/readme-zh_TW.txt
r3355807 r3487767 3 3 Tags: table of contents 4 4 Requires at least: 6.0 5 Tested up to: 6. 86 Stable tag: 1.0. 65 Tested up to: 6.9 6 Stable tag: 1.0.7 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 43 43 == 更新紀錄 == 44 44 45 = 1.0.7 = 46 * 修正:當標題數量多或標題文字過長時,目錄內容會超出容器範圍 47 * 新增:固定模式下加入垂直捲軸,並使用細窄美化樣式(支援 WebKit 及 Firefox) 48 45 49 = 1.0.6 = 46 50 * 新增:「自動顯示」設定選項,可控制目錄自動顯示功能 -
muki-floating-toc/tags/1.0.7/readme.txt
r3355807 r3487767 3 3 Tags: table of contents 4 4 Requires at least: 6.0 5 Tested up to: 6. 86 Stable tag: 1.0. 65 Tested up to: 6.9 6 Stable tag: 1.0.7 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 43 43 == Changelog == 44 44 45 = 1.0.7 = 46 * Fix: TOC content overflowing container when there are many headings or long heading text 47 * Add vertical scrollbar to pinned TOC with styled thin scrollbar (WebKit + Firefox) 48 45 49 = 1.0.6 = 46 50 * New: Add "Auto Display" setting to control automatic TOC display -
muki-floating-toc/tags/1.0.7/src/css/muki-floating-toc.css
r3348225 r3487767 170 170 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 171 171 padding: 15px; 172 transition: width 0.45s cubic-bezier(0.3, 0.7, 0.1, 1), 173 background-color 0.3s ease, 172 overflow-y: auto; 173 overflow-x: hidden; 174 scrollbar-width: thin; 175 scrollbar-color: rgba(0, 0, 0, 0.15) transparent; 176 transition: width 0.45s cubic-bezier(0.3, 0.7, 0.1, 1), 177 background-color 0.3s ease, 174 178 box-shadow 0.35s ease, 175 179 padding 0.4s ease, 176 180 transform 0s; 181 } 182 183 .muki-floating-toc.pinned::-webkit-scrollbar { 184 width: 4px; 185 } 186 187 .muki-floating-toc.pinned::-webkit-scrollbar-track { 188 background: transparent; 189 } 190 191 .muki-floating-toc.pinned::-webkit-scrollbar-thumb { 192 background-color: rgba(0, 0, 0, 0.15); 193 border-radius: 4px; 194 } 195 196 .muki-floating-toc.pinned::-webkit-scrollbar-thumb:hover { 197 background-color: rgba(0, 0, 0, 0.3); 177 198 } 178 199 -
muki-floating-toc/tags/1.0.7/src/js/muki-floating-toc.js
r3348225 r3487767 63 63 // Validate content selector for security 64 64 if (!isValidSelector(selectorContent)) { 65 console.log('Muki Floating TOC: 無效的內容選擇器,使用默認值');66 65 selectorContent = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 67 66 } … … 71 70 72 71 if (!$content || $content.length === 0) { 73 console.log('Muki Floating TOC: 未找到文章容器');74 72 return; 75 73 } 76 74 77 75 if ($toc.length === 0) { 78 console.log('Muki Floating TOC: 未找到 TOC 元素');79 76 return; 80 77 } 81 78 82 console.log('Muki Floating TOC: 找到文章容器', $content.prop('tagName'), $content.attr('class'));83 84 79 85 80 var excludeSelectors = getSafeSetting('excludeSelectors', '.single-author-box-container', 'string'); 86 if (isValidSelector(excludeSelectors)) { 87 console.log('Muki Floating TOC: 排除選擇器', excludeSelectors); 88 } else { 81 if (!isValidSelector(excludeSelectors)) { 89 82 excludeSelectors = '.single-author-box-container'; 90 console.log('Muki Floating TOC: 使用默認排除選擇器');91 83 } 92 84 … … 96 88 var $headings = $(); // Empty jQuery object to store headings 97 89 var headingsCache = []; // Cache for heading positions 98 var contentOffset, contentTop, contentLeft, contentWidth, contentHeight, contentBottom, tocHeight;99 90 100 91 // Generate unique ID generator for this TOC instance … … 132 123 133 124 134 $ (window).on('resize',function () {125 $window.on('resize', throttle(function () { 135 126 136 127 contentOffset = $content.offset(); … … 142 133 tocHeight = $toc.outerHeight(); 143 134 135 // Refresh cached heading positions after layout change 136 headingsCache = $headings.map(function () { 137 return $(this).offset().top; 138 }).get(); 144 139 145 140 positionTOC(); 146 } );141 }, 150)); 147 142 148 143 function initToolbar($toc) { … … 208 203 if (defaultPin === true || defaultPin === 'true' || defaultPin === 1 || defaultPin === '1') { 209 204 shouldPin = true; 210 console.log('Muki Floating TOC: 使用後台設定的預設固定狀態,設定值為:', defaultPin);211 205 } 212 206 } … … 228 222 229 223 // Use the pre-validated excludeSelectors variable from outer scope 230 console.log('Muki Floating TOC: 使用排除選擇器', excludeSelectors);231 224 232 225 233 226 var allHeadings = $content.find(headingSelectors); 234 console.log('Muki Floating TOC: 在文章容器內找到標題總數量', allHeadings.length);235 227 236 228 … … 246 238 247 239 if ($this.closest(selector).length > 0) { 248 console.log('Muki Floating TOC: 排除標題', $this.text(), '因為它在', selector, '內');249 240 return false; 250 241 } … … 256 247 }); 257 248 258 console.log('Muki Floating TOC: 排除後的標題數量', $headings.length);259 260 249 // Cache heading positions 261 250 headingsCache = $headings.map(function () { … … 265 254 266 255 if ($headings.length === 0) { 267 console.log('Muki Floating TOC: 未找到標題,添加默認線段');268 256 for (var i = 0; i < 5; i++) { 269 257 var $defaultItem = $('<div>', { … … 457 445 458 446 var positionLeft = getSafeSetting('positionLeft', true, 'boolean'); 447 var position; 459 448 460 449 if (positionLeft) { 461 462 var position = contentLeft - 60; 463 464 450 position = contentLeft - 60; 465 451 position = Math.max(10, position); 466 467 452 468 453 $toc.css({ … … 471 456 }); 472 457 } else { 473 474 var position = contentLeft + contentWidth + 20; 475 458 position = contentLeft + contentWidth + 20; 476 459 477 460 $toc.css({ … … 496 479 497 480 498 $ (document).on('click', 'a[href^="#"]', function (e) {481 $toc.on('click', 'a[href^="#"]', function (e) { 499 482 var href = $(this).attr('href'); 500 501 483 502 484 if (href === '#' || href.length <= 1) return; … … 506 488 e.preventDefault(); 507 489 508 509 490 var fixedHeaderHeight = getSafeSetting('fixedHeaderHeight', 0, 'number'); 510 511 512 491 var extraSpace = 20; 513 492 var offset = $target.offset().top - (fixedHeaderHeight + extraSpace); -
muki-floating-toc/trunk/includes/class-muki-floating-toc.php
r3355807 r3487767 17 17 public static function init() { 18 18 // Load default settings 19 self::$settings = array( 20 'position_left' => true, 21 'default_pin' => false, 22 'auto_display' => true, 23 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 24 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 25 'fixed_header_height' => 0, 26 'custom_content_selector' => '' 27 ); 19 self::$settings = muki_floating_toc_get_defaults(); 28 20 29 21 // Add settings page … … 318 310 // Further restrictive regex to allow only valid CSS selector characters 319 311 // Allows: a-z, A-Z, 0-9, #, ., ,, -, _, [, ], =, " 320 $selectors = preg_replace('/[^\w\s#., -_\[\]="]/', '', $selectors);312 $selectors = preg_replace('/[^\w\s#.,_\[\]=":-]/', '', $selectors); 321 313 322 314 return $selectors; -
muki-floating-toc/trunk/muki-floating-toc.php
r3355807 r3487767 3 3 * Plugin Name: Muki Floating TOC 4 4 * Description: Add a floating TOC on the left or right side of articles, following scrolling and fixed at appropriate positions. 5 * Version: 1.0. 65 * Version: 1.0.7 6 6 * Author: Muki Wu 7 7 * Author URI: https://muki.tw … … 20 20 21 21 /** 22 * Load plugin text domain for internationalization 23 */ 24 function muki_floating_toc_load_textdomain() { 25 load_plugin_textdomain( 26 'muki-floating-toc', 27 false, 28 dirname(plugin_basename(__FILE__)) . '/languages/' 29 ); 30 } 31 add_action('plugins_loaded', 'muki_floating_toc_load_textdomain'); 32 33 // Register scripts and styles 34 function muki_floating_toc_scripts() { 35 // Only load on single posts 36 if (is_single()) { 37 wp_enqueue_style( 38 'muki-floating-toc-style', 39 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 40 array(), 41 '1.0.6' 42 ); 43 44 wp_enqueue_script( 45 'muki-floating-toc-script', 46 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 47 array('jquery'), 48 '1.0.6', 49 true 50 ); 51 52 // Get settings 53 $settings = get_option('muki_floating_toc_settings', array( 54 'position_left' => true, 55 'default_pin' => false, 56 'auto_display' => true, 57 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 58 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 59 'fixed_header_height' => 0, 60 'custom_content_selector' => '' 61 )); 62 63 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 64 65 // if custom_content_selector has value, use it first 66 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 67 68 // Pass settings to JavaScript 69 wp_localize_script( 70 'muki-floating-toc-script', 71 'muki_floating_toc_settings', 72 array( 73 'selectorContent' => $content_selector, 74 'positionLeft' => isset($settings['position_left']) ? (bool)$settings['position_left'] : true, 75 'defaultPin' => isset($settings['default_pin']) ? (bool)$settings['default_pin'] : false, 76 'excludeSelectors' => isset($settings['exclude_selectors']) ? $settings['exclude_selectors'] : '.single-author-box-container', 77 'fixedHeaderHeight' => isset($settings['fixed_header_height']) ? intval($settings['fixed_header_height']) : 0, 78 'headingLevels' => isset($settings['heading_levels']) ? $settings['heading_levels'] : array('h2', 'h3', 'h4') 79 ) 80 ); 81 } 82 } 83 add_action('wp_enqueue_scripts', 'muki_floating_toc_scripts'); 84 85 /** 86 * Add floating TOC HTML to the footer 87 * No longer using the_content filter to avoid content positioning issues 88 */ 89 function muki_floating_toc_add_to_footer() { 90 // Only add on single posts 91 if (!is_single()) { 92 return; 93 } 94 95 // Get settings to check if auto display is enabled 96 $settings = get_option('muki_floating_toc_settings', array( 22 * Get plugin default settings 23 */ 24 function muki_floating_toc_get_defaults() { 25 return array( 97 26 'position_left' => true, 98 27 'default_pin' => false, … … 102 31 'fixed_header_height' => 0, 103 32 'custom_content_selector' => '' 104 )); 105 106 // Only auto display if setting is enabled 107 if (!isset($settings['auto_display']) || !$settings['auto_display']) { 108 return; 109 } 110 111 // Create floating TOC HTML 112 $toc_html = muki_floating_toc_get_html(); 113 114 echo wp_kses_post($toc_html); 115 } 116 add_action('wp_footer', 'muki_floating_toc_add_to_footer', 999); // Increase priority to ensure it loads last 117 118 /** 119 * Add Dashicons support 120 */ 121 function muki_floating_toc_enqueue_dashicons() { 122 wp_enqueue_style('dashicons'); 123 } 124 add_action('wp_enqueue_scripts', 'muki_floating_toc_enqueue_dashicons'); 125 126 /** 127 * Manual TOC display function for theme developers 128 * This allows developers to place the TOC anywhere in their template files 129 */ 130 function muki_floating_toc_display() { 131 static $displayed = false; 132 133 // Prevent multiple displays 134 if ($displayed) { 135 return; 136 } 137 138 // Only work on single posts or pages 139 if (!is_single() && !is_page()) { 140 return; 141 } 142 143 // Ensure scripts and styles are loaded 144 muki_floating_toc_enqueue_assets(); 145 146 // Mark as displayed 147 $displayed = true; 148 149 // Get the TOC HTML 150 $toc_html = muki_floating_toc_get_html(); 151 152 echo wp_kses_post($toc_html); 153 } 154 155 /** 156 * Enqueue assets for manual display 157 */ 158 function muki_floating_toc_enqueue_assets() { 159 if (!wp_style_is_enqueued('muki-floating-toc-style')) { 160 wp_enqueue_style( 161 'muki-floating-toc-style', 162 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 163 array(), 164 '1.0.6' 165 ); 166 } 167 168 if (!wp_script_is_enqueued('muki-floating-toc-script')) { 169 wp_enqueue_script( 170 'muki-floating-toc-script', 171 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 172 array('jquery'), 173 '1.0.6', 174 true 175 ); 176 177 // Get settings and localize script 178 $settings = get_option('muki_floating_toc_settings', array( 179 'position_left' => true, 180 'default_pin' => false, 181 'auto_display' => true, 182 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 183 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 184 'fixed_header_height' => 0, 185 'custom_content_selector' => '' 186 )); 187 188 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 189 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 190 191 wp_localize_script( 192 'muki-floating-toc-script', 193 'muki_floating_toc_settings', 194 array( 195 'selectorContent' => $content_selector, 196 'positionLeft' => isset($settings['position_left']) ? (bool)$settings['position_left'] : true, 197 'defaultPin' => isset($settings['default_pin']) ? (bool)$settings['default_pin'] : false, 198 'excludeSelectors' => isset($settings['exclude_selectors']) ? $settings['exclude_selectors'] : '.single-author-box-container', 199 'fixedHeaderHeight' => isset($settings['fixed_header_height']) ? intval($settings['fixed_header_height']) : 0, 200 'headingLevels' => isset($settings['heading_levels']) ? $settings['heading_levels'] : array('h2', 'h3', 'h4') 201 ) 202 ); 203 } 204 205 // Ensure dashicons are loaded 206 wp_enqueue_style('dashicons'); 207 } 208 209 /** 210 * Get TOC HTML structure 211 */ 212 function muki_floating_toc_get_html() { 213 $toc_html = '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents">'; 214 $toc_html .= '<div class="muki-toc-toolbar">'; 215 $toc_html .= '<button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button>'; 216 $toc_html .= '</div>'; 217 $toc_html .= '</div>'; 218 219 return $toc_html; 220 } 221 222 /** 223 * Shortcode handler for [muki_floating_toc] 224 * This allows users to place TOC anywhere in post content using shortcode 225 */ 226 function muki_floating_toc_shortcode($atts = array()) { 227 // Only work on single posts or pages 228 if (!is_single() && !is_page()) { 229 return ''; 230 } 231 232 // Prevent multiple displays 233 static $shortcode_used = false; 234 if ($shortcode_used) { 235 return '<p><em>' . esc_html__('Note: TOC shortcode can only be used once per page.', 'muki-floating-toc') . '</em></p>'; 236 } 237 $shortcode_used = true; 238 239 // Parse shortcode attributes 240 $atts = shortcode_atts(array(), $atts, 'muki_floating_toc'); 241 242 // Mark that shortcode was used and enqueue assets in footer 243 add_action('wp_footer', 'muki_floating_toc_enqueue_shortcode_assets', 5); 244 245 // Return simple HTML structure - JavaScript will build the TOC 246 return '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents"> 247 <div class="muki-toc-toolbar"> 248 <button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button> 249 </div> 250 </div>'; 251 } 252 253 /** 254 * Enqueue assets specifically for shortcode usage 255 */ 256 function muki_floating_toc_enqueue_shortcode_assets() { 257 // Enqueue styles 258 wp_enqueue_style( 259 'muki-floating-toc-style', 260 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 261 array(), 262 '1.0.6' 263 ); 264 265 // Enqueue scripts 266 wp_enqueue_script( 267 'muki-floating-toc-script', 268 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 269 array('jquery'), 270 '1.0.6', 271 true 272 ); 273 274 // Get settings 275 $settings = get_option('muki_floating_toc_settings', array( 276 'position_left' => true, 277 'default_pin' => false, 278 'auto_display' => true, 279 'heading_levels' => array('h2', 'h3', 'h4', 'h5', 'h6'), 280 'exclude_selectors' => '.single-author-box-container, .author-box, .comment-respond', 281 'fixed_header_height' => 0, 282 'custom_content_selector' => '' 283 )); 284 33 ); 34 } 35 36 /** 37 * Get plugin settings with defaults 38 */ 39 function muki_floating_toc_get_settings() { 40 return get_option('muki_floating_toc_settings', muki_floating_toc_get_defaults()); 41 } 42 43 /** 44 * Localize script with plugin settings 45 */ 46 function muki_floating_toc_localize_settings() { 47 $settings = muki_floating_toc_get_settings(); 285 48 $default_selector = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 286 49 $content_selector = !empty($settings['custom_content_selector']) ? $settings['custom_content_selector'] : $default_selector; 287 50 288 // Localize script289 51 wp_localize_script( 290 52 'muki-floating-toc-script', … … 299 61 ) 300 62 ); 301 63 } 64 65 /** 66 * Load plugin text domain for internationalization 67 */ 68 function muki_floating_toc_load_textdomain() { 69 load_plugin_textdomain( 70 'muki-floating-toc', 71 false, 72 dirname(plugin_basename(__FILE__)) . '/languages/' 73 ); 74 } 75 add_action('plugins_loaded', 'muki_floating_toc_load_textdomain'); 76 77 // Register scripts and styles 78 function muki_floating_toc_scripts() { 79 // Only load on single posts 80 if (is_single()) { 81 wp_enqueue_style( 82 'muki-floating-toc-style', 83 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 84 array(), 85 '1.0.7' 86 ); 87 88 wp_enqueue_script( 89 'muki-floating-toc-script', 90 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 91 array('jquery'), 92 '1.0.7', 93 true 94 ); 95 96 // Pass settings to JavaScript 97 muki_floating_toc_localize_settings(); 98 } 99 } 100 add_action('wp_enqueue_scripts', 'muki_floating_toc_scripts'); 101 102 /** 103 * Add floating TOC HTML to the footer 104 * No longer using the_content filter to avoid content positioning issues 105 */ 106 function muki_floating_toc_add_to_footer() { 107 // Only add on single posts 108 if (!is_single()) { 109 return; 110 } 111 112 // Get settings to check if auto display is enabled 113 $settings = muki_floating_toc_get_settings(); 114 115 // Only auto display if setting is enabled 116 if (!isset($settings['auto_display']) || !$settings['auto_display']) { 117 return; 118 } 119 120 // Create floating TOC HTML 121 $toc_html = muki_floating_toc_get_html(); 122 123 echo wp_kses_post($toc_html); 124 } 125 add_action('wp_footer', 'muki_floating_toc_add_to_footer', 999); // Increase priority to ensure it loads last 126 127 /** 128 * Add Dashicons support 129 */ 130 function muki_floating_toc_enqueue_dashicons() { 131 wp_enqueue_style('dashicons'); 132 } 133 add_action('wp_enqueue_scripts', 'muki_floating_toc_enqueue_dashicons'); 134 135 /** 136 * Manual TOC display function for theme developers 137 * This allows developers to place the TOC anywhere in their template files 138 */ 139 function muki_floating_toc_display() { 140 static $displayed = false; 141 142 // Prevent multiple displays 143 if ($displayed) { 144 return; 145 } 146 147 // Only work on single posts or pages 148 if (!is_single() && !is_page()) { 149 return; 150 } 151 152 // Ensure scripts and styles are loaded 153 muki_floating_toc_enqueue_assets(); 154 155 // Mark as displayed 156 $displayed = true; 157 158 // Get the TOC HTML 159 $toc_html = muki_floating_toc_get_html(); 160 161 echo wp_kses_post($toc_html); 162 } 163 164 /** 165 * Enqueue assets for manual display 166 */ 167 function muki_floating_toc_enqueue_assets() { 168 if (!wp_style_is_enqueued('muki-floating-toc-style')) { 169 wp_enqueue_style( 170 'muki-floating-toc-style', 171 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 172 array(), 173 '1.0.7' 174 ); 175 } 176 177 if (!wp_script_is_enqueued('muki-floating-toc-script')) { 178 wp_enqueue_script( 179 'muki-floating-toc-script', 180 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 181 array('jquery'), 182 '1.0.7', 183 true 184 ); 185 186 muki_floating_toc_localize_settings(); 187 } 188 189 // Ensure dashicons are loaded 190 wp_enqueue_style('dashicons'); 191 } 192 193 /** 194 * Get TOC HTML structure 195 */ 196 function muki_floating_toc_get_html() { 197 $toc_html = '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents">'; 198 $toc_html .= '<div class="muki-toc-toolbar">'; 199 $toc_html .= '<button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button>'; 200 $toc_html .= '</div>'; 201 $toc_html .= '</div>'; 202 203 return $toc_html; 204 } 205 206 /** 207 * Shortcode handler for [muki_floating_toc] 208 * This allows users to place TOC anywhere in post content using shortcode 209 */ 210 function muki_floating_toc_shortcode($atts = array()) { 211 // Only work on single posts or pages 212 if (!is_single() && !is_page()) { 213 return ''; 214 } 215 216 // Prevent multiple displays 217 static $shortcode_used = false; 218 if ($shortcode_used) { 219 return '<p><em>' . esc_html__('Note: TOC shortcode can only be used once per page.', 'muki-floating-toc') . '</em></p>'; 220 } 221 $shortcode_used = true; 222 223 // Parse shortcode attributes 224 $atts = shortcode_atts(array(), $atts, 'muki_floating_toc'); 225 226 // Mark that shortcode was used and enqueue assets in footer 227 add_action('wp_footer', 'muki_floating_toc_enqueue_shortcode_assets', 5); 228 229 // Return simple HTML structure - JavaScript will build the TOC 230 return '<div id="muki-floating-toc" class="muki-floating-toc" aria-label="Article Table of Contents"> 231 <div class="muki-toc-toolbar"> 232 <button class="muki-toc-pin-button" title="Pin TOC"><span class="dashicons dashicons-admin-post"></span></button> 233 </div> 234 </div>'; 235 } 236 237 /** 238 * Enqueue assets specifically for shortcode usage 239 */ 240 function muki_floating_toc_enqueue_shortcode_assets() { 241 // Enqueue styles 242 wp_enqueue_style( 243 'muki-floating-toc-style', 244 plugin_dir_url(__FILE__) . 'src/css/muki-floating-toc.css', 245 array(), 246 '1.0.7' 247 ); 248 249 // Enqueue scripts 250 wp_enqueue_script( 251 'muki-floating-toc-script', 252 plugin_dir_url(__FILE__) . 'src/js/muki-floating-toc.js', 253 array('jquery'), 254 '1.0.7', 255 true 256 ); 257 258 muki_floating_toc_localize_settings(); 259 302 260 // Enqueue dashicons 303 261 wp_enqueue_style('dashicons'); -
muki-floating-toc/trunk/readme-zh_TW.txt
r3355807 r3487767 3 3 Tags: table of contents 4 4 Requires at least: 6.0 5 Tested up to: 6. 86 Stable tag: 1.0. 65 Tested up to: 6.9 6 Stable tag: 1.0.7 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 43 43 == 更新紀錄 == 44 44 45 = 1.0.7 = 46 * 修正:當標題數量多或標題文字過長時,目錄內容會超出容器範圍 47 * 新增:固定模式下加入垂直捲軸,並使用細窄美化樣式(支援 WebKit 及 Firefox) 48 45 49 = 1.0.6 = 46 50 * 新增:「自動顯示」設定選項,可控制目錄自動顯示功能 -
muki-floating-toc/trunk/readme.txt
r3355807 r3487767 3 3 Tags: table of contents 4 4 Requires at least: 6.0 5 Tested up to: 6. 86 Stable tag: 1.0. 65 Tested up to: 6.9 6 Stable tag: 1.0.7 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 43 43 == Changelog == 44 44 45 = 1.0.7 = 46 * Fix: TOC content overflowing container when there are many headings or long heading text 47 * Add vertical scrollbar to pinned TOC with styled thin scrollbar (WebKit + Firefox) 48 45 49 = 1.0.6 = 46 50 * New: Add "Auto Display" setting to control automatic TOC display -
muki-floating-toc/trunk/src/css/muki-floating-toc.css
r3348225 r3487767 170 170 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 171 171 padding: 15px; 172 transition: width 0.45s cubic-bezier(0.3, 0.7, 0.1, 1), 173 background-color 0.3s ease, 172 overflow-y: auto; 173 overflow-x: hidden; 174 scrollbar-width: thin; 175 scrollbar-color: rgba(0, 0, 0, 0.15) transparent; 176 transition: width 0.45s cubic-bezier(0.3, 0.7, 0.1, 1), 177 background-color 0.3s ease, 174 178 box-shadow 0.35s ease, 175 179 padding 0.4s ease, 176 180 transform 0s; 181 } 182 183 .muki-floating-toc.pinned::-webkit-scrollbar { 184 width: 4px; 185 } 186 187 .muki-floating-toc.pinned::-webkit-scrollbar-track { 188 background: transparent; 189 } 190 191 .muki-floating-toc.pinned::-webkit-scrollbar-thumb { 192 background-color: rgba(0, 0, 0, 0.15); 193 border-radius: 4px; 194 } 195 196 .muki-floating-toc.pinned::-webkit-scrollbar-thumb:hover { 197 background-color: rgba(0, 0, 0, 0.3); 177 198 } 178 199 -
muki-floating-toc/trunk/src/js/muki-floating-toc.js
r3348225 r3487767 63 63 // Validate content selector for security 64 64 if (!isValidSelector(selectorContent)) { 65 console.log('Muki Floating TOC: 無效的內容選擇器,使用默認值');66 65 selectorContent = '.entry-content, article[class*="post-"], .post, .type-post, .page, .type-page'; 67 66 } … … 71 70 72 71 if (!$content || $content.length === 0) { 73 console.log('Muki Floating TOC: 未找到文章容器');74 72 return; 75 73 } 76 74 77 75 if ($toc.length === 0) { 78 console.log('Muki Floating TOC: 未找到 TOC 元素');79 76 return; 80 77 } 81 78 82 console.log('Muki Floating TOC: 找到文章容器', $content.prop('tagName'), $content.attr('class'));83 84 79 85 80 var excludeSelectors = getSafeSetting('excludeSelectors', '.single-author-box-container', 'string'); 86 if (isValidSelector(excludeSelectors)) { 87 console.log('Muki Floating TOC: 排除選擇器', excludeSelectors); 88 } else { 81 if (!isValidSelector(excludeSelectors)) { 89 82 excludeSelectors = '.single-author-box-container'; 90 console.log('Muki Floating TOC: 使用默認排除選擇器');91 83 } 92 84 … … 96 88 var $headings = $(); // Empty jQuery object to store headings 97 89 var headingsCache = []; // Cache for heading positions 98 var contentOffset, contentTop, contentLeft, contentWidth, contentHeight, contentBottom, tocHeight;99 90 100 91 // Generate unique ID generator for this TOC instance … … 132 123 133 124 134 $ (window).on('resize',function () {125 $window.on('resize', throttle(function () { 135 126 136 127 contentOffset = $content.offset(); … … 142 133 tocHeight = $toc.outerHeight(); 143 134 135 // Refresh cached heading positions after layout change 136 headingsCache = $headings.map(function () { 137 return $(this).offset().top; 138 }).get(); 144 139 145 140 positionTOC(); 146 } );141 }, 150)); 147 142 148 143 function initToolbar($toc) { … … 208 203 if (defaultPin === true || defaultPin === 'true' || defaultPin === 1 || defaultPin === '1') { 209 204 shouldPin = true; 210 console.log('Muki Floating TOC: 使用後台設定的預設固定狀態,設定值為:', defaultPin);211 205 } 212 206 } … … 228 222 229 223 // Use the pre-validated excludeSelectors variable from outer scope 230 console.log('Muki Floating TOC: 使用排除選擇器', excludeSelectors);231 224 232 225 233 226 var allHeadings = $content.find(headingSelectors); 234 console.log('Muki Floating TOC: 在文章容器內找到標題總數量', allHeadings.length);235 227 236 228 … … 246 238 247 239 if ($this.closest(selector).length > 0) { 248 console.log('Muki Floating TOC: 排除標題', $this.text(), '因為它在', selector, '內');249 240 return false; 250 241 } … … 256 247 }); 257 248 258 console.log('Muki Floating TOC: 排除後的標題數量', $headings.length);259 260 249 // Cache heading positions 261 250 headingsCache = $headings.map(function () { … … 265 254 266 255 if ($headings.length === 0) { 267 console.log('Muki Floating TOC: 未找到標題,添加默認線段');268 256 for (var i = 0; i < 5; i++) { 269 257 var $defaultItem = $('<div>', { … … 457 445 458 446 var positionLeft = getSafeSetting('positionLeft', true, 'boolean'); 447 var position; 459 448 460 449 if (positionLeft) { 461 462 var position = contentLeft - 60; 463 464 450 position = contentLeft - 60; 465 451 position = Math.max(10, position); 466 467 452 468 453 $toc.css({ … … 471 456 }); 472 457 } else { 473 474 var position = contentLeft + contentWidth + 20; 475 458 position = contentLeft + contentWidth + 20; 476 459 477 460 $toc.css({ … … 496 479 497 480 498 $ (document).on('click', 'a[href^="#"]', function (e) {481 $toc.on('click', 'a[href^="#"]', function (e) { 499 482 var href = $(this).attr('href'); 500 501 483 502 484 if (href === '#' || href.length <= 1) return; … … 506 488 e.preventDefault(); 507 489 508 509 490 var fixedHeaderHeight = getSafeSetting('fixedHeaderHeight', 0, 'number'); 510 511 512 491 var extraSpace = 20; 513 492 var offset = $target.offset().top - (fixedHeaderHeight + extraSpace);
Note: See TracChangeset
for help on using the changeset viewer.