- 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 04b25e9684ac..e302bb4b222c 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;
- }
- });
- });
+ }
- 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();
+ 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();
+ }
}
- }
- });
+ });
- 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 b30a668a2e5f..6f71b25152bc 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:
//
//
-'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
that gets toggled
- calendarDivName2: 'calendarin', // name of
that contains calendar
- calendarLinkName: 'calendarlink', // name of the link that is used to toggle
- clockDivName: 'clockbox', // name of clock
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
that gets toggled
+ calendarDivName2: "calendarin", // name of
that contains calendar
+ calendarLinkName: "calendarlink", // name of the link that is used to toggle
+ clockDivName: "clockbox", // name of clock
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 @@
//
Cancel
//
- 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
.
- 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 @@
//
//
Cancel
//
- 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 fb5db940d654..a9c06ad4ae2d 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 '.../
/add/' or
// '...///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 d3daeab89095..30fd5209ae01 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 b13242078a54..f10a584fa991 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 3069c6f27bfd..b4bc29c8dbb0 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 96a4c62ef4c3..f692d7ffe15d 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 10504d4a8415..d36dad6f49e5 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 f5536ebc2d3b..c765264b3fdd 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 cd3726cf3061..994425229503 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('' + options.addText + " ");
+ $parent.append(
+ '' +
+ options.addText +
+ " ",
+ );
addButton = $parent.find("tr:last a");
} else {
// Otherwise, insert it immediately after the last form:
- $this.filter(":last").after('");
+ $this
+ .filter(":last")
+ .after(
+ '",
+ );
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('");
+ row.children(":last").append(
+ '",
+ );
} else if (row.is("ul") || row.is("ol")) {
// If they're laid out as an ordered/unordered list,
// insert an after the last list item:
- row.append(' ' + options.deleteText + " ");
+ row.append(
+ '' +
+ options.deleteText +
+ " ",
+ );
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
- row.children(":first").append('' + options.deleteText + " ");
+ row.children(":first").append(
+ '' +
+ options.deleteText +
+ " ",
+ );
}
// 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 f40b27f47da4..e9f446f96ec4 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 7e735db15cf3..777299f8b060 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 bdd93a6eb559..1da24f0daf63 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 89e95ab44dc7..5b1950d907ff 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 a58841f00412..617065ac4d05 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 e79d375c55cf..0f5767ff6f6c 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 9fc040949647..3a23ec1647ab 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 50860650f9a4..05629496c83f 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);
+ });
});
diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py
index 02e56bdd52f9..b7bfa9d54e31 100644
--- a/django/core/serializers/pyyaml.py
+++ b/django/core/serializers/pyyaml.py
@@ -4,7 +4,6 @@
Requires PyYaml (https://pyyaml.org/), but that's checked for in __init__.
"""
-import collections
import datetime
import decimal
@@ -28,9 +27,6 @@ class DjangoSafeDumper(SafeDumper):
def represent_decimal(self, data):
return self.represent_scalar("tag:yaml.org,2002:str", str(data))
- def represent_ordered_dict(self, data):
- return self.represent_mapping("tag:yaml.org,2002:map", data.items())
-
def represent_time(self, data):
# Base YAML doesn't support serialization of time types (as opposed to
# dates or datetimes, which it does support). Converting them to
@@ -40,9 +36,6 @@ def represent_time(self, data):
DjangoSafeDumper.add_representer(decimal.Decimal, DjangoSafeDumper.represent_decimal)
-DjangoSafeDumper.add_representer(
- collections.OrderedDict, DjangoSafeDumper.represent_ordered_dict
-)
DjangoSafeDumper.add_representer(datetime.time, DjangoSafeDumper.represent_time)
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 5dfbb76a01cf..6d3005ac40bc 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -292,7 +292,7 @@ def _handle_object(self, node):
field_names = {f.name for f in Model._meta.get_fields()}
# Deserialize each field.
- for field_node in node.getElementsByTagName("field"):
+ for field_node in getChildrenByTagName(node, "field"):
# If the field is missing the name attribute, bail (are you
# sensing a pattern here?)
field_name = field_node.getAttribute("name")
@@ -319,12 +319,12 @@ def _handle_object(self, node):
[
(
None
- if nat_node.getElementsByTagName("None")
+ if getChildrenByTagName(nat_node, "None")
else getInnerText(nat_node).strip()
)
- for nat_node in obj_node.getElementsByTagName("natural")
+ for nat_node in getChildrenByTagName(obj_node, "natural")
]
- for obj_node in field_node.getElementsByTagName("object")
+ for obj_node in getChildrenByTagName(field_node, "object")
]
else:
m2m_data[field.name] = value
@@ -336,15 +336,15 @@ def _handle_object(self, node):
deferred_fields[field] = [
(
None
- if k.getElementsByTagName("None")
+ if getChildrenByTagName(k, "None")
else getInnerText(k).strip()
)
- for k in field_node.getElementsByTagName("natural")
+ for k in getChildrenByTagName(field_node, "natural")
]
else:
data[field.attname] = value
else:
- if field_node.getElementsByTagName("None"):
+ if getChildrenByTagName(field_node, "None"):
value = None
else:
value = field.to_python(getInnerText(field_node).strip())
@@ -363,8 +363,8 @@ def _handle_fk_field_node(self, node, field):
Handle a node for a ForeignKey
"""
# Check if there is a child node named 'None', returning None if so.
- natural_keys = node.getElementsByTagName("natural")
- if node.getElementsByTagName("None") and not natural_keys:
+ natural_keys = getChildrenByTagName(node, "natural")
+ if getChildrenByTagName(node, "None") and not natural_keys:
return None
else:
model = field.remote_field.model
@@ -374,7 +374,7 @@ def _handle_fk_field_node(self, node, field):
# key
field_value = []
for k in natural_keys:
- if k.getElementsByTagName("None"):
+ if getChildrenByTagName(k, "None"):
field_value.append(None)
else:
field_value.append(getInnerText(k).strip())
@@ -414,13 +414,13 @@ def _handle_m2m_field_node(self, node, field):
if hasattr(default_manager, "get_by_natural_key"):
def m2m_convert(n):
- keys = n.getElementsByTagName("natural")
+ keys = getChildrenByTagName(n, "natural")
if keys:
# If there are 'natural' subelements, it must be a natural
# key
field_value = []
for k in keys:
- if k.getElementsByTagName("None"):
+ if getChildrenByTagName(k, "None"):
field_value.append(None)
else:
field_value.append(getInnerText(k).strip())
@@ -441,7 +441,7 @@ def m2m_convert(n):
values = []
try:
- for c in node.getElementsByTagName("object"):
+ for c in getChildrenByTagName(node, "object"):
values.append(m2m_convert(c))
except SuspiciousOperation:
raise
@@ -479,6 +479,25 @@ def check_element_type(element):
return element.nodeType in (element.TEXT_NODE, element.CDATA_SECTION_NODE)
+def getChildrenByTagName(node, tag_name):
+ """
+ Like Element.getElementsByTagName() but return only direct children.
+
+ Element.getElementsByTagName() searches all descendants (direct children,
+ children's children, etc.). This prevents correct deserialization of
+ third-party nested fields. For example:
+
+
+
+
+ """
+ return [
+ n
+ for n in node.childNodes
+ if n.nodeType == node.ELEMENT_NODE and n.tagName == tag_name
+ ]
+
+
def getInnerText(node):
return "".join(
[child.data for child in node.childNodes if check_element_type(child)]
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 8be560856b06..45192b78092f 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -2376,14 +2376,15 @@ def orderby_issubset_groupby(self):
return True
# Don't pollute the original query (might disrupt joins).
q = self.clone()
- order_by_set = {
- (
- order_by.resolve_expression(q)
- if hasattr(order_by, "resolve_expression")
- else F(order_by).resolve_expression(q)
- )
- for order_by in q.order_by
- }
+ order_by_set = set()
+ for order_by in q.order_by:
+ if hasattr(order_by, "resolve_expression"):
+ order_by_set.add(order_by.resolve_expression(q))
+ elif order_by == "?":
+ # Random ordering can't be compared against group by.
+ return False
+ else:
+ order_by_set.add(F(order_by.removeprefix("-")).resolve_expression(q))
return order_by_set.issubset(self.group_by)
def clear_ordering(self, force=False, clear_default=True):
diff --git a/docs/internals/contributing/writing-code/javascript.txt b/docs/internals/contributing/writing-code/javascript.txt
index b61fc009b7e8..484aa7f5b6cf 100644
--- a/docs/internals/contributing/writing-code/javascript.txt
+++ b/docs/internals/contributing/writing-code/javascript.txt
@@ -20,9 +20,9 @@ Code style
Different JavaScript files sometimes use a different code style. Please try
to conform to the code style of each file.
-* Use the `ESLint`_ code linter to check your code for bugs and style errors.
- ESLint will be run when you run the JavaScript tests. We also recommended
- installing a ESLint plugin in your text editor.
+* Use the `Biome`_ code linter to check your code for bugs and style errors.
+ Biome will be run by the pre-commit hooks. We also recommended installing
+ a Biome plugin in your text editor.
* Where possible, write code that will work even if the page structure is later
changed with JavaScript. For instance, when binding a click handler, use
@@ -117,8 +117,8 @@ Then run the tests with:
$ npm test
+.. _Biome: https://biomejs.dev/
.. _EditorConfig: https://editorconfig.org/
.. _Java: https://www.java.com
-.. _eslint: https://eslint.org/
.. _node.js: https://nodejs.org/
.. _qunit: https://qunitjs.com/
diff --git a/docs/internals/howto-release-django.txt b/docs/internals/howto-release-django.txt
index 248495b34cf5..fabf1331cc0b 100644
--- a/docs/internals/howto-release-django.txt
+++ b/docs/internals/howto-release-django.txt
@@ -53,6 +53,19 @@ The short version of the steps involved is:
There are a lot of details, so please read on.
+.. _checklist-generator:
+
+.. admonition:: Use the checklists app
+
+ To generate a checklist compiling the tasks described below as relevant to
+ the specific release(s) you are issuing, use the checklists app in the
+ `project admin `_. This
+ populates a lot of boilerplate you will need for announcements, CVE
+ publication, and hashes for commit messages. By using this app for preparing
+ security issue metadata, your peer releasers can check your entries and
+ consult them again in the future.
+ (`Example `_)
+
Prerequisites
=============
@@ -150,9 +163,23 @@ any time leading up to the actual release.
10 (or more) days before a security release
-------------------------------------------
-#. Request the `CVE IDs `_ for the security
- issue(s) being released. One CVE ID per issue, requested with
- ``Vendor: djangoproject`` and ``Product: django``.
+#. Reserve one `CVE ID `_ per security
+ issue as follows. (Or, if you lack CNA credentials, email
+ ``cna@djangoproject.com`` with a request.)
+
+ * Enable virtual environment with :pypi:`cvelib` installed.
+
+ * Export user information:
+
+ .. code-block:: shell
+
+ $ export CVE_USER=@djangoproject.com CVE_ORG=DSF
+
+ * Reserve:
+
+ .. code-block:: shell
+
+ $ cve --interactive reserve
#. Generate the relevant (private) patch(es) using ``git format-patch``, one
for the ``main`` branch and one for each stable branch being patched.
@@ -162,9 +189,9 @@ A week before a security release
#. Send out pre-notification exactly **one week** before the security release.
The template for that email and a list of the recipients are in the private
- ``django-security`` GitHub wiki. BCC the pre-notification recipients and be
+ ``django-security`` GitHub wiki. BCC the pre-notification recipients, and be
sure to include the relevant CVE IDs. Attach all the relevant patches
- (targeting ``main`` and the stable branches) and sign the email text with
+ (targeting ``main`` and the stable branches), and sign the email text with
the key you'll use for the release, with a command like:
.. code-block:: shell
@@ -185,6 +212,17 @@ A week before a security release
For details of severity levels, see:
https://docs.djangoproject.com/en/dev/internals/security/#how-django-discloses-security-issues
+#. Prepare issue metadata:
+ * Severity
+ * Short description
+ * Reporter
+ * Remediator
+ * Reported at
+ * Confirmed at (usually date CVE reserved)
+ * CWE Problem Type
+ * CAPEC Impact Type
+ * CVSS (4.0) Score & Vector
+
A few days before any release
-----------------------------
@@ -644,12 +682,18 @@ Now you're ready to actually put the release out there. To do this:
#. Post the release announcement to the |django-announce| mailing list and the
Django Forum. This should include a link to the announcement blog post.
+#. If this is a security release, publish the CVE metadata. (The
+ :ref:`checklist app` generates JSON for this.):
+
+ .. code-block:: shell
+
+ $ cve publish --cve-json-file
+
#. If this is a security release, send a separate email to
- ``oss-security@lists.openwall.com``. Provide a descriptive subject, for
- example, "Django" plus the issue title from the release notes (including CVE
- ID). The message body should include the vulnerability details, for example,
- the announcement blog post text. Include a link to the announcement blog
- post.
+ ``oss-security@lists.openwall.com``. Provide "Django" plus the CVE IDs in
+ the subject line. The message body should include the vulnerability details,
+ for example, the announcement blog post text. Include a link to the
+ announcement blog post.
Post-release
============
@@ -708,8 +752,8 @@ You're almost done! All that's left to do now is:
.. code-block:: shell
- git checkout stable/A.B.x
- git checkout -b update-translations-catalog-A.B.x
+ $ git checkout stable/A.B.x
+ $ git checkout -b update-translations-catalog-A.B.x
#. Ensure that the release's dedicated virtual environment is enabled and
run the following:
diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt
index 477117c00466..142ddb631e04 100644
--- a/docs/releases/6.1.txt
+++ b/docs/releases/6.1.txt
@@ -435,6 +435,9 @@ backends.
* The ``object-tools`` block is hoisted out of the ``content`` block in forms.
+* The undocumented ``InclusionAdminNode.__init__()`` now takes the template tag
+ ``name`` as the first positional argument.
+
:mod:`django.contrib.gis`
-------------------------
@@ -497,6 +500,9 @@ Miscellaneous
* :class:`~django.contrib.contenttypes.fields.GenericForeignKey` now uses a
separate descriptor class: the private ``GenericForeignKeyDescriptor``.
+* The undocumented ``django.template.library.parse_bits()`` function no longer
+ accepts the ``takes_context`` argument.
+
* The minimum supported version of SQLite is increased from 3.31.0 to 3.37.0.
* The :lookup:`iexact=None ` lookup on
diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist
index 1aa456b91af1..f963940184e9 100644
--- a/docs/spelling_wordlist
+++ b/docs/spelling_wordlist
@@ -52,6 +52,7 @@ benchmarking
Benoit
Berners
Biggs
+Biome
bitwise
Bjørn
blazingly
@@ -421,6 +422,7 @@ reindent
releaser
releasers
reloader
+remediator
renderer
renderers
repo
diff --git a/eslint-recommended.js b/eslint-recommended.js
deleted file mode 100644
index 66b183a512f4..000000000000
--- a/eslint-recommended.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* https://github.com/eslint/eslint/blob/v9.36.0/packages/js/src/configs/eslint-recommended.js */
-
-/*
-Copyright OpenJS Foundation and other contributors,
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/**
- * @fileoverview Configuration applied when a user configuration extends from
- * eslint:recommended.
- * @author Nicholas C. Zakas
- */
-
-"use strict";
-
-/* eslint sort-keys: ["error", "asc"] -- Long, so make more readable */
-
-/*
- * IMPORTANT!
- *
- * We cannot add a "name" property to this object because it's still used in eslintrc
- * which doesn't support the "name" property. If we add a "name" property, it will
- * cause an error.
- */
-
-module.exports = Object.freeze({
- rules: Object.freeze({
- "constructor-super": "error",
- "for-direction": "error",
- "getter-return": "error",
- "no-async-promise-executor": "error",
- "no-case-declarations": "error",
- "no-class-assign": "error",
- "no-compare-neg-zero": "error",
- "no-cond-assign": "error",
- "no-const-assign": "error",
- "no-constant-binary-expression": "error",
- "no-constant-condition": "error",
- "no-control-regex": "error",
- "no-debugger": "error",
- "no-delete-var": "error",
- "no-dupe-args": "error",
- "no-dupe-class-members": "error",
- "no-dupe-else-if": "error",
- "no-dupe-keys": "error",
- "no-duplicate-case": "error",
- "no-empty": "error",
- "no-empty-character-class": "error",
- "no-empty-pattern": "error",
- "no-empty-static-block": "error",
- "no-ex-assign": "error",
- "no-extra-boolean-cast": "error",
- "no-fallthrough": "error",
- "no-func-assign": "error",
- "no-global-assign": "error",
- "no-import-assign": "error",
- "no-invalid-regexp": "error",
- "no-irregular-whitespace": "error",
- "no-loss-of-precision": "error",
- "no-misleading-character-class": "error",
- "no-new-native-nonconstructor": "error",
- "no-nonoctal-decimal-escape": "error",
- "no-obj-calls": "error",
- "no-octal": "error",
- "no-prototype-builtins": "error",
- "no-redeclare": "error",
- "no-regex-spaces": "error",
- "no-self-assign": "error",
- "no-setter-return": "error",
- "no-shadow-restricted-names": "error",
- "no-sparse-arrays": "error",
- "no-this-before-super": "error",
- "no-undef": "error",
- "no-unexpected-multiline": "error",
- "no-unreachable": "error",
- "no-unsafe-finally": "error",
- "no-unsafe-negation": "error",
- "no-unsafe-optional-chaining": "error",
- "no-unused-labels": "error",
- "no-unused-private-class-members": "error",
- "no-unused-vars": "error",
- "no-useless-backreference": "error",
- "no-useless-catch": "error",
- "no-useless-escape": "error",
- "no-with": "error",
- "require-yield": "error",
- "use-isnan": "error",
- "valid-typeof": "error",
- }),
-});
diff --git a/eslint.config.mjs b/eslint.config.mjs
deleted file mode 100644
index c3fd4f33a5b7..000000000000
--- a/eslint.config.mjs
+++ /dev/null
@@ -1,63 +0,0 @@
-import globals from "./globals.js";
-import recommended from "./eslint-recommended.js";
-
-export default [
- recommended,
- {
- files: ["**/*.js"],
- rules: {
- "camelcase": ["off", {"properties": "always"}],
- "comma-spacing": ["error", {"before": false, "after": true}],
- "curly": ["error", "all"],
- "dot-notation": ["error", {"allowKeywords": true}],
- "eqeqeq": ["error"],
- "indent": ["error", 4],
- "key-spacing": ["error", {"beforeColon": false, "afterColon": true}],
- "linebreak-style": ["error", "unix"],
- "new-cap": ["off", {"newIsCap": true, "capIsNew": true}],
- "no-alert": ["off"],
- "no-eval": ["error"],
- "no-extend-native": ["error", {"exceptions": ["Date", "String"]}],
- "no-multi-spaces": ["error"],
- "no-octal-escape": ["error"],
- "no-script-url": ["error"],
- "no-shadow": ["error", {"hoist": "functions"}],
- "no-underscore-dangle": ["error"],
- "no-unused-vars": ["error", {"vars": "local", "args": "none"}],
- "no-var": ["error"],
- "prefer-const": ["error"],
- "quotes": ["off", "single"],
- "semi": ["error", "always"],
- "space-before-blocks": ["error", "always"],
- "space-before-function-paren": ["error", {"anonymous": "never", "named": "never"}],
- "space-infix-ops": ["error", {"int32Hint": false}],
- "strict": ["error", "global"]
- },
- languageOptions: {
- ecmaVersion: 6,
- sourceType: "script",
- globals: {
- ...globals.browser,
- ...globals.commonjs,
- "django": false
- }
- }
- },
- {
- files: ["**/*.mjs"],
- languageOptions: {
- sourceType: "module"
- }
- },
- {
- ignores: [
- "**/*.min.js",
- "**/vendor/**/*.js",
- "django/contrib/gis/templates/**/*.js",
- "django/views/templates/*.js",
- "docs/_build/**/*.js",
- "node_modules/**.js",
- "tests/**/*.js",
- ]
- }
-];
diff --git a/globals.js b/globals.js
deleted file mode 100644
index a57de514a883..000000000000
--- a/globals.js
+++ /dev/null
@@ -1,1191 +0,0 @@
-/* https://github.com/sindresorhus/globals/blob/v16.4.0/globals.json */
-
-/*
-MIT License
-
-Copyright (c) Sindre Sorhus (https://sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-"use strict";
-
-
-module.exports = {
- "browser": {
- "AbortController": false,
- "AbortSignal": false,
- "AbsoluteOrientationSensor": false,
- "AbstractRange": false,
- "Accelerometer": false,
- "addEventListener": false,
- "ai": false,
- "AI": false,
- "AICreateMonitor": false,
- "AITextSession": false,
- "alert": false,
- "AnalyserNode": false,
- "Animation": false,
- "AnimationEffect": false,
- "AnimationEvent": false,
- "AnimationPlaybackEvent": false,
- "AnimationTimeline": false,
- "AsyncDisposableStack": false,
- "atob": false,
- "Attr": false,
- "Audio": false,
- "AudioBuffer": false,
- "AudioBufferSourceNode": false,
- "AudioContext": false,
- "AudioData": false,
- "AudioDecoder": false,
- "AudioDestinationNode": false,
- "AudioEncoder": false,
- "AudioListener": false,
- "AudioNode": false,
- "AudioParam": false,
- "AudioParamMap": false,
- "AudioProcessingEvent": false,
- "AudioScheduledSourceNode": false,
- "AudioSinkInfo": false,
- "AudioWorklet": false,
- "AudioWorkletGlobalScope": false,
- "AudioWorkletNode": false,
- "AudioWorkletProcessor": false,
- "AuthenticatorAssertionResponse": false,
- "AuthenticatorAttestationResponse": false,
- "AuthenticatorResponse": false,
- "BackgroundFetchManager": false,
- "BackgroundFetchRecord": false,
- "BackgroundFetchRegistration": false,
- "BarcodeDetector": false,
- "BarProp": false,
- "BaseAudioContext": false,
- "BatteryManager": false,
- "BeforeUnloadEvent": false,
- "BiquadFilterNode": false,
- "Blob": false,
- "BlobEvent": false,
- "Bluetooth": false,
- "BluetoothCharacteristicProperties": false,
- "BluetoothDevice": false,
- "BluetoothRemoteGATTCharacteristic": false,
- "BluetoothRemoteGATTDescriptor": false,
- "BluetoothRemoteGATTServer": false,
- "BluetoothRemoteGATTService": false,
- "BluetoothUUID": false,
- "blur": false,
- "BroadcastChannel": false,
- "BrowserCaptureMediaStreamTrack": false,
- "btoa": false,
- "ByteLengthQueuingStrategy": false,
- "Cache": false,
- "caches": false,
- "CacheStorage": false,
- "cancelAnimationFrame": false,
- "cancelIdleCallback": false,
- "CanvasCaptureMediaStream": false,
- "CanvasCaptureMediaStreamTrack": false,
- "CanvasGradient": false,
- "CanvasPattern": false,
- "CanvasRenderingContext2D": false,
- "CaptureController": false,
- "CaretPosition": false,
- "CDATASection": false,
- "ChannelMergerNode": false,
- "ChannelSplitterNode": false,
- "ChapterInformation": false,
- "CharacterBoundsUpdateEvent": false,
- "CharacterData": false,
- "clearInterval": false,
- "clearTimeout": false,
- "clientInformation": false,
- "Clipboard": false,
- "ClipboardChangeEvent": false,
- "ClipboardEvent": false,
- "ClipboardItem": false,
- "close": false,
- "closed": false,
- "CloseEvent": false,
- "CloseWatcher": false,
- "CommandEvent": false,
- "Comment": false,
- "CompositionEvent": false,
- "CompressionStream": false,
- "confirm": false,
- "console": false,
- "ConstantSourceNode": false,
- "ContentVisibilityAutoStateChangeEvent": false,
- "ConvolverNode": false,
- "CookieChangeEvent": false,
- "CookieDeprecationLabel": false,
- "cookieStore": false,
- "CookieStore": false,
- "CookieStoreManager": false,
- "CountQueuingStrategy": false,
- "createImageBitmap": false,
- "CreateMonitor": false,
- "Credential": false,
- "credentialless": false,
- "CredentialsContainer": false,
- "CropTarget": false,
- "crossOriginIsolated": false,
- "crypto": false,
- "Crypto": false,
- "CryptoKey": false,
- "CSPViolationReportBody": false,
- "CSS": false,
- "CSSAnimation": false,
- "CSSConditionRule": false,
- "CSSContainerRule": false,
- "CSSCounterStyleRule": false,
- "CSSFontFaceRule": false,
- "CSSFontFeatureValuesRule": false,
- "CSSFontPaletteValuesRule": false,
- "CSSFunctionDeclarations": false,
- "CSSFunctionDescriptors": false,
- "CSSFunctionRule": false,
- "CSSGroupingRule": false,
- "CSSImageValue": false,
- "CSSImportRule": false,
- "CSSKeyframeRule": false,
- "CSSKeyframesRule": false,
- "CSSKeywordValue": false,
- "CSSLayerBlockRule": false,
- "CSSLayerStatementRule": false,
- "CSSMarginRule": false,
- "CSSMathClamp": false,
- "CSSMathInvert": false,
- "CSSMathMax": false,
- "CSSMathMin": false,
- "CSSMathNegate": false,
- "CSSMathProduct": false,
- "CSSMathSum": false,
- "CSSMathValue": false,
- "CSSMatrixComponent": false,
- "CSSMediaRule": false,
- "CSSNamespaceRule": false,
- "CSSNestedDeclarations": false,
- "CSSNumericArray": false,
- "CSSNumericValue": false,
- "CSSPageDescriptors": false,
- "CSSPageRule": false,
- "CSSPerspective": false,
- "CSSPositionTryDescriptors": false,
- "CSSPositionTryRule": false,
- "CSSPositionValue": false,
- "CSSPropertyRule": false,
- "CSSRotate": false,
- "CSSRule": false,
- "CSSRuleList": false,
- "CSSScale": false,
- "CSSScopeRule": false,
- "CSSSkew": false,
- "CSSSkewX": false,
- "CSSSkewY": false,
- "CSSStartingStyleRule": false,
- "CSSStyleDeclaration": false,
- "CSSStyleRule": false,
- "CSSStyleSheet": false,
- "CSSStyleValue": false,
- "CSSSupportsRule": false,
- "CSSTransformComponent": false,
- "CSSTransformValue": false,
- "CSSTransition": false,
- "CSSTranslate": false,
- "CSSUnitValue": false,
- "CSSUnparsedValue": false,
- "CSSVariableReferenceValue": false,
- "CSSViewTransitionRule": false,
- "currentFrame": false,
- "currentTime": false,
- "CustomElementRegistry": false,
- "customElements": false,
- "CustomEvent": false,
- "CustomStateSet": false,
- "DataTransfer": false,
- "DataTransferItem": false,
- "DataTransferItemList": false,
- "DecompressionStream": false,
- "DelayNode": false,
- "DelegatedInkTrailPresenter": false,
- "DeviceMotionEvent": false,
- "DeviceMotionEventAcceleration": false,
- "DeviceMotionEventRotationRate": false,
- "DeviceOrientationEvent": false,
- "devicePixelRatio": false,
- "DevicePosture": false,
- "dispatchEvent": false,
- "DisposableStack": false,
- "document": false,
- "Document": false,
- "DocumentFragment": false,
- "documentPictureInPicture": false,
- "DocumentPictureInPicture": false,
- "DocumentPictureInPictureEvent": false,
- "DocumentTimeline": false,
- "DocumentType": false,
- "DOMError": false,
- "DOMException": false,
- "DOMImplementation": false,
- "DOMMatrix": false,
- "DOMMatrixReadOnly": false,
- "DOMParser": false,
- "DOMPoint": false,
- "DOMPointReadOnly": false,
- "DOMQuad": false,
- "DOMRect": false,
- "DOMRectList": false,
- "DOMRectReadOnly": false,
- "DOMStringList": false,
- "DOMStringMap": false,
- "DOMTokenList": false,
- "DragEvent": false,
- "DynamicsCompressorNode": false,
- "EditContext": false,
- "Element": false,
- "ElementInternals": false,
- "EncodedAudioChunk": false,
- "EncodedVideoChunk": false,
- "ErrorEvent": false,
- "event": false,
- "Event": false,
- "EventCounts": false,
- "EventSource": false,
- "EventTarget": false,
- "external": false,
- "External": false,
- "EyeDropper": false,
- "FeaturePolicy": false,
- "FederatedCredential": false,
- "fence": false,
- "Fence": false,
- "FencedFrameConfig": false,
- "fetch": false,
- "fetchLater": false,
- "FetchLaterResult": false,
- "File": false,
- "FileList": false,
- "FileReader": false,
- "FileSystem": false,
- "FileSystemDirectoryEntry": false,
- "FileSystemDirectoryHandle": false,
- "FileSystemDirectoryReader": false,
- "FileSystemEntry": false,
- "FileSystemFileEntry": false,
- "FileSystemFileHandle": false,
- "FileSystemHandle": false,
- "FileSystemObserver": false,
- "FileSystemWritableFileStream": false,
- "find": false,
- "focus": false,
- "FocusEvent": false,
- "FontData": false,
- "FontFace": false,
- "FontFaceSet": false,
- "FontFaceSetLoadEvent": false,
- "FormData": false,
- "FormDataEvent": false,
- "FragmentDirective": false,
- "frameElement": false,
- "frames": false,
- "GainNode": false,
- "Gamepad": false,
- "GamepadAxisMoveEvent": false,
- "GamepadButton": false,
- "GamepadButtonEvent": false,
- "GamepadEvent": false,
- "GamepadHapticActuator": false,
- "GamepadPose": false,
- "Geolocation": false,
- "GeolocationCoordinates": false,
- "GeolocationPosition": false,
- "GeolocationPositionError": false,
- "getComputedStyle": false,
- "getScreenDetails": false,
- "getSelection": false,
- "GPU": false,
- "GPUAdapter": false,
- "GPUAdapterInfo": false,
- "GPUBindGroup": false,
- "GPUBindGroupLayout": false,
- "GPUBuffer": false,
- "GPUBufferUsage": false,
- "GPUCanvasContext": false,
- "GPUColorWrite": false,
- "GPUCommandBuffer": false,
- "GPUCommandEncoder": false,
- "GPUCompilationInfo": false,
- "GPUCompilationMessage": false,
- "GPUComputePassEncoder": false,
- "GPUComputePipeline": false,
- "GPUDevice": false,
- "GPUDeviceLostInfo": false,
- "GPUError": false,
- "GPUExternalTexture": false,
- "GPUInternalError": false,
- "GPUMapMode": false,
- "GPUOutOfMemoryError": false,
- "GPUPipelineError": false,
- "GPUPipelineLayout": false,
- "GPUQuerySet": false,
- "GPUQueue": false,
- "GPURenderBundle": false,
- "GPURenderBundleEncoder": false,
- "GPURenderPassEncoder": false,
- "GPURenderPipeline": false,
- "GPUSampler": false,
- "GPUShaderModule": false,
- "GPUShaderStage": false,
- "GPUSupportedFeatures": false,
- "GPUSupportedLimits": false,
- "GPUTexture": false,
- "GPUTextureUsage": false,
- "GPUTextureView": false,
- "GPUUncapturedErrorEvent": false,
- "GPUValidationError": false,
- "GravitySensor": false,
- "Gyroscope": false,
- "HashChangeEvent": false,
- "Headers": false,
- "HID": false,
- "HIDConnectionEvent": false,
- "HIDDevice": false,
- "HIDInputReportEvent": false,
- "Highlight": false,
- "HighlightRegistry": false,
- "history": false,
- "History": false,
- "HTMLAllCollection": false,
- "HTMLAnchorElement": false,
- "HTMLAreaElement": false,
- "HTMLAudioElement": false,
- "HTMLBaseElement": false,
- "HTMLBodyElement": false,
- "HTMLBRElement": false,
- "HTMLButtonElement": false,
- "HTMLCanvasElement": false,
- "HTMLCollection": false,
- "HTMLDataElement": false,
- "HTMLDataListElement": false,
- "HTMLDetailsElement": false,
- "HTMLDialogElement": false,
- "HTMLDirectoryElement": false,
- "HTMLDivElement": false,
- "HTMLDListElement": false,
- "HTMLDocument": false,
- "HTMLElement": false,
- "HTMLEmbedElement": false,
- "HTMLFencedFrameElement": false,
- "HTMLFieldSetElement": false,
- "HTMLFontElement": false,
- "HTMLFormControlsCollection": false,
- "HTMLFormElement": false,
- "HTMLFrameElement": false,
- "HTMLFrameSetElement": false,
- "HTMLHeadElement": false,
- "HTMLHeadingElement": false,
- "HTMLHRElement": false,
- "HTMLHtmlElement": false,
- "HTMLIFrameElement": false,
- "HTMLImageElement": false,
- "HTMLInputElement": false,
- "HTMLLabelElement": false,
- "HTMLLegendElement": false,
- "HTMLLIElement": false,
- "HTMLLinkElement": false,
- "HTMLMapElement": false,
- "HTMLMarqueeElement": false,
- "HTMLMediaElement": false,
- "HTMLMenuElement": false,
- "HTMLMetaElement": false,
- "HTMLMeterElement": false,
- "HTMLModElement": false,
- "HTMLObjectElement": false,
- "HTMLOListElement": false,
- "HTMLOptGroupElement": false,
- "HTMLOptionElement": false,
- "HTMLOptionsCollection": false,
- "HTMLOutputElement": false,
- "HTMLParagraphElement": false,
- "HTMLParamElement": false,
- "HTMLPictureElement": false,
- "HTMLPreElement": false,
- "HTMLProgressElement": false,
- "HTMLQuoteElement": false,
- "HTMLScriptElement": false,
- "HTMLSelectedContentElement": false,
- "HTMLSelectElement": false,
- "HTMLSlotElement": false,
- "HTMLSourceElement": false,
- "HTMLSpanElement": false,
- "HTMLStyleElement": false,
- "HTMLTableCaptionElement": false,
- "HTMLTableCellElement": false,
- "HTMLTableColElement": false,
- "HTMLTableElement": false,
- "HTMLTableRowElement": false,
- "HTMLTableSectionElement": false,
- "HTMLTemplateElement": false,
- "HTMLTextAreaElement": false,
- "HTMLTimeElement": false,
- "HTMLTitleElement": false,
- "HTMLTrackElement": false,
- "HTMLUListElement": false,
- "HTMLUnknownElement": false,
- "HTMLVideoElement": false,
- "IDBCursor": false,
- "IDBCursorWithValue": false,
- "IDBDatabase": false,
- "IDBFactory": false,
- "IDBIndex": false,
- "IDBKeyRange": false,
- "IDBObjectStore": false,
- "IDBOpenDBRequest": false,
- "IDBRequest": false,
- "IDBTransaction": false,
- "IDBVersionChangeEvent": false,
- "IdentityCredential": false,
- "IdentityCredentialError": false,
- "IdentityProvider": false,
- "IdleDeadline": false,
- "IdleDetector": false,
- "IIRFilterNode": false,
- "Image": false,
- "ImageBitmap": false,
- "ImageBitmapRenderingContext": false,
- "ImageCapture": false,
- "ImageData": false,
- "ImageDecoder": false,
- "ImageTrack": false,
- "ImageTrackList": false,
- "indexedDB": false,
- "Ink": false,
- "innerHeight": false,
- "innerWidth": false,
- "InputDeviceCapabilities": false,
- "InputDeviceInfo": false,
- "InputEvent": false,
- "IntegrityViolationReportBody": false,
- "IntersectionObserver": false,
- "IntersectionObserverEntry": false,
- "isSecureContext": false,
- "Keyboard": false,
- "KeyboardEvent": false,
- "KeyboardLayoutMap": false,
- "KeyframeEffect": false,
- "LanguageDetector": false,
- "LargestContentfulPaint": false,
- "LaunchParams": false,
- "launchQueue": false,
- "LaunchQueue": false,
- "LayoutShift": false,
- "LayoutShiftAttribution": false,
- "length": false,
- "LinearAccelerationSensor": false,
- "localStorage": false,
- "location": true,
- "Location": false,
- "locationbar": false,
- "Lock": false,
- "LockManager": false,
- "matchMedia": false,
- "MathMLElement": false,
- "MediaCapabilities": false,
- "MediaCapabilitiesInfo": false,
- "MediaDeviceInfo": false,
- "MediaDevices": false,
- "MediaElementAudioSourceNode": false,
- "MediaEncryptedEvent": false,
- "MediaError": false,
- "MediaKeyError": false,
- "MediaKeyMessageEvent": false,
- "MediaKeys": false,
- "MediaKeySession": false,
- "MediaKeyStatusMap": false,
- "MediaKeySystemAccess": false,
- "MediaList": false,
- "MediaMetadata": false,
- "MediaQueryList": false,
- "MediaQueryListEvent": false,
- "MediaRecorder": false,
- "MediaRecorderErrorEvent": false,
- "MediaSession": false,
- "MediaSource": false,
- "MediaSourceHandle": false,
- "MediaStream": false,
- "MediaStreamAudioDestinationNode": false,
- "MediaStreamAudioSourceNode": false,
- "MediaStreamEvent": false,
- "MediaStreamTrack": false,
- "MediaStreamTrackAudioSourceNode": false,
- "MediaStreamTrackAudioStats": false,
- "MediaStreamTrackEvent": false,
- "MediaStreamTrackGenerator": false,
- "MediaStreamTrackProcessor": false,
- "MediaStreamTrackVideoStats": false,
- "menubar": false,
- "MessageChannel": false,
- "MessageEvent": false,
- "MessagePort": false,
- "MIDIAccess": false,
- "MIDIConnectionEvent": false,
- "MIDIInput": false,
- "MIDIInputMap": false,
- "MIDIMessageEvent": false,
- "MIDIOutput": false,
- "MIDIOutputMap": false,
- "MIDIPort": false,
- "MimeType": false,
- "MimeTypeArray": false,
- "model": false,
- "ModelGenericSession": false,
- "ModelManager": false,
- "MouseEvent": false,
- "moveBy": false,
- "moveTo": false,
- "MutationEvent": false,
- "MutationObserver": false,
- "MutationRecord": false,
- "name": false,
- "NamedNodeMap": false,
- "NavigateEvent": false,
- "navigation": false,
- "Navigation": false,
- "NavigationActivation": false,
- "NavigationCurrentEntryChangeEvent": false,
- "NavigationDestination": false,
- "NavigationHistoryEntry": false,
- "NavigationPreloadManager": false,
- "NavigationTransition": false,
- "navigator": false,
- "Navigator": false,
- "NavigatorLogin": false,
- "NavigatorManagedData": false,
- "NavigatorUAData": false,
- "NetworkInformation": false,
- "Node": false,
- "NodeFilter": false,
- "NodeIterator": false,
- "NodeList": false,
- "Notification": false,
- "NotifyPaintEvent": false,
- "NotRestoredReasonDetails": false,
- "NotRestoredReasons": false,
- "Observable": false,
- "OfflineAudioCompletionEvent": false,
- "OfflineAudioContext": false,
- "offscreenBuffering": false,
- "OffscreenCanvas": false,
- "OffscreenCanvasRenderingContext2D": false,
- "onabort": true,
- "onafterprint": true,
- "onanimationcancel": true,
- "onanimationend": true,
- "onanimationiteration": true,
- "onanimationstart": true,
- "onappinstalled": true,
- "onauxclick": true,
- "onbeforeinput": true,
- "onbeforeinstallprompt": true,
- "onbeforematch": true,
- "onbeforeprint": true,
- "onbeforetoggle": true,
- "onbeforeunload": true,
- "onbeforexrselect": true,
- "onblur": true,
- "oncancel": true,
- "oncanplay": true,
- "oncanplaythrough": true,
- "onchange": true,
- "onclick": true,
- "onclose": true,
- "oncommand": true,
- "oncontentvisibilityautostatechange": true,
- "oncontextlost": true,
- "oncontextmenu": true,
- "oncontextrestored": true,
- "oncopy": true,
- "oncuechange": true,
- "oncut": true,
- "ondblclick": true,
- "ondevicemotion": true,
- "ondeviceorientation": true,
- "ondeviceorientationabsolute": true,
- "ondrag": true,
- "ondragend": true,
- "ondragenter": true,
- "ondragleave": true,
- "ondragover": true,
- "ondragstart": true,
- "ondrop": true,
- "ondurationchange": true,
- "onemptied": true,
- "onended": true,
- "onerror": true,
- "onfocus": true,
- "onformdata": true,
- "ongamepadconnected": true,
- "ongamepaddisconnected": true,
- "ongotpointercapture": true,
- "onhashchange": true,
- "oninput": true,
- "oninvalid": true,
- "onkeydown": true,
- "onkeypress": true,
- "onkeyup": true,
- "onlanguagechange": true,
- "onload": true,
- "onloadeddata": true,
- "onloadedmetadata": true,
- "onloadstart": true,
- "onlostpointercapture": true,
- "onmessage": true,
- "onmessageerror": true,
- "onmousedown": true,
- "onmouseenter": true,
- "onmouseleave": true,
- "onmousemove": true,
- "onmouseout": true,
- "onmouseover": true,
- "onmouseup": true,
- "onmousewheel": true,
- "onoffline": true,
- "ononline": true,
- "onpagehide": true,
- "onpagereveal": true,
- "onpageshow": true,
- "onpageswap": true,
- "onpaste": true,
- "onpause": true,
- "onplay": true,
- "onplaying": true,
- "onpointercancel": true,
- "onpointerdown": true,
- "onpointerenter": true,
- "onpointerleave": true,
- "onpointermove": true,
- "onpointerout": true,
- "onpointerover": true,
- "onpointerrawupdate": true,
- "onpointerup": true,
- "onpopstate": true,
- "onprogress": true,
- "onratechange": true,
- "onrejectionhandled": true,
- "onreset": true,
- "onresize": true,
- "onscroll": true,
- "onscrollend": true,
- "onscrollsnapchange": true,
- "onscrollsnapchanging": true,
- "onsearch": true,
- "onsecuritypolicyviolation": true,
- "onseeked": true,
- "onseeking": true,
- "onselect": true,
- "onselectionchange": true,
- "onselectstart": true,
- "onslotchange": true,
- "onstalled": true,
- "onstorage": true,
- "onsubmit": true,
- "onsuspend": true,
- "ontimeupdate": true,
- "ontoggle": true,
- "ontransitioncancel": true,
- "ontransitionend": true,
- "ontransitionrun": true,
- "ontransitionstart": true,
- "onunhandledrejection": true,
- "onunload": true,
- "onvolumechange": true,
- "onwaiting": true,
- "onwheel": true,
- "open": false,
- "opener": false,
- "Option": false,
- "OrientationSensor": false,
- "origin": false,
- "originAgentCluster": false,
- "OscillatorNode": false,
- "OTPCredential": false,
- "outerHeight": false,
- "outerWidth": false,
- "OverconstrainedError": false,
- "PageRevealEvent": false,
- "PageSwapEvent": false,
- "PageTransitionEvent": false,
- "pageXOffset": false,
- "pageYOffset": false,
- "PannerNode": false,
- "parent": false,
- "PasswordCredential": false,
- "Path2D": false,
- "PaymentAddress": false,
- "PaymentManager": false,
- "PaymentMethodChangeEvent": false,
- "PaymentRequest": false,
- "PaymentRequestUpdateEvent": false,
- "PaymentResponse": false,
- "performance": false,
- "Performance": false,
- "PerformanceElementTiming": false,
- "PerformanceEntry": false,
- "PerformanceEventTiming": false,
- "PerformanceLongAnimationFrameTiming": false,
- "PerformanceLongTaskTiming": false,
- "PerformanceMark": false,
- "PerformanceMeasure": false,
- "PerformanceNavigation": false,
- "PerformanceNavigationTiming": false,
- "PerformanceObserver": false,
- "PerformanceObserverEntryList": false,
- "PerformancePaintTiming": false,
- "PerformanceResourceTiming": false,
- "PerformanceScriptTiming": false,
- "PerformanceServerTiming": false,
- "PerformanceTiming": false,
- "PeriodicSyncManager": false,
- "PeriodicWave": false,
- "Permissions": false,
- "PermissionStatus": false,
- "PERSISTENT": false,
- "personalbar": false,
- "PictureInPictureEvent": false,
- "PictureInPictureWindow": false,
- "Plugin": false,
- "PluginArray": false,
- "PointerEvent": false,
- "PopStateEvent": false,
- "postMessage": false,
- "Presentation": false,
- "PresentationAvailability": false,
- "PresentationConnection": false,
- "PresentationConnectionAvailableEvent": false,
- "PresentationConnectionCloseEvent": false,
- "PresentationConnectionList": false,
- "PresentationReceiver": false,
- "PresentationRequest": false,
- "PressureObserver": false,
- "PressureRecord": false,
- "print": false,
- "ProcessingInstruction": false,
- "Profiler": false,
- "ProgressEvent": false,
- "PromiseRejectionEvent": false,
- "prompt": false,
- "ProtectedAudience": false,
- "PublicKeyCredential": false,
- "PushManager": false,
- "PushSubscription": false,
- "PushSubscriptionOptions": false,
- "queryLocalFonts": false,
- "queueMicrotask": false,
- "QuotaExceededError": false,
- "RadioNodeList": false,
- "Range": false,
- "ReadableByteStreamController": false,
- "ReadableStream": false,
- "ReadableStreamBYOBReader": false,
- "ReadableStreamBYOBRequest": false,
- "ReadableStreamDefaultController": false,
- "ReadableStreamDefaultReader": false,
- "registerProcessor": false,
- "RelativeOrientationSensor": false,
- "RemotePlayback": false,
- "removeEventListener": false,
- "ReportBody": false,
- "reportError": false,
- "ReportingObserver": false,
- "Request": false,
- "requestAnimationFrame": false,
- "requestIdleCallback": false,
- "resizeBy": false,
- "ResizeObserver": false,
- "ResizeObserverEntry": false,
- "ResizeObserverSize": false,
- "resizeTo": false,
- "Response": false,
- "RestrictionTarget": false,
- "RTCCertificate": false,
- "RTCDataChannel": false,
- "RTCDataChannelEvent": false,
- "RTCDtlsTransport": false,
- "RTCDTMFSender": false,
- "RTCDTMFToneChangeEvent": false,
- "RTCEncodedAudioFrame": false,
- "RTCEncodedVideoFrame": false,
- "RTCError": false,
- "RTCErrorEvent": false,
- "RTCIceCandidate": false,
- "RTCIceTransport": false,
- "RTCPeerConnection": false,
- "RTCPeerConnectionIceErrorEvent": false,
- "RTCPeerConnectionIceEvent": false,
- "RTCRtpReceiver": false,
- "RTCRtpScriptTransform": false,
- "RTCRtpSender": false,
- "RTCRtpTransceiver": false,
- "RTCSctpTransport": false,
- "RTCSessionDescription": false,
- "RTCStatsReport": false,
- "RTCTrackEvent": false,
- "sampleRate": false,
- "scheduler": false,
- "Scheduler": false,
- "Scheduling": false,
- "screen": false,
- "Screen": false,
- "ScreenDetailed": false,
- "ScreenDetails": false,
- "screenLeft": false,
- "ScreenOrientation": false,
- "screenTop": false,
- "screenX": false,
- "screenY": false,
- "ScriptProcessorNode": false,
- "scroll": false,
- "scrollbars": false,
- "scrollBy": false,
- "ScrollTimeline": false,
- "scrollTo": false,
- "scrollX": false,
- "scrollY": false,
- "SecurityPolicyViolationEvent": false,
- "Selection": false,
- "self": false,
- "Sensor": false,
- "SensorErrorEvent": false,
- "Serial": false,
- "SerialPort": false,
- "ServiceWorker": false,
- "ServiceWorkerContainer": false,
- "ServiceWorkerRegistration": false,
- "sessionStorage": false,
- "setInterval": false,
- "setTimeout": false,
- "ShadowRoot": false,
- "sharedStorage": false,
- "SharedStorage": false,
- "SharedStorageAppendMethod": false,
- "SharedStorageClearMethod": false,
- "SharedStorageDeleteMethod": false,
- "SharedStorageModifierMethod": false,
- "SharedStorageSetMethod": false,
- "SharedStorageWorklet": false,
- "SharedWorker": false,
- "showDirectoryPicker": false,
- "showOpenFilePicker": false,
- "showSaveFilePicker": false,
- "SnapEvent": false,
- "SourceBuffer": false,
- "SourceBufferList": false,
- "SpeechGrammar": false,
- "SpeechGrammarList": false,
- "SpeechRecognition": false,
- "SpeechRecognitionErrorEvent": false,
- "SpeechRecognitionEvent": false,
- "speechSynthesis": false,
- "SpeechSynthesis": false,
- "SpeechSynthesisErrorEvent": false,
- "SpeechSynthesisEvent": false,
- "SpeechSynthesisUtterance": false,
- "SpeechSynthesisVoice": false,
- "StaticRange": false,
- "status": false,
- "statusbar": false,
- "StereoPannerNode": false,
- "stop": false,
- "Storage": false,
- "StorageBucket": false,
- "StorageBucketManager": false,
- "StorageEvent": false,
- "StorageManager": false,
- "structuredClone": false,
- "styleMedia": false,
- "StylePropertyMap": false,
- "StylePropertyMapReadOnly": false,
- "StyleSheet": false,
- "StyleSheetList": false,
- "SubmitEvent": false,
- "Subscriber": false,
- "SubtleCrypto": false,
- "Summarizer": false,
- "SuppressedError": false,
- "SVGAElement": false,
- "SVGAngle": false,
- "SVGAnimatedAngle": false,
- "SVGAnimatedBoolean": false,
- "SVGAnimatedEnumeration": false,
- "SVGAnimatedInteger": false,
- "SVGAnimatedLength": false,
- "SVGAnimatedLengthList": false,
- "SVGAnimatedNumber": false,
- "SVGAnimatedNumberList": false,
- "SVGAnimatedPreserveAspectRatio": false,
- "SVGAnimatedRect": false,
- "SVGAnimatedString": false,
- "SVGAnimatedTransformList": false,
- "SVGAnimateElement": false,
- "SVGAnimateMotionElement": false,
- "SVGAnimateTransformElement": false,
- "SVGAnimationElement": false,
- "SVGCircleElement": false,
- "SVGClipPathElement": false,
- "SVGComponentTransferFunctionElement": false,
- "SVGDefsElement": false,
- "SVGDescElement": false,
- "SVGElement": false,
- "SVGEllipseElement": false,
- "SVGFEBlendElement": false,
- "SVGFEColorMatrixElement": false,
- "SVGFEComponentTransferElement": false,
- "SVGFECompositeElement": false,
- "SVGFEConvolveMatrixElement": false,
- "SVGFEDiffuseLightingElement": false,
- "SVGFEDisplacementMapElement": false,
- "SVGFEDistantLightElement": false,
- "SVGFEDropShadowElement": false,
- "SVGFEFloodElement": false,
- "SVGFEFuncAElement": false,
- "SVGFEFuncBElement": false,
- "SVGFEFuncGElement": false,
- "SVGFEFuncRElement": false,
- "SVGFEGaussianBlurElement": false,
- "SVGFEImageElement": false,
- "SVGFEMergeElement": false,
- "SVGFEMergeNodeElement": false,
- "SVGFEMorphologyElement": false,
- "SVGFEOffsetElement": false,
- "SVGFEPointLightElement": false,
- "SVGFESpecularLightingElement": false,
- "SVGFESpotLightElement": false,
- "SVGFETileElement": false,
- "SVGFETurbulenceElement": false,
- "SVGFilterElement": false,
- "SVGForeignObjectElement": false,
- "SVGGElement": false,
- "SVGGeometryElement": false,
- "SVGGradientElement": false,
- "SVGGraphicsElement": false,
- "SVGImageElement": false,
- "SVGLength": false,
- "SVGLengthList": false,
- "SVGLinearGradientElement": false,
- "SVGLineElement": false,
- "SVGMarkerElement": false,
- "SVGMaskElement": false,
- "SVGMatrix": false,
- "SVGMetadataElement": false,
- "SVGMPathElement": false,
- "SVGNumber": false,
- "SVGNumberList": false,
- "SVGPathElement": false,
- "SVGPatternElement": false,
- "SVGPoint": false,
- "SVGPointList": false,
- "SVGPolygonElement": false,
- "SVGPolylineElement": false,
- "SVGPreserveAspectRatio": false,
- "SVGRadialGradientElement": false,
- "SVGRect": false,
- "SVGRectElement": false,
- "SVGScriptElement": false,
- "SVGSetElement": false,
- "SVGStopElement": false,
- "SVGStringList": false,
- "SVGStyleElement": false,
- "SVGSVGElement": false,
- "SVGSwitchElement": false,
- "SVGSymbolElement": false,
- "SVGTextContentElement": false,
- "SVGTextElement": false,
- "SVGTextPathElement": false,
- "SVGTextPositioningElement": false,
- "SVGTitleElement": false,
- "SVGTransform": false,
- "SVGTransformList": false,
- "SVGTSpanElement": false,
- "SVGUnitTypes": false,
- "SVGUseElement": false,
- "SVGViewElement": false,
- "SyncManager": false,
- "TaskAttributionTiming": false,
- "TaskController": false,
- "TaskPriorityChangeEvent": false,
- "TaskSignal": false,
- "TEMPORARY": false,
- "Text": false,
- "TextDecoder": false,
- "TextDecoderStream": false,
- "TextEncoder": false,
- "TextEncoderStream": false,
- "TextEvent": false,
- "TextFormat": false,
- "TextFormatUpdateEvent": false,
- "TextMetrics": false,
- "TextTrack": false,
- "TextTrackCue": false,
- "TextTrackCueList": false,
- "TextTrackList": false,
- "TextUpdateEvent": false,
- "TimeEvent": false,
- "TimeRanges": false,
- "ToggleEvent": false,
- "toolbar": false,
- "top": false,
- "Touch": false,
- "TouchEvent": false,
- "TouchList": false,
- "TrackEvent": false,
- "TransformStream": false,
- "TransformStreamDefaultController": false,
- "TransitionEvent": false,
- "Translator": false,
- "TreeWalker": false,
- "TrustedHTML": false,
- "TrustedScript": false,
- "TrustedScriptURL": false,
- "TrustedTypePolicy": false,
- "TrustedTypePolicyFactory": false,
- "trustedTypes": false,
- "UIEvent": false,
- "URL": false,
- "URLPattern": false,
- "URLSearchParams": false,
- "USB": false,
- "USBAlternateInterface": false,
- "USBConfiguration": false,
- "USBConnectionEvent": false,
- "USBDevice": false,
- "USBEndpoint": false,
- "USBInterface": false,
- "USBInTransferResult": false,
- "USBIsochronousInTransferPacket": false,
- "USBIsochronousInTransferResult": false,
- "USBIsochronousOutTransferPacket": false,
- "USBIsochronousOutTransferResult": false,
- "USBOutTransferResult": false,
- "UserActivation": false,
- "ValidityState": false,
- "VideoColorSpace": false,
- "VideoDecoder": false,
- "VideoEncoder": false,
- "VideoFrame": false,
- "VideoPlaybackQuality": false,
- "viewport": false,
- "Viewport": false,
- "ViewTimeline": false,
- "ViewTransition": false,
- "ViewTransitionTypeSet": false,
- "VirtualKeyboard": false,
- "VirtualKeyboardGeometryChangeEvent": false,
- "VisibilityStateEntry": false,
- "visualViewport": false,
- "VisualViewport": false,
- "VTTCue": false,
- "VTTRegion": false,
- "WakeLock": false,
- "WakeLockSentinel": false,
- "WaveShaperNode": false,
- "WebAssembly": false,
- "WebGL2RenderingContext": false,
- "WebGLActiveInfo": false,
- "WebGLBuffer": false,
- "WebGLContextEvent": false,
- "WebGLFramebuffer": false,
- "WebGLObject": false,
- "WebGLProgram": false,
- "WebGLQuery": false,
- "WebGLRenderbuffer": false,
- "WebGLRenderingContext": false,
- "WebGLSampler": false,
- "WebGLShader": false,
- "WebGLShaderPrecisionFormat": false,
- "WebGLSync": false,
- "WebGLTexture": false,
- "WebGLTransformFeedback": false,
- "WebGLUniformLocation": false,
- "WebGLVertexArrayObject": false,
- "WebSocket": false,
- "WebSocketError": false,
- "WebSocketStream": false,
- "WebTransport": false,
- "WebTransportBidirectionalStream": false,
- "WebTransportDatagramDuplexStream": false,
- "WebTransportError": false,
- "WebTransportReceiveStream": false,
- "WebTransportSendStream": false,
- "WGSLLanguageFeatures": false,
- "WheelEvent": false,
- "when": false,
- "window": false,
- "Window": false,
- "WindowControlsOverlay": false,
- "WindowControlsOverlayGeometryChangeEvent": false,
- "Worker": false,
- "Worklet": false,
- "WorkletGlobalScope": false,
- "WritableStream": false,
- "WritableStreamDefaultController": false,
- "WritableStreamDefaultWriter": false,
- "XMLDocument": false,
- "XMLHttpRequest": false,
- "XMLHttpRequestEventTarget": false,
- "XMLHttpRequestUpload": false,
- "XMLSerializer": false,
- "XPathEvaluator": false,
- "XPathExpression": false,
- "XPathResult": false,
- "XRAnchor": false,
- "XRAnchorSet": false,
- "XRBoundedReferenceSpace": false,
- "XRCamera": false,
- "XRCPUDepthInformation": false,
- "XRDepthInformation": false,
- "XRDOMOverlayState": false,
- "XRFrame": false,
- "XRHand": false,
- "XRHitTestResult": false,
- "XRHitTestSource": false,
- "XRInputSource": false,
- "XRInputSourceArray": false,
- "XRInputSourceEvent": false,
- "XRInputSourcesChangeEvent": false,
- "XRJointPose": false,
- "XRJointSpace": false,
- "XRLayer": false,
- "XRLightEstimate": false,
- "XRLightProbe": false,
- "XRPose": false,
- "XRRay": false,
- "XRReferenceSpace": false,
- "XRReferenceSpaceEvent": false,
- "XRRenderState": false,
- "XRRigidTransform": false,
- "XRSession": false,
- "XRSessionEvent": false,
- "XRSpace": false,
- "XRSystem": false,
- "XRTransientInputHitTestResult": false,
- "XRTransientInputHitTestSource": false,
- "XRView": false,
- "XRViewerPose": false,
- "XRViewport": false,
- "XRWebGLBinding": false,
- "XRWebGLDepthInformation": false,
- "XRWebGLLayer": false,
- "XSLTProcessor": false
- },
- "commonjs": {
- "exports": true,
- "global": false,
- "module": false,
- "require": false
- }
-};
diff --git a/js_tests/admin/DateTimeShortcuts.test.js b/js_tests/admin/DateTimeShortcuts.test.js
index 6cb534610cd6..5c850ce7d249 100644
--- a/js_tests/admin/DateTimeShortcuts.test.js
+++ b/js_tests/admin/DateTimeShortcuts.test.js
@@ -1,59 +1,81 @@
/* global QUnit, DateTimeShortcuts */
-'use strict';
+"use strict";
-QUnit.module('admin.DateTimeShortcuts');
+QUnit.module("admin.DateTimeShortcuts");
-QUnit.test('init', function(assert) {
+QUnit.test("init", function (assert) {
const $ = django.jQuery;
- const dateField = $(' ');
- $('#qunit-fixture').append(dateField);
+ const dateField = $(
+ ' ',
+ );
+ $("#qunit-fixture").append(dateField);
DateTimeShortcuts.init();
- const shortcuts = $('.datetimeshortcuts');
+ const shortcuts = $(".datetimeshortcuts");
assert.equal(shortcuts.length, 1);
- assert.equal(shortcuts.find('a:first').text(), 'Today');
- assert.equal(shortcuts.find('a:last .date-icon').length, 1);
+ assert.equal(shortcuts.find("a:first").text(), "Today");
+ assert.equal(shortcuts.find("a:last .date-icon").length, 1);
// To prevent incorrect timezone warnings on date/time widgets, timezoneOffset
// should be 0 when a timezone offset isn't set in the HTML body attribute.
assert.equal(DateTimeShortcuts.timezoneOffset, 0);
});
-QUnit.test('custom time shortcuts', function(assert) {
+QUnit.test("custom time shortcuts", function (assert) {
const $ = django.jQuery;
- const timeField = $(' ');
- $('#qunit-fixture').append(timeField);
- DateTimeShortcuts.clockHours.time_test = [['3 a.m.', 3]];
+ const timeField = $(
+ ' ',
+ );
+ $("#qunit-fixture").append(timeField);
+ DateTimeShortcuts.clockHours.time_test = [["3 a.m.", 3]];
DateTimeShortcuts.init();
- assert.equal($('.clockbox').find('a').first().text(), '3 a.m.');
+ assert.equal($(".clockbox").find("a").first().text(), "3 a.m.");
});
-QUnit.test('time zone offset warning - single field', function(assert) {
+QUnit.test("time zone offset warning - single field", function (assert) {
const $ = django.jQuery;
- const savedOffset = $('body').attr('data-admin-utc-offset');
+ const savedOffset = $("body").attr("data-admin-utc-offset");
// Single date or time field.
- const timeField = $(' ');
- $('#qunit-fixture').append(timeField);
- $('body').attr('data-admin-utc-offset', new Date().getTimezoneOffset() * -60 + 3600);
+ const timeField = $(
+ ' ',
+ );
+ $("#qunit-fixture").append(timeField);
+ $("body").attr(
+ "data-admin-utc-offset",
+ new Date().getTimezoneOffset() * -60 + 3600,
+ );
DateTimeShortcuts.init();
- $('body').attr('data-admin-utc-offset', savedOffset);
- assert.equal($('.timezonewarning').text(), 'Note: You are 1 hour behind server time.');
- assert.equal($('.timezonewarning').attr("id"), "id_updated_at_timezone_warning_helptext");
+ $("body").attr("data-admin-utc-offset", savedOffset);
+ assert.equal(
+ $(".timezonewarning").text(),
+ "Note: You are 1 hour behind server time.",
+ );
+ assert.equal(
+ $(".timezonewarning").attr("id"),
+ "id_updated_at_timezone_warning_helptext",
+ );
});
-QUnit.test('time zone offset warning - date and time field', function(assert) {
+QUnit.test("time zone offset warning - date and time field", function (assert) {
const $ = django.jQuery;
- const savedOffset = $('body').attr('data-admin-utc-offset');
+ const savedOffset = $("body").attr("data-admin-utc-offset");
// DateTimeField with fieldset containing date and time inputs.
- const dateTimeField = '' +
- ' ' +
- ' ' +
- '
';
- $('#qunit-fixture').append($(dateTimeField));
- $('body').attr('data-admin-utc-offset', new Date().getTimezoneOffset() * -60 + 3600);
+ const dateTimeField =
+ '' +
+ ' ' +
+ ' ' +
+ "
";
+ $("#qunit-fixture").append($(dateTimeField));
+ $("body").attr(
+ "data-admin-utc-offset",
+ new Date().getTimezoneOffset() * -60 + 3600,
+ );
DateTimeShortcuts.init();
- $('body').attr('data-admin-utc-offset', savedOffset);
- assert.equal($('.timezonewarning').attr("id"), "id_updated_at_timezone_warning_helptext");
+ $("body").attr("data-admin-utc-offset", savedOffset);
+ assert.equal(
+ $(".timezonewarning").attr("id"),
+ "id_updated_at_timezone_warning_helptext",
+ );
});
diff --git a/js_tests/admin/RelatedObjectLookups.test.js b/js_tests/admin/RelatedObjectLookups.test.js
index 0d71d88f2a8a..b7df8f181ffb 100644
--- a/js_tests/admin/RelatedObjectLookups.test.js
+++ b/js_tests/admin/RelatedObjectLookups.test.js
@@ -1,77 +1,98 @@
/* global QUnit, RelatedObjectLookups */
-'use strict';
+"use strict";
-QUnit.module('admin.RelatedObjectLookups', {
- beforeEach: function() {
+QUnit.module("admin.RelatedObjectLookups", {
+ beforeEach: function () {
const $ = django.jQuery;
- $('#qunit-fixture').append(`
+ $("#qunit-fixture").append(`
`);
- }
+ },
});
-QUnit.test('dismissRelatedLookupPopup closes popup window', function(assert) {
- const testId = 'test_id';
+QUnit.test("dismissRelatedLookupPopup closes popup window", function (assert) {
+ const testId = "test_id";
let windowClosed = false;
const mockWin = {
name: testId,
- close: function() {
+ close: function () {
windowClosed = true;
- }
+ },
};
- window.dismissRelatedLookupPopup(mockWin, '123');
- assert.true(windowClosed, 'Popup window should be closed');
+ window.dismissRelatedLookupPopup(mockWin, "123");
+ assert.true(windowClosed, "Popup window should be closed");
});
-QUnit.test('dismissRelatedLookupPopup removes window from relatedWindows array', function(assert) {
- const testId = 'test_id';
- const mockWin = {
- name: testId,
- close: function() {}
- };
- window.relatedWindows.push(mockWin);
- assert.equal(window.relatedWindows.indexOf(mockWin), 0, 'Window should be in relatedWindows array');
- window.dismissRelatedLookupPopup(mockWin, '123');
- assert.equal(window.relatedWindows.indexOf(mockWin), -1, 'Window should be removed from relatedWindows array');
-});
+QUnit.test(
+ "dismissRelatedLookupPopup removes window from relatedWindows array",
+ function (assert) {
+ const testId = "test_id";
+ const mockWin = {
+ name: testId,
+ close: function () {},
+ };
+ window.relatedWindows.push(mockWin);
+ assert.equal(
+ window.relatedWindows.indexOf(mockWin),
+ 0,
+ "Window should be in relatedWindows array",
+ );
+ window.dismissRelatedLookupPopup(mockWin, "123");
+ assert.equal(
+ window.relatedWindows.indexOf(mockWin),
+ -1,
+ "Window should be removed from relatedWindows array",
+ );
+ },
+);
-QUnit.test('dismissRelatedLookupPopup triggers change event for single value field', function(assert) {
- assert.timeout(1000);
- const done = assert.async();
- const $ = django.jQuery;
- const testId = 'test_id';
- const newValue = '123';
- const mockWin = {
- name: testId,
- close: function() {}
- };
- let changeTriggered = false;
- $('#test_id').on('change', function() {
- changeTriggered = true;
- assert.equal(this.value, newValue, 'Value should be updated');
- done();
- });
- window.dismissRelatedLookupPopup(mockWin, newValue);
- assert.true(changeTriggered, 'Change event should be triggered');
-});
+QUnit.test(
+ "dismissRelatedLookupPopup triggers change event for single value field",
+ function (assert) {
+ assert.timeout(1000);
+ const done = assert.async();
+ const $ = django.jQuery;
+ const testId = "test_id";
+ const newValue = "123";
+ const mockWin = {
+ name: testId,
+ close: function () {},
+ };
+ let changeTriggered = false;
+ $("#test_id").on("change", function () {
+ changeTriggered = true;
+ assert.equal(this.value, newValue, "Value should be updated");
+ done();
+ });
+ window.dismissRelatedLookupPopup(mockWin, newValue);
+ assert.true(changeTriggered, "Change event should be triggered");
+ },
+);
-QUnit.test('dismissRelatedLookupPopup triggers change event for many-to-many field', function(assert) {
- assert.timeout(1000);
- const $ = django.jQuery;
- const testId = 'many_test_id';
- const existingValue = '1,2';
- const newValue = '3';
- $('#many_test_id').val(existingValue);
- const mockWin = {
- name: testId,
- close: function() {}
- };
- let changeTriggered = false;
- $('#many_test_id').on('change', function() {
- changeTriggered = true;
- assert.equal(this.value, existingValue + ',' + newValue, 'Value should be appended for many-to-many fields');
- });
- window.dismissRelatedLookupPopup(mockWin, newValue);
- assert.true(changeTriggered, 'Change event should be triggered');
-});
+QUnit.test(
+ "dismissRelatedLookupPopup triggers change event for many-to-many field",
+ function (assert) {
+ assert.timeout(1000);
+ const $ = django.jQuery;
+ const testId = "many_test_id";
+ const existingValue = "1,2";
+ const newValue = "3";
+ $("#many_test_id").val(existingValue);
+ const mockWin = {
+ name: testId,
+ close: function () {},
+ };
+ let changeTriggered = false;
+ $("#many_test_id").on("change", function () {
+ changeTriggered = true;
+ assert.equal(
+ this.value,
+ existingValue + "," + newValue,
+ "Value should be appended for many-to-many fields",
+ );
+ });
+ window.dismissRelatedLookupPopup(mockWin, newValue);
+ assert.true(changeTriggered, "Change event should be triggered");
+ },
+);
diff --git a/js_tests/admin/SelectBox.test.js b/js_tests/admin/SelectBox.test.js
index 4915ba6b9bd5..e32fa4c35304 100644
--- a/js_tests/admin/SelectBox.test.js
+++ b/js_tests/admin/SelectBox.test.js
@@ -1,207 +1,210 @@
/* global QUnit, SelectBox */
-'use strict';
+"use strict";
-QUnit.module('admin.SelectBox');
+QUnit.module("admin.SelectBox");
-QUnit.test('init: no options', function(assert) {
+QUnit.test("init: no options", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- SelectBox.init('id');
+ $(' ').appendTo("#qunit-fixture");
+ SelectBox.init("id");
assert.equal(SelectBox.cache.id.length, 0);
});
-QUnit.test('filter', function(assert) {
+QUnit.test("filter", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- $('A ').appendTo('#id');
- $('B ').appendTo('#id');
- SelectBox.init('id');
- assert.equal($('#id option').length, 2);
- SelectBox.filter('id', "A");
- assert.equal($('#id option').length, 1);
- assert.equal($('#id option').text(), "A");
+ $(' ').appendTo("#qunit-fixture");
+ $('A ').appendTo("#id");
+ $('B ').appendTo("#id");
+ SelectBox.init("id");
+ assert.equal($("#id option").length, 2);
+ SelectBox.filter("id", "A");
+ assert.equal($("#id option").length, 1);
+ assert.equal($("#id option").text(), "A");
});
-QUnit.test('preserve scroll position', function(assert) {
+QUnit.test("preserve scroll position", function (assert) {
const $ = django.jQuery;
const optionsCount = 100;
- $(' ').appendTo('#qunit-fixture');
- $(' ').appendTo('#qunit-fixture');
- const fromSelectBox = document.getElementById('from_id');
- const toSelectBox = document.getElementById('to_id');
+ $(' ').appendTo("#qunit-fixture");
+ $(' ').appendTo("#qunit-fixture");
+ const fromSelectBox = document.getElementById("from_id");
+ const toSelectBox = document.getElementById("to_id");
for (let i = 0; i < optionsCount; i++) {
fromSelectBox.appendChild(new Option());
}
- SelectBox.init('from_id');
- SelectBox.init('to_id');
+ SelectBox.init("from_id");
+ SelectBox.init("to_id");
const selectedOptions = [97, 98, 99];
for (const index of selectedOptions) {
fromSelectBox.options[index].selected = true;
fromSelectBox.options[index].scrollIntoView();
}
assert.equal(fromSelectBox.options.length, optionsCount);
- SelectBox.move('from_id', 'to_id');
- assert.equal(fromSelectBox.options.length, optionsCount - selectedOptions.length);
+ SelectBox.move("from_id", "to_id");
+ assert.equal(
+ fromSelectBox.options.length,
+ optionsCount - selectedOptions.length,
+ );
assert.equal(toSelectBox.options.length, selectedOptions.length);
assert.notEqual(fromSelectBox.scrollTop, 0);
});
-QUnit.test('retain optgroups', function(assert) {
+QUnit.test("retain optgroups", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- const grp = $('').appendTo('#id');
+ $(' ').appendTo("#qunit-fixture");
+ const grp = $('').appendTo("#id");
$('A ').appendTo(grp);
- $(' ').appendTo('#id');
- $('B ').appendTo('#id');
- SelectBox.init('id');
- SelectBox.redisplay('id');
- assert.equal($('#id option').length, 2);
- assert.equal($('#id optgroup').length, 1);
+ $(" ").appendTo("#id");
+ $('B ').appendTo("#id");
+ SelectBox.init("id");
+ SelectBox.redisplay("id");
+ assert.equal($("#id option").length, 2);
+ assert.equal($("#id optgroup").length, 1);
});
-QUnit.test('sort optgroups', function(assert) {
+QUnit.test("sort optgroups", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
// Add optgroups in non-alphabetical order
- const grp2 = $('').appendTo('#id');
+ const grp2 = $('').appendTo("#id");
$('Item 3 ').appendTo(grp2);
$('Item 4 ').appendTo(grp2);
- const grp1 = $('').appendTo('#id');
+ const grp1 = $('').appendTo("#id");
$('Item 1 ').appendTo(grp1);
$('Item 2 ').appendTo(grp1);
- SelectBox.init('id');
+ SelectBox.init("id");
// Verify cache is sorted by group then by item
assert.equal(SelectBox.cache.id.length, 4);
- assert.equal(SelectBox.cache.id[0].group, 'Group A');
- assert.equal(SelectBox.cache.id[0].text, 'Item 1');
- assert.equal(SelectBox.cache.id[1].group, 'Group A');
- assert.equal(SelectBox.cache.id[1].text, 'Item 2');
- assert.equal(SelectBox.cache.id[2].group, 'Group B');
- assert.equal(SelectBox.cache.id[2].text, 'Item 3');
- assert.equal(SelectBox.cache.id[3].group, 'Group B');
- assert.equal(SelectBox.cache.id[3].text, 'Item 4');
+ assert.equal(SelectBox.cache.id[0].group, "Group A");
+ assert.equal(SelectBox.cache.id[0].text, "Item 1");
+ assert.equal(SelectBox.cache.id[1].group, "Group A");
+ assert.equal(SelectBox.cache.id[1].text, "Item 2");
+ assert.equal(SelectBox.cache.id[2].group, "Group B");
+ assert.equal(SelectBox.cache.id[2].text, "Item 3");
+ assert.equal(SelectBox.cache.id[3].group, "Group B");
+ assert.equal(SelectBox.cache.id[3].text, "Item 4");
});
-QUnit.test('do not sort when no optgroups', function(assert) {
+QUnit.test("do not sort when no optgroups", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
// Add options in non-alphabetical order
- $('Zebra ').appendTo('#id');
- $('Apple ').appendTo('#id');
- $('Banana ').appendTo('#id');
+ $('Zebra ').appendTo("#id");
+ $('Apple ').appendTo("#id");
+ $('Banana ').appendTo("#id");
- SelectBox.init('id');
+ SelectBox.init("id");
// Verify cache preserves original order (not sorted)
assert.equal(SelectBox.cache.id.length, 3);
- assert.equal(SelectBox.cache.id[0].text, 'Zebra');
- assert.equal(SelectBox.cache.id[1].text, 'Apple');
- assert.equal(SelectBox.cache.id[2].text, 'Banana');
+ assert.equal(SelectBox.cache.id[0].text, "Zebra");
+ assert.equal(SelectBox.cache.id[1].text, "Apple");
+ assert.equal(SelectBox.cache.id[2].text, "Banana");
});
-QUnit.test('move with optgroups sorts', function(assert) {
+QUnit.test("move with optgroups sorts", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
+ $(' ').appendTo("#qunit-fixture");
// Add options with optgroups to from_id in non-alphabetical order
- const grp2 = $('').appendTo('#from_id');
+ const grp2 = $('').appendTo("#from_id");
$('Item 2 ').appendTo(grp2);
- const grp1 = $('').appendTo('#from_id');
+ const grp1 = $('').appendTo("#from_id");
$('Item 1 ').appendTo(grp1);
- SelectBox.init('from_id');
- SelectBox.init('to_id');
+ SelectBox.init("from_id");
+ SelectBox.init("to_id");
// Select and move item
- document.getElementById('from_id').options[0].selected = true;
- SelectBox.move('from_id', 'to_id');
+ document.getElementById("from_id").options[0].selected = true;
+ SelectBox.move("from_id", "to_id");
// Verify to_id cache is sorted (even though we only added one item)
assert.equal(SelectBox.cache.to_id.length, 1);
- assert.equal(SelectBox.cache.to_id[0].group, 'Group B');
- assert.equal(SelectBox.cache.to_id[0].text, 'Item 2');
+ assert.equal(SelectBox.cache.to_id[0].group, "Group B");
+ assert.equal(SelectBox.cache.to_id[0].text, "Item 2");
});
-QUnit.test('move without optgroups does not sort', function(assert) {
+QUnit.test("move without optgroups does not sort", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
+ $(' ').appendTo("#qunit-fixture");
// Add options without optgroups in non-alphabetical order
- $('Zebra ').appendTo('#from_id');
- $('Apple ').appendTo('#from_id');
+ $('Zebra ').appendTo("#from_id");
+ $('Apple ').appendTo("#from_id");
- SelectBox.init('from_id');
- SelectBox.init('to_id');
+ SelectBox.init("from_id");
+ SelectBox.init("to_id");
// Select and move first item (Zebra)
- document.getElementById('from_id').options[0].selected = true;
- SelectBox.move('from_id', 'to_id');
+ document.getElementById("from_id").options[0].selected = true;
+ SelectBox.move("from_id", "to_id");
// Verify to_id cache preserves order (not sorted)
assert.equal(SelectBox.cache.to_id.length, 1);
- assert.equal(SelectBox.cache.to_id[0].text, 'Zebra');
+ assert.equal(SelectBox.cache.to_id[0].text, "Zebra");
// Move second item (Apple)
- document.getElementById('from_id').options[0].selected = true;
- SelectBox.move('from_id', 'to_id');
+ document.getElementById("from_id").options[0].selected = true;
+ SelectBox.move("from_id", "to_id");
// Verify items are in order they were added, not alphabetical
assert.equal(SelectBox.cache.to_id.length, 2);
- assert.equal(SelectBox.cache.to_id[0].text, 'Zebra');
- assert.equal(SelectBox.cache.to_id[1].text, 'Apple');
+ assert.equal(SelectBox.cache.to_id[0].text, "Zebra");
+ assert.equal(SelectBox.cache.to_id[1].text, "Apple");
});
-QUnit.test('move_all with optgroups sorts', function(assert) {
+QUnit.test("move_all with optgroups sorts", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
+ $(' ').appendTo("#qunit-fixture");
// Add options with optgroups in non-alphabetical order
- const grp2 = $('').appendTo('#from_id');
+ const grp2 = $('').appendTo("#from_id");
$('Zebra ').appendTo(grp2);
- const grp1 = $('').appendTo('#from_id');
+ const grp1 = $('').appendTo("#from_id");
$('Apple ').appendTo(grp1);
$('Banana ').appendTo(grp1);
- SelectBox.init('from_id');
- SelectBox.init('to_id');
+ SelectBox.init("from_id");
+ SelectBox.init("to_id");
// Move all items
- SelectBox.move_all('from_id', 'to_id');
+ SelectBox.move_all("from_id", "to_id");
// Verify to_id cache is sorted by group
assert.equal(SelectBox.cache.to_id.length, 3);
- assert.equal(SelectBox.cache.to_id[0].group, 'Group A');
- assert.equal(SelectBox.cache.to_id[0].text, 'Apple');
- assert.equal(SelectBox.cache.to_id[1].group, 'Group A');
- assert.equal(SelectBox.cache.to_id[1].text, 'Banana');
- assert.equal(SelectBox.cache.to_id[2].group, 'Group B');
- assert.equal(SelectBox.cache.to_id[2].text, 'Zebra');
+ assert.equal(SelectBox.cache.to_id[0].group, "Group A");
+ assert.equal(SelectBox.cache.to_id[0].text, "Apple");
+ assert.equal(SelectBox.cache.to_id[1].group, "Group A");
+ assert.equal(SelectBox.cache.to_id[1].text, "Banana");
+ assert.equal(SelectBox.cache.to_id[2].group, "Group B");
+ assert.equal(SelectBox.cache.to_id[2].text, "Zebra");
});
-QUnit.test('move_all without optgroups does not sort', function(assert) {
+QUnit.test("move_all without optgroups does not sort", function (assert) {
const $ = django.jQuery;
- $(' ').appendTo('#qunit-fixture');
- $(' ').appendTo('#qunit-fixture');
+ $(' ').appendTo("#qunit-fixture");
+ $(' ').appendTo("#qunit-fixture");
// Add options without optgroups in non-alphabetical order
- $('Zebra ').appendTo('#from_id');
- $('Apple ').appendTo('#from_id');
- $('Banana ').appendTo('#from_id');
+ $('Zebra ').appendTo("#from_id");
+ $('Apple ').appendTo("#from_id");
+ $('Banana ').appendTo("#from_id");
- SelectBox.init('from_id');
- SelectBox.init('to_id');
+ SelectBox.init("from_id");
+ SelectBox.init("to_id");
// Move all items
- SelectBox.move_all('from_id', 'to_id');
+ SelectBox.move_all("from_id", "to_id");
// Verify to_id cache preserves original order (not sorted)
assert.equal(SelectBox.cache.to_id.length, 3);
- assert.equal(SelectBox.cache.to_id[0].text, 'Zebra');
- assert.equal(SelectBox.cache.to_id[1].text, 'Apple');
- assert.equal(SelectBox.cache.to_id[2].text, 'Banana');
+ assert.equal(SelectBox.cache.to_id[0].text, "Zebra");
+ assert.equal(SelectBox.cache.to_id[1].text, "Apple");
+ assert.equal(SelectBox.cache.to_id[2].text, "Banana");
});
diff --git a/js_tests/admin/SelectFilter2.test.js b/js_tests/admin/SelectFilter2.test.js
index 9a020d2c539a..0d0283f9b6b8 100644
--- a/js_tests/admin/SelectFilter2.test.js
+++ b/js_tests/admin/SelectFilter2.test.js
@@ -1,174 +1,241 @@
/* global QUnit, SelectFilter */
-'use strict';
+"use strict";
-QUnit.module('admin.SelectFilter2');
+QUnit.module("admin.SelectFilter2");
-QUnit.test('init', function(assert) {
+QUnit.test("init", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Test ').appendTo('#test');
- $('This is helpful.
').appendTo('#test');
- $('A ').appendTo('#test');
- SelectFilter.init('id', 'things', 0);
+ $('').appendTo("#qunit-fixture");
+ $('Test ').appendTo("#test");
+ $('This is helpful.
').appendTo("#test");
+ $('A ').appendTo(
+ "#test",
+ );
+ SelectFilter.init("id", "things", 0);
assert.deepEqual(
- Array.from($('#test')[0].children).map(child => child.tagName),
- ["LABEL", "DIV", "DIV"]
- );
- assert.equal($('.helptext')[0].nextSibling.getAttribute("class"), "selector");
- assert.equal($('.selector-available label').text().trim(), "Available things");
- assert.equal($('.selector-available label').attr("id"), "id_from_label");
- assert.equal($('.selector-chosen label').text().trim(), "Chosen things");
- assert.equal($('.selector-chosen label').attr("id"), "id_to_label");
- assert.equal($('.selector-chosen select')[0].getAttribute('multiple'), '');
- assert.equal($('.selector-chooseall').text(), "Choose all things");
- assert.equal($('.selector-chooseall').prop("tagName"), "BUTTON");
- assert.equal($('.selector-add').text(), "Choose selected things");
- assert.equal($('.selector-add').prop("tagName"), "BUTTON");
- assert.equal($('.selector-remove').text(), "Remove selected things");
- assert.equal($('.selector-remove').prop("tagName"), "BUTTON");
- assert.equal($('.selector-clearall').text(), "Remove all things");
- assert.equal($('.selector-clearall').prop("tagName"), "BUTTON");
- assert.equal($('.selector-available .filtered').attr("aria-labelledby"), "id_from_label");
- assert.equal($('.selector-available .filtered').attr("aria-describedby"), "id_helptext id_choose_helptext");
- assert.equal($('.selector-available .selector-available-title label').text(), "Available things ");
- assert.equal($('.selector-available .selector-available-title .helptext').text(), 'Choose things by selecting them and then select the "Choose" arrow button.');
- assert.equal($('.selector-chosen .filtered').attr("aria-labelledby"), "id_to_label");
- assert.equal($('.selector-chosen .filtered').attr("aria-describedby"), "id_helptext id_remove_helptext");
- assert.equal($('.selector-chosen .selector-chosen-title label').text(), "Chosen things ");
- assert.equal($('.selector-chosen .selector-chosen-title .helptext').text(), 'Remove things by selecting them and then select the "Remove" arrow button.');
- assert.equal($('.selector-filter label .help-tooltip')[0].getAttribute("aria-label"), "Type into this box to filter down the list of available things.");
- assert.equal($('.selector-filter label .help-tooltip')[1].getAttribute("aria-label"), "Type into this box to filter down the list of selected things.");
+ Array.from($("#test")[0].children).map((child) => child.tagName),
+ ["LABEL", "DIV", "DIV"],
+ );
+ assert.equal(
+ $(".helptext")[0].nextSibling.getAttribute("class"),
+ "selector",
+ );
+ assert.equal(
+ $(".selector-available label").text().trim(),
+ "Available things",
+ );
+ assert.equal($(".selector-available label").attr("id"), "id_from_label");
+ assert.equal($(".selector-chosen label").text().trim(), "Chosen things");
+ assert.equal($(".selector-chosen label").attr("id"), "id_to_label");
+ assert.equal($(".selector-chosen select")[0].getAttribute("multiple"), "");
+ assert.equal($(".selector-chooseall").text(), "Choose all things");
+ assert.equal($(".selector-chooseall").prop("tagName"), "BUTTON");
+ assert.equal($(".selector-add").text(), "Choose selected things");
+ assert.equal($(".selector-add").prop("tagName"), "BUTTON");
+ assert.equal($(".selector-remove").text(), "Remove selected things");
+ assert.equal($(".selector-remove").prop("tagName"), "BUTTON");
+ assert.equal($(".selector-clearall").text(), "Remove all things");
+ assert.equal($(".selector-clearall").prop("tagName"), "BUTTON");
+ assert.equal(
+ $(".selector-available .filtered").attr("aria-labelledby"),
+ "id_from_label",
+ );
+ assert.equal(
+ $(".selector-available .filtered").attr("aria-describedby"),
+ "id_helptext id_choose_helptext",
+ );
+ assert.equal(
+ $(".selector-available .selector-available-title label").text(),
+ "Available things ",
+ );
+ assert.equal(
+ $(".selector-available .selector-available-title .helptext").text(),
+ 'Choose things by selecting them and then select the "Choose" arrow button.',
+ );
+ assert.equal(
+ $(".selector-chosen .filtered").attr("aria-labelledby"),
+ "id_to_label",
+ );
+ assert.equal(
+ $(".selector-chosen .filtered").attr("aria-describedby"),
+ "id_helptext id_remove_helptext",
+ );
+ assert.equal(
+ $(".selector-chosen .selector-chosen-title label").text(),
+ "Chosen things ",
+ );
+ assert.equal(
+ $(".selector-chosen .selector-chosen-title .helptext").text(),
+ 'Remove things by selecting them and then select the "Remove" arrow button.',
+ );
+ assert.equal(
+ $(".selector-filter label .help-tooltip")[0].getAttribute("aria-label"),
+ "Type into this box to filter down the list of available things.",
+ );
+ assert.equal(
+ $(".selector-filter label .help-tooltip")[1].getAttribute("aria-label"),
+ "Type into this box to filter down the list of selected things.",
+ );
assert.equal($('#test button:not([type="button"])').length, 0);
});
-QUnit.test('filtering available options', function(assert) {
+QUnit.test("filtering available options", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 3);
- assert.equal($('#select_to option').length, 0);
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo("#select");
+ $('Blue ').appendTo("#select");
+ $('Green ').appendTo("#select");
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 3);
+ assert.equal($("#select_to option").length, 0);
const done = assert.async();
- const search_term = 'r';
- const event = new KeyboardEvent('keyup', {'key': search_term});
- $('#select_input').val(search_term);
- SelectFilter.filter_key_up(event, 'select', '_from');
+ const search_term = "r";
+ const event = new KeyboardEvent("keyup", { key: search_term });
+ $("#select_input").val(search_term);
+ SelectFilter.filter_key_up(event, "select", "_from");
setTimeout(() => {
- assert.equal($('#select_from option').length, 2);
- assert.equal($('#select_to option').length, 0);
- assert.equal($('#select_from option')[0].value, '1');
- assert.equal($('#select_from option')[1].value, '3');
+ assert.equal($("#select_from option").length, 2);
+ assert.equal($("#select_to option").length, 0);
+ assert.equal($("#select_from option")[0].value, "1");
+ assert.equal($("#select_from option")[1].value, "3");
done();
});
});
-QUnit.test('filtering selected options', function(assert) {
+QUnit.test("filtering selected options", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 0);
- assert.equal($('#select_to option').length, 3);
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo(
+ "#select",
+ );
+ $('Blue ').appendTo(
+ "#select",
+ );
+ $('Green ').appendTo(
+ "#select",
+ );
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 0);
+ assert.equal($("#select_to option").length, 3);
const done = assert.async();
- const search_term = 'r';
- const event = new KeyboardEvent('keyup', {'key': search_term});
- $('#select_selected_input').val(search_term);
- SelectFilter.filter_key_up(event, 'select', '_to', '_selected_input');
+ const search_term = "r";
+ const event = new KeyboardEvent("keyup", { key: search_term });
+ $("#select_selected_input").val(search_term);
+ SelectFilter.filter_key_up(event, "select", "_to", "_selected_input");
setTimeout(() => {
- assert.equal($('#select_from option').length, 0);
- assert.equal($('#select_to option').length, 2);
- assert.equal($('#select_to option')[0].value, '1');
- assert.equal($('#select_to option')[1].value, '3');
+ assert.equal($("#select_from option").length, 0);
+ assert.equal($("#select_to option").length, 2);
+ assert.equal($("#select_to option")[0].value, "1");
+ assert.equal($("#select_to option")[1].value, "3");
done();
});
});
-QUnit.test('filtering available options to nothing', function(assert) {
+QUnit.test("filtering available options to nothing", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 3);
- assert.equal($('#select_to option').length, 0);
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo("#select");
+ $('Blue ').appendTo("#select");
+ $('Green ').appendTo("#select");
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 3);
+ assert.equal($("#select_to option").length, 0);
const done = assert.async();
- const search_term = 'x';
- const event = new KeyboardEvent('keyup', {'key': search_term});
- $('#select_input').val(search_term);
- SelectFilter.filter_key_up(event, 'select', '_from');
+ const search_term = "x";
+ const event = new KeyboardEvent("keyup", { key: search_term });
+ $("#select_input").val(search_term);
+ SelectFilter.filter_key_up(event, "select", "_from");
setTimeout(() => {
- assert.equal($('#select_from option').length, 0);
- assert.equal($('#select_to option').length, 0);
+ assert.equal($("#select_from option").length, 0);
+ assert.equal($("#select_to option").length, 0);
done();
});
});
-QUnit.test('filtering selected options to nothing', function(assert) {
+QUnit.test("filtering selected options to nothing", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 0);
- assert.equal($('#select_to option').length, 3);
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo(
+ "#select",
+ );
+ $('Blue ').appendTo(
+ "#select",
+ );
+ $('Green ').appendTo(
+ "#select",
+ );
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 0);
+ assert.equal($("#select_to option").length, 3);
const done = assert.async();
- const search_term = 'x';
- const event = new KeyboardEvent('keyup', {'key': search_term});
- $('#select_selected_input').val(search_term);
- SelectFilter.filter_key_up(event, 'select', '_to', '_selected_input');
+ const search_term = "x";
+ const event = new KeyboardEvent("keyup", { key: search_term });
+ $("#select_selected_input").val(search_term);
+ SelectFilter.filter_key_up(event, "select", "_to", "_selected_input");
setTimeout(() => {
- assert.equal($('#select_from option').length, 0);
- assert.equal($('#select_to option').length, 0);
+ assert.equal($("#select_from option").length, 0);
+ assert.equal($("#select_to option").length, 0);
done();
});
});
-QUnit.test('selecting option', function(assert) {
+QUnit.test("selecting option", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 3);
- assert.equal($('#select_to option').length, 0);
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo("#select");
+ $('Blue ').appendTo("#select");
+ $('Green ').appendTo("#select");
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 3);
+ assert.equal($("#select_to option").length, 0);
// move to the right
const done = assert.async();
- $('#select_from')[0].selectedIndex = 0;
- const event = new KeyboardEvent('keydown', {'keyCode': 39, 'charCode': 39});
- SelectFilter.filter_key_down(event, 'select', '_from', '_to');
+ $("#select_from")[0].selectedIndex = 0;
+ const event = new KeyboardEvent("keydown", { keyCode: 39, charCode: 39 });
+ SelectFilter.filter_key_down(event, "select", "_from", "_to");
setTimeout(() => {
- assert.equal($('#select_from option').length, 2);
- assert.equal($('#select_to option').length, 1);
- assert.equal($('#select_to option')[0].value, '1');
+ assert.equal($("#select_from option").length, 2);
+ assert.equal($("#select_to option").length, 1);
+ assert.equal($("#select_to option")[0].value, "1");
done();
});
});
-QUnit.test('deselecting option', function(assert) {
+QUnit.test("deselecting option", function (assert) {
const $ = django.jQuery;
- $('').appendTo('#qunit-fixture');
- $('Red ').appendTo('#select');
- $('Blue ').appendTo('#select');
- $('Green ').appendTo('#select');
- SelectFilter.init('select', 'items', 0);
- assert.equal($('#select_from option').length, 2);
- assert.equal($('#select_to option').length, 1);
- assert.equal($('#select_to option')[0].value, '1');
+ $('').appendTo(
+ "#qunit-fixture",
+ );
+ $('Red ').appendTo(
+ "#select",
+ );
+ $('Blue ').appendTo("#select");
+ $('Green ').appendTo("#select");
+ SelectFilter.init("select", "items", 0);
+ assert.equal($("#select_from option").length, 2);
+ assert.equal($("#select_to option").length, 1);
+ assert.equal($("#select_to option")[0].value, "1");
// move back to the left
const done_left = assert.async();
- $('#select_to')[0].selectedIndex = 0;
- const event_left = new KeyboardEvent('keydown', {'keyCode': 37, 'charCode': 37});
- SelectFilter.filter_key_down(event_left, 'select', '_to', '_from');
+ $("#select_to")[0].selectedIndex = 0;
+ const event_left = new KeyboardEvent("keydown", {
+ keyCode: 37,
+ charCode: 37,
+ });
+ SelectFilter.filter_key_down(event_left, "select", "_to", "_from");
setTimeout(() => {
- assert.equal($('#select_from option').length, 3);
- assert.equal($('#select_to option').length, 0);
+ assert.equal($("#select_from option").length, 3);
+ assert.equal($("#select_to option").length, 0);
done_left();
});
});
diff --git a/js_tests/admin/URLify.test.js b/js_tests/admin/URLify.test.js
index 471f2fbf050e..36afd676c9d0 100644
--- a/js_tests/admin/URLify.test.js
+++ b/js_tests/admin/URLify.test.js
@@ -1,28 +1,28 @@
/* global QUnit, URLify */
-'use strict';
+"use strict";
-QUnit.module('admin.URLify');
+QUnit.module("admin.URLify");
-QUnit.test('empty string', function(assert) {
- assert.strictEqual(URLify('', 8, true), '');
+QUnit.test("empty string", function (assert) {
+ assert.strictEqual(URLify("", 8, true), "");
});
-QUnit.test('preserve nonessential words', function(assert) {
- assert.strictEqual(URLify('the D is silent', 15, true), 'the-d-is-silent');
+QUnit.test("preserve nonessential words", function (assert) {
+ assert.strictEqual(URLify("the D is silent", 15, true), "the-d-is-silent");
});
-QUnit.test('strip non-URL characters', function(assert) {
- assert.strictEqual(URLify('D#silent@', 7, true), 'dsilent');
+QUnit.test("strip non-URL characters", function (assert) {
+ assert.strictEqual(URLify("D#silent@", 7, true), "dsilent");
});
-QUnit.test('merge adjacent whitespace', function(assert) {
- assert.strictEqual(URLify('D silent', 8, true), 'd-silent');
+QUnit.test("merge adjacent whitespace", function (assert) {
+ assert.strictEqual(URLify("D silent", 8, true), "d-silent");
});
-QUnit.test('trim trailing hyphens', function(assert) {
- assert.strictEqual(URLify('D silent always', 9, true), 'd-silent');
+QUnit.test("trim trailing hyphens", function (assert) {
+ assert.strictEqual(URLify("D silent always", 9, true), "d-silent");
});
-QUnit.test('non-ASCII string', function(assert) {
- assert.strictEqual(URLify('Kaupa-miða', 255, true), 'kaupa-miða');
+QUnit.test("non-ASCII string", function (assert) {
+ assert.strictEqual(URLify("Kaupa-miða", 255, true), "kaupa-miða");
});
diff --git a/js_tests/admin/actions.test.js b/js_tests/admin/actions.test.js
index bcc10debaa64..cfe1b6a20afa 100644
--- a/js_tests/admin/actions.test.js
+++ b/js_tests/admin/actions.test.js
@@ -1,23 +1,21 @@
/* global QUnit, Actions */
-'use strict';
+"use strict";
-QUnit.module('admin.actions', {
- beforeEach: function() {
+QUnit.module("admin.actions", {
+ beforeEach: function () {
// Number of results shown on page
- /* eslint-disable */
- window._actions_icnt = '100';
- /* eslint-enable */
+ window._actions_icnt = "100";
const $ = django.jQuery;
- $('#qunit-fixture').append($('#result-table').text());
+ $("#qunit-fixture").append($("#result-table").text());
- Actions(document.querySelectorAll('tr input.action-select'));
- }
+ Actions(document.querySelectorAll("tr input.action-select"));
+ },
});
-QUnit.test('check', function(assert) {
+QUnit.test("check", function (assert) {
const $ = django.jQuery;
- assert.notOk($('.action-select').is(':checked'));
- $('#action-toggle').click();
- assert.ok($('.action-select').is(':checked'));
+ assert.notOk($(".action-select").is(":checked"));
+ $("#action-toggle").click();
+ assert.ok($(".action-select").is(":checked"));
});
diff --git a/js_tests/admin/core.test.js b/js_tests/admin/core.test.js
index c549ad99c9f9..8f59d120d6b7 100644
--- a/js_tests/admin/core.test.js
+++ b/js_tests/admin/core.test.js
@@ -1,97 +1,152 @@
/* global QUnit */
-'use strict';
+"use strict";
-QUnit.module('admin.core');
+QUnit.module("admin.core");
-QUnit.test('Date.getTwelveHours', function(assert) {
- assert.equal(new Date(2011, 0, 1, 0, 0).getTwelveHours(), 12, '0:00');
- assert.equal(new Date(2011, 0, 1, 11, 0).getTwelveHours(), 11, '11:00');
- assert.equal(new Date(2011, 0, 1, 16, 0).getTwelveHours(), 4, '16:00');
+QUnit.test("Date.getTwelveHours", function (assert) {
+ assert.equal(new Date(2011, 0, 1, 0, 0).getTwelveHours(), 12, "0:00");
+ assert.equal(new Date(2011, 0, 1, 11, 0).getTwelveHours(), 11, "11:00");
+ assert.equal(new Date(2011, 0, 1, 16, 0).getTwelveHours(), 4, "16:00");
});
-QUnit.test('Date.getTwoDigitMonth', function(assert) {
- assert.equal(new Date(2011, 0, 1).getTwoDigitMonth(), '01', 'jan 1');
- assert.equal(new Date(2011, 9, 1).getTwoDigitMonth(), '10', 'oct 1');
+QUnit.test("Date.getTwoDigitMonth", function (assert) {
+ assert.equal(new Date(2011, 0, 1).getTwoDigitMonth(), "01", "jan 1");
+ assert.equal(new Date(2011, 9, 1).getTwoDigitMonth(), "10", "oct 1");
});
-QUnit.test('Date.getTwoDigitDate', function(assert) {
- assert.equal(new Date(2011, 0, 1).getTwoDigitDate(), '01', 'jan 1');
- assert.equal(new Date(2011, 0, 15).getTwoDigitDate(), '15', 'jan 15');
+QUnit.test("Date.getTwoDigitDate", function (assert) {
+ assert.equal(new Date(2011, 0, 1).getTwoDigitDate(), "01", "jan 1");
+ assert.equal(new Date(2011, 0, 15).getTwoDigitDate(), "15", "jan 15");
});
-QUnit.test('Date.getTwoDigitTwelveHour', function(assert) {
- assert.equal(new Date(2011, 0, 1, 0, 0).getTwoDigitTwelveHour(), '12', '0:00');
- assert.equal(new Date(2011, 0, 1, 4, 0).getTwoDigitTwelveHour(), '04', '4:00');
- assert.equal(new Date(2011, 0, 1, 22, 0).getTwoDigitTwelveHour(), '10', '22:00');
+QUnit.test("Date.getTwoDigitTwelveHour", function (assert) {
+ assert.equal(
+ new Date(2011, 0, 1, 0, 0).getTwoDigitTwelveHour(),
+ "12",
+ "0:00",
+ );
+ assert.equal(
+ new Date(2011, 0, 1, 4, 0).getTwoDigitTwelveHour(),
+ "04",
+ "4:00",
+ );
+ assert.equal(
+ new Date(2011, 0, 1, 22, 0).getTwoDigitTwelveHour(),
+ "10",
+ "22:00",
+ );
});
-QUnit.test('Date.getTwoDigitHour', function(assert) {
- assert.equal(new Date(2014, 6, 1, 9, 0).getTwoDigitHour(), '09', '9:00 am is 09');
- assert.equal(new Date(2014, 6, 1, 11, 0).getTwoDigitHour(), '11', '11:00 am is 11');
+QUnit.test("Date.getTwoDigitHour", function (assert) {
+ assert.equal(
+ new Date(2014, 6, 1, 9, 0).getTwoDigitHour(),
+ "09",
+ "9:00 am is 09",
+ );
+ assert.equal(
+ new Date(2014, 6, 1, 11, 0).getTwoDigitHour(),
+ "11",
+ "11:00 am is 11",
+ );
});
-QUnit.test('Date.getTwoDigitMinute', function(assert) {
- assert.equal(new Date(2014, 6, 1, 0, 5).getTwoDigitMinute(), '05', '12:05 am is 05');
- assert.equal(new Date(2014, 6, 1, 0, 15).getTwoDigitMinute(), '15', '12:15 am is 15');
+QUnit.test("Date.getTwoDigitMinute", function (assert) {
+ assert.equal(
+ new Date(2014, 6, 1, 0, 5).getTwoDigitMinute(),
+ "05",
+ "12:05 am is 05",
+ );
+ assert.equal(
+ new Date(2014, 6, 1, 0, 15).getTwoDigitMinute(),
+ "15",
+ "12:15 am is 15",
+ );
});
-QUnit.test('Date.getTwoDigitSecond', function(assert) {
- assert.equal(new Date(2014, 6, 1, 0, 0, 2).getTwoDigitSecond(), '02', '12:00:02 am is 02');
- assert.equal(new Date(2014, 6, 1, 0, 0, 20).getTwoDigitSecond(), '20', '12:00:20 am is 20');
+QUnit.test("Date.getTwoDigitSecond", function (assert) {
+ assert.equal(
+ new Date(2014, 6, 1, 0, 0, 2).getTwoDigitSecond(),
+ "02",
+ "12:00:02 am is 02",
+ );
+ assert.equal(
+ new Date(2014, 6, 1, 0, 0, 20).getTwoDigitSecond(),
+ "20",
+ "12:00:20 am is 20",
+ );
});
-QUnit.test('Date.getAbbrevMonthName', function(assert) {
- assert.equal(new Date(2020, 0, 26).getAbbrevMonthName(), 'Jan', 'jan 26');
- assert.equal(new Date(2020, 9, 26).getAbbrevMonthName(), 'Oct', 'oct 26');
+QUnit.test("Date.getAbbrevMonthName", function (assert) {
+ assert.equal(new Date(2020, 0, 26).getAbbrevMonthName(), "Jan", "jan 26");
+ assert.equal(new Date(2020, 9, 26).getAbbrevMonthName(), "Oct", "oct 26");
});
-QUnit.test('Date.getFullMonthName', function(assert) {
- assert.equal(new Date(2020, 0, 26).getFullMonthName(), 'January', 'jan 26');
- assert.equal(new Date(2020, 9, 26).getFullMonthName(), 'October', 'oct 26');
+QUnit.test("Date.getFullMonthName", function (assert) {
+ assert.equal(new Date(2020, 0, 26).getFullMonthName(), "January", "jan 26");
+ assert.equal(new Date(2020, 9, 26).getFullMonthName(), "October", "oct 26");
});
-QUnit.test('Date.getAbbrevDayName', function(assert) {
- assert.equal(new Date(2020, 0, 26).getAbbrevDayName(), 'Sun', 'jan 26 2020 is a Sunday');
- assert.equal(new Date(2020, 9, 26).getAbbrevDayName(), 'Mon', 'oct 26 2020 is a Monday');
+QUnit.test("Date.getAbbrevDayName", function (assert) {
+ assert.equal(
+ new Date(2020, 0, 26).getAbbrevDayName(),
+ "Sun",
+ "jan 26 2020 is a Sunday",
+ );
+ assert.equal(
+ new Date(2020, 9, 26).getAbbrevDayName(),
+ "Mon",
+ "oct 26 2020 is a Monday",
+ );
});
-QUnit.test('Date.getFullDayName', function(assert) {
- assert.equal(new Date(2020, 0, 26).getFullDayName(), 'Sunday', 'jan 26 2020 is a Sunday');
- assert.equal(new Date(2020, 9, 26).getFullDayName(), 'Monday', 'oct 26 2020 is a Monday');
+QUnit.test("Date.getFullDayName", function (assert) {
+ assert.equal(
+ new Date(2020, 0, 26).getFullDayName(),
+ "Sunday",
+ "jan 26 2020 is a Sunday",
+ );
+ assert.equal(
+ new Date(2020, 9, 26).getFullDayName(),
+ "Monday",
+ "oct 26 2020 is a Monday",
+ );
});
-QUnit.test('Date.strftime', function(assert) {
+QUnit.test("Date.strftime", function (assert) {
const date = new Date(2014, 6, 1, 11, 0, 5);
- assert.equal(date.strftime('%Y-%m-%d %H:%M:%S'), '2014-07-01 11:00:05');
- assert.equal(date.strftime('%B %d, %Y'), 'July 01, 2014');
- assert.equal(date.strftime('%b %d, %Y'), 'Jul 01, 2014');
- assert.equal(date.strftime('%a %d %m %y'), 'Tue 01 07 14');
- assert.equal(date.strftime('%A (day %w of week) %I %p'), 'Tuesday (day 02 of week) 11 AM');
+ assert.equal(date.strftime("%Y-%m-%d %H:%M:%S"), "2014-07-01 11:00:05");
+ assert.equal(date.strftime("%B %d, %Y"), "July 01, 2014");
+ assert.equal(date.strftime("%b %d, %Y"), "Jul 01, 2014");
+ assert.equal(date.strftime("%a %d %m %y"), "Tue 01 07 14");
+ assert.equal(
+ date.strftime("%A (day %w of week) %I %p"),
+ "Tuesday (day 02 of week) 11 AM",
+ );
});
-QUnit.test('String.strptime', function(assert) {
+QUnit.test("String.strptime", function (assert) {
// Use UTC functions for extracting dates since the calendar uses them as
// well. Month numbering starts with 0 (January).
- const firstParsedDate = '1988-02-26'.strptime('%Y-%m-%d');
+ const firstParsedDate = "1988-02-26".strptime("%Y-%m-%d");
assert.equal(firstParsedDate.getUTCDate(), 26);
assert.equal(firstParsedDate.getUTCMonth(), 1);
assert.equal(firstParsedDate.getUTCFullYear(), 1988);
// A %y value in the range of [69, 99] is in the previous century.
- const secondParsedDate = '26/02/88'.strptime('%d/%m/%y');
+ const secondParsedDate = "26/02/88".strptime("%d/%m/%y");
assert.equal(secondParsedDate.getUTCDate(), 26);
assert.equal(secondParsedDate.getUTCMonth(), 1);
assert.equal(secondParsedDate.getUTCFullYear(), 1988);
- const format = django.get_format('DATE_INPUT_FORMATS')[0];
- const thirdParsedDate = '1983-11-20'.strptime(format);
+ const format = django.get_format("DATE_INPUT_FORMATS")[0];
+ const thirdParsedDate = "1983-11-20".strptime(format);
assert.equal(thirdParsedDate.getUTCDate(), 20);
assert.equal(thirdParsedDate.getUTCMonth(), 10);
assert.equal(thirdParsedDate.getUTCFullYear(), 1983);
// A %y value in the range of [00, 68] is in the current century.
- const fourthParsedDate = '27/09/68'.strptime('%d/%m/%y');
+ const fourthParsedDate = "27/09/68".strptime("%d/%m/%y");
assert.equal(fourthParsedDate.getUTCDate(), 27);
assert.equal(fourthParsedDate.getUTCMonth(), 8);
assert.equal(fourthParsedDate.getUTCFullYear(), 2068);
@@ -103,8 +158,10 @@ QUnit.test('String.strptime', function(assert) {
// Checking timezones from GMT+0100 to GMT+1200
for (let i = 1; i <= 12; i++) {
- const tz = i > 9 ? '' + i : '0' + i;
- const date = new Date(Date.parse('Feb 26, 1988 00:00:00 GMT+' + tz + '00'));
+ const tz = i > 9 ? "" + i : "0" + i;
+ const date = new Date(
+ Date.parse("Feb 26, 1988 00:00:00 GMT+" + tz + "00"),
+ );
assert.notEqual(date.getUTCDate(), 26);
assert.equal(date.getUTCDate(), 25);
assert.equal(date.getUTCMonth(), 1);
@@ -113,8 +170,10 @@ QUnit.test('String.strptime', function(assert) {
// Checking timezones from GMT+0000 to GMT-1100
for (let i = 0; i <= 11; i++) {
- const tz = i > 9 ? '' + i : '0' + i;
- const date = new Date(Date.parse('Feb 26, 1988 00:00:00 GMT-' + tz + '00'));
+ const tz = i > 9 ? "" + i : "0" + i;
+ const date = new Date(
+ Date.parse("Feb 26, 1988 00:00:00 GMT-" + tz + "00"),
+ );
assert.equal(date.getUTCDate(), 26);
assert.equal(date.getUTCMonth(), 1);
assert.equal(date.getUTCFullYear(), 1988);
diff --git a/js_tests/admin/inlines.test.js b/js_tests/admin/inlines.test.js
index ee8567dbf4cd..28de67cf65c2 100644
--- a/js_tests/admin/inlines.test.js
+++ b/js_tests/admin/inlines.test.js
@@ -1,174 +1,197 @@
/* global QUnit */
-'use strict';
+"use strict";
-QUnit.module('admin.inlines: tabular formsets', {
- beforeEach: function() {
+QUnit.module("admin.inlines: tabular formsets", {
+ beforeEach: function () {
const $ = django.jQuery;
- const that = this;
- this.addText = 'Add another';
-
- $('#qunit-fixture').append($('#tabular-formset').text());
- this.table = $('table.inline');
- this.inlineRow = this.table.find('tr');
- this.inlineRow.tabularFormset('table.inline tr.form-row', {
- prefix: 'first',
- addText: that.addText,
- deleteText: 'Remove'
+
+ this.addText = "Add another";
+
+ $("#qunit-fixture").append($("#tabular-formset").text());
+ this.table = $("table.inline");
+ this.inlineRow = this.table.find("tr");
+ this.inlineRow.tabularFormset("table.inline tr.form-row", {
+ prefix: "first",
+ addText: this.addText,
+ deleteText: "Remove",
});
- }
+ },
});
-QUnit.test('no forms', function(assert) {
- assert.ok(this.inlineRow.hasClass('dynamic-first'));
- assert.equal(this.table.find('.add-row a').text(), this.addText);
+QUnit.test("no forms", function (assert) {
+ assert.ok(this.inlineRow.hasClass("dynamic-first"));
+ assert.equal(this.table.find(".add-row a").text(), this.addText);
});
-QUnit.test('add form', function(assert) {
- const addButton = this.table.find('.add-row a');
+QUnit.test("add form", function (assert) {
+ const addButton = this.table.find(".add-row a");
assert.equal(addButton.text(), this.addText);
addButton.click();
- assert.ok(this.table.find('#first-1'));
+ assert.ok(this.table.find("#first-1"));
});
-QUnit.test('added form has remove button', function(assert) {
- const addButton = this.table.find('.add-row a');
+QUnit.test("added form has remove button", function (assert) {
+ const addButton = this.table.find(".add-row a");
assert.equal(addButton.text(), this.addText);
addButton.click();
- assert.equal(this.table.find('#first-1 .inline-deletelink').length, 1);
+ assert.equal(this.table.find("#first-1 .inline-deletelink").length, 1);
});
-QUnit.test('add/remove form events', function(assert) {
+QUnit.test("add/remove form events", function (assert) {
assert.expect(5);
- const addButton = this.table.find('.add-row a');
- document.addEventListener('formset:added', (event) => {
- assert.ok(true, 'event `formset:added` triggered');
- assert.equal(true, event.target.matches('#first-1'));
- assert.equal(event.detail.formsetName, 'first');
- }, {once: true});
+ const addButton = this.table.find(".add-row a");
+ document.addEventListener(
+ "formset:added",
+ (event) => {
+ assert.ok(true, "event `formset:added` triggered");
+ assert.equal(true, event.target.matches("#first-1"));
+ assert.equal(event.detail.formsetName, "first");
+ },
+ { once: true },
+ );
addButton.click();
- const deleteLink = this.table.find('.inline-deletelink');
- document.addEventListener('formset:removed', (event) => {
- assert.ok(true, 'event `formset:removed` triggered');
- assert.equal(event.detail.formsetName, 'first');
- }, {once: true});
+ const deleteLink = this.table.find(".inline-deletelink");
+ document.addEventListener(
+ "formset:removed",
+ (event) => {
+ assert.ok(true, "event `formset:removed` triggered");
+ assert.equal(event.detail.formsetName, "first");
+ },
+ { once: true },
+ );
deleteLink.click();
});
-QUnit.test('existing add button', function(assert) {
+QUnit.test("existing add button", function (assert) {
const $ = django.jQuery;
- $('#qunit-fixture').empty(); // Clear the table added in beforeEach
- $('#qunit-fixture').append($('#tabular-formset').text());
- this.table = $('table.inline');
- this.inlineRow = this.table.find('tr');
+ $("#qunit-fixture").empty(); // Clear the table added in beforeEach
+ $("#qunit-fixture").append($("#tabular-formset").text());
+ this.table = $("table.inline");
+ this.inlineRow = this.table.find("tr");
this.table.append(' ');
- const addButton = this.table.find('.add-button');
- this.inlineRow.tabularFormset('table.inline tr', {
- prefix: 'first',
- deleteText: 'Remove',
- addButton: addButton
+ const addButton = this.table.find(".add-button");
+ this.inlineRow.tabularFormset("table.inline tr", {
+ prefix: "first",
+ deleteText: "Remove",
+ addButton: addButton,
});
- assert.equal(this.table.find('.add-row a').length, 0);
+ assert.equal(this.table.find(".add-row a").length, 0);
addButton.click();
- assert.ok(this.table.find('#first-1'));
+ assert.ok(this.table.find("#first-1"));
});
-
-QUnit.module('admin.inlines: tabular formsets with validation errors', {
- beforeEach: function() {
+QUnit.module("admin.inlines: tabular formsets with validation errors", {
+ beforeEach: function () {
const $ = django.jQuery;
- $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
- this.table = $('table.inline');
- this.inlineRows = this.table.find('tr.form-row');
- this.inlineRows.tabularFormset('table.inline tr.form-row', {
- prefix: 'second'
+ $("#qunit-fixture").append(
+ $("#tabular-formset-with-validation-error").text(),
+ );
+ this.table = $("table.inline");
+ this.inlineRows = this.table.find("tr.form-row");
+ this.inlineRows.tabularFormset("table.inline tr.form-row", {
+ prefix: "second",
});
- }
+ },
});
-QUnit.test('first form has delete checkbox and no button', function(assert) {
+QUnit.test("first form has delete checkbox and no button", function (assert) {
const tr = this.inlineRows.slice(0, 1);
- assert.ok(tr.hasClass('dynamic-second'));
- assert.ok(tr.hasClass('has_original'));
- assert.equal(tr.find('td.delete input').length, 1);
- assert.equal(tr.find('td.delete .inline-deletelink').length, 0);
+ assert.ok(tr.hasClass("dynamic-second"));
+ assert.ok(tr.hasClass("has_original"));
+ assert.equal(tr.find("td.delete input").length, 1);
+ assert.equal(tr.find("td.delete .inline-deletelink").length, 0);
});
-QUnit.test('dynamic form has remove button', function(assert) {
+QUnit.test("dynamic form has remove button", function (assert) {
const tr = this.inlineRows.slice(1, 2);
- assert.ok(tr.hasClass('dynamic-second'));
- assert.notOk(tr.hasClass('has_original'));
- assert.equal(tr.find('.inline-deletelink').length, 1);
+ assert.ok(tr.hasClass("dynamic-second"));
+ assert.notOk(tr.hasClass("has_original"));
+ assert.equal(tr.find(".inline-deletelink").length, 1);
});
-QUnit.test('dynamic template has nothing', function(assert) {
+QUnit.test("dynamic template has nothing", function (assert) {
const tr = this.inlineRows.slice(2, 3);
- assert.ok(tr.hasClass('empty-form'));
- assert.notOk(tr.hasClass('dynamic-second'));
- assert.notOk(tr.hasClass('has_original'));
- assert.equal(tr.find('td.delete')[0].innerHTML, '');
+ assert.ok(tr.hasClass("empty-form"));
+ assert.notOk(tr.hasClass("dynamic-second"));
+ assert.notOk(tr.hasClass("has_original"));
+ assert.equal(tr.find("td.delete")[0].innerHTML, "");
});
-QUnit.test('removing a form-row also removed related row with non-field errors', function(assert) {
- const $ = django.jQuery;
- assert.ok(this.table.find('.row-form-errors').length);
- const tr = this.inlineRows.slice(1, 2);
- const trWithErrors = tr.prev();
- assert.ok(trWithErrors.hasClass('row-form-errors'));
- const deleteLink = tr.find('a.inline-deletelink');
- deleteLink.trigger($.Event('click', {target: deleteLink}));
- assert.notOk(this.table.find('.row-form-errors').length);
-});
-
-QUnit.module('admin.inlines: tabular formsets with max_num', {
- beforeEach: function() {
+QUnit.test(
+ "removing a form-row also removed related row with non-field errors",
+ function (assert) {
+ const $ = django.jQuery;
+ assert.ok(this.table.find(".row-form-errors").length);
+ const tr = this.inlineRows.slice(1, 2);
+ const trWithErrors = tr.prev();
+ assert.ok(trWithErrors.hasClass("row-form-errors"));
+ const deleteLink = tr.find("a.inline-deletelink");
+ deleteLink.trigger($.Event("click", { target: deleteLink }));
+ assert.notOk(this.table.find(".row-form-errors").length);
+ },
+);
+
+QUnit.module("admin.inlines: tabular formsets with max_num", {
+ beforeEach: function () {
const $ = django.jQuery;
- $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
- this.table = $('table.inline');
- this.maxNum = $('input.id_second-MAX_NUM_FORMS');
+ $("#qunit-fixture").append(
+ $("#tabular-formset-with-validation-error").text(),
+ );
+ this.table = $("table.inline");
+ this.maxNum = $("input.id_second-MAX_NUM_FORMS");
this.maxNum.val(2);
- this.inlineRows = this.table.find('tr.form-row');
- this.inlineRows.tabularFormset('table.inline tr.form-row', {
- prefix: 'second'
+ this.inlineRows = this.table.find("tr.form-row");
+ this.inlineRows.tabularFormset("table.inline tr.form-row", {
+ prefix: "second",
});
- }
+ },
});
-QUnit.test('does not show the add button if already at max_num', function(assert) {
- const addButton = this.table.find('tr.add_row > td > a');
- assert.notOk(addButton.is(':visible'));
-});
+QUnit.test(
+ "does not show the add button if already at max_num",
+ function (assert) {
+ const addButton = this.table.find("tr.add_row > td > a");
+ assert.notOk(addButton.is(":visible"));
+ },
+);
-QUnit.test('make addButton visible again', function(assert) {
+QUnit.test("make addButton visible again", function (assert) {
const $ = django.jQuery;
- const addButton = this.table.find('tr.add_row > td > a');
- const removeButton = this.table.find('tr.form-row:first').find('a.inline-deletelink');
- removeButton.trigger($.Event( "click", { target: removeButton } ));
- assert.notOk(addButton.is(':visible'));
+ const addButton = this.table.find("tr.add_row > td > a");
+ const removeButton = this.table
+ .find("tr.form-row:first")
+ .find("a.inline-deletelink");
+ removeButton.trigger($.Event("click", { target: removeButton }));
+ assert.notOk(addButton.is(":visible"));
});
-
-QUnit.module('admin.inlines: tabular formsets with min_num', {
- beforeEach: function() {
+QUnit.module("admin.inlines: tabular formsets with min_num", {
+ beforeEach: function () {
const $ = django.jQuery;
- $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
- this.table = $('table.inline');
- this.minNum = $('input#id_second-MIN_NUM_FORMS');
+ $("#qunit-fixture").append(
+ $("#tabular-formset-with-validation-error").text(),
+ );
+ this.table = $("table.inline");
+ this.minNum = $("input#id_second-MIN_NUM_FORMS");
this.minNum.val(2);
- this.inlineRows = this.table.find('tr.form-row');
- this.inlineRows.tabularFormset('table.inline tr.form-row', {
- prefix: 'second'
+ this.inlineRows = this.table.find("tr.form-row");
+ this.inlineRows.tabularFormset("table.inline tr.form-row", {
+ prefix: "second",
});
- }
+ },
});
-QUnit.test('does not show the remove buttons if already at min_num', function(assert) {
- assert.notOk(this.table.find('.inline-deletelink:visible').length);
-});
+QUnit.test(
+ "does not show the remove buttons if already at min_num",
+ function (assert) {
+ assert.notOk(this.table.find(".inline-deletelink:visible").length);
+ },
+);
-QUnit.test('make removeButtons visible again', function(assert) {
+QUnit.test("make removeButtons visible again", function (assert) {
const $ = django.jQuery;
- const addButton = this.table.find('tr.add-row > td > a');
- addButton.trigger($.Event( "click", { target: addButton } ));
- assert.equal(this.table.find('.inline-deletelink:visible').length, 2);
+ const addButton = this.table.find("tr.add-row > td > a");
+ addButton.trigger($.Event("click", { target: addButton }));
+ assert.equal(this.table.find(".inline-deletelink:visible").length, 2);
});
diff --git a/js_tests/admin/jsi18n-mocks.test.js b/js_tests/admin/jsi18n-mocks.test.js
index 6609c28e4397..058bb3df2542 100644
--- a/js_tests/admin/jsi18n-mocks.test.js
+++ b/js_tests/admin/jsi18n-mocks.test.js
@@ -1,29 +1,36 @@
-'use strict';
+"use strict";
{
- const globals = this;
- const django = globals.django;
+ const django = this.django;
- django.pluralidx = function(count) { return (count === 1) ? 0 : 1; };
+ django.pluralidx = function (count) {
+ return count === 1 ? 0 : 1;
+ };
/* gettext identity library */
- django.gettext = function(msgid) { return msgid; };
- django.ngettext = function(singular, plural, count) {
- return (count === 1) ? singular : plural;
+ django.gettext = function (msgid) {
+ return msgid;
+ };
+ django.ngettext = function (singular, plural, count) {
+ return count === 1 ? singular : plural;
+ };
+ django.gettext_noop = function (msgid) {
+ return msgid;
+ };
+ django.pgettext = function (context, msgid) {
+ return msgid;
};
- django.gettext_noop = function(msgid) { return msgid; };
- django.pgettext = function(context, msgid) { return msgid; };
- django.npgettext = function(context, singular, plural, count) {
- return (count === 1) ? singular : plural;
+ django.npgettext = function (context, singular, plural, count) {
+ return count === 1 ? singular : plural;
};
- django.interpolate = function(fmt, obj, named) {
+ django.interpolate = function (fmt, obj, named) {
if (named) {
- return fmt.replace(/%\(\w+\)s/g, function(match) {
+ return fmt.replace(/%\(\w+\)s/g, function (match) {
return String(obj[match.slice(2, -2)]);
});
} else {
- return fmt.replace(/%s/g, function(match) {
+ return fmt.replace(/%s/g, function (match) {
return String(obj.shift());
});
}
@@ -32,8 +39,8 @@
/* formatting library */
django.formats = {
- "DATETIME_FORMAT": "N j, Y, P",
- "DATETIME_INPUT_FORMATS": [
+ DATETIME_FORMAT: "N j, Y, P",
+ DATETIME_INPUT_FORMATS: [
"%Y-%m-%d %H:%M:%S",
"%Y-%m-%d %H:%M:%S.%f",
"%Y-%m-%d %H:%M",
@@ -45,33 +52,25 @@
"%m/%d/%y %H:%M:%S",
"%m/%d/%y %H:%M:%S.%f",
"%m/%d/%y %H:%M",
- "%m/%d/%y"
- ],
- "DATE_FORMAT": "N j, Y",
- "DATE_INPUT_FORMATS": [
- "%Y-%m-%d",
- "%m/%d/%Y",
- "%m/%d/%y"
- ],
- "DECIMAL_SEPARATOR": ".",
- "FIRST_DAY_OF_WEEK": 0,
- "MONTH_DAY_FORMAT": "F j",
- "NUMBER_GROUPING": 3,
- "SHORT_DATETIME_FORMAT": "m/d/Y P",
- "SHORT_DATE_FORMAT": "m/d/Y",
- "THOUSAND_SEPARATOR": ",",
- "TIME_FORMAT": "P",
- "TIME_INPUT_FORMATS": [
- "%H:%M:%S",
- "%H:%M:%S.%f",
- "%H:%M"
+ "%m/%d/%y",
],
- "YEAR_MONTH_FORMAT": "F Y"
+ DATE_FORMAT: "N j, Y",
+ DATE_INPUT_FORMATS: ["%Y-%m-%d", "%m/%d/%Y", "%m/%d/%y"],
+ DECIMAL_SEPARATOR: ".",
+ FIRST_DAY_OF_WEEK: 0,
+ MONTH_DAY_FORMAT: "F j",
+ NUMBER_GROUPING: 3,
+ SHORT_DATETIME_FORMAT: "m/d/Y P",
+ SHORT_DATE_FORMAT: "m/d/Y",
+ THOUSAND_SEPARATOR: ",",
+ TIME_FORMAT: "P",
+ TIME_INPUT_FORMATS: ["%H:%M:%S", "%H:%M:%S.%f", "%H:%M"],
+ YEAR_MONTH_FORMAT: "F Y",
};
- django.get_format = function(format_type) {
+ django.get_format = function (format_type) {
const value = django.formats[format_type];
- if (typeof value === 'undefined') {
+ if (typeof value === "undefined") {
return format_type;
} else {
return value;
@@ -79,12 +78,12 @@
};
/* add to global namespace */
- globals.pluralidx = django.pluralidx;
- globals.gettext = django.gettext;
- globals.ngettext = django.ngettext;
- globals.gettext_noop = django.gettext_noop;
- globals.pgettext = django.pgettext;
- globals.npgettext = django.npgettext;
- globals.interpolate = django.interpolate;
- globals.get_format = django.get_format;
-};
+ this.pluralidx = django.pluralidx;
+ this.gettext = django.gettext;
+ this.ngettext = django.ngettext;
+ this.gettext_noop = django.gettext_noop;
+ this.pgettext = django.pgettext;
+ this.npgettext = django.npgettext;
+ this.interpolate = django.interpolate;
+ this.get_format = django.get_format;
+}
diff --git a/js_tests/admin/navigation.test.js b/js_tests/admin/navigation.test.js
index 0da50e757c42..a53dd7974790 100644
--- a/js_tests/admin/navigation.test.js
+++ b/js_tests/admin/navigation.test.js
@@ -1,24 +1,24 @@
/* global QUnit, initSidebarQuickFilter */
-'use strict';
+"use strict";
-QUnit.module('admin.sidebar: filter', {
- beforeEach: function() {
+QUnit.module("admin.sidebar: filter", {
+ beforeEach: function () {
const $ = django.jQuery;
- $('#qunit-fixture').append($('#nav-sidebar-filter').text());
- this.navSidebar = $('#nav-sidebar');
- this.navFilter = $('#nav-filter');
+ $("#qunit-fixture").append($("#nav-sidebar-filter").text());
+ this.navSidebar = $("#nav-sidebar");
+ this.navFilter = $("#nav-filter");
initSidebarQuickFilter();
- }
+ },
});
-QUnit.test('filter by a model name', function(assert) {
- assert.equal(this.navSidebar.find('th[scope=row] a').length, 2);
+QUnit.test("filter by a model name", function (assert) {
+ assert.equal(this.navSidebar.find("th[scope=row] a").length, 2);
- this.navFilter.val('us'); // Matches 'users'.
- this.navFilter[0].dispatchEvent(new Event('change'));
+ this.navFilter.val("us"); // Matches 'users'.
+ this.navFilter[0].dispatchEvent(new Event("change"));
assert.equal(this.navSidebar.find('tr[class^="model-"]:visible').length, 1);
- this.navFilter.val('nonexistent');
- this.navFilter[0].dispatchEvent(new Event('change'));
+ this.navFilter.val("nonexistent");
+ this.navFilter[0].dispatchEvent(new Event("change"));
assert.equal(this.navSidebar.find('tr[class^="model-"]:visible').length, 0);
});
diff --git a/js_tests/gis/mapwidget.test.js b/js_tests/gis/mapwidget.test.js
index 4f2f3bb91c87..838cf22219a2 100644
--- a/js_tests/gis/mapwidget.test.js
+++ b/js_tests/gis/mapwidget.test.js
@@ -1,157 +1,232 @@
/* global QUnit, MapWidget, ol */
-'use strict';
+"use strict";
-QUnit.module('gis.OLMapWidget');
+QUnit.module("gis.OLMapWidget");
-QUnit.test('MapWidget.featureAdded', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.featureAdded", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
const widget = new MapWidget(options);
assert.equal(widget.featureCollection.getLength(), 1);
widget.serializeFeatures();
assert.equal(
- document.getElementById('id_point').value,
+ document.getElementById("id_point").value,
'{"type":"Point","coordinates":[7.8177,47.397]}',
- 'Point added to vector layer'
+ "Point added to vector layer",
);
});
-QUnit.test('MapWidget.map_srid', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.map_srid", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
const widget = new MapWidget(options);
- assert.equal(widget.map.getView().getProjection().getCode(), 'EPSG:3857', 'SRID 3857');
+ assert.equal(
+ widget.map.getView().getProjection().getCode(),
+ "EPSG:3857",
+ "SRID 3857",
+ );
});
-QUnit.test('MapWidget.defaultCenter', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.defaultCenter", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
let widget = new MapWidget(options);
- assert.equal(widget.defaultCenter().toString(), '0,0', 'Default center at 0, 0');
+ assert.equal(
+ widget.defaultCenter().toString(),
+ "0,0",
+ "Default center at 0, 0",
+ );
options.default_lat = 47.08;
options.default_lon = 6.81;
widget = new MapWidget(options);
assert.equal(
widget.defaultCenter().toString(),
- '6.81,47.08',
- 'Default center at 6.81, 47.08'
+ "6.81,47.08",
+ "Default center at 6.81, 47.08",
);
assert.equal(Math.round(widget.map.getView().getZoom()), 17);
});
-QUnit.test('MapWidget.interactions', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.interactions", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
const widget = new MapWidget(options);
assert.equal(Object.keys(widget.interactions).length, 2);
- assert.equal(widget.interactions.draw.getActive(), false, "Draw is inactive with an existing point");
- assert.equal(widget.interactions.modify.getActive(), true, "Modify is active with an existing point");
+ assert.equal(
+ widget.interactions.draw.getActive(),
+ false,
+ "Draw is inactive with an existing point",
+ );
+ assert.equal(
+ widget.interactions.modify.getActive(),
+ true,
+ "Modify is active with an existing point",
+ );
});
-QUnit.test('MapWidget.clearFeatures', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.clearFeatures", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
const widget = new MapWidget(options);
- const initial_value = document.getElementById('id_point').value;
+ const initial_value = document.getElementById("id_point").value;
widget.clearFeatures();
- assert.equal(document.getElementById('id_point').value, "");
- document.getElementById('id_point').value = initial_value;
+ assert.equal(document.getElementById("id_point").value, "");
+ document.getElementById("id_point").value = initial_value;
});
-QUnit.test('MapWidget.multipolygon', function(assert) {
- const options = {id: 'id_multipolygon', map_id: 'id_multipolygon_map', geom_name: 'MultiPolygon'};
+QUnit.test("MapWidget.multipolygon", function (assert) {
+ const options = {
+ id: "id_multipolygon",
+ map_id: "id_multipolygon_map",
+ geom_name: "MultiPolygon",
+ };
const widget = new MapWidget(options);
assert.ok(widget.options.is_collection);
- assert.equal(widget.interactions.draw.getActive(), true, "Draw is active with no existing content");
+ assert.equal(
+ widget.interactions.draw.getActive(),
+ true,
+ "Draw is active with no existing content",
+ );
});
-QUnit.test('MapWidget.IsCollection', function(assert) {
- const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
+QUnit.test("MapWidget.IsCollection", function (assert) {
+ const options = {
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ };
let widget = new MapWidget(options);
assert.notOk(widget.options.is_collection);
// Empty the default initial Point
- document.getElementById('id_point').value = "";
+ document.getElementById("id_point").value = "";
- options.geom_name = 'Polygon';
+ options.geom_name = "Polygon";
widget = new MapWidget(options);
assert.notOk(widget.options.is_collection);
- options.geom_name = 'LineString';
+ options.geom_name = "LineString";
widget = new MapWidget(options);
assert.notOk(widget.options.is_collection);
- options.geom_name = 'MultiPoint';
+ options.geom_name = "MultiPoint";
widget = new MapWidget(options);
assert.ok(widget.options.is_collection);
- options.geom_name = 'MultiPolygon';
+ options.geom_name = "MultiPolygon";
widget = new MapWidget(options);
assert.ok(widget.options.is_collection);
- options.geom_name = 'MultiLineString';
+ options.geom_name = "MultiLineString";
widget = new MapWidget(options);
assert.ok(widget.options.is_collection);
- options.geom_name = 'GeometryCollection';
+ options.geom_name = "GeometryCollection";
widget = new MapWidget(options);
assert.ok(widget.options.is_collection);
});
-QUnit.test('MapWidget.layerBuilder.osm returns OSM layer', function(assert) {
+QUnit.test("MapWidget.layerBuilder.osm returns OSM layer", function (assert) {
const layer = MapWidget.layerBuilder.osm();
- assert.ok(layer instanceof ol.layer.Tile, 'Layer is Tile');
- assert.ok(layer.getSource() instanceof ol.source.OSM, 'Source is OSM');
+ assert.ok(layer instanceof ol.layer.Tile, "Layer is Tile");
+ assert.ok(layer.getSource() instanceof ol.source.OSM, "Source is OSM");
});
-QUnit.test('MapWidget.layerBuilder.nasaWorldview returns XYZ layer', function(assert) {
- const layer = MapWidget.layerBuilder.nasaWorldview();
- assert.ok(layer instanceof ol.layer.Tile, 'Layer is Tile');
- assert.ok(layer.getSource() instanceof ol.source.XYZ, 'Source is XYZ');
- assert.ok(layer.getSource().getUrls()[0].includes('earthdata.nasa.gov'), 'URL is NASA-hosted');
-});
+QUnit.test(
+ "MapWidget.layerBuilder.nasaWorldview returns XYZ layer",
+ function (assert) {
+ const layer = MapWidget.layerBuilder.nasaWorldview();
+ assert.ok(layer instanceof ol.layer.Tile, "Layer is Tile");
+ assert.ok(layer.getSource() instanceof ol.source.XYZ, "Source is XYZ");
+ assert.ok(
+ layer.getSource().getUrls()[0].includes("earthdata.nasa.gov"),
+ "URL is NASA-hosted",
+ );
+ },
+);
-QUnit.test('MapWidget uses default OSM base layer when none specified', function(assert) {
- const widget = new MapWidget({
- id: 'id_point',
- map_id: 'id_point_map',
- geom_name: 'Point'
- });
- assert.ok(widget.baseLayer.getSource() instanceof ol.source.OSM, 'Default base layer is OSM');
-});
+QUnit.test(
+ "MapWidget uses default OSM base layer when none specified",
+ function (assert) {
+ const widget = new MapWidget({
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ });
+ assert.ok(
+ widget.baseLayer.getSource() instanceof ol.source.OSM,
+ "Default base layer is OSM",
+ );
+ },
+);
-QUnit.test('MapWidget uses named base layer from layerBuilder', function(assert) {
- const widget = new MapWidget({
- id: 'id_point',
- map_id: 'id_point_map',
- geom_name: 'Point',
- base_layer: 'nasaWorldview'
- });
- assert.ok(widget.baseLayer.getSource() instanceof ol.source.XYZ, 'Uses named base layer from builder');
-});
+QUnit.test(
+ "MapWidget uses named base layer from layerBuilder",
+ function (assert) {
+ const widget = new MapWidget({
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ base_layer: "nasaWorldview",
+ });
+ assert.ok(
+ widget.baseLayer.getSource() instanceof ol.source.XYZ,
+ "Uses named base layer from builder",
+ );
+ },
+);
-QUnit.test('MapWidget uses passed-in base layer object directly', function(assert) {
- const customLayer = new ol.layer.Tile({source: new ol.source.OSM()});
- const widget = new MapWidget({
- id: 'id_point',
- map_id: 'id_point_map',
- geom_name: 'Point',
- base_layer: customLayer
- });
- assert.strictEqual(widget.baseLayer, customLayer, 'Uses provided layer object');
-});
+QUnit.test(
+ "MapWidget uses passed-in base layer object directly",
+ function (assert) {
+ const customLayer = new ol.layer.Tile({ source: new ol.source.OSM() });
+ const widget = new MapWidget({
+ id: "id_point",
+ map_id: "id_point_map",
+ geom_name: "Point",
+ base_layer: customLayer,
+ });
+ assert.strictEqual(
+ widget.baseLayer,
+ customLayer,
+ "Uses provided layer object",
+ );
+ },
+);
-QUnit.test('initMapWidgetInSection initializes widgets and skips __prefix__', function(assert) {
- const wrapper1 = document.createElement('div');
- wrapper1.className = 'dj_map_wrapper';
- wrapper1.id = 'id_point_map_wrapper';
- wrapper1.innerHTML = `
+QUnit.test(
+ "initMapWidgetInSection initializes widgets and skips __prefix__",
+ function (assert) {
+ const wrapper1 = document.createElement("div");
+ wrapper1.className = "dj_map_wrapper";
+ wrapper1.id = "id_point_map_wrapper";
+ wrapper1.innerHTML = `
`;
- document.body.appendChild(wrapper1);
+ document.body.appendChild(wrapper1);
- const wrapper2 = document.createElement('div');
- wrapper2.className = 'dj_map_wrapper';
- wrapper2.id = 'form-__prefix__-map_wrapper';
- wrapper2.innerHTML = `
+ const wrapper2 = document.createElement("div");
+ wrapper2.className = "dj_map_wrapper";
+ wrapper2.id = "form-__prefix__-map_wrapper";
+ wrapper2.innerHTML = `
`;
- document.body.appendChild(wrapper2);
+ document.body.appendChild(wrapper2);
- const maps = window.initMapWidgetInSection(document);
+ const maps = window.initMapWidgetInSection(document);
- assert.equal(maps.length, 1, 'Only one map widget is initialized');
- assert.ok(maps[0] instanceof MapWidget, 'Map is instance of MapWidget');
- assert.equal(maps[0].options.id, 'id_point', 'Correct widget was initialized');
- assert.equal(maps[0].options.map_id, 'id_point_map', 'Map ID is correct');
+ assert.equal(maps.length, 1, "Only one map widget is initialized");
+ assert.ok(maps[0] instanceof MapWidget, "Map is instance of MapWidget");
+ assert.equal(
+ maps[0].options.id,
+ "id_point",
+ "Correct widget was initialized",
+ );
+ assert.equal(
+ maps[0].options.map_id,
+ "id_point_map",
+ "Map ID is correct",
+ );
- // Clean up
- wrapper1.remove();
- wrapper2.remove();
-});
+ // Clean up
+ wrapper1.remove();
+ wrapper2.remove();
+ },
+);
diff --git a/package.json b/package.json
index e1d22cda119f..212aab0b192b 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,6 @@
"name": "Django",
"private": true,
"scripts": {
- "pretest": "eslint .",
"test": "grunt test --verbose",
"biome": "biome check"
},
@@ -11,7 +10,6 @@
},
"devDependencies": {
"@biomejs/biome": "^2.4.12",
- "eslint": "^9.39.1",
"puppeteer": "^24.22.0",
"grunt": "^1.6.1",
"grunt-cli": "^1.5.0",
diff --git a/scripts/pr_quality/check_pr.py b/scripts/pr_quality/check_pr.py
index 054d3e6adf50..51d106e87537 100644
--- a/scripts/pr_quality/check_pr.py
+++ b/scripts/pr_quality/check_pr.py
@@ -57,6 +57,8 @@
PR_TEMPLATE_DATE = date(2024, 3, 4) # 3fcef50 -- PR template introduced
AI_DISCLOSURE_DATE = date(2026, 1, 8) # 4f580c4 -- AI disclosure added
+ALLOWED_STAGES = ("Accepted", "Ready for checkin")
+
logger = logging.getLogger(__name__)
@@ -215,7 +217,8 @@ def check_trac_ticket(pr_body, total_changes, threshold=LARGE_PR_THRESHOLD):
def check_trac_status(ticket_id, ticket_data):
- """The referenced Trac ticket must be Accepted, unresolved, and assigned.
+ """The referenced Trac ticket must be Accepted or Ready for checkin,
+ unresolved, and assigned.
ticket_data is the dict returned by fetch_trac_ticket(). Passing None
skips the check (non-fatal fetch error). Passing TICKET_NOT_FOUND fails
@@ -232,10 +235,10 @@ def check_trac_status(ticket_id, ticket_data):
stage = ticket_data.get("custom", {}).get("stage", "").strip()
resolution = (ticket_data.get("resolution") or "").strip()
status = ticket_data.get("status", "").strip()
- if stage == "Accepted" and not resolution and status == "assigned":
+ if stage in ALLOWED_STAGES and not resolution and status == "assigned":
return None
current_state = [
- f"{stage=}" if stage != "Accepted" else "",
+ f"{stage=}" if stage not in ALLOWED_STAGES else "",
f"{resolution=}" if resolution else "",
f"{status=}" if status != "assigned" else "",
]
@@ -480,7 +483,7 @@ def main(
results = [
("Trac ticket referenced", ticket_result, LEVEL_ERROR),
- ("Trac ticket status is Accepted", ticket_status_result, LEVEL_ERROR),
+ ("Trac ticket is ready for work", ticket_status_result, LEVEL_ERROR),
("Trac ticket has_patch flag set", ticket_has_patch_result, LEVEL_WARNING),
("PR title includes ticket number", pr_title_result, LEVEL_WARNING),
("Branch description provided", check_branch_description(pr_body), LEVEL_ERROR),
diff --git a/scripts/pr_quality/errors.py b/scripts/pr_quality/errors.py
index 8b98873f6dd6..cd305868ac37 100644
--- a/scripts/pr_quality/errors.py
+++ b/scripts/pr_quality/errors.py
@@ -56,18 +56,17 @@ def as_details(self, level=LEVEL_ERROR):
INVALID_TRAC_STATUS = (
"Trac Ticket Not Ready for a Pull Request",
"The referenced ticket **ticket-{ticket_id}** is not ready for a pull request. "
- "A ticket must be in the *Accepted* stage, *assigned* status, and have no "
- "resolution.\n\n"
+ "A ticket must be in the *Accepted* or *Ready for checkin* stage, "
+ "*assigned* status, and have no resolution.\n\n"
"**Current state:** {current_state}\n\n"
"**What to do:**\n\n"
f"1. Check the ticket at {TRAC_URL}/ticket/{{ticket_id}}.\n"
"2. If *Unreviewed*, wait for a community member to accept it. "
"A ticket cannot be accepted by its reporter.\n"
- "3. If *Ready for Checkin*, there is already a solution for it.\n"
- "4. If *Someday/Maybe*, discuss on the "
+ "3. If *Someday/Maybe*, discuss on the "
f"[Django Forum]({FORUM_URL}/c/internals/5) before proceeding.\n"
- "5. If resolved or closed, it is not eligible for a PR.\n"
- "6. If not *assigned*, claim it by setting yourself as the owner.\n\n"
+ "4. If resolved or closed, it is not eligible for a PR.\n"
+ "5. If not *assigned*, claim it by setting yourself as the owner.\n\n"
f"For more information on the Django triage process see {TRIAGING_URL}.",
)
diff --git a/scripts/pr_quality/tests/test_check_pr.py b/scripts/pr_quality/tests/test_check_pr.py
index f238ebb0c6f5..c7565df5ab5c 100644
--- a/scripts/pr_quality/tests/test_check_pr.py
+++ b/scripts/pr_quality/tests/test_check_pr.py
@@ -318,27 +318,34 @@ def test_accepted_assigned_unresolved_passes(self):
data = make_trac_json(stage="Accepted", status="assigned", resolution=None)
self.assertIsNone(check_pr.check_trac_status("36991", data))
+ def test_ready_for_checkin_assigned_unresolved_passes(self):
+ data = make_trac_json(
+ stage="Ready for checkin", status="assigned", resolution=None
+ )
+ self.assertIsNone(check_pr.check_trac_status("36991", data))
+
def test_non_accepted_stage_fails(self):
- for stage in ["Unreviewed", "Ready for Checkin", "Someday/Maybe"]:
+ for stage in ["Unreviewed", "Someday/Maybe"]:
with self.subTest(stage=stage):
data = make_trac_json(stage=stage)
self.assertIsNotNone(check_pr.check_trac_status("36991", data))
def test_resolved_ticket_fails(self):
- for resolution in [
- "fixed",
- "wontfix",
- "duplicate",
- "invalid",
- "worksforme",
- "needsinfo",
- "needsnewfeatureprocess",
- ]:
- with self.subTest(resolution=resolution):
- data = make_trac_json(
- stage="Accepted", status="assigned", resolution=resolution
- )
- self.assertIsNotNone(check_pr.check_trac_status("36991", data))
+ for stage in ("Accepted", "Ready for checkin"):
+ for resolution in [
+ "fixed",
+ "wontfix",
+ "duplicate",
+ "invalid",
+ "worksforme",
+ "needsinfo",
+ "needsnewfeatureprocess",
+ ]:
+ with self.subTest(stage=stage, resolution=resolution):
+ data = make_trac_json(
+ stage=stage, status="assigned", resolution=resolution
+ )
+ self.assertIsNotNone(check_pr.check_trac_status("36991", data))
def test_unassigned_ticket_fails(self):
for status in ["new", "closed", ""]:
@@ -743,7 +750,7 @@ def test_no_ticket_results_include_skipped_sentinels(self):
_, mock_summary, _ = self.call_main(pr_body=body)
_, results, _ = mock_summary.call_args.args
result_map = {name: result for name, result, _ in results}
- self.assertIs(result_map["Trac ticket status is Accepted"], check_pr.SKIPPED)
+ self.assertIs(result_map["Trac ticket is ready for work"], check_pr.SKIPPED)
self.assertIs(result_map["Trac ticket has_patch flag set"], check_pr.SKIPPED)
self.assertIs(result_map["PR title includes ticket number"], check_pr.SKIPPED)
@@ -754,7 +761,7 @@ def test_non_accepted_ticket_skips_has_patch(self):
)
_, results, _ = mock_summary.call_args.args
result_map = {name: result for name, result, _ in results}
- self.assertIsNotNone(result_map["Trac ticket status is Accepted"])
+ self.assertIsNotNone(result_map["Trac ticket is ready for work"])
self.assertIs(result_map["Trac ticket has_patch flag set"], check_pr.SKIPPED)
def test_established_author_skips_all_checks(self):
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py
index 33763d589bdf..f2ed13420f64 100644
--- a/tests/aggregation_regress/tests.py
+++ b/tests/aggregation_regress/tests.py
@@ -188,6 +188,14 @@ def test_count_preserve_group_by(self):
)
self.assertEqual(qs.order_by("id").count(), len(qs.order_by("id")))
self.assertEqual(qs.extra(order_by=["id"]).count(), len(qs.order_by("id")))
+ self.assertEqual(qs.order_by("-id").count(), len(qs.order_by("-id")))
+ self.assertEqual(
+ qs.order_by("-publications").count(), len(qs.order_by("-publications"))
+ )
+ self.assertEqual(
+ qs.order_by("-contact__name").count(), len(qs.order_by("-contact__name"))
+ )
+ self.assertEqual(qs.order_by("?").count(), len(qs.order_by("?")))
def test_annotation_with_value(self):
values = (