Commit 2f868e5e by Gregory Martin Committed by GitHub

Merge pull request #13733 from edx/yro_localized-datetime

Set up DateUtil factory, modify requests to handle moment-timezones, moment-with-locales.
parents 252880e5 4ddda443
......@@ -50,8 +50,8 @@
'jquery.immediateDescendents': 'coffee/src/jquery.immediateDescendents',
'datepair': 'js/vendor/timepicker/datepair',
'date': 'js/vendor/date',
'moment': 'js/vendor/moment.min',
'moment-with-locales': 'js/vendor/moment-with-locales.min',
moment: 'common/js/vendor/moment-with-locales',
'moment-timezone': 'common/js/vendor/moment-timezone-with-data',
'text': 'js/vendor/requirejs/text',
'underscore': 'common/js/vendor/underscore',
'underscore.string': 'common/js/vendor/underscore.string',
......
......@@ -32,8 +32,7 @@
'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate',
'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair',
'date': 'xmodule_js/common_static/js/vendor/date',
'moment': 'xmodule_js/common_static/js/vendor/moment.min',
'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min',
moment: 'common/js/vendor/moment-with-locales',
'text': 'xmodule_js/common_static/js/vendor/requirejs/text',
'underscore': 'common/js/vendor/underscore',
'underscore.string': 'common/js/vendor/underscore.string',
......
......@@ -32,7 +32,7 @@ var options = {
{pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true},
{pattern: 'common_static/js/vendor/jquery.ui.draggable.js', included: true},
{pattern: 'common_static/js/vendor/json2.js', included: true},
{pattern: 'common_static/js/vendor/moment.min.js', included: true},
{pattern: 'common_static/js/vendor/moment-with-locales.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js', included: true},
{pattern: 'common_static/js/src/accessibility_tools.js', included: true},
......
......@@ -34,7 +34,7 @@
requirejs.config({
baseUrl: '/base/',
paths: {
'moment': 'common_static/js/vendor/moment.min',
moment: 'common_static/js/vendor/moment-with-locales',
'draggabilly': 'common_static/js/vendor/draggabilly',
'edx-ui-toolkit': 'common_static/edx-ui-toolkit'
},
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -919,7 +919,7 @@ class ViewsTestCase(ModuleStoreTestCase):
)
# removes newlines and whitespace from the returned view string
view = ''.join(render_accordion(request, self.course, table_of_contents['chapters']).split())
view = ''.join(render_accordion(request, self.course, table_of_contents['chapters'], 'en').split())
# the course id unicode is re-encoded here because the quote function does not accept unicode
course_id = quote(unicode(self.course.id).encode("utf-8"))
......
......@@ -398,7 +398,12 @@ class CoursewareIndex(View):
self.section_url_name,
self.field_data_cache,
)
courseware_context['accordion'] = render_accordion(self.request, self.course, table_of_contents['chapters'])
courseware_context['accordion'] = render_accordion(
self.request,
self.course,
table_of_contents['chapters'],
courseware_context['language_preference'],
)
# entrance exam data
if course_has_entrance_exam(self.course):
......@@ -494,7 +499,7 @@ class CoursewareIndex(View):
raise
def render_accordion(request, course, table_of_contents):
def render_accordion(request, course, table_of_contents, language_preference):
"""
Returns the HTML that renders the navigation for the given course.
Expects the table_of_contents to have data on each chapter and section,
......@@ -506,7 +511,9 @@ def render_accordion(request, course, table_of_contents):
('course_id', unicode(course.id)),
('csrf', csrf(request)['csrf_token']),
('due_date_display_format', course.due_date_display_format),
('time_zone', get_user_time_zone(request.user).zone),
('time_zone', request.user.preferences.model.get_value(request.user, "time_zone", None)),
('language', language_preference),
] + TEMPLATE_IMPORTS.items()
)
return render_to_string('courseware/accordion.html', context)
......
define(['jquery',
'underscore',
'moment-with-locales',
'moment',
'teams/js/views/team_card',
'teams/js/models/team'],
function($, _, moment, TeamCardView, Team) {
......
......@@ -5,7 +5,7 @@
'backbone',
'underscore',
'gettext',
'moment-with-locales',
'moment',
'js/components/card/views/card',
'teams/js/views/team_utils',
'text!teams/templates/team-membership-details.underscore',
......
......@@ -1568,7 +1568,7 @@ PIPELINE_JS = {
[
'js/sticky_filter.js',
'js/query-params.js',
'js/vendor/moment-with-locales.min.js',
'common/js/vendor/moment-with-locales.js',
]
),
'output_filename': 'js/lms-application.js',
......@@ -1716,7 +1716,7 @@ REQUIRE_ENVIRONMENT = "node"
REQUIRE_JS_PATH_OVERRIDES = {
'js/bookmarks/views/bookmark_button': 'js/bookmarks/views/bookmark_button.js',
'js/views/message_banner': 'js/views/message_banner.js',
'moment': 'js/vendor/moment-with-locales.min.js',
'moment': 'common/js/vendor/moment-with-locales.js',
'js/courseware/course_home_events': 'js/courseware/course_home_events.js',
'js/courseware/accordion_events': 'js/courseware/accordion_events.js',
'js/courseware/link_clicked_events': 'js/courseware/link_clicked_events.js',
......
/**
*
* A helper function to utilize DateUtils quickly in display templates.
*
* @param: {string} data-datetime A pre-localized datetime string, assumed to be in UTC.
* @param: {string} lang The user's preferred language.
* @param: {string} data-timezone (optional) A user-set timezone preference.
* @param: {object} data-format (optional) a format constant as defined in DataUtil.dateFormatEnum.
* @param: {string} data-string (optional) a string for parsing through StringUtils after localizing
* datetime
*
* @return: {string} a user-time, localized, formatted datetime string
*
*/
(function(define) {
'use strict';
define([
'jquery',
'edx-ui-toolkit/js/utils/date-utils',
'edx-ui-toolkit/js/utils/string-utils'
], function($, DateUtils, StringUtils) {
var DateUtilFactory;
var localizedTime;
var stringHandler;
var displayDatetime;
var isValid;
var transform;
transform = function(iterationKey) {
var context;
$(iterationKey).each(function() {
if (isValid($(this).data('datetime'))) {
context = {
datetime: $(this).data('datetime'),
timezone: $(this).data('timezone'),
language: $(this).attr('lang'),
format: $(this).data('format')
};
displayDatetime = stringHandler(
localizedTime(context),
$(this).data('string'),
$(this).data('datetoken')
);
$(this).text(displayDatetime);
}
});
};
localizedTime = function(context) {
return DateUtils.localize(context);
};
stringHandler = function(localTimeString, containerString, token) {
var returnString;
var interpolateDict = {};
var dateToken;
if (isValid(token)) {
dateToken = token;
} else {
dateToken = 'date';
}
interpolateDict[dateToken] = localTimeString;
if (isValid(containerString)) {
returnString = StringUtils.interpolate(
containerString,
interpolateDict
);
} else {
returnString = localTimeString;
}
return returnString;
};
isValid = function(candidateVariable) {
return candidateVariable !== undefined
&& candidateVariable !== ''
&& candidateVariable !== 'Invalid date'
&& candidateVariable !== 'None';
};
DateUtilFactory = {
transform: transform,
stringHandler: stringHandler
};
return DateUtilFactory;
});
}).call(this, define || RequireJS.define);
define(['../dateutil_factory.js'], function(DateUtilIterator) {
'use strict';
describe('DateUtilFactory', function() {
beforeEach(function() {
setFixtures('<div class="test"></div>');
});
describe('stringHandler', function() {
it('returns a complete string', function() {
var localTimeString = 'RANDOM_STRING';
var containerString = 'RANDOM_STRING_TWO {random_token}';
var dateToken = 'random_token';
var answer = 'RANDOM_STRING_TWO RANDOM_STRING';
expect(DateUtilIterator.stringHandler(localTimeString, containerString, dateToken)).toEqual(answer);
});
});
describe('transform', function() {
var $form;
it('localizes some times', function() {
/* we have to generate a fake span and then test the resultant texts */
var iterationKey = '.localized-datetime';
var testLangs = {
en: 'Due Oct 14, 2016 08:00 UTC',
ru: 'Due 14 окт. 2016 г. 08:00 UTC',
ar: 'Due ١٤ تشرين الأول أكتوبر ٢٠١٦ ٠٨:٠٠ UTC',
fr: 'Due 14 oct. 2016 08:00 UTC'
};
$form = $(
'<span class="subtitle-name localized-datetime" ' +
'data-timezone="UTC" ' +
'data-datetime="2016-10-14 08:00:00+00:00" ' +
'data-string="Due {date}"></span>'
);
Object.keys(testLangs).forEach(function(key) {
$form.attr('lang', String(key));
$(document.body).append($form);
DateUtilIterator.transform(iterationKey);
expect($form.text()).toEqual(testLangs[key]);
$form.remove();
});
$form = null;
});
});
});
});
......@@ -57,8 +57,8 @@
paths: {
'annotator_1.2.9': 'js/vendor/edxnotes/annotator-full.min',
'date': 'js/vendor/date',
'moment': 'js/vendor/moment.min',
'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min',
moment: 'common/js/vendor/moment-with-locales',
'moment-timezone': 'common/js/vendor/moment-timezone-with-data',
'text': 'js/vendor/requirejs/text',
'logger': 'js/src/logger',
'backbone': 'common/js/vendor/backbone',
......@@ -212,8 +212,9 @@
'moment': {
exports: 'moment'
},
'moment-with-locales': {
exports: 'moment'
'moment-timezone': {
exports: 'moment',
deps: ['moment']
},
// Because Draggabilly is being used by video code, the namespaced version of
// require is not being recognized. Therefore the library is being added to the
......
......@@ -32,8 +32,8 @@
'jquery.url': 'xmodule_js/common_static/js/vendor/url.min',
'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair',
'date': 'xmodule_js/common_static/js/vendor/date',
'moment': 'xmodule_js/common_static/js/vendor/moment.min',
'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min',
moment: 'common/js/vendor/moment-with-locales',
'moment-timezone': 'common/js/vendor/moment-timezone-with-data',
'text': 'xmodule_js/common_static/js/vendor/requirejs/text',
'underscore': 'common/js/vendor/underscore',
'underscore.string': 'common/js/vendor/underscore.string',
......@@ -731,6 +731,7 @@
'js/spec/learner_dashboard/course_card_view_spec.js',
'js/spec/learner_dashboard/course_enroll_view_spec.js',
'js/spec/markdown_editor_spec.js',
'js/spec/dateutil_factory_spec.js',
'js/spec/navigation_spec.js',
'js/spec/search/search_spec.js',
'js/spec/shoppingcart/shoppingcart_spec.js',
......
......@@ -34,7 +34,7 @@
requirejs.config({
baseUrl: '/base/',
paths: {
'moment': 'xmodule_js/common_static/js/vendor/moment.min',
moment: 'xmodule_js/common_static/js/vendor/moment-with-locales',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
'edx-ui-toolkit': 'edx-ui-toolkit'
},
......
......@@ -6,7 +6,7 @@
"backbone-validation": "~0.11.5",
"coffee-script": "1.6.1",
"edx-pattern-library": "0.16.6",
"edx-ui-toolkit": "1.4.1",
"edx-ui-toolkit": "1.5.0",
"jquery": "~2.2.0",
"jquery-migrate": "^1.4.1",
"jquery.scrollto": "~2.1.2",
......
......@@ -55,6 +55,8 @@ NPM_INSTALLED_LIBRARIES = [
'backbone/backbone.js',
'edx-ui-toolkit/node_modules/backbone.paginator/lib/backbone.paginator.js',
'backbone-validation/dist/backbone-validation-min.js',
'edx-ui-toolkit/node_modules/moment-timezone/builds/moment-timezone-with-data.js',
'edx-ui-toolkit/node_modules/moment/min/moment-with-locales.js',
]
# Directory to install static vendor files
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment