-
Notifications
You must be signed in to change notification settings - Fork 0
MDS Filtering and Search
- Introduction
- System Architecture
- FilterDropdown Class Implementation
- Filter Configuration System
- Filter Initialization and Setup
- Filtering Logic and Matching
- Interactive Dropdown Behavior
- Filter State Management
- Performance Considerations
- Usage Examples
- Troubleshooting Guide
The MDS (Metadata Service) filtering and search system provides an interactive interface for exploring authenticator metadata from the FIDO Metadata Service. The system enables users to dynamically filter authenticator data by various attributes including protocol, certification status, user verification methods, attachment types, transport protocols, and cryptographic algorithms.
The filtering system consists of two main components: the FilterDropdown class that manages interactive dropdown filters, and the createFilterDropdown function that instantiates these dropdown controls. Together, they provide a responsive and intuitive way to navigate large datasets of authenticator metadata.
The MDS filtering system follows a modular architecture with clear separation of concerns:
graph TB
subgraph "Filter System Architecture"
A[HTML Table Structure] --> B[Filter Initialization]
B --> C[FilterDropdown Instances]
C --> D[Event Handlers]
D --> E[Filter Logic Engine]
E --> F[Filtered Results Display]
G[FILTER_CONFIG] --> B
H[FILTER_LOOKUP] --> B
I[applyFilters Function] --> E
J[User Input] --> D
K[Dropdown Selection] --> D
L[Text Input] --> D
end
subgraph "Core Components"
M[FilterDropdown Class] --> N[createFilterDropdown Function]
O[matchesFilters Function] --> P[applyFilters Function]
Q[updateFilter Function] --> R[State Management]
end
Diagram sources
- mds.js
- mds-dropdown.js
Section sources
- mds.js
- mds-dropdown.js
The FilterDropdown class provides the core functionality for interactive dropdown filters. It encapsulates the dropdown's state, rendering logic, and user interaction handling.
classDiagram
class FilterDropdown {
+HTMLElement input
+Function onSelect
+Array options
+Array filtered
+Number activeIndex
+HTMLElement list
+HTMLElement container
+Boolean expandToContent
+constructor(input, onSelect, config)
+setOptions(options) void
+open() void
+close() void
+filter(query) void
+render() void
+handleKeyDown(event) void
+move(delta) void
+select(value) void
+handleDocumentClick(event) void
}
class createFilterDropdown {
+createFilterDropdown(input, onSelect, config) FilterDropdown
}
FilterDropdown <-- createFilterDropdown : creates
Diagram sources
- mds-dropdown.js
The FilterDropdown class implements several critical methods:
- Constructor: Initializes the dropdown structure, attaches event listeners, and sets up the DOM elements
- setOptions: Processes and sorts available filter options, removing duplicates and maintaining alphabetical order
- open/close: Manages the visibility state of the dropdown menu
- filter: Performs text-based filtering of available options based on user input
- render: Updates the DOM to display filtered options with proper styling
- handleKeyDown: Processes keyboard navigation and selection within the dropdown
- select: Handles option selection and triggers the parent filter update
The dropdown implements a comprehensive event handling system:
sequenceDiagram
participant User as User Input
participant Input as Filter Input
participant Dropdown as FilterDropdown
participant Container as Dropdown Container
participant Parent as Parent Filter
User->>Input : Focus/Clickevent
Input->>Dropdown : open()
Dropdown->>Dropdown : filter(input.value)
Dropdown->>Dropdown : render()
Dropdown->>Container : Display options
User->>Container : Click option
Container->>Dropdown : select(value)
Dropdown->>Parent : onSelect(value)
Parent->>Parent : updateFilter(key, value)
Parent->>Parent : applyFilters()
User->>Input : Escape key
Input->>Dropdown : close()
Dropdown->>Container : Hide dropdown
Diagram sources
- mds-dropdown.js
Section sources
- mds-dropdown.js
The filtering system uses structured configuration objects defined in FILTER_CONFIG and FILTER_LOOKUP constants to manage filter behavior across different metadata fields.
The FILTER_CONFIG array defines the complete filter specification for each searchable field:
| Field | Description | Options Key | Static Options | Expand Dropdown |
|---|---|---|---|---|
| name | Authenticator name | - | - | No |
| protocol | FIDO protocol version | protocol | - | No |
| certification | Certification status | certification | CERTIFICATION_OPTIONS | No |
| id | AAGUID or AAID | - | - | No |
| userVerification | User verification methods | userVerification | - | Yes |
| attachment | Attachment type | attachment | - | No |
| transports | Transport protocols | transports | - | No |
| keyProtection | Key protection mechanisms | keyProtection | - | No |
| algorithms | Cryptographic algorithms | algorithms | - | Yes |
| algorithmInfo | Algorithm information | - | - | No |
| commonName | Certificate common name | - | - | No |
The FILTER_LOOKUP object provides efficient access to filter configurations by key:
flowchart TD
A[Filter Key Request] --> B[FILTER_LOOKUP Lookup]
B --> C{Configuration Found?}
C --> |Yes| D[Return Filter Config]
C --> |No| E[Return Undefined]
F[FILTER_CONFIG Array] --> G[Reduce Operation]
G --> H[Map Key to Config]
H --> I[FILTER_LOOKUP Object]
Diagram sources
- mds-constants.js
Section sources
- mds-constants.js
The filter initialization process occurs during the initializeState function, which sets up the complete filtering infrastructure for the MDS table.
flowchart TD
A[initializeState Called] --> B[Create Filters Object]
B --> C[Create Filter Inputs Map]
C --> D[Setup updateFilter Function]
D --> E[Initialize Dropdowns Map]
E --> F[Iterate FILTER_CONFIG]
F --> G[Find Input Element]
G --> H{Input Found?}
H --> |Yes| I[Add to Filter Inputs]
H --> |No| J[Skip Configuration]
I --> K[Attach Event Listeners]
K --> L[Create FilterDropdown]
L --> M[Set Initial Options]
M --> N[Continue Loop]
N --> O{More Configurations?}
O --> |Yes| F
O --> |No| P[Complete Initialization]
Diagram sources
- mds.js
Each filter input receives comprehensive event handling:
- keydown: Handles Enter key for immediate filtering and Escape key for clearing
- change: Responds to dropdown selections and manual input changes
- input: Provides real-time filtering as users type
For filters with optionsKey specified, the system automatically creates FilterDropdown instances:
sequenceDiagram
participant Init as Initialization
participant Config as FILTER_CONFIG
participant Factory as createFilterDropdown
participant Dropdown as FilterDropdown
participant Input as Filter Input
Init->>Config : Get filter configuration
Config->>Init : Return config object
Init->>Input : Find input element
Input->>Init : Return input element
Init->>Factory : createFilterDropdown(input, callback, config)
Factory->>Dropdown : new FilterDropdown(...)
Dropdown->>Init : Return dropdown instance
Init->>Dropdown : setOptions(staticOptions)
Dropdown->>Init : Options set and filtered
Diagram sources
- mds.js
Section sources
- mds.js
The filtering system implements sophisticated matching logic through the matchesFilters function, which evaluates whether individual entries satisfy all active filter criteria.
flowchart TD
A[matchesFilters Called] --> B[Iterate Active Filters]
B --> C[Get Filter Key and Value]
C --> D{Value Empty?}
D --> |Yes| E[Return True - No Filter]
D --> |No| F[Convert to Lowercase]
F --> G{Special Filter Type?}
G --> |certification| H[Certification Logic]
G --> |Other| I[Standard Text Match]
H --> J[Normalize Enum Keys]
J --> K{Known Option?}
K --> |Yes| L[Apply Certification Rules]
K --> |No| M[Text Contains Check]
L --> N[Check Status Prefix]
N --> O[Return Match Result]
I --> P[Check Text Contains]
P --> O
M --> O
O --> Q{More Filters?}
Q --> |Yes| B
Q --> |No| R[Return Final Result]
Diagram sources
- mds.js
The system implements specialized logic for certain filter types:
The certification filter handles complex certification status matching:
- Exact matches: Direct comparison against known certification statuses
- Prefix matching: "FIDO_CERTIFIED" matches all certified variants
- Fallback handling: Uses display text when status information is unavailable
For most other fields, the system performs case-insensitive substring matching against the field's text content.
The filtering system includes several performance optimizations:
- Early termination: Returns immediately when a filter fails to match
- Case normalization: Converts strings to lowercase once per filter evaluation
- Efficient lookups: Uses object property access for field value retrieval
Section sources
- mds.js
The dropdown system provides rich interactive capabilities for filter selection, including keyboard navigation, mouse interaction, and visual feedback.
The dropdown supports comprehensive keyboard navigation:
stateDiagram-v2
[*] --> Closed
Closed --> Open : Focus/Click
Open --> Navigate : Arrow Keys
Navigate --> Select : Enter
Navigate --> Open : Arrow Down/Up
Open --> Close : Escape
Select --> Closed : Option Selected
Close --> [*]
state Navigate {
[*] --> FirstOption
FirstOption --> NextOption : Arrow Down
NextOption --> PreviousOption : Arrow Up
PreviousOption --> LastOption : Arrow Up
LastOption --> FirstOption : Arrow Down
}
Diagram sources
- mds-dropdown.js
The dropdown maintains several visual states:
- Hidden/Visible: Controls overall dropdown display
- Active Index: Tracks currently highlighted option
- Expanded Mode: Enables full-width dropdown expansion for long lists
- Empty State: Shows "No matches" message when filtering yields no results
Mouse interactions are handled through delegated event listeners:
- Click outside: Closes the dropdown when clicking away from the filter area
- Option selection: Allows selecting options by clicking on dropdown items
- Prevent default: Stops form submission when clicking within the dropdown
Section sources
- mds-dropdown.js
- mds-dropdown.js
The filtering system maintains state through the mdsState object, which tracks active filters, dropdown instances, and UI state.
classDiagram
class MDSState {
+Object filters
+Object filterInputs
+Object dropdowns
+Object sort
+Object sortButtons
+HTMLElement tableBody
+HTMLElement tableContainer
+HTMLElement horizontalScrollContainer
}
class FilterState {
+String key
+String value
}
class DropdownState {
+FilterDropdown instance
+Array options
+Array filtered
}
MDSState --> FilterState : contains
MDSState --> DropdownState : contains
Diagram sources
- mds.js
The system maintains filter state across interactions:
- Real-time updates: Filters are applied immediately as users modify input values
- State preservation: Filter values persist until explicitly cleared
- Cross-filter coordination: Multiple filters work together to narrow results
- Reset functionality: All filters can be cleared simultaneously
The resetFilters function provides comprehensive filter clearing:
flowchart TD
A[resetFilters Called] --> B[Iterate mdsState.filters]
B --> C[Check Current Value]
C --> D{Value Exists?}
D --> |Yes| E[Clear Filter Value]
D --> |No| F[Skip Filter]
E --> G[Clear Input Element]
G --> H[Mark as Changed]
F --> I{More Filters?}
H --> I
I --> |Yes| B
I --> |No| J{Changed State?}
J --> |Yes| K[applyFilters]
J --> |No| L[Check Data Length]
K --> M[Update UI]
L --> N{Filtered Data Empty?}
N --> |Yes| K
N --> |No| O[No Action Needed]
M --> P[Complete]
O --> P
Diagram sources
- mds.js
Section sources
- mds.js
- mds.js
The filtering system is designed with performance in mind, implementing several optimization strategies for handling large datasets efficiently.
- Debounced updates: Filter applications are batched to prevent excessive re-rendering
- Efficient string matching: Uses native JavaScript string methods for optimal performance
- Memory management: Dropdown instances are properly cleaned up when closed
- DOM manipulation minimization: Batched DOM updates reduce layout thrashing
- Lazy loading: Dropdown options are populated only when needed
- Event listener cleanup: Automatic cleanup prevents memory leaks
- State object management: Minimal state footprint reduces memory overhead
- Configurable dropdown expansion: Long lists can be expanded for better usability
- Incremental filtering: Users can build complex filters incrementally
- Responsive design: The system adapts to different screen sizes and input methods
Users can filter authenticators by typing directly into filter inputs:
- Protocol filtering: Type "FIDO 2" to show only FIDO 2.0 authenticators
- Certification filtering: Use the dropdown to select specific certification levels
- User verification: Filter by biometric or PIN-based verification methods
The system supports combining multiple filters for precise results:
- Protocol + Certification: Find FIDO 2.1 authenticators with Level 1 certification
- User Verification + Transport: Locate biometric authenticators supporting USB transport
- Algorithm + Key Protection: Search for authenticators using specific cryptographic algorithms with hardware key protection
Users can build filters progressively:
- Start with a broad filter (e.g., "PIN" for user verification)
- Add protocol constraints to narrow results
- Apply certification requirements for compliance checking
- Cause: JavaScript errors preventing dropdown initialization
- Solution: Check browser console for errors and ensure FILTER_CONFIG is properly defined
- Cause: Filter state not updating or applyFilters function not being called
- Solution: Verify event listeners are attached and updateFilter function is properly implemented
- Cause: Large datasets causing slow filtering responses
- Solution: Implement pagination or increase filtering debouncing intervals
- Cause: Options not being set or staticOptions not properly configured
- Solution: Ensure setOptions is called with valid data and staticOptions array is complete
The system includes several debugging capabilities:
- Console logging: Filter state and matching results are logged for debugging
- State inspection: Direct access to mdsState object for runtime analysis
- Event monitoring: Comprehensive event tracking for interaction debugging
Section sources
- mds.js
- mds-dropdown.js