Skip to content

Commit

Permalink
Removed unveil JavaScript library
Browse files Browse the repository at this point in the history
The `unveil` library is used to lazy-load images, and its last release
was in 2013. This is useful functionality, but we don't need JavaScript
to get it. All modern browsers now support it natively with the
`loading="lazy"` attribute on the `img` HTML tag:

- https://caniuse.com/loading-lazy-attr
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#loading

This patch removes the `unveil` library and all references to it and
uses the `loading` attribute in the one place where `unveil` was being
used. This includes `fundraising-heroes.js`, the sole purpose of which
was to initialize `unveil`.
  • Loading branch information
adamzap authored and bmispelon committed Dec 6, 2024
1 parent 0d4e748 commit 6757a83
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 222 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,4 @@ djangoproject/cache
djangoproject/static/js/lib/jquery-flot/examples
djangoproject/static/css/*.map
djangoproject/static/css/*.css
djangoproject/static/js/lib/unveil/jquery-1.9.1.min.js
djangoproject/static/js/lib/unveil/index.html
djangoproject/static/js/lib/unveil/img
node_modules/
1 change: 0 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"jquery.inview": "1.0.0",
"webfontloader": "~1.5.10",
"jquery.payment": "~1.1.4",
"unveil": "~1.3.0",
"jquery-flot": "~0.8.3",
"clipboard": "~1.5.12"
}
Expand Down
17 changes: 0 additions & 17 deletions djangoproject/static/js/lib/unveil/.bower.json

This file was deleted.

84 changes: 0 additions & 84 deletions djangoproject/static/js/lib/unveil/README.md

This file was deleted.

5 changes: 0 additions & 5 deletions djangoproject/static/js/lib/unveil/bower.json

This file was deleted.

57 changes: 0 additions & 57 deletions djangoproject/static/js/lib/unveil/jquery.unveil.js

This file was deleted.

11 changes: 0 additions & 11 deletions djangoproject/static/js/lib/unveil/jquery.unveil.min.js

This file was deleted.

5 changes: 0 additions & 5 deletions djangoproject/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ define(function() {
mods.push('mod/fundraising-index');
}

//fundraising heroes list
if (hasClass('heroes-section')) {
mods.push('mod/fundraising-heroes');
}

if (hasClass('dashboard-index')) {
mods.push('dashboard/index');
}
Expand Down
27 changes: 0 additions & 27 deletions djangoproject/static/js/mod/fundraising-heroes.js

This file was deleted.

2 changes: 0 additions & 2 deletions djangoproject/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@
'jquery.inview': ["jquery"],
'jquery.payment': ["jquery"],
'jquery.flot': ["jquery"],
'jquery.unveil': ["jquery"],
'stripe': {
exports: 'Stripe'
}
Expand All @@ -159,7 +158,6 @@
"jquery": extless("{% static 'js/lib/jquery/dist/jquery.min.js' %}"),
"jquery.inview": extless("{% static 'js/lib/jquery.inview/jquery.inview.min.js' %}"),
"jquery.payment": extless("{% static 'js/lib/jquery.payment/lib/jquery.payment.js' %}"),
"jquery.unveil": extless("{% static 'js/lib/unveil/jquery.unveil.min.js' %}"),
"jquery.flot": extless("{% static 'js/lib/jquery-flot/jquery.flot.min.js' %}"),
"clipboard": extless("{% static 'js/lib/clipboard/dist/clipboard.min.js' %}"),
"mod/floating-warning": extless("{% static 'js/mod/floating-warning.js' %}"),
Expand Down
19 changes: 14 additions & 5 deletions djangoproject/templates/fundraising/includes/_hero_with_logo.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
{% load static thumbnail %}
{% load i18n static thumbnail %}
<div class="hero">
<div class="hero-logo">
{% if obj.url %}<a href="{{ obj.url }}" rel="nofollow">{% endif %}
<img src="{% static 'img/fundraising-heart.svg' %}"
data-src="{% if obj.logo %}{{ obj.thumbnail.url }}{% else %}{% static 'img/fundraising-heart.svg' %}{% endif %}"
data-src-retina="{% if obj.logo %}{{ obj.thumbnail.url|resolution:'2x' }}{% else %}{% static 'img/fundraising-heart.svg' %}{% endif %}"
alt="{{ obj.display_name }}" />
{% if obj.logo %}
<img
src="{{ obj.thumbnail.url }}"
srcset="{{ obj.thumbnail.url|resolution:'2x' }} 2x"
width="{{ obj.THUMBNAIL_SIZE }}"
height="{{ obj.THUMBNAIL_SIZE }}"
loading="lazy"
alt="{% blocktranslate trimmed with company_name=obj.display_name %}
Logo of company {{ company_name }}{% endblocktranslate %}"
>
{% else %}
<img src="{% static 'img/fundraising-heart.svg' %}" alt="{% translate 'Pixelated heart logo' %}">
{% endif %}
{% if obj.url %}</a>{% endif %}
</div>
<div class="hero-name">
Expand Down
77 changes: 72 additions & 5 deletions fundraising/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,98 @@
import json
from datetime import datetime
import shutil
import tempfile
from base64 import b64decode
from datetime import date, datetime
from operator import attrgetter
from unittest.mock import patch

import stripe
from django.conf import settings
from django.core import mail
from django.core.files.base import ContentFile
from django.template.defaultfilters import date as date_filter
from django.test import TestCase
from django.test.utils import override_settings
from django.urls import reverse
from django_hosts.resolvers import reverse as django_hosts_reverse
from django_recaptcha.client import RecaptchaResponse

from members.models import CorporateMember, Invoice

from ..models import DjangoHero, Donation


class TemporaryMediaRootMixin:
"""
A TestCase mixin that overrides settings.MEDIA_ROOT for every test on the
class to point to a temporary directory that is destroyed when the tests
finished.
The content of the directory persists between different tests on the class.
"""

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.tmpdir = tempfile.mkdtemp(prefix="djangoprojectcom_")

@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.tmpdir, ignore_errors=True)
super().tearDownClass()

def run(self, result=None):
with self.settings(MEDIA_ROOT=self.tmpdir):
return super().run(result)


class TestIndex(TestCase):
def test_redirect(self):
response = self.client.get(reverse("fundraising:index"))
self.assertEqual(response.status_code, 200)


class TestCampaign(TestCase):
class TestCampaign(TemporaryMediaRootMixin, TestCase):
def setUp(self):
self.index_url = reverse("fundraising:index")
self.imagefile = ContentFile(
content=b64decode(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA"
"DUlEQVR42mPk8Tb+DwACgAGLzMGnPAAAAABJRU5ErkJggg=="
),
name="logo.png",
)

def test_corporate_member_without_logo(self):
member = CorporateMember.objects.create(
display_name="Test Member", membership_level=1, logo=None
)
Invoice.objects.create(amount=100, expiration_date=date.today(), member=member)
response = self.client.get(self.index_url)

self.assertContains(
response,
'<img src="/s/img/fundraising-heart.svg" alt="Pixelated heart logo">',
html=True,
)

def test_corporate_member_with_logo(self):
member = CorporateMember.objects.create(
display_name="Test Member", membership_level=1, logo=self.imagefile
)
Invoice.objects.create(amount=100, expiration_date=date.today(), member=member)
response = self.client.get(self.index_url)

self.assertContains(
response,
"""<img
src="/m/cache/9b/e7/9be7b86ebc112b001cad84f900bf0bf7.png"
srcset="/m/cache/9b/e7/[email protected] 2x"
width="170"
height="170"
loading="lazy"
alt="Logo of company Test Member"
>""",
html=True,
)

def test_anonymous_donor(self):
hero = DjangoHero.objects.create(
Expand All @@ -35,13 +103,12 @@ def test_anonymous_donor(self):
response = self.client.get(self.index_url)
self.assertContains(response, "Anonymous Hero")

@override_settings(MEDIA_ROOT="djangoproject/")
def test_anonymous_donor_with_logo(self):
hero = DjangoHero.objects.create(
is_visible=True,
approved=True,
hero_type="individual",
logo="static/img/logo-django.png",
logo=self.imagefile,
)
donation = hero.donation_set.create(subscription_amount="5")
donation.payment_set.create(amount="5")
Expand Down

0 comments on commit 6757a83

Please sign in to comment.