# 크롬 135버전부터 버튼에 command 및 commandfor 도입

> Clean Markdown view of GeekNews topic #19630. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=19630](https://news.hada.io/topic?id=19630)
- GeekNews Markdown: [https://news.hada.io/topic/19630.md](https://news.hada.io/topic/19630.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-03-08T12:33:16+09:00
- Updated: 2025-03-08T12:33:16+09:00
- Original source: [developer.chrome.com](https://developer.chrome.com/blog/command-and-commandfor)
- Points: 4
- Comments: 1

## Summary

Chrome 135 버전에서는 버튼에 새로운 `command` 및 `commandfor` 속성을 도입하여 기존의 `popovertargetaction` 및 `popovertarget` 속성을 개선하고 대체합니다. 이 새로운 속성들은 버튼이 다른 요소에 대해 선언적으로 동작할 수 있게 하여, 프레임워크의 편리함과 유연성을 동시에 제공합니다. 또한, 내장 명령 외에도 사용자 정의 명령을 정의할 수 있으며, Shadow DOM에서도 명령을 처리할 수 있는 기능을 지원합니다.

## Topic Body

- 버튼은 동적 웹 애플리케이션을 만드는 데 필수임. 메뉴를 열고, 작업을 전환하고, 폼을 제출하는데 사용  
- Chrome 135에서는 새로운 `command` 및 `commandfor` 속성으로 이전의 `popovertargetaction` 및 `popovertarget` 속성을 개선하고 대체함  
- 기존에 버튼 동작을 구현할 때 발생하는 문제점:  
  - **HTML의 `onclick` 핸들러**는 보안 정책(CSP)으로 인해 실제 코드에서 사용이 제한될 수 있음  
  - 버튼과 다른 요소의 상태 동기화가 필요하며, 접근성을 유지하면서 상태를 관리하는 코드는 복잡함  
  - React, AlpineJS, Svelte 등에서도 상태 및 이벤트 핸들링이 복잡함  
### `command`와 `commandfor` 패턴  
- `command`와 `commandfor` 속성을 사용하면 버튼이 다른 요소에 대해 선언적으로 동작할 수 있음. 이는 프레임워크의 편리함을 제공하면서도 유연성을 유지  
- `commandfor` 버튼은 ID를 사용(`for`속성과 비슷) 하고, `command`는 내장 값을 받아 더 직관적인 접근 방식을 제공  
- 예제: 메뉴 열기 버튼 구현  
  - aria-expanded나 추가적인 JavaScript가 필요하지 않음  
  ```HTML  
  &lt;button commandfor="my-menu" command="show-popover"&gt;  
    Open Menu  
  &lt;/button&gt;  
  &lt;div popover id="my-menu"&gt;  
    &lt;!-- ... --&gt;  
  &lt;/div&gt;  
  ```  
### `command`와 `commandfor` vs `popovertargetaction`과 `popovertarget`  
- `popover`를 사용한 적이 있다면 `popovertarget`과 `popovertargetaction` 속성에 익숙할 수 있음  
- 이들은 `commandfor`와 `command`와 유사하게 작동하지만, 팝오버에 특화  
- 새로운 속성은 이전 속성을 완전히 대체하며, 추가 기능을 제공함  
  
### 내장 명령  
  
- `command` 속성은 다양한 API와 매핑되는 동작들을 내장  
  - `show-popover`: `el.showPopover()`와 매핑됨  
  - `hide-popover`: `el.hidePopover()`와 매핑됨  
  - `toggle-popover`: `el.togglePopover()`와 매핑됨  
  - `show-modal`: `dialogEl.showModal()`와 매핑됨  
  - `close`: `dialogEl.close()`와 매핑됨  
- 예제: 삭제 확인 다이얼로그 구현  
  - JavaScript 없이 상태 및 접근성 관리 가능  
  ```html  
  &lt;button commandfor="confirm-dialog" command="show-modal"&gt;  
    Delete Record  
  &lt;/button&gt;  
  &lt;dialog id="confirm-dialog"&gt;  
    &lt;header&gt;  
      &lt;h1&gt;Delete Record?&lt;/h1&gt;  
      &lt;button commandfor="confirm-dialog" command="close" aria-label="Close"&gt;  
        &lt;img role="none" src="/close-icon.svg"&gt;  
      &lt;/button&gt;  
    &lt;/header&gt;  
    &lt;p&gt;Are you sure? This action cannot be undone&lt;/p&gt;  
    &lt;footer&gt;  
      &lt;button commandfor="confirm-dialog" command="close" value="cancel"&gt;  
        Cancel  
      &lt;/button&gt;  
      &lt;button commandfor="confirm-dialog" command="close" value="delete"&gt;  
        Delete  
      &lt;/button&gt;  
    &lt;/footer&gt;  
  &lt;/dialog&gt;  
  ```  
  - 결과 처리 코드: 다이얼로그의 close 이벤트에서 반환 값 처리 가능  
  ```javascript  
  dialog.addEventListener("close", (event) => {  
    if (event.target.returnValue === "cancel") {  
      console.log("Cancel was clicked");  
    } else if (event.target.returnValue === "delete") {  
      console.log("Delete was clicked");  
    }  
  });  
  ```  
### 사용자 정의 명령  
  
- 내장 명령 외에도 `--` 접두사를 사용하여 사용자 정의 명령을 정의할 수 있음  
- 사용자 정의 명령은 대상 요소에서 `"command"` 이벤트를 발생시키지만, 추가적인 로직은 수행하지 않음  
- 예제: 이미지 회전 명령 구현  
  ```html  
  &lt;button commandfor="the-image" command="--rotate-landscape"&gt;  
    Landscape  
  &lt;/button&gt;  
  &lt;button commandfor="the-image" command="--rotate-portrait"&gt;  
    Portrait  
  &lt;/button&gt;  
  &lt;img id="the-image" src="photo.jpg"&gt;  
  
  &lt;script type="module"&gt;  
    const image = document.getElementById("the-image");  
    image.addEventListener("command", (event) => {  
      if (event.command === "--rotate-landscape") {  
        image.style.rotate = "-90deg";  
      } else if (event.command === "--rotate-portrait") {  
        image.style.rotate = "0deg";  
      }  
    });  
  &lt;/script&gt;  
  ```  
### Shadow DOM에서 명령 처리  
- Shadow DOM에서는 commandfor가 ID를 기반으로 작동하기 때문에 다음과 같은 제한 사항이 있음:  
  - Shadow DOM 간에 요소 참조 불가  
  - 이 경우 JavaScript API를 사용하여 `.commandForElement` 속성을 설정할 수 있음  
- 예제: Shadow DOM에서 명령 연결  
  ```html  
  &lt;my-element&gt;  
    &lt;template shadowrootmode="open"&gt;  
      &lt;button command="show-popover"&gt;Show popover&lt;/button&gt;  
      &lt;slot&gt;&lt;/slot&gt;  
    &lt;/template&gt;  
    &lt;div popover&gt;&lt;!-- ... --&gt;&lt;/div&gt;  
  &lt;/my-element&gt;  
  
  &lt;script&gt;  
    customElements.define("my-element", class extends HTMLElement {  
      connectedCallback() {  
        const popover = this.querySelector('[popover]');  
        this.shadowRoot.querySelector('button').commandForElement = popover;  
      }  
    });  
  &lt;/script&gt;  
  ```  
### 향후 계획  
  
- Chrome에서는 추가 내장 명령 도입을 계획 중:  
  - &lt;details&gt; 요소 열기 및 닫기  
  - &lt;input&gt; 및 &lt;select&gt;에서 "show-picker" 명령 지원  
  - &lt;video&gt; 및 &lt;audio&gt; 재생 명령  
  - 요소에서 텍스트 복사 기능

## Comments



### Comment 35576

- Author: neo
- Created: 2025-03-08T12:33:16+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=43292056) 
- 프로그래밍 언어 이론가들은 80년대부터 "goto"의 더 강력한 버전인 "comefrom"에 대해 추측해 왔음. 이는 intercal에서만 구현되었음. intercal은 C와 같은 언어보다 안전성, 성능, 인체공학적으로 우수하지만 상업 시장에 진입하는 데 어려움을 겪고 있음. javascript가 intercal의 이 기능을 통합하는 것을 보는 것은 흥미로움. 이는 javascript의 클로저 기반 객체가 함수형 프로그래밍을 주류로 이끈 것처럼 정중한 프로그래밍의 급증으로 이어질 수 있기를 바람

- Invokers는 Chrome만의 것이 아님. Firefox nightly에서도 이미 사용 가능함

- JS 없이 선언적 UI 동작을 구현하는 아이디어는 매력적임
  - 팝오버/모달의 보일러플레이트를 제거함 (aria-expanded 조작 불필요)
  - show-modal과 같은 내장 명령은 접근성을 마크업에 통합함
  - 사용자 정의 명령(e.g., --rotate-landscape)은 HTML을 통해 컴포넌트가 API를 노출할 수 있게 함

- 의문점:
  - 추상화 vs. 마법: 이는 단순히 복잡성을 JS에서 HTML로 이동시키는 것인가? 프레임워크는 이미 상태를 추상화함. 이는 어떻게 공존할 것인가?
  - Shadow DOM 마찰: shadow roots 간에 .commandForElement를 설정하기 위해 JS가 필요함. 이는 절반만 해결된 문제처럼 보임
  - 미래 대비: OpenUI가 20개 이상의 명령(e.g., show-picker, toggle-details)을 추가하면, 플랫폼이 틈새 구문으로 부풀어 오를 것인가?

- 사양:
  - button element, commandfor 속성
  - button element, command 속성

- 이것이 Next, Be, Apple 등이 약 30년 전에 사용한 액션/메시징 패턴인가, 아니면 내가 뭔가 놓친 것인가
  - 이는 유용했지만 기본적인 디자인 패턴을 유지하려는 복잡성 때문에 인터페이스 기반 컨트롤러 패턴으로 진화했음. 따라서 이 상자가 열리면 많은 개선 요청이 있을 것으로 예상함

- Netscape의 초기 Java UI 툴킷(IFC)이 액션 요소를 연결할 수 있게 했음

- 새로운 command 및 commandfor 속성은 popovertargetaction 및 popovertarget 속성을 개선하고 대체함
  - 이것들이 기본적으로 사용 가능해진 것인가? 대체한다는 것은 무슨 의미인가? 언젠가 이를 제거할 것인가? 웹 개발자들이 더 이상 필요하지 않은 것을 업데이트로 제거할 수는 없음

- 문자열로 프로그래밍하는 것에 완전히 알레르기 반응을 보임. 접근성 이점은 이해하지만, 또 다른 웹 앱 동작 레이어로 요소 ID를 사용하는 것에 대해 특별히 흥미롭지 않음

- 전체 API 없이 이를 구현하지 말았어야 함. 5개 정도의 명령 대신, HTML을 통해 모든 JavaScript 기능을 구현할 수 있는 것처럼 보임. 이는 수천 개의 명령이 될 수 있음

- HTML에서 command and conquer에 대한 기대감이 있었음

- HTML을 개선하고 확장하는 것은 좋지만, 아직 갈 길이 멀음. HTMX 팀이 몇 가지 좋은 아이디어를 가지고 있음
