From fbb4f0797cc44fe2dedda38d1c681fe09473859e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 20 Jul 2015 19:35:17 -0400 Subject: [PATCH] Fixed JavaScript "strict" violations. --- .../admin/static/admin/js/SelectBox.js | 222 +++--- .../admin/static/admin/js/SelectFilter2.js | 1 + .../contrib/admin/static/admin/js/actions.js | 1 + .../admin/js/admin/DateTimeShortcuts.js | 677 +++++++++--------- .../admin/js/admin/RelatedObjectLookups.js | 262 +++---- .../contrib/admin/static/admin/js/calendar.js | 316 ++++---- .../contrib/admin/static/admin/js/collapse.js | 1 + django/contrib/admin/static/admin/js/core.js | 212 +++--- .../contrib/admin/static/admin/js/inlines.js | 1 + .../admin/static/admin/js/prepopulate.js | 1 + .../admin/static/admin/js/timeparse.js | 171 ++--- .../contrib/admin/static/admin/js/urlify.js | 314 ++++---- .../contrib/gis/static/gis/js/OLMapWidget.js | 1 + 13 files changed, 1118 insertions(+), 1062 deletions(-) diff --git a/django/contrib/admin/static/admin/js/SelectBox.js b/django/contrib/admin/static/admin/js/SelectBox.js index be97864984..e5278c78fe 100644 --- a/django/contrib/admin/static/admin/js/SelectBox.js +++ b/django/contrib/admin/static/admin/js/SelectBox.js @@ -1,117 +1,121 @@ /*eslint no-cond-assign:1*/ -var SelectBox = { - cache: {}, - init: function(id) { - var box = document.getElementById(id); - var node; - SelectBox.cache[id] = []; - var cache = SelectBox.cache[id]; - for (var i = 0; (node = box.options[i]); i++) { - cache.push({value: node.value, text: node.text, displayed: 1}); - } - }, - redisplay: function(id) { - // Repopulate HTML select box from cache - var box = document.getElementById(id); - box.options.length = 0; // clear all options - for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { - var node = SelectBox.cache[id][i]; - if (node.displayed) { - var new_option = new Option(node.text, node.value, false, false); - // Shows a tooltip when hovering over the option - new_option.setAttribute("title", node.text); - box.options[box.options.length] = new_option; +(function() { + 'use strict'; + var SelectBox = { + cache: {}, + init: function(id) { + var box = document.getElementById(id); + var node; + SelectBox.cache[id] = []; + var cache = SelectBox.cache[id]; + for (var i = 0; (node = box.options[i]); i++) { + cache.push({value: node.value, text: node.text, displayed: 1}); } - } - }, - filter: function(id, text) { - // Redisplay the HTML select box, displaying only the choices containing ALL - // the words in text. (It's an AND search.) - var tokens = text.toLowerCase().split(/\s+/); - var node, token; - for (var i = 0; (node = SelectBox.cache[id][i]); i++) { - node.displayed = 1; - for (var j = 0; (token = tokens[j]); j++) { - if (node.text.toLowerCase().indexOf(token) === -1) { - node.displayed = 0; + }, + redisplay: function(id) { + // Repopulate HTML select box from cache + var box = document.getElementById(id); + box.options.length = 0; // clear all options + for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { + var node = SelectBox.cache[id][i]; + if (node.displayed) { + var new_option = new Option(node.text, node.value, false, false); + // Shows a tooltip when hovering over the option + new_option.setAttribute("title", node.text); + box.options[box.options.length] = new_option; } } - } - SelectBox.redisplay(id); - }, - delete_from_cache: function(id, value) { - var node, delete_index = null; - for (var i = 0; (node = SelectBox.cache[id][i]); i++) { - if (node.value === value) { - delete_index = i; - break; - } - } - var j = SelectBox.cache[id].length - 1; - for (i = delete_index; i < j; i++) { - SelectBox.cache[id][i] = SelectBox.cache[id][i + 1]; - } - SelectBox.cache[id].length--; - }, - add_to_cache: function(id, option) { - SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); - }, - cache_contains: function(id, value) { - // Check if an item is contained in the cache - var node; - for (var i = 0; (node = SelectBox.cache[id][i]); i++) { - if (node.value === value) { - return true; - } - } - return false; - }, - move: function(from, to) { - var from_box = document.getElementById(from); - var option; - for (var i = 0; (option = from_box.options[i]); i++) { - if (option.selected && SelectBox.cache_contains(from, option.value)) { - SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); - SelectBox.delete_from_cache(from, option.value); - } - } - SelectBox.redisplay(from); - SelectBox.redisplay(to); - }, - move_all: function(from, to) { - var from_box = document.getElementById(from); - var option; - for (var i = 0; (option = from_box.options[i]); i++) { - if (SelectBox.cache_contains(from, option.value)) { - SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); - SelectBox.delete_from_cache(from, option.value); - } - } - SelectBox.redisplay(from); - SelectBox.redisplay(to); - }, - sort: function(id) { - SelectBox.cache[id].sort( function(a, b) { - a = a.text.toLowerCase(); - b = b.text.toLowerCase(); - try { - if (a > b) { - return 1; - } - if (a < b) { - return -1; + }, + filter: function(id, text) { + // Redisplay the HTML select box, displaying only the choices containing ALL + // the words in text. (It's an AND search.) + var tokens = text.toLowerCase().split(/\s+/); + var node, token; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + node.displayed = 1; + for (var j = 0; (token = tokens[j]); j++) { + if (node.text.toLowerCase().indexOf(token) === -1) { + node.displayed = 0; + } } } - catch (e) { - // silently fail on IE 'unknown' exception + SelectBox.redisplay(id); + }, + delete_from_cache: function(id, value) { + var node, delete_index = null; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + if (node.value === value) { + delete_index = i; + break; + } + } + var j = SelectBox.cache[id].length - 1; + for (i = delete_index; i < j; i++) { + SelectBox.cache[id][i] = SelectBox.cache[id][i + 1]; + } + SelectBox.cache[id].length--; + }, + add_to_cache: function(id, option) { + SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); + }, + cache_contains: function(id, value) { + // Check if an item is contained in the cache + var node; + for (var i = 0; (node = SelectBox.cache[id][i]); i++) { + if (node.value === value) { + return true; + } + } + return false; + }, + move: function(from, to) { + var from_box = document.getElementById(from); + var option; + for (var i = 0; (option = from_box.options[i]); i++) { + if (option.selected && SelectBox.cache_contains(from, option.value)) { + SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); + SelectBox.delete_from_cache(from, option.value); + } + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + move_all: function(from, to) { + var from_box = document.getElementById(from); + var option; + for (var i = 0; (option = from_box.options[i]); i++) { + if (SelectBox.cache_contains(from, option.value)) { + SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); + SelectBox.delete_from_cache(from, option.value); + } + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + sort: function(id) { + SelectBox.cache[id].sort( function(a, b) { + a = a.text.toLowerCase(); + b = b.text.toLowerCase(); + try { + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + } + catch (e) { + // silently fail on IE 'unknown' exception + } + return 0; + } ); + }, + select_all: function(id) { + var box = document.getElementById(id); + for (var i = 0; i < box.options.length; i++) { + box.options[i].selected = 'selected'; } - return 0; - } ); - }, - select_all: function(id) { - var box = document.getElementById(id); - for (var i = 0; i < box.options.length; i++) { - box.options[i].selected = 'selected'; } - } -}; + }; + window.SelectBox = SelectBox; +})(); diff --git a/django/contrib/admin/static/admin/js/SelectFilter2.js b/django/contrib/admin/static/admin/js/SelectFilter2.js index 616ec9bb5f..acf3996c38 100644 --- a/django/contrib/admin/static/admin/js/SelectFilter2.js +++ b/django/contrib/admin/static/admin/js/SelectFilter2.js @@ -5,6 +5,7 @@ SelectFilter2 - Turns a multiple-select box into a filter interface. Requires core.js, SelectBox.js and addevent.js. */ (function($) { + 'use strict'; function findForm(node) { // returns the node of the form containing the given node if (node.tagName.toLowerCase() !== 'form') { diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js index e899000ab3..95e8492b98 100644 --- a/django/contrib/admin/static/admin/js/actions.js +++ b/django/contrib/admin/static/admin/js/actions.js @@ -1,5 +1,6 @@ /*global _actions_icnt, gettext, interpolate, ngettext*/ (function($) { + 'use strict'; var lastChecked; $.fn.actions = function(opts) { diff --git a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js index b41c0cd505..d0acc23bb6 100644 --- a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js @@ -2,360 +2,363 @@ // Inserts shortcut buttons after all of the following: // // - -var DateTimeShortcuts = { - calendars: [], - calendarInputs: [], - clockInputs: [], - 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 - timezoneOffset: 0, - init: function() { - var body = document.getElementsByTagName('body')[0]; - var serverOffset = body.getAttribute('data-admin-utc-offset'); - if (serverOffset !== undefined) { - var localOffset = new Date().getTimezoneOffset() * -60; - DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; - } - - var inputs = document.getElementsByTagName('input'); - for (var i = 0; i < inputs.length; i++) { - var inp = inputs[i]; - if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) { - DateTimeShortcuts.addClock(inp); - DateTimeShortcuts.addTimezoneWarning(inp); +(function() { + 'use strict'; + var DateTimeShortcuts = { + calendars: [], + calendarInputs: [], + clockInputs: [], + 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 + timezoneOffset: 0, + init: function() { + var body = document.getElementsByTagName('body')[0]; + var serverOffset = body.getAttribute('data-admin-utc-offset'); + if (serverOffset !== undefined) { + var localOffset = new Date().getTimezoneOffset() * -60; + DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; } - else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) { - DateTimeShortcuts.addCalendar(inp); - DateTimeShortcuts.addTimezoneWarning(inp); + + var inputs = document.getElementsByTagName('input'); + for (var i = 0; i < inputs.length; i++) { + var inp = inputs[i]; + if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) { + DateTimeShortcuts.addClock(inp); + DateTimeShortcuts.addTimezoneWarning(inp); + } + else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) { + DateTimeShortcuts.addCalendar(inp); + DateTimeShortcuts.addTimezoneWarning(inp); + } } - } - }, - // Return the current time while accounting for the server timezone. - now: function() { - var body = document.getElementsByTagName('body')[0]; - var serverOffset = body.getAttribute('data-admin-utc-offset'); - if (serverOffset !== undefined) { - var localNow = new Date(); - var localOffset = localNow.getTimezoneOffset() * -60; - 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) { - var $ = django.jQuery; - var warningClass = DateTimeShortcuts.timezoneWarningClass; - var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; + }, + // Return the current time while accounting for the server timezone. + now: function() { + var body = document.getElementsByTagName('body')[0]; + var serverOffset = body.getAttribute('data-admin-utc-offset'); + if (serverOffset !== undefined) { + var localNow = new Date(); + var localOffset = localNow.getTimezoneOffset() * -60; + 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) { + var $ = django.jQuery; + var warningClass = DateTimeShortcuts.timezoneWarningClass; + var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; - // Only warn if there is a time zone mismatch. - if (!timezoneOffset) { - return; - } + // Only warn if there is a time zone mismatch. + if (!timezoneOffset) { + return; + } - // Check if warning is already there. - if ($(inp).siblings('.' + warningClass).length) { - return; - } + // Check if warning is already there. + if ($(inp).siblings('.' + warningClass).length) { + return; + } - var 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 + var 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 + ); + } + else { + timezoneOffset *= -1; + message = ngettext( + 'Note: You are %s hour behind server time.', + 'Note: You are %s hours behind server time.', + timezoneOffset + ); + } + message = interpolate(message, [timezoneOffset]); + + var $warning = $(''); + $warning.attr('class', warningClass); + $warning.text(message); + + $(inp).parent() + .append($('
')) + .append($warning); + }, + // Add clock widget to a given field + addClock: function(inp) { + var num = DateTimeShortcuts.clockInputs.length; + DateTimeShortcuts.clockInputs[num] = inp; + DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; + + // Shortcut links (clock icon and "Now" link) + var shortcuts_span = document.createElement('span'); + shortcuts_span.className = DateTimeShortcuts.shortCutsClass; + inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); + var now_link = document.createElement('a'); + now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); + now_link.appendChild(document.createTextNode(gettext('Now'))); + var clock_link = document.createElement('a'); + clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); + clock_link.id = DateTimeShortcuts.clockLinkName + num; + quickElement( + 'span', clock_link, '', + 'class', 'clock-icon', + 'title', gettext('Choose a Time') ); - } - else { - timezoneOffset *= -1; - message = ngettext( - 'Note: You are %s hour behind server time.', - 'Note: You are %s hours behind server time.', - timezoneOffset + shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(now_link); + shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild(clock_link); + + // Create clock link div + // + // Markup looks like: + //
+ //

Choose a time

+ // + //

Cancel

+ //
+ + var clock_box = document.createElement('div'); + clock_box.style.display = 'none'; + clock_box.style.position = 'absolute'; + clock_box.className = 'clockbox module'; + clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num); + document.body.appendChild(clock_box); + addEvent(clock_box, 'click', cancelEventPropagation); + + quickElement('h2', clock_box, gettext('Choose a time')); + var time_list = quickElement('ul', clock_box); + time_list.className = 'timelist'; + quickElement("a", quickElement("li", time_list), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); + quickElement("a", quickElement("li", time_list), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 0);"); + quickElement("a", quickElement("li", time_list), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 6);"); + quickElement("a", quickElement("li", time_list), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 12);"); + quickElement("a", quickElement("li", time_list), gettext("6 p.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 18);"); + + var cancel_p = quickElement('p', clock_box); + cancel_p.className = 'calendar-cancel'; + quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');'); + django.jQuery(document).bind('keyup', function(event) { + if (event.which === 27) { + // ESC key closes popup + DateTimeShortcuts.dismissClock(num); + event.preventDefault(); + } + }); + }, + openClock: function(num) { + var clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); + var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); + + // Recalculate the clockbox position + // is it left-to-right or right-to-left layout ? + if (getStyle(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 + // TODO: IE returns wrong value for findPosX when in rtl mode + // (it returns as it was left aligned), needs to be fixed. + clock_box.style.left = findPosX(clock_link) - 110 + 'px'; + } + clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; + + // Show the clock box + clock_box.style.display = 'block'; + addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); + }, + dismissClock: function(num) { + document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; + removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); + }, + handleClockQuicklink: function(num, val) { + var d; + if (val === -1) { + d = DateTimeShortcuts.now(); + } + 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].focus(); + DateTimeShortcuts.dismissClock(num); + }, + // Add calendar widget to a given field. + addCalendar: function(inp) { + var num = DateTimeShortcuts.calendars.length; + + DateTimeShortcuts.calendarInputs[num] = inp; + DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; + + // Shortcut links (calendar icon and "Today" link) + var shortcuts_span = document.createElement('span'); + shortcuts_span.className = DateTimeShortcuts.shortCutsClass; + inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); + var today_link = document.createElement('a'); + today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); + today_link.appendChild(document.createTextNode(gettext('Today'))); + var cal_link = document.createElement('a'); + cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); + cal_link.id = DateTimeShortcuts.calendarLinkName + num; + quickElement( + 'span', cal_link, '', + 'class', 'date-icon', + 'title', gettext('Choose a Date') ); - } - message = interpolate(message, [timezoneOffset]); + shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(today_link); + shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild(cal_link); - var $warning = $(''); - $warning.attr('class', warningClass); - $warning.text(message); + // Create calendarbox div. + // + // Markup looks like: + // + //
+ //

+ // + // February 2003 + //

+ //
+ // + //
+ //
+ // Yesterday | Today | Tomorrow + //
+ //

Cancel

+ //
+ var cal_box = document.createElement('div'); + cal_box.style.display = 'none'; + cal_box.style.position = 'absolute'; + cal_box.className = 'calendarbox module'; + cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num); + document.body.appendChild(cal_box); + addEvent(cal_box, 'click', cancelEventPropagation); - $(inp).parent() - .append($('
')) - .append($warning); - }, - // Add clock widget to a given field - addClock: function(inp) { - var num = DateTimeShortcuts.clockInputs.length; - DateTimeShortcuts.clockInputs[num] = inp; - DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; + // next-prev links + var cal_nav = quickElement('div', cal_box); + var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev(' + num + ');'); + cal_nav_prev.className = 'calendarnav-previous'; + var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext(' + num + ');'); + cal_nav_next.className = 'calendarnav-next'; - // Shortcut links (clock icon and "Now" link) - var shortcuts_span = document.createElement('span'); - shortcuts_span.className = DateTimeShortcuts.shortCutsClass; - inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - var now_link = document.createElement('a'); - now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); - now_link.appendChild(document.createTextNode(gettext('Now'))); - var clock_link = document.createElement('a'); - clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); - clock_link.id = DateTimeShortcuts.clockLinkName + num; - quickElement( - 'span', clock_link, '', - 'class', 'clock-icon', - 'title', gettext('Choose a Time') - ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); - shortcuts_span.appendChild(now_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); - shortcuts_span.appendChild(clock_link); + // main box + var 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(); - // Create clock link div - // - // Markup looks like: - //
- //

Choose a time

- // - //

Cancel

- //
+ // calendar shortcuts + var shortcuts = quickElement('div', cal_box); + shortcuts.className = 'calendar-shortcuts'; + quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);'); + shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); + quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); + shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); + quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);'); - var clock_box = document.createElement('div'); - clock_box.style.display = 'none'; - clock_box.style.position = 'absolute'; - clock_box.className = 'clockbox module'; - clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num); - document.body.appendChild(clock_box); - addEvent(clock_box, 'click', cancelEventPropagation); + // cancel bar + var cancel_p = quickElement('p', cal_box); + cancel_p.className = 'calendar-cancel'; + quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); + django.jQuery(document).bind('keyup', function(event) { + if (event.which === 27) { + // ESC key closes popup + DateTimeShortcuts.dismissCalendar(num); + event.preventDefault(); + } + }); + }, + openCalendar: function(num) { + var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); + var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); + var inp = DateTimeShortcuts.calendarInputs[num]; - quickElement('h2', clock_box, gettext('Choose a time')); - var time_list = quickElement('ul', clock_box); - time_list.className = 'timelist'; - quickElement("a", quickElement("li", time_list), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); - quickElement("a", quickElement("li", time_list), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 0);"); - quickElement("a", quickElement("li", time_list), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 6);"); - quickElement("a", quickElement("li", time_list), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 12);"); - quickElement("a", quickElement("li", time_list), gettext("6 p.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 18);"); - - var cancel_p = quickElement('p', clock_box); - cancel_p.className = 'calendar-cancel'; - quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');'); - django.jQuery(document).bind('keyup', function(event) { - if (event.which === 27) { - // ESC key closes popup - DateTimeShortcuts.dismissClock(num); - event.preventDefault(); + // 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) { + var format = get_format('DATE_INPUT_FORMATS')[0]; + var selected = inp.value.strptime(format); + var year = selected.getFullYear(); + var month = selected.getMonth() + 1; + var re = /\d{4}/; + if (re.test(year.toString()) && month >= 1 && month <= 12) { + DateTimeShortcuts.calendars[num].drawDate(month, year, selected); + } } - }); - }, - openClock: function(num) { - var clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); - var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); - // Recalculate the clockbox position - // is it left-to-right or right-to-left layout ? - if (getStyle(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 - // TODO: IE returns wrong value for findPosX when in rtl mode - // (it returns as it was left aligned), needs to be fixed. - clock_box.style.left = findPosX(clock_link) - 110 + 'px'; - } - clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; - - // Show the clock box - clock_box.style.display = 'block'; - addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); - }, - dismissClock: function(num) { - document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; - removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); - }, - handleClockQuicklink: function(num, val) { - var d; - if (val === -1) { - d = DateTimeShortcuts.now(); - } - 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].focus(); - DateTimeShortcuts.dismissClock(num); - }, - // Add calendar widget to a given field. - addCalendar: function(inp) { - var num = DateTimeShortcuts.calendars.length; - - DateTimeShortcuts.calendarInputs[num] = inp; - DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; - - // Shortcut links (calendar icon and "Today" link) - var shortcuts_span = document.createElement('span'); - shortcuts_span.className = DateTimeShortcuts.shortCutsClass; - inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); - var today_link = document.createElement('a'); - today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); - today_link.appendChild(document.createTextNode(gettext('Today'))); - var cal_link = document.createElement('a'); - cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); - cal_link.id = DateTimeShortcuts.calendarLinkName + num; - quickElement( - 'span', cal_link, '', - 'class', 'date-icon', - 'title', gettext('Choose a Date') - ); - shortcuts_span.appendChild(document.createTextNode('\u00A0')); - shortcuts_span.appendChild(today_link); - shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); - shortcuts_span.appendChild(cal_link); - - // Create calendarbox div. - // - // Markup looks like: - // - //
- //

- // - // February 2003 - //

- //
- // - //
- //
- // Yesterday | Today | Tomorrow - //
- //

Cancel

- //
- var cal_box = document.createElement('div'); - cal_box.style.display = 'none'; - cal_box.style.position = 'absolute'; - cal_box.className = 'calendarbox module'; - cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num); - document.body.appendChild(cal_box); - addEvent(cal_box, 'click', cancelEventPropagation); - - // next-prev links - var cal_nav = quickElement('div', cal_box); - var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev(' + num + ');'); - cal_nav_prev.className = 'calendarnav-previous'; - var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext(' + num + ');'); - cal_nav_next.className = 'calendarnav-next'; - - // main box - var 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 - var shortcuts = quickElement('div', cal_box); - shortcuts.className = 'calendar-shortcuts'; - quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);'); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); - shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);'); - - // cancel bar - var cancel_p = quickElement('p', cal_box); - cancel_p.className = 'calendar-cancel'; - quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); - django.jQuery(document).bind('keyup', function(event) { - if (event.which === 27) { - // ESC key closes popup - DateTimeShortcuts.dismissCalendar(num); - event.preventDefault(); + // Recalculate the clockbox position + // is it left-to-right or right-to-left layout ? + if (getStyle(document.body, 'direction') !== 'rtl') { + cal_box.style.left = findPosX(cal_link) + 17 + 'px'; } - }); - }, - openCalendar: function(num) { - var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); - var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); - var inp = DateTimeShortcuts.calendarInputs[num]; + 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 + // TODO: IE returns wrong value for findPosX when in rtl mode + // (it returns as it was left aligned), needs to be fixed. + cal_box.style.left = findPosX(cal_link) - 180 + 'px'; + } + cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; - // 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) { + cal_box.style.display = 'block'; + addEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); + }, + dismissCalendar: function(num) { + document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; + removeEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); + }, + drawPrev: function(num) { + DateTimeShortcuts.calendars[num].drawPreviousMonth(); + }, + drawNext: function(num) { + DateTimeShortcuts.calendars[num].drawNextMonth(); + }, + handleCalendarCallback: function(num) { var format = get_format('DATE_INPUT_FORMATS')[0]; - var selected = inp.value.strptime(format); - var year = selected.getFullYear(); - var month = selected.getMonth() + 1; - var re = /\d{4}/; - if (re.test(year.toString()) && month >= 1 && month <= 12) { - DateTimeShortcuts.calendars[num].drawDate(month, year, selected); - } + // the format needs to be escaped a little + format = format.replace('\\', '\\\\'); + format = format.replace('\r', '\\r'); + format = format.replace('\n', '\\n'); + format = format.replace('\t', '\\t'); + format = format.replace("'", "\\'"); + 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';}"].join(''); + }, + handleCalendarQuickLink: function(num, offset) { + var d = DateTimeShortcuts.now(); + d.setDate(d.getDate() + offset); + DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); + DateTimeShortcuts.calendarInputs[num].focus(); + DateTimeShortcuts.dismissCalendar(num); } + }; - // Recalculate the clockbox position - // is it left-to-right or right-to-left layout ? - if (getStyle(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 - // TODO: IE returns wrong value for findPosX when in rtl mode - // (it returns as it was left aligned), needs to be fixed. - cal_box.style.left = findPosX(cal_link) - 180 + 'px'; - } - cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; - - cal_box.style.display = 'block'; - addEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); - }, - dismissCalendar: function(num) { - document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; - removeEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); - }, - drawPrev: function(num) { - DateTimeShortcuts.calendars[num].drawPreviousMonth(); - }, - drawNext: function(num) { - DateTimeShortcuts.calendars[num].drawNextMonth(); - }, - handleCalendarCallback: function(num) { - var format = get_format('DATE_INPUT_FORMATS')[0]; - // the format needs to be escaped a little - format = format.replace('\\', '\\\\'); - format = format.replace('\r', '\\r'); - format = format.replace('\n', '\\n'); - format = format.replace('\t', '\\t'); - format = format.replace("'", "\\'"); - 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';}"].join(''); - }, - handleCalendarQuickLink: function(num, offset) { - var d = DateTimeShortcuts.now(); - d.setDate(d.getDate() + offset); - DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); - DateTimeShortcuts.calendarInputs[num].focus(); - DateTimeShortcuts.dismissCalendar(num); - } -}; - -addEvent(window, 'load', DateTimeShortcuts.init); + addEvent(window, '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 59688260ad..fa782fe2b8 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -2,141 +2,159 @@ // Handles related-objects functionality: lookup link for raw_id_fields // and Add Another links. -function html_unescape(text) { - // Unescape a string that was escaped using django.utils.html.escape. - text = text.replace(/</g, '<'); - text = text.replace(/>/g, '>'); - text = text.replace(/"/g, '"'); - text = text.replace(/'/g, "'"); - text = text.replace(/&/g, '&'); - return text; -} +(function() { + 'use strict'; -// IE doesn't accept periods or dashes in the window name, but the element IDs -// we use to generate popup window names may contain them, therefore we map them -// to allowed characters in a reversible way so that we can locate the correct -// element when the popup window is dismissed. -function id_to_windowname(text) { - text = text.replace(/\./g, '__dot__'); - text = text.replace(/\-/g, '__dash__'); - return text; -} - -function windowname_to_id(text) { - text = text.replace(/__dot__/g, '.'); - text = text.replace(/__dash__/g, '-'); - return text; -} - -function showAdminPopup(triggeringLink, name_regexp, add_popup) { - var name = triggeringLink.id.replace(name_regexp, ''); - name = id_to_windowname(name); - var href = triggeringLink.href; - if (add_popup) { - if (href.indexOf('?') === -1) { - href += '?_popup=1'; - } else { - href += '&_popup=1'; - } + function html_unescape(text) { + // Unescape a string that was escaped using django.utils.html.escape. + text = text.replace(/</g, '<'); + text = text.replace(/>/g, '>'); + text = text.replace(/"/g, '"'); + text = text.replace(/'/g, "'"); + text = text.replace(/&/g, '&'); + return text; } - var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); - win.focus(); - return false; -} -function showRelatedObjectLookupPopup(triggeringLink) { - return showAdminPopup(triggeringLink, /^lookup_/, true); -} - -function dismissRelatedLookupPopup(win, chosenId) { - var name = windowname_to_id(win.name); - var elem = document.getElementById(name); - if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { - elem.value += ',' + chosenId; - } else { - document.getElementById(name).value = chosenId; + // IE doesn't accept periods or dashes in the window name, but the element IDs + // we use to generate popup window names may contain them, therefore we map them + // to allowed characters in a reversible way so that we can locate the correct + // element when the popup window is dismissed. + function id_to_windowname(text) { + text = text.replace(/\./g, '__dot__'); + text = text.replace(/\-/g, '__dash__'); + return text; } - win.close(); -} -function showRelatedObjectPopup(triggeringLink) { - return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false); -} - -function updateRelatedObjectLinks(triggeringLink) { - var $this = django.jQuery(triggeringLink); - var siblings = $this.nextAll('.change-related, .delete-related'); - if (!siblings.length) { - return; + function windowname_to_id(text) { + text = text.replace(/__dot__/g, '.'); + text = text.replace(/__dash__/g, '-'); + return text; } - var value = $this.val(); - if (value) { - siblings.each(function() { - var elm = django.jQuery(this); - elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); - }); - } else { - siblings.removeAttr('href'); - } -} -function dismissAddRelatedObjectPopup(win, newId, newRepr) { - // newId and newRepr are expected to have previously been escaped by - // django.utils.html.escape. - newId = html_unescape(newId); - newRepr = html_unescape(newRepr); - var name = windowname_to_id(win.name); - var elem = document.getElementById(name); - if (elem) { - var elemName = elem.nodeName.toUpperCase(); - if (elemName === 'SELECT') { - elem.options[elem.options.length] = new Option(newRepr, newId, true, true); - } else if (elemName === 'INPUT') { - if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { - elem.value += ',' + newId; + function showAdminPopup(triggeringLink, name_regexp, add_popup) { + var name = triggeringLink.id.replace(name_regexp, ''); + name = id_to_windowname(name); + var href = triggeringLink.href; + if (add_popup) { + if (href.indexOf('?') === -1) { + href += '?_popup=1'; } else { - elem.value = newId; + href += '&_popup=1'; } } - // Trigger a change event to update related links if required. - django.jQuery(elem).trigger('change'); - } else { - var toId = name + "_to"; - var o = new Option(newRepr, newId); - SelectBox.add_to_cache(toId, o); - SelectBox.redisplay(toId); + var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); + win.focus(); + return false; } - win.close(); -} -function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { - objId = html_unescape(objId); - newRepr = html_unescape(newRepr); - var id = windowname_to_id(win.name).replace(/^edit_/, ''); - var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); - var selects = django.jQuery(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - this.innerHTML = newRepr; - this.value = newId; + function showRelatedObjectLookupPopup(triggeringLink) { + return showAdminPopup(triggeringLink, /^lookup_/, true); + } + + function dismissRelatedLookupPopup(win, chosenId) { + var name = windowname_to_id(win.name); + var elem = document.getElementById(name); + if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { + elem.value += ',' + chosenId; + } else { + document.getElementById(name).value = chosenId; } - }); - win.close(); -} + win.close(); + } -function dismissDeleteRelatedObjectPopup(win, objId) { - objId = html_unescape(objId); - var id = windowname_to_id(win.name).replace(/^delete_/, ''); - var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); - var selects = django.jQuery(selectsSelector); - selects.find('option').each(function() { - if (this.value === objId) { - django.jQuery(this).remove(); + function showRelatedObjectPopup(triggeringLink) { + return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false); + } + + function updateRelatedObjectLinks(triggeringLink) { + var $this = django.jQuery(triggeringLink); + var siblings = $this.nextAll('.change-related, .delete-related'); + if (!siblings.length) { + return; } - }).trigger('change'); - win.close(); -} + var value = $this.val(); + if (value) { + siblings.each(function() { + var elm = django.jQuery(this); + elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); + }); + } else { + siblings.removeAttr('href'); + } + } -// Kept for backward compatibility -var showAddAnotherPopup = showRelatedObjectPopup; -var dismissAddAnotherPopup = dismissAddRelatedObjectPopup; + function dismissAddRelatedObjectPopup(win, newId, newRepr) { + // newId and newRepr are expected to have previously been escaped by + // django.utils.html.escape. + newId = html_unescape(newId); + newRepr = html_unescape(newRepr); + var name = windowname_to_id(win.name); + var elem = document.getElementById(name); + if (elem) { + var elemName = elem.nodeName.toUpperCase(); + if (elemName === 'SELECT') { + elem.options[elem.options.length] = new Option(newRepr, newId, true, true); + } else if (elemName === 'INPUT') { + if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { + elem.value += ',' + newId; + } else { + elem.value = newId; + } + } + // Trigger a change event to update related links if required. + django.jQuery(elem).trigger('change'); + } else { + var toId = name + "_to"; + var o = new Option(newRepr, newId); + SelectBox.add_to_cache(toId, o); + SelectBox.redisplay(toId); + } + win.close(); + } + + function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { + objId = html_unescape(objId); + newRepr = html_unescape(newRepr); + var id = windowname_to_id(win.name).replace(/^edit_/, ''); + var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + var selects = django.jQuery(selectsSelector); + selects.find('option').each(function() { + if (this.value === objId) { + this.innerHTML = newRepr; + this.value = newId; + } + }); + win.close(); + } + + function dismissDeleteRelatedObjectPopup(win, objId) { + objId = html_unescape(objId); + var id = windowname_to_id(win.name).replace(/^delete_/, ''); + var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + var selects = django.jQuery(selectsSelector); + selects.find('option').each(function() { + if (this.value === objId) { + django.jQuery(this).remove(); + } + }).trigger('change'); + win.close(); + } + + // Global for testing purposes + window.html_unescape = html_unescape; + window.id_to_windowname = id_to_windowname; + window.windowname_to_id = windowname_to_id; + + window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup; + window.dismissRelatedLookupPopup = dismissRelatedLookupPopup; + window.showRelatedObjectPopup = showRelatedObjectPopup; + window.updateRelatedObjectLinks = updateRelatedObjectLinks; + window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup; + window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup; + window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup; + + // Kept for backward compatibility + window.showAddAnotherPopup = showRelatedObjectPopup; + window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup; + +})(); diff --git a/django/contrib/admin/static/admin/js/calendar.js b/django/contrib/admin/static/admin/js/calendar.js index 3083ca8b1a..1043dd61ef 100644 --- a/django/contrib/admin/static/admin/js/calendar.js +++ b/django/contrib/admin/static/admin/js/calendar.js @@ -4,171 +4,175 @@ calendar.js - Calendar functions by Adrian Holovaty depends on core.js for utility functions like removeChildren or quickElement */ -// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions -var CalendarNamespace = { - monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), - daysOfWeek: gettext('S M T W T F S').split(' '), - 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) { - var days; - 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) { - days = 30; - } - else if (month === 2 && CalendarNamespace.isLeapYear(year)) { - days = 29; - } - else { - days = 28; - } - return days; - }, - draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 - var today = new Date(); - var todayDay = today.getDate(); - var todayMonth = today.getMonth() + 1; - var todayYear = today.getFullYear(); - var todayClass = ''; - - // Use UTC functions here because the date field does not contain time - // and using the UTC function variants prevent the local time offset - // from altering the date, specifically the day field. For example: - // - // ``` - // var x = new Date('2013-10-02'); - // var day = x.getDate(); - // ``` - // - // The day variable above will be 1 instead of 2 in, say, US Pacific time - // zone. - var isSelectedMonth = false; - if (typeof selected !== 'undefined') { - isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); - } - - month = parseInt(month); - year = parseInt(year); - var calDiv = document.getElementById(div_id); - removeChildren(calDiv); - var calTable = document.createElement('table'); - quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); - var tableBody = quickElement('tbody', calTable); - - // Draw days-of-week header - var tableRow = quickElement('tr', tableBody); - for (var i = 0; i < 7; i++) { - quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); - } - - var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); - var days = CalendarNamespace.getDaysInMonth(month, year); - - var nonDayCell; - - // Draw blanks before first of month - tableRow = quickElement('tr', tableBody); - for (i = 0; i < startingPos; i++) { - nonDayCell = quickElement('td', tableRow, ' '); - nonDayCell.className = "nonday"; - } - - // Draw days of month - var currentDay = 1; - for (i = startingPos; currentDay <= days; i++) { - if (i % 7 === 0 && currentDay !== 1) { - tableRow = quickElement('tr', tableBody); +(function() { + 'use strict'; + // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions + var CalendarNamespace = { + monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), + daysOfWeek: gettext('S M T W T F S').split(' '), + 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) { + var days; + if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { + days = 31; } - if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { - todayClass = 'today'; - } else { - todayClass = ''; + else if (month === 4 || month === 6 || month === 9 || month === 11) { + days = 30; + } + else if (month === 2 && CalendarNamespace.isLeapYear(year)) { + days = 29; + } + else { + days = 28; + } + return days; + }, + draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 + var today = new Date(); + var todayDay = today.getDate(); + var todayMonth = today.getMonth() + 1; + var todayYear = today.getFullYear(); + var todayClass = ''; + + // Use UTC functions here because the date field does not contain time + // and using the UTC function variants prevent the local time offset + // from altering the date, specifically the day field. For example: + // + // ``` + // var x = new Date('2013-10-02'); + // var day = x.getDate(); + // ``` + // + // The day variable above will be 1 instead of 2 in, say, US Pacific time + // zone. + var isSelectedMonth = false; + if (typeof selected !== 'undefined') { + isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); } - // use UTC function; see above for explanation. - if (isSelectedMonth && currentDay === selected.getUTCDate()) { - if (todayClass !== '') { - todayClass += " "; + month = parseInt(month); + year = parseInt(year); + var calDiv = document.getElementById(div_id); + removeChildren(calDiv); + var calTable = document.createElement('table'); + quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); + var tableBody = quickElement('tbody', calTable); + + // Draw days-of-week header + var tableRow = quickElement('tr', tableBody); + for (var i = 0; i < 7; i++) { + quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); + } + + var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); + var days = CalendarNamespace.getDaysInMonth(month, year); + + var nonDayCell; + + // Draw blanks before first of month + tableRow = quickElement('tr', tableBody); + for (i = 0; i < startingPos; i++) { + nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell.className = "nonday"; + } + + // Draw days of month + var currentDay = 1; + for (i = startingPos; currentDay <= days; i++) { + if (i % 7 === 0 && currentDay !== 1) { + tableRow = quickElement('tr', tableBody); } - todayClass += "selected"; + if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { + todayClass = 'today'; + } else { + todayClass = ''; + } + + // use UTC function; see above for explanation. + if (isSelectedMonth && currentDay === selected.getUTCDate()) { + if (todayClass !== '') { + todayClass += " "; + } + todayClass += "selected"; + } + + var cell = quickElement('td', tableRow, '', 'class', todayClass); + + quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '(' + year + ',' + month + ',' + currentDay + '));'); + currentDay++; } - var cell = quickElement('td', tableRow, '', 'class', todayClass); + // Draw blanks after end of month (optional, but makes for valid code) + while (tableRow.childNodes.length < 7) { + nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell.className = "nonday"; + } - quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '(' + year + ',' + month + ',' + currentDay + '));'); - currentDay++; + calDiv.appendChild(calTable); } + }; - // Draw blanks after end of month (optional, but makes for valid code) - while (tableRow.childNodes.length < 7) { - nonDayCell = quickElement('td', tableRow, ' '); - nonDayCell.className = "nonday"; - } - - calDiv.appendChild(calTable); - } -}; - -// Calendar -- A calendar instance -function Calendar(div_id, callback, selected) { - // div_id (string) is the ID of the element in which the calendar will - // be displayed - // callback (string) is the name of a JavaScript function that will be - // called with the parameters (year, month, day) when a day in the - // calendar is clicked - this.div_id = div_id; - this.callback = callback; - this.today = new Date(); - this.currentMonth = this.today.getMonth() + 1; - this.currentYear = this.today.getFullYear(); - if (typeof selected !== 'undefined') { - this.selected = selected; - } -} -Calendar.prototype = { - drawCurrent: function() { - CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); - }, - drawDate: function(month, year, selected) { - this.currentMonth = month; - this.currentYear = year; - - if(selected) { + // Calendar -- A calendar instance + function Calendar(div_id, callback, selected) { + // div_id (string) is the ID of the element in which the calendar will + // be displayed + // callback (string) is the name of a JavaScript function that will be + // called with the parameters (year, month, day) when a day in the + // calendar is clicked + this.div_id = div_id; + this.callback = callback; + this.today = new Date(); + this.currentMonth = this.today.getMonth() + 1; + this.currentYear = this.today.getFullYear(); + if (typeof selected !== 'undefined') { this.selected = selected; } - - this.drawCurrent(); - }, - drawPreviousMonth: function() { - if (this.currentMonth === 1) { - this.currentMonth = 12; - this.currentYear--; - } - else { - this.currentMonth--; - } - this.drawCurrent(); - }, - drawNextMonth: function() { - if (this.currentMonth === 12) { - this.currentMonth = 1; - this.currentYear++; - } - else { - this.currentMonth++; - } - this.drawCurrent(); - }, - drawPreviousYear: function() { - this.currentYear--; - this.drawCurrent(); - }, - drawNextYear: function() { - this.currentYear++; - this.drawCurrent(); } -}; + Calendar.prototype = { + drawCurrent: function() { + CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); + }, + drawDate: function(month, year, selected) { + this.currentMonth = month; + this.currentYear = year; + + if(selected) { + this.selected = selected; + } + + this.drawCurrent(); + }, + drawPreviousMonth: function() { + if (this.currentMonth === 1) { + this.currentMonth = 12; + this.currentYear--; + } + else { + this.currentMonth--; + } + this.drawCurrent(); + }, + drawNextMonth: function() { + if (this.currentMonth === 12) { + this.currentMonth = 1; + this.currentYear++; + } + else { + this.currentMonth++; + } + this.drawCurrent(); + }, + drawPreviousYear: function() { + this.currentYear--; + this.drawCurrent(); + }, + drawNextYear: function() { + this.currentYear++; + this.drawCurrent(); + } + }; + window.Calendar = Calendar; +})(); diff --git a/django/contrib/admin/static/admin/js/collapse.js b/django/contrib/admin/static/admin/js/collapse.js index 4a018cf614..7cb936288e 100644 --- a/django/contrib/admin/static/admin/js/collapse.js +++ b/django/contrib/admin/static/admin/js/collapse.js @@ -1,5 +1,6 @@ /*global gettext*/ (function($) { + 'use strict'; $(document).ready(function() { // Add anchor tag for Show/Hide link $("fieldset.collapse").each(function(i, elem) { diff --git a/django/contrib/admin/static/admin/js/core.js b/django/contrib/admin/static/admin/js/core.js index 3df0a8a807..34f99262c5 100644 --- a/django/contrib/admin/static/admin/js/core.js +++ b/django/contrib/admin/static/admin/js/core.js @@ -6,6 +6,7 @@ var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.spl // Cross-browser event handlers. function addEvent(obj, evType, fn) { + 'use strict'; if (obj.addEventListener) { obj.addEventListener(evType, fn, false); return true; @@ -18,6 +19,7 @@ function addEvent(obj, evType, fn) { } function removeEvent(obj, evType, fn) { + 'use strict'; if (obj.removeEventListener) { obj.removeEventListener(evType, fn, false); return true; @@ -30,6 +32,7 @@ function removeEvent(obj, evType, fn) { } function cancelEventPropagation(e) { + 'use strict'; if (!e) { e = window.event; } @@ -41,6 +44,7 @@ function cancelEventPropagation(e) { // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); function quickElement() { + 'use strict'; var obj = document.createElement(arguments[0]); if (arguments[2]) { var textNode = document.createTextNode(arguments[2]); @@ -56,6 +60,7 @@ function quickElement() { // "a" is reference to an object function removeChildren(a) { + 'use strict'; while (a.hasChildNodes()) { a.removeChild(a.lastChild); } @@ -89,6 +94,7 @@ if (!xmlhttp && typeof XMLHttpRequest !== 'undefined') { // See http://www.quirksmode.org/js/findpos.html // ---------------------------------------------------------------------------- function findPosX(obj) { + 'use strict'; var curleft = 0; if (obj.offsetParent) { while (obj.offsetParent) { @@ -106,6 +112,7 @@ function findPosX(obj) { } function findPosY(obj) { + 'use strict'; var curtop = 0; if (obj.offsetParent) { while (obj.offsetParent) { @@ -125,120 +132,123 @@ function findPosY(obj) { //----------------------------------------------------------------------------- // Date object extensions // ---------------------------------------------------------------------------- - -Date.prototype.getTwelveHours = function() { - var hours = this.getHours(); - if (hours === 0) { - return 12; - } - else { - return hours <= 12 ? hours : hours - 12; - } -}; - -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.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.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.getHourMinute = function() { - return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); -}; - -Date.prototype.getHourMinuteSecond = function() { - return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); -}; - -Date.prototype.strftime = function(format) { - var fields = { - c: this.toString(), - d: this.getTwoDigitDate(), - H: this.getTwoDigitHour(), - I: this.getTwoDigitTwelveHour(), - m: this.getTwoDigitMonth(), - M: this.getTwoDigitMinute(), - p: (this.getHours() >= 12) ? 'PM' : 'AM', - S: this.getTwoDigitSecond(), - w: '0' + this.getDay(), - x: this.toLocaleDateString(), - X: this.toLocaleTimeString(), - y: ('' + this.getFullYear()).substr(2, 4), - Y: '' + this.getFullYear(), - '%': '%' - }; - var result = '', i = 0; - while (i < format.length) { - if (format.charAt(i) === '%') { - result = result + fields[format.charAt(i + 1)]; - ++i; +(function() { + 'use strict'; + Date.prototype.getTwelveHours = function() { + var hours = this.getHours(); + if (hours === 0) { + return 12; } else { - result = result + format.charAt(i); + return hours <= 12 ? hours : hours - 12; } - ++i; - } - return result; -}; + }; + + 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.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.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.getHourMinute = function() { + return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); + }; + + Date.prototype.getHourMinuteSecond = function() { + return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); + }; + + Date.prototype.strftime = function(format) { + var fields = { + c: this.toString(), + d: this.getTwoDigitDate(), + H: this.getTwoDigitHour(), + I: this.getTwoDigitTwelveHour(), + m: this.getTwoDigitMonth(), + M: this.getTwoDigitMinute(), + p: (this.getHours() >= 12) ? 'PM' : 'AM', + S: this.getTwoDigitSecond(), + w: '0' + this.getDay(), + x: this.toLocaleDateString(), + X: this.toLocaleTimeString(), + y: ('' + this.getFullYear()).substr(2, 4), + Y: '' + this.getFullYear(), + '%': '%' + }; + var result = '', i = 0; + while (i < format.length) { + if (format.charAt(i) === '%') { + result = result + fields[format.charAt(i + 1)]; + ++i; + } + else { + result = result + format.charAt(i); + } + ++i; + } + return result; + }; // ---------------------------------------------------------------------------- // String object extensions // ---------------------------------------------------------------------------- -String.prototype.pad_left = function(pad_length, pad_string) { - var new_string = this; - for (var i = 0; new_string.length < pad_length; i++) { - new_string = pad_string + new_string; - } - return new_string; -}; - -String.prototype.strptime = function(format) { - var split_format = format.split(/[.\-/]/); - var date = this.split(/[.\-/]/); - var i = 0; - var 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": - year = date[i]; - break; + String.prototype.pad_left = function(pad_length, pad_string) { + var new_string = this; + for (var i = 0; new_string.length < pad_length; i++) { + new_string = pad_string + new_string; } - ++i; - } - return new Date(year, month, day); -}; + return new_string; + }; + String.prototype.strptime = function(format) { + var split_format = format.split(/[.\-/]/); + var date = this.split(/[.\-/]/); + var i = 0; + var 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": + year = date[i]; + break; + } + ++i; + } + return new Date(year, month, day); + }; + +})(); // ---------------------------------------------------------------------------- // Get the computed style for and element // ---------------------------------------------------------------------------- function getStyle(oElm, strCssRule) { + 'use strict'; var strValue = ""; if(document.defaultView && document.defaultView.getComputedStyle) { strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); diff --git a/django/contrib/admin/static/admin/js/inlines.js b/django/contrib/admin/static/admin/js/inlines.js index 0c6da51986..3e082217c7 100644 --- a/django/contrib/admin/static/admin/js/inlines.js +++ b/django/contrib/admin/static/admin/js/inlines.js @@ -16,6 +16,7 @@ * See: http://www.opensource.org/licenses/bsd-license.php */ (function($) { + 'use strict'; $.fn.formset = function(opts) { var options = $.extend({}, $.fn.formset.defaults, opts); var $this = $(this); diff --git a/django/contrib/admin/static/admin/js/prepopulate.js b/django/contrib/admin/static/admin/js/prepopulate.js index e0a13ee9a3..5d4b0e8c27 100644 --- a/django/contrib/admin/static/admin/js/prepopulate.js +++ b/django/contrib/admin/static/admin/js/prepopulate.js @@ -1,5 +1,6 @@ /*global URLify*/ (function($) { + 'use strict'; $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { /* Depends on urlify.js diff --git a/django/contrib/admin/static/admin/js/timeparse.js b/django/contrib/admin/static/admin/js/timeparse.js index 15dc13956f..3cdc7ec7ce 100644 --- a/django/contrib/admin/static/admin/js/timeparse.js +++ b/django/contrib/admin/static/admin/js/timeparse.js @@ -1,101 +1,106 @@ -var timeParsePatterns = [ - // 9 - { - re: /^\d{1,2}$/i, - handler: function(bits) { - if (bits[0].length === 1) { - return '0' + bits[0] + ':00'; - } else { - return bits[0] + ':00'; +(function() { + 'use strict'; + var timeParsePatterns = [ + // 9 + { + re: /^\d{1,2}$/i, + handler: function(bits) { + if (bits[0].length === 1) { + return '0' + bits[0] + ':00'; + } else { + return bits[0] + ':00'; + } } - } - }, - // 13:00 - { - re: /^\d{2}[:.]\d{2}$/i, - handler: function(bits) { - return bits[0].replace('.', ':'); - } - }, - // 9:00 - { - re: /^\d[:.]\d{2}$/i, - handler: function(bits) { - return '0' + bits[0].replace('.', ':'); - } - }, - // 3 am / 3 a.m. / 3am - { - re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, - handler: function(bits) { - var hour = parseInt(bits[1]); - if (hour === 12) { - hour = 0; + }, + // 13:00 + { + re: /^\d{2}[:.]\d{2}$/i, + handler: function(bits) { + return bits[0].replace('.', ':'); } - if (bits[2].toLowerCase() === 'p') { + }, + // 9:00 + { + re: /^\d[:.]\d{2}$/i, + handler: function(bits) { + return '0' + bits[0].replace('.', ':'); + } + }, + // 3 am / 3 a.m. / 3am + { + re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, + handler: function(bits) { + var hour = parseInt(bits[1]); if (hour === 12) { hour = 0; } - return (hour + 12) + ':00'; - } else { - if (hour < 10) { - return '0' + hour + ':00'; + if (bits[2].toLowerCase() === 'p') { + if (hour === 12) { + hour = 0; + } + return (hour + 12) + ':00'; } else { - return hour + ':00'; + if (hour < 10) { + return '0' + hour + ':00'; + } else { + return hour + ':00'; + } } } - } - }, - // 3.30 am / 3:15 a.m. / 3.00am - { - re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, - handler: function(bits) { - var hour = parseInt(bits[1]); - var mins = parseInt(bits[2]); - if (mins < 10) { - mins = '0' + mins; - } - if (hour === 12) { - hour = 0; - } - if (bits[3].toLowerCase() === 'p') { + }, + // 3.30 am / 3:15 a.m. / 3.00am + { + re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, + handler: function(bits) { + var hour = parseInt(bits[1]); + var mins = parseInt(bits[2]); + if (mins < 10) { + mins = '0' + mins; + } if (hour === 12) { hour = 0; } - return (hour + 12) + ':' + mins; - } else { - if (hour < 10) { - return '0' + hour + ':' + mins; + if (bits[3].toLowerCase() === 'p') { + if (hour === 12) { + hour = 0; + } + return (hour + 12) + ':' + mins; } else { - return hour + ':' + mins; + if (hour < 10) { + return '0' + hour + ':' + mins; + } else { + return hour + ':' + mins; + } } } + }, + // noon + { + re: /^no/i, + handler: function(bits) { + return '12:00'; + } + }, + // midnight + { + re: /^mid/i, + handler: function(bits) { + return '00:00'; + } } - }, - // noon - { - re: /^no/i, - handler: function(bits) { - return '12:00'; - } - }, - // midnight - { - re: /^mid/i, - handler: function(bits) { - return '00:00'; - } - } -]; + ]; -function parseTimeString(s) { - for (var i = 0; i < timeParsePatterns.length; i++) { - var re = timeParsePatterns[i].re; - var handler = timeParsePatterns[i].handler; - var bits = re.exec(s); - if (bits) { - return handler(bits); + function parseTimeString(s) { + for (var i = 0; i < timeParsePatterns.length; i++) { + var re = timeParsePatterns[i].re; + var handler = timeParsePatterns[i].handler; + var bits = re.exec(s); + if (bits) { + return handler(bits); + } } + return s; } - return s; -} + + window.parseTimeString = parseTimeString; +})(); diff --git a/django/contrib/admin/static/admin/js/urlify.js b/django/contrib/admin/static/admin/js/urlify.js index 5e99985300..25fd78dd7e 100644 --- a/django/contrib/admin/static/admin/js/urlify.js +++ b/django/contrib/admin/static/admin/js/urlify.js @@ -1,165 +1,171 @@ /*global XRegExp*/ -var 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' -}; -var LATIN_SYMBOLS_MAP = { - '©': '(c)' -}; -var 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' -}; -var TURKISH_MAP = { - 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u', - 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G' -}; -var ROMANIAN_MAP = { - 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a', - 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A' -}; -var 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' -}; -var UKRAINIAN_MAP = { - 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i', 'ї': 'yi', - 'ґ': 'g' -}; -var CZECH_MAP = { - 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', - 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', - 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z' -}; -var POLISH_MAP = { - 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', - 'ź': 'z', 'ż': 'z', - 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S', - 'Ź': 'Z', 'Ż': 'Z' -}; -var LATVIAN_MAP = { - 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', - 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z', - 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L', - 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z' -}; -var 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' -}; -var LITHUANIAN_MAP = { - 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u', - 'ū': 'u', 'ž': 'z', - 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U', - 'Ū': 'U', 'Ž': 'Z' -}; -var SERBIAN_MAP = { - 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz', 'đ': 'dj', - 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C', 'Џ': 'Dz', 'Đ': 'Dj' -}; -var AZERBAIJANI_MAP = { - 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', - 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U' -}; +(function() { + 'use strict'; -var ALL_DOWNCODE_MAPS = [ - LATIN_MAP, - LATIN_SYMBOLS_MAP, - GREEK_MAP, - TURKISH_MAP, - ROMANIAN_MAP, - RUSSIAN_MAP, - UKRAINIAN_MAP, - CZECH_MAP, - POLISH_MAP, - LATVIAN_MAP, - ARABIC_MAP, - LITHUANIAN_MAP, - SERBIAN_MAP, - AZERBAIJANI_MAP -]; + var 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' + }; + var LATIN_SYMBOLS_MAP = { + '©': '(c)' + }; + var 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' + }; + var TURKISH_MAP = { + 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u', + 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G' + }; + var ROMANIAN_MAP = { + 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a', + 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A' + }; + var 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' + }; + var UKRAINIAN_MAP = { + 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i', + 'ї': 'yi', 'ґ': 'g' + }; + var CZECH_MAP = { + 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', + 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', + 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z' + }; + var POLISH_MAP = { + 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', + 'ź': 'z', 'ż': 'z', + 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S', + 'Ź': 'Z', 'Ż': 'Z' + }; + var LATVIAN_MAP = { + 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', + 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z', + 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L', + 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z' + }; + var 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' + }; + var LITHUANIAN_MAP = { + 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u', + 'ū': 'u', 'ž': 'z', + 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U', + 'Ū': 'U', 'Ž': 'Z' + }; + var SERBIAN_MAP = { + 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz', + 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C', + 'Џ': 'Dz', 'Đ': 'Dj' + }; + var AZERBAIJANI_MAP = { + 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', + 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U' + }; -var Downcoder = { - 'Initialize': function() { - if (Downcoder.map) { // already made - return; - } - Downcoder.map = {}; - Downcoder.chars = []; - for (var i = 0; i < ALL_DOWNCODE_MAPS.length; i++) { - var lookup = ALL_DOWNCODE_MAPS[i]; - for (var c in lookup) { - if (lookup.hasOwnProperty(c)) { - Downcoder.map[c] = lookup[c]; + var ALL_DOWNCODE_MAPS = [ + LATIN_MAP, + LATIN_SYMBOLS_MAP, + GREEK_MAP, + TURKISH_MAP, + ROMANIAN_MAP, + RUSSIAN_MAP, + UKRAINIAN_MAP, + CZECH_MAP, + POLISH_MAP, + LATVIAN_MAP, + ARABIC_MAP, + LITHUANIAN_MAP, + SERBIAN_MAP, + AZERBAIJANI_MAP + ]; + + var Downcoder = { + 'Initialize': function() { + if (Downcoder.map) { // already made + return; + } + Downcoder.map = {}; + Downcoder.chars = []; + for (var i = 0; i < ALL_DOWNCODE_MAPS.length; i++) { + var lookup = ALL_DOWNCODE_MAPS[i]; + for (var c in lookup) { + if (lookup.hasOwnProperty(c)) { + Downcoder.map[c] = lookup[c]; + } } } - } - for (var k in Downcoder.map) { - if (Downcoder.map.hasOwnProperty(k)) { - Downcoder.chars.push(k); + for (var k in Downcoder.map) { + if (Downcoder.map.hasOwnProperty(k)) { + Downcoder.chars.push(k); + } } + Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g'); } - Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g'); - } -}; + }; -function downcode(slug) { - Downcoder.Initialize(); - return slug.replace(Downcoder.regex, function(m) { - return Downcoder.map[m]; - }); -} + function downcode(slug) { + Downcoder.Initialize(); + 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" - // remove all these words from the string before urlifying - if (!allowUnicode) { - s = downcode(s); + function URLify(s, num_chars, allowUnicode) { + // changes, e.g., "Petty theft" to "petty_theft" + // remove all these words from the string before urlifying + if (!allowUnicode) { + s = downcode(s); + } + var removelist = [ + "a", "an", "as", "at", "before", "but", "by", "for", "from", "is", + "in", "into", "like", "of", "off", "on", "onto", "per", "since", + "than", "the", "this", "that", "to", "up", "via", "with" + ]; + var r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi'); + s = s.replace(r, ''); + // if downcode doesn't hit, the char will be stripped here + 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'), ''); + } else { + 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.toLowerCase(); // convert to lowercase + return s.substring(0, num_chars);// trim to first num_chars chars } - var removelist = [ - "a", "an", "as", "at", "before", "but", "by", "for", "from", "is", - "in", "into", "like", "of", "off", "on", "onto", "per", "since", - "than", "the", "this", "that", "to", "up", "via", "with" - ]; - var r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi'); - s = s.replace(r, ''); - // if downcode doesn't hit, the char will be stripped here - 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'), ''); - } else { - 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.toLowerCase(); // convert to lowercase - return s.substring(0, num_chars);// trim to first num_chars chars -} + window.URLify = URLify; +})(); diff --git a/django/contrib/gis/static/gis/js/OLMapWidget.js b/django/contrib/gis/static/gis/js/OLMapWidget.js index da347d77b3..40dd5890ce 100644 --- a/django/contrib/gis/static/gis/js/OLMapWidget.js +++ b/django/contrib/gis/static/gis/js/OLMapWidget.js @@ -1,5 +1,6 @@ /*global OpenLayers*/ (function() { + 'use strict'; /** * Transforms an array of features to a single feature with the merged * geometry of geom_type