diff options
| author | Tom Carrick <tom@carrick.eu> | 2026-04-19 11:54:17 +0300 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-04-19 13:45:56 +0300 |
| commit | fc0a0ebd4fe573299a5f978e77fa3bca8424f661 (patch) | |
| tree | 02df30c20820ddc4a6764969e8dbd9c3a22f437d /django | |
| parent | 47789e3a2b471995ed753c87ce69ffbaa59c0601 (diff) | |
Formatted JavaScript files.
Diffstat (limited to 'django')
20 files changed, 2081 insertions, 989 deletions
diff --git a/django/contrib/admin/static/admin/js/SelectBox.js b/django/contrib/admin/static/admin/js/SelectBox.js index 17c182c53f..7b6a751ea0 100644 --- a/django/contrib/admin/static/admin/js/SelectBox.js +++ b/django/contrib/admin/static/admin/js/SelectBox.js @@ -1,26 +1,31 @@ -'use strict'; +"use strict"; { const getOptionGroupName = (option) => option.parentElement.label; const SelectBox = { cache: {}, - init: function(id) { + init: function (id) { const box = document.getElementById(id); SelectBox.cache[id] = []; const cache = SelectBox.cache[id]; for (const node of box.options) { const group = getOptionGroupName(node); - cache.push({group, value: node.value, text: node.text, displayed: 1}); + cache.push({ + group, + value: node.value, + text: node.text, + displayed: 1, + }); } // Only sort if there are any groups (to preserve existing behavior for non-grouped selects) - if (cache.some(item => item.group)) { + if (cache.some((item) => item.group)) { SelectBox.sort(id); } }, - redisplay: function(id) { + redisplay: function (id) { // Repopulate HTML select box from cache const box = document.getElementById(id); const scroll_value_from_top = box.scrollTop; - box.innerHTML = ''; + box.innerHTML = ""; let node = box; let currentOptgroup = null; for (const option of SelectBox.cache[id]) { @@ -28,15 +33,20 @@ // Create a new optgroup when the group changes if (option.group && option.group !== currentOptgroup) { currentOptgroup = option.group; - node = document.createElement('optgroup'); - node.setAttribute('label', option.group); + node = document.createElement("optgroup"); + node.setAttribute("label", option.group); box.appendChild(node); } else if (!option.group && currentOptgroup !== null) { // Back to ungrouped options currentOptgroup = null; node = box; } - const new_option = new Option(option.text, option.value, false, false); + const new_option = new Option( + option.text, + option.value, + false, + false, + ); // Shows a tooltip when hovering over the option new_option.title = option.text; node.appendChild(new_option); @@ -44,7 +54,7 @@ } box.scrollTop = scroll_value_from_top; }, - filter: function(id, text) { + filter: function (id, text) { // Redisplay the HTML select box, displaying only the choices containing ALL // the words in text. (It's an AND search.) const tokens = text.toLowerCase().split(/\s+/); @@ -62,9 +72,9 @@ }, get_hidden_node_count(id) { const cache = SelectBox.cache[id] || []; - return cache.filter(node => node.displayed === 0).length; + return cache.filter((node) => node.displayed === 0).length; }, - delete_from_cache: function(id, value) { + delete_from_cache: function (id, value) { let delete_index = null; const cache = SelectBox.cache[id]; for (const [i, node] of cache.entries()) { @@ -75,10 +85,15 @@ } cache.splice(delete_index, 1); }, - add_to_cache: function(id, option) { - SelectBox.cache[id].push({group: option.group, value: option.value, text: option.text, displayed: 1}); + add_to_cache: function (id, option) { + SelectBox.cache[id].push({ + group: option.group, + value: option.value, + text: option.text, + displayed: 1, + }); }, - cache_contains: function(id, value) { + cache_contains: function (id, value) { // Check if an item is contained in the cache for (const node of SelectBox.cache[id]) { if (node.value === value) { @@ -87,44 +102,61 @@ } return false; }, - move: function(from, to) { + move: function (from, to) { const from_box = document.getElementById(from); for (const option of from_box.options) { const option_value = option.value; - if (option.selected && SelectBox.cache_contains(from, option_value)) { + if ( + option.selected && + SelectBox.cache_contains(from, option_value) + ) { const group = getOptionGroupName(option); - SelectBox.add_to_cache(to, {group, value: option_value, text: option.text, displayed: 1}); + SelectBox.add_to_cache(to, { + group, + value: option_value, + text: option.text, + displayed: 1, + }); SelectBox.delete_from_cache(from, option_value); } } // Only sort if there are any groups (to preserve existing behavior for non-grouped selects) - if (SelectBox.cache[to].some(item => item.group)) { + if (SelectBox.cache[to].some((item) => item.group)) { SelectBox.sort(to); } SelectBox.redisplay(from); SelectBox.redisplay(to); }, - move_all: function(from, to) { + move_all: function (from, to) { const from_box = document.getElementById(from); for (const option of from_box.options) { const option_value = option.value; if (SelectBox.cache_contains(from, option_value)) { const group = getOptionGroupName(option); - SelectBox.add_to_cache(to, {group, value: option_value, text: option.text, displayed: 1}); + SelectBox.add_to_cache(to, { + group, + value: option_value, + text: option.text, + displayed: 1, + }); SelectBox.delete_from_cache(from, option_value); } } // Only sort if there are any groups (to preserve existing behavior for non-grouped selects) - if (SelectBox.cache[to].some(item => item.group)) { + if (SelectBox.cache[to].some((item) => item.group)) { SelectBox.sort(to); } SelectBox.redisplay(from); SelectBox.redisplay(to); }, - sort: function(id) { - SelectBox.cache[id].sort(function(a, b) { - a = (a.group && a.group.toLowerCase() || '') + a.text.toLowerCase(); - b = (b.group && b.group.toLowerCase() || '') + b.text.toLowerCase(); + sort: function (id) { + SelectBox.cache[id].sort(function (a, b) { + a = + ((a.group && a.group.toLowerCase()) || "") + + a.text.toLowerCase(); + b = + ((b.group && b.group.toLowerCase()) || "") + + b.text.toLowerCase(); if (a > b) { return 1; } @@ -132,14 +164,14 @@ return -1; } return 0; - } ); + }); }, - select_all: function(id) { + select_all: function (id) { const box = document.getElementById(id); for (const option of box.options) { option.selected = true; } - } + }, }; window.SelectBox = SelectBox; } diff --git a/django/contrib/admin/static/admin/js/SelectFilter2.js b/django/contrib/admin/static/admin/js/SelectFilter2.js index 99efa1e0ca..ebaaa0cd60 100644 --- a/django/contrib/admin/static/admin/js/SelectFilter2.js +++ b/django/contrib/admin/static/admin/js/SelectFilter2.js @@ -4,161 +4,289 @@ SelectFilter2 - Turns a multiple-select box into a filter interface. Requires core.js and SelectBox.js. */ -'use strict'; +"use strict"; { window.SelectFilter = { - init: function(field_id, field_name, is_stacked) { + init: function (field_id, field_name, is_stacked) { if (field_id.match(/__prefix__/)) { // Don't initialize on empty forms. return; } const from_box = document.getElementById(field_id); - from_box.id += '_from'; // change its ID - from_box.className = 'filtered'; - from_box.setAttribute('aria-labelledby', field_id + '_from_label'); - from_box.setAttribute('aria-describedby', `${field_id}_helptext ${field_id}_choose_helptext`); + from_box.id += "_from"; // change its ID + from_box.className = "filtered"; + from_box.setAttribute("aria-labelledby", field_id + "_from_label"); + from_box.setAttribute( + "aria-describedby", + `${field_id}_helptext ${field_id}_choose_helptext`, + ); // <div class="selector"> or <div class="selector stacked"> - const selector_div = quickElement('div', from_box.parentNode); + const selector_div = quickElement("div", from_box.parentNode); // Make sure the selector div appears between the label and the add link. - from_box.parentNode.insertBefore(selector_div, from_box.nextSibling); - selector_div.className = is_stacked ? 'selector stacked' : 'selector'; + from_box.parentNode.insertBefore( + selector_div, + from_box.nextSibling, + ); + selector_div.className = is_stacked + ? "selector stacked" + : "selector"; // <div class="selector-available"> - const selector_available = quickElement('div', selector_div); - selector_available.className = 'selector-available'; - const selector_available_title = quickElement('div', selector_available); - selector_available_title.id = field_id + '_from_title'; - selector_available_title.className = 'selector-available-title'; + const selector_available = quickElement("div", selector_div); + selector_available.className = "selector-available"; + const selector_available_title = quickElement( + "div", + selector_available, + ); + selector_available_title.id = field_id + "_from_title"; + selector_available_title.className = "selector-available-title"; quickElement( - 'label', + "label", selector_available_title, - interpolate(gettext('Available %s') + ' ', [field_name]), - 'id', - field_id + '_from_label', - 'for', - field_id + '_from' + interpolate(gettext("Available %s") + " ", [field_name]), + "id", + field_id + "_from_label", + "for", + field_id + "_from", ); quickElement( - 'p', + "p", selector_available_title, - interpolate(gettext('Choose %s by selecting them and then select the "Choose" arrow button.'), [field_name]), - 'id', `${field_id}_choose_helptext`, 'class', 'helptext' + interpolate( + gettext( + 'Choose %s by selecting them and then select the "Choose" arrow button.', + ), + [field_name], + ), + "id", + `${field_id}_choose_helptext`, + "class", + "helptext", ); - const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); - filter_p.className = 'selector-filter'; + const filter_p = quickElement( + "p", + selector_available, + "", + "id", + field_id + "_filter", + ); + filter_p.className = "selector-filter"; - const search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input'); + const search_filter_label = quickElement( + "label", + filter_p, + "", + "for", + field_id + "_input", + ); quickElement( - 'span', search_filter_label, '', - 'class', 'help-tooltip search-label-icon', - 'aria-label', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]) + "span", + search_filter_label, + "", + "class", + "help-tooltip search-label-icon", + "aria-label", + interpolate( + gettext( + "Type into this box to filter down the list of available %s.", + ), + [field_name], + ), ); - filter_p.appendChild(document.createTextNode(' ')); + filter_p.appendChild(document.createTextNode(" ")); - const filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); - filter_input.id = field_id + '_input'; + const filter_input = quickElement( + "input", + filter_p, + "", + "type", + "text", + "placeholder", + gettext("Filter"), + ); + filter_input.id = field_id + "_input"; selector_available.appendChild(from_box); const choose_all = quickElement( - 'button', + "button", selector_available, - interpolate(gettext('Choose all %s'), [field_name]), - 'id', field_id + '_add_all', - 'class', 'selector-chooseall', - 'type', 'button' + interpolate(gettext("Choose all %s"), [field_name]), + "id", + field_id + "_add_all", + "class", + "selector-chooseall", + "type", + "button", ); // <ul class="selector-chooser"> - const selector_chooser = quickElement('ul', selector_div); - selector_chooser.className = 'selector-chooser'; + const selector_chooser = quickElement("ul", selector_div); + selector_chooser.className = "selector-chooser"; const add_button = quickElement( - 'button', - quickElement('li', selector_chooser), - interpolate(gettext('Choose selected %s'), [field_name]), - 'id', field_id + '_add', - 'class', 'selector-add', - 'type', 'button' + "button", + quickElement("li", selector_chooser), + interpolate(gettext("Choose selected %s"), [field_name]), + "id", + field_id + "_add", + "class", + "selector-add", + "type", + "button", ); const remove_button = quickElement( - 'button', - quickElement('li', selector_chooser), - interpolate(gettext('Remove selected %s'), [field_name]), - 'id', field_id + '_remove', - 'class', 'selector-remove', - 'type', 'button' + "button", + quickElement("li", selector_chooser), + interpolate(gettext("Remove selected %s"), [field_name]), + "id", + field_id + "_remove", + "class", + "selector-remove", + "type", + "button", ); // <div class="selector-chosen"> - const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen'); - selector_chosen.className = 'selector-chosen'; - const selector_chosen_title = quickElement('div', selector_chosen); - selector_chosen_title.className = 'selector-chosen-title'; - selector_chosen_title.id = field_id + '_to_title'; + const selector_chosen = quickElement( + "div", + selector_div, + "", + "id", + field_id + "_selector_chosen", + ); + selector_chosen.className = "selector-chosen"; + const selector_chosen_title = quickElement("div", selector_chosen); + selector_chosen_title.className = "selector-chosen-title"; + selector_chosen_title.id = field_id + "_to_title"; quickElement( - 'label', + "label", selector_chosen_title, - interpolate(gettext('Chosen %s') + ' ', [field_name]), - 'id', - field_id + '_to_label', - 'for', - field_id + '_to' + interpolate(gettext("Chosen %s") + " ", [field_name]), + "id", + field_id + "_to_label", + "for", + field_id + "_to", ); quickElement( - 'p', + "p", selector_chosen_title, - interpolate(gettext('Remove %s by selecting them and then select the "Remove" arrow button.'), [field_name]), - 'id', `${field_id}_remove_helptext`, 'class', 'helptext' + interpolate( + gettext( + 'Remove %s by selecting them and then select the "Remove" arrow button.', + ), + [field_name], + ), + "id", + `${field_id}_remove_helptext`, + "class", + "helptext", ); - - const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected'); - filter_selected_p.className = 'selector-filter'; - const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input'); + const filter_selected_p = quickElement( + "p", + selector_chosen, + "", + "id", + field_id + "_filter_selected", + ); + filter_selected_p.className = "selector-filter"; + + const search_filter_selected_label = quickElement( + "label", + filter_selected_p, + "", + "for", + field_id + "_selected_input", + ); quickElement( - 'span', search_filter_selected_label, '', - 'class', 'help-tooltip search-label-icon', - 'aria-label', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name]) + "span", + search_filter_selected_label, + "", + "class", + "help-tooltip search-label-icon", + "aria-label", + interpolate( + gettext( + "Type into this box to filter down the list of selected %s.", + ), + [field_name], + ), ); - filter_selected_p.appendChild(document.createTextNode(' ')); + filter_selected_p.appendChild(document.createTextNode(" ")); - const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter")); - filter_selected_input.id = field_id + '_selected_input'; + const filter_selected_input = quickElement( + "input", + filter_selected_p, + "", + "type", + "text", + "placeholder", + gettext("Filter"), + ); + filter_selected_input.id = field_id + "_selected_input"; quickElement( - 'select', + "select", selector_chosen, - '', - 'id', field_id + '_to', - 'multiple', '', - 'size', from_box.size, - 'name', from_box.name, - 'aria-labelledby', field_id + '_to_label', - 'aria-describedby', `${field_id}_helptext ${field_id}_remove_helptext`, - 'class', 'filtered' + "", + "id", + field_id + "_to", + "multiple", + "", + "size", + from_box.size, + "name", + from_box.name, + "aria-labelledby", + field_id + "_to_label", + "aria-describedby", + `${field_id}_helptext ${field_id}_remove_helptext`, + "class", + "filtered", + ); + const warning_footer = quickElement( + "div", + selector_chosen, + "", + "class", + "list-footer-display", + ); + quickElement( + "span", + warning_footer, + "", + "id", + field_id + "_list-footer-display-text", + ); + quickElement( + "span", + warning_footer, + " " + gettext("(click to clear)"), + "class", + "list-footer-display__clear", ); - const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display'); - quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text'); - quickElement('span', warning_footer, ' ' + gettext('(click to clear)'), 'class', 'list-footer-display__clear'); const clear_all = quickElement( - 'button', + "button", selector_chosen, - interpolate(gettext('Remove all %s'), [field_name]), - 'id', field_id + '_remove_all', - 'class', 'selector-clearall', - 'type', 'button' + interpolate(gettext("Remove all %s"), [field_name]), + "id", + field_id + "_remove_all", + "class", + "selector-clearall", + "type", + "button", ); - from_box.name = from_box.name + '_old'; + from_box.name = from_box.name + "_old"; // Set up the JavaScript event handlers for the select box filter interface - const move_selection = function(e, elem, move_func, from, to) { - if (!elem.hasAttribute('disabled')) { + const move_selection = function (e, elem, move_func, from, to) { + if (!elem.hasAttribute("disabled")) { move_func(from, to); SelectFilter.refresh_icons(field_id); SelectFilter.refresh_filtered_selects(field_id); @@ -166,151 +294,230 @@ Requires core.js and SelectBox.js. } e.preventDefault(); }; - choose_all.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to'); + choose_all.addEventListener("click", function (e) { + move_selection( + e, + this, + SelectBox.move_all, + field_id + "_from", + field_id + "_to", + ); }); - add_button.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to'); + add_button.addEventListener("click", function (e) { + move_selection( + e, + this, + SelectBox.move, + field_id + "_from", + field_id + "_to", + ); }); - remove_button.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from'); + remove_button.addEventListener("click", function (e) { + move_selection( + e, + this, + SelectBox.move, + field_id + "_to", + field_id + "_from", + ); }); - clear_all.addEventListener('click', function(e) { - move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from'); + clear_all.addEventListener("click", function (e) { + move_selection( + e, + this, + SelectBox.move_all, + field_id + "_to", + field_id + "_from", + ); }); - warning_footer.addEventListener('click', function(e) { - filter_selected_input.value = ''; - SelectBox.filter(field_id + '_to', ''); + warning_footer.addEventListener("click", function (e) { + filter_selected_input.value = ""; + SelectBox.filter(field_id + "_to", ""); SelectFilter.refresh_filtered_warning(field_id); SelectFilter.refresh_icons(field_id); }); - filter_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id, '_from', '_to'); + filter_input.addEventListener("keypress", function (e) { + SelectFilter.filter_key_press(e, field_id, "_from", "_to"); }); - filter_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id, '_from'); + filter_input.addEventListener("keyup", function (e) { + SelectFilter.filter_key_up(e, field_id, "_from"); }); - filter_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id, '_from', '_to'); + filter_input.addEventListener("keydown", function (e) { + SelectFilter.filter_key_down(e, field_id, "_from", "_to"); }); - filter_selected_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id, '_to', '_from'); + filter_selected_input.addEventListener("keypress", function (e) { + SelectFilter.filter_key_press(e, field_id, "_to", "_from"); }); - filter_selected_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input'); + filter_selected_input.addEventListener("keyup", function (e) { + SelectFilter.filter_key_up( + e, + field_id, + "_to", + "_selected_input", + ); }); - filter_selected_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id, '_to', '_from'); + filter_selected_input.addEventListener("keydown", function (e) { + SelectFilter.filter_key_down(e, field_id, "_to", "_from"); }); - selector_div.addEventListener('change', function(e) { - if (e.target.tagName === 'SELECT') { + selector_div.addEventListener("change", function (e) { + if (e.target.tagName === "SELECT") { SelectFilter.refresh_icons(field_id); } }); - selector_div.addEventListener('dblclick', function(e) { - if (e.target.tagName === 'OPTION') { - if (e.target.closest('select').id === field_id + '_to') { - SelectBox.move(field_id + '_to', field_id + '_from'); + selector_div.addEventListener("dblclick", function (e) { + if (e.target.tagName === "OPTION") { + if (e.target.closest("select").id === field_id + "_to") { + SelectBox.move(field_id + "_to", field_id + "_from"); } else { - SelectBox.move(field_id + '_from', field_id + '_to'); + SelectBox.move(field_id + "_from", field_id + "_to"); } SelectFilter.refresh_icons(field_id); } }); - from_box.closest('form').addEventListener('submit', function() { - SelectBox.filter(field_id + '_to', ''); - SelectBox.select_all(field_id + '_to'); + from_box.closest("form").addEventListener("submit", function () { + SelectBox.filter(field_id + "_to", ""); + SelectBox.select_all(field_id + "_to"); }); - SelectBox.init(field_id + '_from'); - SelectBox.init(field_id + '_to'); + SelectBox.init(field_id + "_from"); + SelectBox.init(field_id + "_to"); // Move selected from_box options to to_box - SelectBox.move(field_id + '_from', field_id + '_to'); + SelectBox.move(field_id + "_from", field_id + "_to"); // Initial icon refresh SelectFilter.refresh_icons(field_id); }, - any_selected: function(field) { + any_selected: function (field) { // Temporarily add the required attribute and check validity. field.required = true; const any_selected = field.checkValidity(); field.required = false; return any_selected; }, - refresh_filtered_warning: function(field_id) { - const count = SelectBox.get_hidden_node_count(field_id + '_to'); - const selector = document.getElementById(field_id + '_selector_chosen'); - const warning = document.getElementById(field_id + '_list-footer-display-text'); - selector.className = selector.className.replace('selector-chosen--with-filtered', ''); - warning.textContent = interpolate(ngettext( - '%s selected option not visible', - '%s selected options not visible', - count - ), [count]); - if(count > 0) { - selector.className += ' selector-chosen--with-filtered'; + refresh_filtered_warning: function (field_id) { + const count = SelectBox.get_hidden_node_count(field_id + "_to"); + const selector = document.getElementById( + field_id + "_selector_chosen", + ); + const warning = document.getElementById( + field_id + "_list-footer-display-text", + ); + selector.className = selector.className.replace( + "selector-chosen--with-filtered", + "", + ); + warning.textContent = interpolate( + ngettext( + "%s selected option not visible", + "%s selected options not visible", + count, + ), + [count], + ); + if (count > 0) { + selector.className += " selector-chosen--with-filtered"; } }, - refresh_filtered_selects: function(field_id) { - SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value); - SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value); + refresh_filtered_selects: function (field_id) { + SelectBox.filter( + field_id + "_from", + document.getElementById(field_id + "_input").value, + ); + SelectBox.filter( + field_id + "_to", + document.getElementById(field_id + "_selected_input").value, + ); }, - refresh_icons: function(field_id) { - const from = document.getElementById(field_id + '_from'); - const to = document.getElementById(field_id + '_to'); + refresh_icons: function (field_id) { + const from = document.getElementById(field_id + "_from"); + const to = document.getElementById(field_id + "_to"); // Disabled if no items are selected. - document.getElementById(field_id + '_add').disabled = !SelectFilter.any_selected(from); - document.getElementById(field_id + '_remove').disabled = !SelectFilter.any_selected(to); + document.getElementById(field_id + "_add").disabled = + !SelectFilter.any_selected(from); + document.getElementById(field_id + "_remove").disabled = + !SelectFilter.any_selected(to); // Disabled if the corresponding box is empty. - document.getElementById(field_id + '_add_all').disabled = !from.querySelector('option'); - document.getElementById(field_id + '_remove_all').disabled = !to.querySelector('option'); + document.getElementById(field_id + "_add_all").disabled = + !from.querySelector("option"); + document.getElementById(field_id + "_remove_all").disabled = + !to.querySelector("option"); }, - filter_key_press: function(event, field_id, source, target) { + filter_key_press: function (event, field_id, source, target) { const source_box = document.getElementById(field_id + source); // don't submit form if user pressed Enter - if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { + if ( + (event.which && event.which === 13) || + (event.keyCode && event.keyCode === 13) + ) { source_box.selectedIndex = 0; SelectBox.move(field_id + source, field_id + target); source_box.selectedIndex = 0; event.preventDefault(); } }, - filter_key_up: function(event, field_id, source, filter_input) { - const input = filter_input || '_input'; + filter_key_up: function (event, field_id, source, filter_input) { + const input = filter_input || "_input"; const source_box = document.getElementById(field_id + source); const temp = source_box.selectedIndex; - SelectBox.filter(field_id + source, document.getElementById(field_id + input).value); + SelectBox.filter( + field_id + source, + document.getElementById(field_id + input).value, + ); source_box.selectedIndex = temp; SelectFilter.refresh_filtered_warning(field_id); SelectFilter.refresh_icons(field_id); }, - filter_key_down: function(event, field_id, source, target) { + filter_key_down: function (event, field_id, source, target) { const source_box = document.getElementById(field_id + source); // right key (39) or left key (37) - const direction = source === '_from' ? 39 : 37; + const direction = source === "_from" ? 39 : 37; // right arrow -- move across - if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) { + if ( + (event.which && event.which === direction) || + (event.keyCode && event.keyCode === direction) + ) { const old_index = source_box.selectedIndex; SelectBox.move(field_id + source, field_id + target); SelectFilter.refresh_filtered_selects(field_id); SelectFilter.refresh_filtered_warning(field_id); - source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index; + source_box.selectedIndex = + old_index === source_box.length + ? source_box.length - 1 + : old_index; return; } // down arrow -- wrap around - if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { - source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1; + if ( + (event.which && event.which === 40) || + (event.keyCode && event.keyCode === 40) + ) { + source_box.selectedIndex = + source_box.length === source_box.selectedIndex + 1 + ? 0 + : source_box.selectedIndex + 1; } // up arrow -- wrap around - if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { - source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1; + if ( + (event.which && event.which === 38) || + (event.keyCode && event.keyCode === 38) + ) { + source_box.selectedIndex = + source_box.selectedIndex === 0 + ? source_box.length - 1 + : source_box.selectedIndex - 1; } - } + }, }; - window.addEventListener('load', function(e) { - document.querySelectorAll('select.selectfilter, select.selectfilterstacked').forEach(function(el) { - const data = el.dataset; - SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10)); - }); + window.addEventListener("load", function (e) { + document + .querySelectorAll("select.selectfilter, select.selectfilterstacked") + .forEach(function (el) { + const data = el.dataset; + SelectFilter.init( + el.id, + data.fieldName, + parseInt(data.isStacked, 10), + ); + }); }); } diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js index 04b25e9684..e302bb4b22 100644 --- a/django/contrib/admin/static/admin/js/actions.js +++ b/django/contrib/admin/static/admin/js/actions.js @@ -1,15 +1,15 @@ /*global gettext, interpolate, ngettext, Actions*/ -'use strict'; +"use strict"; { function show(selector) { - document.querySelectorAll(selector).forEach(function(el) { - el.classList.remove('hidden'); + document.querySelectorAll(selector).forEach(function (el) { + el.classList.remove("hidden"); }); } function hide(selector) { - document.querySelectorAll(selector).forEach(function(el) { - el.classList.add('hidden'); + document.querySelectorAll(selector).forEach(function (el) { + el.classList.add("hidden"); }); } @@ -22,7 +22,9 @@ function showClear(options) { show(options.acrossClears); hide(options.acrossQuestions); - document.querySelector(options.actionContainer).classList.remove(options.selectedClass); + document + .querySelector(options.actionContainer) + .classList.remove(options.selectedClass); show(options.allContainer); hide(options.counterContainer); } @@ -37,10 +39,12 @@ function clearAcross(options) { reset(options); const acrossInputs = document.querySelectorAll(options.acrossInput); - acrossInputs.forEach(function(acrossInput) { + acrossInputs.forEach(function (acrossInput) { acrossInput.value = 0; }); - document.querySelector(options.actionContainer).classList.remove(options.selectedClass); + document + .querySelector(options.actionContainer) + .classList.remove(options.selectedClass); } function checker(actionCheckboxes, options, checked) { @@ -49,14 +53,14 @@ } else { reset(options); } - actionCheckboxes.forEach(function(el) { + actionCheckboxes.forEach(function (el) { el.checked = checked; - el.closest('tr').classList.toggle(options.selectedClass, checked); + el.closest("tr").classList.toggle(options.selectedClass, checked); }); } function updateCounter(actionCheckboxes, options) { - const sel = Array.from(actionCheckboxes).filter(function(el) { + const sel = Array.from(actionCheckboxes).filter(function (el) { return el.checked; }).length; const counter = document.querySelector(options.counterContainer); @@ -64,10 +68,17 @@ // and contains the total amount of objects in the queryset const actions_icnt = Number(counter.dataset.actionsIcnt); counter.textContent = interpolate( - ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { + ngettext( + "%(sel)s of %(cnt)s selected", + "%(sel)s of %(cnt)s selected", + sel, + ), + { sel: sel, - cnt: actions_icnt - }, true); + cnt: actions_icnt, + }, + true, + ); const allToggle = document.getElementById(options.allToggleId); allToggle.checked = sel === actionCheckboxes.length; if (allToggle.checked) { @@ -85,94 +96,123 @@ acrossQuestions: "div.actions span.question", acrossClears: "div.actions span.clear", allToggleId: "action-toggle", - selectedClass: "selected" + selectedClass: "selected", }; - window.Actions = function(actionCheckboxes, options) { + window.Actions = function (actionCheckboxes, options) { options = Object.assign({}, defaults, options); let list_editable_changed = false; let lastChecked = null; let shiftPressed = false; - document.addEventListener('keydown', (event) => { + document.addEventListener("keydown", (event) => { shiftPressed = event.shiftKey; }); - document.addEventListener('keyup', (event) => { + document.addEventListener("keyup", (event) => { shiftPressed = event.shiftKey; }); - document.getElementById(options.allToggleId).addEventListener('click', function(event) { - checker(actionCheckboxes, options, this.checked); - updateCounter(actionCheckboxes, options); - }); + document + .getElementById(options.allToggleId) + .addEventListener("click", function (event) { + checker(actionCheckboxes, options, this.checked); + updateCounter(actionCheckboxes, options); + }); - document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) { - el.addEventListener('click', function(event) { - event.preventDefault(); - const acrossInputs = document.querySelectorAll(options.acrossInput); - acrossInputs.forEach(function(acrossInput) { - acrossInput.value = 1; + document + .querySelectorAll(options.acrossQuestions + " a") + .forEach(function (el) { + el.addEventListener("click", function (event) { + event.preventDefault(); + const acrossInputs = document.querySelectorAll( + options.acrossInput, + ); + acrossInputs.forEach(function (acrossInput) { + acrossInput.value = 1; + }); + showClear(options); }); - showClear(options); }); - }); - document.querySelectorAll(options.acrossClears + " a").forEach(function(el) { - el.addEventListener('click', function(event) { - event.preventDefault(); - document.getElementById(options.allToggleId).checked = false; - clearAcross(options); - checker(actionCheckboxes, options, false); - updateCounter(actionCheckboxes, options); + document + .querySelectorAll(options.acrossClears + " a") + .forEach(function (el) { + el.addEventListener("click", function (event) { + event.preventDefault(); + document.getElementById(options.allToggleId).checked = + false; + clearAcross(options); + checker(actionCheckboxes, options, false); + updateCounter(actionCheckboxes, options); + }); }); - }); function affectedCheckboxes(target, withModifier) { - const multiSelect = (lastChecked && withModifier && lastChecked !== target); + const multiSelect = + lastChecked && withModifier && lastChecked !== target; if (!multiSelect) { return [target]; } const checkboxes = Array.from(actionCheckboxes); - const targetIndex = checkboxes.findIndex(el => el === target); - const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked); + const targetIndex = checkboxes.findIndex((el) => el === target); + const lastCheckedIndex = checkboxes.findIndex( + (el) => el === lastChecked, + ); const startIndex = Math.min(targetIndex, lastCheckedIndex); const endIndex = Math.max(targetIndex, lastCheckedIndex); - const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex)); + const filtered = checkboxes.filter( + (el, index) => startIndex <= index && index <= endIndex, + ); return filtered; - }; + } - Array.from(document.getElementById('result_list').tBodies).forEach(function(el) { - el.addEventListener('change', function(event) { - const target = event.target; - if (target.classList.contains('action-select')) { - const checkboxes = affectedCheckboxes(target, shiftPressed); - checker(checkboxes, options, target.checked); - updateCounter(actionCheckboxes, options); - lastChecked = target; - } else { - list_editable_changed = true; - } - }); - }); + Array.from(document.getElementById("result_list").tBodies).forEach( + function (el) { + el.addEventListener("change", function (event) { + const target = event.target; + if (target.classList.contains("action-select")) { + const checkboxes = affectedCheckboxes( + target, + shiftPressed, + ); + checker(checkboxes, options, target.checked); + updateCounter(actionCheckboxes, options); + lastChecked = target; + } else { + list_editable_changed = true; + } + }); + }, + ); - document.querySelector('#changelist-form button[name=index]').addEventListener('click', function(event) { - if (list_editable_changed) { - const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); - if (!confirmed) { - event.preventDefault(); + document + .querySelector("#changelist-form button[name=index]") + .addEventListener("click", function (event) { + if (list_editable_changed) { + const confirmed = confirm( + gettext( + "You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.", + ), + ); + if (!confirmed) { + event.preventDefault(); + } } - } - }); + }); - const el = document.querySelector('#changelist-form input[name=_save]'); + const el = document.querySelector("#changelist-form input[name=_save]"); // The button does not exist if no fields are editable. if (el) { - el.addEventListener('click', function(event) { - if (document.querySelector('[name=action]').value) { + el.addEventListener("click", function (event) { + if (document.querySelector("[name=action]").value) { const text = list_editable_changed - ? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.") - : gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button."); + ? gettext( + "You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.", + ) + : gettext( + "You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button.", + ); if (!confirm(text)) { event.preventDefault(); } @@ -181,22 +221,24 @@ } // Sync counter when navigating to the page, such as through the back // button. - window.addEventListener('pageshow', (event) => updateCounter(actionCheckboxes, options)); + window.addEventListener("pageshow", (event) => + updateCounter(actionCheckboxes, options), + ); }; // Call function fn when the DOM is loaded and ready. If it is already // loaded, call the function now. // http://youmightnotneedjquery.com/#ready function ready(fn) { - if (document.readyState !== 'loading') { + if (document.readyState !== "loading") { fn(); } else { - document.addEventListener('DOMContentLoaded', fn); + document.addEventListener("DOMContentLoaded", fn); } } - ready(function() { - const actionsEls = document.querySelectorAll('tr input.action-select'); + ready(function () { + const actionsEls = document.querySelectorAll("tr input.action-select"); if (actionsEls.length > 0) { Actions(actionsEls); } diff --git a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js index b30a668a2e..6f71b25152 100644 --- a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js @@ -2,7 +2,7 @@ // Inserts shortcut buttons after all of the following: // <input type="text" class="vDateField"> // <input type="text" class="vTimeField"> -'use strict'; +"use strict"; { const DateTimeShortcuts = { calendars: [], @@ -10,55 +10,62 @@ clockInputs: [], clockHours: { default_: [ - [gettext_noop('Now'), -1], - [gettext_noop('Midnight'), 0], - [gettext_noop('6 a.m.'), 6], - [gettext_noop('Noon'), 12], - [gettext_noop('6 p.m.'), 18] - ] + [gettext_noop("Now"), -1], + [gettext_noop("Midnight"), 0], + [gettext_noop("6 a.m."), 6], + [gettext_noop("Noon"), 12], + [gettext_noop("6 p.m."), 18], + ], }, dismissClockFunc: [], dismissCalendarFunc: [], - calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled - calendarDivName2: 'calendarin', // name of <div> that contains calendar - calendarLinkName: 'calendarlink', // name of the link that is used to toggle - clockDivName: 'clockbox', // name of clock <div> that gets toggled - clockLinkName: 'clocklink', // name of the link that is used to toggle - shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts - timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch + calendarDivName1: "calendarbox", // name of calendar <div> that gets toggled + calendarDivName2: "calendarin", // name of <div> that contains calendar + calendarLinkName: "calendarlink", // name of the link that is used to toggle + clockDivName: "clockbox", // name of clock <div> that gets toggled + clockLinkName: "clocklink", // name of the link that is used to toggle + shortCutsClass: "datetimeshortcuts", // class of the clock and cal shortcuts + timezoneWarningClass: "timezonewarning", // class of the warning for timezone mismatch timezoneOffset: 0, - init: function() { + init: function () { const serverOffset = document.body.dataset.adminUtcOffset; if (serverOffset) { const localOffset = new Date().getTimezoneOffset() * -60; DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; } - for (const inp of document.getElementsByTagName('input')) { - if (inp.type === 'text' && inp.classList.contains('vTimeField')) { + for (const inp of document.getElementsByTagName("input")) { + if ( + inp.type === "text" && + inp.classList.contains("vTimeField") + ) { DateTimeShortcuts.addClock(inp); DateTimeShortcuts.addTimezoneWarning(inp); - } - else if (inp.type === 'text' && inp.classList.contains('vDateField')) { + } else if ( + inp.type === "text" && + inp.classList.contains("vDateField") + ) { DateTimeShortcuts.addCalendar(inp); DateTimeShortcuts.addTimezoneWarning(inp); } } }, // Return the current time while accounting for the server timezone. - now: function() { + now: function () { const serverOffset = document.body.dataset.adminUtcOffset; if (serverOffset) { const localNow = new Date(); const localOffset = localNow.getTimezoneOffset() * -60; - localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset)); + localNow.setTime( + localNow.getTime() + 1000 * (serverOffset - localOffset), + ); return localNow; } else { return new Date(); } }, // Add a warning when the time zone in the browser and backend do not match. - addTimezoneWarning: function(inp) { + addTimezoneWarning: function (inp) { const warningClass = DateTimeShortcuts.timezoneWarningClass; let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; @@ -68,35 +75,40 @@ } // Check if warning is already there. - if (inp.parentNode.parentNode.querySelectorAll('.' + warningClass).length) { + if ( + inp.parentNode.parentNode.querySelectorAll("." + warningClass) + .length + ) { return; } let message; if (timezoneOffset > 0) { message = ngettext( - 'Note: You are %s hour ahead of server time.', - 'Note: You are %s hours ahead of server time.', - timezoneOffset + "Note: You are %s hour ahead of server time.", + "Note: You are %s hours ahead of server time.", + timezoneOffset, ); - } - else { + } else { timezoneOffset *= -1; message = ngettext( - 'Note: You are %s hour behind server time.', - 'Note: You are %s hours behind server time.', - timezoneOffset + "Note: You are %s hour behind server time.", + "Note: You are %s hours behind server time.", + timezoneOffset, ); } message = interpolate(message, [timezoneOffset]); - const warning = document.createElement('div'); + const warning = document.createElement("div"); const id = inp.id; - const field_id = inp.closest('p.datetime') ? id.slice(0, id.lastIndexOf("_")) : id; - warning.classList.add('help', warningClass); + const field_id = inp.closest("p.datetime") + ? id.slice(0, id.lastIndexOf("_")) + : id; + warning.classList.add("help", warningClass); warning.id = `${field_id}_timezone_warning_helptext`; warning.textContent = message; - const errorList = inp.parentNode.parentNode.querySelector('ul.errorlist'); + const errorList = + inp.parentNode.parentNode.querySelector("ul.errorlist"); if (errorList) { errorList.before(warning); } else { @@ -104,27 +116,30 @@ } }, // Add clock widget to a given field - addClock: function(inp) { + addClock: function (inp) { const num = DateTimeShortcuts.clockInputs.length; DateTimeShortcuts.clockInputs[num] = inp; - DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; + DateTimeShortcuts.dismissClockFunc[num] = function () { + DateTimeShortcuts.dismissClock(num); + return true; + }; // Shortcut links (clock icon and "Now" link) - const shortcuts_span = document.createElement('span'); + const shortcuts_span = document.createElement("span"); shortcuts_span.className = DateTimeShortcuts.shortCutsClass; inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - const now_link = document.createElement('a'); + const now_link = document.createElement("a"); now_link.href = "#"; - now_link.textContent = gettext('Now'); - now_link.role = 'button'; - now_link.addEventListener('click', function(e) { + now_link.textContent = gettext("Now"); + now_link.role = "button"; + now_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleClockQuicklink(num, -1); }); - const clock_link = document.createElement('a'); - clock_link.href = '#'; + const clock_link = document.createElement("a"); + clock_link.href = "#"; clock_link.id = DateTimeShortcuts.clockLinkName + num; - clock_link.addEventListener('click', function(e) { + clock_link.addEventListener("click", function (e) { e.preventDefault(); // avoid triggering the document click handler to dismiss the clock e.stopPropagation(); @@ -132,13 +147,19 @@ }); quickElement( - 'span', clock_link, '', - 'class', 'clock-icon', - 'title', gettext('Choose a Time') + "span", + clock_link, + "", + "class", + "clock-icon", + "title", + gettext("Choose a Time"), ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(document.createTextNode("\u00A0")); shortcuts_span.appendChild(now_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild( + document.createTextNode("\u00A0|\u00A0"), + ); shortcuts_span.appendChild(clock_link); // Create clock link div @@ -156,38 +177,59 @@ // <p class="calendar-cancel"><a href="#">Cancel</a></p> // </div> - const clock_box = document.createElement('div'); - clock_box.style.display = 'none'; - clock_box.style.position = 'absolute'; - clock_box.className = 'clockbox module'; + const clock_box = document.createElement("div"); + clock_box.style.display = "none"; + clock_box.style.position = "absolute"; + clock_box.className = "clockbox module"; clock_box.id = DateTimeShortcuts.clockDivName + num; document.body.appendChild(clock_box); - clock_box.addEventListener('click', function(e) { e.stopPropagation(); }); + clock_box.addEventListener("click", function (e) { + e.stopPropagation(); + }); - quickElement('h2', clock_box, gettext('Choose a time')); - const time_list = quickElement('ul', clock_box); - time_list.className = 'timelist'; + quickElement("h2", clock_box, gettext("Choose a time")); + const time_list = quickElement("ul", clock_box); + time_list.className = "timelist"; // The list of choices can be overridden in JavaScript like this: // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]]; // where name is the name attribute of the <input>. - const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name; - DateTimeShortcuts.clockHours[name].forEach(function(element) { - const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'role', 'button', 'href', '#'); - time_link.addEventListener('click', function(e) { + const name = + typeof DateTimeShortcuts.clockHours[inp.name] === "undefined" + ? "default_" + : inp.name; + DateTimeShortcuts.clockHours[name].forEach(function (element) { + const time_link = quickElement( + "a", + quickElement("li", time_list), + gettext(element[0]), + "role", + "button", + "href", + "#", + ); + time_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleClockQuicklink(num, element[1]); }); }); - const cancel_p = quickElement('p', clock_box); - cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#'); - cancel_link.addEventListener('click', function(e) { + const cancel_p = quickElement("p", clock_box); + cancel_p.className = "calendar-cancel"; + const cancel_link = quickElement( + "a", + cancel_p, + gettext("Cancel"), + "role", + "button", + "href", + "#", + ); + cancel_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.dismissClock(num); }); - document.addEventListener('keyup', function(event) { + document.addEventListener("keyup", function (event) { if (event.which === 27) { // ESC key closes popup DateTimeShortcuts.dismissClock(num); @@ -195,78 +237,99 @@ } }); }, - openClock: function(num) { - const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); - const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); + openClock: function (num) { + const clock_box = document.getElementById( + DateTimeShortcuts.clockDivName + num, + ); + const clock_link = document.getElementById( + DateTimeShortcuts.clockLinkName + num, + ); // Recalculate the clockbox position // is it left-to-right or right-to-left layout ? - if (window.getComputedStyle(document.body).direction !== 'rtl') { - clock_box.style.left = findPosX(clock_link) + 17 + 'px'; - } - else { + if (window.getComputedStyle(document.body).direction !== "rtl") { + clock_box.style.left = findPosX(clock_link) + 17 + "px"; + } else { // since style's width is in em, it'd be tough to calculate // px value of it. let's use an estimated px for now - clock_box.style.left = findPosX(clock_link) - 110 + 'px'; + clock_box.style.left = findPosX(clock_link) - 110 + "px"; } - clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; + clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + "px"; // Show the clock box - clock_box.style.display = 'block'; - document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); + clock_box.style.display = "block"; + document.addEventListener( + "click", + DateTimeShortcuts.dismissClockFunc[num], + ); }, - dismissClock: function(num) { - document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; - document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); + dismissClock: function (num) { + document.getElementById( + DateTimeShortcuts.clockDivName + num, + ).style.display = "none"; + document.removeEventListener( + "click", + DateTimeShortcuts.dismissClockFunc[num], + ); }, - handleClockQuicklink: function(num, val) { + handleClockQuicklink: function (num, val) { let d; if (val === -1) { d = DateTimeShortcuts.now(); - } - else { + } else { d = new Date(1970, 1, 1, val, 0, 0, 0); } - DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); + DateTimeShortcuts.clockInputs[num].value = d.strftime( + get_format("TIME_INPUT_FORMATS")[0], + ); DateTimeShortcuts.clockInputs[num].focus(); DateTimeShortcuts.dismissClock(num); }, // Add calendar widget to a given field. - addCalendar: function(inp) { + addCalendar: function (inp) { const num = DateTimeShortcuts.calendars.length; DateTimeShortcuts.calendarInputs[num] = inp; - DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; + DateTimeShortcuts.dismissCalendarFunc[num] = function () { + DateTimeShortcuts.dismissCalendar(num); + return true; + }; // Shortcut links (calendar icon and "Today" link) - const shortcuts_span = document.createElement('span'); + const shortcuts_span = document.createElement("span"); shortcuts_span.className = DateTimeShortcuts.shortCutsClass; inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - const today_link = document.createElement('a'); - today_link.href = '#'; - today_link.role = 'button'; - today_link.appendChild(document.createTextNode(gettext('Today'))); - today_link.addEventListener('click', function(e) { + const today_link = document.createElement("a"); + today_link.href = "#"; + today_link.role = "button"; + today_link.appendChild(document.createTextNode(gettext("Today"))); + today_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, 0); }); - const cal_link = document.createElement('a'); - cal_link.href = '#'; + const cal_link = document.createElement("a"); + cal_link.href = "#"; cal_link.id = DateTimeShortcuts.calendarLinkName + num; - cal_link.addEventListener('click', function(e) { + cal_link.addEventListener("click", function (e) { e.preventDefault(); // avoid triggering the document click handler to dismiss the calendar e.stopPropagation(); DateTimeShortcuts.openCalendar(num); }); quickElement( - 'span', cal_link, '', - 'class', 'date-icon', - 'title', gettext('Choose a Date') + "span", + cal_link, + "", + "class", + "date-icon", + "title", + gettext("Choose a Date"), ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(document.createTextNode("\u00A0")); shortcuts_span.appendChild(today_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild( + document.createTextNode("\u00A0|\u00A0"), + ); shortcuts_span.appendChild(cal_link); // Create calendarbox div. @@ -286,66 +349,109 @@ // </div> // <p class="calendar-cancel"><a href="#">Cancel</a></p> // </div> - const cal_box = document.createElement('div'); - cal_box.style.display = 'none'; - cal_box.style.position = 'absolute'; - cal_box.className = 'calendarbox module'; + const cal_box = document.createElement("div"); + cal_box.style.display = "none"; + cal_box.style.position = "absolute"; + cal_box.className = "calendarbox module"; cal_box.id = DateTimeShortcuts.calendarDivName1 + num; document.body.appendChild(cal_box); - cal_box.addEventListener('click', function(e) { e.stopPropagation(); }); + cal_box.addEventListener("click", function (e) { + e.stopPropagation(); + }); // next-prev links - const cal_nav = quickElement('div', cal_box); - const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#'); - cal_nav_prev.className = 'calendarnav-previous'; - cal_nav_prev.addEventListener('click', function(e) { + const cal_nav = quickElement("div", cal_box); + const cal_nav_prev = quickElement("a", cal_nav, "<", "href", "#"); + cal_nav_prev.className = "calendarnav-previous"; + cal_nav_prev.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.drawPrev(num); }); - const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#'); - cal_nav_next.className = 'calendarnav-next'; - cal_nav_next.addEventListener('click', function(e) { + const cal_nav_next = quickElement("a", cal_nav, ">", "href", "#"); + cal_nav_next.className = "calendarnav-next"; + cal_nav_next.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.drawNext(num); }); // main box - const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); - cal_main.className = 'calendar'; - DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); + const cal_main = quickElement( + "div", + cal_box, + "", + "id", + DateTimeShortcuts.calendarDivName2 + num, + ); + cal_main.className = "calendar"; + DateTimeShortcuts.calendars[num] = new Calendar( + DateTimeShortcuts.calendarDivName2 + num, + DateTimeShortcuts.handleCalendarCallback(num), + ); DateTimeShortcuts.calendars[num].drawCurrent(); // calendar shortcuts - const shortcuts = quickElement('div', cal_box); - shortcuts.className = 'calendar-shortcuts'; - let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'role', 'button', 'href', '#'); - day_link.addEventListener('click', function(e) { + const shortcuts = quickElement("div", cal_box); + shortcuts.className = "calendar-shortcuts"; + let day_link = quickElement( + "a", + shortcuts, + gettext("Yesterday"), + "role", + "button", + "href", + "#", + ); + day_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, -1); }); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Today'), 'role', 'button', 'href', '#'); - day_link.addEventListener('click', function(e) { + shortcuts.appendChild(document.createTextNode("\u00A0|\u00A0")); + day_link = quickElement( + "a", + shortcuts, + gettext("Today"), + "role", + "button", + "href", + "#", + ); + day_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, 0); }); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'role', 'button', 'href', '#'); - day_link.addEventListener('click', function(e) { + shortcuts.appendChild(document.createTextNode("\u00A0|\u00A0")); + day_link = quickElement( + "a", + shortcuts, + gettext("Tomorrow"), + "role", + "button", + "href", + "#", + ); + day_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, +1); }); // cancel bar - const cancel_p = quickElement('p', cal_box); - cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#'); - cancel_link.addEventListener('click', function(e) { + const cancel_p = quickElement("p", cal_box); + cancel_p.className = "calendar-cancel"; + const cancel_link = quickElement( + "a", + cancel_p, + gettext("Cancel"), + "role", + "button", + "href", + "#", + ); + cancel_link.addEventListener("click", function (e) { e.preventDefault(); DateTimeShortcuts.dismissCalendar(num); }); - document.addEventListener('keyup', function(event) { + document.addEventListener("keyup", function (event) { if (event.which === 27) { // ESC key closes popup DateTimeShortcuts.dismissCalendar(num); @@ -353,66 +459,89 @@ } }); }, - openCalendar: function(num) { - const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); - const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); + openCalendar: function (num) { + const cal_box = document.getElementById( + DateTimeShortcuts.calendarDivName1 + num, + ); + const cal_link = document.getElementById( + DateTimeShortcuts.calendarLinkName + num, + ); const inp = DateTimeShortcuts.calendarInputs[num]; // Determine if the current value in the input has a valid date. // If so, draw the calendar with that date's year and month. if (inp.value) { - const format = get_format('DATE_INPUT_FORMATS')[0]; + const format = get_format("DATE_INPUT_FORMATS")[0]; const selected = inp.value.strptime(format); const year = selected.getUTCFullYear(); const month = selected.getUTCMonth() + 1; const re = /\d{4}/; if (re.test(year.toString()) && month >= 1 && month <= 12) { - DateTimeShortcuts.calendars[num].drawDate(month, year, selected); + DateTimeShortcuts.calendars[num].drawDate( + month, + year, + selected, + ); } } // Recalculate the clockbox position // is it left-to-right or right-to-left layout ? - if (window.getComputedStyle(document.body).direction !== 'rtl') { - cal_box.style.left = findPosX(cal_link) + 17 + 'px'; - } - else { + if (window.getComputedStyle(document.body).direction !== "rtl") { + cal_box.style.left = findPosX(cal_link) + 17 + "px"; + } else { // since style's width is in em, it'd be tough to calculate // px value of it. let's use an estimated px for now - cal_box.style.left = findPosX(cal_link) - 180 + 'px'; + cal_box.style.left = findPosX(cal_link) - 180 + "px"; } - cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; + cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + "px"; - cal_box.style.display = 'block'; - document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); + cal_box.style.display = "block"; + document.addEventListener( + "click", + DateTimeShortcuts.dismissCalendarFunc[num], + ); }, - dismissCalendar: function(num) { - document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; - document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); + dismissCalendar: function (num) { + document.getElementById( + DateTimeShortcuts.calendarDivName1 + num, + ).style.display = "none"; + document.removeEventListener( + "click", + DateTimeShortcuts.dismissCalendarFunc[num], + ); }, - drawPrev: function(num) { + drawPrev: function (num) { DateTimeShortcuts.calendars[num].drawPreviousMonth(); }, - drawNext: function(num) { + drawNext: function (num) { DateTimeShortcuts.calendars[num].drawNextMonth(); }, - handleCalendarCallback: function(num) { - const format = get_format('DATE_INPUT_FORMATS')[0]; - return function(y, m, d) { - DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format); + handleCalendarCallback: function (num) { + const format = get_format("DATE_INPUT_FORMATS")[0]; + return function (y, m, d) { + DateTimeShortcuts.calendarInputs[num].value = new Date( + y, + m - 1, + d, + ).strftime(format); DateTimeShortcuts.calendarInputs[num].focus(); - document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; + document.getElementById( + DateTimeShortcuts.calendarDivName1 + num, + ).style.display = "none"; }; }, - handleCalendarQuickLink: function(num, offset) { + handleCalendarQuickLink: function (num, offset) { const d = DateTimeShortcuts.now(); d.setDate(d.getDate() + offset); - DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); + DateTimeShortcuts.calendarInputs[num].value = d.strftime( + get_format("DATE_INPUT_FORMATS")[0], + ); DateTimeShortcuts.calendarInputs[num].focus(); DateTimeShortcuts.dismissCalendar(num); - } + }, }; - window.addEventListener('load', DateTimeShortcuts.init); + window.addEventListener("load", DateTimeShortcuts.init); window.DateTimeShortcuts = DateTimeShortcuts; } diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js index fb5db940d6..a9c06ad4ae 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -1,25 +1,25 @@ /*global SelectBox, interpolate*/ // Handles related-objects functionality: lookup link for raw_id_fields // and Add Another links. -'use strict'; +"use strict"; { const $ = django.jQuery; let popupIndex = 0; const relatedWindows = []; function dismissChildPopups() { - relatedWindows.forEach(function(win) { - if(!win.closed) { + relatedWindows.forEach(function (win) { + if (!win.closed) { win.dismissChildPopups(); - win.close(); + win.close(); } }); } function setPopupIndex() { - if(document.getElementsByName("_popup").length > 0) { + if (document.getElementsByName("_popup").length > 0) { const index = window.name.lastIndexOf("__") + 2; - popupIndex = parseInt(window.name.substring(index)); + popupIndex = parseInt(window.name.substring(index)); } else { popupIndex = 0; } @@ -30,16 +30,20 @@ } function removePopupIndex(name) { - return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); + return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ""); } function showAdminPopup(triggeringLink, name_regexp, add_popup) { - const name = addPopupIndex(triggeringLink.id.replace(name_regexp, '')); + const name = addPopupIndex(triggeringLink.id.replace(name_regexp, "")); const href = new URL(triggeringLink.href); if (add_popup) { - href.searchParams.set('_popup', 1); + href.searchParams.set("_popup", 1); } - const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); + const win = window.open( + href, + name, + "height=500,width=800,resizable=yes,scrollbars=yes", + ); relatedWindows.push(win); win.focus(); return false; @@ -52,12 +56,15 @@ function dismissRelatedLookupPopup(win, chosenId) { const name = removePopupIndex(win.name); const elem = document.getElementById(name); - if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { - elem.value += ',' + chosenId; + if ( + elem.classList.contains("vManyToManyRawIdAdminField") && + elem.value + ) { + elem.value += "," + chosenId; } else { elem.value = chosenId; } - $(elem).trigger('change'); + $(elem).trigger("change"); const index = relatedWindows.indexOf(win); if (index > -1) { relatedWindows.splice(index, 1); @@ -71,24 +78,36 @@ function updateRelatedObjectLinks(triggeringLink) { const $this = $(triggeringLink); - const siblings = $this.nextAll('.view-related, .change-related, .delete-related'); + const siblings = $this.nextAll( + ".view-related, .change-related, .delete-related", + ); if (!siblings.length) { return; } const value = $this.val(); if (value) { - siblings.each(function() { + siblings.each(function () { const elm = $(this); - elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); - elm.removeAttr('aria-disabled'); + elm.attr( + "href", + elm.attr("data-href-template").replace("__fk__", value), + ); + elm.removeAttr("aria-disabled"); }); } else { - siblings.removeAttr('href'); - siblings.attr('aria-disabled', true); + siblings.removeAttr("href"); + siblings.attr("aria-disabled", true); } } - function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId, skipIds = []) { + function updateRelatedSelectsOptions( + currentSelect, + win, + objId, + newRepr, + newId, + skipIds = [], + ) { // After create/edit a model from the options next to the current // select (+ or :pencil:) update ForeignKey PK of the rest of selects // in the page. @@ -96,12 +115,18 @@ const path = win.location.pathname; // Extract the model from the popup url '.../<model>/add/' or // '.../<model>/<id>/change/' depending the action (add or change). - const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; + const modelName = + path.split("/")[path.split("/").length - (objId ? 4 : 3)]; // Select elements with a specific model reference and context of "available-source". - const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] [data-context="available-source"]`); + const selectsRelated = document.querySelectorAll( + `[data-model-ref="${modelName}"] [data-context="available-source"]`, + ); - selectsRelated.forEach(function(select) { - if (currentSelect === select || skipIds && skipIds.includes(select.id)) { + selectsRelated.forEach(function (select) { + if ( + currentSelect === select || + (skipIds && skipIds.includes(select.id)) + ) { return; } @@ -112,14 +137,14 @@ select.options.add(option); // Update SelectBox cache for related fields. if ( - window.SelectBox !== undefined - && !SelectBox.cache[currentSelect.id] + window.SelectBox !== undefined && + !SelectBox.cache[currentSelect.id] && // Only if SelectBox is managing that field. - && SelectBox.cache[select.id] + SelectBox.cache[select.id] ) { SelectBox.add_to_cache(select.id, option); // Sort if there are any groups present - if (SelectBox.cache[select.id].some(item => item.group)) { + if (SelectBox.cache[select.id].some((item) => item.group)) { SelectBox.sort(select.id); } SelectBox.redisplay(select.id); @@ -137,18 +162,26 @@ const elem = document.getElementById(name); if (elem) { const elemName = elem.nodeName.toUpperCase(); - if (elemName === 'SELECT') { - elem.options[elem.options.length] = new Option(newRepr, newId, true, true); + if (elemName === "SELECT") { + elem.options[elem.options.length] = new Option( + newRepr, + newId, + true, + true, + ); updateRelatedSelectsOptions(elem, win, null, newRepr, newId); - } else if (elemName === 'INPUT') { - if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { - elem.value += ',' + newId; + } else if (elemName === "INPUT") { + if ( + elem.classList.contains("vManyToManyRawIdAdminField") && + elem.value + ) { + elem.value += "," + newId; } else { elem.value = newId; } } // Trigger a change event to update related links if required. - $(elem).trigger('change'); + $(elem).trigger("change"); } else { const toId = name + "_to"; const toElem = document.getElementById(toId); @@ -156,13 +189,20 @@ newOption.group = optgroup; SelectBox.add_to_cache(toId, newOption); // Sort if there are any groups present - if (SelectBox.cache[toId].some(item => item.group)) { + if (SelectBox.cache[toId].some((item) => item.group)) { SelectBox.sort(toId); } SelectBox.redisplay(toId); - if (toElem && toElem.nodeName.toUpperCase() === 'SELECT') { + if (toElem && toElem.nodeName.toUpperCase() === "SELECT") { const skipIds = [name + "_from"]; - updateRelatedSelectsOptions(toElem, win, null, newRepr, newId, skipIds); + updateRelatedSelectsOptions( + toElem, + win, + null, + newRepr, + newId, + skipIds, + ); } } const index = relatedWindows.indexOf(win); @@ -173,22 +213,32 @@ } function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { - const id = removePopupIndex(win.name.replace(/^edit_/, '')); - const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + const id = removePopupIndex(win.name.replace(/^edit_/, "")); + const selectsSelector = interpolate("#%s, #%s_from, #%s_to", [ + id, + id, + id, + ]); const selects = $(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - this.textContent = newRepr; - this.value = newId; - } - }).trigger('change'); + selects + .find("option") + .each(function () { + if (this.value === objId) { + this.textContent = newRepr; + this.value = newId; + } + }) + .trigger("change"); updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId); - selects.next().find('.select2-selection__rendered').each(function() { - // The element can have a clear button as a child. - // Use the lastChild to modify only the displayed value. - this.lastChild.textContent = newRepr; - this.title = newRepr; - }); + selects + .next() + .find(".select2-selection__rendered") + .each(function () { + // The element can have a clear button as a child. + // Use the lastChild to modify only the displayed value. + this.lastChild.textContent = newRepr; + this.title = newRepr; + }); const index = relatedWindows.indexOf(win); if (index > -1) { relatedWindows.splice(index, 1); @@ -197,14 +247,21 @@ } function dismissDeleteRelatedObjectPopup(win, objId) { - const id = removePopupIndex(win.name.replace(/^delete_/, '')); - const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + const id = removePopupIndex(win.name.replace(/^delete_/, "")); + const selectsSelector = interpolate("#%s, #%s_from, #%s_to", [ + id, + id, + id, + ]); const selects = $(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - $(this).remove(); - } - }).trigger('change'); + selects + .find("option") + .each(function () { + if (this.value === objId) { + $(this).remove(); + } + }) + .trigger("change"); const index = relatedWindows.indexOf(win); if (index > -1) { relatedWindows.splice(index, 1); @@ -226,37 +283,46 @@ window.showAddAnotherPopup = showRelatedObjectPopup; window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup; - window.addEventListener('unload', function(evt) { + window.addEventListener("unload", function (evt) { window.dismissChildPopups(); }); - $(document).ready(function() { + $(document).ready(function () { setPopupIndex(); - $("a[data-popup-opener]").on('click', function(event) { + $("a[data-popup-opener]").on("click", function (event) { event.preventDefault(); - opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener")); + opener.dismissRelatedLookupPopup( + window, + $(this).data("popup-opener"), + ); }); - $('body').on('click', '.related-widget-wrapper-link[data-popup="yes"]', function(e) { - e.preventDefault(); - if (this.href) { - const event = $.Event('django:show-related', {href: this.href}); - $(this).trigger(event); - if (!event.isDefaultPrevented()) { - showRelatedObjectPopup(this); + $("body").on( + "click", + '.related-widget-wrapper-link[data-popup="yes"]', + function (e) { + e.preventDefault(); + if (this.href) { + const event = $.Event("django:show-related", { + href: this.href, + }); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showRelatedObjectPopup(this); + } } - } - }); - $('body').on('change', '.related-widget-wrapper select', function(e) { - const event = $.Event('django:update-related'); + }, + ); + $("body").on("change", ".related-widget-wrapper select", function (e) { + const event = $.Event("django:update-related"); $(this).trigger(event); if (!event.isDefaultPrevented()) { updateRelatedObjectLinks(this); } }); - $('.related-widget-wrapper select').trigger('change'); - $('body').on('click', '.related-lookup', function(e) { + $(".related-widget-wrapper select").trigger("change"); + $("body").on("click", ".related-lookup", function (e) { e.preventDefault(); - const event = $.Event('django:lookup-related'); + const event = $.Event("django:lookup-related"); $(this).trigger(event); if (!event.isDefaultPrevented()) { showRelatedObjectLookupPopup(this); diff --git a/django/contrib/admin/static/admin/js/autocomplete.js b/django/contrib/admin/static/admin/js/autocomplete.js index d3daeab890..30fd5209ae 100644 --- a/django/contrib/admin/static/admin/js/autocomplete.js +++ b/django/contrib/admin/static/admin/js/autocomplete.js @@ -1,9 +1,9 @@ -'use strict'; +"use strict"; { const $ = django.jQuery; - $.fn.djangoAdminSelect2 = function() { - $.each(this, function(i, element) { + $.fn.djangoAdminSelect2 = function () { + $.each(this, function (i, element) { $(element).select2({ ajax: { data: (params) => { @@ -12,22 +12,22 @@ page: params.page, app_label: element.dataset.appLabel, model_name: element.dataset.modelName, - field_name: element.dataset.fieldName + field_name: element.dataset.fieldName, }; - } - } + }, + }, }); }); return this; }; - $(function() { + $(function () { // Initialize all autocomplete widgets except the one in the template // form used when a new formset is added. - $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2(); + $(".admin-autocomplete").not("[name*=__prefix__]").djangoAdminSelect2(); }); - document.addEventListener('formset:added', (event) => { - $(event.target).find('.admin-autocomplete').djangoAdminSelect2(); + document.addEventListener("formset:added", (event) => { + $(event.target).find(".admin-autocomplete").djangoAdminSelect2(); }); } diff --git a/django/contrib/admin/static/admin/js/calendar.js b/django/contrib/admin/static/admin/js/calendar.js index b13242078a..f10a584fa9 100644 --- a/django/contrib/admin/static/admin/js/calendar.js +++ b/django/contrib/admin/static/admin/js/calendar.js @@ -3,91 +3,102 @@ calendar.js - Calendar functions by Adrian Holovaty depends on core.js for utility functions like removeChildren or quickElement */ -'use strict'; +"use strict"; { // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions const CalendarNamespace = { monthsOfYear: [ - gettext('January'), - gettext('February'), - gettext('March'), - gettext('April'), - gettext('May'), - gettext('June'), - gettext('July'), - gettext('August'), - gettext('September'), - gettext('October'), - gettext('November'), - gettext('December') + gettext("January"), + gettext("February"), + gettext("March"), + gettext("April"), + gettext("May"), + gettext("June"), + gettext("July"), + gettext("August"), + gettext("September"), + gettext("October"), + gettext("November"), + gettext("December"), ], monthsOfYearAbbrev: [ - pgettext('abbrev. month January', 'Jan'), - pgettext('abbrev. month February', 'Feb'), - pgettext('abbrev. month March', 'Mar'), - pgettext('abbrev. month April', 'Apr'), - pgettext('abbrev. month May', 'May'), - pgettext('abbrev. month June', 'Jun'), - pgettext('abbrev. month July', 'Jul'), - pgettext('abbrev. month August', 'Aug'), - pgettext('abbrev. month September', 'Sep'), - pgettext('abbrev. month October', 'Oct'), - pgettext('abbrev. month November', 'Nov'), - pgettext('abbrev. month December', 'Dec') + pgettext("abbrev. month January", "Jan"), + pgettext("abbrev. month February", "Feb"), + pgettext("abbrev. month March", "Mar"), + pgettext("abbrev. month April", "Apr"), + pgettext("abbrev. month May", "May"), + pgettext("abbrev. month June", "Jun"), + pgettext("abbrev. month July", "Jul"), + pgettext("abbrev. month August", "Aug"), + pgettext("abbrev. month September", "Sep"), + pgettext("abbrev. month October", "Oct"), + pgettext("abbrev. month November", "Nov"), + pgettext("abbrev. month December", "Dec"), ], daysOfWeek: [ - gettext('Sunday'), - gettext('Monday'), - gettext('Tuesday'), - gettext('Wednesday'), - gettext('Thursday'), - gettext('Friday'), - gettext('Saturday') + gettext("Sunday"), + gettext("Monday"), + gettext("Tuesday"), + gettext("Wednesday"), + gettext("Thursday"), + gettext("Friday"), + gettext("Saturday"), ], daysOfWeekAbbrev: [ - pgettext('abbrev. day Sunday', 'Sun'), - pgettext('abbrev. day Monday', 'Mon'), - pgettext('abbrev. day Tuesday', 'Tue'), - pgettext('abbrev. day Wednesday', 'Wed'), - pgettext('abbrev. day Thursday', 'Thur'), - pgettext('abbrev. day Friday', 'Fri'), - pgettext('abbrev. day Saturday', 'Sat') + pgettext("abbrev. day Sunday", "Sun"), + pgettext("abbrev. day Monday", "Mon"), + pgettext("abbrev. day Tuesday", "Tue"), + pgettext("abbrev. day Wednesday", "Wed"), + pgettext("abbrev. day Thursday", "Thur"), + pgettext("abbrev. day Friday", "Fri"), + pgettext("abbrev. day Saturday", "Sat"), ], daysOfWeekInitial: [ - pgettext('one letter Sunday', 'S'), - pgettext('one letter Monday', 'M'), - pgettext('one letter Tuesday', 'T'), - pgettext('one letter Wednesday', 'W'), - pgettext('one letter Thursday', 'T'), - pgettext('one letter Friday', 'F'), - pgettext('one letter Saturday', 'S') + pgettext("one letter Sunday", "S"), + pgettext("one letter Monday", "M"), + pgettext("one letter Tuesday", "T"), + pgettext("one letter Wednesday", "W"), + pgettext("one letter Thursday", "T"), + pgettext("one letter Friday", "F"), + pgettext("one letter Saturday", "S"), ], - firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), - isLeapYear: function(year) { - return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0)); + firstDayOfWeek: parseInt(get_format("FIRST_DAY_OF_WEEK")), + isLeapYear: function (year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; }, - getDaysInMonth: function(month, year) { + getDaysInMonth: function (month, year) { let days; - if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { + if ( + month === 1 || + month === 3 || + month === 5 || + month === 7 || + month === 8 || + month === 10 || + month === 12 + ) { days = 31; - } - else if (month === 4 || month === 6 || month === 9 || month === 11) { + } else if ( + month === 4 || + month === 6 || + month === 9 || + month === 11 + ) { days = 30; - } - else if (month === 2 && CalendarNamespace.isLeapYear(year)) { + } else if (month === 2 && CalendarNamespace.isLeapYear(year)) { days = 29; - } - else { + } else { days = 28; } return days; }, - draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 + draw: function (month, year, div_id, callback, selected) { + // month = 1-12, year = 1-9999 const today = new Date(); const todayDay = today.getDate(); const todayMonth = today.getMonth() + 1; const todayYear = today.getFullYear(); - let todayClass = ''; + let todayClass = ""; // Use UTC functions here because the date field does not contain time // and using the UTC function variants prevent the local time offset @@ -101,33 +112,49 @@ depends on core.js for utility functions like removeChildren or quickElement // The day variable above will be 1 instead of 2 in, say, US Pacific time // zone. let isSelectedMonth = false; - if (typeof selected !== 'undefined') { - isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); + if (typeof selected !== "undefined") { + isSelectedMonth = + selected.getUTCFullYear() === year && + selected.getUTCMonth() + 1 === month; } month = parseInt(month); year = parseInt(year); const calDiv = document.getElementById(div_id); removeChildren(calDiv); - const calTable = document.createElement('table'); - quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); - const tableBody = quickElement('tbody', calTable); + const calTable = document.createElement("table"); + quickElement( + "caption", + calTable, + CalendarNamespace.monthsOfYear[month - 1] + " " + year, + ); + const tableBody = quickElement("tbody", calTable); // Draw days-of-week header - let tableRow = quickElement('tr', tableBody); + let tableRow = quickElement("tr", tableBody); for (let i = 0; i < 7; i++) { - quickElement('th', tableRow, CalendarNamespace.daysOfWeekInitial[(i + CalendarNamespace.firstDayOfWeek) % 7]); + quickElement( + "th", + tableRow, + CalendarNamespace.daysOfWeekInitial[ + (i + CalendarNamespace.firstDayOfWeek) % 7 + ], + ); } - const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); + const startingPos = new Date( + year, + month - 1, + 1 - CalendarNamespace.firstDayOfWeek, + ).getDay(); const days = CalendarNamespace.getDaysInMonth(month, year); let nonDayCell; // Draw blanks before first of month - tableRow = quickElement('tr', tableBody); + tableRow = quickElement("tr", tableBody); for (let i = 0; i < startingPos; i++) { - nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell = quickElement("td", tableRow, " "); nonDayCell.className = "nonday"; } @@ -143,36 +170,54 @@ depends on core.js for utility functions like removeChildren or quickElement let currentDay = 1; for (let i = startingPos; currentDay <= days; i++) { if (i % 7 === 0 && currentDay !== 1) { - tableRow = quickElement('tr', tableBody); + tableRow = quickElement("tr", tableBody); } - if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { - todayClass = 'today'; + if ( + currentDay === todayDay && + month === todayMonth && + year === todayYear + ) { + todayClass = "today"; } else { - todayClass = ''; + todayClass = ""; } // use UTC function; see above for explanation. if (isSelectedMonth && currentDay === selected.getUTCDate()) { - if (todayClass !== '') { + if (todayClass !== "") { todayClass += " "; } todayClass += "selected"; } - const cell = quickElement('td', tableRow, '', 'class', todayClass); - const link = quickElement('a', cell, currentDay, 'role', 'button', 'href', '#'); - link.addEventListener('click', calendarMonth(year, month)); + const cell = quickElement( + "td", + tableRow, + "", + "class", + todayClass, + ); + const link = quickElement( + "a", + cell, + currentDay, + "role", + "button", + "href", + "#", + ); + link.addEventListener("click", calendarMonth(year, month)); currentDay++; } // Draw blanks after end of month (optional, but makes for valid code) while (tableRow.childNodes.length < 7) { - nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell = quickElement("td", tableRow, " "); nonDayCell.className = "nonday"; } calDiv.appendChild(calTable); - } + }, }; // Calendar -- A calendar instance @@ -187,52 +232,56 @@ depends on core.js for utility functions like removeChildren or quickElement this.today = new Date(); this.currentMonth = this.today.getMonth() + 1; this.currentYear = this.today.getFullYear(); - if (typeof selected !== 'undefined') { + if (typeof selected !== "undefined") { this.selected = selected; } } Calendar.prototype = { - drawCurrent: function() { - CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); + drawCurrent: function () { + CalendarNamespace.draw( + this.currentMonth, + this.currentYear, + this.div_id, + this.callback, + this.selected, + ); }, - drawDate: function(month, year, selected) { + drawDate: function (month, year, selected) { this.currentMonth = month; this.currentYear = year; - if(selected) { + if (selected) { this.selected = selected; } this.drawCurrent(); }, - drawPreviousMonth: function() { + drawPreviousMonth: function () { if (this.currentMonth === 1) { this.currentMonth = 12; this.currentYear--; - } - else { + } else { this.currentMonth--; } this.drawCurrent(); }, - drawNextMonth: function() { + drawNextMonth: function () { if (this.currentMonth === 12) { this.currentMonth = 1; this.currentYear++; - } - else { + } else { this.currentMonth++; } this.drawCurrent(); }, - drawPreviousYear: function() { + drawPreviousYear: function () { this.currentYear--; this.drawCurrent(); }, - drawNextYear: function() { + drawNextYear: function () { this.currentYear++; this.drawCurrent(); - } + }, }; window.Calendar = Calendar; window.CalendarNamespace = CalendarNamespace; diff --git a/django/contrib/admin/static/admin/js/cancel.js b/django/contrib/admin/static/admin/js/cancel.js index 3069c6f27b..b4bc29c8db 100644 --- a/django/contrib/admin/static/admin/js/cancel.js +++ b/django/contrib/admin/static/admin/js/cancel.js @@ -1,29 +1,29 @@ -'use strict'; +"use strict"; { // Call function fn when the DOM is loaded and ready. If it is already // loaded, call the function now. // http://youmightnotneedjquery.com/#ready function ready(fn) { - if (document.readyState !== 'loading') { + if (document.readyState !== "loading") { fn(); } else { - document.addEventListener('DOMContentLoaded', fn); + document.addEventListener("DOMContentLoaded", fn); } } - ready(function() { + ready(function () { function handleClick(event) { event.preventDefault(); const params = new URLSearchParams(window.location.search); - if (params.has('_popup')) { + if (params.has("_popup")) { window.close(); // Close the popup. } else { window.history.back(); // Otherwise, go back. } } - document.querySelectorAll('.cancel-link').forEach(function(el) { - el.addEventListener('click', handleClick); + document.querySelectorAll(".cancel-link").forEach(function (el) { + el.addEventListener("click", handleClick); }); }); } diff --git a/django/contrib/admin/static/admin/js/change_form.js b/django/contrib/admin/static/admin/js/change_form.js index 96a4c62ef4..f692d7ffe1 100644 --- a/django/contrib/admin/static/admin/js/change_form.js +++ b/django/contrib/admin/static/admin/js/change_form.js @@ -1,13 +1,18 @@ -'use strict'; +"use strict"; { - const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA']; - const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName; + const inputTags = ["BUTTON", "INPUT", "SELECT", "TEXTAREA"]; + const modelName = document.getElementById("django-admin-form-add-constants") + .dataset.modelName; if (modelName) { - const form = document.getElementById(modelName + '_form'); + const form = document.getElementById(modelName + "_form"); for (const element of form.elements) { // HTMLElement.offsetParent returns null when the element is not // rendered. - if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) { + if ( + inputTags.includes(element.tagName) && + !element.disabled && + element.offsetParent + ) { element.focus(); break; } diff --git a/django/contrib/admin/static/admin/js/core.js b/django/contrib/admin/static/admin/js/core.js index 10504d4a84..d36dad6f49 100644 --- a/django/contrib/admin/static/admin/js/core.js +++ b/django/contrib/admin/static/admin/js/core.js @@ -1,5 +1,5 @@ // Core JavaScript helper functions -'use strict'; +"use strict"; // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); function quickElement() { @@ -57,59 +57,67 @@ function findPosY(obj) { // Date object extensions // ---------------------------------------------------------------------------- { - Date.prototype.getTwelveHours = function() { + Date.prototype.getTwelveHours = function () { return this.getHours() % 12 || 12; }; - Date.prototype.getTwoDigitMonth = function() { - return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); + Date.prototype.getTwoDigitMonth = function () { + return this.getMonth() < 9 + ? "0" + (this.getMonth() + 1) + : this.getMonth() + 1; }; - Date.prototype.getTwoDigitDate = function() { - return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); + Date.prototype.getTwoDigitDate = function () { + return this.getDate() < 10 ? "0" + this.getDate() : this.getDate(); }; - Date.prototype.getTwoDigitTwelveHour = function() { - return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); + Date.prototype.getTwoDigitTwelveHour = function () { + return this.getTwelveHours() < 10 + ? "0" + this.getTwelveHours() + : this.getTwelveHours(); }; - Date.prototype.getTwoDigitHour = function() { - return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); + Date.prototype.getTwoDigitHour = function () { + return this.getHours() < 10 ? "0" + this.getHours() : this.getHours(); }; - Date.prototype.getTwoDigitMinute = function() { - return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); + Date.prototype.getTwoDigitMinute = function () { + return this.getMinutes() < 10 + ? "0" + this.getMinutes() + : this.getMinutes(); }; - Date.prototype.getTwoDigitSecond = function() { - return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); + Date.prototype.getTwoDigitSecond = function () { + return this.getSeconds() < 10 + ? "0" + this.getSeconds() + : this.getSeconds(); }; - Date.prototype.getAbbrevDayName = function() { + Date.prototype.getAbbrevDayName = function () { return typeof window.CalendarNamespace === "undefined" - ? '0' + this.getDay() + ? "0" + this.getDay() : window.CalendarNamespace.daysOfWeekAbbrev[this.getDay()]; }; - Date.prototype.getFullDayName = function() { + Date.prototype.getFullDayName = function () { return typeof window.CalendarNamespace === "undefined" - ? '0' + this.getDay() + ? "0" + this.getDay() : window.CalendarNamespace.daysOfWeek[this.getDay()]; }; - Date.prototype.getAbbrevMonthName = function() { + Date.prototype.getAbbrevMonthName = function () { return typeof window.CalendarNamespace === "undefined" ? this.getTwoDigitMonth() : window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()]; }; - Date.prototype.getFullMonthName = function() { + Date.prototype.getFullMonthName = function () { return typeof window.CalendarNamespace === "undefined" ? this.getTwoDigitMonth() : window.CalendarNamespace.monthsOfYear[this.getMonth()]; }; - Date.prototype.strftime = function(format) { + Date.prototype.strftime = function (format) { const fields = { a: this.getAbbrevDayName(), A: this.getFullDayName(), @@ -121,22 +129,22 @@ function findPosY(obj) { I: this.getTwoDigitTwelveHour(), m: this.getTwoDigitMonth(), M: this.getTwoDigitMinute(), - p: (this.getHours() >= 12) ? 'PM' : 'AM', + p: this.getHours() >= 12 ? "PM" : "AM", S: this.getTwoDigitSecond(), - w: '0' + this.getDay(), + w: "0" + this.getDay(), x: this.toLocaleDateString(), X: this.toLocaleTimeString(), - y: ('' + this.getFullYear()).substr(2, 4), - Y: '' + this.getFullYear(), - '%': '%' + y: ("" + this.getFullYear()).substr(2, 4), + Y: "" + this.getFullYear(), + "%": "%", }; - let result = '', i = 0; + let result = "", + i = 0; while (i < format.length) { - if (format.charAt(i) === '%') { + if (format.charAt(i) === "%") { result += fields[format.charAt(i + 1)]; ++i; - } - else { + } else { result += format.charAt(i); } ++i; @@ -147,32 +155,34 @@ function findPosY(obj) { // ---------------------------------------------------------------------------- // String object extensions // ---------------------------------------------------------------------------- - String.prototype.strptime = function(format) { + String.prototype.strptime = function (format) { const split_format = format.split(/[.\-/]/); const date = this.split(/[.\-/]/); let i = 0; let day, month, year; while (i < split_format.length) { switch (split_format[i]) { - case "%d": - day = date[i]; - break; - case "%m": - month = date[i] - 1; - break; - case "%Y": - year = date[i]; - break; - case "%y": - // A %y value in the range of [00, 68] is in the current - // century, while [69, 99] is in the previous century, - // according to the Open Group Specification. - if (parseInt(date[i], 10) >= 69) { + case "%d": + day = date[i]; + break; + case "%m": + month = date[i] - 1; + break; + case "%Y": year = date[i]; - } else { - year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100; - } - break; + break; + case "%y": + // A %y value in the range of [00, 68] is in the current + // century, while [69, 99] is in the previous century, + // according to the Open Group Specification. + if (parseInt(date[i], 10) >= 69) { + year = date[i]; + } else { + year = + new Date(Date.UTC(date[i], 0)).getUTCFullYear() + + 100; + } + break; } ++i; } diff --git a/django/contrib/admin/static/admin/js/filters.js b/django/contrib/admin/static/admin/js/filters.js index f5536ebc2d..c765264b3f 100644 --- a/django/contrib/admin/static/admin/js/filters.js +++ b/django/contrib/admin/static/admin/js/filters.js @@ -1,30 +1,39 @@ /** * Persist changelist filters state (collapsed/expanded). */ -'use strict'; +"use strict"; { // Init filters. - let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState')); + let filters = JSON.parse( + sessionStorage.getItem("django.admin.filtersState"), + ); if (!filters) { filters = {}; } Object.entries(filters).forEach(([key, value]) => { - const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`); + const detailElement = document.querySelector( + `[data-filter-title='${CSS.escape(key)}']`, + ); // Check if the filter is present, it could be from other view. if (detailElement) { - value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open'); + value + ? detailElement.setAttribute("open", "") + : detailElement.removeAttribute("open"); } }); // Save filter state when clicks. - const details = document.querySelectorAll('details'); - details.forEach(detail => { - detail.addEventListener('toggle', event => { + const details = document.querySelectorAll("details"); + details.forEach((detail) => { + detail.addEventListener("toggle", (event) => { filters[`${event.target.dataset.filterTitle}`] = detail.open; - sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters)); + sessionStorage.setItem( + "django.admin.filtersState", + JSON.stringify(filters), + ); }); }); } diff --git a/django/contrib/admin/static/admin/js/inlines.js b/django/contrib/admin/static/admin/js/inlines.js index cd3726cf30..9944252295 100644 --- a/django/contrib/admin/static/admin/js/inlines.js +++ b/django/contrib/admin/static/admin/js/inlines.js @@ -15,18 +15,21 @@ * Licensed under the New BSD License * See: https://opensource.org/licenses/bsd-license.php */ -'use strict'; +"use strict"; { const $ = django.jQuery; - $.fn.formset = function(opts) { + $.fn.formset = function (opts) { const options = $.extend({}, $.fn.formset.defaults, opts); const $this = $(this); const $parent = $this.parent(); - const updateElementIndex = function(el, prefix, ndx) { + const updateElementIndex = function (el, prefix, ndx) { const id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); const replacement = prefix + "-" + ndx; if ($(el).prop("for")) { - $(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); + $(el).prop( + "for", + $(el).prop("for").replace(id_regex, replacement), + ); } if (el.id) { el.id = el.id.replace(id_regex, replacement); @@ -35,33 +38,58 @@ el.name = el.name.replace(id_regex, replacement); } }; - const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); + const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop( + "autocomplete", + "off", + ); let nextIndex = parseInt(totalForms.val(), 10); - const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); - const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop("autocomplete", "off"); + const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop( + "autocomplete", + "off", + ); + const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop( + "autocomplete", + "off", + ); let addButton; /** * The "Add another MyModel" button below the inline forms. */ - const addInlineAddButton = function() { + const addInlineAddButton = function () { if (addButton === null) { if ($this.prop("tagName") === "TR") { // If forms are laid out as table rows, insert the // "add" button in a new table row: const numCols = $this.eq(-1).children().length; - $parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a role="button" class="addlink" href="#">' + options.addText + "</a></tr>"); + $parent.append( + '<tr class="' + + options.addCssClass + + '"><td colspan="' + + numCols + + '"><a role="button" class="addlink" href="#">' + + options.addText + + "</a></tr>", + ); addButton = $parent.find("tr:last a"); } else { // Otherwise, insert it immediately after the last form: - $this.filter(":last").after('<div class="' + options.addCssClass + '"><a role="button" class="addlink" href="#">' + options.addText + "</a></div>"); + $this + .filter(":last") + .after( + '<div class="' + + options.addCssClass + + '"><a role="button" class="addlink" href="#">' + + options.addText + + "</a></div>", + ); addButton = $this.filter(":last").next().find("a"); } } - addButton.on('click', addInlineClickHandler); + addButton.on("click", addInlineClickHandler); }; - const addInlineClickHandler = function(e) { + const addInlineClickHandler = function (e) { e.preventDefault(); const template = $("#" + options.prefix + "-empty"); const row = template.clone(true); @@ -69,7 +97,7 @@ .addClass(options.formCssClass) .attr("id", options.prefix + "-" + nextIndex); addInlineDeleteButton(row); - row.find("*").each(function() { + row.find("*").each(function () { updateElementIndex(this, options.prefix, totalForms.val()); }); // Insert the new form when it has been fully edited. @@ -78,55 +106,81 @@ $(totalForms).val(parseInt(totalForms.val(), 10) + 1); nextIndex += 1; // Hide the add button if there's a limit and it's been reached. - if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) { + if ( + maxForms.val() !== "" && + maxForms.val() - totalForms.val() <= 0 + ) { addButton.parent().hide(); } // Show the remove buttons if there are more than min_num. - toggleDeleteButtonVisibility(row.closest('.inline-group')); + toggleDeleteButtonVisibility(row.closest(".inline-group")); // Pass the new form to the post-add callback, if provided. if (options.added) { options.added(row); } - row.get(0).dispatchEvent(new CustomEvent("formset:added", { - bubbles: true, - detail: { - formsetName: options.prefix - } - })); + row.get(0).dispatchEvent( + new CustomEvent("formset:added", { + bubbles: true, + detail: { + formsetName: options.prefix, + }, + }), + ); }; /** * The "X" button that is part of every unsaved inline. * (When saved, it is replaced with a "Delete" checkbox.) */ - const addInlineDeleteButton = function(row) { + const addInlineDeleteButton = function (row) { if (row.is("tr")) { // If the forms are laid out in table rows, insert // the remove button into the last table cell: - row.children(":last").append('<div><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>"); + row.children(":last").append( + '<div><a role="button" class="' + + options.deleteCssClass + + '" href="#">' + + options.deleteText + + "</a></div>", + ); } else if (row.is("ul") || row.is("ol")) { // If they're laid out as an ordered/unordered list, // insert an <li> after the last list item: - row.append('<li><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>"); + row.append( + '<li><a role="button" class="' + + options.deleteCssClass + + '" href="#">' + + options.deleteText + + "</a></li>", + ); } else { // Otherwise, just insert the remove button as the // last child element of the form's container: - row.children(":first").append('<span><a role="button" class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>"); + row.children(":first").append( + '<span><a role="button" class="' + + options.deleteCssClass + + '" href="#">' + + options.deleteText + + "</a></span>", + ); } // Add delete handler for each row. - row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this)); + row.find("a." + options.deleteCssClass).on( + "click", + inlineDeleteHandler.bind(this), + ); }; - const inlineDeleteHandler = function(e1) { + const inlineDeleteHandler = function (e1) { e1.preventDefault(); const deleteButton = $(e1.target); - const row = deleteButton.closest('.' + options.formCssClass); - const inlineGroup = row.closest('.inline-group'); + const row = deleteButton.closest("." + options.formCssClass); + const inlineGroup = row.closest(".inline-group"); // Remove the parent form containing this button, // and also remove the relevant row with non-field errors: const prevRow = row.prev(); - if (prevRow.length && prevRow.hasClass('row-form-errors')) { + if (prevRow.length && prevRow.hasClass("row-form-errors")) { prevRow.remove(); } row.remove(); @@ -135,16 +189,18 @@ if (options.removed) { options.removed(row); } - document.dispatchEvent(new CustomEvent("formset:removed", { - detail: { - formsetName: options.prefix - } - })); + document.dispatchEvent( + new CustomEvent("formset:removed", { + detail: { + formsetName: options.prefix, + }, + }), + ); // Update the TOTAL_FORMS form count. const forms = $("." + options.formCssClass); $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); // Show add button again once below maximum number. - if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) { + if (maxForms.val() === "" || maxForms.val() - forms.length > 0) { addButton.parent().show(); } // Hide the remove buttons if at min_num. @@ -152,7 +208,7 @@ // Also, update names and ids for all remaining form controls so // they remain in sequence: let i, formCount; - const updateElementCallback = function() { + const updateElementCallback = function () { updateElementIndex(this, options.prefix, i); }; for (i = 0, formCount = forms.length; i < formCount; i++) { @@ -161,22 +217,35 @@ } }; - const toggleDeleteButtonVisibility = function(inlineGroup) { - if ((minForms.val() !== '') && (minForms.val() - totalForms.val()) >= 0) { - inlineGroup.find('.inline-deletelink').hide(); + const toggleDeleteButtonVisibility = function (inlineGroup) { + if ( + minForms.val() !== "" && + minForms.val() - totalForms.val() >= 0 + ) { + inlineGroup.find(".inline-deletelink").hide(); } else { - inlineGroup.find('.inline-deletelink').show(); + inlineGroup.find(".inline-deletelink").show(); } }; - $this.each(function(i) { - $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); + $this.each(function (i) { + $(this) + .not("." + options.emptyCssClass) + .addClass(options.formCssClass); }); // Create the delete buttons for all unsaved inlines: - $this.filter('.' + options.formCssClass + ':not(.has_original):not(.' + options.emptyCssClass + ')').each(function() { - addInlineDeleteButton($(this)); - }); + $this + .filter( + "." + + options.formCssClass + + ":not(.has_original):not(." + + options.emptyCssClass + + ")", + ) + .each(function () { + addInlineDeleteButton($(this)); + }); toggleDeleteButtonVisibility($this); // Create the add button, initially hidden. @@ -185,7 +254,8 @@ // Show the add button if allowed to add more items. // Note that max_num = None translates to a blank string. - const showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0; + const showAddButton = + maxForms.val() === "" || maxForms.val() - totalForms.val() > 0; if ($this.length && showAddButton) { addButton.parent().show(); } else { @@ -206,15 +276,14 @@ formCssClass: "dynamic-form", // CSS class applied to each form in a formset added: null, // Function called each time a new form is added removed: null, // Function called each time a form is deleted - addButton: null // Existing add button to use + addButton: null, // Existing add button to use }; - // Tabular inlines --------------------------------------------------------- - $.fn.tabularFormset = function(selector, options) { + $.fn.tabularFormset = function (selector, options) { const $rows = $(this); - const reinitDateTimeShortCuts = function() { + const reinitDateTimeShortCuts = function () { // Reinitialize the calendar and clock widgets by force if (typeof DateTimeShortcuts !== "undefined") { $(".datetimeshortcuts").remove(); @@ -222,30 +291,36 @@ } }; - const updateSelectFilter = function() { + const updateSelectFilter = function () { // If any SelectFilter widgets are a part of the new form, // instantiate a new SelectFilter instance for it. - if (typeof SelectFilter !== 'undefined') { - $('.selectfilter').each(function(index, value) { + if (typeof SelectFilter !== "undefined") { + $(".selectfilter").each(function (index, value) { SelectFilter.init(value.id, this.dataset.fieldName, false); }); - $('.selectfilterstacked').each(function(index, value) { + $(".selectfilterstacked").each(function (index, value) { SelectFilter.init(value.id, this.dataset.fieldName, true); }); } }; - const initPrepopulatedFields = function(row) { - row.find('.prepopulated_field').each(function() { + const initPrepopulatedFields = function (row) { + row.find(".prepopulated_field").each(function () { const field = $(this), - input = field.find('input, select, textarea'), - dependency_list = input.data('dependency_list') || [], + input = field.find("input, select, textarea"), + dependency_list = input.data("dependency_list") || [], dependencies = []; - $.each(dependency_list, function(i, field_name) { - dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id')); + $.each(dependency_list, function (i, field_name) { + dependencies.push( + "#" + + row + .find(".field-" + field_name) + .find("input, select, textarea") + .attr("id"), + ); }); if (dependencies.length) { - input.prepopulate(dependencies, input.attr('maxlength')); + input.prepopulate(dependencies, input.attr("maxlength")); } }); }; @@ -257,28 +332,34 @@ deleteCssClass: "inline-deletelink", deleteText: options.deleteText, emptyCssClass: "empty-form", - added: function(row) { + added: function (row) { initPrepopulatedFields(row); reinitDateTimeShortCuts(); updateSelectFilter(); }, - addButton: options.addButton + addButton: options.addButton, }); return $rows; }; // Stacked inlines --------------------------------------------------------- - $.fn.stackedFormset = function(selector, options) { + $.fn.stackedFormset = function (selector, options) { const $rows = $(this); - const updateInlineLabel = function(row) { - $(selector).find(".inline_label").each(function(i) { - const count = i + 1; - $(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); - }); + const updateInlineLabel = function (row) { + $(selector) + .find(".inline_label") + .each(function (i) { + const count = i + 1; + $(this).html( + $(this) + .html() + .replace(/(#\d+)/g, "#" + count), + ); + }); }; - const reinitDateTimeShortCuts = function() { + const reinitDateTimeShortCuts = function () { // Reinitialize the calendar and clock widgets by force, yuck. if (typeof DateTimeShortcuts !== "undefined") { $(".datetimeshortcuts").remove(); @@ -286,35 +367,44 @@ } }; - const updateSelectFilter = function() { + const updateSelectFilter = function () { // If any SelectFilter widgets were added, instantiate a new instance. if (typeof SelectFilter !== "undefined") { - $(".selectfilter").each(function(index, value) { + $(".selectfilter").each(function (index, value) { SelectFilter.init(value.id, this.dataset.fieldName, false); }); - $(".selectfilterstacked").each(function(index, value) { + $(".selectfilterstacked").each(function (index, value) { SelectFilter.init(value.id, this.dataset.fieldName, true); }); } }; - const initPrepopulatedFields = function(row) { - row.find('.prepopulated_field').each(function() { + const initPrepopulatedFields = function (row) { + row.find(".prepopulated_field").each(function () { const field = $(this), - input = field.find('input, select, textarea'), - dependency_list = input.data('dependency_list') || [], + input = field.find("input, select, textarea"), + dependency_list = input.data("dependency_list") || [], dependencies = []; - $.each(dependency_list, function(i, field_name) { + $.each(dependency_list, function (i, field_name) { // Dependency in a fieldset. - let field_element = row.find('.form-row .field-' + field_name); + let field_element = row.find( + ".form-row .field-" + field_name, + ); // Dependency without a fieldset. if (!field_element.length) { - field_element = row.find('.form-row.field-' + field_name); + field_element = row.find( + ".form-row.field-" + field_name, + ); } - dependencies.push('#' + field_element.find('input, select, textarea').attr('id')); + dependencies.push( + "#" + + field_element + .find("input, select, textarea") + .attr("id"), + ); }); if (dependencies.length) { - input.prepopulate(dependencies, input.attr('maxlength')); + input.prepopulate(dependencies, input.attr("maxlength")); } }); }; @@ -327,32 +417,34 @@ deleteText: options.deleteText, emptyCssClass: "empty-form", removed: updateInlineLabel, - added: function(row) { + added: function (row) { initPrepopulatedFields(row); reinitDateTimeShortCuts(); updateSelectFilter(); updateInlineLabel(row); }, - addButton: options.addButton + addButton: options.addButton, }); return $rows; }; - $(document).ready(function() { - $(".js-inline-admin-formset").each(function() { + $(document).ready(function () { + $(".js-inline-admin-formset").each(function () { const data = $(this).data(), inlineOptions = data.inlineFormset; let selector; - switch(data.inlineType) { - case "stacked": - selector = inlineOptions.name + "-group .inline-related"; - $(selector).stackedFormset(selector, inlineOptions.options); - break; - case "tabular": - selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr.form-row"; - $(selector).tabularFormset(selector, inlineOptions.options); - break; + switch (data.inlineType) { + case "stacked": + selector = inlineOptions.name + "-group .inline-related"; + $(selector).stackedFormset(selector, inlineOptions.options); + break; + case "tabular": + selector = + inlineOptions.name + + "-group .tabular.inline-related tbody:first > tr.form-row"; + $(selector).tabularFormset(selector, inlineOptions.options); + break; } }); }); diff --git a/django/contrib/admin/static/admin/js/jquery.init.js b/django/contrib/admin/static/admin/js/jquery.init.js index f40b27f47d..e9f446f96e 100644 --- a/django/contrib/admin/static/admin/js/jquery.init.js +++ b/django/contrib/admin/static/admin/js/jquery.init.js @@ -1,8 +1,8 @@ /*global jQuery:false*/ -'use strict'; +"use strict"; /* Puts the included jQuery into our own namespace using noConflict and passing * it 'true'. This ensures that the included jQuery doesn't pollute the global * namespace (i.e. this preserves pre-existing values for both window.$ and * window.jQuery). */ -window.django = {jQuery: jQuery.noConflict(true)}; +window.django = { jQuery: jQuery.noConflict(true) }; diff --git a/django/contrib/admin/static/admin/js/nav_sidebar.js b/django/contrib/admin/static/admin/js/nav_sidebar.js index 7e735db15c..777299f8b0 100644 --- a/django/contrib/admin/static/admin/js/nav_sidebar.js +++ b/django/contrib/admin/static/admin/js/nav_sidebar.js @@ -1,36 +1,41 @@ -'use strict'; +"use strict"; { - const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); + const toggleNavSidebar = document.getElementById("toggle-nav-sidebar"); if (toggleNavSidebar !== null) { - const navSidebar = document.getElementById('nav-sidebar'); - const main = document.getElementById('main'); - let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); + const navSidebar = document.getElementById("nav-sidebar"); + const main = document.getElementById("main"); + let navSidebarIsOpen = localStorage.getItem( + "django.admin.navSidebarIsOpen", + ); if (navSidebarIsOpen === null) { - navSidebarIsOpen = 'true'; + navSidebarIsOpen = "true"; } - main.classList.toggle('shifted', navSidebarIsOpen === 'true'); - navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); + main.classList.toggle("shifted", navSidebarIsOpen === "true"); + navSidebar.setAttribute("aria-expanded", navSidebarIsOpen); - toggleNavSidebar.addEventListener('click', function() { - if (navSidebarIsOpen === 'true') { - navSidebarIsOpen = 'false'; + toggleNavSidebar.addEventListener("click", function () { + if (navSidebarIsOpen === "true") { + navSidebarIsOpen = "false"; } else { - navSidebarIsOpen = 'true'; + navSidebarIsOpen = "true"; } - localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); - main.classList.toggle('shifted'); - navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); + localStorage.setItem( + "django.admin.navSidebarIsOpen", + navSidebarIsOpen, + ); + main.classList.toggle("shifted"); + navSidebar.setAttribute("aria-expanded", navSidebarIsOpen); }); } function initSidebarQuickFilter() { const options = []; - const navSidebar = document.getElementById('nav-sidebar'); + const navSidebar = document.getElementById("nav-sidebar"); if (!navSidebar) { return; } - navSidebar.querySelectorAll('th[scope=row] a').forEach((container) => { - options.push({title: container.innerHTML, node: container}); + navSidebar.querySelectorAll("th[scope=row] a").forEach((container) => { + options.push({ title: container.innerHTML, node: container }); }); function checkValue(event) { @@ -38,16 +43,16 @@ if (filterValue) { filterValue = filterValue.toLowerCase(); } - if (event.key === 'Escape') { - filterValue = ''; - event.target.value = ''; // clear input + if (event.key === "Escape") { + filterValue = ""; + event.target.value = ""; // clear input } let matches = false; for (const o of options) { - let displayValue = ''; + let displayValue = ""; if (filterValue) { if (o.title.toLowerCase().indexOf(filterValue) === -1) { - displayValue = 'none'; + displayValue = "none"; } else { matches = true; } @@ -56,22 +61,27 @@ o.node.parentNode.parentNode.style.display = displayValue; } if (!filterValue || matches) { - event.target.classList.remove('no-results'); + event.target.classList.remove("no-results"); } else { - event.target.classList.add('no-results'); + event.target.classList.add("no-results"); } - sessionStorage.setItem('django.admin.navSidebarFilterValue', filterValue); + sessionStorage.setItem( + "django.admin.navSidebarFilterValue", + filterValue, + ); } - const nav = document.getElementById('nav-filter'); - nav.addEventListener('change', checkValue, false); - nav.addEventListener('input', checkValue, false); - nav.addEventListener('keyup', checkValue, false); + const nav = document.getElementById("nav-filter"); + nav.addEventListener("change", checkValue, false); + nav.addEventListener("input", checkValue, false); + nav.addEventListener("keyup", checkValue, false); - const storedValue = sessionStorage.getItem('django.admin.navSidebarFilterValue'); + const storedValue = sessionStorage.getItem( + "django.admin.navSidebarFilterValue", + ); if (storedValue) { nav.value = storedValue; - checkValue({target: nav, key: ''}); + checkValue({ target: nav, key: "" }); } } window.initSidebarQuickFilter = initSidebarQuickFilter; diff --git a/django/contrib/admin/static/admin/js/popup_response.js b/django/contrib/admin/static/admin/js/popup_response.js index bdd93a6eb5..1da24f0daf 100644 --- a/django/contrib/admin/static/admin/js/popup_response.js +++ b/django/contrib/admin/static/admin/js/popup_response.js @@ -1,15 +1,28 @@ -'use strict'; +"use strict"; { - const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); - switch(initData.action) { - case 'change': - opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); - break; - case 'delete': - opener.dismissDeleteRelatedObjectPopup(window, initData.value); - break; - default: - opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj, initData.optgroup); - break; + const initData = JSON.parse( + document.getElementById("django-admin-popup-response-constants").dataset + .popupResponse, + ); + switch (initData.action) { + case "change": + opener.dismissChangeRelatedObjectPopup( + window, + initData.value, + initData.obj, + initData.new_value, + ); + break; + case "delete": + opener.dismissDeleteRelatedObjectPopup(window, initData.value); + break; + default: + opener.dismissAddRelatedObjectPopup( + window, + initData.value, + initData.obj, + initData.optgroup, + ); + break; } } diff --git a/django/contrib/admin/static/admin/js/prepopulate.js b/django/contrib/admin/static/admin/js/prepopulate.js index 89e95ab44d..5b1950d907 100644 --- a/django/contrib/admin/static/admin/js/prepopulate.js +++ b/django/contrib/admin/static/admin/js/prepopulate.js @@ -1,8 +1,8 @@ /*global URLify*/ -'use strict'; +"use strict"; { const $ = django.jQuery; - $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { + $.fn.prepopulate = function (dependencies, maxLength, allowUnicode) { /* Depends on urlify.js Populates a selected field with the values of the dependent fields, @@ -11,32 +11,34 @@ maxLength - maximum length of the URLify'd string allowUnicode - Unicode support of the URLify'd string */ - return this.each(function() { + return this.each(function () { const prepopulatedField = $(this); - const populate = function() { + const populate = function () { // Bail if the field's value has been changed by the user - if (prepopulatedField.data('_changed')) { + if (prepopulatedField.data("_changed")) { return; } const values = []; - $.each(dependencies, function(i, field) { + $.each(dependencies, function (i, field) { field = $(field); if (field.val().length > 0) { values.push(field.val()); } }); - prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); + prepopulatedField.val( + URLify(values.join(" "), maxLength, allowUnicode), + ); }; - prepopulatedField.data('_changed', false); - prepopulatedField.on('change', function() { - prepopulatedField.data('_changed', true); + prepopulatedField.data("_changed", false); + prepopulatedField.on("change", function () { + prepopulatedField.data("_changed", true); }); if (!prepopulatedField.val()) { - $(dependencies.join(',')).on('keyup change focus', populate); + $(dependencies.join(",")).on("keyup change focus", populate); } }); }; diff --git a/django/contrib/admin/static/admin/js/prepopulate_init.js b/django/contrib/admin/static/admin/js/prepopulate_init.js index a58841f004..617065ac4d 100644 --- a/django/contrib/admin/static/admin/js/prepopulate_init.js +++ b/django/contrib/admin/static/admin/js/prepopulate_init.js @@ -1,15 +1,24 @@ -'use strict'; +"use strict"; { const $ = django.jQuery; - const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields'); - $.each(fields, function(index, field) { + const fields = $("#django-admin-prepopulated-fields-constants").data( + "prepopulatedFields", + ); + $.each(fields, function (index, field) { $( - '.empty-form .form-row .field-' + field.name + - ', .empty-form.form-row .field-' + field.name + - ', .empty-form .form-row.field-' + field.name - ).addClass('prepopulated_field'); - $(field.id).data('dependency_list', field.dependency_list).prepopulate( - field.dependency_ids, field.maxLength, field.allowUnicode - ); + ".empty-form .form-row .field-" + + field.name + + ", .empty-form.form-row .field-" + + field.name + + ", .empty-form .form-row.field-" + + field.name, + ).addClass("prepopulated_field"); + $(field.id) + .data("dependency_list", field.dependency_list) + .prepopulate( + field.dependency_ids, + field.maxLength, + field.allowUnicode, + ); }); } diff --git a/django/contrib/admin/static/admin/js/theme.js b/django/contrib/admin/static/admin/js/theme.js index e79d375c55..0f5767ff6f 100644 --- a/django/contrib/admin/static/admin/js/theme.js +++ b/django/contrib/admin/static/admin/js/theme.js @@ -1,8 +1,10 @@ -'use strict'; +"use strict"; { function setTheme(mode) { if (mode !== "light" && mode !== "dark" && mode !== "auto") { - console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + console.error( + `Got invalid theme mode: ${mode}. Resetting to auto.`, + ); mode = "auto"; } document.documentElement.dataset.theme = mode; @@ -11,7 +13,9 @@ function cycleTheme() { const currentTheme = localStorage.getItem("theme") || "auto"; - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + const prefersDark = window.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; if (prefersDark) { // Auto (dark) -> Light -> Dark @@ -40,7 +44,7 @@ currentTheme ? setTheme(currentTheme) : setTheme("auto"); } - window.addEventListener('load', function(_) { + window.addEventListener("load", function (_) { const buttons = document.getElementsByClassName("theme-toggle"); Array.from(buttons).forEach((btn) => { btn.addEventListener("click", cycleTheme); diff --git a/django/contrib/admin/static/admin/js/urlify.js b/django/contrib/admin/static/admin/js/urlify.js index 9fc0409496..3a23ec1647 100644 --- a/django/contrib/admin/static/admin/js/urlify.js +++ b/django/contrib/admin/static/admin/js/urlify.js @@ -1,109 +1,469 @@ /*global XRegExp*/ -'use strict'; +"use strict"; { const LATIN_MAP = { - 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', - 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', - 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', - 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', - 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a', - 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', - 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', - 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', - 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', - 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' + À: "A", + Á: "A", + Â: "A", + Ã: "A", + Ä: "A", + Å: "A", + Æ: "AE", + Ç: "C", + È: "E", + É: "E", + Ê: "E", + Ë: "E", + Ì: "I", + Í: "I", + Î: "I", + Ï: "I", + Ð: "D", + Ñ: "N", + Ò: "O", + Ó: "O", + Ô: "O", + Õ: "O", + Ö: "O", + Ő: "O", + Ø: "O", + Ù: "U", + Ú: "U", + Û: "U", + Ü: "U", + Ű: "U", + Ý: "Y", + Þ: "TH", + Ÿ: "Y", + ß: "ss", + à: "a", + á: "a", + â: "a", + ã: "a", + ä: "a", + å: "a", + æ: "ae", + ç: "c", + è: "e", + é: "e", + ê: "e", + ë: "e", + ì: "i", + í: "i", + î: "i", + ï: "i", + ð: "d", + ñ: "n", + ò: "o", + ó: "o", + ô: "o", + õ: "o", + ö: "o", + ő: "o", + ø: "o", + ù: "u", + ú: "u", + û: "u", + ü: "u", + ű: "u", + ý: "y", + þ: "th", + ÿ: "y", }; const LATIN_SYMBOLS_MAP = { - '©': '(c)' + "©": "(c)", }; const GREEK_MAP = { - 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h', - 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3', - 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f', - 'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o', - 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y', - 'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z', - 'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N', - 'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y', - 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I', - 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y' + α: "a", + β: "b", + γ: "g", + δ: "d", + ε: "e", + ζ: "z", + η: "h", + θ: "8", + ι: "i", + κ: "k", + λ: "l", + μ: "m", + ν: "n", + ξ: "3", + ο: "o", + π: "p", + ρ: "r", + σ: "s", + τ: "t", + υ: "y", + φ: "f", + χ: "x", + ψ: "ps", + ω: "w", + ά: "a", + έ: "e", + ί: "i", + ό: "o", + ύ: "y", + ή: "h", + ώ: "w", + ς: "s", + ϊ: "i", + ΰ: "y", + ϋ: "y", + ΐ: "i", + Α: "A", + Β: "B", + Γ: "G", + Δ: "D", + Ε: "E", + Ζ: "Z", + Η: "H", + Θ: "8", + Ι: "I", + Κ: "K", + Λ: "L", + Μ: "M", + Ν: "N", + Ξ: "3", + Ο: "O", + Π: "P", + Ρ: "R", + Σ: "S", + Τ: "T", + Υ: "Y", + Φ: "F", + Χ: "X", + Ψ: "PS", + Ω: "W", + Ά: "A", + Έ: "E", + Ί: "I", + Ό: "O", + Ύ: "Y", + Ή: "H", + Ώ: "W", + Ϊ: "I", + Ϋ: "Y", }; const TURKISH_MAP = { - 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u', - 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G' + ş: "s", + Ş: "S", + ı: "i", + İ: "I", + ç: "c", + Ç: "C", + ü: "u", + Ü: "U", + ö: "o", + Ö: "O", + ğ: "g", + Ğ: "G", }; const ROMANIAN_MAP = { - 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a', - 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A' + ă: "a", + î: "i", + ș: "s", + ț: "t", + â: "a", + Ă: "A", + Î: "I", + Ș: "S", + Ț: "T", + Â: "A", }; const RUSSIAN_MAP = { - 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo', - 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', - 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', - 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '', - 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya', - 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo', - 'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M', - 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', - 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '', - 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya' + а: "a", + б: "b", + в: "v", + г: "g", + д: "d", + е: "e", + ё: "yo", + ж: "zh", + з: "z", + и: "i", + й: "j", + к: "k", + л: "l", + м: "m", + н: "n", + о: "o", + п: "p", + р: "r", + с: "s", + т: "t", + у: "u", + ф: "f", + х: "h", + ц: "c", + ч: "ch", + ш: "sh", + щ: "sh", + ъ: "", + ы: "y", + ь: "", + э: "e", + ю: "yu", + я: "ya", + А: "A", + Б: "B", + В: "V", + Г: "G", + Д: "D", + Е: "E", + Ё: "Yo", + Ж: "Zh", + З: "Z", + И: "I", + Й: "J", + К: "K", + Л: "L", + М: "M", + Н: "N", + О: "O", + П: "P", + Р: "R", + С: "S", + Т: "T", + У: "U", + Ф: "F", + Х: "H", + Ц: "C", + Ч: "Ch", + Ш: "Sh", + Щ: "Sh", + Ъ: "", + Ы: "Y", + Ь: "", + Э: "E", + Ю: "Yu", + Я: "Ya", }; const UKRAINIAN_MAP = { - 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i', - 'ї': 'yi', 'ґ': 'g' + Є: "Ye", + І: "I", + Ї: "Yi", + Ґ: "G", + є: "ye", + і: "i", + ї: "yi", + ґ: "g", }; const CZECH_MAP = { - 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', - 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', - 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z' + č: "c", + ď: "d", + ě: "e", + ň: "n", + ř: "r", + š: "s", + ť: "t", + ů: "u", + ž: "z", + Č: "C", + Ď: "D", + Ě: "E", + Ň: "N", + Ř: "R", + Š: "S", + Ť: "T", + Ů: "U", + Ž: "Z", }; const SLOVAK_MAP = { - 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l', - 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't', - 'ú': 'u', 'ý': 'y', 'ž': 'z', - 'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L', - 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T', - 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z' + á: "a", + ä: "a", + č: "c", + ď: "d", + é: "e", + í: "i", + ľ: "l", + ĺ: "l", + ň: "n", + ó: "o", + ô: "o", + ŕ: "r", + š: "s", + ť: "t", + ú: "u", + ý: "y", + ž: "z", + Á: "a", + Ä: "A", + Č: "C", + Ď: "D", + É: "E", + Í: "I", + Ľ: "L", + Ĺ: "L", + Ň: "N", + Ó: "O", + Ô: "O", + Ŕ: "R", + Š: "S", + Ť: "T", + Ú: "U", + Ý: "Y", + Ž: "Z", }; const POLISH_MAP = { - 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', - 'ź': 'z', 'ż': 'z', - 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S', - 'Ź': 'Z', 'Ż': 'Z' + ą: "a", + ć: "c", + ę: "e", + ł: "l", + ń: "n", + ó: "o", + ś: "s", + ź: "z", + ż: "z", + Ą: "A", + Ć: "C", + Ę: "E", + Ł: "L", + Ń: "N", + Ó: "O", + Ś: "S", + Ź: "Z", + Ż: "Z", }; const LATVIAN_MAP = { - 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', - 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z', - 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L', - 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z' + ā: "a", + č: "c", + ē: "e", + ģ: "g", + ī: "i", + ķ: "k", + ļ: "l", + ņ: "n", + š: "s", + ū: "u", + ž: "z", + Ā: "A", + Č: "C", + Ē: "E", + Ģ: "G", + Ī: "I", + Ķ: "K", + Ļ: "L", + Ņ: "N", + Š: "S", + Ū: "U", + Ž: "Z", }; const ARABIC_MAP = { - 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd', - 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't', - 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm', - 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y' + أ: "a", + ب: "b", + ت: "t", + ث: "th", + ج: "g", + ح: "h", + خ: "kh", + د: "d", + ذ: "th", + ر: "r", + ز: "z", + س: "s", + ش: "sh", + ص: "s", + ض: "d", + ط: "t", + ظ: "th", + ع: "aa", + غ: "gh", + ف: "f", + ق: "k", + ك: "k", + ل: "l", + م: "m", + ن: "n", + ه: "h", + و: "o", + ي: "y", }; const LITHUANIAN_MAP = { - 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u', - 'ū': 'u', 'ž': 'z', - 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U', - 'Ū': 'U', 'Ž': 'Z' + ą: "a", + č: "c", + ę: "e", + ė: "e", + į: "i", + š: "s", + ų: "u", + ū: "u", + ž: "z", + Ą: "A", + Č: "C", + Ę: "E", + Ė: "E", + Į: "I", + Š: "S", + Ų: "U", + Ū: "U", + Ž: "Z", }; const SERBIAN_MAP = { - 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz', - 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C', - 'Џ': 'Dz', 'Đ': 'Dj' + ђ: "dj", + ј: "j", + љ: "lj", + њ: "nj", + ћ: "c", + џ: "dz", + đ: "dj", + Ђ: "Dj", + Ј: "j", + Љ: "Lj", + Њ: "Nj", + Ћ: "C", + Џ: "Dz", + Đ: "Dj", }; const AZERBAIJANI_MAP = { - 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', - 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U' + ç: "c", + ə: "e", + ğ: "g", + ı: "i", + ö: "o", + ş: "s", + ü: "u", + Ç: "C", + Ə: "E", + Ğ: "G", + İ: "I", + Ö: "O", + Ş: "S", + Ü: "U", }; const GEORGIAN_MAP = { - 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z', - 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o', - 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f', - 'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz', - 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h' + ა: "a", + ბ: "b", + გ: "g", + დ: "d", + ე: "e", + ვ: "v", + ზ: "z", + თ: "t", + ი: "i", + კ: "k", + ლ: "l", + მ: "m", + ნ: "n", + ო: "o", + პ: "p", + ჟ: "j", + რ: "r", + ს: "s", + ტ: "t", + უ: "u", + ფ: "f", + ქ: "q", + ღ: "g", + ყ: "y", + შ: "sh", + ჩ: "ch", + ც: "c", + ძ: "dz", + წ: "w", + ჭ: "ch", + ხ: "x", + ჯ: "j", + ჰ: "h", }; const ALL_DOWNCODE_MAPS = [ @@ -122,30 +482,33 @@ LITHUANIAN_MAP, SERBIAN_MAP, AZERBAIJANI_MAP, - GEORGIAN_MAP + GEORGIAN_MAP, ]; const Downcoder = { - 'Initialize': function() { - if (Downcoder.map) { // already made + Initialize: function () { + if (Downcoder.map) { + // already made return; } Downcoder.map = {}; for (const lookup of ALL_DOWNCODE_MAPS) { Object.assign(Downcoder.map, lookup); } - Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g'); - } + Downcoder.regex = new RegExp( + Object.keys(Downcoder.map).join("|"), + "g", + ); + }, }; function downcode(slug) { Downcoder.Initialize(); - return slug.replace(Downcoder.regex, function(m) { + return slug.replace(Downcoder.regex, function (m) { return Downcoder.map[m]; }); } - function URLify(s, num_chars, allowUnicode) { // changes, e.g., "Petty theft" to "petty-theft" if (!allowUnicode) { @@ -156,14 +519,14 @@ if (allowUnicode) { // Keep Unicode letters including both lowercase and uppercase // characters, whitespace, and dash; remove other characters. - s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), ''); + s = XRegExp.replace(s, XRegExp("[^-_\\p{L}\\p{N}\\s]", "g"), ""); } else { - s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars + s = s.replace(/[^-\w\s]/g, ""); // remove unneeded chars } - s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces - s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens + s = s.replace(/^\s+|\s+$/g, ""); // trim leading/trailing spaces + s = s.replace(/[-\s]+/g, "-"); // convert spaces to hyphens s = s.substring(0, num_chars); // trim to first num_chars chars - return s.replace(/-+$/g, ''); // trim any trailing hyphens + return s.replace(/-+$/g, ""); // trim any trailing hyphens } window.URLify = URLify; } diff --git a/django/contrib/gis/static/gis/js/OLMapWidget.js b/django/contrib/gis/static/gis/js/OLMapWidget.js index 50860650f9..05629496c8 100644 --- a/django/contrib/gis/static/gis/js/OLMapWidget.js +++ b/django/contrib/gis/static/gis/js/OLMapWidget.js @@ -1,38 +1,45 @@ /* global ol */ -'use strict'; +"use strict"; class GeometryTypeControl extends ol.control.Control { // Map control to switch type when geometry type is unknown constructor(opt_options) { const options = opt_options || {}; - const element = document.createElement('div'); - element.className = 'switch-type type-' + options.type + ' ol-control ol-unselectable'; + const element = document.createElement("div"); + element.className = + "switch-type type-" + options.type + " ol-control ol-unselectable"; if (options.active) { element.classList.add("type-active"); } super({ element: element, - target: options.target + target: options.target, }); const self = this; - const switchType = function(e) { + const switchType = function (e) { e.preventDefault(); if (options.widget.currentGeometryType !== self) { - options.widget.map.removeInteraction(options.widget.interactions.draw); + options.widget.map.removeInteraction( + options.widget.interactions.draw, + ); options.widget.interactions.draw = new ol.interaction.Draw({ features: options.widget.featureCollection, - type: options.type + type: options.type, }); - options.widget.map.addInteraction(options.widget.interactions.draw); - options.widget.currentGeometryType.element.classList.remove('type-active'); + options.widget.map.addInteraction( + options.widget.interactions.draw, + ); + options.widget.currentGeometryType.element.classList.remove( + "type-active", + ); options.widget.currentGeometryType = self; element.classList.add("type-active"); } }; - element.addEventListener('click', switchType, false); - element.addEventListener('touchstart', switchType, false); + element.addEventListener("click", switchType, false); + element.addEventListener("touchstart", switchType, false); } } @@ -40,7 +47,7 @@ class GeometryTypeControl extends ol.control.Control { class MapWidget { constructor(options) { this.map = null; - this.interactions = {draw: null, modify: null}; + this.interactions = { draw: null, modify: null }; this.typeChoices = false; this.ready = false; @@ -49,7 +56,9 @@ class MapWidget { default_lat: 0, default_lon: 0, default_zoom: 12, - is_collection: options.geom_name.includes('Multi') || options.geom_name.includes('Collection') + is_collection: + options.geom_name.includes("Multi") || + options.geom_name.includes("Collection"), }; // Altering using user-provided options @@ -62,9 +71,12 @@ class MapWidget { // Options' base_layer can be empty, or contain a layerBuilder key, or // be a layer already constructed. const base_layer = options.base_layer; - if (typeof base_layer === 'string' && base_layer in MapWidget.layerBuilder) { + if ( + typeof base_layer === "string" && + base_layer in MapWidget.layerBuilder + ) { this.baseLayer = MapWidget.layerBuilder[base_layer](); - } else if (base_layer && typeof base_layer !== 'string') { + } else if (base_layer && typeof base_layer !== "string") { this.baseLayer = base_layer; } else { this.baseLayer = MapWidget.layerBuilder.osm(); @@ -76,17 +88,17 @@ class MapWidget { map: this.map, source: new ol.source.Vector({ features: this.featureCollection, - useSpatialIndex: false // improve performance + useSpatialIndex: false, // improve performance }), updateWhileAnimating: true, // optional, for instant visual feedback - updateWhileInteracting: true // optional, for instant visual feedback + updateWhileInteracting: true, // optional, for instant visual feedback }); // Populate and set handlers for the feature container const self = this; - this.featureCollection.on('add', function(event) { + this.featureCollection.on("add", function (event) { const feature = event.element; - feature.on('change', function() { + feature.on("change", function () { self.serializeFeatures(); }); if (self.ready) { @@ -100,14 +112,16 @@ class MapWidget { const initial_value = document.getElementById(this.options.id).value; if (initial_value) { const jsonFormat = new ol.format.GeoJSON(); - const features = jsonFormat.readFeatures('{"type": "Feature", "geometry": ' + initial_value + '}'); + const features = jsonFormat.readFeatures( + '{"type": "Feature", "geometry": ' + initial_value + "}", + ); const extent = ol.extent.createEmpty(); - features.forEach(function(feature) { + features.forEach(function (feature) { this.featureOverlay.getSource().addFeature(feature); ol.extent.extend(extent, feature.getGeometry().getExtent()); }, this); // Center/zoom the map - this.map.getView().fit(extent, {minResolution: 1}); + this.map.getView().fit(extent, { minResolution: 1 }); } else { this.map.getView().setCenter(this.defaultCenter()); } @@ -115,9 +129,11 @@ class MapWidget { if (initial_value && !this.options.is_collection) { this.disableDrawing(); } - const clearNode = document.getElementById(this.map.getTarget()).nextElementSibling; - if (clearNode.classList.contains('clear_features')) { - clearNode.querySelector('a').addEventListener('click', (ev) => { + const clearNode = document.getElementById( + this.map.getTarget(), + ).nextElementSibling; + if (clearNode.classList.contains("clear_features")) { + clearNode.querySelector("a").addEventListener("click", (ev) => { ev.preventDefault(); self.clearFeatures(); }); @@ -130,8 +146,8 @@ class MapWidget { target: this.options.map_id, layers: [this.baseLayer], view: new ol.View({ - zoom: this.options.default_zoom - }) + zoom: this.options.default_zoom, + }), }); } @@ -139,10 +155,12 @@ class MapWidget { // Initialize the modify interaction this.interactions.modify = new ol.interaction.Modify({ features: this.featureCollection, - deleteCondition: function(event) { - return ol.events.condition.shiftKeyOnly(event) && - ol.events.condition.singleClick(event); - } + deleteCondition: function (event) { + return ( + ol.events.condition.shiftKeyOnly(event) && + ol.events.condition.singleClick(event) + ); + }, }); // Initialize the draw interaction @@ -150,15 +168,31 @@ class MapWidget { if (geomType === "Geometry" || geomType === "GeometryCollection") { // Default to Point, but create icons to switch type geomType = "Point"; - this.currentGeometryType = new GeometryTypeControl({widget: this, type: "Point", active: true}); + this.currentGeometryType = new GeometryTypeControl({ + widget: this, + type: "Point", + active: true, + }); this.map.addControl(this.currentGeometryType); - this.map.addControl(new GeometryTypeControl({widget: this, type: "LineString", active: false})); - this.map.addControl(new GeometryTypeControl({widget: this, type: "Polygon", active: false})); + this.map.addControl( + new GeometryTypeControl({ + widget: this, + type: "LineString", + active: false, + }), + ); + this.map.addControl( + new GeometryTypeControl({ + widget: this, + type: "Polygon", + active: false, + }), + ); this.typeChoices = true; } this.interactions.draw = new ol.interaction.Draw({ features: this.featureCollection, - type: geomType + type: geomType, }); this.map.addInteraction(this.interactions.draw); @@ -168,7 +202,11 @@ class MapWidget { defaultCenter() { const center = [this.options.default_lon, this.options.default_lat]; if (this.options.map_srid) { - return ol.proj.transform(center, 'EPSG:4326', this.map.getView().getProjection()); + return ol.proj.transform( + center, + "EPSG:4326", + this.map.getView().getProjection(), + ); } return center; } @@ -200,7 +238,7 @@ class MapWidget { clearFeatures() { this.featureCollection.clear(); // Empty textarea widget - document.getElementById(this.options.id).value = ''; + document.getElementById(this.options.id).value = ""; this.enableDrawing(); } @@ -219,14 +257,20 @@ class MapWidget { geometry = features[0].getGeometry().clone(); for (let j = 1; j < features.length; j++) { switch (geometry.getType()) { - case "MultiPoint": - geometry.appendPoint(features[j].getGeometry().getPoint(0)); - break; - case "MultiLineString": - geometry.appendLineString(features[j].getGeometry().getLineString(0)); - break; - case "MultiPolygon": - geometry.appendPolygon(features[j].getGeometry().getPolygon(0)); + case "MultiPoint": + geometry.appendPoint( + features[j].getGeometry().getPoint(0), + ); + break; + case "MultiLineString": + geometry.appendLineString( + features[j].getGeometry().getLineString(0), + ); + break; + case "MultiPolygon": + geometry.appendPolygon( + features[j].getGeometry().getPolygon(0), + ); } } } @@ -236,7 +280,8 @@ class MapWidget { } } const jsonFormat = new ol.format.GeoJSON(); - document.getElementById(this.options.id).value = jsonFormat.writeGeometry(geometry); + document.getElementById(this.options.id).value = + jsonFormat.writeGeometry(geometry); } } @@ -247,15 +292,16 @@ MapWidget.layerBuilder = { source: new ol.source.XYZ({ attributions: "NASA Worldview", maxZoom: 8, - url: "https://map1{a-c}.vis.earthdata.nasa.gov/wmts-webmerc/" + - "BlueMarble_ShadedRelief_Bathymetry/default/%7BTime%7D/" + - "GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg" - }) + url: + "https://map1{a-c}.vis.earthdata.nasa.gov/wmts-webmerc/" + + "BlueMarble_ShadedRelief_Bathymetry/default/%7BTime%7D/" + + "GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg", + }), }); }, osm: () => { - return new ol.layer.Tile({source: new ol.source.OSM()}); - } + return new ol.layer.Tile({ source: new ol.source.OSM() }); + }, }; function initMapWidgetInSection(section) { @@ -263,11 +309,13 @@ function initMapWidgetInSection(section) { section.querySelectorAll(".dj_map_wrapper").forEach((wrapper) => { // Avoid initializing map widget on an empty form. - if (wrapper.id.includes('__prefix__')) { + if (wrapper.id.includes("__prefix__")) { return; } const textarea_id = wrapper.querySelector("textarea").id; - const options_script = wrapper.querySelector(`script#${textarea_id}_mapwidget_options`); + const options_script = wrapper.querySelector( + `script#${textarea_id}_mapwidget_options`, + ); const options = JSON.parse(options_script.textContent); options.id = textarea_id; options.map_id = wrapper.querySelector(".dj_map").id; @@ -275,9 +323,11 @@ function initMapWidgetInSection(section) { }); return maps; -}; +} document.addEventListener("DOMContentLoaded", () => { initMapWidgetInSection(document); - document.addEventListener('formset:added', (ev) => {initMapWidgetInSection(ev.target);}); + document.addEventListener("formset:added", (ev) => { + initMapWidgetInSection(ev.target); + }); }); |
