Plugin Directory

Changeset 3218885


Ignore:
Timestamp:
01/08/2025 10:11:59 AM (15 months ago)
Author:
aweos
Message:

Version 2.0.0: Code overhaul, removed dependencies, optimized CSS, unified menu design, improved customizer, reduced size, faster loading, simplified scrollbar.

Location:
aweos-offcanvas-menu/trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • aweos-offcanvas-menu/trunk/aweos-offcanvas-menu.php

    r3121136 r3218885  
    33Plugin Name: AWEOS Offcanvas Menu for Divi
    44Plugin URI:  https://developer.wordpress.org/plugins/aweos-offcanvas-menu/
    5 Description: Displays an offcanvas menu
    6 Version:     1.4.2
     5Description: Displays an offcanvas menu 
     6Version:     2.0.0
    77Author:      AWEOS GmbH
    88Author URI:  https://aweos.de
     
    1313*/
    1414
    15 require_once(__DIR__.'/vendor/autoload.php');
    16 
    17 use MatthiasMullie\Minify;
     15// Ersetze Minify durch WordPress eigene Funktionen
     16function 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}
    1823
    1924function awoc_register_offcanvas_menu()
     
    2631function awoc_offcanvas_asset()
    2732{
    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);
    3137    }
    3238}
     
    4450function awoc_offcanvas_customizer($wp_customize)
    4551{
    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(
    52108        '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
    229126    $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(
    236131        '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,
    240136    ));
    241137
    242138    $wp_customize->add_setting('awoc_offcanvas_always_active_setting', array(
    243         'title'      => __('Always active', 'awoc_offcanvas'),
    244         'priority'   => 30,
    245139        '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(
    249143        'type' => 'checkbox',
    250144        'label' => __('Always active', 'awoc_offcanvas'),
    251145        '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    )));
    254458}
    255459add_action('customize_register', 'awoc_offcanvas_customizer', 1, 100);
    256460
     461function 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
    257778add_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 
     779function awoc_offcanvas_inline_style() {
    284780    echo '<style type="text/css">';
    285     echo $minifier->minify();
     781    echo awoc_generate_inline_css();
    286782    echo '</style>';
    287783}
     
    290786function awoc_display_offcanvas_menu()
    291787{
    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>';
    294818    echo wp_nav_menu([
    295819        'theme_location' => 'offcanvas-menu',
     
    318842    ]);
    319843}
     844
     845// Füge das generierte CSS zum Header hinzu
     846add_action('wp_head', 'awoc_generate_custom_css');
     847function 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
     913add_action('wp_footer', 'awoc_add_menu_interaction_script');
     914function 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  
    11/* Disable default Divi menu */
    22
    3 #mobile_menu {
     3.et_mobile_menu {
    44  display: none !important;
     5  visibility: hidden;
    56}
    67
     
    5859
    5960#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 {
    60129  font-weight: 400;
    61130  font-family: Arial;
     
    64133  line-height: 40px;
    65134  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 {
    70139  display: flex;
    71140  flex-wrap: wrap;
    72141}
    73142
    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 {
    75144  width: 100%;
    76   display: block;
    77145  display: flex;
    78146  flex-direction: row;
     
    81149}
    82150
    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;
     164background-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 {
    84359  content: "5";
    85360  -webkit-transform: rotate(0deg);
    86           transform: rotate(0deg);
     361  transform: rotate(0deg);
    87362  transition: -webkit-transform 0.2s;
    88363  transition: transform 0.2s;
     
    104379  align-items: center;
    105380  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 {
    121390  display: none;
    122391  padding-left: 0;
    123392  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 {
    137406  display: flex;
    138407  flex-wrap: wrap;
    139408}
    140409
    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 {
    142411  width: 100%;
    143   display: block;
    144412  display: flex;
    145413  flex-direction: row;
     
    148416}
    149417
    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 {
    151419  content: "5";
    152420  -webkit-transform: rotate(0deg);
    153           transform: rotate(0deg);
     421  transform: rotate(0deg);
    154422  transition: -webkit-transform 0.2s;
    155423  transition: transform 0.2s;
     
    171439  align-items: center;
    172440  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 {
    188450  display: none;
    189451  padding-left: 0;
     
    191453}
    192454
    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 {
    200465  padding: 0 10px 0 35px;
    201466}
    202467
    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 */
    276503#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;
    283510}
    284511
    285512#offcanvas_container .close-sidebar-inner .fa:before,
    286513#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;
    292520}
    293521
    294522#offcanvas_container .close-sidebar-inner .fa:before {
    295   -webkit-transform: rotate(45deg);
    296           transform: rotate(45deg);
     523    transform: rotate(45deg);
    297524}
    298525
    299526#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 */
    304531#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";
     1jQuery(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        }
    21816    }
    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) {
    124420        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();
    158436});
    158537
    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
    159243
    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');
    159546
    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    });
    162250
    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');
    215060    });
    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: true
    2157     });
    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   });
    217661});
    217762
    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/*
    12/******/ (function(modules) { // webpackBootstrap
    23/******/    // The module cache
     
    1819/******/
    1920/******/        // 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__);
    2122/******/
    2223/******/        // Flag the module as loaded
     
    9596
    9697(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);
    104124      });
    105125    });
    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': newval
    111       });
    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': newval
    118       });
    119       jQuery('#offcanvas_container .close-sidebar-inner').css({
    120         'border-bottom-color': newval
    121       });
    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': newval
    128       });
    129       jQuery('#offcanvas_container .close-sidebar-inner').children('span').eq(0).css({
    130         color: newval
    131       });
    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': newval
    138       });
    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': newval
    145       });
    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': newval
    152       });
    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': newval
    159       });
    160       jQuery('#offcanvas_container .close-sidebar-inner .fa').css({
    161         'color': newval
    162       });
    163126
    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  }
    175129})(jQuery);
    176130
     
    189143/***/ })
    190144
    191 /******/ });
     145});
  • aweos-offcanvas-menu/trunk/readme.txt

    r3121136 r3218885  
    44Donate link: https://aweos.de
    55Tested up to: 6.6
     6Requires at least: 5.0
    67Requires PHP: 7.0
     8Requires: jQuery
    79Stable tag: trunk
     10Version: 2.0.0
    811License: GPL v2 or later
    912License URI: http://www.gnu.org/licenses/gpl-2.0.txt
    1013
    11 This Plugin creates a nice looking and mobile friendly sidemenu. It requires the Divi Theme.
     14This Plugin creates a mobile-friendly sidemenu that works with any WordPress theme, though it's optimized for Divi.
    1215
    1316== Description ==
     
    4043== Frequently Asked Questions ==
    4144
    42 There are no FAQ's at the moment
     45There are no FAQs at the moment
    4346
    4447== Screenshots ==
     
    4851== Changelog ==
    4952
    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
    5270
    5371### 1.2.3
Note: See TracChangeset for help on using the changeset viewer.