item_spacing) && 'discard' === $args->item_spacing) { $t = ''; $n = ''; } else { $t = "\t"; $n = "\n"; } $indent = str_repeat($t, $depth); // Default class to add to the file. $classes = array('dropdown-menu'); /** * Filters the CSS class(es) applied to a menu list element. * * @param array $classes The CSS classes that are applied to the menu `'; if ($container) { $fallback_output .= ''; } // if $args has 'echo' key and it's true echo, otherwise return. if (array_key_exists('echo', $args) && $args['echo']) { echo wp_specialchars_decode($fallback_output); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } else { return $fallback_output; } } } /** * Find any custom linkmod or icon classes and store in their holder * arrays then remove them from the main classes array. * * Supported linkmods: .disabled, .dropdown-header, .dropdown-divider, .sr-only * Supported iconsets: Font Awesome 4/5, Glypicons * * NOTE: This accepts the linkmod and icon arrays by reference. * * @param array $classes an array of classes currently assigned to the item. * @param array $linkmod_classes an array to hold linkmod classes. * @param array $icon_classes an array to hold icon classes. * @param integer $depth an integer holding current depth level. * * @return array $classes a maybe modified array of classnames. * @since 4.0.0 * */ private function separate_linkmods_and_icons_from_classes($classes, &$linkmod_classes, &$icon_classes, $depth) { // Loop through $classes array to find linkmod or icon classes. foreach ($classes as $key => $class) { // If any special classes are found, store the class in it's // holder array and and unset the item from $classes. if (preg_match('/^disabled|^sr-only/i', $class)) { // Test for .disabled or .sr-only classes. $linkmod_classes[] = $class; unset($classes[$key]); } elseif (preg_match('/^dropdown-header|^dropdown-divider|^dropdown-item-text/i', $class) && $depth > 0) { // Test for .dropdown-header or .dropdown-divider and a // depth greater than 0 - IE inside a dropdown. $linkmod_classes[] = $class; unset($classes[$key]); } elseif (preg_match('/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/i', $class)) { // Font Awesome. $icon_classes[] = $class; unset($classes[$key]); } elseif (preg_match('/^glyphicon-(\S*)?|^glyphicon(\s?)$/i', $class)) { // Glyphicons. $icon_classes[] = $class; unset($classes[$key]); } } return $classes; } /** * Return a string containing a linkmod type and update $atts array * accordingly depending on the decided. * * @param array $linkmod_classes array of any link modifier classes. * * @return string empty for default, a linkmod type string otherwise. * @since 4.0.0 * */ private function get_linkmod_type($linkmod_classes = array()) { $linkmod_type = ''; // Loop through array of linkmod classes to handle their $atts. if (!empty($linkmod_classes)) { foreach ($linkmod_classes as $link_class) { if (!empty($link_class)) { // check for special class types and set a flag for them. if ('dropdown-header' === $link_class) { $linkmod_type = 'dropdown-header'; } elseif ('dropdown-divider' === $link_class) { $linkmod_type = 'dropdown-divider'; } elseif ('dropdown-item-text' === $link_class) { $linkmod_type = 'dropdown-item-text'; } } } } return $linkmod_type; } /** * Update the attributes of a nav item depending on the limkmod classes. * * @param array $atts array of atts for the current link in nav item. * @param array $linkmod_classes an array of classes that modify link or nav item behaviors or displays. * * @return array maybe updated array of attributes for item. * @since 4.0.0 * */ private function update_atts_for_linkmod_type($atts = array(), $linkmod_classes = array()) { if (!empty($linkmod_classes)) { foreach ($linkmod_classes as $link_class) { if (!empty($link_class)) { // update $atts with a space and the extra classname... // so long as it's not a sr-only class. if ('sr-only' !== $link_class) { $atts['class'] .= ' ' . esc_attr($link_class); } // check for special class types we need additional handling for. if ('disabled' === $link_class) { // Convert link to '#' and unset open targets. $atts['href'] = '#'; unset($atts['target']); } elseif ('dropdown-header' === $link_class || 'dropdown-divider' === $link_class || 'dropdown-item-text' === $link_class) { // Store a type flag and unset href and target. unset($atts['href']); unset($atts['target']); } } } } return $atts; } /** * Wraps the passed text in a screen reader only class. * * @param string $text the string of text to be wrapped in a screen reader class. * * @return string the string wrapped in a span with the class. * @since 4.0.0 * */ private function wrap_for_screen_reader($text = '') { if ($text) { $text = '' . $text . ''; } return $text; } /** * Returns the correct opening element and attributes for a linkmod. * * @param string $linkmod_type a sting containing a linkmod type flag. * @param string $attributes a string of attributes to add to the element. * * @return string a string with the openign tag for the element with attribibutes added. * @since 4.0.0 * */ private function linkmod_element_open($linkmod_type, $attributes = '') { $output = ''; if ('dropdown-item-text' === $linkmod_type) { $output .= ''; } elseif ('dropdown-header' === $linkmod_type) { // For a header use a span with the .h6 class instead of a real // header tag so that it doesn't confuse screen readers. $output .= ''; } elseif ('dropdown-divider' === $linkmod_type) { // this is a divider. $output .= ''; } return $output; } } }