@@ -823,6 +823,119 @@ function edac_remove_corrected_posts( $post_ID, $type, $pre = 1, $ruleset = 'php
823823 );
824824}
825825
826+ /**
827+ * Get the canonical landmark detection rules the scanner uses to populate the
828+ * `landmark` database column.
829+ *
830+ * This is the single source of truth mirrored by `LANDMARK_TAGS`,
831+ * `LANDMARK_ROLES`, `CONDITIONAL_LANDMARK_TAGS`, and
832+ * `CONDITIONAL_LANDMARK_ROLES` in `src/pageScanner/index.js`. Tag names stay
833+ * uppercase to match `Element.tagName`; role names stay lowercase to match
834+ * the already-lowercased `role` attribute the scanner compares against.
835+ *
836+ * Tag-detected and role-detected landmarks are NOT normalized to a shared
837+ * value even when conceptually the same landmark — e.g. a `<nav>` element
838+ * saves `nav`, but `role="navigation"` saves `navigation`. Same for `<aside>`
839+ * (`aside`) vs `role="complementary"` (`complementary`).
840+ *
841+ * Third-party code may extend the landmark set via the `edac_landmark_types`
842+ * filter, but must return an array with all four keys intact.
843+ *
844+ * @since 1.44.0
845+ *
846+ * @return array{tags: string[], roles: string[], conditionalTags: string[], conditionalRoles: string[]} Landmark detection rules.
847+ */
848+ function edac_get_landmark_types (): array {
849+ $ types = [
850+ 'tags ' => [ 'MAIN ' , 'HEADER ' , 'FOOTER ' , 'NAV ' , 'ASIDE ' ],
851+ 'roles ' => [ 'main ' , 'navigation ' , 'banner ' , 'contentinfo ' , 'complementary ' ],
852+ 'conditionalTags ' => [ 'SECTION ' , 'ARTICLE ' , 'FORM ' ],
853+ 'conditionalRoles ' => [ 'region ' , 'article ' , 'form ' ],
854+ ];
855+
856+ /**
857+ * Filter the landmark types used by the scanner and Issues Explorer filter.
858+ *
859+ * @since 1.44.0
860+ *
861+ * @param array $types {
862+ * @type string[] $tags Uppercase HTML tag names detected unconditionally.
863+ * @type string[] $roles ARIA roles detected unconditionally.
864+ * @type string[] $conditionalTags Uppercase HTML tag names detected only when the element has an accessible name.
865+ * @type string[] $conditionalRoles ARIA roles detected only when the element has an accessible name.
866+ * }
867+ */
868+ $ filtered = apply_filters ( 'edac_landmark_types ' , $ types );
869+
870+ return is_array ( $ filtered ) ? $ filtered : $ types ;
871+ }
872+
873+ /**
874+ * Get the distinct landmark values that can actually be written to the
875+ * `landmark` database column, as filter-friendly `{ value, label }` pairs.
876+ *
877+ * Built from `edac_get_landmark_types()` so the Issues Explorer's Landmark
878+ * filter (in the pro plugin) can never drift from what the scanner persists.
879+ *
880+ * @since 1.44.0
881+ *
882+ * @return array<array{value: string, label: string}> Filter options, value lowercase, label human-readable.
883+ */
884+ function edac_get_landmark_filter_options (): array {
885+ $ types = edac_get_landmark_types ();
886+
887+ $ values = array_unique (
888+ array_map (
889+ 'strtolower ' ,
890+ array_merge (
891+ $ types ['tags ' ] ?? [],
892+ $ types ['roles ' ] ?? [],
893+ $ types ['conditionalTags ' ] ?? [],
894+ $ types ['conditionalRoles ' ] ?? []
895+ )
896+ )
897+ );
898+
899+ $ labels = [
900+ /* translators: Landmark type label for the Issues Explorer filter. */
901+ 'main ' => __ ( 'Main ' , 'accessibility-checker ' ),
902+ /* translators: Landmark type label for the Issues Explorer filter. */
903+ 'header ' => __ ( 'Header ' , 'accessibility-checker ' ),
904+ /* translators: Landmark type label for the Issues Explorer filter. */
905+ 'footer ' => __ ( 'Footer ' , 'accessibility-checker ' ),
906+ /* translators: Landmark type label for the Issues Explorer filter. */
907+ 'nav ' => __ ( 'Nav ' , 'accessibility-checker ' ),
908+ /* translators: Landmark type label for the Issues Explorer filter. */
909+ 'aside ' => __ ( 'Aside ' , 'accessibility-checker ' ),
910+ /* translators: Landmark type label for the Issues Explorer filter. */
911+ 'navigation ' => __ ( 'Navigation ' , 'accessibility-checker ' ),
912+ /* translators: Landmark type label for the Issues Explorer filter. */
913+ 'banner ' => __ ( 'Banner ' , 'accessibility-checker ' ),
914+ /* translators: Landmark type label for the Issues Explorer filter. */
915+ 'contentinfo ' => __ ( 'Content Info ' , 'accessibility-checker ' ),
916+ /* translators: Landmark type label for the Issues Explorer filter. */
917+ 'complementary ' => __ ( 'Complementary ' , 'accessibility-checker ' ),
918+ /* translators: Landmark type label for the Issues Explorer filter. */
919+ 'section ' => __ ( 'Section ' , 'accessibility-checker ' ),
920+ /* translators: Landmark type label for the Issues Explorer filter. */
921+ 'article ' => __ ( 'Article ' , 'accessibility-checker ' ),
922+ /* translators: Landmark type label for the Issues Explorer filter. */
923+ 'form ' => __ ( 'Form ' , 'accessibility-checker ' ),
924+ /* translators: Landmark type label for the Issues Explorer filter. */
925+ 'region ' => __ ( 'Region ' , 'accessibility-checker ' ),
926+ ];
927+
928+ return array_map (
929+ static function ( $ value ) use ( $ labels ) {
930+ return [
931+ 'value ' => $ value ,
932+ 'label ' => $ labels [ $ value ] ?? ucfirst ( $ value ),
933+ ];
934+ },
935+ array_values ( $ values )
936+ );
937+ }
938+
826939/**
827940 * Generate a landmark link with proper URL and ARIA label
828941 *
0 commit comments