Changeset 3218885
- Timestamp:
- 01/08/2025 10:11:59 AM (15 months ago)
- Location:
- aweos-offcanvas-menu/trunk
- Files:
-
- 1 added
- 5 edited
-
aweos-offcanvas-menu.php (modified) (6 diffs)
-
public/css/app.css (modified) (8 diffs)
-
public/css/style.css (added)
-
public/js/app.js (modified) (1 diff)
-
public/js/customize.js (modified) (4 diffs)
-
readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
aweos-offcanvas-menu/trunk/aweos-offcanvas-menu.php
r3121136 r3218885 3 3 Plugin Name: AWEOS Offcanvas Menu for Divi 4 4 Plugin URI: https://developer.wordpress.org/plugins/aweos-offcanvas-menu/ 5 Description: Displays an offcanvas menu 6 Version: 1.4.25 Description: Displays an offcanvas menu 6 Version: 2.0.0 7 7 Author: AWEOS GmbH 8 8 Author URI: https://aweos.de … … 13 13 */ 14 14 15 require_once(__DIR__.'/vendor/autoload.php'); 16 17 use MatthiasMullie\Minify; 15 // Ersetze Minify durch WordPress eigene Funktionen 16 function awoc_minify_css($css) { 17 // Entferne Kommentare 18 $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css); 19 // Entferne Leerzeichen 20 $css = str_replace(["\r\n", "\r", "\n", "\t", ' ', ' ', ' '], '', $css); 21 return $css; 22 } 18 23 19 24 function awoc_register_offcanvas_menu() … … 26 31 function awoc_offcanvas_asset() 27 32 { 28 wp_enqueue_style('awoc_offcanvas_style', plugin_dir_url(__FILE__) . 'public/css/app.css', null, '12' . time()); 29 if (! is_customize_preview()) { 30 wp_enqueue_script('awoc_offcanvas_script', plugin_dir_url(__FILE__) . 'public/js/app.js', ['jquery'], '12' . time(), true); 33 wp_enqueue_style('awoc_offcanvas_style', plugin_dir_url(__FILE__) . 'public/css/app.css', [], '1.4.3'); 34 35 if (!is_customize_preview()) { 36 wp_enqueue_script('awoc_offcanvas_script', plugin_dir_url(__FILE__) . 'public/js/app.js', ['jquery'], '1.4.3', true); 31 37 } 32 38 } … … 44 50 function awoc_offcanvas_customizer($wp_customize) 45 51 { 46 $colorControlClass = class_exists(ET_Divi_Customize_Color_Alpha_Control::class) 47 ? ET_Divi_Customize_Color_Alpha_Control::class 48 : WP_Customize_Color_Control 49 ; 50 51 $wp_customize->add_section('awoc_offcanvas_section', [ 52 $colorControlClass = 'WP_Customize_Color_Control'; 53 54 // Styling für Überschriften und Controls 55 $wp_customize->add_setting('awoc_customizer_styles', array( 56 'default' => '', 57 'sanitize_callback' => 'esc_html' 58 )); 59 60 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_customizer_styles', array( 61 'type' => 'hidden', 62 'section' => 'awoc_offcanvas_section', 63 'settings' => 'awoc_customizer_styles', 64 'priority' => 1, 65 'description' => '<style> 66 /* Styling für Gruppenüberschriften */ 67 .customize-control-hidden .customize-control-title { 68 font-size: 16px !important; 69 font-weight: 600 !important; 70 padding: 5px 0 5px !important; 71 border-bottom: 2px solid #00000069 !important; 72 margin-bottom: 5px !important; 73 color: #1e1e1e !important; 74 text-transform: uppercase !important; 75 } 76 77 /* Styling für einzelne Einstellungen */ 78 .customize-control:not([id*="_heading"]) .customize-control-title { 79 font-size: 13px !important; 80 font-weight: normal !important; 81 margin: 5px 0 !important; 82 color: #50575e !important; 83 } 84 85 /* Abstand zwischen Gruppen */ 86 .customize-control[id*="_heading"] { 87 margin-top: 10px !important; 88 } 89 90 /* Erste Gruppe braucht keinen extra Abstand */ 91 #customize-control-awoc_basic_heading { 92 margin-top: 0 !important; 93 } 94 95 /* Padding auf 0 setzen */ 96 .customize-control-checkbox, 97 .customize-control-nav_menu_auto_add .customize-inside-control-row, 98 .customize-control-nav_menu_auto_add > label { 99 padding: 0 !important; 100 padding-top: 2px !important; 101 102 } 103 </style>' 104 ))); 105 106 // Hauptsektion für Off-Canvas-Menu (unter Header & Navigation) 107 $wp_customize->add_section('awoc_offcanvas_section', array( 52 108 'title' => __('Off-Canvas-Menu', 'awoc_offcanvas'), 53 'panel' => 'et_divi_header_panel' 54 ]); 55 $wp_customize->add_setting('awoc_offcanvas_background_color_setting', array( 56 'title' => __('Background Color', 'awoc_offcanvas'), 57 'priority' => 30, 58 'default' => '#000000', 59 'transport' => 'postMessage' 60 )); 61 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_background_color_control', array( 62 'label' => __('Background Color', 'awoc_offcanvas'), 63 'section' => 'awoc_offcanvas_section', 64 'settings' => 'awoc_offcanvas_background_color_setting', 65 ))); 66 67 $wp_customize->add_setting('awoc_offcanvas_border_color_setting', array( 68 'title' => __('Border-Color between links', 'awoc_offcanvas'), 69 'priority' => 30, 70 'default' => '#c5c5c5', 71 'transport' => 'postMessage' 72 )); 73 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_border_color_control', array( 74 'label' => __('Border-Color between links', 'awoc_offcanvas'), 75 'section' => 'awoc_offcanvas_section', 76 'settings' => 'awoc_offcanvas_border_color_setting', 77 ))); 78 79 $wp_customize->add_setting('awoc_offcanvas_font_color_setting', array( 80 'title' => __('Font Color', 'awoc_offcanvas'), 81 'priority' => 30, 82 'default' => '#222', 83 'transport' => 'postMessage' 84 )); 85 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_font_color_control', array( 86 'label' => __('Font Color', 'awoc_offcanvas'), 87 'section' => 'awoc_offcanvas_section', 88 'settings' => 'awoc_offcanvas_font_color_setting', 89 ))); 90 91 $wp_customize->add_setting('awoc_offcanvas_border_right_color_setting', array( 92 'title' => __('Right border color', 'awoc_offcanvas'), 93 'priority' => 30, 94 'default' => '#ffffff', 95 'transport' => 'postMessage' 96 )); 97 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_border_right_color_control', array( 98 'label' => __('Right border color', 'awoc_offcanvas'), 99 'section' => 'awoc_offcanvas_section', 100 'settings' => 'awoc_offcanvas_border_right_color_setting', 101 ))); 102 103 $wp_customize->add_setting('awoc_offcanvas_open_font_setting', array( 104 'title' => __('Font color for open item', 'awoc_offcanvas'), 105 'priority' => 30, 106 'default' => '#444444', 107 'transport' => 'postMessage' 108 )); 109 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_open_font_control', array( 110 'label' => __('Font color for open item', 'awoc_offcanvas'), 111 'section' => 'awoc_offcanvas_section', 112 'settings' => 'awoc_offcanvas_open_font_setting', 113 ))); 114 115 $wp_customize->add_setting('awoc_offcanvas_open_background_setting', array( 116 'title' => __('Background color for open item', 'awoc_offcanvas'), 117 'priority' => 30, 118 'default' => 'orange', 119 'transport' => 'postMessage' 120 )); 121 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_open_background_control', array( 122 'label' => __('Background color for open item', 'awoc_offcanvas'), 123 'section' => 'awoc_offcanvas_section', 124 'settings' => 'awoc_offcanvas_open_background_setting', 125 ))); 126 127 $wp_customize->add_setting('awoc_offcanvas_display_border_setting', array( 128 'title' => __('Display right border', 'awoc_offcanvas'), 129 'priority' => 30, 130 'default' => 0, 131 'transport' => 'postMessage' 132 )); 133 $wp_customize->add_control('awoc_offcanvas_display_border_control', array( 134 'type' => 'checkbox', 135 'label' => __('Display right border', 'awoc_offcanvas'), 136 'section' => 'awoc_offcanvas_section', 137 'settings' => 'awoc_offcanvas_display_border_setting' 138 )); 139 140 $wp_customize->add_setting('awoc_offcanvas_submenu_background_setting', array( 141 'title' => __('Background for submenu', 'awoc_offcanvas'), 142 'priority' => 30, 143 'default' => '#dddddd', 144 'transport' => 'postMessage' 145 )); 146 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_submenu_background_control', array( 147 'label' => __('Background for submenu', 'awoc_offcanvas'), 148 'section' => 'awoc_offcanvas_section', 149 'settings' => 'awoc_offcanvas_submenu_background_setting', 150 ))); 151 152 $wp_customize->add_setting('awoc_offcanvas_right_arrow_background_setting', array( 153 'title' => __('Background for right arrow on main elements', 'awoc_offcanvas'), 154 'priority' => 30, 155 'default' => '#000', 156 'transport' => 'postMessage' 157 )); 158 $wp_customize->add_control(new $colorControlClass($wp_customize, 159 'awoc_offcanvas_right_arrow_background_control', array( 160 'label' => __('Background for right arrow on main elements', 'awoc_offcanvas'), 161 'section' => 'awoc_offcanvas_section', 162 'settings' => 'awoc_offcanvas_right_arrow_background_setting', 163 ))); 164 165 $wp_customize->add_setting('awoc_offcanvas_submenu_right_arrow_background_setting', array( 166 'title' => __('Background for right arrow on submenu elements', 'awoc_offcanvas'), 167 'priority' => 30, 168 'default' => '#333', 169 'transport' => 'postMessage' 170 )); 171 $wp_customize->add_control(new $colorControlClass($wp_customize, 172 'awoc_offcanvas_submenu_right_arrow_background_control', array( 173 'label' => __('Background for right arrow on submenu elements', 'awoc_offcanvas'), 174 'section' => 'awoc_offcanvas_section', 175 'settings' => 'awoc_offcanvas_submenu_right_arrow_background_setting', 176 ))); 177 178 $wp_customize->add_setting('awoc_offcanvas_right_arrow_font_color_setting', array( 179 'title' => __('Font color for right arrow', 'awoc_offcanvas'), 180 'priority' => 30, 181 'default' => '#333', 182 'transport' => 'postMessage' 183 )); 184 $wp_customize->add_control(new $colorControlClass($wp_customize, 185 'awoc_offcanvas_right_arrow_font_color_setting', array( 186 'label' => __('Font color for right arrow', 'awoc_offcanvas'), 187 'section' => 'awoc_offcanvas_section', 188 'settings' => 'awoc_offcanvas_right_arrow_font_color_setting', 189 ))); 190 191 $wp_customize->add_setting('awoc_offcanvas_scrollbar_thumb_setting', array( 192 'title' => __('Scrollbar thumb color', 'awoc_offcanvas'), 193 'priority' => 30, 194 'default' => '#ffffff', 195 'transport' => 'postMessage' 196 )); 197 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_scrollbar_thumb_control', array( 198 'label' => __('Scrollbar thumb color', 'awoc_offcanvas'), 199 'section' => 'awoc_offcanvas_section', 200 'settings' => 'awoc_offcanvas_scrollbar_thumb_setting', 201 ))); 202 203 /* Close button */ 204 $wp_customize->add_setting('awoc_offcanvas_close_background_setting', array( 205 'title' => __('Close button background', 'awoc_offcanvas'), 206 'priority' => 30, 207 'default' => '#222', 208 'transport' => 'postMessage' 209 )); 210 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_close_background_control', array( 211 'label' => __('Close button background', 'awoc_offcanvas'), 212 'section' => 'awoc_offcanvas_section', 213 'settings' => 'awoc_offcanvas_close_background_setting', 214 ))); 215 216 $wp_customize->add_setting('awoc_offcanvas_close_color_setting', array( 217 'title' => __('Close button color', 'awoc_offcanvas'), 218 'priority' => 30, 219 'default' => '#222', 220 'transport' => 'postMessage' 221 )); 222 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_close_color_control', array( 223 'label' => __('Close button color', 'awoc_offcanvas'), 224 'section' => 'awoc_offcanvas_section', 225 'settings' => 'awoc_offcanvas_close_color_setting', 226 ))); 227 228 /* Max Width */ 109 'panel' => 'et_divi_header_panel', 110 'priority' => 30 111 )); 112 113 // GRUPPE 1: GRUNDLEGENDE EINSTELLUNGEN (10-19) 114 $wp_customize->add_setting('awoc_basic_heading', array( 115 'default' => '', 116 'sanitize_callback' => 'esc_html' 117 )); 118 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_basic_heading', array( 119 'label' => '⚙️ ' . __('Basic Settings', 'awoc_offcanvas'), 120 'section' => 'awoc_offcanvas_section', 121 'settings' => 'awoc_basic_heading', 122 'type' => 'hidden', 123 'priority' => 10 124 ))); 125 229 126 $wp_customize->add_setting('awoc_offcanvas_max_width_setting', array( 230 'title' => __('Max width', 'awoc_offcanvas'), 231 'priority' => 30, 232 'default' => '768', 233 'transport' => 'postMessage' 234 )); 235 $wp_customize->add_control('awoc_offcanvas_max_width_control', array( 127 'default' => '980', 128 'transport' => 'refresh' 129 )); 130 $wp_customize->add_control('awoc_max_width_control', array( 236 131 'type' => 'text', 237 'label' => __('Max width', 'awoc_offcanvas'), 238 'section' => 'awoc_offcanvas_section', 239 'settings' => 'awoc_offcanvas_max_width_setting' 132 'label' => __('Max Width', 'awoc_offcanvas'), 133 'section' => 'awoc_offcanvas_section', 134 'settings' => 'awoc_offcanvas_max_width_setting', 135 'priority' => 13, 240 136 )); 241 137 242 138 $wp_customize->add_setting('awoc_offcanvas_always_active_setting', array( 243 'title' => __('Always active', 'awoc_offcanvas'),244 'priority' => 30,245 139 'default' => false, 246 'transport' => ' postMessage'247 )); 248 $wp_customize->add_control('awoc_offcanvas_always_active ', array(140 'transport' => 'refresh' 141 )); 142 $wp_customize->add_control('awoc_offcanvas_always_active_control', array( 249 143 'type' => 'checkbox', 250 144 'label' => __('Always active', 'awoc_offcanvas'), 251 145 'section' => 'awoc_offcanvas_section', 252 'settings' => 'awoc_offcanvas_always_active_setting' 253 )); 146 'settings' => 'awoc_offcanvas_always_active_setting', 147 'priority' => 12, 148 'description' => '<style> 149 input[type="checkbox"] { 150 display: none; /* Verstecke die Standard-Checkbox */ 151 } 152 153 input[type="checkbox"] + label { 154 position: relative; 155 padding-left: 25px; /* Platz für das benutzerdefinierte Design */ 156 cursor: pointer; 157 user-select: none; /* Verhindert Textauswahl */ 158 } 159 160 input[type="checkbox"] + label:before { 161 content: ""; 162 position: absolute; 163 left: 0; 164 top: 50%; 165 transform: translateY(-50%); 166 width: 16px; /* Breite der benutzerdefinierten Checkbox */ 167 height: 16px; /* Höhe der benutzerdefinierten Checkbox */ 168 border: 2px solid #2271b1; /* Rahmenfarbe */ 169 border-radius: 4px; /* Abgerundete Ecken */ 170 background: white; /* Hintergrundfarbe */ 171 } 172 173 input[type="checkbox"]:checked + label:before { 174 background: #2271b1; /* Hintergrundfarbe, wenn ausgewählt */ 175 border-color: #2271b1; /* Rahmenfarbe, wenn ausgewählt */ 176 } 177 178 input[type="checkbox"]:checked + label:after { 179 content: "✔"; /* Häkchen-Symbol */ 180 position: absolute; 181 left: 5px; /* Position des Häkchens */ 182 top: 50%; 183 transform: translateY(-50%); 184 color: white; /* Häkchenfarbe */ 185 font-size: 12px; /* Größe des Häkchens */ 186 } 187 </style>' 188 )); 189 190 // GRUPPE 2: HAUPTMENÜ-DESIGN (20-29) 191 $wp_customize->add_setting('awoc_main_menu_heading', array( 192 'default' => '', 193 'sanitize_callback' => 'esc_html' 194 )); 195 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_main_menu_heading', array( 196 'label' => '🎨 ' . __('Main Menu Design', 'awoc_offcanvas'), 197 'section' => 'awoc_offcanvas_section', 198 'settings' => 'awoc_main_menu_heading', 199 'type' => 'hidden', 200 'priority' => 20 201 ))); 202 203 $wp_customize->add_setting('awoc_offcanvas_background_color_setting', array( 204 'default' => '#000000', 205 'transport' => 'refresh' 206 )); 207 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_background_color_control', array( 208 'label' => __('Background Color', 'awoc_offcanvas'), 209 'section' => 'awoc_offcanvas_section', 210 'settings' => 'awoc_offcanvas_background_color_setting', 211 'priority' => 21 212 ))); 213 214 $wp_customize->add_setting('awoc_offcanvas_font_color_setting', array( 215 'default' => '#222', 216 'transport' => 'refresh' 217 )); 218 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_font_color_control', array( 219 'label' => __('Font Color', 'awoc_offcanvas'), 220 'section' => 'awoc_offcanvas_section', 221 'settings' => 'awoc_offcanvas_font_color_setting', 222 'priority' => 22 223 ))); 224 225 $wp_customize->add_setting('awoc_offcanvas_border_color_setting', array( 226 'default' => '#c5c5c5', 227 'transport' => 'refresh' 228 )); 229 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_border_color_control', array( 230 'label' => __('Border-Color between links', 'awoc_offcanvas'), 231 'section' => 'awoc_offcanvas_section', 232 'settings' => 'awoc_offcanvas_border_color_setting', 233 'priority' => 23 234 ))); 235 236 // GRUPPE 3: AKTIVE ELEMENTE (30-39) 237 $wp_customize->add_setting('awoc_active_items_heading', array( 238 'default' => '', 239 'sanitize_callback' => 'esc_html' 240 )); 241 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_active_items_heading', array( 242 'label' => '✨ ' . __('Active Items', 'awoc_offcanvas'), 243 'section' => 'awoc_offcanvas_section', 244 'settings' => 'awoc_active_items_heading', 245 'type' => 'hidden', 246 'priority' => 30 247 ))); 248 249 $wp_customize->add_setting('awoc_offcanvas_open_font_setting', array( 250 'default' => '#444444', 251 'transport' => 'refresh' 252 )); 253 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_open_font_control', array( 254 'label' => __('Font color for open item', 'awoc_offcanvas'), 255 'section' => 'awoc_offcanvas_section', 256 'settings' => 'awoc_offcanvas_open_font_setting', 257 'priority' => 31 258 ))); 259 260 $wp_customize->add_setting('awoc_offcanvas_open_background_setting', array( 261 'default' => 'orange', 262 'transport' => 'refresh' 263 )); 264 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_open_background_control', array( 265 'label' => __('Background Color for open Item', 'awoc_offcanvas'), 266 'section' => 'awoc_offcanvas_section', 267 'settings' => 'awoc_offcanvas_open_background_setting', 268 'priority' => 32 269 ))); 270 271 // GRUPPE 4: UNTERMENÜ-DESIGN (40-49) 272 $wp_customize->add_setting('awoc_submenu_heading', array( 273 'default' => '', 274 'sanitize_callback' => 'esc_html' 275 )); 276 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_submenu_heading', array( 277 'label' => '📑 ' . __('Submenu Design', 'awoc_offcanvas'), 278 'section' => 'awoc_offcanvas_section', 279 'settings' => 'awoc_submenu_heading', 280 'type' => 'hidden', 281 'priority' => 40 282 ))); 283 284 $wp_customize->add_setting('awoc_offcanvas_submenu_background_setting', array( 285 'default' => '#dddddd', 286 'transport' => 'refresh' 287 )); 288 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_submenu_background_control', array( 289 'label' => __('Background for submenu', 'awoc_offcanvas'), 290 'section' => 'awoc_offcanvas_section', 291 'settings' => 'awoc_offcanvas_submenu_background_setting', 292 'priority' => 41 293 ))); 294 295 $wp_customize->add_setting('awoc_offcanvas_right_arrow_background_setting', array( 296 'default' => '#000', 297 'transport' => 'refresh' 298 )); 299 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_right_arrow_background_control', array( 300 'label' => __('Background for right arrow on main elements', 'awoc_offcanvas'), 301 'section' => 'awoc_offcanvas_section', 302 'settings' => 'awoc_offcanvas_right_arrow_background_setting', 303 'priority' => 42 304 ))); 305 306 $wp_customize->add_setting('awoc_offcanvas_submenu_right_arrow_background_setting', array( 307 'default' => '#333', 308 'transport' => 'refresh' 309 )); 310 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_submenu_right_arrow_background_control', array( 311 'label' => __('Background for right arrow on submenu elements', 'awoc_offcanvas'), 312 'section' => 'awoc_offcanvas_section', 313 'settings' => 'awoc_offcanvas_submenu_right_arrow_background_setting', 314 'priority' => 43 315 ))); 316 317 $wp_customize->add_setting('awoc_offcanvas_right_arrow_font_color_setting', array( 318 'default' => '#333', 319 'transport' => 'refresh' 320 )); 321 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_right_arrow_font_color_control', array( 322 'label' => __('Font color for right arrow', 'awoc_offcanvas'), 323 'section' => 'awoc_offcanvas_section', 324 'settings' => 'awoc_offcanvas_right_arrow_font_color_setting', 325 'priority' => 44 326 ))); 327 328 // GRUPPE 5: RECHTE BORDER (50-59) 329 $wp_customize->add_setting('awoc_right_border_heading', array( 330 'default' => '', 331 'sanitize_callback' => 'esc_html' 332 )); 333 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_right_border_heading', array( 334 'label' => '↔️ ' . __('Right Border', 'awoc_offcanvas'), 335 'section' => 'awoc_offcanvas_section', 336 'settings' => 'awoc_right_border_heading', 337 'type' => 'hidden', 338 'priority' => 50 339 ))); 340 341 $wp_customize->add_setting('awoc_offcanvas_show_right_border_setting', array( 342 'default' => true, 343 'transport' => 'refresh' 344 )); 345 $wp_customize->add_control('awoc_offcanvas_show_right_border_control', array( 346 'type' => 'checkbox', 347 'label' => __('Display Right Border', 'awoc_offcanvas'), 348 'section' => 'awoc_offcanvas_section', 349 'settings' => 'awoc_offcanvas_show_right_border_setting', 350 'priority' => 51 351 )); 352 353 $wp_customize->add_setting('awoc_offcanvas_border_right_color_setting', array( 354 'default' => '#ffffff', 355 'transport' => 'refresh' 356 )); 357 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_border_right_color_control', array( 358 'label' => __('Right Border Color', 'awoc_offcanvas'), 359 'section' => 'awoc_offcanvas_section', 360 'settings' => 'awoc_offcanvas_border_right_color_setting', 361 'priority' => 52 362 ))); 363 364 $wp_customize->add_setting('awoc_offcanvas_right_border_width_setting', array( 365 'default' => '1', 366 'transport' => 'refresh' 367 )); 368 $wp_customize->add_control('awoc_offcanvas_right_border_width_control', array( 369 'type' => 'range', 370 'label' => __('Right Border Width', 'awoc_offcanvas'), 371 'section' => 'awoc_offcanvas_section', 372 'settings' => 'awoc_offcanvas_right_border_width_setting', 373 'input_attrs' => array( 374 'min' => 1, 375 'max' => 10, 376 'step' => 1, 377 'class' => 'awoc-range-slider' 378 ), 379 'priority' => 53, 380 'description' => '<style> 381 .customize-control input[type=range] { 382 width: 100% !important; 383 accent-color: #2271b1; 384 } 385 .awoc-range-tooltip { 386 background: #2271b1; 387 color: white; 388 padding: 2px 8px; 389 border-radius: 4px; 390 font-size: 12px; 391 display: inline-block; 392 margin-left: 0px; 393 vertical-align: start; 394 } 395 </style> 396 <span class="awoc-range-tooltip">1px</span> 397 <script> 398 jQuery(document).ready(function($) { 399 var rangeInput = $("#customize-control-awoc_offcanvas_right_border_width_control input[type=range]"); 400 var tooltip = $("#customize-control-awoc_offcanvas_right_border_width_control .awoc-range-tooltip"); 401 402 // Initial value 403 tooltip.text(rangeInput.val() + "px"); 404 405 // Update on change 406 rangeInput.on("input change", function() { 407 tooltip.text($(this).val() + "px"); 408 }); 409 }); 410 </script>' 411 )); 412 413 // GRUPPE 6: UI ELEMENTE (60-69) 414 $wp_customize->add_setting('awoc_ui_elements_heading', array( 415 'default' => '', 416 'sanitize_callback' => 'esc_html' 417 )); 418 $wp_customize->add_control(new WP_Customize_Control($wp_customize, 'awoc_ui_elements_heading', array( 419 'label' => '🔧 ' . __('UI Elements', 'awoc_offcanvas'), 420 'section' => 'awoc_offcanvas_section', 421 'settings' => 'awoc_ui_elements_heading', 422 'type' => 'hidden', 423 'priority' => 60 424 ))); 425 426 $wp_customize->add_setting('awoc_offcanvas_scrollbar_thumb_setting', array( 427 'default' => '#ffffff', 428 'transport' => 'refresh' 429 )); 430 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_scrollbar_thumb_control', array( 431 'label' => __('Scrollbar thumb color', 'awoc_offcanvas'), 432 'section' => 'awoc_offcanvas_section', 433 'settings' => 'awoc_offcanvas_scrollbar_thumb_setting', 434 'priority' => 61 435 ))); 436 437 $wp_customize->add_setting('awoc_offcanvas_close_background_setting', array( 438 'default' => '#222222', 439 'transport' => 'refresh' 440 )); 441 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_close_background_control', array( 442 'label' => __('Close button background', 'awoc_offcanvas'), 443 'section' => 'awoc_offcanvas_section', 444 'settings' => 'awoc_offcanvas_close_background_setting', 445 'priority' => 62 446 ))); 447 448 $wp_customize->add_setting('awoc_offcanvas_close_color_setting', array( 449 'default' => '#222', 450 'transport' => 'refresh' 451 )); 452 $wp_customize->add_control(new $colorControlClass($wp_customize, 'awoc_offcanvas_close_color_control', array( 453 'label' => __('Close button color', 'awoc_offcanvas'), 454 'section' => 'awoc_offcanvas_section', 455 'settings' => 'awoc_offcanvas_close_color_setting', 456 'priority' => 63 457 ))); 254 458 } 255 459 add_action('customize_register', 'awoc_offcanvas_customizer', 1, 100); 256 460 461 function awoc_generate_inline_css() { 462 $always_active = get_theme_mod('awoc_offcanvas_always_active_setting', false); 463 $max_width = get_theme_mod('awoc_offcanvas_max_width_setting', '980'); 464 $always_active = filter_var($always_active, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); 465 $max_width = absint($max_width); 466 467 // Hole den Status der Right Border Checkbox 468 $show_right_border = get_theme_mod('awoc_offcanvas_show_right_border_setting', true); 469 $right_border_color = get_theme_mod('awoc_offcanvas_border_right_color_setting', '#ffffff'); 470 471 $css = ' 472 #offcanvas_container { 473 background-color: ' . get_theme_mod('awoc_offcanvas_background_color_setting', '#000000') . '; 474 } 475 '; 476 477 // Right Border CSS nur wenn aktiviert 478 if ($show_right_border) { 479 $css .= ' 480 #offcanvas_container { 481 border-right: 1px solid ' . $right_border_color . '; 482 } 483 '; 484 } 485 486 if ($always_active === true) { 487 // Always Active Mode CSS 488 $css .= ' 489 /* Force hide default menu and show mobile menu when always active */ 490 @media (min-width: 981px) { 491 #et_mobile_nav_menu { 492 display: block !important; 493 } 494 #top-menu-nav, #top-menu { 495 display: none !important; 496 } 497 } 498 '; 499 } else { 500 // Custom breakpoint CSS 501 $css .= ' 502 /* Custom responsive breakpoint */ 503 @media (max-width: ' . $max_width . 'px) { 504 #et_mobile_nav_menu { 505 display: block !important; 506 } 507 #top-menu-nav, #top-menu { 508 display: none !important; 509 } 510 } 511 @media (min-width: ' . ($max_width + 1) . 'px) { 512 #et_mobile_nav_menu { 513 display: none !important; 514 } 515 #top-menu-nav, #top-menu { 516 display: block !important; 517 } 518 } 519 '; 520 } 521 522 // Rest des bestehenden CSS 523 $css .= ' 524 #offcanvas_container .ps__rail-y { 525 background-color: ' . get_theme_mod('awoc_offcanvas_border_right_color_setting', '#ffffff') . '; 526 } 527 528 #offcanvas_container .ps__thumb-y { 529 background-color: ' . get_theme_mod('awoc_offcanvas_scrollbar_thumb_setting', '#ffffff') . '; 530 } 531 532 #offcanvas_menu_inner li.menu-item > a { 533 border-bottom: 1px ' . get_theme_mod('awoc_offcanvas_border_color_setting', '#c5c5c5') . ' solid; 534 color: ' . get_theme_mod('awoc_offcanvas_font_color_setting', '#222') . '; 535 } 536 537 #offcanvas_menu_inner li.menu-item.visible > a { 538 color: ' . get_theme_mod('awoc_offcanvas_open_font_setting', '#444444') . '; 539 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; 540 } 541 542 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a, 543 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > ul.sub-menu li.menu-item.menu-item-has-children.visible > a { 544 color: ' . get_theme_mod('awoc_offcanvas_open_font_setting', '#FF5733') . '; /* Schriftfarbe für den Hauptmenüpunkt und alle übergeordneten Punkte */ 545 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; /* Hintergrundfarbe für den Hauptmenüpunkt */ 546 } 547 548 #offcanvas_menu_inner .sub-menu { 549 background-color: ' . get_theme_mod('awoc_offcanvas_submenu_background_setting', '#dddddd') . '; 550 } 551 552 #offcanvas_menu_inner li.menu-item-has-children > a:after { 553 color: ' . get_theme_mod('awoc_offcanvas_right_arrow_font_color_setting', '#333') . '; 554 } 555 556 #offcanvas_container .close-sidebar-inner { 557 background-color: ' . get_theme_mod('awoc_offcanvas_close_background_setting', '#222222') . '; 558 color: ' . get_theme_mod('awoc_offcanvas_close_color_setting', '#222') . '; 559 } 560 561 // Check 562 #offcanvas_menu_inner li.menu-item.menu-item-has-children.visible > a { 563 color: ' . get_theme_mod('awoc_offcanvas_open_font_setting', '#444444') . '; /* Schriftfarbe für den Hauptmenüpunkt */ 564 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; /* Hintergrundfarbe für den Hauptmenüpunkt */ 565 } 566 567 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a { 568 color: ' . get_theme_mod('awoc_offcanvas_open_font_setting', '#444444') . '; /* Schriftfarbe für den Hauptmenüpunkt */ 569 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; /* Hintergrundfarbe für den Hauptmenüpunkt */ 570 } 571 '; 572 573 $css .= ' 574 /* Pfeil-Styling - Basis für alle Pfeile */ 575 #offcanvas_menu_inner li.menu-item-has-children > a { 576 position: relative; 577 padding-right: 40px; 578 } 579 580 #offcanvas_menu_inner li.menu-item-has-children > a:after { 581 content: "\\f054"; 582 font-family: "FontAwesome"; 583 position: absolute; 584 right: 15px; 585 top: 50%; 586 transform: translateY(-50%) scale(0.7); 587 font-size: 14px; 588 line-height: 1; 589 text-align: center; 590 } 591 592 /* Hauptmenü-Pfeile mit Kreis */ 593 #offcanvas_container #offcanvas_menu_inner > li.menu-item-has-children > a:after { 594 background-color: ' . get_theme_mod('awoc_offcanvas_right_arrow_background_setting', '#000') . '; 595 border-radius: 0; 596 width: 25px; 597 height: 0; 598 display: flex; 599 align-items: center; 600 justify-content: center; 601 padding: 0; 602 margin-right: 0; 603 color: #ffffff; 604 } 605 606 /* Untermenü-Pfeile */ 607 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children > a:after { 608 background-color: ' . get_theme_mod('awoc_offcanvas_submenu_right_arrow_background_setting', '#333') . '; 609 border-radius: 0; 610 width: 25px; 611 height: 0; 612 display: flex; 613 align-items: center; 614 justify-content: center; 615 padding: 12px; 616 margin-right: 5px; 617 color: #ffffff; 618 } 619 620 #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 621 transform: translateY(-50%) rotate(90deg); 622 transition: transform 0.2s ease; 623 } 624 625 #offcanvas_menu_inner .sub-menu { 626 display: none; 627 margin-left: 0; 628 margin-top: 0; 629 margin-bottom: 0; 630 padding: 0; 631 } 632 633 /* Verbesserte Struktur für verschachtelte Menüs */ 634 #offcanvas_menu_inner li.menu-item-has-children { 635 position: relative; 636 } 637 638 /* Vertikale Linien */ 639 #offcanvas_menu_inner .sub-menu { 640 position: relative; 641 margin-left: 20px; 642 // border-left: 0px solid ' . get_theme_mod('awoc_offcanvas_border_color_setting', '#c5c5c5') . '; 643 margin-top: 0; 644 margin-bottom: 0; 645 padding-top: 0; 646 padding-bottom: 0; 647 } 648 649 /* Einrückungen für alle Ebenen */ 650 #offcanvas_menu_inner .sub-menu li > a { 651 padding-left: 0; 652 display: block; 653 } 654 655 /* Hintergrundfarben */ 656 #offcanvas_menu_inner .sub-menu li > a { 657 background-color: ' . get_theme_mod('awoc_offcanvas_submenu_background_setting', '#dddddd') . '; 658 } 659 660 /* Letztes Element in jedem Untermenü */ 661 #offcanvas_menu_inner .sub-menu li:last-child > a { 662 border-bottom: none; 663 } 664 665 /* Container für Untermenüs */ 666 #offcanvas_menu_inner .sub-menu { 667 display: none; 668 background-color: ' . get_theme_mod('awoc_offcanvas_submenu_background_setting', '#dddddd') . '; 669 } 670 671 /* Open Item Background */ 672 #offcanvas_menu_inner li.menu-item.visible > a { 673 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; 674 } 675 '; 676 677 /* Scrollbar Styling */ 678 $css .= ' 679 #offcanvas_container { 680 scrollbar-width: thin; 681 scrollbar-color: ' . get_theme_mod('awoc_offcanvas_scrollbar_thumb_setting', '#ffffff') . ' transparent; 682 } 683 684 #offcanvas_container::-webkit-scrollbar { 685 width: 8px; 686 } 687 688 #offcanvas_container::-webkit-scrollbar-track { 689 background: transparent; 690 } 691 692 #offcanvas_container::-webkit-scrollbar-thumb { 693 background-color: ' . get_theme_mod('awoc_offcanvas_scrollbar_thumb_setting', '#ffffff') . '; 694 border-radius: 4px; 695 } 696 '; 697 698 $css .= ' 699 /* ETmodules Icon Styles */ 700 #offcanvas_container #offcanvas_menu_inner > li.menu-item-has-children > a:after { 701 content: "5"; 702 transform: rotate(0deg); 703 transition: transform 0.2s; 704 font-family: ETmodules !important; 705 text-shadow: 0 0; 706 font-style: normal; 707 font-variant: normal; 708 -webkit-font-smoothing: antialiased; 709 -moz-osx-font-smoothing: grayscale; 710 text-transform: none; 711 speak: none; 712 vertical-align: middle; 713 height: 0; 714 width: 40px; 715 display: flex; 716 justify-content: center; 717 align-items: center; 718 font-size: 1.3rem; 719 background-color: ' . get_theme_mod('awoc_offcanvas_arrow_background_setting', '#7cba3d') . '; 720 border-radius: 3px; 721 margin-right: 5px; 722 color: #ffffff; 723 } 724 '; 725 726 /* Hauptmenü-Pfeile */ 727 $css .= ' 728 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a:after { 729 content: "5"; 730 font-family: ETmodules !important; 731 position: absolute; 732 right: 0; 733 top: 50%; 734 transform: translateY(-50%); 735 width: auto; 736 height: auto; 737 font-size: 1.3rem; 738 display: flex; 739 justify-content: center; 740 align-items: center; 741 background-color: ' . get_theme_mod('awoc_offcanvas_right_arrow_background_setting', '#000') . ' !important; 742 color: #ffffff; 743 transition: transform 0.2s; 744 -webkit-font-smoothing: antialiased; 745 -moz-osx-font-smoothing: grayscale; 746 } 747 748 /* Untermenü-Pfeile */ 749 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu li.menu-item-has-children > a:after { 750 content: "5"; 751 font-family: ETmodules !important; 752 position: absolute; 753 right: 0; 754 top: 50%; 755 transform: translateY(-50%); 756 width: auto; 757 height: auto; 758 font-size: 1.3rem; 759 display: flex; 760 justify-content: center; 761 align-items: center; 762 background-color: ' . get_theme_mod('awoc_offcanvas_submenu_right_arrow_background_setting', '#333') . ' !important; 763 color: #ffffff; 764 transition: transform 0.2s; 765 -webkit-font-smoothing: antialiased; 766 -moz-osx-font-smoothing: grayscale; 767 } 768 769 /* Gemeinsame Rotation */ 770 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 771 transform: translateY(-50%) rotate(90deg); 772 } 773 '; 774 775 return awoc_minify_css($css); 776 } 777 257 778 add_action('wp_head', 'awoc_offcanvas_inline_style'); 258 function awoc_offcanvas_inline_style() 259 { 260 $loader = new Twig_Loader_Filesystem(__DIR__); 261 $twig = new Twig_Environment($loader); 262 263 $css = $twig->render('aweos-offcanvas-menu.css', [ 264 'displayBorder' => get_theme_mod('awoc_offcanvas_display_border_setting', true), 265 'borderRightColor' => get_theme_mod('awoc_offcanvas_border_right_color_setting', '#000033'), 266 'borderColor' => get_theme_mod('awoc_offcanvas_border_color_setting', '#c5c5c5'), 267 'backgroundColor' => get_theme_mod('awoc_offcanvas_background_color_setting', '#333'), 268 'submenuBackground' => get_theme_mod('awoc_offcanvas_submenu_background_setting', '#ddd'), 269 'maxWidth' => get_theme_mod('awoc_offcanvas_max_width_setting', 980), 270 'alwaysActive' => get_theme_mod('awoc_offcanvas_always_active_setting', false), 271 'scrollbarThumb' => get_theme_mod('awoc_offcanvas_scrollbar_thumb_setting', '#000066'), 272 'fontColor' => get_theme_mod('awoc_offcanvas_font_color_setting', '#222'), 273 'closeColor' => get_theme_mod('awoc_offcanvas_close_color_setting', '#222'), 274 'closeBackground' => get_theme_mod('awoc_offcanvas_close_background_setting', '#eee'), 275 'openFont' => get_theme_mod('awoc_offcanvas_open_font_setting', '#eee'), 276 'openBackground' => get_theme_mod('awoc_offcanvas_open_background_setting', '#228ADA'), 277 'rightArrowBackground' => get_theme_mod('awoc_offcanvas_submenu_right_arrow_background_setting', '#000000'), 278 'rightArrowFontColor' => get_theme_mod('awoc_offcanvas_right_arrow_font_color_setting', '#ffffff'), 279 ]); 280 281 $minifier = new Minify\CSS(); 282 $minifier->add($css); 283 779 function awoc_offcanvas_inline_style() { 284 780 echo '<style type="text/css">'; 285 echo $minifier->minify();781 echo awoc_generate_inline_css(); 286 782 echo '</style>'; 287 783 } … … 290 786 function awoc_display_offcanvas_menu() 291 787 { 292 echo '<div id="offcanvas_container" data-max="'.((!get_theme_mod('awoc_offcanvas_always_active_setting', false)) ? get_theme_mod('awoc_offcanvas_max_width_setting', 980) : 'false').'">'; 293 echo '<div class="close-sidebar-inner"><span>Schließen</span><span class="fa fa-close"></span></div>'; 788 error_log('=== AWOC PHP DEBUG START ==='); 789 790 // Hole die Werte aus den Theme Mods 791 $always_active = get_theme_mod('awoc_offcanvas_always_active_setting', false); 792 $max_width = get_theme_mod('awoc_offcanvas_max_width_setting', '980'); 793 794 error_log('AWOC: Raw always_active = ' . var_export($always_active, true)); 795 error_log('AWOC: Raw max_width = ' . var_export($max_width, true)); 796 797 // Explizite Typumwandlung und Validierung 798 $max_width = absint($max_width); 799 // Stellen Sie sicher, dass $always_active wirklich ein Boolean ist 800 $always_active = filter_var($always_active, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); 801 802 error_log('AWOC: Converted always_active = ' . var_export($always_active, true)); 803 error_log('AWOC: Converted max_width = ' . var_export($max_width, true)); 804 805 // Setze data-max nur auf 'false' wenn always_active true ist 806 $data_max = $always_active === true ? 'false' : (string)$max_width; 807 808 error_log('AWOC: Final data_max = ' . var_export($data_max, true)); 809 810 // Debug-Kommentare im HTML 811 echo "<!-- AWOC Debug Start -->\n"; 812 echo "<!-- always_active (raw): " . esc_html(var_export($always_active, true)) . " -->\n"; 813 echo "<!-- max_width (raw): " . esc_html(var_export($max_width, true)) . " -->\n"; 814 echo "<!-- data_max: " . esc_html(var_export($data_max, true)) . " -->\n"; 815 816 echo '<div id="offcanvas_container" data-max="' . esc_attr($data_max) . '">'; 817 echo '<div class="close-sidebar-inner"><span>Schließen</span><span class="fa"></span></div>'; 294 818 echo wp_nav_menu([ 295 819 'theme_location' => 'offcanvas-menu', … … 318 842 ]); 319 843 } 844 845 // Füge das generierte CSS zum Header hinzu 846 add_action('wp_head', 'awoc_generate_custom_css'); 847 function awoc_generate_custom_css() { 848 ?> 849 <style type="text/css"> 850 /* Basis-Styles für das Offcanvas-Menü */ 851 #offcanvas_container { 852 background-color: <?php echo get_theme_mod('awoc_offcanvas_background_color_setting', '#000000'); ?>; 853 <?php if(get_theme_mod('awoc_offcanvas_show_right_border_setting', true)): ?> 854 border-right: <?php echo get_theme_mod('awoc_offcanvas_right_border_width_setting', '1'); ?>px solid <?php echo get_theme_mod('awoc_offcanvas_border_right_color_setting', '#ffffff'); ?> !important; 855 <?php endif; ?> 856 } 857 858 #offcanvas_menu_inner li.menu-item > a { 859 color: <?php echo get_theme_mod('awoc_offcanvas_font_color_setting', '#ffffff'); ?>; 860 border-bottom: 1px solid <?php echo get_theme_mod('awoc_offcanvas_border_color_setting', '#c5c5c5'); ?>; 861 } 862 863 #offcanvas_menu_inner li.menu-item.visible > a { 864 background-color: <?php echo get_theme_mod('awoc_offcanvas_active_bg_setting', '#orange'); ?>; 865 color: <?php echo get_theme_mod('awoc_offcanvas_active_color_setting', '#ffffff'); ?>; 866 } 867 868 /* Close Button Styles - Spezifischere Selektoren */ 869 body #offcanvas_container .close-sidebar-inner, 870 html body #offcanvas_container div.close-sidebar-inner { 871 background: <?php echo get_theme_mod('awoc_offcanvas_close_background_setting', '#222222'); ?> !important; 872 background-color: <?php echo get_theme_mod('awoc_offcanvas_close_background_setting', '#222222'); ?> !important; 873 } 874 875 #offcanvas_container .close-sidebar-inner span { 876 color: <?php echo get_theme_mod('awoc_offcanvas_close_color_setting', '#ffffff'); ?> !important; 877 } 878 879 /* Always Active Styles */ 880 <?php if(get_theme_mod('awoc_offcanvas_always_active_setting', false)): ?> 881 @media (min-width: 981px) { 882 #et_mobile_nav_menu { 883 display: block !important; 884 } 885 #top-menu-nav, #top-menu { 886 display: none !important; 887 } 888 } 889 <?php else: ?> 890 /* Custom Max Width Breakpoint */ 891 @media (max-width: <?php echo get_theme_mod('awoc_offcanvas_max_width_setting', '980'); ?>px) { 892 #et_mobile_nav_menu { 893 display: block !important; 894 } 895 #top-menu-nav, #top-menu { 896 display: none !important; 897 } 898 } 899 @media (min-width: <?php echo get_theme_mod('awoc_offcanvas_max_width_setting', '980'); ?>px) { 900 #et_mobile_nav_menu { 901 display: none !important; 902 } 903 #top-menu-nav, #top-menu { 904 display: block !important; 905 } 906 } 907 <?php endif; ?> 908 </style> 909 <?php 910 } 911 912 // Füge das JavaScript für die Menü-Interaktion hinzu 913 add_action('wp_footer', 'awoc_add_menu_interaction_script'); 914 function awoc_add_menu_interaction_script() { 915 ?> 916 <script> 917 jQuery(document).ready(function($) { 918 // Füge Click/Touch Event Handler hinzu 919 $('#offcanvas_menu_inner li.menu-item-has-children > a').on('click touchend', function(e) { 920 e.preventDefault(); // Verhindere Standard-Link-Verhalten 921 922 var $menuItem = $(this).parent(); 923 var $subMenu = $menuItem.children('.sub-menu'); 924 var $arrow = $(this).find('.et-pb-arrow-down'); 925 926 // Toggle active class und rotate arrow 927 $menuItem.toggleClass('visible'); 928 929 // Slide toggle für smooth animation 930 $subMenu.slideToggle(300); 931 932 return false; 933 }); 934 935 // Verhindere Bubble-Up von Touch-Events auf Links ohne Untermenüs 936 $('#offcanvas_menu_inner li:not(.menu-item-has-children) > a').on('click touchend', function(e) { 937 // Erlaube normales Link-Verhalten 938 return true; 939 }); 940 }); 941 </script> 942 943 <style> 944 /* Pfeil-Styling */ 945 #offcanvas_menu_inner li.menu-item-has-children > a:after { 946 content: "3"; 947 font-family: ETmodules !important; 948 font-size: 16px; 949 position: absolute; 950 right: 10px; 951 top: 50%; 952 transform: translateY(-50%) rotate(0deg); 953 transition: transform 0.3s ease; 954 } 955 956 /* Gedrehter Pfeil für sichtbare Untermenüs */ 957 #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 958 transform: translateY(-50%) rotate(180deg); 959 } 960 961 /* Untermenü-Styling */ 962 #offcanvas_menu_inner .sub-menu { 963 display: none; /* Initial versteckt */ 964 padding-left: 20px; 965 } 966 967 /* Hover-Effekte für bessere UX */ 968 #offcanvas_menu_inner li.menu-item-has-children > a { 969 position: relative; 970 cursor: pointer; 971 } 972 973 #offcanvas_menu_inner li.menu-item-has-children > a:hover:after { 974 opacity: 0.8; 975 } 976 977 /* Touch-Geräte Optimierung */ 978 @media (hover: none) { 979 #offcanvas_menu_inner li.menu-item-has-children > a { 980 -webkit-tap-highlight-color: transparent; 981 } 982 } 983 </style> 984 <?php 985 } -
aweos-offcanvas-menu/trunk/public/css/app.css
r2056606 r3218885 1 1 /* Disable default Divi menu */ 2 2 3 #mobile_menu {3 .et_mobile_menu { 4 4 display: none !important; 5 visibility: hidden; 5 6 } 6 7 … … 58 59 59 60 #offcanvas_container #offcanvas_menu_inner > li.menu-item > a { 61 display: flex; 62 justify-content: space-between; 63 align-items: center; 64 padding: 10px 15px; 65 min-height: 40px; 66 font-weight: 400; 67 font-family: Arial; 68 font-size: 13.5px; 69 cursor: pointer; 70 width: 100%; 71 position: relative; 72 } 73 74 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children { 75 display: flex; 76 flex-wrap: wrap; 77 } 78 79 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a { 80 width: 100%; 81 display: flex; 82 flex-direction: row; 83 justify-content: space-between; 84 transition: background-color 0.2s; 85 } 86 87 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a:after { 88 content: "5"; 89 -webkit-transform: rotate(0deg); 90 transform: rotate(0deg); 91 transition: -webkit-transform 0.2s; 92 transition: transform 0.2s; 93 transition: transform 0.2s, -webkit-transform 0.2s; 94 font-family: ETmodules; 95 text-shadow: 0 0; 96 font-style: normal; 97 font-variant: normal; 98 -webkit-font-smoothing: antialiased; 99 -moz-osx-font-smoothing: grayscale; 100 line-height: 1; 101 text-transform: none; 102 speak: none; 103 vertical-align: middle; 104 height: auto; 105 width: auto; 106 display: flex; 107 justify-content: center; 108 align-items: center; 109 font-size: 1.3rem; 110 margin: 0; 111 } 112 113 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a { 114 transition: background-color 0.2s; 115 } 116 117 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a:after { 118 transform: translateY(-50%) rotate(90deg); 119 } 120 121 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu { 122 display: none; 123 padding-left: 0; 124 flex-basis: 100%; 125 126 } 127 128 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > a { 60 129 font-weight: 400; 61 130 font-family: Arial; … … 64 133 line-height: 40px; 65 134 display: block; 66 padding: 0 10px 0 15px;67 } 68 69 #offcanvas_container #offcanvas_menu_inner > li.menu-item .menu-item-has-children {135 padding: 0 10px 0 25px; 136 } 137 138 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children { 70 139 display: flex; 71 140 flex-wrap: wrap; 72 141 } 73 142 74 #offcanvas_container #offcanvas_menu_inner > li.menu-item .menu-item-has-children > a {143 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children > a { 75 144 width: 100%; 76 display: block;77 145 display: flex; 78 146 flex-direction: row; … … 81 149 } 82 150 83 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a:after { 151 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children > a:after { 152 content: "5"; 153 font-family: ETmodules !important; 154 position: absolute; 155 right: 0; 156 top: 50%; 157 transform: translateY(-50%); 158 width: auto; 159 height: auto; 160 font-size: 1.3rem; 161 display: flex; 162 justify-content: center; 163 align-items: center; 164 background-color: ' . get_theme_mod('awoc_offcanvas_right_arrow_background_setting', '#7cba3d') . ' !important; 165 color: #ffffff; 166 transition: transform 0.2s; 167 -webkit-font-smoothing: antialiased; 168 -moz-osx-font-smoothing: grayscale; 169 } 170 171 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children.visible > a { 172 transition: background-color 0.2s; 173 } 174 175 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children.visible > a:after { 176 transform: translateY(-50%) rotate(90deg); 177 } 178 179 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu { 180 display: none; 181 padding-left: 0; 182 flex-basis: 100%; 183 } 184 185 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li > a { 186 font-weight: 400; 187 font-family: Arial; 188 font-size: 13.5px; 189 cursor: pointer; 190 line-height: 40px; 191 display: block; 192 padding: 0 10px 0 35px; 193 } 194 195 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children { 196 display: flex; 197 flex-wrap: wrap; 198 } 199 200 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children > a { 201 width: 100%; 202 display: flex; 203 flex-direction: row; 204 justify-content: space-between; 205 transition: background-color 0.2s; 206 } 207 208 /* Styling für den Pfeil im Untermenü */ 209 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children > a:after { 210 content: "5"; 211 font-family: ETmodules !important; 212 position: absolute; 213 right: 0; 214 top: 50%; 215 transform: translateY(-50%); 216 width: auto; 217 height: auto; 218 font-size: 1.3rem; 219 display: flex; 220 justify-content: center; 221 align-items: center; 222 background-color: ' . get_theme_mod('awoc_offcanvas_right_arrow_submenu_background_setting', '#7cba3d') . ' !important; 223 color: #ffffff; 224 transition: transform 0.2s; 225 -webkit-font-smoothing: antialiased; 226 -moz-osx-font-smoothing: grayscale; 227 } 228 229 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children.visible > a { 230 transition: background-color 0.2s; 231 } 232 233 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children.visible > a:after { 234 transform: translateY(-50%) rotate(90deg); 235 } 236 237 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li > ul.sub-menu { 238 display: none; 239 padding-left: 0; 240 flex-basis: 100%; 241 } 242 243 #offcanvas_container .ps__rail-y { 244 opacity: 1; 245 display: block !important; 246 width: 10px; 247 height: 100%; 248 } 249 250 #offcanvas_container .close-sidebar-inner { 251 height: 46px; 252 vertical-align: middle; 253 font-family: Arial; 254 font-size: 13.5px; 255 cursor: pointer; 256 padding: 7px 15px; 257 } 258 259 #offcanvas_container .close-sidebar-inner .fa { 260 position: relative; 261 width: 32px; 262 height: 32px; 263 opacity: 0.4; 264 display: inline-block; 265 vertical-align: middle; 266 } 267 268 #offcanvas_container .close-sidebar-inner .fa:before, 269 #offcanvas_container .close-sidebar-inner .fa:after { 270 position: absolute; 271 left: 15px; 272 height: 33px; 273 width: 2px; 274 background-color: currentColor; 275 } 276 277 #offcanvas_container .close-sidebar-inner .fa:before { 278 transform: rotate(45deg); 279 } 280 281 #offcanvas_container .close-sidebar-inner .fa:after { 282 transform: rotate(-45deg); 283 } 284 285 #offcanvas_container .close-sidebar-inner:hover .fa { 286 opacity: 1; 287 } 288 289 #offcanvas_container .close-sidebar-inner:hover span:first-child { 290 opacity: 1; 291 } 292 293 #offcanvas_container .close-sidebar-inner span:first-child { 294 vertical-align: middle; 295 width: calc(100% - 32px); 296 display: inline-block; 297 opacity: 0.8; 298 } 299 300 #offcanvas_container + .offcanvas-menu-background { 301 background-color: rgba(0, 0, 0, 0); 302 transition: background-color 0.3s, width 0s ease 0.3s, height 0s ease 0.3s, left 0.3s; 303 z-index: 100000; 304 position: fixed; 305 width: 0; 306 height: 0; 307 top: 0; 308 left: 0; 309 display: block; 310 } 311 312 /* Styles für das close-icon als Ersatz für font-awesome */ 313 #offcanvas_container .close-sidebar-inner .close-icon { 314 position: relative; 315 width: 32px; 316 height: 32px; 317 opacity: 0.4; 318 display: inline-block; 319 vertical-align: middle; 320 } 321 322 #offcanvas_container .close-sidebar-inner .close-icon:before, 323 #offcanvas_container .close-sidebar-inner .close-icon:after { 324 position: absolute; 325 left: 15px; 326 content: " "; 327 height: 33px; 328 width: 2px; 329 background-color: currentColor; 330 } 331 332 #offcanvas_container .close-sidebar-inner .close-icon:before { 333 transform: rotate(45deg); 334 } 335 336 #offcanvas_container .close-sidebar-inner .close-icon:after { 337 transform: rotate(-45deg); 338 } 339 340 /* Hover Effekt für das close-icon */ 341 #offcanvas_container .close-sidebar-inner:hover .close-icon { 342 opacity: 1; 343 } 344 345 /* Styles für den Text neben dem close-icon */ 346 #offcanvas_container .close-sidebar-inner > span:first-child { 347 vertical-align: middle; 348 width: calc(100% - 32px); 349 display: inline-block; 350 opacity: 0.8; 351 } 352 353 #offcanvas_container .close-sidebar-inner:hover > span:first-child { 354 opacity: 1; 355 } 356 357 /* ETmodules Icon Styles */ 358 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children > a:after { 84 359 content: "5"; 85 360 -webkit-transform: rotate(0deg); 86 transform: rotate(0deg);361 transform: rotate(0deg); 87 362 transition: -webkit-transform 0.2s; 88 363 transition: transform 0.2s; … … 104 379 align-items: center; 105 380 font-size: 1.3rem; 106 } 107 108 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a { 109 transition: background-color 0.2s; 110 } 111 112 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a:after { 113 -webkit-transform: rotate(90deg); 114 transform: rotate(90deg); 115 transition: -webkit-transform 0.2s; 116 transition: transform 0.2s; 117 transition: transform 0.2s, -webkit-transform 0.2s; 118 } 119 120 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu { 381 border-radius: 0; 382 } 383 384 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 385 transform: rotate(90deg); 386 } 387 388 /* Submenu Styles */ 389 #offcanvas_container #offcanvas_menu_inner .sub-menu { 121 390 display: none; 122 391 padding-left: 0; 123 392 flex-basis: 100%; 124 } 125 126 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > a { 127 font-weight: 400; 128 font-family: Arial;129 font-size: 13.5px; 130 cursor: pointer; 131 line-height: 40px; 132 display: block;133 padding: 0 10px 0 25px; 134 } 135 136 #offcanvas_ container #offcanvas_menu_inner > li.menu-item > ul.sub-menu >li.menu-item-has-children {393 background-color: inherit; 394 } 395 396 #offcanvas_container #offcanvas_menu_inner .sub-menu > li > a { 397 padding-left: 25px; 398 } 399 400 #offcanvas_container #offcanvas_menu_inner .sub-menu .sub-menu > li > a { 401 padding-left: 35px; 402 } 403 404 /* Allgemeine Styles für alle Menü-Ebenen */ 405 #offcanvas_menu_inner li.menu-item-has-children { 137 406 display: flex; 138 407 flex-wrap: wrap; 139 408 } 140 409 141 #offcanvas_ container #offcanvas_menu_inner > li.menu-item > ul.sub-menu >li.menu-item-has-children > a {410 #offcanvas_menu_inner li.menu-item-has-children > a { 142 411 width: 100%; 143 display: block;144 412 display: flex; 145 413 flex-direction: row; … … 148 416 } 149 417 150 #offcanvas_ container #offcanvas_menu_inner > li.menu-item > ul.sub-menu >li.menu-item-has-children > a:after {418 #offcanvas_menu_inner li.menu-item-has-children > a:after { 151 419 content: "5"; 152 420 -webkit-transform: rotate(0deg); 153 transform: rotate(0deg);421 transform: rotate(0deg); 154 422 transition: -webkit-transform 0.2s; 155 423 transition: transform 0.2s; … … 171 439 align-items: center; 172 440 font-size: 1.3rem; 173 } 174 175 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children.visible > a { 176 transition: background-color 0.2s; 177 } 178 179 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li.menu-item-has-children.visible > a:after { 180 -webkit-transform: rotate(90deg); 181 transform: rotate(90deg); 182 transition: -webkit-transform 0.2s; 183 transition: transform 0.2s; 184 transition: transform 0.2s, -webkit-transform 0.2s; 185 } 186 187 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu { 441 border-radius: 0; 442 } 443 444 #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 445 transform: rotate(90deg); 446 } 447 448 /* Submenu Styles */ 449 #offcanvas_menu_inner .sub-menu { 188 450 display: none; 189 451 padding-left: 0; … … 191 453 } 192 454 193 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li > a { 194 font-weight: 400; 195 font-family: Arial; 196 font-size: 13.5px; 197 cursor: pointer; 198 line-height: 40px; 199 display: block; 455 /* Padding für verschiedene Menü-Ebenen */ 456 #offcanvas_menu_inner > li > a { 457 padding: 0 10px 0 15px; 458 } 459 460 #offcanvas_menu_inner > li > .sub-menu > li > a { 461 padding: 0 10px 0 25px; 462 } 463 464 #offcanvas_menu_inner > li > .sub-menu > li > .sub-menu > li > a { 200 465 padding: 0 10px 0 35px; 201 466 } 202 467 203 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children { 204 display: flex; 205 flex-wrap: wrap; 206 } 207 208 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children > a { 209 width: 100%; 210 display: block; 211 display: flex; 212 flex-direction: row; 213 justify-content: space-between; 214 transition: background-color 0.2s; 215 } 216 217 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children > a:after { 218 content: "5"; 219 -webkit-transform: rotate(0deg); 220 transform: rotate(0deg); 221 transition: -webkit-transform 0.2s; 222 transition: transform 0.2s; 223 transition: transform 0.2s, -webkit-transform 0.2s; 224 font-family: ETmodules; 225 text-shadow: 0 0; 226 font-style: normal; 227 font-variant: normal; 228 -webkit-font-smoothing: antialiased; 229 -moz-osx-font-smoothing: grayscale; 230 line-height: 1; 231 text-transform: none; 232 speak: none; 233 vertical-align: middle; 234 height: 40px; 235 width: 40px; 236 display: flex; 237 justify-content: center; 238 align-items: center; 239 font-size: 1.3rem; 240 } 241 242 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children.visible > a { 243 transition: background-color 0.2s; 244 } 245 246 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li.menu-item-has-children.visible > a:after { 247 -webkit-transform: rotate(90deg); 248 transform: rotate(90deg); 249 transition: -webkit-transform 0.2s; 250 transition: transform 0.2s; 251 transition: transform 0.2s, -webkit-transform 0.2s; 252 } 253 254 #offcanvas_container #offcanvas_menu_inner > li.menu-item > ul.sub-menu > li > ul.sub-menu > li > ul.sub-menu { 255 display: none; 256 padding-left: 0; 257 flex-basis: 100%; 258 } 259 260 #offcanvas_container .ps__rail-y { 261 opacity: 1; 262 display: block !important; 263 width: 10px; 264 height: 100%; 265 } 266 267 #offcanvas_container .close-sidebar-inner { 268 height: 46px; 269 vertical-align: middle; 270 font-family: Arial; 271 font-size: 13.5px; 272 cursor: pointer; 273 padding: 7px 15px; 274 } 275 468 /* Untermenü-Pfeile auch mit Hintergrund */ 469 #offcanvas_container #offcanvas_menu_inner .sub-menu li.menu-item-has-children > a:after { 470 background-color: #7cba3d !important; 471 color: #ffffff; 472 padding: 10px; 473 margin-right: 0px; 474 } 475 476 /* Gemeinsame Styles für alle Menü-Pfeile */ 477 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children > a:after { 478 content: "5"; 479 font-family: ETmodules !important; 480 position: absolute; 481 right: 0; 482 top: 50%; 483 width: auto; 484 height: auto; 485 font-size: 1.3rem; 486 display: flex; 487 justify-content: center; 488 align-items: center; 489 color: #ffffff; 490 transition: transform 0.2s; 491 -webkit-font-smoothing: antialiased; 492 background-color: #4dbc2f !important; 493 padding: 10px; 494 border-radius: 0; 495 } 496 497 /* Rotation für aufgeklappte Menüpunkte */ 498 #offcanvas_container #offcanvas_menu_inner li.menu-item-has-children.visible > a:after { 499 transform: translateY(-50%) rotate(90deg); 500 } 501 502 /* Styles für das X-Icon */ 276 503 #offcanvas_container .close-sidebar-inner .fa { 277 position: relative;278 width: 32px;279 height: 32px;280 opacity: 0.4;281 display: inline-block;282 vertical-align: middle;504 position: relative; 505 width: 32px; 506 height: 32px; 507 opacity: 0.4; 508 display: inline-block; 509 vertical-align: middle; 283 510 } 284 511 285 512 #offcanvas_container .close-sidebar-inner .fa:before, 286 513 #offcanvas_container .close-sidebar-inner .fa:after { 287 position: absolute; 288 left: 15px; 289 content: " "; 290 height: 33px; 291 width: 2px; 514 position: absolute; 515 left: 15px; 516 content: ""; 517 height: 33px; 518 width: 2px; 519 background-color: currentColor; 292 520 } 293 521 294 522 #offcanvas_container .close-sidebar-inner .fa:before { 295 -webkit-transform: rotate(45deg); 296 transform: rotate(45deg); 523 transform: rotate(45deg); 297 524 } 298 525 299 526 #offcanvas_container .close-sidebar-inner .fa:after { 300 -webkit-transform: rotate(-45deg);301 transform: rotate(-45deg); 302 } 303 527 transform: rotate(-45deg); 528 } 529 530 /* Hover Effekt für das X */ 304 531 #offcanvas_container .close-sidebar-inner:hover .fa { 305 opacity: 1; 306 } 307 308 #offcanvas_container .close-sidebar-inner:hover span:first-child { 309 opacity: 1; 310 } 311 312 #offcanvas_container .close-sidebar-inner span:first-child { 313 vertical-align: middle; 314 width: calc(100% - 32px); 315 display: inline-block; 316 opacity: 0.8; 317 } 318 319 #offcanvas_container + .offcanvas-menu-background { 320 background-color: rgba(0, 0, 0, 0); 321 transition: background-color 0.3s, width 0s ease 0.3s, height 0s ease 0.3s, left 0.3s; 322 z-index: 100000; 323 position: fixed; 324 width: 0; 325 height: 0; 326 top: 0; 327 left: 0; 328 display: block; 329 } 330 532 opacity: 1; 533 } 534 535 /* 4.4 Arrows - Touch-optimized */ 536 #offcanvas_menu_inner li.menu-item-has-children > a:after { 537 content: "5"; 538 font-family: ETmodules !important; 539 position: absolute; 540 right: 0; 541 top: 0; 542 width: var(--arrow-width); 543 height: 100%; 544 display: flex; 545 justify-content: center; 546 align-items: center; 547 background-color: var(--arrow-background); 548 color: var(--menu-text); 549 font-size: 1.3rem; 550 transition: transform var(--transition-speed) ease; 551 cursor: pointer; 552 -webkit-tap-highlight-color: transparent; /* Verhindert Highlight auf iOS */ 553 touch-action: auto; /* Optimiert Touch-Verhalten */ 554 555 } 556 /* Customizer-spezifische Styles */ 557 .customize-partial-edit-shortcuts-shown #offcanvas_menu { 558 display: block !important; 559 transform: translateX(0) !important; 560 opacity: 1 !important; 561 visibility: visible !important; 562 } 563 564 .customize-partial-edit-shortcuts-shown .awoc-overlay { 565 display: block !important; 566 opacity: 0.5 !important; 567 visibility: visible !important; 568 } 569 570 /* Optional: Wenn das Menu zu weit links ist und Einstellungen verdeckt */ 571 .customize-partial-edit-shortcuts-shown #offcanvas_menu { 572 right: auto !important; 573 left: 300px !important; /* Anpassen je nach Breite des Customizer-Panels */ 574 } 575 576 /* Damit der Close-Button im Customizer nicht stört */ 577 .customize-partial-edit-shortcuts-shown .awoc-close { 578 display: none !important; 579 } 580 581 /* Tooltip unter dem Slider links bündig positionieren */ 582 .awoc-range-tooltip { 583 position: absolute; /* Positionieren Sie es absolut */ 584 left: 0; /* Links bündig */ 585 top: 100%; /* Direkt unter dem Slider */ 586 transform: translateX(0); /* Keine Verschiebung */ 587 margin-top: 10px; /* Abstand zum Slider */ 588 z-index: 1000; /* Sicherstellen, dass es über anderen Elementen liegt */ 589 } 590 591 592 /* Checkbox Styling */ 593 input[type="checkbox"] { 594 display: none; /* Verstecke die Standard-Checkbox */ 595 } 596 597 input[type="checkbox"] + label { 598 position: relative; 599 padding-left: 25px; /* Platz für das benutzerdefinierte Design */ 600 cursor: pointer; 601 } 602 603 input[type="checkbox"] + label:before { 604 content: ''; 605 position: absolute; 606 left: 0; 607 top: 50%; 608 transform: translateY(-50%); 609 width: 20px; /* Breite der benutzerdefinierten Checkbox */ 610 height: 20px; /* Höhe der benutzerdefinierten Checkbox */ 611 border: 2px solid #2271b1; /* Rahmenfarbe */ 612 border-radius: 4px; /* Abgerundete Ecken */ 613 background: white; /* Hintergrundfarbe */ 614 } 615 616 input[type="checkbox"]:checked + label:before { 617 background: #2271b1; /* Hintergrundfarbe, wenn ausgewählt */ 618 border-color: #2271b1; /* Rahmenfarbe, wenn ausgewählt */ 619 } 620 621 input[type="checkbox"]:checked + label:after { 622 content: '✔'; /* Häkchen-Symbol */ 623 position: absolute; 624 left: 5px; 625 top: 50%; 626 transform: translateY(-50%); 627 color: white; /* Häkchenfarbe */ 628 font-size: 16px; /* Größe des Häkchens */ 629 } 630 631 /* Schriftfarbe für den Hauptmenüpunkt, wenn das Untermenü geöffnet ist */ 632 #offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children.visible > a { 633 color: ' . get_theme_mod('awoc_offcanvas_open_font_setting', '#444444') . '; /* Schriftfarbe für den Hauptmenüpunkt */ 634 background-color: ' . get_theme_mod('awoc_offcanvas_open_background_setting', 'orange') . '; /* Hintergrundfarbe für den Hauptmenüpunkt */ 635 } -
aweos-offcanvas-menu/trunk/public/js/app.js
r2014889 r3218885 1 /******/ (function(modules) { // webpackBootstrap 2 /******/ // The module cache 3 /******/ var installedModules = {}; 4 /******/ 5 /******/ // The require function 6 /******/ function __webpack_require__(moduleId) { 7 /******/ 8 /******/ // Check if module is in cache 9 /******/ if(installedModules[moduleId]) { 10 /******/ return installedModules[moduleId].exports; 11 /******/ } 12 /******/ // Create a new module (and put it into the cache) 13 /******/ var module = installedModules[moduleId] = { 14 /******/ i: moduleId, 15 /******/ l: false, 16 /******/ exports: {} 17 /******/ }; 18 /******/ 19 /******/ // Execute the module function 20 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 /******/ 22 /******/ // Flag the module as loaded 23 /******/ module.l = true; 24 /******/ 25 /******/ // Return the exports of the module 26 /******/ return module.exports; 27 /******/ } 28 /******/ 29 /******/ 30 /******/ // expose the modules object (__webpack_modules__) 31 /******/ __webpack_require__.m = modules; 32 /******/ 33 /******/ // expose the module cache 34 /******/ __webpack_require__.c = installedModules; 35 /******/ 36 /******/ // define getter function for harmony exports 37 /******/ __webpack_require__.d = function(exports, name, getter) { 38 /******/ if(!__webpack_require__.o(exports, name)) { 39 /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 /******/ } 41 /******/ }; 42 /******/ 43 /******/ // define __esModule on exports 44 /******/ __webpack_require__.r = function(exports) { 45 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 /******/ } 48 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 /******/ }; 50 /******/ 51 /******/ // create a fake namespace object 52 /******/ // mode & 1: value is a module id, require it 53 /******/ // mode & 2: merge all properties of value into the ns 54 /******/ // mode & 4: return value when already ns object 55 /******/ // mode & 8|1: behave like require 56 /******/ __webpack_require__.t = function(value, mode) { 57 /******/ if(mode & 1) value = __webpack_require__(value); 58 /******/ if(mode & 8) return value; 59 /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 /******/ var ns = Object.create(null); 61 /******/ __webpack_require__.r(ns); 62 /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 /******/ return ns; 65 /******/ }; 66 /******/ 67 /******/ // getDefaultExport function for compatibility with non-harmony modules 68 /******/ __webpack_require__.n = function(module) { 69 /******/ var getter = module && module.__esModule ? 70 /******/ function getDefault() { return module['default']; } : 71 /******/ function getModuleExports() { return module; }; 72 /******/ __webpack_require__.d(getter, 'a', getter); 73 /******/ return getter; 74 /******/ }; 75 /******/ 76 /******/ // Object.prototype.hasOwnProperty.call 77 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 /******/ 79 /******/ // __webpack_public_path__ 80 /******/ __webpack_require__.p = "/"; 81 /******/ 82 /******/ 83 /******/ // Load entry module and return exports 84 /******/ return __webpack_require__(__webpack_require__.s = 0); 85 /******/ }) 86 /************************************************************************/ 87 /******/ ({ 88 89 /***/ "./node_modules/css-loader/index.js!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css": 90 /*!********************************************************************************************!*\ 91 !*** ./node_modules/css-loader!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css ***! 92 \********************************************************************************************/ 93 /*! no static exports found */ 94 /***/ (function(module, exports, __webpack_require__) { 95 96 exports = module.exports = __webpack_require__(/*! ../../css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false); 97 // imports 98 99 100 // module 101 exports.push([module.i, "/*\n * Container style\n */\n.ps {\n overflow: hidden !important;\n overflow-anchor: none;\n -ms-overflow-style: none;\n touch-action: auto;\n -ms-touch-action: auto;\n}\n\n/*\n * Scrollbar rail styles\n */\n.ps__rail-x {\n display: none;\n opacity: 0;\n transition: background-color .2s linear, opacity .2s linear;\n -webkit-transition: background-color .2s linear, opacity .2s linear;\n height: 15px;\n /* there must be 'bottom' or 'top' for ps__rail-x */\n bottom: 0px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__rail-y {\n display: none;\n opacity: 0;\n transition: background-color .2s linear, opacity .2s linear;\n -webkit-transition: background-color .2s linear, opacity .2s linear;\n width: 15px;\n /* there must be 'right' or 'left' for ps__rail-y */\n right: 0;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps--active-x > .ps__rail-x,\n.ps--active-y > .ps__rail-y {\n display: block;\n background-color: transparent;\n}\n\n.ps:hover > .ps__rail-x,\n.ps:hover > .ps__rail-y,\n.ps--focus > .ps__rail-x,\n.ps--focus > .ps__rail-y,\n.ps--scrolling-x > .ps__rail-x,\n.ps--scrolling-y > .ps__rail-y {\n opacity: 0.6;\n}\n\n.ps .ps__rail-x:hover,\n.ps .ps__rail-y:hover,\n.ps .ps__rail-x:focus,\n.ps .ps__rail-y:focus,\n.ps .ps__rail-x.ps--clicking,\n.ps .ps__rail-y.ps--clicking {\n background-color: #eee;\n opacity: 0.9;\n}\n\n/*\n * Scrollbar thumb styles\n */\n.ps__thumb-x {\n background-color: #aaa;\n border-radius: 6px;\n transition: background-color .2s linear, height .2s ease-in-out;\n -webkit-transition: background-color .2s linear, height .2s ease-in-out;\n height: 6px;\n /* there must be 'bottom' for ps__thumb-x */\n bottom: 2px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__thumb-y {\n background-color: #aaa;\n border-radius: 6px;\n transition: background-color .2s linear, width .2s ease-in-out;\n -webkit-transition: background-color .2s linear, width .2s ease-in-out;\n width: 6px;\n /* there must be 'right' for ps__thumb-y */\n right: 2px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__rail-x:hover > .ps__thumb-x,\n.ps__rail-x:focus > .ps__thumb-x,\n.ps__rail-x.ps--clicking .ps__thumb-x {\n background-color: #999;\n height: 11px;\n}\n\n.ps__rail-y:hover > .ps__thumb-y,\n.ps__rail-y:focus > .ps__thumb-y,\n.ps__rail-y.ps--clicking .ps__thumb-y {\n background-color: #999;\n width: 11px;\n}\n\n/* MS supports */\n@supports (-ms-overflow-style: none) {\n .ps {\n overflow: auto !important;\n }\n}\n\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n .ps {\n overflow: auto !important;\n }\n}\n", ""]); 102 103 // exports 104 105 106 /***/ }), 107 108 /***/ "./node_modules/css-loader/lib/css-base.js": 109 /*!*************************************************!*\ 110 !*** ./node_modules/css-loader/lib/css-base.js ***! 111 \*************************************************/ 112 /*! no static exports found */ 113 /***/ (function(module, exports) { 114 115 /* 116 MIT License http://www.opensource.org/licenses/mit-license.php 117 Author Tobias Koppers @sokra 118 */ 119 // css base code, injected by the css-loader 120 module.exports = function(useSourceMap) { 121 var list = []; 122 123 // return the list of modules as css string 124 list.toString = function toString() { 125 return this.map(function (item) { 126 var content = cssWithMappingToString(item, useSourceMap); 127 if(item[2]) { 128 return "@media " + item[2] + "{" + content + "}"; 129 } else { 130 return content; 131 } 132 }).join(""); 133 }; 134 135 // import a list of modules into the list 136 list.i = function(modules, mediaQuery) { 137 if(typeof modules === "string") 138 modules = [[null, modules, ""]]; 139 var alreadyImportedModules = {}; 140 for(var i = 0; i < this.length; i++) { 141 var id = this[i][0]; 142 if(typeof id === "number") 143 alreadyImportedModules[id] = true; 144 } 145 for(i = 0; i < modules.length; i++) { 146 var item = modules[i]; 147 // skip already imported module 148 // this implementation is not 100% perfect for weird media query combinations 149 // when a module is imported multiple times with different media queries. 150 // I hope this will never occur (Hey this way we have smaller bundles) 151 if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { 152 if(mediaQuery && !item[2]) { 153 item[2] = mediaQuery; 154 } else if(mediaQuery) { 155 item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; 156 } 157 list.push(item); 158 } 159 } 160 }; 161 return list; 162 }; 163 164 function cssWithMappingToString(item, useSourceMap) { 165 var content = item[1] || ''; 166 var cssMapping = item[3]; 167 if (!cssMapping) { 168 return content; 169 } 170 171 if (useSourceMap && typeof btoa === 'function') { 172 var sourceMapping = toComment(cssMapping); 173 var sourceURLs = cssMapping.sources.map(function (source) { 174 return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' 175 }); 176 177 return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); 178 } 179 180 return [content].join('\n'); 181 } 182 183 // Adapted from convert-source-map (MIT) 184 function toComment(sourceMap) { 185 // eslint-disable-next-line no-undef 186 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); 187 var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; 188 189 return '/*# ' + data + ' */'; 190 } 191 192 193 /***/ }), 194 195 /***/ "./node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js": 196 /*!**********************************************************************!*\ 197 !*** ./node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js ***! 198 \**********************************************************************/ 199 /*! exports provided: default */ 200 /***/ (function(module, __webpack_exports__, __webpack_require__) { 201 202 "use strict"; 203 __webpack_require__.r(__webpack_exports__); 204 /*! 205 * perfect-scrollbar v1.4.0 206 * (c) 2018 Hyunje Jun 207 * @license MIT 208 */ 209 function get(element) { 210 return getComputedStyle(element); 211 } 212 213 function set(element, obj) { 214 for (var key in obj) { 215 var val = obj[key]; 216 if (typeof val === 'number') { 217 val = val + "px"; 1 jQuery(document).ready(function($) { 2 var $container = $('#offcanvas_container'); 3 var $background = $('.offcanvas-menu-background'); 4 5 function checkVisibility() { 6 var maxWidth = $container.data('max'); 7 var alwaysActive = $container.data('always-active') === true; 8 9 // Check if the offcanvas menu should be visible based on the window width and always active setting 10 if (alwaysActive || window.innerWidth <= maxWidth) { 11 $container.addClass('is-available'); 12 } else { 13 $container.removeClass('is-available'); 14 $('body').removeClass('offcanvas-open'); 15 } 218 16 } 219 element.style[key] = val; 220 } 221 return element; 222 } 223 224 function div(className) { 225 var div = document.createElement('div'); 226 div.className = className; 227 return div; 228 } 229 230 var elMatches = 231 typeof Element !== 'undefined' && 232 (Element.prototype.matches || 233 Element.prototype.webkitMatchesSelector || 234 Element.prototype.mozMatchesSelector || 235 Element.prototype.msMatchesSelector); 236 237 function matches(element, query) { 238 if (!elMatches) { 239 throw new Error('No element matching method supported'); 240 } 241 242 return elMatches.call(element, query); 243 } 244 245 function remove(element) { 246 if (element.remove) { 247 element.remove(); 248 } else { 249 if (element.parentNode) { 250 element.parentNode.removeChild(element); 251 } 252 } 253 } 254 255 function queryChildren(element, selector) { 256 return Array.prototype.filter.call(element.children, function (child) { return matches(child, selector); } 257 ); 258 } 259 260 var cls = { 261 main: 'ps', 262 element: { 263 thumb: function (x) { return ("ps__thumb-" + x); }, 264 rail: function (x) { return ("ps__rail-" + x); }, 265 consuming: 'ps__child--consume', 266 }, 267 state: { 268 focus: 'ps--focus', 269 clicking: 'ps--clicking', 270 active: function (x) { return ("ps--active-" + x); }, 271 scrolling: function (x) { return ("ps--scrolling-" + x); }, 272 }, 273 }; 274 275 /* 276 * Helper methods 277 */ 278 var scrollingClassTimeout = { x: null, y: null }; 279 280 function addScrollingClass(i, x) { 281 var classList = i.element.classList; 282 var className = cls.state.scrolling(x); 283 284 if (classList.contains(className)) { 285 clearTimeout(scrollingClassTimeout[x]); 286 } else { 287 classList.add(className); 288 } 289 } 290 291 function removeScrollingClass(i, x) { 292 scrollingClassTimeout[x] = setTimeout( 293 function () { return i.isAlive && i.element.classList.remove(cls.state.scrolling(x)); }, 294 i.settings.scrollingThreshold 295 ); 296 } 297 298 function setScrollingClassInstantly(i, x) { 299 addScrollingClass(i, x); 300 removeScrollingClass(i, x); 301 } 302 303 var EventElement = function EventElement(element) { 304 this.element = element; 305 this.handlers = {}; 306 }; 307 308 var prototypeAccessors = { isEmpty: { configurable: true } }; 309 310 EventElement.prototype.bind = function bind (eventName, handler) { 311 if (typeof this.handlers[eventName] === 'undefined') { 312 this.handlers[eventName] = []; 313 } 314 this.handlers[eventName].push(handler); 315 this.element.addEventListener(eventName, handler, false); 316 }; 317 318 EventElement.prototype.unbind = function unbind (eventName, target) { 319 var this$1 = this; 320 321 this.handlers[eventName] = this.handlers[eventName].filter(function (handler) { 322 if (target && handler !== target) { 323 return true; 324 } 325 this$1.element.removeEventListener(eventName, handler, false); 326 return false; 327 }); 328 }; 329 330 EventElement.prototype.unbindAll = function unbindAll () { 331 var this$1 = this; 332 333 for (var name in this$1.handlers) { 334 this$1.unbind(name); 335 } 336 }; 337 338 prototypeAccessors.isEmpty.get = function () { 339 var this$1 = this; 340 341 return Object.keys(this.handlers).every( 342 function (key) { return this$1.handlers[key].length === 0; } 343 ); 344 }; 345 346 Object.defineProperties( EventElement.prototype, prototypeAccessors ); 347 348 var EventManager = function EventManager() { 349 this.eventElements = []; 350 }; 351 352 EventManager.prototype.eventElement = function eventElement (element) { 353 var ee = this.eventElements.filter(function (ee) { return ee.element === element; })[0]; 354 if (!ee) { 355 ee = new EventElement(element); 356 this.eventElements.push(ee); 357 } 358 return ee; 359 }; 360 361 EventManager.prototype.bind = function bind (element, eventName, handler) { 362 this.eventElement(element).bind(eventName, handler); 363 }; 364 365 EventManager.prototype.unbind = function unbind (element, eventName, handler) { 366 var ee = this.eventElement(element); 367 ee.unbind(eventName, handler); 368 369 if (ee.isEmpty) { 370 // remove 371 this.eventElements.splice(this.eventElements.indexOf(ee), 1); 372 } 373 }; 374 375 EventManager.prototype.unbindAll = function unbindAll () { 376 this.eventElements.forEach(function (e) { return e.unbindAll(); }); 377 this.eventElements = []; 378 }; 379 380 EventManager.prototype.once = function once (element, eventName, handler) { 381 var ee = this.eventElement(element); 382 var onceHandler = function (evt) { 383 ee.unbind(eventName, onceHandler); 384 handler(evt); 385 }; 386 ee.bind(eventName, onceHandler); 387 }; 388 389 function createEvent(name) { 390 if (typeof window.CustomEvent === 'function') { 391 return new CustomEvent(name); 392 } else { 393 var evt = document.createEvent('CustomEvent'); 394 evt.initCustomEvent(name, false, false, undefined); 395 return evt; 396 } 397 } 398 399 var processScrollDiff = function( 400 i, 401 axis, 402 diff, 403 useScrollingClass, 404 forceFireReachEvent 405 ) { 406 if ( useScrollingClass === void 0 ) useScrollingClass = true; 407 if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false; 408 409 var fields; 410 if (axis === 'top') { 411 fields = [ 412 'contentHeight', 413 'containerHeight', 414 'scrollTop', 415 'y', 416 'up', 417 'down' ]; 418 } else if (axis === 'left') { 419 fields = [ 420 'contentWidth', 421 'containerWidth', 422 'scrollLeft', 423 'x', 424 'left', 425 'right' ]; 426 } else { 427 throw new Error('A proper axis should be provided'); 428 } 429 430 processScrollDiff$1(i, diff, fields, useScrollingClass, forceFireReachEvent); 431 }; 432 433 function processScrollDiff$1( 434 i, 435 diff, 436 ref, 437 useScrollingClass, 438 forceFireReachEvent 439 ) { 440 var contentHeight = ref[0]; 441 var containerHeight = ref[1]; 442 var scrollTop = ref[2]; 443 var y = ref[3]; 444 var up = ref[4]; 445 var down = ref[5]; 446 if ( useScrollingClass === void 0 ) useScrollingClass = true; 447 if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false; 448 449 var element = i.element; 450 451 // reset reach 452 i.reach[y] = null; 453 454 // 1 for subpixel rounding 455 if (element[scrollTop] < 1) { 456 i.reach[y] = 'start'; 457 } 458 459 // 1 for subpixel rounding 460 if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) { 461 i.reach[y] = 'end'; 462 } 463 464 if (diff) { 465 element.dispatchEvent(createEvent(("ps-scroll-" + y))); 466 467 if (diff < 0) { 468 element.dispatchEvent(createEvent(("ps-scroll-" + up))); 469 } else if (diff > 0) { 470 element.dispatchEvent(createEvent(("ps-scroll-" + down))); 471 } 472 473 if (useScrollingClass) { 474 setScrollingClassInstantly(i, y); 475 } 476 } 477 478 if (i.reach[y] && (diff || forceFireReachEvent)) { 479 element.dispatchEvent(createEvent(("ps-" + y + "-reach-" + (i.reach[y])))); 480 } 481 } 482 483 function toInt(x) { 484 return parseInt(x, 10) || 0; 485 } 486 487 function isEditable(el) { 488 return ( 489 matches(el, 'input,[contenteditable]') || 490 matches(el, 'select,[contenteditable]') || 491 matches(el, 'textarea,[contenteditable]') || 492 matches(el, 'button,[contenteditable]') 493 ); 494 } 495 496 function outerWidth(element) { 497 var styles = get(element); 498 return ( 499 toInt(styles.width) + 500 toInt(styles.paddingLeft) + 501 toInt(styles.paddingRight) + 502 toInt(styles.borderLeftWidth) + 503 toInt(styles.borderRightWidth) 504 ); 505 } 506 507 var env = { 508 isWebKit: 509 typeof document !== 'undefined' && 510 'WebkitAppearance' in document.documentElement.style, 511 supportsTouch: 512 typeof window !== 'undefined' && 513 ('ontouchstart' in window || 514 (window.DocumentTouch && document instanceof window.DocumentTouch)), 515 supportsIePointer: 516 typeof navigator !== 'undefined' && navigator.msMaxTouchPoints, 517 isChrome: 518 typeof navigator !== 'undefined' && 519 /Chrome/i.test(navigator && navigator.userAgent), 520 }; 521 522 var updateGeometry = function(i) { 523 var element = i.element; 524 var roundedScrollTop = Math.floor(element.scrollTop); 525 526 i.containerWidth = element.clientWidth; 527 i.containerHeight = element.clientHeight; 528 i.contentWidth = element.scrollWidth; 529 i.contentHeight = element.scrollHeight; 530 531 if (!element.contains(i.scrollbarXRail)) { 532 // clean up and append 533 queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); } 534 ); 535 element.appendChild(i.scrollbarXRail); 536 } 537 if (!element.contains(i.scrollbarYRail)) { 538 // clean up and append 539 queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); } 540 ); 541 element.appendChild(i.scrollbarYRail); 542 } 543 544 if ( 545 !i.settings.suppressScrollX && 546 i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth 547 ) { 548 i.scrollbarXActive = true; 549 i.railXWidth = i.containerWidth - i.railXMarginWidth; 550 i.railXRatio = i.containerWidth / i.railXWidth; 551 i.scrollbarXWidth = getThumbSize( 552 i, 553 toInt(i.railXWidth * i.containerWidth / i.contentWidth) 554 ); 555 i.scrollbarXLeft = toInt( 556 (i.negativeScrollAdjustment + element.scrollLeft) * 557 (i.railXWidth - i.scrollbarXWidth) / 558 (i.contentWidth - i.containerWidth) 559 ); 560 } else { 561 i.scrollbarXActive = false; 562 } 563 564 if ( 565 !i.settings.suppressScrollY && 566 i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight 567 ) { 568 i.scrollbarYActive = true; 569 i.railYHeight = i.containerHeight - i.railYMarginHeight; 570 i.railYRatio = i.containerHeight / i.railYHeight; 571 i.scrollbarYHeight = getThumbSize( 572 i, 573 toInt(i.railYHeight * i.containerHeight / i.contentHeight) 574 ); 575 i.scrollbarYTop = toInt( 576 roundedScrollTop * 577 (i.railYHeight - i.scrollbarYHeight) / 578 (i.contentHeight - i.containerHeight) 579 ); 580 } else { 581 i.scrollbarYActive = false; 582 } 583 584 if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) { 585 i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth; 586 } 587 if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) { 588 i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight; 589 } 590 591 updateCss(element, i); 592 593 if (i.scrollbarXActive) { 594 element.classList.add(cls.state.active('x')); 595 } else { 596 element.classList.remove(cls.state.active('x')); 597 i.scrollbarXWidth = 0; 598 i.scrollbarXLeft = 0; 599 element.scrollLeft = 0; 600 } 601 if (i.scrollbarYActive) { 602 element.classList.add(cls.state.active('y')); 603 } else { 604 element.classList.remove(cls.state.active('y')); 605 i.scrollbarYHeight = 0; 606 i.scrollbarYTop = 0; 607 element.scrollTop = 0; 608 } 609 }; 610 611 function getThumbSize(i, thumbSize) { 612 if (i.settings.minScrollbarLength) { 613 thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength); 614 } 615 if (i.settings.maxScrollbarLength) { 616 thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength); 617 } 618 return thumbSize; 619 } 620 621 function updateCss(element, i) { 622 var xRailOffset = { width: i.railXWidth }; 623 var roundedScrollTop = Math.floor(element.scrollTop); 624 625 if (i.isRtl) { 626 xRailOffset.left = 627 i.negativeScrollAdjustment + 628 element.scrollLeft + 629 i.containerWidth - 630 i.contentWidth; 631 } else { 632 xRailOffset.left = element.scrollLeft; 633 } 634 if (i.isScrollbarXUsingBottom) { 635 xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop; 636 } else { 637 xRailOffset.top = i.scrollbarXTop + roundedScrollTop; 638 } 639 set(i.scrollbarXRail, xRailOffset); 640 641 var yRailOffset = { top: roundedScrollTop, height: i.railYHeight }; 642 if (i.isScrollbarYUsingRight) { 643 if (i.isRtl) { 644 yRailOffset.right = 645 i.contentWidth - 646 (i.negativeScrollAdjustment + element.scrollLeft) - 647 i.scrollbarYRight - 648 i.scrollbarYOuterWidth; 649 } else { 650 yRailOffset.right = i.scrollbarYRight - element.scrollLeft; 651 } 652 } else { 653 if (i.isRtl) { 654 yRailOffset.left = 655 i.negativeScrollAdjustment + 656 element.scrollLeft + 657 i.containerWidth * 2 - 658 i.contentWidth - 659 i.scrollbarYLeft - 660 i.scrollbarYOuterWidth; 661 } else { 662 yRailOffset.left = i.scrollbarYLeft + element.scrollLeft; 663 } 664 } 665 set(i.scrollbarYRail, yRailOffset); 666 667 set(i.scrollbarX, { 668 left: i.scrollbarXLeft, 669 width: i.scrollbarXWidth - i.railBorderXWidth, 670 }); 671 set(i.scrollbarY, { 672 top: i.scrollbarYTop, 673 height: i.scrollbarYHeight - i.railBorderYWidth, 674 }); 675 } 676 677 var clickRail = function(i) { 678 i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); }); 679 i.event.bind(i.scrollbarYRail, 'mousedown', function (e) { 680 var positionTop = 681 e.pageY - 682 window.pageYOffset - 683 i.scrollbarYRail.getBoundingClientRect().top; 684 var direction = positionTop > i.scrollbarYTop ? 1 : -1; 685 686 i.element.scrollTop += direction * i.containerHeight; 687 updateGeometry(i); 688 689 e.stopPropagation(); 690 }); 691 692 i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); }); 693 i.event.bind(i.scrollbarXRail, 'mousedown', function (e) { 694 var positionLeft = 695 e.pageX - 696 window.pageXOffset - 697 i.scrollbarXRail.getBoundingClientRect().left; 698 var direction = positionLeft > i.scrollbarXLeft ? 1 : -1; 699 700 i.element.scrollLeft += direction * i.containerWidth; 701 updateGeometry(i); 702 703 e.stopPropagation(); 704 }); 705 }; 706 707 var dragThumb = function(i) { 708 bindMouseScrollHandler(i, [ 709 'containerWidth', 710 'contentWidth', 711 'pageX', 712 'railXWidth', 713 'scrollbarX', 714 'scrollbarXWidth', 715 'scrollLeft', 716 'x', 717 'scrollbarXRail' ]); 718 bindMouseScrollHandler(i, [ 719 'containerHeight', 720 'contentHeight', 721 'pageY', 722 'railYHeight', 723 'scrollbarY', 724 'scrollbarYHeight', 725 'scrollTop', 726 'y', 727 'scrollbarYRail' ]); 728 }; 729 730 function bindMouseScrollHandler( 731 i, 732 ref 733 ) { 734 var containerHeight = ref[0]; 735 var contentHeight = ref[1]; 736 var pageY = ref[2]; 737 var railYHeight = ref[3]; 738 var scrollbarY = ref[4]; 739 var scrollbarYHeight = ref[5]; 740 var scrollTop = ref[6]; 741 var y = ref[7]; 742 var scrollbarYRail = ref[8]; 743 744 var element = i.element; 745 746 var startingScrollTop = null; 747 var startingMousePageY = null; 748 var scrollBy = null; 749 750 function mouseMoveHandler(e) { 751 element[scrollTop] = 752 startingScrollTop + scrollBy * (e[pageY] - startingMousePageY); 753 addScrollingClass(i, y); 754 updateGeometry(i); 755 756 e.stopPropagation(); 757 e.preventDefault(); 758 } 759 760 function mouseUpHandler() { 761 removeScrollingClass(i, y); 762 i[scrollbarYRail].classList.remove(cls.state.clicking); 763 i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); 764 } 765 766 i.event.bind(i[scrollbarY], 'mousedown', function (e) { 767 startingScrollTop = element[scrollTop]; 768 startingMousePageY = e[pageY]; 769 scrollBy = 770 (i[contentHeight] - i[containerHeight]) / 771 (i[railYHeight] - i[scrollbarYHeight]); 772 773 i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); 774 i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); 775 776 i[scrollbarYRail].classList.add(cls.state.clicking); 777 778 e.stopPropagation(); 779 e.preventDefault(); 780 }); 781 } 782 783 var keyboard = function(i) { 784 var element = i.element; 785 786 var elementHovered = function () { return matches(element, ':hover'); }; 787 var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); }; 788 789 function shouldPreventDefault(deltaX, deltaY) { 790 var scrollTop = Math.floor(element.scrollTop); 791 if (deltaX === 0) { 792 if (!i.scrollbarYActive) { 793 return false; 794 } 795 if ( 796 (scrollTop === 0 && deltaY > 0) || 797 (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0) 798 ) { 799 return !i.settings.wheelPropagation; 800 } 801 } 802 803 var scrollLeft = element.scrollLeft; 804 if (deltaY === 0) { 805 if (!i.scrollbarXActive) { 806 return false; 807 } 808 if ( 809 (scrollLeft === 0 && deltaX < 0) || 810 (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0) 811 ) { 812 return !i.settings.wheelPropagation; 813 } 814 } 815 return true; 816 } 817 818 i.event.bind(i.ownerDocument, 'keydown', function (e) { 819 if ( 820 (e.isDefaultPrevented && e.isDefaultPrevented()) || 821 e.defaultPrevented 822 ) { 823 return; 824 } 825 826 if (!elementHovered() && !scrollbarFocused()) { 827 return; 828 } 829 830 var activeElement = document.activeElement 831 ? document.activeElement 832 : i.ownerDocument.activeElement; 833 if (activeElement) { 834 if (activeElement.tagName === 'IFRAME') { 835 activeElement = activeElement.contentDocument.activeElement; 836 } else { 837 // go deeper if element is a webcomponent 838 while (activeElement.shadowRoot) { 839 activeElement = activeElement.shadowRoot.activeElement; 840 } 841 } 842 if (isEditable(activeElement)) { 843 return; 844 } 845 } 846 847 var deltaX = 0; 848 var deltaY = 0; 849 850 switch (e.which) { 851 case 37: // left 852 if (e.metaKey) { 853 deltaX = -i.contentWidth; 854 } else if (e.altKey) { 855 deltaX = -i.containerWidth; 856 } else { 857 deltaX = -30; 858 } 859 break; 860 case 38: // up 861 if (e.metaKey) { 862 deltaY = i.contentHeight; 863 } else if (e.altKey) { 864 deltaY = i.containerHeight; 865 } else { 866 deltaY = 30; 867 } 868 break; 869 case 39: // right 870 if (e.metaKey) { 871 deltaX = i.contentWidth; 872 } else if (e.altKey) { 873 deltaX = i.containerWidth; 874 } else { 875 deltaX = 30; 876 } 877 break; 878 case 40: // down 879 if (e.metaKey) { 880 deltaY = -i.contentHeight; 881 } else if (e.altKey) { 882 deltaY = -i.containerHeight; 883 } else { 884 deltaY = -30; 885 } 886 break; 887 case 32: // space bar 888 if (e.shiftKey) { 889 deltaY = i.containerHeight; 890 } else { 891 deltaY = -i.containerHeight; 892 } 893 break; 894 case 33: // page up 895 deltaY = i.containerHeight; 896 break; 897 case 34: // page down 898 deltaY = -i.containerHeight; 899 break; 900 case 36: // home 901 deltaY = i.contentHeight; 902 break; 903 case 35: // end 904 deltaY = -i.contentHeight; 905 break; 906 default: 907 return; 908 } 909 910 if (i.settings.suppressScrollX && deltaX !== 0) { 911 return; 912 } 913 if (i.settings.suppressScrollY && deltaY !== 0) { 914 return; 915 } 916 917 element.scrollTop -= deltaY; 918 element.scrollLeft += deltaX; 919 updateGeometry(i); 920 921 if (shouldPreventDefault(deltaX, deltaY)) { 922 e.preventDefault(); 923 } 924 }); 925 }; 926 927 var wheel = function(i) { 928 var element = i.element; 929 930 function shouldPreventDefault(deltaX, deltaY) { 931 var roundedScrollTop = Math.floor(element.scrollTop); 932 var isTop = element.scrollTop === 0; 933 var isBottom = 934 roundedScrollTop + element.offsetHeight === element.scrollHeight; 935 var isLeft = element.scrollLeft === 0; 936 var isRight = 937 element.scrollLeft + element.offsetWidth === element.scrollWidth; 938 939 var hitsBound; 940 941 // pick axis with primary direction 942 if (Math.abs(deltaY) > Math.abs(deltaX)) { 943 hitsBound = isTop || isBottom; 944 } else { 945 hitsBound = isLeft || isRight; 946 } 947 948 return hitsBound ? !i.settings.wheelPropagation : true; 949 } 950 951 function getDeltaFromEvent(e) { 952 var deltaX = e.deltaX; 953 var deltaY = -1 * e.deltaY; 954 955 if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') { 956 // OS X Safari 957 deltaX = -1 * e.wheelDeltaX / 6; 958 deltaY = e.wheelDeltaY / 6; 959 } 960 961 if (e.deltaMode && e.deltaMode === 1) { 962 // Firefox in deltaMode 1: Line scrolling 963 deltaX *= 10; 964 deltaY *= 10; 965 } 966 967 if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) { 968 // IE in some mouse drivers 969 deltaX = 0; 970 deltaY = e.wheelDelta; 971 } 972 973 if (e.shiftKey) { 974 // reverse axis with shift key 975 return [-deltaY, -deltaX]; 976 } 977 return [deltaX, deltaY]; 978 } 979 980 function shouldBeConsumedByChild(target, deltaX, deltaY) { 981 // FIXME: this is a workaround for <select> issue in FF and IE #571 982 if (!env.isWebKit && element.querySelector('select:focus')) { 983 return true; 984 } 985 986 if (!element.contains(target)) { 987 return false; 988 } 989 990 var cursor = target; 991 992 while (cursor && cursor !== element) { 993 if (cursor.classList.contains(cls.element.consuming)) { 994 return true; 995 } 996 997 var style = get(cursor); 998 var overflow = [style.overflow, style.overflowX, style.overflowY].join( 999 '' 1000 ); 1001 1002 // if scrollable 1003 if (overflow.match(/(scroll|auto)/)) { 1004 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 1005 if (maxScrollTop > 0) { 1006 if ( 1007 !(cursor.scrollTop === 0 && deltaY > 0) && 1008 !(cursor.scrollTop === maxScrollTop && deltaY < 0) 1009 ) { 1010 return true; 1011 } 1012 } 1013 var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth; 1014 if (maxScrollLeft > 0) { 1015 if ( 1016 !(cursor.scrollLeft === 0 && deltaX < 0) && 1017 !(cursor.scrollLeft === maxScrollLeft && deltaX > 0) 1018 ) { 1019 return true; 1020 } 1021 } 1022 } 1023 1024 cursor = cursor.parentNode; 1025 } 1026 1027 return false; 1028 } 1029 1030 function mousewheelHandler(e) { 1031 var ref = getDeltaFromEvent(e); 1032 var deltaX = ref[0]; 1033 var deltaY = ref[1]; 1034 1035 if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) { 1036 return; 1037 } 1038 1039 var shouldPrevent = false; 1040 if (!i.settings.useBothWheelAxes) { 1041 // deltaX will only be used for horizontal scrolling and deltaY will 1042 // only be used for vertical scrolling - this is the default 1043 element.scrollTop -= deltaY * i.settings.wheelSpeed; 1044 element.scrollLeft += deltaX * i.settings.wheelSpeed; 1045 } else if (i.scrollbarYActive && !i.scrollbarXActive) { 1046 // only vertical scrollbar is active and useBothWheelAxes option is 1047 // active, so let's scroll vertical bar using both mouse wheel axes 1048 if (deltaY) { 1049 element.scrollTop -= deltaY * i.settings.wheelSpeed; 1050 } else { 1051 element.scrollTop += deltaX * i.settings.wheelSpeed; 1052 } 1053 shouldPrevent = true; 1054 } else if (i.scrollbarXActive && !i.scrollbarYActive) { 1055 // useBothWheelAxes and only horizontal bar is active, so use both 1056 // wheel axes for horizontal bar 1057 if (deltaX) { 1058 element.scrollLeft += deltaX * i.settings.wheelSpeed; 1059 } else { 1060 element.scrollLeft -= deltaY * i.settings.wheelSpeed; 1061 } 1062 shouldPrevent = true; 1063 } 1064 1065 updateGeometry(i); 1066 1067 shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY); 1068 if (shouldPrevent && !e.ctrlKey) { 1069 e.stopPropagation(); 1070 e.preventDefault(); 1071 } 1072 } 1073 1074 if (typeof window.onwheel !== 'undefined') { 1075 i.event.bind(element, 'wheel', mousewheelHandler); 1076 } else if (typeof window.onmousewheel !== 'undefined') { 1077 i.event.bind(element, 'mousewheel', mousewheelHandler); 1078 } 1079 }; 1080 1081 var touch = function(i) { 1082 if (!env.supportsTouch && !env.supportsIePointer) { 1083 return; 1084 } 1085 1086 var element = i.element; 1087 1088 function shouldPrevent(deltaX, deltaY) { 1089 var scrollTop = Math.floor(element.scrollTop); 1090 var scrollLeft = element.scrollLeft; 1091 var magnitudeX = Math.abs(deltaX); 1092 var magnitudeY = Math.abs(deltaY); 1093 1094 if (magnitudeY > magnitudeX) { 1095 // user is perhaps trying to swipe up/down the page 1096 1097 if ( 1098 (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) || 1099 (deltaY > 0 && scrollTop === 0) 1100 ) { 1101 // set prevent for mobile Chrome refresh 1102 return window.scrollY === 0 && deltaY > 0 && env.isChrome; 1103 } 1104 } else if (magnitudeX > magnitudeY) { 1105 // user is perhaps trying to swipe left/right across the page 1106 1107 if ( 1108 (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) || 1109 (deltaX > 0 && scrollLeft === 0) 1110 ) { 1111 return true; 1112 } 1113 } 1114 1115 return true; 1116 } 1117 1118 function applyTouchMove(differenceX, differenceY) { 1119 element.scrollTop -= differenceY; 1120 element.scrollLeft -= differenceX; 1121 1122 updateGeometry(i); 1123 } 1124 1125 var startOffset = {}; 1126 var startTime = 0; 1127 var speed = {}; 1128 var easingLoop = null; 1129 1130 function getTouch(e) { 1131 if (e.targetTouches) { 1132 return e.targetTouches[0]; 1133 } else { 1134 // Maybe IE pointer 1135 return e; 1136 } 1137 } 1138 1139 function shouldHandle(e) { 1140 if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) { 1141 return false; 1142 } 1143 if (e.targetTouches && e.targetTouches.length === 1) { 1144 return true; 1145 } 1146 if ( 1147 e.pointerType && 1148 e.pointerType !== 'mouse' && 1149 e.pointerType !== e.MSPOINTER_TYPE_MOUSE 1150 ) { 1151 return true; 1152 } 1153 return false; 1154 } 1155 1156 function touchStart(e) { 1157 if (!shouldHandle(e)) { 1158 return; 1159 } 1160 1161 var touch = getTouch(e); 1162 1163 startOffset.pageX = touch.pageX; 1164 startOffset.pageY = touch.pageY; 1165 1166 startTime = new Date().getTime(); 1167 1168 if (easingLoop !== null) { 1169 clearInterval(easingLoop); 1170 } 1171 } 1172 1173 function shouldBeConsumedByChild(target, deltaX, deltaY) { 1174 if (!element.contains(target)) { 1175 return false; 1176 } 1177 1178 var cursor = target; 1179 1180 while (cursor && cursor !== element) { 1181 if (cursor.classList.contains(cls.element.consuming)) { 1182 return true; 1183 } 1184 1185 var style = get(cursor); 1186 var overflow = [style.overflow, style.overflowX, style.overflowY].join( 1187 '' 1188 ); 1189 1190 // if scrollable 1191 if (overflow.match(/(scroll|auto)/)) { 1192 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 1193 if (maxScrollTop > 0) { 1194 if ( 1195 !(cursor.scrollTop === 0 && deltaY > 0) && 1196 !(cursor.scrollTop === maxScrollTop && deltaY < 0) 1197 ) { 1198 return true; 1199 } 1200 } 1201 var maxScrollLeft = cursor.scrollLeft - cursor.clientWidth; 1202 if (maxScrollLeft > 0) { 1203 if ( 1204 !(cursor.scrollLeft === 0 && deltaX < 0) && 1205 !(cursor.scrollLeft === maxScrollLeft && deltaX > 0) 1206 ) { 1207 return true; 1208 } 1209 } 1210 } 1211 1212 cursor = cursor.parentNode; 1213 } 1214 1215 return false; 1216 } 1217 1218 function touchMove(e) { 1219 if (shouldHandle(e)) { 1220 var touch = getTouch(e); 1221 1222 var currentOffset = { pageX: touch.pageX, pageY: touch.pageY }; 1223 1224 var differenceX = currentOffset.pageX - startOffset.pageX; 1225 var differenceY = currentOffset.pageY - startOffset.pageY; 1226 1227 if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) { 1228 return; 1229 } 1230 1231 applyTouchMove(differenceX, differenceY); 1232 startOffset = currentOffset; 1233 1234 var currentTime = new Date().getTime(); 1235 1236 var timeGap = currentTime - startTime; 1237 if (timeGap > 0) { 1238 speed.x = differenceX / timeGap; 1239 speed.y = differenceY / timeGap; 1240 startTime = currentTime; 1241 } 1242 1243 if (shouldPrevent(differenceX, differenceY)) { 17 18 // Toggle menu on mobile menu bar click 19 $('.mobile_menu_bar').on('click', function(e) { 1244 20 e.preventDefault(); 1245 } 1246 } 1247 } 1248 function touchEnd() { 1249 if (i.settings.swipeEasing) { 1250 clearInterval(easingLoop); 1251 easingLoop = setInterval(function() { 1252 if (i.isInitialized) { 1253 clearInterval(easingLoop); 1254 return; 1255 } 1256 1257 if (!speed.x && !speed.y) { 1258 clearInterval(easingLoop); 1259 return; 1260 } 1261 1262 if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) { 1263 clearInterval(easingLoop); 1264 return; 1265 } 1266 1267 applyTouchMove(speed.x * 30, speed.y * 30); 1268 1269 speed.x *= 0.8; 1270 speed.y *= 0.8; 1271 }, 10); 1272 } 1273 } 1274 1275 if (env.supportsTouch) { 1276 i.event.bind(element, 'touchstart', touchStart); 1277 i.event.bind(element, 'touchmove', touchMove); 1278 i.event.bind(element, 'touchend', touchEnd); 1279 } else if (env.supportsIePointer) { 1280 if (window.PointerEvent) { 1281 i.event.bind(element, 'pointerdown', touchStart); 1282 i.event.bind(element, 'pointermove', touchMove); 1283 i.event.bind(element, 'pointerup', touchEnd); 1284 } else if (window.MSPointerEvent) { 1285 i.event.bind(element, 'MSPointerDown', touchStart); 1286 i.event.bind(element, 'MSPointerMove', touchMove); 1287 i.event.bind(element, 'MSPointerUp', touchEnd); 1288 } 1289 } 1290 }; 1291 1292 var defaultSettings = function () { return ({ 1293 handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'], 1294 maxScrollbarLength: null, 1295 minScrollbarLength: null, 1296 scrollingThreshold: 1000, 1297 scrollXMarginOffset: 0, 1298 scrollYMarginOffset: 0, 1299 suppressScrollX: false, 1300 suppressScrollY: false, 1301 swipeEasing: true, 1302 useBothWheelAxes: false, 1303 wheelPropagation: true, 1304 wheelSpeed: 1, 1305 }); }; 1306 1307 var handlers = { 1308 'click-rail': clickRail, 1309 'drag-thumb': dragThumb, 1310 keyboard: keyboard, 1311 wheel: wheel, 1312 touch: touch, 1313 }; 1314 1315 var PerfectScrollbar = function PerfectScrollbar(element, userSettings) { 1316 var this$1 = this; 1317 if ( userSettings === void 0 ) userSettings = {}; 1318 1319 if (typeof element === 'string') { 1320 element = document.querySelector(element); 1321 } 1322 1323 if (!element || !element.nodeName) { 1324 throw new Error('no element is specified to initialize PerfectScrollbar'); 1325 } 1326 1327 this.element = element; 1328 1329 element.classList.add(cls.main); 1330 1331 this.settings = defaultSettings(); 1332 for (var key in userSettings) { 1333 this$1.settings[key] = userSettings[key]; 1334 } 1335 1336 this.containerWidth = null; 1337 this.containerHeight = null; 1338 this.contentWidth = null; 1339 this.contentHeight = null; 1340 1341 var focus = function () { return element.classList.add(cls.state.focus); }; 1342 var blur = function () { return element.classList.remove(cls.state.focus); }; 1343 1344 this.isRtl = get(element).direction === 'rtl'; 1345 this.isNegativeScroll = (function () { 1346 var originalScrollLeft = element.scrollLeft; 1347 var result = null; 1348 element.scrollLeft = -1; 1349 result = element.scrollLeft < 0; 1350 element.scrollLeft = originalScrollLeft; 1351 return result; 1352 })(); 1353 this.negativeScrollAdjustment = this.isNegativeScroll 1354 ? element.scrollWidth - element.clientWidth 1355 : 0; 1356 this.event = new EventManager(); 1357 this.ownerDocument = element.ownerDocument || document; 1358 1359 this.scrollbarXRail = div(cls.element.rail('x')); 1360 element.appendChild(this.scrollbarXRail); 1361 this.scrollbarX = div(cls.element.thumb('x')); 1362 this.scrollbarXRail.appendChild(this.scrollbarX); 1363 this.scrollbarX.setAttribute('tabindex', 0); 1364 this.event.bind(this.scrollbarX, 'focus', focus); 1365 this.event.bind(this.scrollbarX, 'blur', blur); 1366 this.scrollbarXActive = null; 1367 this.scrollbarXWidth = null; 1368 this.scrollbarXLeft = null; 1369 var railXStyle = get(this.scrollbarXRail); 1370 this.scrollbarXBottom = parseInt(railXStyle.bottom, 10); 1371 if (isNaN(this.scrollbarXBottom)) { 1372 this.isScrollbarXUsingBottom = false; 1373 this.scrollbarXTop = toInt(railXStyle.top); 1374 } else { 1375 this.isScrollbarXUsingBottom = true; 1376 } 1377 this.railBorderXWidth = 1378 toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth); 1379 // Set rail to display:block to calculate margins 1380 set(this.scrollbarXRail, { display: 'block' }); 1381 this.railXMarginWidth = 1382 toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight); 1383 set(this.scrollbarXRail, { display: '' }); 1384 this.railXWidth = null; 1385 this.railXRatio = null; 1386 1387 this.scrollbarYRail = div(cls.element.rail('y')); 1388 element.appendChild(this.scrollbarYRail); 1389 this.scrollbarY = div(cls.element.thumb('y')); 1390 this.scrollbarYRail.appendChild(this.scrollbarY); 1391 this.scrollbarY.setAttribute('tabindex', 0); 1392 this.event.bind(this.scrollbarY, 'focus', focus); 1393 this.event.bind(this.scrollbarY, 'blur', blur); 1394 this.scrollbarYActive = null; 1395 this.scrollbarYHeight = null; 1396 this.scrollbarYTop = null; 1397 var railYStyle = get(this.scrollbarYRail); 1398 this.scrollbarYRight = parseInt(railYStyle.right, 10); 1399 if (isNaN(this.scrollbarYRight)) { 1400 this.isScrollbarYUsingRight = false; 1401 this.scrollbarYLeft = toInt(railYStyle.left); 1402 } else { 1403 this.isScrollbarYUsingRight = true; 1404 } 1405 this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null; 1406 this.railBorderYWidth = 1407 toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth); 1408 set(this.scrollbarYRail, { display: 'block' }); 1409 this.railYMarginHeight = 1410 toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom); 1411 set(this.scrollbarYRail, { display: '' }); 1412 this.railYHeight = null; 1413 this.railYRatio = null; 1414 1415 this.reach = { 1416 x: 1417 element.scrollLeft <= 0 1418 ? 'start' 1419 : element.scrollLeft >= this.contentWidth - this.containerWidth 1420 ? 'end' 1421 : null, 1422 y: 1423 element.scrollTop <= 0 1424 ? 'start' 1425 : element.scrollTop >= this.contentHeight - this.containerHeight 1426 ? 'end' 1427 : null, 1428 }; 1429 1430 this.isAlive = true; 1431 1432 this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); }); 1433 1434 this.lastScrollTop = Math.floor(element.scrollTop); // for onScroll only 1435 this.lastScrollLeft = element.scrollLeft; // for onScroll only 1436 this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); }); 1437 updateGeometry(this); 1438 }; 1439 1440 PerfectScrollbar.prototype.update = function update () { 1441 if (!this.isAlive) { 1442 return; 1443 } 1444 1445 // Recalcuate negative scrollLeft adjustment 1446 this.negativeScrollAdjustment = this.isNegativeScroll 1447 ? this.element.scrollWidth - this.element.clientWidth 1448 : 0; 1449 1450 // Recalculate rail margins 1451 set(this.scrollbarXRail, { display: 'block' }); 1452 set(this.scrollbarYRail, { display: 'block' }); 1453 this.railXMarginWidth = 1454 toInt(get(this.scrollbarXRail).marginLeft) + 1455 toInt(get(this.scrollbarXRail).marginRight); 1456 this.railYMarginHeight = 1457 toInt(get(this.scrollbarYRail).marginTop) + 1458 toInt(get(this.scrollbarYRail).marginBottom); 1459 1460 // Hide scrollbars not to affect scrollWidth and scrollHeight 1461 set(this.scrollbarXRail, { display: 'none' }); 1462 set(this.scrollbarYRail, { display: 'none' }); 1463 1464 updateGeometry(this); 1465 1466 processScrollDiff(this, 'top', 0, false, true); 1467 processScrollDiff(this, 'left', 0, false, true); 1468 1469 set(this.scrollbarXRail, { display: '' }); 1470 set(this.scrollbarYRail, { display: '' }); 1471 }; 1472 1473 PerfectScrollbar.prototype.onScroll = function onScroll (e) { 1474 if (!this.isAlive) { 1475 return; 1476 } 1477 1478 updateGeometry(this); 1479 processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop); 1480 processScrollDiff( 1481 this, 1482 'left', 1483 this.element.scrollLeft - this.lastScrollLeft 1484 ); 1485 1486 this.lastScrollTop = Math.floor(this.element.scrollTop); 1487 this.lastScrollLeft = this.element.scrollLeft; 1488 }; 1489 1490 PerfectScrollbar.prototype.destroy = function destroy () { 1491 if (!this.isAlive) { 1492 return; 1493 } 1494 1495 this.event.unbindAll(); 1496 remove(this.scrollbarX); 1497 remove(this.scrollbarY); 1498 remove(this.scrollbarXRail); 1499 remove(this.scrollbarYRail); 1500 this.removePsClasses(); 1501 1502 // unset elements 1503 this.element = null; 1504 this.scrollbarX = null; 1505 this.scrollbarY = null; 1506 this.scrollbarXRail = null; 1507 this.scrollbarYRail = null; 1508 1509 this.isAlive = false; 1510 }; 1511 1512 PerfectScrollbar.prototype.removePsClasses = function removePsClasses () { 1513 this.element.className = this.element.className 1514 .split(' ') 1515 .filter(function (name) { return !name.match(/^ps([-_].+|)$/); }) 1516 .join(' '); 1517 }; 1518 1519 /* harmony default export */ __webpack_exports__["default"] = (PerfectScrollbar); 1520 1521 1522 /***/ }), 1523 1524 /***/ "./node_modules/style-loader/index.js!./node_modules/css-loader/index.js!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css": 1525 /*!************************************************************************************************************************!*\ 1526 !*** ./node_modules/style-loader!./node_modules/css-loader!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css ***! 1527 \************************************************************************************************************************/ 1528 /*! no static exports found */ 1529 /***/ (function(module, exports, __webpack_require__) { 1530 1531 1532 var content = __webpack_require__(/*! !../../css-loader!./perfect-scrollbar.css */ "./node_modules/css-loader/index.js!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css"); 1533 1534 if(typeof content === 'string') content = [[module.i, content, '']]; 1535 1536 var transform; 1537 var insertInto; 1538 1539 1540 1541 var options = {"hmr":true} 1542 1543 options.transform = transform 1544 options.insertInto = undefined; 1545 1546 var update = __webpack_require__(/*! ../../style-loader/lib/addStyles.js */ "./node_modules/style-loader/lib/addStyles.js")(content, options); 1547 1548 if(content.locals) module.exports = content.locals; 1549 1550 if(false) {} 1551 1552 /***/ }), 1553 1554 /***/ "./node_modules/style-loader/lib/addStyles.js": 1555 /*!****************************************************!*\ 1556 !*** ./node_modules/style-loader/lib/addStyles.js ***! 1557 \****************************************************/ 1558 /*! no static exports found */ 1559 /***/ (function(module, exports, __webpack_require__) { 1560 1561 /* 1562 MIT License http://www.opensource.org/licenses/mit-license.php 1563 Author Tobias Koppers @sokra 1564 */ 1565 1566 var stylesInDom = {}; 1567 1568 var memoize = function (fn) { 1569 var memo; 1570 1571 return function () { 1572 if (typeof memo === "undefined") memo = fn.apply(this, arguments); 1573 return memo; 1574 }; 1575 }; 1576 1577 var isOldIE = memoize(function () { 1578 // Test for IE <= 9 as proposed by Browserhacks 1579 // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 1580 // Tests for existence of standard globals is to allow style-loader 1581 // to operate correctly into non-standard environments 1582 // @see https://github.com/webpack-contrib/style-loader/issues/177 1583 return window && document && document.all && !window.atob; 21 $('body').toggleClass('offcanvas-open'); 22 }); 23 24 // Close buttons for the offcanvas menu 25 $('.close-sidebar-inner, .offcanvas-menu-background').on('click', function() { 26 $('body').removeClass('offcanvas-open'); 27 }); 28 29 // Resize handler to check visibility on window resize 30 $(window).on('resize', function() { 31 checkVisibility(); 32 }); 33 34 // Initial visibility check 35 checkVisibility(); 1584 36 }); 1585 37 1586 var getTarget = function (target, parent) { 1587 if (parent){ 1588 return parent.querySelector(target); 1589 } 1590 return document.querySelector(target); 1591 }; 38 // jQuery is assumed to be loaded 39 $(document).ready(function() { 40 // When a menu item with a submenu is clicked 41 $('#offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a').on('click', function(e) { 42 e.preventDefault(); // Prevent the default link behavior 1592 43 1593 var getElement = (function (fn) { 1594 var memo = {};44 // Remove the 'sub-active' class from all submenus 45 $('#offcanvas_container #offcanvas_menu_inner .sub-menu').removeClass('sub-active'); 1595 46 1596 return function(target, parent) { 1597 // If passing function in options, then use it for resolve "head" element. 1598 // Useful for Shadow Root style i.e 1599 // { 1600 // insertInto: function () { return document.querySelector("#foo").shadowRoot } 1601 // } 1602 if (typeof target === 'function') { 1603 return target(); 1604 } 1605 if (typeof memo[target] === "undefined") { 1606 var styleTarget = getTarget.call(this, target, parent); 1607 // Special case to return head of iframe instead of iframe itself 1608 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { 1609 try { 1610 // This will throw an exception if access to iframe is blocked 1611 // due to cross-origin restrictions 1612 styleTarget = styleTarget.contentDocument.head; 1613 } catch(e) { 1614 styleTarget = null; 1615 } 1616 } 1617 memo[target] = styleTarget; 1618 } 1619 return memo[target] 1620 }; 1621 })(); 47 // Add the 'sub-active' class to the current submenu 48 $(this).next('.sub-menu').toggleClass('sub-active'); 49 }); 1622 50 1623 var singleton = null; 1624 var singletonCounter = 0; 1625 var stylesInsertedAtTop = []; 1626 1627 var fixUrls = __webpack_require__(/*! ./urls */ "./node_modules/style-loader/lib/urls.js"); 1628 1629 module.exports = function(list, options) { 1630 if (typeof DEBUG !== "undefined" && DEBUG) { 1631 if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); 1632 } 1633 1634 options = options || {}; 1635 1636 options.attrs = typeof options.attrs === "object" ? options.attrs : {}; 1637 1638 // Force single-tag solution on IE6-9, which has a hard limit on the # of <style> 1639 // tags it will allow on a page 1640 if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE(); 1641 1642 // By default, add <style> tags to the <head> element 1643 if (!options.insertInto) options.insertInto = "head"; 1644 1645 // By default, add <style> tags to the bottom of the target 1646 if (!options.insertAt) options.insertAt = "bottom"; 1647 1648 var styles = listToStyles(list, options); 1649 1650 addStylesToDom(styles, options); 1651 1652 return function update (newList) { 1653 var mayRemove = []; 1654 1655 for (var i = 0; i < styles.length; i++) { 1656 var item = styles[i]; 1657 var domStyle = stylesInDom[item.id]; 1658 1659 domStyle.refs--; 1660 mayRemove.push(domStyle); 1661 } 1662 1663 if(newList) { 1664 var newStyles = listToStyles(newList, options); 1665 addStylesToDom(newStyles, options); 1666 } 1667 1668 for (var i = 0; i < mayRemove.length; i++) { 1669 var domStyle = mayRemove[i]; 1670 1671 if(domStyle.refs === 0) { 1672 for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j](); 1673 1674 delete stylesInDom[domStyle.id]; 1675 } 1676 } 1677 }; 1678 }; 1679 1680 function addStylesToDom (styles, options) { 1681 for (var i = 0; i < styles.length; i++) { 1682 var item = styles[i]; 1683 var domStyle = stylesInDom[item.id]; 1684 1685 if(domStyle) { 1686 domStyle.refs++; 1687 1688 for(var j = 0; j < domStyle.parts.length; j++) { 1689 domStyle.parts[j](item.parts[j]); 1690 } 1691 1692 for(; j < item.parts.length; j++) { 1693 domStyle.parts.push(addStyle(item.parts[j], options)); 1694 } 1695 } else { 1696 var parts = []; 1697 1698 for(var j = 0; j < item.parts.length; j++) { 1699 parts.push(addStyle(item.parts[j], options)); 1700 } 1701 1702 stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts}; 1703 } 1704 } 1705 } 1706 1707 function listToStyles (list, options) { 1708 var styles = []; 1709 var newStyles = {}; 1710 1711 for (var i = 0; i < list.length; i++) { 1712 var item = list[i]; 1713 var id = options.base ? item[0] + options.base : item[0]; 1714 var css = item[1]; 1715 var media = item[2]; 1716 var sourceMap = item[3]; 1717 var part = {css: css, media: media, sourceMap: sourceMap}; 1718 1719 if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]}); 1720 else newStyles[id].parts.push(part); 1721 } 1722 1723 return styles; 1724 } 1725 1726 function insertStyleElement (options, style) { 1727 var target = getElement(options.insertInto) 1728 1729 if (!target) { 1730 throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid."); 1731 } 1732 1733 var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1]; 1734 1735 if (options.insertAt === "top") { 1736 if (!lastStyleElementInsertedAtTop) { 1737 target.insertBefore(style, target.firstChild); 1738 } else if (lastStyleElementInsertedAtTop.nextSibling) { 1739 target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling); 1740 } else { 1741 target.appendChild(style); 1742 } 1743 stylesInsertedAtTop.push(style); 1744 } else if (options.insertAt === "bottom") { 1745 target.appendChild(style); 1746 } else if (typeof options.insertAt === "object" && options.insertAt.before) { 1747 var nextSibling = getElement(options.insertAt.before, target); 1748 target.insertBefore(style, nextSibling); 1749 } else { 1750 throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n"); 1751 } 1752 } 1753 1754 function removeStyleElement (style) { 1755 if (style.parentNode === null) return false; 1756 style.parentNode.removeChild(style); 1757 1758 var idx = stylesInsertedAtTop.indexOf(style); 1759 if(idx >= 0) { 1760 stylesInsertedAtTop.splice(idx, 1); 1761 } 1762 } 1763 1764 function createStyleElement (options) { 1765 var style = document.createElement("style"); 1766 1767 if(options.attrs.type === undefined) { 1768 options.attrs.type = "text/css"; 1769 } 1770 1771 if(options.attrs.nonce === undefined) { 1772 var nonce = getNonce(); 1773 if (nonce) { 1774 options.attrs.nonce = nonce; 1775 } 1776 } 1777 1778 addAttrs(style, options.attrs); 1779 insertStyleElement(options, style); 1780 1781 return style; 1782 } 1783 1784 function createLinkElement (options) { 1785 var link = document.createElement("link"); 1786 1787 if(options.attrs.type === undefined) { 1788 options.attrs.type = "text/css"; 1789 } 1790 options.attrs.rel = "stylesheet"; 1791 1792 addAttrs(link, options.attrs); 1793 insertStyleElement(options, link); 1794 1795 return link; 1796 } 1797 1798 function addAttrs (el, attrs) { 1799 Object.keys(attrs).forEach(function (key) { 1800 el.setAttribute(key, attrs[key]); 1801 }); 1802 } 1803 1804 function getNonce() { 1805 if (false) {} 1806 1807 return __webpack_require__.nc; 1808 } 1809 1810 function addStyle (obj, options) { 1811 var style, update, remove, result; 1812 1813 // If a transform function was defined, run it on the css 1814 if (options.transform && obj.css) { 1815 result = typeof options.transform === 'function' 1816 ? options.transform(obj.css) 1817 : options.transform.default(obj.css); 1818 1819 if (result) { 1820 // If transform returns a value, use that instead of the original css. 1821 // This allows running runtime transformations on the css. 1822 obj.css = result; 1823 } else { 1824 // If the transform function returns a falsy value, don't add this css. 1825 // This allows conditional loading of css 1826 return function() { 1827 // noop 1828 }; 1829 } 1830 } 1831 1832 if (options.singleton) { 1833 var styleIndex = singletonCounter++; 1834 1835 style = singleton || (singleton = createStyleElement(options)); 1836 1837 update = applyToSingletonTag.bind(null, style, styleIndex, false); 1838 remove = applyToSingletonTag.bind(null, style, styleIndex, true); 1839 1840 } else if ( 1841 obj.sourceMap && 1842 typeof URL === "function" && 1843 typeof URL.createObjectURL === "function" && 1844 typeof URL.revokeObjectURL === "function" && 1845 typeof Blob === "function" && 1846 typeof btoa === "function" 1847 ) { 1848 style = createLinkElement(options); 1849 update = updateLink.bind(null, style, options); 1850 remove = function () { 1851 removeStyleElement(style); 1852 1853 if(style.href) URL.revokeObjectURL(style.href); 1854 }; 1855 } else { 1856 style = createStyleElement(options); 1857 update = applyToTag.bind(null, style); 1858 remove = function () { 1859 removeStyleElement(style); 1860 }; 1861 } 1862 1863 update(obj); 1864 1865 return function updateStyle (newObj) { 1866 if (newObj) { 1867 if ( 1868 newObj.css === obj.css && 1869 newObj.media === obj.media && 1870 newObj.sourceMap === obj.sourceMap 1871 ) { 1872 return; 1873 } 1874 1875 update(obj = newObj); 1876 } else { 1877 remove(); 1878 } 1879 }; 1880 } 1881 1882 var replaceText = (function () { 1883 var textStore = []; 1884 1885 return function (index, replacement) { 1886 textStore[index] = replacement; 1887 1888 return textStore.filter(Boolean).join('\n'); 1889 }; 1890 })(); 1891 1892 function applyToSingletonTag (style, index, remove, obj) { 1893 var css = remove ? "" : obj.css; 1894 1895 if (style.styleSheet) { 1896 style.styleSheet.cssText = replaceText(index, css); 1897 } else { 1898 var cssNode = document.createTextNode(css); 1899 var childNodes = style.childNodes; 1900 1901 if (childNodes[index]) style.removeChild(childNodes[index]); 1902 1903 if (childNodes.length) { 1904 style.insertBefore(cssNode, childNodes[index]); 1905 } else { 1906 style.appendChild(cssNode); 1907 } 1908 } 1909 } 1910 1911 function applyToTag (style, obj) { 1912 var css = obj.css; 1913 var media = obj.media; 1914 1915 if(media) { 1916 style.setAttribute("media", media) 1917 } 1918 1919 if(style.styleSheet) { 1920 style.styleSheet.cssText = css; 1921 } else { 1922 while(style.firstChild) { 1923 style.removeChild(style.firstChild); 1924 } 1925 1926 style.appendChild(document.createTextNode(css)); 1927 } 1928 } 1929 1930 function updateLink (link, options, obj) { 1931 var css = obj.css; 1932 var sourceMap = obj.sourceMap; 1933 1934 /* 1935 If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled 1936 and there is no publicPath defined then lets turn convertToAbsoluteUrls 1937 on by default. Otherwise default to the convertToAbsoluteUrls option 1938 directly 1939 */ 1940 var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap; 1941 1942 if (options.convertToAbsoluteUrls || autoFixUrls) { 1943 css = fixUrls(css); 1944 } 1945 1946 if (sourceMap) { 1947 // http://stackoverflow.com/a/26603875 1948 css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */"; 1949 } 1950 1951 var blob = new Blob([css], { type: "text/css" }); 1952 1953 var oldSrc = link.href; 1954 1955 link.href = URL.createObjectURL(blob); 1956 1957 if(oldSrc) URL.revokeObjectURL(oldSrc); 1958 } 1959 1960 1961 /***/ }), 1962 1963 /***/ "./node_modules/style-loader/lib/urls.js": 1964 /*!***********************************************!*\ 1965 !*** ./node_modules/style-loader/lib/urls.js ***! 1966 \***********************************************/ 1967 /*! no static exports found */ 1968 /***/ (function(module, exports) { 1969 1970 1971 /** 1972 * When source maps are enabled, `style-loader` uses a link element with a data-uri to 1973 * embed the css on the page. This breaks all relative urls because now they are relative to a 1974 * bundle instead of the current page. 1975 * 1976 * One solution is to only use full urls, but that may be impossible. 1977 * 1978 * Instead, this function "fixes" the relative urls to be absolute according to the current page location. 1979 * 1980 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command. 1981 * 1982 */ 1983 1984 module.exports = function (css) { 1985 // get current location 1986 var location = typeof window !== "undefined" && window.location; 1987 1988 if (!location) { 1989 throw new Error("fixUrls requires window.location"); 1990 } 1991 1992 // blank or null? 1993 if (!css || typeof css !== "string") { 1994 return css; 1995 } 1996 1997 var baseUrl = location.protocol + "//" + location.host; 1998 var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/"); 1999 2000 // convert each url(...) 2001 /* 2002 This regular expression is just a way to recursively match brackets within 2003 a string. 2004 2005 /url\s*\( = Match on the word "url" with any whitespace after it and then a parens 2006 ( = Start a capturing group 2007 (?: = Start a non-capturing group 2008 [^)(] = Match anything that isn't a parentheses 2009 | = OR 2010 \( = Match a start parentheses 2011 (?: = Start another non-capturing groups 2012 [^)(]+ = Match anything that isn't a parentheses 2013 | = OR 2014 \( = Match a start parentheses 2015 [^)(]* = Match anything that isn't a parentheses 2016 \) = Match a end parentheses 2017 ) = End Group 2018 *\) = Match anything and then a close parens 2019 ) = Close non-capturing group 2020 * = Match anything 2021 ) = Close capturing group 2022 \) = Match a close parens 2023 2024 /gi = Get all matches, not the first. Be case insensitive. 2025 */ 2026 var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) { 2027 // strip quotes (if they exist) 2028 var unquotedOrigUrl = origUrl 2029 .trim() 2030 .replace(/^"(.*)"$/, function(o, $1){ return $1; }) 2031 .replace(/^'(.*)'$/, function(o, $1){ return $1; }); 2032 2033 // already a full url? no change 2034 if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(unquotedOrigUrl)) { 2035 return fullMatch; 2036 } 2037 2038 // convert the url to a full url 2039 var newUrl; 2040 2041 if (unquotedOrigUrl.indexOf("//") === 0) { 2042 //TODO: should we add protocol? 2043 newUrl = unquotedOrigUrl; 2044 } else if (unquotedOrigUrl.indexOf("/") === 0) { 2045 // path should be relative to the base url 2046 newUrl = baseUrl + unquotedOrigUrl; // already starts with '/' 2047 } else { 2048 // path should be relative to current directory 2049 newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './' 2050 } 2051 2052 // send back the fixed url(...) 2053 return "url(" + JSON.stringify(newUrl) + ")"; 2054 }); 2055 2056 // send back the fixed css 2057 return fixedCss; 2058 }; 2059 2060 2061 /***/ }), 2062 2063 /***/ "./resources/assets/js/app.js": 2064 /*!************************************!*\ 2065 !*** ./resources/assets/js/app.js ***! 2066 \************************************/ 2067 /*! no exports provided */ 2068 /***/ (function(module, __webpack_exports__, __webpack_require__) { 2069 2070 "use strict"; 2071 __webpack_require__.r(__webpack_exports__); 2072 /* harmony import */ var perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! perfect-scrollbar */ "./node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js"); 2073 2074 2075 __webpack_require__(/*! style-loader!css-loader!perfect-scrollbar/css/perfect-scrollbar.css */ "./node_modules/style-loader/index.js!./node_modules/css-loader/index.js!./node_modules/perfect-scrollbar/css/perfect-scrollbar.css"); 2076 2077 function offcanvasOpen() { 2078 return jQuery('body').hasClass('offcanvas-open'); 2079 } 2080 2081 function openOffcanvas() { 2082 jQuery('body').addClass('offcanvas-open'); 2083 } 2084 2085 function closeOffcanvas() { 2086 jQuery('body').removeClass('offcanvas-open'); 2087 } 2088 2089 function aw_trigger_offcanvas() { 2090 if (offcanvasOpen()) { 2091 closeOffcanvas(); 2092 } else { 2093 openOffcanvas(); 2094 } 2095 } 2096 2097 jQuery(document).ready(function () { 2098 jQuery('#offcanvas_container').find('a').each(function () { 2099 var _this = this; 2100 2101 var currentLink = jQuery(this); 2102 var currentListItem = jQuery(this).parent('li'); 2103 2104 if (jQuery(this).next('.sub-menu').length == 0) { 2105 return; 2106 } 2107 2108 jQuery(this).data('clicks', 0); 2109 jQuery(this).on('click touchstart', function (e) { 2110 var clickedLink = jQuery(_this); 2111 var clickedListItem = jQuery(_this).parent('li'); 2112 2113 if (jQuery(_this).data('clicks') == 0) { 2114 e.preventDefault(); 2115 2116 if (jQuery(_this).parent('li').hasClass('visible')) { 2117 jQuery(_this).parent('li').removeClass('visible'); 2118 jQuery(_this).next('.sub-menu').slideUp(); 2119 } else { 2120 jQuery(_this).parent('li').addClass('visible'); 2121 jQuery(_this).next('.sub-menu').slideDown(); // Schließe alle offenen Submenus, die sich auf gleicher Ebene befinden 2122 // Außer das geöffnete 2123 2124 jQuery(_this).parent('li').parent('ul').children('li').not(clickedListItem).each(function () { 2125 jQuery(this).removeClass('visible'); 2126 jQuery(this).children('.sub-menu').slideUp(); 2127 jQuery(this).children('a').data('clicks', 0); 2128 }); 2129 } 2130 2131 jQuery(_this).data('clicks', jQuery(_this).data('clicks') + 1); 2132 return; 2133 } // Wenn Link ins leere läuft (href ist '#') soll beim zweiten Klick 2134 // nicht weitergeleitet werden. Stattdessen wird das Menü 2135 // geschlossen. Auch werden clicks auf 0 zurückgesetzt 2136 // damit ein Öffnen danach möglich ist. 2137 2138 2139 if (jQuery(_this).attr('href') == '#') { 2140 e.preventDefault(); 2141 jQuery(_this).parent('li').removeClass('visible'); 2142 jQuery(_this).next('.sub-menu').slideUp(); 2143 jQuery(_this).data('clicks', 0); 2144 } 2145 2146 if (e.type == 'touchstart') { 2147 window.location.href = jQuery(_this).attr('href'); 2148 return; 2149 } 51 // Toggle visibility of the current menu item 52 $('#offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a').on('click', function(e) { 53 e.preventDefault(); // Prevent the default link behavior 54 55 // Remove the 'sub-active' class from all submenus 56 $('#offcanvas_container #offcanvas_menu_inner .sub-menu').removeClass('sub-active'); 57 58 // Add the 'visible' class to the current menu item 59 $(this).parent().toggleClass('visible'); 2150 60 }); 2151 });2152 jQuery('#et-top-navigation .mobile_menu_bar_toggle').click(function (e) {2153 e.preventDefault();2154 var container = document.querySelector('#offcanvas_container');2155 window.ps = new perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__["default"](container, {2156 suppressScrollX: true2157 });2158 aw_trigger_offcanvas();2159 ps.update();2160 ps.update();2161 });2162 jQuery('.close-sidebar-inner, .offcanvas-menu-background').click(function (e) {2163 e.preventDefault();2164 aw_trigger_offcanvas();2165 });2166 jQuery(window).resize(function () {2167 if (jQuery('#offcanvas_container').data('max') === false) {2168 return;2169 }2170 2171 if (jQuery('#offcanvas_container').data('max') < window.innerWidth && jQuery('#page-container').hasClass('push')) {2172 jQuery('#page-container').unbind('click');2173 removePushFromPageContainer();2174 }2175 });2176 61 }); 2177 62 2178 /***/ }), 2179 2180 /***/ "./resources/assets/sass/app.scss": 2181 /*!****************************************!*\ 2182 !*** ./resources/assets/sass/app.scss ***! 2183 \****************************************/ 2184 /*! no static exports found */ 2185 /***/ (function(module, exports) { 2186 2187 // removed by extract-text-webpack-plugin 2188 2189 /***/ }), 2190 2191 /***/ 0: 2192 /*!***************************************************************************!*\ 2193 !*** multi ./resources/assets/js/app.js ./resources/assets/sass/app.scss ***! 2194 \***************************************************************************/ 2195 /*! no static exports found */ 2196 /***/ (function(module, exports, __webpack_require__) { 2197 2198 __webpack_require__(/*! /Users/werbeagenturaweos/www/wordpressPlugins/aweos-offcanvas-menu/trunk/resources/assets/js/app.js */"./resources/assets/js/app.js"); 2199 module.exports = __webpack_require__(/*! /Users/werbeagenturaweos/www/wordpressPlugins/aweos-offcanvas-menu/trunk/resources/assets/sass/app.scss */"./resources/assets/sass/app.scss"); 2200 2201 2202 /***/ }) 2203 2204 /******/ }); 63 $(document).ready(function() { 64 $('#offcanvas_container #offcanvas_menu_inner > li.menu-item.menu-item-has-children > a').on('click', function(e) { 65 e.preventDefault(); // Prevent the default link behavior 66 $(this).parent().toggleClass('visible'); // Toggle visibility 67 }); 68 }); -
aweos-offcanvas-menu/trunk/public/js/customize.js
r2014889 r3218885 1 /* 1 2 /******/ (function(modules) { // webpackBootstrap 2 3 /******/ // The module cache … … 18 19 /******/ 19 20 /******/ // Execute the module function 20 /****** /modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);21 /****** modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 22 /******/ 22 23 /******/ // Flag the module as loaded … … 95 96 96 97 (function ($) { 97 wp.customize('aw_offcanvas_background_color_setting', function (value) { 98 value.bind(function (newval) { 99 jQuery('#offcanvas_container').css({ 100 'background-color': newval 101 }); 102 jQuery('#offcanvas_menu_inner > li.menu-item > ul > li.menu-item > ul').css({ 103 'background-color': newval 98 'use strict'; 99 100 // Wenn wir im Customizer sind 101 if (wp.customize) { 102 // Menu initial öffnen 103 $(document).ready(function() { 104 if ($('#offcanvas_menu').length) { 105 $('#offcanvas_menu').addClass('awoc-active'); 106 $('.awoc-overlay').addClass('awoc-active'); 107 $('body').addClass('awoc-menu-open'); 108 } 109 }); 110 111 // Verhindern, dass das Menu geschlossen wird 112 $(document).on('click', '.awoc-close, .awoc-overlay', function(e) { 113 if (wp.customize) { 114 e.preventDefault(); 115 e.stopPropagation(); 116 return false; 117 } 118 }); 119 120 // Live-Updates für die Customizer-Einstellungen 121 wp.customize('awoc_offcanvas_background_color_setting', function(value) { 122 value.bind(function(newval) { 123 $('#offcanvas_menu').css('background-color', newval); 104 124 }); 105 125 }); 106 });107 wp.customize('aw_offcanvas_border_right_color_setting', function (value) {108 value.bind(function (newval) {109 jQuery('#offcanvas_container .ps__rail-y').css({110 'background-color': newval111 });112 });113 });114 wp.customize('aw_offcanvas_border_color_setting', function (value) {115 value.bind(function (newval) {116 jQuery('#offcanvas_container li.menu-item').children('a').css({117 'border-bottom-color': newval118 });119 jQuery('#offcanvas_container .close-sidebar-inner').css({120 'border-bottom-color': newval121 });122 });123 });124 wp.customize('aw_offcanvas_font_color_setting', function (value) {125 value.bind(function (newval) {126 jQuery('#offcanvas_container li.menu-item').children('a').css({127 'color': newval128 });129 jQuery('#offcanvas_container .close-sidebar-inner').children('span').eq(0).css({130 color: newval131 });132 });133 });134 wp.customize('aw_offcanvas_open_font_setting', function (value) {135 value.bind(function (newval) {136 jQuery('#offcanvas_container li.menu-item.visible').children('a').css({137 'color': newval138 });139 });140 });141 wp.customize('aw_offcanvas_open_background_setting', function (value) {142 value.bind(function (newval) {143 jQuery('#offcanvas_container li.menu-item.visible').children('a').css({144 'background-color': newval145 });146 });147 });148 wp.customize('aw_offcanvas_close_background_setting', function (value) {149 value.bind(function (newval) {150 jQuery('#offcanvas_container .close-sidebar-inner').css({151 'background-color': newval152 });153 });154 });155 wp.customize('aw_offcanvas_close_color_setting', function (value) {156 value.bind(function (newval) {157 jQuery('#offcanvas_container .close-sidebar-inner span').css({158 'color': newval159 });160 jQuery('#offcanvas_container .close-sidebar-inner .fa').css({161 'color': newval162 });163 126 164 if (document.getElementById('aw-offcanvas-close-style')) { 165 document.getElementById('aw-offcanvas-close-style').remove(); 166 } 167 168 var css = document.createElement("style"); 169 css.setAttribute('id', 'aw-offcanvas-close-style'); 170 css.type = "text/css"; 171 css.innerHTML = "#offcanvas_container .close-sidebar-inner .fa:before { background-color: " + newval + " } #offcanvas_container .close-sidebar-inner .fa:after { background-color: " + newval + " }"; 172 document.body.appendChild(css); 173 }); 174 }); 127 // ... weitere Customizer-Bindings ... 128 } 175 129 })(jQuery); 176 130 … … 189 143 /***/ }) 190 144 191 /******/});145 }); -
aweos-offcanvas-menu/trunk/readme.txt
r3121136 r3218885 4 4 Donate link: https://aweos.de 5 5 Tested up to: 6.6 6 Requires at least: 5.0 6 7 Requires PHP: 7.0 8 Requires: jQuery 7 9 Stable tag: trunk 10 Version: 2.0.0 8 11 License: GPL v2 or later 9 12 License URI: http://www.gnu.org/licenses/gpl-2.0.txt 10 13 11 This Plugin creates a nice looking and mobile friendly sidemenu. It requires the Divi Theme.14 This Plugin creates a mobile-friendly sidemenu that works with any WordPress theme, though it's optimized for Divi. 12 15 13 16 == Description == … … 40 43 == Frequently Asked Questions == 41 44 42 There are no FAQ 's at the moment45 There are no FAQs at the moment 43 46 44 47 == Screenshots == … … 48 51 == Changelog == 49 52 50 ### 1.4.1 51 Update Readme 53 ### 2.0.0 54 * Complete code overhaul for better performance 55 * Removal of all external dependencies 56 * Optimized CSS structure following best practices 57 * Unified menu arrow design 58 * Improved customizer integration 59 * Reduced file size 60 * Faster loading times 61 * Simplified scrollbar implementation 62 63 ### 1.4.3 64 * Removed external dependencies for better performance and compatibility 65 * Simplified scrollbar implementation 66 * Improved CSS generation 67 68 ### 1.4.2 69 * Update Readme 52 70 53 71 ### 1.2.3
Note: See TracChangeset
for help on using the changeset viewer.