Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 19, 2025

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 19, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 19, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 19, 2025

      My latest hands-on could be the best value AI laptop of the summer, but I still have questions

      May 19, 2025

      DOOM: The Dark Ages had the lowest Steam launch numbers in series history — Is it suffering from the ‘Game Pass Effect’?

      May 19, 2025

      Microsoft won’t be left exposed if something “catastrophic” happens to OpenAI — but may still be 3 to 6 months behind ChatGPT

      May 19, 2025

      Microsoft Copilot gets OpenAI’s GPT-4o image generation support — but maybe a day late and a dollar short for the hype?

      May 19, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      ES6: Set Vs Array- What and When?

      May 19, 2025
      Recent

      ES6: Set Vs Array- What and When?

      May 19, 2025

      Transform JSON into Typed Collections with Laravel’s AsCollection::of()

      May 19, 2025

      Deployer

      May 19, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      My latest hands-on could be the best value AI laptop of the summer, but I still have questions

      May 19, 2025
      Recent

      My latest hands-on could be the best value AI laptop of the summer, but I still have questions

      May 19, 2025

      DOOM: The Dark Ages had the lowest Steam launch numbers in series history — Is it suffering from the ‘Game Pass Effect’?

      May 19, 2025

      Microsoft won’t be left exposed if something “catastrophic” happens to OpenAI — but may still be 3 to 6 months behind ChatGPT

      May 19, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»Invoker Commands: Additional Ways to Work With Dialog, Popover… and More?

    Invoker Commands: Additional Ways to Work With Dialog, Popover… and More?

    November 20, 2024

    The Popover API and <dialog> element are two of my favorite new platform features. In fact, I recently [wrote a detailed overview of their use cases] and the sorts of things you can do with them, even learning a few tricks in the process that I couldn’t find documented anywhere else.

    I’ll admit that one thing that I really dislike about popovers and dialogs is that they could’ve easily been combined into a single API. They cover different use cases (notably, dialogs are typically modal) but are quite similar in practice, and yet their implementations are different.

    Well, web browsers are now experimenting with two HTML attributes — technically, they’re called “invoker commands” — that are designed to invoke popovers, dialogs, and further down the line, all kinds of actions without writing JavaScript. Although, if you do reach for JavaScript, the new attributes — command and commandfor — come with some new events that we can listen for.

    Invoker commands? I’m sure you have questions, so let’s dive in.

    We’re in experimental territory

    Before we get into the weeds, we’re dealing with experimental features. To use invoker commands today in November 2024 you’ll need Chrome Canary 134+ with the enable-experimental-web-platform-features flag set to Enabled, Firefox Nightly 135+ with the dom.element.invokers.enabled flag set to true, or Safari Technology Preview with the InvokerAttributesEnabled flag set to true.

    I’m optimistic we’ll get baseline coverage for command and commandfor in due time considering how nicely they abstract the kind of work that currently takes a hefty amount of scripting.

    Basic command and commandfor usage

    First, you’ll need a <button> or a button-esque <input> along the lines of <input type="button"> or <input type="reset">. Next, tack on the command attribute. The command value should be the command name that you want the button to invoke (e.g., show-modal). After that, drop the commandfor attribute in there referencing the dialog or popover you’re targeting by its id.

    <button command="show-modal" commandfor="dialogA">Show dialogA</button>
    
    <dialog id="dialogA">...</dialog>

    In this example, I have a <button> element with a command attribute set to show-modal and a commandfor attribute set to dialogA, which matches the id of a <dialog> element we’re targeting:

    Let’s get into the possible values for these invoker commands and dissect what they’re doing.

    Looking closer at the attribute values

    CodePen Embed Fallback

    The show-modal value is the command that I just showed you in that last example. Specifically, it’s the HTML-invoked equivalent of JavaScript’s showModal() method.

    The main benefit is that show-modal enables us to, well… show a modal without reaching directly for JavaScript. Yes, this is almost identical to how HTML-invoked popovers already work with thepopovertarget and popovertargetaction attributes, so it’s cool that the “balance is being redressed” as the Open UI explainer describes it, even more so because you can use the command and commandfor invoker commands for popovers too.

    There isn’t a show command to invoke show() for creating non-modal dialogs. I’ve mentioned before that non-modal dialogs are redundant now that we have the Popover API, especially since popovers have ::backdrops and other dialog-like features. My bold prediction is that non-modal dialogs will be quietly phased out over time.

    The close command is the HTML-invoked equivalent of JavaScript’s close() method used for closing the dialog. You probably could have guessed that based on the name alone!

    <dialog id="dialogA">
      <!-- Close #dialogA -->
      <button command="close" commandfor="dialogA">Close dialogA</button>
    </dialog>

    The show-popover, hide-popover, and toggle-popover values

    <button command="show-popover" commandfor="id">

    …invokes showPopover(), and is the same thing as:

    <button popovertargetaction="show" popovertarget="id">

    Similarly:

    <button command="hide-popover" commandfor="id">

    …invokes hidePopover(), and is the same thing as:

    <button popovertargetaction="hide" popovertarget="id">

    Finally:

    <button command="toggle-popover" commandfor="id">

    …invokes togglePopover(), and is the same thing as:

    <button popovertargetaction="toggle" popovertarget="id">
    <!--  or <button popovertarget="id">, since ‘toggle’ is the default action anyway. -->

    I know all of this can be tough to organize in your mind’s eye, so perhaps a table will help tie things together:

    command Invokes popovertargetaction equivalent
    show-popover showPopover() show
    hide-popover hidePopover() hide
    toggle-popover togglePopover() toggle

    So… yeah, popovers can already be invoked using HTML attributes, making command and commandfor not all that useful in this context. But like I said, invoker commands also come with some useful JavaScript stuff, so let’s dive into all of that.

    Listening to commands with JavaScript

    Invoker commands dispatch a command event to the target whenever their source button is clicked on, which we can listen for and work with in JavaScript. This isn’t required for a <dialog> element’s close event, or a popover attribute’s toggle or beforetoggle event, because we can already listen for those, right?

    For example, the Dialog API doesn’t dispatch an event when a <dialog> is shown. So, let’s use invoker commands to listen for the command event instead, and then read event.command to take the appropriate action.

    // Select all dialogs
    const dialogs = document.querySelectorAll("dialog");
    
    // Loop all dialogs
    dialogs.forEach(dialog => {
    
      // Listen for close (as normal)
      dialog.addEventListener("close", () => {
        // Dialog was closed
      });
    
      // Listen for command
      dialog.addEventListener("command", event => {
    
        // If command is show-modal
        if (event.command == "show-modal") {
          // Dialog was shown (modally)
        }
    
        // Another way to listen for close
        else if (event.command == "close") {
          // Dialog was closed
        }
    
      });
    });

    So invoker commands give us additional ways to work with dialogs and popovers, and in some scenarios, they’ll be less verbose. In other scenarios though, they’ll be more verbose. Your approach should depend on what you need your dialogs and popovers to do.

    For the sake of completeness, here’s an example for popovers, even though it’s largely the same:

    // Select all popovers
    const popovers = document.querySelectorAll("[popover]");
    
    // Loop all popovers
    popovers.forEach(popover => {
    
      // Listen for command
      popover.addEventListener("command", event => {
    
        // If command is show-popover
        if (event.command == "show-popover") {
          // Popover was shown
        }
    
        // If command is hide-popover
        else if (event.command == "hide-popover") {
          // Popover was hidden
        }
    
        // If command is toggle-popover
        else if (event.command == "toggle-popover") {
          // Popover was toggled
        }
    
      });
    });

    Being able to listen for show-popover and hide-popover is useful as we otherwise have to write a sort of “if opened, do this, else do that” logic from within a toggle or beforetoggle event listener or toggle-popover conditional. But <dialog> elements? Yeah, those benefit more from the command and commandfor attributes than they do from this command JavaScript event.

    Another thing that’s available to us via JavaScript is event.source, which is the button that invokes the popover or <dialog>:

    if (event.command == "toggle-popover") {
      // Toggle the invoker’s class
      event.source.classList.toggle("active");
    }

    You can also set the command and commandfor attributes using JavaScript:

    const button = document.querySelector("button");
    const dialog = document.querySelector("dialog");
    
    button.command = "show-modal";
    button.commandForElement = dialog; /* Not dialog.id */

    …which is only slightly less verbose than:

    button.command = "show-modal";
    button.setAttribute("commandfor", dialog.id);

    Creating custom commands

    The command attribute also accepts custom commands prefixed with two dashes (--). I suppose this makes them like CSS custom properties but for JavaScript events and event handler HTML attributes. The latter observation is maybe a bit (or definitely a lot) controversial since using event handler HTML attributes is considered bad practice. But let’s take a look at that anyway, shall we?

    Custom commands look like this:

    <button command="--spin-me-a-bit" commandfor="record">Spin me a bit</button>
    <button command="--spin-me-a-lot" commandfor="record">Spin me a lot</button>
    <button command="--spin-me-right-round" commandfor="record">Spin me right round</button>
    const record = document.querySelector("#record");
    
    record.addEventListener("command", event => {
      if (event.command == "--spin-me-a-bit") {
        record.style.rotate = "90deg";
      } else if (event.command == "--spin-me-a-lot") {
        record.style.rotate = "180deg";
      } else if (event.command == "--spin-me-right-round") {
        record.style.rotate = "360deg";
      }
    });

    event.command must match the string with the dashed (--) prefix.

    Are popover and <dialog> the only features that support invoker commands?

    According to Open UI, invokers targeting additional elements such as <details> were deferred from the initial release. I think this is because HTML-invoked dialogs and an API that unifies dialogs and popovers is a must-have, whereas other commands (even custom commands) feel more like a nice-to-have deal.

    However, based on experimentation (I couldn’t help myself!) web browsers have actually implemented additional invokers to varying degrees. For example, <details> commands work as expected whereas <select> commands match event.command (e.g., show-picker) but fail to actually invoke the method (showPicker()). I missed all of this at first because MDN only mentions dialog and popover.

    Open UI also alludes to commands for <input type="file">, <input type="number">, <video>, <audio>, and fullscreen-related methods, but I don’t think that anything is certain at this point.

    So, what would be the benefits of invoker commands?

    Well, a whole lot less JavaScript for one, especially if more invoker commands are implemented over time. Additionally, we can listen for these commands almost as if they were JavaScript events. But if nothing else, invoker commands simply provide more ways to interact with APIs such as the Dialog and Popover APIs. In a nutshell, it seems like a lot of “dotting i’s” and “crossing-t’s” which is never a bad thing.


    Invoker Commands: Additional Ways to Work With Dialog, Popover… and More? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Hostinger
    Facebook Twitter Reddit Email Copy Link
    Previous ArticleTEKEVER raises €70M for Unmanned Aerial Systems development
    Next Article How to make Storybook Interactions respect user motion preferences

    Related Posts

    Security

    Nmap 7.96 Launches with Lightning-Fast DNS and 612 Scripts

    May 19, 2025
    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-4915 – PHPGurukul Auto Taxi Stand Management System SQL Injection

    May 19, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Learn the Basics of API Security

    Development

    Prepare for your iOS interview

    Development
    I love Jack Black, but A Minecraft Movie with Matt Berry would have been next-level

    I love Jack Black, but A Minecraft Movie with Matt Berry would have been next-level

    News & Updates

    911 S5 Botnet — Likely the World’s Largest Botnet Ever, Dismantled

    Development

    Highlights

    CVE-2025-4795 – Gongfuxiang SchoolCMS SQL Injection Vulnerability

    May 16, 2025

    CVE ID : CVE-2025-4795

    Published : May 16, 2025, 7:15 p.m. | 1 hour, 48 minutes ago

    Description : A vulnerability classified as critical has been found in gongfuxiang schoolcms 2.3.1. This affects the function SaveInfo of the file /index.php?m=Admin&c=article&a=SaveInfo. The manipulation of the argument ID leads to sql injection. It is possible to initiate the attack remotely. The exploit has been disclosed to the public and may be used.

    Severity: 4.7 | MEDIUM

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    GiveWP WordPress Plugin Vulnerability Puts 100,000+ Websites at Risk

    August 21, 2024

    The best free website builders of 2025: Expert tested and reviewed

    March 29, 2025

    A New Validation Rule and the Ability to Manually Fail a Command in Laravel 11.8

    May 22, 2024
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.