|
7 | 7 | */
|
8 | 8 |
|
9 | 9 | use AmpProject\Amp;
|
| 10 | +use AmpProject\AmpWP\Services; |
| 11 | +use AmpProject\Dom\Element; |
| 12 | +use AmpProject\Extension; |
10 | 13 | use AmpProject\Html\Attribute;
|
11 | 14 | use AmpProject\Html\Tag;
|
12 | 15 | use AmpProject\Html\Role;
|
| 16 | +use AmpProject\Layout; |
13 | 17 |
|
14 | 18 | /**
|
15 | 19 | * Class AMP_Core_Theme_Sanitizer
|
@@ -162,8 +166,13 @@ protected static function get_theme_features_config( $theme_slug, $args = [] ) {
|
162 | 166 | 'wp_print_footer_scripts' => [
|
163 | 167 | 'twentynineteen_skip_link_focus_fix', // See <https://github.com/WordPress/twentynineteen/pull/47>.
|
164 | 168 | ],
|
| 169 | + 'wp_nav_menu' => [ |
| 170 | + 'twentynineteen_add_ellipses_to_nav', |
| 171 | + ], |
165 | 172 | ],
|
166 | 173 | 'adjust_twentynineteen_images' => [],
|
| 174 | + 'update_twentynineteen_mobile_main_menu' => [], |
| 175 | + 'add_nav_menu_styles' => [], |
167 | 176 | ];
|
168 | 177 |
|
169 | 178 | // Twenty Seventeen.
|
@@ -1150,6 +1159,118 @@ static function() use ( $args ) {
|
1150 | 1159 | }
|
1151 | 1160 | }
|
1152 | 1161 |
|
| 1162 | + <?php elseif ( 'twentynineteen' === get_template() ) : ?> |
| 1163 | + .amp-twentynineteen-main-navigation { |
| 1164 | + max-width: 100vw; |
| 1165 | + width: 100vw; |
| 1166 | + height: 100vh; |
| 1167 | + } |
| 1168 | + .admin-bar .amp-twentynineteen-main-navigation { |
| 1169 | + top: 46px; |
| 1170 | + height: calc(100vh - 46px); |
| 1171 | + } |
| 1172 | + |
| 1173 | + .amp-twentynineteen-main-navigation .sub-menu > li > a:hover, |
| 1174 | + .amp-twentynineteen-main-navigation .sub-menu > li > a:focus, |
| 1175 | + .amp-twentynineteen-main-navigation .sub-menu > li > .menu-item-link-return:hover, |
| 1176 | + .amp-twentynineteen-main-navigation .sub-menu > li > .menu-item-link-return:focus { |
| 1177 | + background: inherit; |
| 1178 | + } |
| 1179 | + |
| 1180 | + .amp-twentynineteen-main-navigation .sub-menu > li { |
| 1181 | + position: static; |
| 1182 | + display: flex; |
| 1183 | + } |
| 1184 | + |
| 1185 | + .amp-twentynineteen-main-navigation .sub-menu > li.menu-item-has-children .submenu-expand { |
| 1186 | + position: static; |
| 1187 | + } |
| 1188 | + |
| 1189 | + .amp-twentynineteen-main-navigation .sub-menu.expanded-true { |
| 1190 | + display: table; |
| 1191 | + margin-top: 0; |
| 1192 | + opacity: 1; |
| 1193 | + padding-left: 0; |
| 1194 | + left: 0; |
| 1195 | + top: 0; |
| 1196 | + right: 0; |
| 1197 | + bottom: 0; |
| 1198 | + position: static; |
| 1199 | + z-index: 100000; /* Make sure appears above mobile admin bar */ |
| 1200 | + width: 100vw; |
| 1201 | + height: 100%; |
| 1202 | + max-width: 100vw; |
| 1203 | + } |
| 1204 | + |
| 1205 | + .amp-twentynineteen-main-navigation .sub-menu > li.mobile-parent-nav-menu-item { |
| 1206 | + display: block; |
| 1207 | + } |
| 1208 | + |
| 1209 | + .amp-twentynineteen-main-navigation .submenu-expand .svg-icon { |
| 1210 | + <?php if ( is_rtl() ) : ?> |
| 1211 | + transform: rotate(90deg); |
| 1212 | + <?php else : ?> |
| 1213 | + transform: rotate(270deg); |
| 1214 | + <?php endif; ?> |
| 1215 | + } |
| 1216 | + |
| 1217 | + .amp-twentynineteen-main-navigation .sub-menu > li > a, |
| 1218 | + .amp-twentynineteen-main-navigation .sub-menu > li > .menu-item-link-return { |
| 1219 | + flex-grow: 1; |
| 1220 | + max-width: none; |
| 1221 | + } |
| 1222 | + |
| 1223 | + .amp-twentynineteen-main-navigation .sub-menu > li > .menu-item-link-return .svg-icon { |
| 1224 | + <?php if ( is_rtl() ) : ?> |
| 1225 | + transform: rotate(180deg); |
| 1226 | + <?php endif; ?> |
| 1227 | + } |
| 1228 | + |
| 1229 | + .main-navigation .main-menu > li.menu-item-has-children > .submenu-expand.display-on-mobile, |
| 1230 | + .display-on-mobile { |
| 1231 | + display: none; |
| 1232 | + } |
| 1233 | + |
| 1234 | + @media only screen and (max-width: 768px) { |
| 1235 | + .display-on-mobile { |
| 1236 | + display: block; |
| 1237 | + } |
| 1238 | + |
| 1239 | + .main-navigation .main-menu .menu-item-has-children:not(.off-canvas):focus-within > .sub-menu, |
| 1240 | + .main-navigation .main-menu .menu-item-has-children:not(.off-canvas):hover > .sub-menu, |
| 1241 | + .main-navigation .main-menu .menu-item-has-children:not(.off-canvas):focus > .sub-menu, |
| 1242 | + .main-navigation .main-menu > li.menu-item-has-children .submenu-expand.display-on-desktop, |
| 1243 | + .display-on-desktop { |
| 1244 | + display: none; |
| 1245 | + } |
| 1246 | + |
| 1247 | + .main-navigation .main-menu > li.menu-item-has-children > .submenu-expand.display-on-mobile svg { |
| 1248 | + position: relative; |
| 1249 | + top: -2px; |
| 1250 | + <?php if ( is_rtl() ) : ?> |
| 1251 | + right: -2px; |
| 1252 | + <?php else : ?> |
| 1253 | + left: -2px; |
| 1254 | + <?php endif; ?> |
| 1255 | + } |
| 1256 | + |
| 1257 | + .main-navigation .main-menu > li.menu-item-has-children > .submenu-expand.display-on-mobile { |
| 1258 | + display: inline-block; |
| 1259 | + <?php if ( is_rtl() ) : ?> |
| 1260 | + margin-left: 0.5rem; |
| 1261 | + margin-right: 0.25rem; |
| 1262 | + <?php else : ?> |
| 1263 | + margin-left: 0.25rem; |
| 1264 | + margin-right: 0.5rem; |
| 1265 | + <?php endif; ?> |
| 1266 | + background: #0073aa; |
| 1267 | + color: #FFF; |
| 1268 | + border-radius: 50%; |
| 1269 | + width: 20px; |
| 1270 | + height: 20px; |
| 1271 | + vertical-align: middle; |
| 1272 | + } |
| 1273 | + } |
1153 | 1274 | <?php elseif ( 'twentyseventeen' === get_template() ) : ?>
|
1154 | 1275 | /* Show the button*/
|
1155 | 1276 | .no-js .menu-toggle {
|
@@ -2343,4 +2464,159 @@ protected function guess_modal_role( DOMElement $modal ) {
|
2343 | 2464 | // None of the roles we are looking for match any of the classes.
|
2344 | 2465 | return Role::DIALOG;
|
2345 | 2466 | }
|
| 2467 | + |
| 2468 | + /** |
| 2469 | + * Evaluates the given XPath expression and give first Element if exist. |
| 2470 | + * |
| 2471 | + * @param string $expression The XPath expression to execute. |
| 2472 | + * @param Element $context_node The optional context node can be specified for doing relative XPath queries. |
| 2473 | + * By default, the queries are relative to the root element. |
| 2474 | + * |
| 2475 | + * @return Element|null Return Element if exists otherwise null. |
| 2476 | + */ |
| 2477 | + protected function get_first_element( $expression, $context_node = null ) { |
| 2478 | + /** @var DOMNodeList $dom_node_list */ |
| 2479 | + $dom_node_list = $this->dom->xpath->query( $expression, $context_node ); |
| 2480 | + |
| 2481 | + $dom_node = $dom_node_list->item( 0 ); |
| 2482 | + return $dom_node instanceof Element ? $dom_node : null; |
| 2483 | + } |
| 2484 | + |
| 2485 | + /** |
| 2486 | + * Update main navigation menu for "twentynineteen" theme. |
| 2487 | + * |
| 2488 | + * @return void |
| 2489 | + */ |
| 2490 | + public function update_twentynineteen_mobile_main_menu() { |
| 2491 | + |
| 2492 | + $xpaths = [ |
| 2493 | + 'main_menu' => '//nav[ @id = "site-navigation" ]//ul[ @class = "main-menu"]', |
| 2494 | + 'top_menu_items' => './li[ contains( @class, "menu-item" ) and contains( @class, "menu-item-has-children" ) ]', |
| 2495 | + 'expand_button' => './button[ @class = "submenu-expand" ]', |
| 2496 | + 'submenu' => './ul[ @class = "sub-menu" ]', |
| 2497 | + 'close_button_in_submenu' => './li[ contains( @class, "mobile-parent-nav-menu-item" ) ]//button[ contains( @class, "menu-item-link-return" ) ]', |
| 2498 | + ]; |
| 2499 | + |
| 2500 | + $main_menu = $this->get_first_element( $xpaths['main_menu'] ); |
| 2501 | + if ( empty( $main_menu ) ) { |
| 2502 | + return; |
| 2503 | + } |
| 2504 | + |
| 2505 | + $menu_items = $this->dom->xpath->query( $xpaths['top_menu_items'], $main_menu ); |
| 2506 | + |
| 2507 | + /** @var Element $menu_item */ |
| 2508 | + foreach ( $menu_items as $menu_item ) { |
| 2509 | + $expand_button = $this->get_first_element( $xpaths['expand_button'], $menu_item ); |
| 2510 | + $sub_menu = $this->get_first_element( $xpaths['submenu'], $menu_item ); |
| 2511 | + |
| 2512 | + if ( empty( $expand_button ) || empty( $sub_menu ) ) { |
| 2513 | + continue; |
| 2514 | + } |
| 2515 | + |
| 2516 | + // AMP Sidebar. |
| 2517 | + $amp_sidebar = AMP_DOM_Utils::create_node( |
| 2518 | + $this->dom, |
| 2519 | + Extension::SIDEBAR, |
| 2520 | + [ |
| 2521 | + Attribute::LAYOUT => Layout::NODISPLAY, |
| 2522 | + Attribute::CLASS_ => 'amp-twentynineteen-main-navigation', |
| 2523 | + Attribute::SIDE => is_rtl() ? 'left' : 'right', |
| 2524 | + ] |
| 2525 | + ); |
| 2526 | + |
| 2527 | + $sidebar_id = $this->dom->getElementId( $amp_sidebar ); |
| 2528 | + |
| 2529 | + // AMP nested menu. |
| 2530 | + $amp_nested_menu = AMP_DOM_Utils::create_node( |
| 2531 | + $this->dom, |
| 2532 | + Extension::NESTED_MENU, |
| 2533 | + [ |
| 2534 | + Attribute::LAYOUT => Layout::FILL, |
| 2535 | + ] |
| 2536 | + ); |
| 2537 | + |
| 2538 | + // Clone the sub-menu and expand button for AMP navigation. |
| 2539 | + /** @var Element $amp_sub_menu */ |
| 2540 | + $amp_sub_menu = $sub_menu->cloneNode( true ); |
| 2541 | + |
| 2542 | + /** @var Element $amp_expand_button */ |
| 2543 | + $amp_expand_button = $expand_button->cloneNode( true ); |
| 2544 | + |
| 2545 | + $sub_menu->setAttribute( Attribute::CLASS_, $sub_menu->getAttribute( Attribute::CLASS_ ) . ' display-on-desktop' ); |
| 2546 | + $expand_button->setAttribute( Attribute::CLASS_, $expand_button->getAttribute( Attribute::CLASS_ ) . ' display-on-desktop' ); |
| 2547 | + |
| 2548 | + $menu_item->appendChild( $amp_expand_button ); |
| 2549 | + $menu_item->appendChild( $amp_sub_menu ); |
| 2550 | + $this->update_twentynineteen_main_nested_menu( $amp_sub_menu ); |
| 2551 | + |
| 2552 | + $amp_sub_menu->setAttribute( Attribute::CLASS_, $amp_sub_menu->getAttribute( Attribute::CLASS_ ) . ' expanded-true display-on-mobile' ); |
| 2553 | + $amp_expand_button->setAttribute( Attribute::CLASS_, $amp_expand_button->getAttribute( Attribute::CLASS_ ) . ' display-on-mobile' ); |
| 2554 | + |
| 2555 | + // Handle buttons. |
| 2556 | + $amp_expand_button->addAmpAction( 'tap', "$sidebar_id.open" ); |
| 2557 | + $back_button = $this->get_first_element( $xpaths['close_button_in_submenu'], $amp_sub_menu ); |
| 2558 | + if ( ! empty( $back_button ) ) { |
| 2559 | + $back_button->addAmpAction( 'tap', "$sidebar_id.close" ); |
| 2560 | + } |
| 2561 | + |
| 2562 | + $amp_nested_menu->appendChild( $amp_sub_menu ); |
| 2563 | + $amp_sidebar->appendChild( $amp_nested_menu ); |
| 2564 | + $menu_item->appendChild( $amp_sidebar ); |
| 2565 | + } |
| 2566 | + } |
| 2567 | + |
| 2568 | + /** |
| 2569 | + * Update the markup of the nested menu to AMP compatible markup. |
| 2570 | + * |
| 2571 | + * @param Element $sub_menu Element of sub-menu from main navigation. |
| 2572 | + * |
| 2573 | + * @return void |
| 2574 | + */ |
| 2575 | + public function update_twentynineteen_main_nested_menu( Element $sub_menu ) { |
| 2576 | + |
| 2577 | + $xpaths = [ |
| 2578 | + 'menu_items' => './li[ contains( @class, "menu-item" ) and contains( @class, "menu-item-has-children" ) ]', |
| 2579 | + 'expand_button' => './button[ @class = "submenu-expand" ]', |
| 2580 | + 'back_button' => './li[ contains( @class, "mobile-parent-nav-menu-item" ) ]//button[ contains( @class, "menu-item-link-return" ) ]', |
| 2581 | + 'submenu' => './ul[ @class = "sub-menu" ]', |
| 2582 | + ]; |
| 2583 | + |
| 2584 | + $menu_items = $this->dom->xpath->query( $xpaths['menu_items'], $sub_menu ); |
| 2585 | + if ( 0 === $menu_items->length ) { |
| 2586 | + return; |
| 2587 | + } |
| 2588 | + |
| 2589 | + /** @var Element $menu_item */ |
| 2590 | + foreach ( $menu_items as $menu_item ) { |
| 2591 | + $nested_sub_menu = $this->get_first_element( $xpaths['submenu'], $menu_item ); |
| 2592 | + |
| 2593 | + if ( empty( $nested_sub_menu ) ) { |
| 2594 | + continue; |
| 2595 | + } |
| 2596 | + |
| 2597 | + $this->update_twentynineteen_main_nested_menu( $nested_sub_menu ); |
| 2598 | + |
| 2599 | + $back_button = $this->get_first_element( $xpaths['back_button'], $nested_sub_menu ); |
| 2600 | + if ( ! empty( $back_button ) ) { |
| 2601 | + $back_button->setAttribute( Attribute::AMP_NESTED_SUBMENU_CLOSE, '' ); |
| 2602 | + } |
| 2603 | + |
| 2604 | + $open_button = $this->get_first_element( $xpaths['expand_button'], $menu_item ); |
| 2605 | + if ( ! empty( $open_button ) ) { |
| 2606 | + $open_button->setAttribute( Attribute::AMP_NESTED_SUBMENU_OPEN, '' ); |
| 2607 | + } |
| 2608 | + |
| 2609 | + $amp_nested_menu_div = AMP_DOM_Utils::create_node( |
| 2610 | + $this->dom, |
| 2611 | + Tag::DIV, |
| 2612 | + [ |
| 2613 | + Attribute::AMP_NESTED_SUBMENU => '', |
| 2614 | + ] |
| 2615 | + ); |
| 2616 | + |
| 2617 | + $nested_sub_menu->setAttribute( Attribute::CLASS_, $nested_sub_menu->getAttribute( Attribute::CLASS_ ) . ' expanded-true' ); |
| 2618 | + $amp_nested_menu_div->appendChild( $nested_sub_menu ); |
| 2619 | + $menu_item->appendChild( $amp_nested_menu_div ); |
| 2620 | + } |
| 2621 | + } |
2346 | 2622 | }
|
0 commit comments