From 998c3343631b9d38ecf96b211475ecf5e22c9155 Mon Sep 17 00:00:00 2001
From: j <13580441+gary02@users.noreply.github.com>
Date: Mon, 14 Oct 2024 17:32:22 +0800
Subject: [PATCH 1/5] Fix #309 -- handle submit buttons `form*` attributes
---
.gitignore | 1 +
s3file/static/s3file/js/s3file.js | 13 +++++++++++--
tests/test_forms.py | 2 ++
tests/testapp/templates/form.html | 2 +-
tests/testapp/views.py | 2 ++
5 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index cfb6375..03ed1e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,4 @@ target/
node_modules
*.min.js
+.python-version
diff --git a/s3file/static/s3file/js/s3file.js b/s3file/static/s3file/js/s3file.js
index ad88901..4969477 100644
--- a/s3file/static/s3file/js/s3file.js
+++ b/s3file/static/s3file/js/s3file.js
@@ -114,7 +114,7 @@
form.appendChild(submitInput)
}
- function uploadS3Inputs (form) {
+ function uploadS3Inputs (form, submitter) {
window.uploading = 0
form.loaded = 0
form.total = 0
@@ -136,6 +136,15 @@
window.uploading += 1
uploadFiles(form, input, input.name)
})
+ // override form attributes with submit button attributes
+ if (submitter) {
+ form.action = submitter.getAttribute('formaction') || form.action
+ form.method = submitter.getAttribute('formmethod') || form.method
+ form.enctype = submitter.getAttribute('formEnctype') || form.enctype
+ form.formnovalidate = submitter.getAttribute('formnovalidate') || form.novalidate
+ form.target = submitter.getAttribute('formtarget') || form.target
+ }
+
waitForAllFiles(form)
}
@@ -147,7 +156,7 @@
forms.forEach(function (form) {
form.addEventListener('submit', function (e) {
e.preventDefault()
- uploadS3Inputs(e.target)
+ uploadS3Inputs(e.target, e.submitter)
})
var submitButtons = form.querySelectorAll('input[type=submit], button[type=submit]')
Array.from(submitButtons).forEach(function (submitButton) {
diff --git a/tests/test_forms.py b/tests/test_forms.py
index 9f4ee39..2894ed1 100644
--- a/tests/test_forms.py
+++ b/tests/test_forms.py
@@ -187,6 +187,7 @@ def test_file_insert_submit_value(
with wait_for_page_load(driver, timeout=10):
save_button.click()
assert "save" in driver.page_source
+ assert "formaction" not in driver.page_source
driver.get(live_server + self.create_url)
file_input = driver.find_element(By.XPATH, "//input[@name='file']")
@@ -197,6 +198,7 @@ def test_file_insert_submit_value(
save_button.click()
assert "save_continue" in driver.page_source
assert "continue_value" in driver.page_source
+ assert "formaction" in driver.page_source
@pytest.mark.selenium
def test_progress(self, driver, live_server, upload_file, freeze_upload_folder):
diff --git a/tests/testapp/templates/form.html b/tests/testapp/templates/form.html
index 7891e93..335723e 100644
--- a/tests/testapp/templates/form.html
+++ b/tests/testapp/templates/form.html
@@ -15,7 +15,7 @@
{% csrf_token %}
{{ form }}
-
+
0%
diff --git a/tests/testapp/views.py b/tests/testapp/views.py
index 85e8f54..9b4ea17 100644
--- a/tests/testapp/views.py
+++ b/tests/testapp/views.py
@@ -26,6 +26,7 @@ def form_valid(self, form):
"file": self.request.FILES.getlist("file"),
"other_file": self.request.FILES.getlist("other_file"),
},
+ "QUERY_STRING": self.request.GET,
},
status=201,
encoder=FileEncoder,
@@ -45,6 +46,7 @@ def form_valid(self, form):
"file": self.request.FILES.getlist("file"),
"other_file": self.request.FILES.getlist("other_file"),
},
+ "QUERY_STRING": self.request.GET,
},
status=201,
encoder=FileEncoder,
From 10c44fcb2c7a93d3bffa5db0fe038987cee065f7 Mon Sep 17 00:00:00 2001
From: j <13580441+gary02@users.noreply.github.com>
Date: Mon, 14 Oct 2024 17:43:50 +0800
Subject: [PATCH 2/5] Refactor -- gather form mutation code together
---
s3file/static/s3file/js/s3file.js | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/s3file/static/s3file/js/s3file.js b/s3file/static/s3file/js/s3file.js
index 4969477..cbc0424 100644
--- a/s3file/static/s3file/js/s3file.js
+++ b/s3file/static/s3file/js/s3file.js
@@ -104,16 +104,6 @@
})
}
- function clickSubmit (e) {
- var submitButton = e.currentTarget
- var form = submitButton.closest('form')
- var submitInput = document.createElement('input')
- submitInput.type = 'hidden'
- submitInput.value = submitButton.value || '1'
- submitInput.name = submitButton.name
- form.appendChild(submitInput)
- }
-
function uploadS3Inputs (form, submitter) {
window.uploading = 0
form.loaded = 0
@@ -136,13 +126,20 @@
window.uploading += 1
uploadFiles(form, input, input.name)
})
- // override form attributes with submit button attributes
+
if (submitter) {
+ // override form attributes with submit button attributes
form.action = submitter.getAttribute('formaction') || form.action
form.method = submitter.getAttribute('formmethod') || form.method
form.enctype = submitter.getAttribute('formEnctype') || form.enctype
form.formnovalidate = submitter.getAttribute('formnovalidate') || form.novalidate
form.target = submitter.getAttribute('formtarget') || form.target
+ // add submit button value to form
+ var submitInput = document.createElement('input')
+ submitInput.type = 'hidden'
+ submitInput.value = submitter.value || '1'
+ submitInput.name = submitter.name
+ form.appendChild(submitInput)
}
waitForAllFiles(form)
@@ -158,10 +155,6 @@
e.preventDefault()
uploadS3Inputs(e.target, e.submitter)
})
- var submitButtons = form.querySelectorAll('input[type=submit], button[type=submit]')
- Array.from(submitButtons).forEach(function (submitButton) {
- submitButton.addEventListener('click', clickSubmit)
- })
})
})
})()
From 06eb2d95159f7cb07e7084ba795b88a86a7db4c9 Mon Sep 17 00:00:00 2001
From: j <13580441+gary02@users.noreply.github.com>
Date: Tue, 15 Oct 2024 09:55:57 +0800
Subject: [PATCH 3/5] Refactor -- remove anonymous function handler
also see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#memory_issues
---
.gitignore | 1 -
s3file/static/s3file/js/s3file.js | 13 ++++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/.gitignore b/.gitignore
index 03ed1e4..cfb6375 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,4 +59,3 @@ target/
node_modules
*.min.js
-.python-version
diff --git a/s3file/static/s3file/js/s3file.js b/s3file/static/s3file/js/s3file.js
index cbc0424..834f31d 100644
--- a/s3file/static/s3file/js/s3file.js
+++ b/s3file/static/s3file/js/s3file.js
@@ -104,7 +104,13 @@
})
}
- function uploadS3Inputs (form, submitter) {
+ function uploadS3Inputs (event) {
+
+ event.preventDefault()
+
+ var form = event.target
+ var submitter = event.submitter
+
window.uploading = 0
form.loaded = 0
form.total = 0
@@ -151,10 +157,7 @@
})
forms = new Set(forms)
forms.forEach(function (form) {
- form.addEventListener('submit', function (e) {
- e.preventDefault()
- uploadS3Inputs(e.target, e.submitter)
- })
+ form.addEventListener('submit', uploadS3Inputs)
})
})
})()
From c1bfe96faefeeef29d45d7c9b73f76ceafbeeefc Mon Sep 17 00:00:00 2001
From: j <13580441+gary02@users.noreply.github.com>
Date: Tue, 15 Oct 2024 10:40:50 +0800
Subject: [PATCH 4/5] Fix typo
---
s3file/static/s3file/js/s3file.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/s3file/static/s3file/js/s3file.js b/s3file/static/s3file/js/s3file.js
index 834f31d..f08b742 100644
--- a/s3file/static/s3file/js/s3file.js
+++ b/s3file/static/s3file/js/s3file.js
@@ -138,7 +138,7 @@
form.action = submitter.getAttribute('formaction') || form.action
form.method = submitter.getAttribute('formmethod') || form.method
form.enctype = submitter.getAttribute('formEnctype') || form.enctype
- form.formnovalidate = submitter.getAttribute('formnovalidate') || form.novalidate
+ form.novalidate = submitter.getAttribute('formnovalidate') || form.novalidate
form.target = submitter.getAttribute('formtarget') || form.target
// add submit button value to form
var submitInput = document.createElement('input')
From 9d410288cc5b866768788fdf744b5f0dac5064cc Mon Sep 17 00:00:00 2001
From: j <13580441+gary02@users.noreply.github.com>
Date: Sun, 20 Oct 2024 18:00:52 +0800
Subject: [PATCH 5/5] Refactor -- run `standard --fix` to pass lint check
---
s3file/static/s3file/js/s3file.js | 57 +++++++++++++++----------------
1 file changed, 28 insertions(+), 29 deletions(-)
diff --git a/s3file/static/s3file/js/s3file.js b/s3file/static/s3file/js/s3file.js
index f08b742..a45cadc 100644
--- a/s3file/static/s3file/js/s3file.js
+++ b/s3file/static/s3file/js/s3file.js
@@ -2,8 +2,8 @@
(function () {
function parseURL (text) {
- var xml = new window.DOMParser().parseFromString(text, 'text/xml')
- var tag = xml.getElementsByTagName('Key')[0]
+ const xml = new window.DOMParser().parseFromString(text, 'text/xml')
+ const tag = xml.getElementsByTagName('Key')[0]
return decodeURI(tag.childNodes[0].nodeValue)
}
@@ -20,7 +20,7 @@
function request (method, url, data, fileInput, file, form) {
file.loaded = 0
return new Promise(function (resolve, reject) {
- var xhr = new window.XMLHttpRequest()
+ const xhr = new window.XMLHttpRequest()
xhr.onload = function () {
if (xhr.status === 201) {
@@ -31,11 +31,11 @@
}
xhr.upload.onprogress = function (e) {
- var diff = e.loaded - file.loaded
+ const diff = e.loaded - file.loaded
form.loaded += diff
fileInput.loaded += diff
file.loaded = e.loaded
- var defaultEventData = {
+ const defaultEventData = {
currentFile: file,
currentFileName: file.name,
currentFileProgress: Math.min(e.loaded / e.total, 1),
@@ -67,15 +67,15 @@
}
function uploadFiles (form, fileInput, name) {
- var url = fileInput.getAttribute('data-url')
+ const url = fileInput.getAttribute('data-url')
fileInput.loaded = 0
fileInput.total = 0
- var promises = Array.from(fileInput.files).map(function (file) {
+ const promises = Array.from(fileInput.files).map(function (file) {
form.total += file.size
fileInput.total += file.size
- var s3Form = new window.FormData()
+ const s3Form = new window.FormData()
Array.from(fileInput.attributes).forEach(function (attr) {
- var name = attr.name
+ let name = attr.name
if (name.startsWith('data-fields')) {
name = name.replace('data-fields-', '')
@@ -89,7 +89,7 @@
})
Promise.all(promises).then(function (results) {
results.forEach(function (result) {
- var hiddenFileInput = document.createElement('input')
+ const hiddenFileInput = document.createElement('input')
hiddenFileInput.type = 'hidden'
hiddenFileInput.name = name
hiddenFileInput.value = parseURL(result)
@@ -105,24 +105,23 @@
}
function uploadS3Inputs (event) {
-
event.preventDefault()
- var form = event.target
- var submitter = event.submitter
+ const form = event.target
+ const submitter = event.submitter
window.uploading = 0
form.loaded = 0
form.total = 0
- var inputs = Array.from(form.querySelectorAll('input[type=file].s3file'))
+ const inputs = Array.from(form.querySelectorAll('input[type=file].s3file'))
inputs.forEach(function (input) {
- var hiddenS3Input = document.createElement('input')
+ const hiddenS3Input = document.createElement('input')
hiddenS3Input.type = 'hidden'
hiddenS3Input.name = 's3file'
hiddenS3Input.value = input.name
form.appendChild(hiddenS3Input)
- var hiddenSignatureInput = document.createElement('input')
+ const hiddenSignatureInput = document.createElement('input')
hiddenSignatureInput.type = 'hidden'
hiddenSignatureInput.name = input.name + '-s3f-signature'
hiddenSignatureInput.value = input.dataset.s3fSignature
@@ -134,25 +133,25 @@
})
if (submitter) {
- // override form attributes with submit button attributes
- form.action = submitter.getAttribute('formaction') || form.action
- form.method = submitter.getAttribute('formmethod') || form.method
- form.enctype = submitter.getAttribute('formEnctype') || form.enctype
- form.novalidate = submitter.getAttribute('formnovalidate') || form.novalidate
- form.target = submitter.getAttribute('formtarget') || form.target
- // add submit button value to form
- var submitInput = document.createElement('input')
- submitInput.type = 'hidden'
- submitInput.value = submitter.value || '1'
- submitInput.name = submitter.name
- form.appendChild(submitInput)
+ // override form attributes with submit button attributes
+ form.action = submitter.getAttribute('formaction') || form.action
+ form.method = submitter.getAttribute('formmethod') || form.method
+ form.enctype = submitter.getAttribute('formEnctype') || form.enctype
+ form.novalidate = submitter.getAttribute('formnovalidate') || form.novalidate
+ form.target = submitter.getAttribute('formtarget') || form.target
+ // add submit button value to form
+ const submitInput = document.createElement('input')
+ submitInput.type = 'hidden'
+ submitInput.value = submitter.value || '1'
+ submitInput.name = submitter.name
+ form.appendChild(submitInput)
}
waitForAllFiles(form)
}
document.addEventListener('DOMContentLoaded', function () {
- var forms = Array.from(document.querySelectorAll('input[type=file].s3file')).map(function (input) {
+ let forms = Array.from(document.querySelectorAll('input[type=file].s3file')).map(function (input) {
return input.closest('form')
})
forms = new Set(forms)