From 81ffedaacc0d907b9feb73783edefdffd0ced606 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sat, 25 Apr 2020 14:26:43 -0700 Subject: [PATCH] Fixed #31524 -- Removed minified static assets from the admin. --- MANIFEST.in | 1 - django/contrib/admin/bin/compress.py | 52 ------------------- django/contrib/admin/helpers.py | 4 +- django/contrib/admin/options.py | 9 ++-- .../admin/static/admin/js/actions.min.js | 7 --- .../admin/static/admin/js/collapse.min.js | 2 - .../admin/static/admin/js/inlines.min.js | 11 ---- .../admin/static/admin/js/prepopulate.min.js | 1 - .../contributing/writing-code/javascript.txt | 27 ---------- docs/releases/3.1.txt | 5 ++ tests/admin_inlines/tests.py | 2 +- tests/admin_views/tests.py | 16 ++---- 12 files changed, 15 insertions(+), 122 deletions(-) delete mode 100644 django/contrib/admin/bin/compress.py delete mode 100644 django/contrib/admin/static/admin/js/actions.min.js delete mode 100644 django/contrib/admin/static/admin/js/collapse.min.js delete mode 100644 django/contrib/admin/static/admin/js/inlines.min.js delete mode 100644 django/contrib/admin/static/admin/js/prepopulate.min.js diff --git a/MANIFEST.in b/MANIFEST.in index 0e131eb179..fecbae358b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,7 +7,6 @@ include MANIFEST.in include package.json include *.rst graft django -prune django/contrib/admin/bin graft docs graft extras graft js_tests diff --git a/django/contrib/admin/bin/compress.py b/django/contrib/admin/bin/compress.py deleted file mode 100644 index 52ddcf5295..0000000000 --- a/django/contrib/admin/bin/compress.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -import argparse -import subprocess -import sys -from pathlib import Path - -js_path = Path(__file__).parents[1] / 'static' / 'admin' / 'js' - - -def main(): - description = """With no file paths given this script will automatically -compress files of the admin app. Requires the Google Closure Compiler library -and Java version 7 or later.""" - parser = argparse.ArgumentParser(description=description) - parser.add_argument('file', nargs='*') - parser.add_argument("-v", "--verbose", action="store_true", dest="verbose") - parser.add_argument("-q", "--quiet", action="store_false", dest="verbose") - options = parser.parse_args() - - if not options.file: - if options.verbose: - sys.stdout.write("No filenames given; defaulting to admin scripts\n") - files = [ - js_path / f - for f in ["actions.js", "collapse.js", "inlines.js", "prepopulate.js"] - ] - else: - files = [Path(f) for f in options.file] - - for file_path in files: - to_compress = file_path.expanduser() - if to_compress.exists(): - to_compress_min = to_compress.with_suffix('.min.js') - cmd = ['npx'] - if not options.verbose: - cmd.append('-q') - cmd.extend([ - 'google-closure-compiler', - '--language_out=ECMASCRIPT_2015', - '--rewrite_polyfills=false', - '--js', str(to_compress), - '--js_output_file', str(to_compress_min), - ]) - if options.verbose: - sys.stdout.write("Running: %s\n" % ' '.join(cmd)) - subprocess.run(cmd) - else: - sys.stdout.write("File %s not found. Sure it exists?\n" % to_compress) - - -if __name__ == '__main__': - main() diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 09dbd090fc..56d7970d2a 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -1,7 +1,6 @@ import json from django import forms -from django.conf import settings from django.contrib.admin.utils import ( display_for_field, flatten_fieldsets, help_text_for_field, label_for_field, lookup_field, @@ -80,8 +79,7 @@ class Fieldset: @property def media(self): if 'collapse' in self.classes: - extra = '' if settings.DEBUG else '.min' - return forms.Media(js=['admin/js/collapse%s.js' % extra]) + return forms.Media(js=['admin/js/collapse.js']) return forms.Media() def __iter__(self): diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 90f14d2136..b895378d37 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -642,9 +642,9 @@ class ModelAdmin(BaseModelAdmin): 'jquery.init.js', 'core.js', 'admin/RelatedObjectLookups.js', - 'actions%s.js' % extra, + 'actions.js', 'urlify.js', - 'prepopulate%s.js' % extra, + 'prepopulate.js', 'vendor/xregexp/xregexp%s.js' % extra, ] return forms.Media(js=['admin/js/%s' % url for url in js]) @@ -2024,12 +2024,11 @@ class InlineModelAdmin(BaseModelAdmin): @property def media(self): extra = '' if settings.DEBUG else '.min' - js = ['vendor/jquery/jquery%s.js' % extra, 'jquery.init.js', - 'inlines%s.js' % extra] + js = ['vendor/jquery/jquery%s.js' % extra, 'jquery.init.js', 'inlines.js'] if self.filter_vertical or self.filter_horizontal: js.extend(['SelectBox.js', 'SelectFilter2.js']) if self.classes and 'collapse' in self.classes: - js.append('collapse%s.js' % extra) + js.append('collapse.js') return forms.Media(js=['admin/js/%s' % url for url in js]) def get_extra(self, request, obj=None, **kwargs): diff --git a/django/contrib/admin/static/admin/js/actions.min.js b/django/contrib/admin/static/admin/js/actions.min.js deleted file mode 100644 index 29fd0d8c2d..0000000000 --- a/django/contrib/admin/static/admin/js/actions.min.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict';{const a=django.jQuery;let e;a.fn.actions=function(g){const b=a.extend({},a.fn.actions.defaults,g),f=a(this);let k=!1;const l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},n=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()}, -p=function(){n();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},q=function(c){c?l():n();a(f).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){const c=a(f).filter(":checked").length,d=a(".action-counter").data("actionsIcnt");a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:d},!0));a(b.allToggle).prop("checked",function(){let a;c===f.length?(a=!0,l()):(a=!1,p());return a})}; -a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);h();1===a(b.acrossInput).val()&&m()});a(b.allToggle).show().on("click",function(){q(a(this).prop("checked"));h()});a("a",b.acrossQuestions).on("click",function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("a",b.acrossClears).on("click",function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);p();q(0);h()});e=null;a(f).on("click",function(c){c||(c=window.event); -const d=c.target?c.target:c.srcElement;if(e&&a.data(e)!==a.data(d)&&!0===c.shiftKey){let c=!1;a(e).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)===a.data(e)||a.data(this)===a.data(d))c=c?!1:!0;c&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);e=d;h()});a("form#changelist-form table#result_list tr").on("change","td:gt(0) :input", -function(){k=!0});a('form#changelist-form button[name="index"]').on("click",function(a){if(k)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').on("click",function(c){let d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return k?confirm(gettext("You have selected an action, but you haven\u2019t saved your changes to individual fields yet. Please click OK to save. You\u2019ll need to re-run the action.")): -confirm(gettext("You have selected an action, and you haven\u2019t made any changes on individual fields. You\u2019re probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"};a(document).ready(function(){const g= -a("tr input.action-select");0=h.val()-f.val()&&k.parent().hide();p(d.closest(".inline-group"));a.added&&a.added(d);b(document).trigger("formset:added",[d,a.prefix])}, -r=function(b){b.is("tr")?b.children(":last").append('
'+a.deleteText+"
"):b.is("ul")||b.is("ol")?b.append('
  • '+a.deleteText+"
  • "):b.children(":first").append(''+a.deleteText+"");b.find("a."+a.deleteCssClass).on("click",u.bind(this))},u=function(g){g.preventDefault();var d=b(g.target).closest("."+a.formCssClass);g=d.closest(".inline-group"); -var f=d.prev();f.length&&f.hasClass("row-form-errors")&&f.remove();d.remove();--n;a.removed&&a.removed(d);b(document).trigger("formset:removed",[d,a.prefix]);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(""===h.val()||0'+a.addText+"");k=l.find("tr:last a")}else e.filter(":last").after('"), -k=e.filter(":last").next().find("a");k.on("click",t)})();c=""===h.val()||0 tr.form-row",b(c).tabularFormset(c,a.options)}})})}; diff --git a/django/contrib/admin/static/admin/js/prepopulate.min.js b/django/contrib/admin/static/admin/js/prepopulate.min.js deleted file mode 100644 index 11ead49905..0000000000 --- a/django/contrib/admin/static/admin/js/prepopulate.min.js +++ /dev/null @@ -1 +0,0 @@ -'use strict';{const b=django.jQuery;b.fn.prepopulate=function(d,f,g){return this.each(function(){const a=b(this),h=function(){if(!a.data("_changed")){var e=[];b.each(d,function(a,c){c=b(c);0`) are still included. + .. _deprecated-features-3.1: Features deprecated in 3.1 diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 91bb9465a8..119dd56e61 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -510,7 +510,7 @@ class TestInlineMedia(TestDataMixin, TestCase): 'my_awesome_inline_scripts.js', 'custom_number.js', 'admin/js/jquery.init.js', - 'admin/js/inlines.min.js', + 'admin/js/inlines.js', ] ) self.assertContains(response, 'my_awesome_inline_scripts.js') diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index eb6f009f03..ada1e886ae 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -1229,26 +1229,18 @@ class AdminJavaScriptTest(TestCase): response = self.client.get(reverse('admin:admin_views_section_add')) self.assertNotContains(response, 'vendor/jquery/jquery.js') self.assertContains(response, 'vendor/jquery/jquery.min.js') - self.assertNotContains(response, 'prepopulate.js') - self.assertContains(response, 'prepopulate.min.js') - self.assertNotContains(response, 'actions.js') - self.assertContains(response, 'actions.min.js') - self.assertNotContains(response, 'collapse.js') - self.assertContains(response, 'collapse.min.js') - self.assertNotContains(response, 'inlines.js') - self.assertContains(response, 'inlines.min.js') + self.assertContains(response, 'prepopulate.js') + self.assertContains(response, 'actions.js') + self.assertContains(response, 'collapse.js') + self.assertContains(response, 'inlines.js') with override_settings(DEBUG=True): response = self.client.get(reverse('admin:admin_views_section_add')) self.assertContains(response, 'vendor/jquery/jquery.js') self.assertNotContains(response, 'vendor/jquery/jquery.min.js') self.assertContains(response, 'prepopulate.js') - self.assertNotContains(response, 'prepopulate.min.js') self.assertContains(response, 'actions.js') - self.assertNotContains(response, 'actions.min.js') self.assertContains(response, 'collapse.js') - self.assertNotContains(response, 'collapse.min.js') self.assertContains(response, 'inlines.js') - self.assertNotContains(response, 'inlines.min.js') @override_settings(ROOT_URLCONF='admin_views.urls')