diff --git a/src/ext/method-override.js b/src/ext/method-override.js new file mode 100644 index 00000000..9d379360 --- /dev/null +++ b/src/ext/method-override.js @@ -0,0 +1,11 @@ +htmx.defineExtension('method-override', { + onEvent: function (name, evt) { + if (name === "configRequest.htmx") { + var method = evt.detail.verb; + if (method !== "get" || method !== "post") { + evt.detail.headers['X-HTTP-Method-Override'] = method.toUpperCase(); + evt.detail.verb = "post"; + } + } + } +}); diff --git a/src/ext/rails-method.js b/src/ext/rails-method.js deleted file mode 100644 index 5d48eccc..00000000 --- a/src/ext/rails-method.js +++ /dev/null @@ -1,10 +0,0 @@ -htmx.defineExtension('rails-method', { - onEvent: function (name, evt) { - if (name === "configRequest.htmx") { - var methodOverride = evt.detail.headers['X-HTTP-Method-Override']; - if (methodOverride) { - evt.detail.parameters['_method'] = methodOverride; - } - } - } -}); diff --git a/src/htmx.js b/src/htmx.js index df3e3211..85a1ed1e 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1337,9 +1337,6 @@ return (function () { if (verb !== 'get') { headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; - if (verb !== 'post') { - headers['X-HTTP-Method-Override'] = verb.toUpperCase(); - } } // behavior of anchors w/ empty href is to use the current URL @@ -1356,7 +1353,11 @@ return (function () { path:path }; if(!triggerEvent(elt, 'configRequest.htmx', requestConfig)) return endRequestLock(); + // copy out in case the object was overwritten path = requestConfig.path; + verb = requestConfig.verb; + headers = requestConfig.headers; + filteredParameters = requestConfig.parameters; var splitPath = path.split("#"); var pathNoAnchor = splitPath[0]; @@ -1377,7 +1378,7 @@ return (function () { } xhr.open('GET', finalPathForGet, true); } else { - xhr.open('POST', path, true); + xhr.open(verb.toUpperCase(), path, true); } xhr.overrideMimeType("text/html"); diff --git a/test/attributes/hx-delete.js b/test/attributes/hx-delete.js index 3a166aaf..22b0f760 100644 --- a/test/attributes/hx-delete.js +++ b/test/attributes/hx-delete.js @@ -8,10 +8,9 @@ describe("hx-delete attribute", function(){ clearWorkArea(); }); - it('issues a DELETE request with proper headers', function() + it('issues a DELETE request', function() { this.server.respondWith("DELETE", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('DELETE'); xhr.respond(200, {}, "Deleted!"); }); @@ -21,10 +20,9 @@ describe("hx-delete attribute", function(){ btn.innerHTML.should.equal("Deleted!"); }); - it('issues a DELETE request with proper headers w/ data-* prefix', function() + it('issues a DELETE request w/ data-* prefix', function() { this.server.respondWith("DELETE", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('DELETE'); xhr.respond(200, {}, "Deleted!"); }); diff --git a/test/attributes/hx-patch.js b/test/attributes/hx-patch.js index 6f7a5e9d..a3c51984 100644 --- a/test/attributes/hx-patch.js +++ b/test/attributes/hx-patch.js @@ -8,10 +8,9 @@ describe("hx-patch attribute", function(){ clearWorkArea(); }); - it('issues a PATCH request with proper headers', function() + it('issues a PATCH request', function() { this.server.respondWith("PATCH", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PATCH'); xhr.respond(200, {}, "Patched!"); }); @@ -21,10 +20,9 @@ describe("hx-patch attribute", function(){ btn.innerHTML.should.equal("Patched!"); }); - it('issues a PATCH request with proper headers w/ data-* prefix', function() + it('issues a PATCH request w/ data-* prefix', function() { this.server.respondWith("PATCH", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PATCH'); xhr.respond(200, {}, "Patched!"); }); diff --git a/test/attributes/hx-put.js b/test/attributes/hx-put.js index a1d47bcc..589ec199 100644 --- a/test/attributes/hx-put.js +++ b/test/attributes/hx-put.js @@ -8,10 +8,9 @@ describe("hx-put attribute", function(){ clearWorkArea(); }); - it('issues a PUT request with proper headers', function() + it('issues a PUT request', function() { this.server.respondWith("PUT", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PUT'); xhr.respond(200, {}, "Putted!"); }); @@ -21,10 +20,9 @@ describe("hx-put attribute", function(){ btn.innerHTML.should.equal("Putted!"); }); - it('issues a PUT request with proper headers', function() + it('issues a PUT request w/ data-* prefix', function() { this.server.respondWith("PUT", "/test", function(xhr){ - xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PUT'); xhr.respond(200, {}, "Putted!"); }); diff --git a/test/ext/method-override.js b/test/ext/method-override.js new file mode 100644 index 00000000..b0a21ea1 --- /dev/null +++ b/test/ext/method-override.js @@ -0,0 +1,53 @@ +describe("method-override extension", function(){ + beforeEach(function() { + this.server = makeServer(); + clearWorkArea(); + }); + afterEach(function() { + this.server.restore(); + clearWorkArea(); + }); + + it('issues a DELETE request with proper headers', function() + { + this.server.respondWith("DELETE", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('DELETE'); + xhr.method.should.equal("POST") + xhr.respond(200, {}, "Deleted!"); + }); + + var btn = make('') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Deleted!"); + }); + + it('issues a PATCH request with proper headers', function() + { + this.server.respondWith("PATCH", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PATCH'); + xhr.method.should.equal("POST") + xhr.respond(200, {}, "Patched!"); + }); + + var btn = make('') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Patched!"); + }); + + it('issues a PUT request with proper headers', function() + { + this.server.respondWith("PUT", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PUT'); + xhr.method.should.equal("POST") + xhr.respond(200, {}, "Putted!"); + }); + + var btn = make('') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Putted!"); + }); + +}) diff --git a/test/ext/rails-method.js b/test/ext/rails-method.js deleted file mode 100644 index cc3a5205..00000000 --- a/test/ext/rails-method.js +++ /dev/null @@ -1,61 +0,0 @@ -describe("rails-method extension", function() { - beforeEach(function () { - this.server = makeServer(); - clearWorkArea(); - }); - afterEach(function () { - this.server.restore(); - clearWorkArea(); - }); - - it('Does not affect a GET request', function () { - this.server.respondWith("GET", "/test", function (xhr) { - xhr.respond(200, {}, xhr.url) - }); - var btn = make('') - btn.click(); - this.server.respond(); - btn.innerHTML.should.equal("/test"); - }); - - it('Does not affect a POST request', function () { - this.server.respondWith("POST", "/test", function (xhr) { - xhr.respond(200, {}, getParameters(xhr)['_method']); - }); - var btn = make('') - btn.click(); - this.server.respond(); - btn.innerHTML.should.equal(""); - }); - - it('Adds proper _method param to PUT request', function () { - this.server.respondWith("PUT", "/test", function (xhr) { - xhr.respond(200, {}, getParameters(xhr)['_method']); - }); - var btn = make('') - btn.click(); - this.server.respond(); - btn.innerHTML.should.equal("PUT"); - }); - - it('Adds proper _method param to PATCH request', function () { - this.server.respondWith("PATCH", "/test", function (xhr) { - xhr.respond(200, {}, getParameters(xhr)['_method']); - }); - var btn = make('') - btn.click(); - this.server.respond(); - btn.innerHTML.should.equal("PATCH"); - }); - - it('Adds proper _method param to DELETE request', function () { - this.server.respondWith("DELETE", "/test", function (xhr) { - xhr.respond(200, {}, getParameters(xhr)['_method']); - }); - var btn = make('') - btn.click(); - this.server.respond(); - btn.innerHTML.should.equal("DELETE"); - }); - -}); \ No newline at end of file diff --git a/test/index.html b/test/index.html index 24704252..13fc2bd0 100644 --- a/test/index.html +++ b/test/index.html @@ -83,8 +83,8 @@ - - + + diff --git a/www/extensions.md b/www/extensions.md index 29ebcdfb..0a8b6d9a 100644 --- a/www/extensions.md +++ b/www/extensions.md @@ -33,6 +33,7 @@ The following extensions that are tested and distributed with htmx: | Extension | Description |-----------|------------- | [`json-enc`](/extensions/json-enc) | use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded` +| [`method-override`](/extensions/method-override) | use the `X-HTTP-Method-Override` header for non-`GET` and `POST` requests | [`morphdom-swap`](/extensions/morphdom-swap) | an extension for using the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx. | [`client-side-templates`](/extensions/client-side-templates) | support for client side template processing of JSON responses | [`debug`](/extensions/debug) | an extension for debugging of a particular element using htmx diff --git a/www/extensions/method-override.md b/www/extensions/method-override.md new file mode 100644 index 00000000..6e247a17 --- /dev/null +++ b/www/extensions/method-override.md @@ -0,0 +1,24 @@ +--- +layout: layout.njk +title: htmx - high power tools for html +--- + +## The `method-override` Extension + +This extension makes non-`GET` and `POST` requests use a `POST` with the `X-HTTP-Method-Override` header set to the +actual HTTP method. This is necessary when dealing with some firewall or proxy situations. + +#### Usage + +```html + + + +``` + +#### Source + + + diff --git a/www/extensions/rails-method.md b/www/extensions/rails-method.md deleted file mode 100644 index 0e03086f..00000000 --- a/www/extensions/rails-method.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -layout: layout.njk -title: htmx - high power tools for html ---- - -## The `rails-method` Extension - -This extension includes the rails `_method` parameter in non-`GET` or `POST` requests. - -### Usage - -```html - - ... - -``` - -### Source - -