From c4d3346f2027b1576ce5a492e7ab96e931f46005 Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Tue, 27 May 2025 22:15:04 -0400 Subject: [PATCH 1/8] Add PUT, PATCH, and DELETE to form method attribute --- source | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/source b/source index 76281111e3d..3df6b5bef6b 100644 --- a/source +++ b/source @@ -57151,6 +57151,21 @@ form.method === input; // => true data-x="attr-fs-method-POST-keyword">post POST Indicates the form will use the HTTP POST method. + + put + PUT + Indicates the form will use the HTTP PUT method. + + patch + PATCH + Indicates the form will use the HTTP PATCH method. + + delete + DELETE + Indicates the form will use the HTTP DELETE method. dialog @@ -57184,13 +57199,26 @@ form.method === input; // => true <p><input type=submit></p> </form> + + +
+ +

The method attribute can also specify the value + "delete", which has also sends the form's + values as query parameters, this time with the HTTP DELETE method: + +

<form method="delete" action="/delete-user.cgi">
+ <p><label>User ID: <input type=text name=id></label></p>
+ <p><input type=submit></p>
+</form>
+

On the other hand, here the method attribute is used to specify the value "post", so that the user's - message is submitted in the HTTP request's body:

+ message is submitted in the HTTP request's body, with the POST method:

<form method="post" action="/post-message.cgi">
  <p><label>Message: <input type=text name=m></label></p>
@@ -57199,6 +57227,20 @@ form.method === input; // => true
+
+ +

The method attribute also supports the + "put" and + "patch" keywords, which likewise submit the + form's data as part of the request body, with the respective HTTP method: + +

<form method="put" action="/message/123.cgi">
+ <p><label>Message: <input type=text name=m></label></p>
+ <p><input type=submit value="Save edited message"></p>
+</form>
+ +
+

In this example, a form is used with a dialog. The GET POST + PUT + PATCH + DELETE http Mutate action URL Submit as entity body + Submit as entity body + Submit as entity body + Mutate action URL https Mutate action URL Submit as entity body + Submit as entity body + Submit as entity body + Mutate action URL ftp Get action URL Get action URL + Get action URL + Get action URL + Get action URL javascript Get action URL Get action URL + Get action URL + Get action URL + Get action URL data Mutate action URL Get action URL + Get action URL + Get action URL + Mutate action URL mailto Mail with headers Mail as body + Mail as body + Mail as body + Mail with headers

If scheme is not one of those listed in this table, then the behavior is @@ -60584,8 +60647,9 @@ fur

Submit as entity body
-

Assert: method is POST.

+

Assert: method is POST, + PUT, or + PATCH.

Switch on enctype: From 557885a5228af81ec697b7a71a4ea146f1433a08 Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Tue, 27 May 2025 22:51:03 -0400 Subject: [PATCH 2/8] Rename "POST resource" to "request resource" --- source | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source b/source index 3df6b5bef6b..2e95c1bfc27 100644 --- a/source +++ b/source @@ -60591,8 +60591,8 @@ fur task; when the form is first created, its planned navigation must be set to null. In the behaviors described below, when the user agent is required to plan to navigate to a URL url given - an optional POST resource-or-null postResource (default null), it must - run the following steps:

+ an optional request resource-or-null requestResource (default null), it + must run the following steps:

  1. Let referrerPolicy be the empty string.

  2. @@ -60617,8 +60617,8 @@ fur data-x="navigation-user-involvement">userInvolvement set to userInvolvement, sourceElement set to submitter, referrerPolicy set to referrerPolicy, - documentResource set to postResource, and formDataEntryList set to entry + documentResource set to requestResource, and + formDataEntryList set to entry list.

@@ -60700,9 +60700,9 @@ fur
-

Plan to navigate to parsed action given a POST - resource whose request body is - body and request +

Plan to navigate to parsed action given a request + resource whose request body is + body and request content-type is mimeType.

@@ -98583,8 +98583,8 @@ interface NotRestoredReasons {

To create a fresh top-level traversable given a URL - initialNavigationURL and an optional POST resource-or-null - initialNavigationPostResource (default null):

+ initialNavigationURL and an optional request resource-or-null + initialNavigationRequestResource (default null):

  1. Let traversable be the result of creating a new top-level @@ -98594,7 +98594,7 @@ interface NotRestoredReasons {

    Navigate traversable to initialNavigationURL using traversable's active document, with documentResource set to - initialNavigationPostResource.

    + initialNavigationRequestResource.

    We treat these initial navigations as traversable navigating itself, which will ensure all relevant security checks pass.

    @@ -100387,8 +100387,8 @@ interface NotRestoredReasons { list.

  2. -

    A resource, a string, POST resource - or null, initially null.

    +

    A resource, a string, + request resource or null, initially null.

    A string is treated as HTML. It's used to store the source of an iframe NotRestoredReasons {


    -

    A POST resource has:

    +

    A request resource has:

    • -

      A request body, a - byte sequence or failure.

      +

      A request + body, a byte sequence or failure.

      This is only ever accessed in parallel, so it doesn't need to be stored in memory. However, it must return the same byte sequence each time. If this isn't @@ -100432,7 +100432,7 @@ interface NotRestoredReasons { this must be set to failure.

    • -
    • A request +

    • A request content-type, which is `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`.

    @@ -101255,7 +101255,7 @@ location.href = '#foo';

    To navigate a navigable navigable to a URL url using an optional Document-or-null sourceDocument (default null), with an optional POST + id="source-browsing-context">sourceDocument (default null), with an optional request resource, string, or null documentResource (default null), an optional response-or-null window's navigation API.

  3. Let entryListForFiring be formDataEntryList if - documentResource is a POST resource; otherwise, null.

  4. + documentResource is a request resource; otherwise, null.

  5. Let navigationAPIStateForFiring be navigationAPIState if navigationAPIState is not null; otherwise, @@ -103592,7 +103592,7 @@ location.href = '#foo';

  6. -

    If documentResource is a POST resource:

    +

    If documentResource is a request resource:

    1. Set request's method to `When a user requests a reload of a navigable whose active session history entry's document state's resource is a POST resource, the user agent + data-x="document-state-resource">resource is a request resource, the user agent should prompt the user to confirm the operation first, since otherwise transactions (e.g., purchases or database modifications) could be repeated.

      From 9b957e84b9c0471e466b8659b6b485c3282e867d Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Tue, 27 May 2025 23:21:24 -0400 Subject: [PATCH 3/8] Rename allowPOST to allowUnsafe --- source | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source b/source index 2e95c1bfc27..9075eb09039 100644 --- a/source +++ b/source @@ -101722,7 +101722,7 @@ location.href = '#foo'; data-x="dom-navigationtimingtype-navigate">navigate", sourceSnapshotParams, targetSnapshotParams, userInvolvement, navigationId, navigationParams, cspNavigationType, with allowPOST set to true and allowUnsafe set to true and completionSteps set to the following step:

      @@ -103067,7 +103067,7 @@ location.href = '#foo'; (default null), an optional navigation params-or-null navigationParams (default null), an optional string cspNavigationType (default "other"), an optional boolean allowPOST (default false), and optional + data-x="attempt-to-populate-allow-unsafe">allowUnsafe (default false), and optional algorithm steps completionSteps (default an empty algorithm):

      @@ -103100,9 +103100,9 @@ location.href = '#foo';
    2. entry's URL's scheme is a fetch scheme; and

    3. -
    4. documentResource is null, or allowPOST is true and - documentResource's request body - is not failure,

    5. +
    6. documentResource is null, or allowUnsafe is true and + documentResource's request + body is not failure,

    7. then set navigationParams to the result of POST`.

    8. Set request's body to - documentResource's request + documentResource's request body.

    9. Set `Content-Type` - to documentResource's request + to documentResource's request content-type in request's header list.

    @@ -104626,19 +104626,19 @@ location.href = '#foo'; state's reload pending to false.

  7. -
  8. Let allowPOST be targetEntry's

    Let allowUnsafe be targetEntry's document state's reload pending.

  9. In parallel, attempt to populate the history entry's document for targetEntry, given navigable, potentiallyTargetSpecificSourceSnapshotParams, targetSnapshotParams, - userInvolvement, with allowPOST set - to allowPOST and completionSteps set to - queue a global task on the navigation and traversal task source - given navigable's active window to run - afterDocumentPopulated.

  10. + userInvolvement, with allowUnsafe + set to allowUnsafe and + completionSteps set to queue a global task on the navigation + and traversal task source given navigable's + active window to run afterDocumentPopulated.

    +

Otherwise, run afterDocumentPopulated immediately.

From 50a04144b39dbaf8d4585da19b73927076acafe3 Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Tue, 27 May 2025 22:15:04 -0400 Subject: [PATCH 4/8] Add PUT, PATCH, and DELETE to form method attribute Resolves: #3577 This adds `put`, `patch`, and `delete` values to the form element's `method` attribute, and alters navigation to properly handle those additional HTTP methods. It relies on a corresponding change to fetch spec, which allows `mode=navigate` fetches to make CORS requests ([fetch spec PR #1785](https://github.com/whatwg/fetch/pull/1785)). --- source | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/source b/source index 9075eb09039..52a8b69ca1c 100644 --- a/source +++ b/source @@ -2534,6 +2534,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

The following terms are defined in the HTTP specifications: HTTP

    +
  • method
  • +
  • idempotent method
  • `Accept` header
  • `Accept-Language` header
  • `Cache-Control` header
  • @@ -60533,6 +60535,7 @@ fur GET + DELETE POST PUT PATCH @@ -60541,6 +60544,9 @@ fur http Mutate action URL + Mutate action URL + Submit as entity body + Submit as entity body Submit as entity body Submit as entity body Submit as entity body @@ -60548,6 +60554,9 @@ fur https Mutate action URL + Mutate action URL + Submit as entity body + Submit as entity body Submit as entity body Submit as entity body Submit as entity body @@ -60569,6 +60578,9 @@ fur data Mutate action URL + Mutate action URL + Get action URL + Get action URL Get action URL Get action URL Get action URL @@ -60576,6 +60588,9 @@ fur mailto Mail with headers + Mail with headers + Mail as body + Mail as body Mail as body Mail as body Mail as body @@ -60612,7 +60627,8 @@ fur
  • Set the form's planned navigation to null.

  • Navigate targetNavigable to url - using the form element's node document, with form element's node document, + with method set to method, with historyHandling set to historyHandling, userInvolvement set to userInvolvement, sourceElement set to submitter, @@ -96317,8 +96333,8 @@ callback NavigationInterceptHandler = push" or "replace" navigation representing a POST form submission; null otherwise.

    + data-x="dom-NavigationType-replace">replace" navigation representing a POST, PUT, or + PATCH form submission; null otherwise.

    (Notably, this will be null even for "reload" or "traverse" navigations that are revisiting @@ -100214,6 +100230,9 @@ interface NotRestoredReasons {

  • URL, a URL

  • +
  • method, an HTTP request + method, initially set to GET

  • +
  • document state, a document state.

  • @@ -101257,7 +101276,9 @@ location.href = '#foo'; URL url using an optional Document-or-null sourceDocument (default null), with an optional request resource, string, or null documentResource (default null), an optional documentResource (default null), an optional request + method method, an optional response-or-null response (default null), an optional boolean exceptionsEnabled (default false), an optional @@ -101605,8 +101626,8 @@ location.href = '#foo';
  • Let historyEntry be a new session history entry, with its URL set to url and its document state set to + data-x="she-url">URL set to url, its method + set to method and its document state set to documentState.

  • Let navigationParams be null.

  • @@ -103595,8 +103616,8 @@ location.href = '#foo';

    If documentResource is a request resource:

      -
    1. Set request's method to `POST`.

    2. +
    3. Set request's method to + entry's method.

    4. Set request's body to documentResource's request @@ -104633,7 +104654,7 @@ location.href = '#foo';

    5. In parallel, attempt to populate the history entry's document for targetEntry, given navigable, potentiallyTargetSpecificSourceSnapshotParams, targetSnapshotParams, - userInvolvement, with allowUnsafe + userInvolvement, with allowUnsafe set to allowUnsafe and completionSteps set to queue a global task on the navigation and traversal task source given navigable's @@ -107692,10 +107713,9 @@ new PaymentRequest(…); // Allowed to use

      When a user requests a reload of a navigable whose active session history entry's document state's resource is a request resource, the user agent - should prompt the user to confirm the operation first, since otherwise transactions (e.g., - purchases or database modifications) could be repeated.

      + data-x="she-method">method is a non-idempotent + method, the user agent should prompt the user to confirm the operation first, since otherwise + transcations (e.g. purchases or database modifications) could be repeated.

      When a user requests a reload of a navigable, user agents may provide a mechanism for ignoring any caches when reloading.

      @@ -147424,6 +147444,7 @@ INSERT INTERFACES HERE Alexander Farkas, Alexander J. Vincent, Alexander Kalenik, + Alexander Petros, Alexandre Dieulot, Alexandre Morgaut, Alexey Feldgendler, From a9257456c7def8b7db934af1d4c58c398244ddb1 Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Sat, 2 Aug 2025 16:55:02 -0600 Subject: [PATCH 5/8] Fix indentation --- source | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source b/source index 52a8b69ca1c..696e12f9aae 100644 --- a/source +++ b/source @@ -57203,16 +57203,16 @@ form.method === input; // => true
-
+

The method attribute can also specify the value - "delete", which has also sends the form's - values as query parameters, this time with the HTTP DELETE method: + "delete", which has also sends + the form's values as query parameters, this time with the HTTP DELETE method:

<form method="delete" action="/delete-user.cgi">
- <p><label>User ID: <input type=text name=id></label></p>
- <p><input type=submit></p>
-</form>
+ <p><label>User ID: <input type=text name=id></label></p> + <p><input type=submit></p> + </form>
From 054b8dd5465b53754516159d818e18ab4206aa3f Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Sat, 2 Aug 2025 17:17:57 -0600 Subject: [PATCH 6/8] Use fetch method definition --- source | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source b/source index 696e12f9aae..c72f49b1a71 100644 --- a/source +++ b/source @@ -2534,7 +2534,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

The following terms are defined in the HTTP specifications: HTTP

    -
  • method
  • idempotent method
  • `Accept` header
  • `Accept-Language` header
  • @@ -100231,7 +100230,7 @@ interface NotRestoredReasons {
  • URL, a URL

  • method, an HTTP request - method, initially set to GET

  • + method, initially set to GET

  • document state, a document state.

  • @@ -101277,7 +101276,7 @@ location.href = '#foo'; id="source-browsing-context">sourceDocument (default null), with an optional request resource, string, or null documentResource (default null), an optional request - method method method, an optional response-or-null response (default null), an optional boolean Date: Sat, 2 Aug 2025 18:39:00 -0600 Subject: [PATCH 7/8] Fix typo --- source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source b/source index c72f49b1a71..ddb08e1493c 100644 --- a/source +++ b/source @@ -107714,7 +107714,7 @@ new PaymentRequest(…); // Allowed to use data-x="nav-active-history-entry">active session history entry's method is a non-idempotent method, the user agent should prompt the user to confirm the operation first, since otherwise - transcations (e.g. purchases or database modifications) could be repeated.

    + transactions (e.g. purchases or database modifications) could be repeated.

    When a user requests a reload of a navigable, user agents may provide a mechanism for ignoring any caches when reloading.

    From c658a44aff2fc23322980d0da96ab7d3dc933070 Mon Sep 17 00:00:00 2001 From: Alexander Petros Date: Sun, 3 Aug 2025 14:14:38 -0600 Subject: [PATCH 8/8] Update commandfor example --- source | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source b/source index ddb08e1493c..9be56e171e5 100644 --- a/source +++ b/source @@ -57208,7 +57208,7 @@ form.method === input; // => true "delete", which has also sends the form's values as query parameters, this time with the HTTP DELETE method: -
    <form method="delete" action="/delete-user.cgi">
    +   
    <form method="delete" action="/user.cgi">
        <p><label>User ID: <input type=text name=id></label></p>
        <p><input type=submit></p>
        </form>
    @@ -57221,7 +57221,7 @@ form.method === input; // => true
    specify the value "post", so that the user's message is submitted in the HTTP request's body, with the POST method:

    -
    <form method="post" action="/post-message.cgi">
    +   
    <form method="post" action="/message.cgi">
      <p><label>Message: <input type=text name=m></label></p>
      <p><input type=submit value="Submit message"></p>
     </form>
    @@ -62715,13 +62715,11 @@ interface HTMLDialogElement : HTMLElement { command="show-modal"> Delete </button> -<dialog id="the-dialog"> - <form action="/delete" method="POST"> - <button type="submit"> - Delete - </button> - <button commandfor="the-dialog" - command="close"> +<dialog id="confirm-delete"> + <form action="/items/123" method="DELETE"> + <p>Are you sure you want to delete this item?</p> + <button type="submit">Delete</button> + <button commandfor="confirm-delete" command="close"> Cancel </button> </form>