Replace JavaScript-only links with semantic buttons
Is your feature request related to a problem? Please describe.
Several interactive controls in wallabag are currently rendered as <a> elements even though they do not navigate to another page or to a meaningful document fragment.
These elements generally use one of the following patterns:
<a href="#">
<a href="javascript: void(null);">
<a data-action="...">Their only purpose is to trigger JavaScript behavior through Stimulus or Materialize, such as:
- opening or closing a sidenav;
- opening the account dropdown;
- displaying the search interface;
- opening filter or export panels;
- changing the application theme;
- expanding an interactive section;
- displaying an inline form or another JavaScript-controlled component.
An anchor represents navigation. Controls whose sole purpose is to perform an action should instead use a semantic <button type="button">.
Keeping JavaScript-only actions as links has several drawbacks:
- incorrect HTML semantics;
- confusing behavior for keyboard and assistive-technology users;
- fake or meaningless link destinations;
- unnecessary use of
preventDefault; - inconsistent focus and accessibility behavior;
- additional complexity for future reusable navigation renderers.
This issue should cover all occurrences in the current master branch rather than only the controls directly involved in another navigation refactoring.
Describe the solution you'd like
Audit the Twig templates in the master branch and replace every anchor that only triggers JavaScript and has no meaningful navigation target with an appropriate semantic button.
For each converted control:
- use
<button type="button">; - preserve its existing visual appearance;
- preserve all Stimulus and Materialize behavior;
- remove meaningless
href="#",javascript:URLs and unnecessary:preventaction modifiers; - preserve existing IDs, classes, controller targets and keyboard shortcuts where required;
- add or improve accessible names and relevant ARIA attributes;
- ensure a visible and consistent keyboard focus state;
- verify compatibility with both light and dark themes;
- update JavaScript or CSS selectors that currently assume an anchor element;
- add or update tests where practical.
The audit should include, but not be limited to:
- top navigation controls;
- sidenav triggers;
- the account dropdown trigger;
- search controls;
- filter and export panel triggers;
- theme-selection controls;
- article-reader controls;
- collapsible or expandable controls;
- tooltip-only help controls;
- other Twig elements using fake link destinations solely to invoke JavaScript.
Controls that have a real navigation target must remain links, even when JavaScript enhances or intercepts them. This includes, for example:
- links with a valid Symfony route that provide a functional fallback;
- links to another page;
- links to external resources;
- links to meaningful fragments, including Materialize tabs.
The distinction must be based on the semantic purpose of each control, not only on the presence of a data-action attribute.
Acceptance criteria
- No anchor remains in the audited Twig templates when its only purpose is to trigger JavaScript and it has no meaningful navigation destination.
- No JavaScript-only control uses
href="#"or ajavascript:URL. - All converted controls use
button[type="button"], unless another button type is intentionally required. - Existing interactions continue to work with a mouse, keyboard and touch input.
- Converted controls remain visually consistent with the current Materialize interface.
- Focus styles are visible and consistent.
- Relevant ARIA relationships such as
aria-controls,aria-expandedoraria-haspopupare used where appropriate. - Real navigational links and meaningful fragment links remain anchors.
- Existing Stimulus controllers and Materialize components work with the new button elements.
- Tests are added or updated to prevent the reintroduction of fake JavaScript links.
Describe alternatives you've considered
One alternative would be to keep the existing anchors and only normalize them while introducing reusable menu renderers.
This would preserve the current markup, but it would also reproduce incorrect semantics in the new implementation and mix an accessibility correction with a larger navigation architecture change.
Another alternative would be to convert only the controls directly affected by the navigation refactoring. This would leave the same problem elsewhere in the application and maintain two different conventions for equivalent interactive controls.
A complete, dedicated refactoring is preferable because it establishes one consistent rule across wallabag before subsequent navigation work relies on the resulting markup.
Additional context
This work is intended as a prerequisite for the planned migration of the main, account, administration and tab navigation to KnpMenu.
Completing the semantic refactoring first will provide known and validated reference markup for the future KnpMenu renderers. The later migration can then focus on menu construction, extensibility, permissions, active-state handling and rendering without simultaneously changing the semantics of the underlying controls.
The issue should nevertheless be implemented and reviewed as a standalone accessibility and frontend-quality improvement, not merely as an implementation detail of the KnpMenu migration.
Source: wallabag/wallabag