diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a9e918f0..ab794f30d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: '(^djangoproject\/static\/.*$)' +exclude: '^djangoproject\/static\/(css\/|fonts\/|img\/|robots).*$' default_language_version: python: python3 repos: @@ -19,6 +19,7 @@ repos: - id: debug-statements - id: detect-private-key - id: end-of-file-fixer + exclude: '(^djangoproject\/static\/js\/lib\/.*$)' exclude_types: [json, sql] - id: file-contents-sorter files: ^(requirements/\w*.txt)$ @@ -46,6 +47,7 @@ repos: hooks: - id: prettier exclude_types: [html, json, scss] + exclude: '(^djangoproject\/static\/js\/lib\/.*$)' - repo: https://github.com/pycqa/isort rev: "5.13.2" hooks: diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..6962fc73f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "overrides": [ + { + "files": "*.js", + "options": { + "tabWidth": 2, + "singleQuote": true + } + } + ] +} diff --git a/djangoproject/static/js/dashboard/detail.js b/djangoproject/static/js/dashboard/detail.js index 3059f7fe0..2cad2687f 100644 --- a/djangoproject/static/js/dashboard/detail.js +++ b/djangoproject/static/js/dashboard/detail.js @@ -1,78 +1,89 @@ -define('dashboard/detail', ['jquery', 'jquery.flot', 'dashboard/utils'], function ($, plot, utils) { - $(function () { - var element = $("#graph"); - var url = element.data('path') + element.data('metric') + ".json?days=365"; - var hover = { - show: function (x, y, message) { - $('
').html(message) - .css({top: y, left: x}) - .appendTo('body') - .show(); - }, - hide: function () { - $("#hover").remove(); - } - }; +define('dashboard/detail', [ + 'jquery', + 'jquery.flot', + 'dashboard/utils', +], function ($, plot, utils) { + $(function () { + var element = $('#graph'); + var url = element.data('path') + element.data('metric') + '.json?days=365'; + var hover = { + show: function (x, y, message) { + $('
') + .html(message) + .css({ top: y, left: x }) + .appendTo('body') + .show(); + }, + hide: function () { + $('#hover').remove(); + }, + }; - $.getJSON(url, function (response) { - for (var i = 0; i < response.data.length; i++) { - response.data[i][0] = response.data[i][0] * 1000; - } - var options = { - xaxis: { - mode: "time", - tickColor: "rgba(0,0,0,0)", - minTickSize: [1, "day"] - }, - yaxis: {min: 0, ticks: 4}, - grid: {borderWidth: 0, hoverable: true, color: "#0C3C26"}, - colors: ["#0C4B33"] - }; - if (response.period == "daily") { - options.bars = { - show: true, - barWidth: 22 * 60 * 60 * 1000, - align: "center" - }; - } else if (response.period == 'weekly') { - options.bars = { - show: true, - barWidth: 22 * 60 * 60 * 7 * 1000, - align: "center" - }; - } - var plot = $.plot(element, [response.data], options); + $.getJSON(url, function (response) { + for (var i = 0; i < response.data.length; i++) { + response.data[i][0] = response.data[i][0] * 1000; + } + var options = { + xaxis: { + mode: 'time', + tickColor: 'rgba(0,0,0,0)', + minTickSize: [1, 'day'], + }, + yaxis: { min: 0, ticks: 4 }, + grid: { borderWidth: 0, hoverable: true, color: '#0C3C26' }, + colors: ['#0C4B33'], + }; + if (response.period == 'daily') { + options.bars = { + show: true, + barWidth: 22 * 60 * 60 * 1000, + align: 'center', + }; + } else if (response.period == 'weekly') { + options.bars = { + show: true, + barWidth: 22 * 60 * 60 * 7 * 1000, + align: 'center', + }; + } + var plot = $.plot(element, [response.data], options); - var format_message = function (timestamp, measurement) { - var unit = measurement == 1 ? response.unit : response.unit_plural; - return utils.formatTimestamp(timestamp, response.period) + '
' + measurement + ' ' + unit; - }; + var format_message = function (timestamp, measurement) { + var unit = measurement == 1 ? response.unit : response.unit_plural; + return ( + utils.formatTimestamp(timestamp, response.period) + + '
' + + measurement + + ' ' + + unit + ); + }; - var previousPoint = null; - element.bind("plothover", function (event, pos, item) { - if (item) { - if (previousPoint != item.dataIndex) { - previousPoint = item.dataIndex; - hover.hide(); - var x, y; - var message = format_message.apply(null, item.datapoint); - if (response.period == 'instant') { - x = item.pageX + 10; - y = item.pageY + 10; - } else { - // I'd like this hover to be centered over the bar. This - // simple math sorta works, but it assumes a *lot* about - // the plot and basically won't scale. Grr. - x = item.pageX - 40; - y = item.pageY - 50; - } - hover.show(x, y, message); - } - } else { - hover.hide(); - previousPoint = null; - } - }); - }); + var previousPoint = null; + element.bind('plothover', function (event, pos, item) { + if (item) { + if (previousPoint != item.dataIndex) { + previousPoint = item.dataIndex; + hover.hide(); + var x, y; + var message = format_message.apply(null, item.datapoint); + if (response.period == 'instant') { + x = item.pageX + 10; + y = item.pageY + 10; + } else { + // I'd like this hover to be centered over the bar. This + // simple math sorta works, but it assumes a *lot* about + // the plot and basically won't scale. Grr. + x = item.pageX - 40; + y = item.pageY - 50; + } + hover.show(x, y, message); + } + } else { + hover.hide(); + previousPoint = null; + } + }); }); + }); }); diff --git a/djangoproject/static/js/dashboard/index.js b/djangoproject/static/js/dashboard/index.js index eae102392..de1225072 100644 --- a/djangoproject/static/js/dashboard/index.js +++ b/djangoproject/static/js/dashboard/index.js @@ -1,44 +1,48 @@ -define('dashboard/index', ['jquery', 'jquery.flot', 'dashboard/utils'], function ($, flot, utils) { - $(function () { - $(".metric .sparkline").each(function (index, elem) { - var element = $(elem); - var valueElement = element.parent().find('.value a'); - var timestampElement = element.parent().find('.timestamp'); - var originalValue = valueElement.html(); - var green = '#93D7B7'; +define('dashboard/index', [ + 'jquery', + 'jquery.flot', + 'dashboard/utils', +], function ($, flot, utils) { + $(function () { + $('.metric .sparkline').each(function (index, elem) { + var element = $(elem); + var valueElement = element.parent().find('.value a'); + var timestampElement = element.parent().find('.timestamp'); + var originalValue = valueElement.html(); + var green = '#93D7B7'; - var url = element.data('path') + element.data('metric') + ".json"; - $.getJSON(url, function (response) { - response.data = utils.convertSecondsToMilliseconds(response.data); - $.plot(element, [response.data], { - xaxis: {show: false, mode: "time"}, - yaxis: {show: false, min: 0}, - grid: {borderWidth: 0, hoverable: true}, - colors: [green], - bars: { - show: true, - barWidth: (response.period == 'daily' ? 24 * 60 * 60 * 1000 : 24 * 60 * 60 * 7 * 1000), - fillColor: green, - lineWidth: 1, - align: "center" - } - }); + var url = element.data('path') + element.data('metric') + '.json'; + $.getJSON(url, function (response) { + response.data = utils.convertSecondsToMilliseconds(response.data); + $.plot(element, [response.data], { + xaxis: { show: false, mode: 'time' }, + yaxis: { show: false, min: 0 }, + grid: { borderWidth: 0, hoverable: true }, + colors: [green], + bars: { + show: true, + barWidth: + response.period == 'daily' + ? 24 * 60 * 60 * 1000 + : 24 * 60 * 60 * 7 * 1000, + fillColor: green, + lineWidth: 1, + align: 'center', + }, + }); - element.bind('plothover', function (event, pos, item) { - if (item) { - valueElement.html(item.datapoint[1]); - timestampElement.html( - utils.formatTimestamp( - item.datapoint[0], - response.period - ) - ); - } else { - valueElement.html(originalValue); - timestampElement.html(' '); - } - }); - }); + element.bind('plothover', function (event, pos, item) { + if (item) { + valueElement.html(item.datapoint[1]); + timestampElement.html( + utils.formatTimestamp(item.datapoint[0], response.period), + ); + } else { + valueElement.html(originalValue); + timestampElement.html(' '); + } }); + }); }); + }); }); diff --git a/djangoproject/static/js/dashboard/utils.js b/djangoproject/static/js/dashboard/utils.js index 9f66475d6..75d6c1595 100644 --- a/djangoproject/static/js/dashboard/utils.js +++ b/djangoproject/static/js/dashboard/utils.js @@ -1,25 +1,29 @@ define('dashboard/utils', ['jquery'], function ($) { - return { - formatTimestamp: function formatTimestamp(timestamp, period) { - var d = new Date(timestamp); - if (period == 'instant') { - return $.plot.formatDate(d, "%b %d, %h:%M %p"); - } else if (period == 'daily') { - return $.plot.formatDate(d, "%b %d"); - } else if (period == 'weekly') { - // A bit more complicated than the above: the timestamp is in the - // middle of the week, so we have to bracket the date. This is - // something of a fudge here, but it works well enough. - var start = new Date(d.getTime() - (3 * 24 * 60 * 60 * 1000)); - var end = new Date(d.getTime() + (3 * 24 * 60 * 60 * 1000)); - return $.plot.formatDate(start, "%b %d") + ' - ' + $.plot.formatDate(end, "%b %d"); - } - }, - convertSecondsToMilliseconds: function convertSecondsToMilliseconds(data) { - for (var i = 0; i < data.length; i++) { - data[i][0] = data[i][0] * 1000; - } - return data; - } - }; + return { + formatTimestamp: function formatTimestamp(timestamp, period) { + var d = new Date(timestamp); + if (period == 'instant') { + return $.plot.formatDate(d, '%b %d, %h:%M %p'); + } else if (period == 'daily') { + return $.plot.formatDate(d, '%b %d'); + } else if (period == 'weekly') { + // A bit more complicated than the above: the timestamp is in the + // middle of the week, so we have to bracket the date. This is + // something of a fudge here, but it works well enough. + var start = new Date(d.getTime() - 3 * 24 * 60 * 60 * 1000); + var end = new Date(d.getTime() + 3 * 24 * 60 * 60 * 1000); + return ( + $.plot.formatDate(start, '%b %d') + + ' - ' + + $.plot.formatDate(end, '%b %d') + ); + } + }, + convertSecondsToMilliseconds: function convertSecondsToMilliseconds(data) { + for (var i = 0; i < data.length; i++) { + data[i][0] = data[i][0] * 1000; + } + return data; + }, + }; }); diff --git a/djangoproject/static/js/main.js b/djangoproject/static/js/main.js index 9dd2c5205..983a4918a 100644 --- a/djangoproject/static/js/main.js +++ b/djangoproject/static/js/main.js @@ -1,81 +1,81 @@ // Require.js Module Loader - http://requirejs.org -define(function() { - var mods = [ - 'mod/mobile-menu', // require mobile menu automatically - ]; - - //detect Class function - function hasClass( className ) { - return !!document.getElementsByClassName( className ).length; //return a boolean - } - - //feature list - if (hasClass('list-features')) { - mods.push('mod/list-feature'); - } - - //collapsing list - if (hasClass('list-collapsing')) { - mods.push('mod/list-collapsing'); - } - - if (hasClass('version-switcher')) { - mods.push('mod/version-switcher'); - } - - if (hasClass('doc-switcher')) { - mods.push('mod/doc-switcher'); - } - - if (hasClass('doc-floating-warning')) { - mods.push('mod/floating-warning'); - } - - //fundraising heart - if (hasClass('fundraising-heart')) { - mods.push('mod/fundraising-heart'); - } - //fundraising donation form - if (hasClass('fundraising-index')) { - mods.push('mod/fundraising-index'); - } - - if (hasClass('dashboard-index')) { - mods.push('dashboard/index'); - } - - if (hasClass('dashboard-detail')) { - mods.push('dashboard/detail'); - } - - // search form - if (hasClass('search')) { - mods.push('mod/search-key'); - } - - if (hasClass('stripe-donation')) { - mods.push('mod/stripe-donation'); - } - - if (hasClass('django-hero-form')) { - mods.push('mod/stripe-change-card'); - } - - if (hasClass('corporate-membership-join-form')) { - mods.push('mod/corporate-member-join'); - } - - if (hasClass('messages')) { - mods.push('mod/messages'); - } - - if (hasClass('code-block-caption') || hasClass('snippet')) { - mods.push('mod/clippify'); - } - - if (hasClass('console-block')) { - mods.push('mod/console-tabs'); - } - - require(mods); +define(function () { + var mods = [ + 'mod/mobile-menu', // require mobile menu automatically + ]; + + //detect Class function + function hasClass(className) { + return !!document.getElementsByClassName(className).length; //return a boolean + } + + //feature list + if (hasClass('list-features')) { + mods.push('mod/list-feature'); + } + + //collapsing list + if (hasClass('list-collapsing')) { + mods.push('mod/list-collapsing'); + } + + if (hasClass('version-switcher')) { + mods.push('mod/version-switcher'); + } + + if (hasClass('doc-switcher')) { + mods.push('mod/doc-switcher'); + } + + if (hasClass('doc-floating-warning')) { + mods.push('mod/floating-warning'); + } + + //fundraising heart + if (hasClass('fundraising-heart')) { + mods.push('mod/fundraising-heart'); + } + //fundraising donation form + if (hasClass('fundraising-index')) { + mods.push('mod/fundraising-index'); + } + + if (hasClass('dashboard-index')) { + mods.push('dashboard/index'); + } + + if (hasClass('dashboard-detail')) { + mods.push('dashboard/detail'); + } + + // search form + if (hasClass('search')) { + mods.push('mod/search-key'); + } + + if (hasClass('stripe-donation')) { + mods.push('mod/stripe-donation'); + } + + if (hasClass('django-hero-form')) { + mods.push('mod/stripe-change-card'); + } + + if (hasClass('corporate-membership-join-form')) { + mods.push('mod/corporate-member-join'); + } + + if (hasClass('messages')) { + mods.push('mod/messages'); + } + + if (hasClass('code-block-caption') || hasClass('snippet')) { + mods.push('mod/clippify'); + } + + if (hasClass('console-block')) { + mods.push('mod/console-tabs'); + } + + require(mods); }); diff --git a/djangoproject/static/js/mod/clippify.js b/djangoproject/static/js/mod/clippify.js index 6e8023213..47c4a22b1 100644 --- a/djangoproject/static/js/mod/clippify.js +++ b/djangoproject/static/js/mod/clippify.js @@ -1,37 +1,39 @@ -define(['jquery'], function($) { - $('.code-block-caption').each(function() { - var header = $(this); - var wrapper = header.parent(); - var code = $('.highlight', wrapper); - var btn = $(''); - btn.append(''); - btn.data('clipboard-text', $.trim(code.text())); - header.append(btn); - }); - // For Django 2.0 docs and older. - $('.snippet').each(function() { - var code = $('.highlight', this); - var btn = $(''); - var header = $('.snippet-filename', this); +define(['jquery'], function ($) { + $('.code-block-caption').each(function () { + var header = $(this); + var wrapper = header.parent(); + var code = $('.highlight', wrapper); + var btn = $(''); + btn.append(''); + btn.data('clipboard-text', $.trim(code.text())); + header.append(btn); + }); + // For Django 2.0 docs and older. + $('.snippet').each(function () { + var code = $('.highlight', this); + var btn = $(''); + var header = $('.snippet-filename', this); - btn.append(''); - btn.data('clipboard-text', $.trim(code.text())); - header.append(btn); - }); - $('.btn-clipboard').click(function() { - var btn = $(this); - var text = btn.data('clipboard-text'); + btn.append(''); + btn.data('clipboard-text', $.trim(code.text())); + header.append(btn); + }); + $('.btn-clipboard').click(function () { + var btn = $(this); + var text = btn.data('clipboard-text'); - function on_success(el) { - var success = $('').text('Copied!') - success.prependTo(btn).delay(1000).fadeOut(); - } + function on_success(el) { + var success = $('').text('Copied!'); + success.prependTo(btn).delay(1000).fadeOut(); + } - function on_error(el) { - var success = $('').text('Could not copy!'); - success.prependTo(btn).delay(5000).fadeOut(); - } + function on_error(el) { + var success = $('').text( + 'Could not copy!', + ); + success.prependTo(btn).delay(5000).fadeOut(); + } - navigator.clipboard.writeText(text).then(on_success, on_error); - }); + navigator.clipboard.writeText(text).then(on_success, on_error); + }); }); diff --git a/djangoproject/static/js/mod/console-tabs.js b/djangoproject/static/js/mod/console-tabs.js index f7f10c2f5..2f6a10249 100644 --- a/djangoproject/static/js/mod/console-tabs.js +++ b/djangoproject/static/js/mod/console-tabs.js @@ -1,30 +1,27 @@ -define([ - 'jquery', -], function( $ ) { +define(['jquery'], function ($) { + var ConsoleBlock = function (class_name) { + this.console_blocks = $(class_name); + this.init(); + }; - var ConsoleBlock = function(class_name) { - this.console_blocks = $(class_name); - this.init(); - }; + ConsoleBlock.prototype = { + init: function () { + var self = this; + $(document).ready(function () { + $('.c-tab-unix').on('click', function () { + $('section.c-content-unix').show(); + $('section.c-content-win').hide(); + $('.c-tab-unix').prop('checked', true); + }); + $('.c-tab-win').on('click', function () { + $('section.c-content-win').show(); + $('section.c-content-unix').hide(); + $('.c-tab-win').prop('checked', true); + }); + }); + }, + }; - ConsoleBlock.prototype = { - init: function(){ - var self = this; - $(document).ready(function () { - $(".c-tab-unix").on("click", function() { - $("section.c-content-unix").show(); - $("section.c-content-win").hide(); - $(".c-tab-unix").prop("checked", true); - }); - $(".c-tab-win").on("click", function() { - $("section.c-content-win").show(); - $("section.c-content-unix").hide(); - $(".c-tab-win").prop("checked", true); - }); - }); - } - }; - - // Export a single instance of our module: - return new ConsoleBlock('.console-block'); + // Export a single instance of our module: + return new ConsoleBlock('.console-block'); }); diff --git a/djangoproject/static/js/mod/corporate-member-join.js b/djangoproject/static/js/mod/corporate-member-join.js index 083c050a3..9a3d1bd7d 100644 --- a/djangoproject/static/js/mod/corporate-member-join.js +++ b/djangoproject/static/js/mod/corporate-member-join.js @@ -1,52 +1,52 @@ -define(['jquery'], function($) { - var CorporateMembershipJoinForm = function(form) { - this.form = $(form); - this.init(); - }; - CorporateMembershipJoinForm.prototype = { - init: function() { - var self = this; - var $amount = self.form.find('#id_amount'); - var $membershipLevel = self.form.find('#id_membership_level'); - $amount.change(function() { - self.setMembershipLevel($(this), $membershipLevel); - }); - $membershipLevel.change(function() { - self.setDonationAmount($(this), $amount); - }); - }, - setDonationAmount: function($membershipLevel, $amount) { - var selectedMembership = $membershipLevel.val(); - if (selectedMembership == '5') { - $amount.val(100000); - } else if (selectedMembership == '4') { - $amount.val(30000); - } else if (selectedMembership == '3') { - $amount.val(12500); - } else if (selectedMembership == '2') { - $amount.val(5000); - } else if (selectedMembership == '1') { - $amount.val(2000); - } else { - $amount.val(''); - } - }, - setMembershipLevel: function($amount, $membershipLevel) { - var amount = parseInt($amount.val()); - if (amount >= 100000) { - $membershipLevel.val(5); - } else if (amount >= 30000) { - $membershipLevel.val(4); - } else if (amount >= 12500) { - $membershipLevel.val(3); - } else if (amount >= 5000) { - $membershipLevel.val(2); - } else if (amount >= 2000) { - $membershipLevel.val(1); - } else { - $membershipLevel.val(''); - } - }, - }; - return new CorporateMembershipJoinForm('.corporate-membership-join-form'); +define(['jquery'], function ($) { + var CorporateMembershipJoinForm = function (form) { + this.form = $(form); + this.init(); + }; + CorporateMembershipJoinForm.prototype = { + init: function () { + var self = this; + var $amount = self.form.find('#id_amount'); + var $membershipLevel = self.form.find('#id_membership_level'); + $amount.change(function () { + self.setMembershipLevel($(this), $membershipLevel); + }); + $membershipLevel.change(function () { + self.setDonationAmount($(this), $amount); + }); + }, + setDonationAmount: function ($membershipLevel, $amount) { + var selectedMembership = $membershipLevel.val(); + if (selectedMembership == '5') { + $amount.val(100000); + } else if (selectedMembership == '4') { + $amount.val(30000); + } else if (selectedMembership == '3') { + $amount.val(12500); + } else if (selectedMembership == '2') { + $amount.val(5000); + } else if (selectedMembership == '1') { + $amount.val(2000); + } else { + $amount.val(''); + } + }, + setMembershipLevel: function ($amount, $membershipLevel) { + var amount = parseInt($amount.val()); + if (amount >= 100000) { + $membershipLevel.val(5); + } else if (amount >= 30000) { + $membershipLevel.val(4); + } else if (amount >= 12500) { + $membershipLevel.val(3); + } else if (amount >= 5000) { + $membershipLevel.val(2); + } else if (amount >= 2000) { + $membershipLevel.val(1); + } else { + $membershipLevel.val(''); + } + }, + }; + return new CorporateMembershipJoinForm('.corporate-membership-join-form'); }); diff --git a/djangoproject/static/js/mod/doc-switcher.js b/djangoproject/static/js/mod/doc-switcher.js index 30e1afa74..081d60664 100644 --- a/djangoproject/static/js/mod/doc-switcher.js +++ b/djangoproject/static/js/mod/doc-switcher.js @@ -1,25 +1,24 @@ define([ - 'jquery' //requires jquery -], function( $ ) { + 'jquery', //requires jquery +], function ($) { + var DocSwitcher = function (switchers) { + this.switchers = $(switchers); + this.init(); + }; - var DocSwitcher = function(switchers) { - this.switchers = $(switchers); - this.init(); - }; + DocSwitcher.prototype = { + init: function () { + var self = this; + $(document).ready(function () { + // Make version switcher clickable for touch devices - DocSwitcher.prototype = { - init: function(){ - var self = this; - $(document).ready(function () { - // Make version switcher clickable for touch devices + self.switchers.find('li.current').on('click', function () { + $(this).closest('ul').toggleClass('open'); + }); + }); + }, + }; - self.switchers.find('li.current').on('click', function () { - $(this).closest("ul").toggleClass('open'); - }); - }); - } - }; - - // Export a single instance of our module: - return new DocSwitcher('.doc-switcher'); + // Export a single instance of our module: + return new DocSwitcher('.doc-switcher'); }); diff --git a/djangoproject/static/js/mod/floating-warning.js b/djangoproject/static/js/mod/floating-warning.js index 2d8d1635f..1e0c8adde 100644 --- a/djangoproject/static/js/mod/floating-warning.js +++ b/djangoproject/static/js/mod/floating-warning.js @@ -1,45 +1,44 @@ define([ - 'jquery' //requires jquery -], function( $ ) { + 'jquery', //requires jquery +], function ($) { + var FloatingWarning = function (warning) { + this.warning = $(warning); // the floating warning div + this.init(); + }; - var FloatingWarning = function(warning) { - this.warning = $(warning); // the floating warning div - this.init(); - }; + FloatingWarning.prototype = { + init: function () { + var self = this; + $(document).ready(function () { + // Clone warning to top of document, without fixed positioning, + // to force correct spacing of header. + self.warning.clone().prependTo('body').css('position', 'relative'); - FloatingWarning.prototype = { - init: function(){ - var self = this; - $(document).ready(function () { - // Clone warning to top of document, without fixed positioning, - // to force correct spacing of header. - self.warning.clone().prependTo('body').css('position', 'relative'); + setTimeout(function () { + self.scroll(window.location.hash, self.warning); + }, 50); // use a delay that should work on all modern computers. should, not will - setTimeout(function () { - self.scroll(window.location.hash, self.warning); - }, 50); // use a delay that should work on all modern computers. should, not will - - // use something nicer - $(window).on('hashchange', function() { - self.scroll(window.location.hash, self.warning); - }); - }); - }, - scroll: function(hash, warning) { - // is there a hash in the current window's location? - if (hash) { - // again, get the target - var target = $("[id='" + hash.slice(1) + "']"); - if (target.length) { - // calculate the offset - var targetOffset = target.offset().top - warning.height() - 20; - // scroll to the place - $('html,body').scrollTop(targetOffset); - } - } + // use something nicer + $(window).on('hashchange', function () { + self.scroll(window.location.hash, self.warning); + }); + }); + }, + scroll: function (hash, warning) { + // is there a hash in the current window's location? + if (hash) { + // again, get the target + var target = $("[id='" + hash.slice(1) + "']"); + if (target.length) { + // calculate the offset + var targetOffset = target.offset().top - warning.height() - 20; + // scroll to the place + $('html,body').scrollTop(targetOffset); } - }; + } + }, + }; - // Export a single instance of our module: - return new FloatingWarning('.doc-floating-warning'); + // Export a single instance of our module: + return new FloatingWarning('.doc-floating-warning'); }); diff --git a/djangoproject/static/js/mod/fundraising-heart.js b/djangoproject/static/js/mod/fundraising-heart.js index 797216767..18a1b043b 100644 --- a/djangoproject/static/js/mod/fundraising-heart.js +++ b/djangoproject/static/js/mod/fundraising-heart.js @@ -1,119 +1,120 @@ -define([ - 'jquery', -], function( $ ) { +define(['jquery'], function ($) { + var maroon = '#ad1d45'; + var amaranth = '#d9195c'; + var cerise = '#d62d75'; + var razzmatazz = '#ee2178'; + var illusion = '#f7b0cf'; + var pixels = [ + // Row 1 + { x: 1, y: 0, color: maroon }, + { x: 2, y: 0, color: amaranth }, + { x: 4, y: 0, color: amaranth }, + { x: 5, y: 0, color: cerise }, - var maroon = '#ad1d45'; - var amaranth = '#d9195c'; - var cerise = '#d62d75'; - var razzmatazz = '#ee2178'; - var illusion = '#f7b0cf'; - var pixels = [ - // Row 1 - {x:1, y: 0, color: maroon}, - {x:2, y: 0, color: amaranth}, - {x:4, y: 0, color: amaranth}, - {x:5, y: 0, color: cerise}, + // Row 2 + { x: 0, y: 1, color: amaranth }, + { x: 1, y: 1, color: razzmatazz }, + { x: 2, y: 1, color: razzmatazz }, + { x: 3, y: 1, color: amaranth }, + { x: 4, y: 1, color: razzmatazz }, + { x: 5, y: 1, color: illusion }, + { x: 6, y: 1, color: maroon }, - // Row 2 - {x:0, y: 1, color: amaranth}, - {x:1, y: 1, color: razzmatazz}, - {x:2, y: 1, color: razzmatazz}, - {x:3, y: 1, color: amaranth}, - {x:4, y: 1, color: razzmatazz}, - {x:5, y: 1, color: illusion}, - {x:6, y: 1, color: maroon}, + // Row 3 + { x: 0, y: 2, color: cerise }, + { x: 1, y: 2, color: amaranth }, + { x: 2, y: 2, color: amaranth }, + { x: 3, y: 2, color: maroon }, + { x: 4, y: 2, color: amaranth }, + { x: 5, y: 2, color: cerise }, + { x: 6, y: 2, color: maroon }, - // Row 3 - {x:0, y: 2, color: cerise}, - {x:1, y: 2, color: amaranth}, - {x:2, y: 2, color: amaranth}, - {x:3, y: 2, color: maroon}, - {x:4, y: 2, color: amaranth}, - {x:5, y: 2, color: cerise}, - {x:6, y: 2, color: maroon}, + // Row 4 + { x: 1, y: 3, color: maroon }, + { x: 2, y: 3, color: razzmatazz }, + { x: 3, y: 3, color: amaranth }, + { x: 4, y: 3, color: razzmatazz }, + { x: 5, y: 3, color: amaranth }, - // Row 4 - {x:1, y: 3, color: maroon}, - {x:2, y: 3, color: razzmatazz}, - {x:3, y: 3, color: amaranth}, - {x:4, y: 3, color: razzmatazz}, - {x:5, y: 3, color: amaranth}, + // Row 5 + { x: 2, y: 4, color: amaranth }, + { x: 3, y: 4, color: cerise }, + { x: 4, y: 4, color: amaranth }, - // Row 5 - {x:2, y: 4, color: amaranth}, - {x:3, y: 4, color: cerise}, - {x:4, y: 4, color: amaranth}, + // Row 6 + { x: 3, y: 5, color: razzmatazz }, + ]; - // Row 6 - {x:3, y: 5, color: razzmatazz}, - ]; + var Heart = function (heart) { + this.heart = $(heart); + this.init(); + }; - var Heart = function(heart) { - this.heart = $(heart); - this.init(); - }; + Heart.prototype = { + init: function () { + this.pixels = pixels.map(function (pixel) { + return new Rectangle(pixel); + }); + this.fadePixels(); + this.draw(); + var heart = this; + }, + fadePixels: function () { + var pixels; + var percent = this.heart.data('percent'); + var fadedCount = Math.ceil((this.pixels.length * (100 - percent)) / 100); + for (var i = 0; i < fadedCount; i++) { + pixels = this.visiblePixels(); + pixels[0].hide(); + } + }, + hiddenPixels: function () { + return this.pixels.filter(function (p) { + return p.isHidden; + }); + }, + visiblePixels: function () { + return this.pixels.filter(function (p) { + return !p.isHidden; + }); + }, + draw: function () { + this.pixels.forEach(function (p) { + document.getElementById('pixels').appendChild(p.element); + }); + }, + }; - Heart.prototype = { - init: function() { - this.pixels = pixels.map(function (pixel) { - return new Rectangle(pixel); - }); - this.fadePixels(); - this.draw(); - var heart = this; - }, - fadePixels: function () { - var pixels; - var percent = this.heart.data('percent'); - var fadedCount = Math.ceil(this.pixels.length * (100 - percent) / 100); - for (var i = 0; i < fadedCount; i++) { - pixels = this.visiblePixels(); - pixels[0].hide(); - } - }, - hiddenPixels: function () { - return this.pixels.filter(function (p) { return p.isHidden; }); - }, - visiblePixels: function () { - return this.pixels.filter(function (p) { return !p.isHidden; }); - }, - draw: function() { - this.pixels.forEach(function (p) { - document.getElementById('pixels').appendChild(p.element); - }); - } - }; - - var Rectangle = function (opts) { + var Rectangle = function (opts) { var namespace = 'http://www.w3.org/2000/svg'; - this.element = document.createElementNS(namespace, 'rect'); - this.size = 71; - this.init(opts); - }; + this.element = document.createElementNS(namespace, 'rect'); + this.size = 71; + this.init(opts); + }; - Rectangle.prototype = { - init: function(opts) { - this.isHidden = false; - this.setAttr('x', opts.x * this.size); - this.setAttr('y', opts.y * this.size); - this.setAttr('width', this.size); - this.setAttr('height', this.size); - this.setAttr('fill', opts.color); - this.element.style.animationDelay = 3 * Math.random() + "s"; - }, - setAttr: function(name, value) { - this.element.setAttributeNS(null, name, value); - }, - hide: function () { - this.isHidden = true; - this.setAttr('class', 'faded'); - }, - show: function () { - this.isHidden = false; - this.setAttr('class', ''); - } - }; + Rectangle.prototype = { + init: function (opts) { + this.isHidden = false; + this.setAttr('x', opts.x * this.size); + this.setAttr('y', opts.y * this.size); + this.setAttr('width', this.size); + this.setAttr('height', this.size); + this.setAttr('fill', opts.color); + this.element.style.animationDelay = 3 * Math.random() + 's'; + }, + setAttr: function (name, value) { + this.element.setAttributeNS(null, name, value); + }, + hide: function () { + this.isHidden = true; + this.setAttr('class', 'faded'); + }, + show: function () { + this.isHidden = false; + this.setAttr('class', ''); + }, + }; - // Export a single instance of our module: - return new Heart('.fundraising-heart'); + // Export a single instance of our module: + return new Heart('.fundraising-heart'); }); diff --git a/djangoproject/static/js/mod/fundraising-index.js b/djangoproject/static/js/mod/fundraising-index.js index a3104ac08..6a0254cff 100644 --- a/djangoproject/static/js/mod/fundraising-index.js +++ b/djangoproject/static/js/mod/fundraising-index.js @@ -1,42 +1,46 @@ define([ - 'jquery' //requires jquery - ], function( $ ) { + 'jquery', //requires jquery +], function ($) { + var FundraisingIndex = function (form) { + this.form = $(form); // the floating warning div + this.init(); + }; - var FundraisingIndex = function(form) { - this.form = $(form); // the floating warning div - this.init(); - }; + FundraisingIndex.prototype = { + init: function () { + var self = this; + $(document).ready(function () { + self.form.find('select').on('change', self.setDonation); + self.form + .find('select') + .on('change', self.setDonateButtonText) + .change(); + }); + }, + setDonation: function (event) { + if ($(this).val() == 'custom') { + $(this).remove(); + $('.custom-donation') + .append('') + .show(); + var input = $('.custom-donation input'); + input.focus(); + // here we're moving the "focus" at the end of the input text + var tmpStr = input.val(); + input.val(''); + input.val(tmpStr); + } + }, + setDonateButtonText: function (event) { + var text = 'Donate'; + var interval = $('#id_interval').val(); + if (interval != 'onetime') { + text += ' ' + interval; + } + $('#donate-button').val(text); + }, + }; - FundraisingIndex.prototype = { - init: function(){ - var self = this; - $(document).ready(function() { - self.form.find('select').on("change", self.setDonation); - self.form.find('select').on("change", self.setDonateButtonText).change(); - }); - }, - setDonation: function(event){ - if ($(this).val() == 'custom'){ - $(this).remove(); - $('.custom-donation').append('').show(); - var input = $('.custom-donation input'); - input.focus(); - // here we're moving the "focus" at the end of the input text - var tmpStr = input.val(); - input.val(''); - input.val(tmpStr); - } - }, - setDonateButtonText: function(event) { - var text = 'Donate'; - var interval = $('#id_interval').val(); - if (interval != 'onetime') { - text += ' ' + interval; - } - $('#donate-button').val(text); - } - }; - - // Export a single instance of our module: - return new FundraisingIndex('.fundraising-index form'); - }); + // Export a single instance of our module: + return new FundraisingIndex('.fundraising-index form'); +}); diff --git a/djangoproject/static/js/mod/list-collapsing.js b/djangoproject/static/js/mod/list-collapsing.js index 1d8b7ba82..e27bf009a 100644 --- a/djangoproject/static/js/mod/list-collapsing.js +++ b/djangoproject/static/js/mod/list-collapsing.js @@ -1,57 +1,62 @@ define([ - 'jquery' //requires jquery -], function( $ ) { - - var CollapsingList = function(list) { - this.list = $(list); - this.init(); - }; - - var hash = window.location.hash; - - CollapsingList.prototype = { - init: function(){ - var self = this; //self = this for functions - - this.items = this.list.children('li'); //get items - this.headings = this.items.children('h2'); //get headings - - this.buttonExpand = $('Expand All'); //build buttons - this.buttonCollapse = $('Collapse All'); //build buttons - this.buttonContainer = $('').insertBefore(this.list); //create a button container - this.buttonContainer //append container to label - .append(this.buttonExpand) - .append(' / ') - .append(this.buttonCollapse); - - this.list.addClass('active'); //activate the list styles w/ class - this.headings.append(' ').attr('tabindex', '0'); //add icons and tabindexes - - this.headings.on( 'click', function( ev ) { //headings onclick (passing event) - var target = $(ev.target).closest('h2'), - parent = target.closest('li'); //store target as var - parent.toggleClass('active'); //toggle active class - }); - - this.buttonExpand.on( 'click', function() { //expand all onclick - self.items.addClass('active'); - }); - this.buttonCollapse.on( 'click', function() { //expand all onclick - self.items.removeClass('active'); - }); - - //expand list item with matching hash id - if (hash) { - $(hash).addClass('active'); - var pos = $(hash).position(); - $(window).scrollTop(pos.top); - } - - } - }; - - //return a new module for each class detected - $('.list-collapsing').each(function(){ - return new CollapsingList(this); - }); + 'jquery', //requires jquery +], function ($) { + var CollapsingList = function (list) { + this.list = $(list); + this.init(); + }; + + var hash = window.location.hash; + + CollapsingList.prototype = { + init: function () { + var self = this; //self = this for functions + + this.items = this.list.children('li'); //get items + this.headings = this.items.children('h2'); //get headings + + this.buttonExpand = $('Expand All'); //build buttons + this.buttonCollapse = $('Collapse All'); //build buttons + this.buttonContainer = $( + '', + ).insertBefore(this.list); //create a button container + this.buttonContainer //append container to label + .append(this.buttonExpand) + .append(' / ') + .append(this.buttonCollapse); + + this.list.addClass('active'); //activate the list styles w/ class + this.headings + .append(' ') + .attr('tabindex', '0'); //add icons and tabindexes + + this.headings.on('click', function (ev) { + //headings onclick (passing event) + var target = $(ev.target).closest('h2'), + parent = target.closest('li'); //store target as var + parent.toggleClass('active'); //toggle active class + }); + + this.buttonExpand.on('click', function () { + //expand all onclick + self.items.addClass('active'); + }); + this.buttonCollapse.on('click', function () { + //expand all onclick + self.items.removeClass('active'); + }); + + //expand list item with matching hash id + if (hash) { + $(hash).addClass('active'); + var pos = $(hash).position(); + $(window).scrollTop(pos.top); + } + }, + }; + + //return a new module for each class detected + $('.list-collapsing').each(function () { + return new CollapsingList(this); + }); }); diff --git a/djangoproject/static/js/mod/list-feature.js b/djangoproject/static/js/mod/list-feature.js index 77d446e03..b7eab8358 100644 --- a/djangoproject/static/js/mod/list-feature.js +++ b/djangoproject/static/js/mod/list-feature.js @@ -1,17 +1,20 @@ define(['jquery'], function ($) { - const observer = new IntersectionObserver(function (entries) { - entries.forEach(function (entry) { - if (!entry.isIntersecting) { - return; - } + const observer = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting) { + return; + } - $(entry.target).addClass('inview'); + $(entry.target).addClass('inview'); - observer.unobserve(entry.target); - }); - }, { threshold: 1.0 }); // Trigger when the element is fully visible + observer.unobserve(entry.target); + }); + }, + { threshold: 1.0 }, + ); // Trigger when the element is fully visible - $('.list-features i').each(function () { - observer.observe(this); - }); + $('.list-features i').each(function () { + observer.observe(this); + }); }); diff --git a/djangoproject/static/js/mod/messages.js b/djangoproject/static/js/mod/messages.js index f998b7687..c6728d5e0 100644 --- a/djangoproject/static/js/mod/messages.js +++ b/djangoproject/static/js/mod/messages.js @@ -1,9 +1,7 @@ define([ - 'jquery' //requires jquery -], function( $ ) { - $('.messages li').on('click', '.close', function() { - $(this).parents('.messages > li').fadeOut(); - }); + 'jquery', //requires jquery +], function ($) { + $('.messages li').on('click', '.close', function () { + $(this).parents('.messages > li').fadeOut(); + }); }); - - diff --git a/djangoproject/static/js/mod/mobile-menu.js b/djangoproject/static/js/mod/mobile-menu.js index b707c9185..c3364abe3 100644 --- a/djangoproject/static/js/mod/mobile-menu.js +++ b/djangoproject/static/js/mod/mobile-menu.js @@ -1,23 +1,22 @@ define([ - 'jquery' //requires jquery -], function( $ ) { + 'jquery', //requires jquery +], function ($) { + var MobileMenuExport = function (menu) { + this.menu = $(menu); //menu container + this.toggleMenuBtn = $('.menu-button'); + this.init(); + }; - var MobileMenuExport = function(menu) { - this.menu = $(menu); //menu container - this.toggleMenuBtn = $('.menu-button') - this.init(); - }; + MobileMenuExport.prototype = { + init: function () { + var self = this; + self.toggleMenuBtn.on('click', function () { + self.menu.toggleClass('active'); + self.toggleMenuBtn.toggleClass('active'); + }); + }, + }; - MobileMenuExport.prototype = { - init: function(){ - var self = this; - self.toggleMenuBtn.on( 'click', function(){ - self.menu.toggleClass('active'); - self.toggleMenuBtn.toggleClass('active'); - }); - } - }; - - // Export a single instance of our module: - return new MobileMenuExport('[role="banner"] [role="navigation"]'); + // Export a single instance of our module: + return new MobileMenuExport('[role="banner"] [role="navigation"]'); }); diff --git a/djangoproject/static/js/mod/search-key.js b/djangoproject/static/js/mod/search-key.js index a5f95b9f9..abdcd5074 100644 --- a/djangoproject/static/js/mod/search-key.js +++ b/djangoproject/static/js/mod/search-key.js @@ -1,31 +1,42 @@ define([ - 'jquery' //requires jquery -], function( $ ) { - const SearchForm = function(search_form) { - this.search_form = $(search_form); // the search form - this.init(); - }; + 'jquery', //requires jquery +], function ($) { + const SearchForm = function (search_form) { + this.search_form = $(search_form); // the search form + this.init(); + }; - SearchForm.prototype = { - init: function(){ - const self = this; - $(document).ready(function () { - const search_form_input = self.search_form.find('input'); - const raw_placeholder = search_form_input.attr('placeholder'); - const shortcut = navigator.userAgent.indexOf("Mac") === -1 ? "Ctrl + K" : "⌘ + K"; - search_form_input.attr('placeholder', `${raw_placeholder} (${shortcut})`); + SearchForm.prototype = { + init: function () { + const self = this; + $(document).ready(function () { + const search_form_input = self.search_form.find('input'); + const raw_placeholder = search_form_input.attr('placeholder'); + const shortcut = + navigator.userAgent.indexOf('Mac') === -1 ? 'Ctrl + K' : '⌘ + K'; + search_form_input.attr( + 'placeholder', + `${raw_placeholder} (${shortcut})`, + ); - $(window).keydown(function(e) { - if ((e.metaKey || e.ctrlKey) && e.key === 'k' && $('input:focus, textarea:focus').length === 0) { - search_form_input.focus().select(); - search_form_input[0].scrollIntoView({ behavior: "smooth", block: "start" }); - return false; - } - }); + $(window).keydown(function (e) { + if ( + (e.metaKey || e.ctrlKey) && + e.key === 'k' && + $('input:focus, textarea:focus').length === 0 + ) { + search_form_input.focus().select(); + search_form_input[0].scrollIntoView({ + behavior: 'smooth', + block: 'start', }); - } - }; + return false; + } + }); + }); + }, + }; - // Export a single instance of our module: - return new SearchForm('.search'); + // Export a single instance of our module: + return new SearchForm('.search'); }); diff --git a/djangoproject/static/js/mod/stripe-change-card.js b/djangoproject/static/js/mod/stripe-change-card.js index 80c2fdc00..796de17b5 100644 --- a/djangoproject/static/js/mod/stripe-change-card.js +++ b/djangoproject/static/js/mod/stripe-change-card.js @@ -1,42 +1,42 @@ define([ - 'jquery', //requires jquery - 'stripe-checkout' -], function($) { - var $heroForm = $('.django-hero-form'); - $heroForm.on('click', '.change-card', function() { - $this = $(this); - var donationId = $this.data('donationId'); - var handler = StripeCheckout.configure({ - key: $heroForm.data('stripeKey'), - image: $heroForm.data('stripeIcon'), - panelLabel: 'Update', - token: function (token) { - var csrfToken = $heroForm.find('[name=csrfmiddlewaretoken]').val(); - var data = { - 'stripe_token': token.id, - 'donation_id': donationId, - 'csrfmiddlewaretoken': csrfToken - }; - $.ajax({ - type: "POST", - url: $heroForm.data('update-card-url'), - data: data, - dataType: 'json', - success: function (data) { - if (data.success) { - $this.parent().find('.change-card-result').text('Card updated'); - } else { - alert(data.error); - } - }, - }); + 'jquery', //requires jquery + 'stripe-checkout', +], function ($) { + var $heroForm = $('.django-hero-form'); + $heroForm.on('click', '.change-card', function () { + $this = $(this); + var donationId = $this.data('donationId'); + var handler = StripeCheckout.configure({ + key: $heroForm.data('stripeKey'), + image: $heroForm.data('stripeIcon'), + panelLabel: 'Update', + token: function (token) { + var csrfToken = $heroForm.find('[name=csrfmiddlewaretoken]').val(); + var data = { + stripe_token: token.id, + donation_id: donationId, + csrfmiddlewaretoken: csrfToken, + }; + $.ajax({ + type: 'POST', + url: $heroForm.data('update-card-url'), + data: data, + dataType: 'json', + success: function (data) { + if (data.success) { + $this.parent().find('.change-card-result').text('Card updated'); + } else { + alert(data.error); } + }, }); + }, + }); - handler.open({ - name: 'Django Software Foundation', - currency: 'USD', - email: $this.data('donor-email') - }); + handler.open({ + name: 'Django Software Foundation', + currency: 'USD', + email: $this.data('donor-email'), }); -}) + }); +}); diff --git a/djangoproject/static/js/mod/stripe-donation.js b/djangoproject/static/js/mod/stripe-donation.js index b0e9be0c5..b2ee62949 100644 --- a/djangoproject/static/js/mod/stripe-donation.js +++ b/djangoproject/static/js/mod/stripe-donation.js @@ -1,59 +1,58 @@ define([ - 'jquery', //requires - 'stripe' -], function($) { - var $donationForm = $('.stripe-donation'); + 'jquery', //requires + 'stripe', +], function ($) { + var $donationForm = $('.stripe-donation'); - function postToStripe(recaptchaToken) { - var interval = $donationForm.find('[name=interval]').val(); - var amount = $donationForm.find('[name=amount]').val(); - var csrfToken = $donationForm.find('[name=csrfmiddlewaretoken]').val(); - var data = { - 'interval': interval, - 'amount': amount, - 'captcha': recaptchaToken, - 'csrfmiddlewaretoken': csrfToken - } - $.ajax({ - type: "POST", - url: $donationForm.attr('action-for-donation-session'), - data: data, - dataType: 'json', - success: function (data) { - console.log(data) - if (data.success) { - var stripe = Stripe($donationForm.data('stripeKey')) - return stripe.redirectToCheckout({sessionId: data.sessionId}) - } else { - msg = 'There was an error setting up your donation. ' - if (data.error.amount) { - msg += data.error.amount - } else { - msg += 'Sorry. Please refresh the page and try again.' - } - alert(msg); - } - } - }) + function postToStripe(recaptchaToken) { + var interval = $donationForm.find('[name=interval]').val(); + var amount = $donationForm.find('[name=amount]').val(); + var csrfToken = $donationForm.find('[name=csrfmiddlewaretoken]').val(); + var data = { + interval: interval, + amount: amount, + captcha: recaptchaToken, + csrfmiddlewaretoken: csrfToken, }; - - // django-recaptcha==4.0.0 adds a `submit` event listener to the form that - // ends up calling form.submit(), therefore bypassing our own event listener. - // As a workaround, we remove their event listener and replace it with our own. - if (window.recaptchaFormSubmit !== undefined) { - $donationForm[0].removeEventListener("submit", window.recaptchaFormSubmit); - } - $donationForm.on('submit', function (e) { - e.preventDefault(); - let captcha_input = document.getElementById("id_captcha"), - public_key = captcha_input.getAttribute('data-sitekey'); - // Validate token on form submit. - // NOTE: the `action` key must match the one defined on the widget. - grecaptcha.execute(public_key, {action: 'form'}).then(function(token) { - captcha_input.value = token; - console.log("reCAPTCHA validated. Posting to stripe..."); - postToStripe(token); - }); + $.ajax({ + type: 'POST', + url: $donationForm.attr('action-for-donation-session'), + data: data, + dataType: 'json', + success: function (data) { + console.log(data); + if (data.success) { + var stripe = Stripe($donationForm.data('stripeKey')); + return stripe.redirectToCheckout({ sessionId: data.sessionId }); + } else { + msg = 'There was an error setting up your donation. '; + if (data.error.amount) { + msg += data.error.amount; + } else { + msg += 'Sorry. Please refresh the page and try again.'; + } + alert(msg); + } + }, }); + } + // django-recaptcha==4.0.0 adds a `submit` event listener to the form that + // ends up calling form.submit(), therefore bypassing our own event listener. + // As a workaround, we remove their event listener and replace it with our own. + if (window.recaptchaFormSubmit !== undefined) { + $donationForm[0].removeEventListener('submit', window.recaptchaFormSubmit); + } + $donationForm.on('submit', function (e) { + e.preventDefault(); + let captcha_input = document.getElementById('id_captcha'), + public_key = captcha_input.getAttribute('data-sitekey'); + // Validate token on form submit. + // NOTE: the `action` key must match the one defined on the widget. + grecaptcha.execute(public_key, { action: 'form' }).then(function (token) { + captcha_input.value = token; + console.log('reCAPTCHA validated. Posting to stripe...'); + postToStripe(token); + }); + }); }); diff --git a/djangoproject/static/js/mod/switch-dark-mode.js b/djangoproject/static/js/mod/switch-dark-mode.js index 3f1cbc247..e71ef21e7 100644 --- a/djangoproject/static/js/mod/switch-dark-mode.js +++ b/djangoproject/static/js/mod/switch-dark-mode.js @@ -1,118 +1,122 @@ - let prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; +let prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - function setTheme(mode) { - if (mode !== "light" && mode !== "dark" && mode !== "auto") { - console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); - mode = "auto"; - } - document.documentElement.dataset.theme = mode; - // trim host to get base domain name for set in cookie domain name for subdomain access - arrHost = window.location.hostname.split('.') - prefix = arrHost.shift() - host = arrHost.join('.') - setCookie('theme', mode, host) - } - - function cycleTheme() { - const currentTheme = getCookie("theme") || "auto"; +function setTheme(mode) { + if (mode !== 'light' && mode !== 'dark' && mode !== 'auto') { + console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + mode = 'auto'; + } + document.documentElement.dataset.theme = mode; + // trim host to get base domain name for set in cookie domain name for subdomain access + arrHost = window.location.hostname.split('.'); + prefix = arrHost.shift(); + host = arrHost.join('.'); + setCookie('theme', mode, host); +} - if (prefersDark) { - // Auto (dark) -> Light -> Dark - if (currentTheme === "auto") { - setTheme("light"); - } else if (currentTheme === "light") { - setTheme("dark"); - } else { - setTheme("auto"); - } - } else { - // Auto (light) -> Dark -> Light - if (currentTheme === "auto") { - setTheme("dark"); - } else if (currentTheme === "dark") { - setTheme("light"); - } else { - setTheme("auto"); - } - } +function cycleTheme() { + const currentTheme = getCookie('theme') || 'auto'; - setReleaseImgClass(); + if (prefersDark) { + // Auto (dark) -> Light -> Dark + if (currentTheme === 'auto') { + setTheme('light'); + } else if (currentTheme === 'light') { + setTheme('dark'); + } else { + setTheme('auto'); } - - function initTheme() { - // set theme defined in localStorage if there is one, or fallback to auto mode - const currentTheme = getCookie("theme"); - currentTheme ? setTheme(currentTheme) : setTheme("auto"); - setReleaseImgClass(); + } else { + // Auto (light) -> Dark -> Light + if (currentTheme === 'auto') { + setTheme('dark'); + } else if (currentTheme === 'dark') { + setTheme('light'); + } else { + setTheme('auto'); } + } - function setupTheme() { - // Attach event handlers for toggling themes - let buttons = document.getElementsByClassName("theme-toggle"); - for (var i = 0; i < buttons.length; i++) { - buttons[i].addEventListener("click", cycleTheme); - }; - setReleaseImgClass(); - } + setReleaseImgClass(); +} - function setReleaseImgClass() { - // set class for the image about releases to invert color if needed - const currentTheme = getCookie("theme") || "auto"; - const image = document.getElementsByClassName("img-release")[0]; +function initTheme() { + // set theme defined in localStorage if there is one, or fallback to auto mode + const currentTheme = getCookie('theme'); + currentTheme ? setTheme(currentTheme) : setTheme('auto'); + setReleaseImgClass(); +} - if(image && (currentTheme == "auto" && prefersDark)) { - image.classList.add('dark') - image.classList.remove('light') - } - if(image && (currentTheme == "auto" && !prefersDark)) { - image.classList.add('light') - image.classList.remove('dark') - } - if(image && (currentTheme == "light")) { - image.classList.add('light') - image.classList.remove('dark') - } - if(image && (currentTheme == "dark")) { - image.classList.add('dark') - image.classList.remove('light') - } - } +function setupTheme() { + // Attach event handlers for toggling themes + let buttons = document.getElementsByClassName('theme-toggle'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', cycleTheme); + } + setReleaseImgClass(); +} - function setCookie(cname, cvalue, domain) { - const d = new Date(); - d.setTime(d.getTime() + (365*24*60*60*1000)); // 1 year - let expires = "expires="+ d.toUTCString(); - // change the SameSite attribute if it's on development or production - sameSiteAttribute = domain == 'localhost' ? 'SameSite=Lax;' : `Domain=${domain}; SameSite=None; Secure;` - document.cookie = `${cname}=${cvalue}; ${sameSiteAttribute} ${expires}; path=/;`; - } +function setReleaseImgClass() { + // set class for the image about releases to invert color if needed + const currentTheme = getCookie('theme') || 'auto'; + const image = document.getElementsByClassName('img-release')[0]; - function getCookie(cname) { - let name = cname + "="; - let decodedCookie = decodeURIComponent(document.cookie); - let ca = decodedCookie.split(';'); - for(let i = 0; i