Explicitly add image/heic to 'accept' attribute on image fields

File upload dialogs (at least on Chrome / Mac) don't count heic as part of image/*, as it's not a web-safe format.
pull/12384/head
Matt Westcott 2024-10-02 21:35:15 +01:00
rodzic 670b721565
commit d02e09e00e
2 zmienionych plików z 38 dodań i 2 usunięć

Wyświetl plik

@ -6,6 +6,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
from django.forms.fields import FileField, ImageField from django.forms.fields import FileField, ImageField
from django.forms.widgets import FileInput
from django.template.defaultfilters import filesizeformat from django.template.defaultfilters import filesizeformat
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -32,6 +33,8 @@ class WagtailImageField(ImageField):
default_validators = [ImageFileExtensionValidator] default_validators = [ImageFileExtensionValidator]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.allowed_image_extensions = get_allowed_image_extensions()
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Get max upload size from settings # Get max upload size from settings
@ -43,8 +46,6 @@ class WagtailImageField(ImageField):
) )
self.max_upload_size_text = filesizeformat(self.max_upload_size) self.max_upload_size_text = filesizeformat(self.max_upload_size)
self.allowed_image_extensions = get_allowed_image_extensions()
self.supported_formats_text = ", ".join(self.allowed_image_extensions).upper() self.supported_formats_text = ", ".join(self.allowed_image_extensions).upper()
# Help text # Help text
@ -181,3 +182,18 @@ class WagtailImageField(ImageField):
self.check_image_pixel_size(f) self.check_image_pixel_size(f)
return f return f
def widget_attrs(self, widget):
attrs = super().widget_attrs(widget)
if (
isinstance(widget, FileInput)
and "accept" not in widget.attrs
and attrs.get("accept") == "image/*"
and "heic" in self.allowed_image_extensions
):
# File upload dialogs (at least on Chrome / Mac) don't count heic as part of image/*, as it's not a
# web-safe format, so add it explicitly
attrs["accept"] = "image/*, image/heic"
return attrs

Wyświetl plik

@ -1621,6 +1621,10 @@ class TestImageChooserView(WagtailTestUtils, TestCase):
# draftail should NOT be a standard JS include on this page # draftail should NOT be a standard JS include on this page
self.assertNotIn("wagtailadmin/js/draftail.js", response_json["html"]) self.assertNotIn("wagtailadmin/js/draftail.js", response_json["html"])
# upload file field should have accept="image/*"
soup = self.get_soup(response_json["html"])
self.assertEqual(soup.select_one('input[type="file"]').get("accept"), "image/*")
def test_simple_with_collection_nesting(self): def test_simple_with_collection_nesting(self):
root_collection = Collection.get_first_root_node() root_collection = Collection.get_first_root_node()
evil_plans = root_collection.add_child(name="Evil plans") evil_plans = root_collection.add_child(name="Evil plans")
@ -1630,6 +1634,22 @@ class TestImageChooserView(WagtailTestUtils, TestCase):
# "Eviler Plans" should be prefixed with &#x21b3 (↳) and 4 non-breaking spaces. # "Eviler Plans" should be prefixed with &#x21b3 (↳) and 4 non-breaking spaces.
self.assertContains(response, "    &#x21b3 Eviler plans") self.assertContains(response, "    &#x21b3 Eviler plans")
@override_settings(
WAGTAILIMAGES_EXTENSIONS=["gif", "jpg", "jpeg", "png", "webp", "avif", "heic"]
)
def test_upload_field_accepts_heic(self):
response = self.get()
self.assertEqual(response.status_code, 200)
response_json = json.loads(response.content.decode())
self.assertEqual(response_json["step"], "choose")
self.assertTemplateUsed(response, "wagtailimages/chooser/chooser.html")
# upload file field should have an explicit 'accept' case for image/heic
soup = self.get_soup(response_json["html"])
self.assertEqual(
soup.select_one('input[type="file"]').get("accept"), "image/*, image/heic"
)
def test_choose_permissions(self): def test_choose_permissions(self):
# Create group with access to admin and Chooser permission on one Collection, but not another. # Create group with access to admin and Chooser permission on one Collection, but not another.
bakers_group = Group.objects.create(name="Bakers") bakers_group = Group.objects.create(name="Bakers")