e8f95558d76877441dea0418256cab1f2d9cc93a
[Packages/TYPO3.CMS.git] / typo3 / sysext / lang / Resources / Public / JavaScript / LanguageModule.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Lang/LanguageModule
16 * Language module class
17 */
18 define(['jquery',
19 'moment',
20 'TYPO3/CMS/Backend/Icons',
21 'TYPO3/CMS/Backend/Notification',
22 'datatables',
23 'TYPO3/CMS/Backend/jquery.clearable'
24 ], function($, moment, Icons, Notification) {
25 'use strict';
26
27 /**
28 *
29 * @type {{me: *, context: null, table: null, topMenu: null, currentRequest: null, settings: {}, icons: {}, labels: {}, identifiers: {searchField: string, topMenu: string, activateIcon: string, deactivateIcon: string, downloadIcon: string, loadingIcon: string, completeIcon: string, progressBar: string, progressBarText: string, progressBarInner: string, lastUpdate: string, languagePrefix: string, extensionPrefix: string}, classes: {enabled: string, disabled: string, processing: string, complete: string, extension: string, actions: string, progressBar: string, loading: string, lastUpdate: string}}}
30 * @exports TYPO3/CMS/Lang/LanguageModule
31 */
32 var LanguageModule = {
33 me: this,
34 context: null,
35 table: null,
36 topMenu: null,
37 currentRequest: null,
38 userAbortRequest: false,
39 settings: {},
40 icons: {},
41 labels: {},
42 buttons: {
43 update: null,
44 cancel: null
45 },
46 identifiers: {
47 searchField: '.t3js-language-searchfield',
48 topMenu: 'div.t3js-module-docheader',
49 activateIcon: 'span.activateIcon',
50 deactivateIcon: 'span.deactivateIcon',
51 downloadIcon: 'span.downloadIcon',
52 removeIcon: 'span.removeIcon',
53 loadingIcon: 'span.loadingIcon',
54 completeIcon: 'span.completeIcon',
55 progressBar: 'div.progressBar',
56 progressBarText: 'div.progress-text',
57 progressBarInner: 'div.progress-bar',
58 lastUpdate: 'td.lastUpdate',
59 languagePrefix: 'language-',
60 extensionPrefix: 'extension-'
61 },
62 classes: {
63 enabled: 'enabled',
64 disabled: 'disabled',
65 processing: 'processing',
66 complete: 'complete',
67 extension: 'extensionName',
68 actions: 'actions',
69 progressBar: 'progressBar',
70 loading: 'loading',
71 lastUpdate: 'lastUpdate'
72 }
73 };
74
75 /**
76 * Initialize language table
77 *
78 * @param {HTMLElement} contextElement
79 * @param {HTMLElement} tableElement
80 */
81 LanguageModule.initializeLanguageTable = function(contextElement, tableElement) {
82 LanguageModule.context = $(contextElement);
83 LanguageModule.topMenu = $(LanguageModule.identifiers.topMenu);
84 LanguageModule.settings = LanguageModule.context.data();
85 LanguageModule.icons = LanguageModule.buildIcons();
86 LanguageModule.labels = LanguageModule.buildLabels();
87 LanguageModule.table = LanguageModule.buildLanguageTable(tableElement);
88 LanguageModule.initializeSearchField();
89 LanguageModule.initializeEventHandler();
90 LanguageModule.initializeButtons();
91 };
92
93 /**
94 * Initialize translation table
95 *
96 * @param {HTMLElement} contextElement
97 * @param {HTMLElement} tableElement
98 */
99 LanguageModule.initializeTranslationTable = function(contextElement, tableElement) {
100 LanguageModule.context = $(contextElement);
101 LanguageModule.topMenu = $(LanguageModule.identifiers.topMenu);
102 LanguageModule.settings = LanguageModule.context.data();
103 LanguageModule.icons = LanguageModule.buildIcons();
104 LanguageModule.labels = LanguageModule.buildLabels();
105 LanguageModule.table = LanguageModule.buildTranslationTable(tableElement);
106 LanguageModule.initializeSearchField();
107 LanguageModule.initializeEventHandler();
108 };
109
110 /**
111 * Activate a language
112 *
113 * @param {HTMLElement} triggerElement
114 * @param {Object} parameters
115 */
116 LanguageModule.activateLanguageAction = function(triggerElement, parameters) {
117 var $row = $(triggerElement).closest('tr'),
118 locale = $row.data('locale');
119
120 if ($row.hasClass(LanguageModule.classes.processing)) {
121 LanguageModule.abortAjaxRequest();
122 }
123 LanguageModule.executeAjaxRequest(LanguageModule.settings.activateLanguageUri, {locale: locale}, function(response, status) {
124 if (status === 'success' && response.success) {
125 $row.removeClass(LanguageModule.classes.disabled).addClass(LanguageModule.classes.enabled);
126 LanguageModule.displaySuccess(LanguageModule.labels.languageActivated);
127 } else {
128 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
129 }
130 });
131 };
132
133 /**
134 * Deactivate a language
135 *
136 * @param {HTMLElement} triggerElement
137 * @param {Object} parameters
138 */
139 LanguageModule.deactivateLanguageAction = function(triggerElement, parameters) {
140 var $row = $(triggerElement).closest('tr'),
141 locale = $row.data('locale');
142
143 if ($row.hasClass(LanguageModule.classes.processing)) {
144 LanguageModule.abortAjaxRequest();
145 }
146 LanguageModule.executeAjaxRequest(LanguageModule.settings.deactivateLanguageUri, {locale: locale}, function(response, status) {
147 if (status === 'success' && response.success) {
148 $row.removeClass(LanguageModule.classes.enabled).removeClass(LanguageModule.classes.complete).addClass(LanguageModule.classes.disabled);
149 LanguageModule.displaySuccess(LanguageModule.labels.languageDeactivated);
150 } else {
151 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
152 }
153 });
154 };
155
156 /**
157 * Remove a language
158 *
159 * @param {HTMLElement} triggerElement
160 * @param {Object} parameters
161 */
162 LanguageModule.removeLanguageAction = function(triggerElement, parameters) {
163 var $row = $(triggerElement).closest('tr'),
164 locale = $row.data('locale'),
165 $lastUpdate = $(LanguageModule.identifiers.lastUpdate, $row);
166
167 if ($row.hasClass(LanguageModule.classes.processing)) {
168 LanguageModule.abortAjaxRequest();
169 }
170 LanguageModule.executeAjaxRequest(LanguageModule.settings.removeLanguageUri, {locale: locale}, function(response, status) {
171 if (status === 'success' && response.success) {
172 $row.removeClass(LanguageModule.classes.enabled).removeClass(LanguageModule.classes.complete).addClass(LanguageModule.classes.disabled);
173 $lastUpdate.html('');
174 LanguageModule.displaySuccess(LanguageModule.labels.languageRemoved);
175 } else {
176 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
177 }
178 });
179 };
180
181 /**
182 * Update a language
183 *
184 * @param {HTMLElement} triggerElement
185 * @param {Object} parameters
186 */
187 LanguageModule.updateLanguageAction = function(triggerElement, parameters) {
188 var $row = $(triggerElement).closest('tr'),
189 locale = $row.data('locale'),
190 $progressBar = $(LanguageModule.identifiers.progressBar, $row),
191 $lastUpdate = $(LanguageModule.identifiers.lastUpdate, $row);
192
193 $row.addClass(LanguageModule.classes.processing);
194 LanguageModule.loadTranslationsByLocale(locale, function(status, data, response) {
195 if (status === 'success') {
196 LanguageModule.setProgress($progressBar, 100);
197 LanguageModule.displaySuccess(LanguageModule.labels.updateComplete);
198 $row.removeClass(LanguageModule.classes.processing).addClass(LanguageModule.classes.complete);
199 $lastUpdate.html(LanguageModule.formatDate(response.timestamp));
200 } else if (status === 'progress') {
201 LanguageModule.setProgress($progressBar, parseFloat(response.progress));
202 } else if (status === 'error') {
203 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
204 }
205 });
206 };
207
208 /**
209 * Update all active languages
210 *
211 * @param {HTMLElement} triggerElement
212 * @param {Object} parameters
213 */
214 LanguageModule.updateActiveLanguagesAction = function(triggerElement, parameters) {
215 var $activeRows = $('tr.' + LanguageModule.classes.enabled, LanguageModule.table.table().container());
216 if ($activeRows.length > 0) {
217 LanguageModule.updateButtonStatus('update');
218 LanguageModule.topMenu.addClass(LanguageModule.classes.processing);
219 $activeRows.addClass(LanguageModule.classes.processing);
220 LanguageModule.loadTranslationsByRows($activeRows, function(row, status, data, response) {
221 var $progressBar = $(LanguageModule.identifiers.progressBar, row),
222 $lastUpdate = $(LanguageModule.identifiers.lastUpdate, row);
223
224 if (status === 'success') {
225 LanguageModule.setProgress($progressBar, 100);
226 row.removeClass(LanguageModule.classes.processing).addClass(LanguageModule.classes.complete);
227 $lastUpdate.html(LanguageModule.formatDate(response.timestamp));
228 } else if (status === 'progress') {
229 LanguageModule.setProgress($progressBar, parseFloat(response.progress));
230 } else if (status === 'error') {
231 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
232 } else if (status === 'finished') {
233 LanguageModule.updateButtonStatus('cancel');
234 LanguageModule.displaySuccess(LanguageModule.labels.updateComplete);
235 LanguageModule.topMenu.removeClass(LanguageModule.classes.processing);
236 }
237 });
238 } else {
239 LanguageModule.displayError(LanguageModule.labels.noLanguageActivated);
240 }
241 };
242
243 /**
244 * Cancel language update
245 *
246 * @param {HTMLElement} triggerElement
247 * @param {Object} parameters
248 */
249 LanguageModule.cancelLanguageUpdateAction = function(triggerElement, parameters) {
250 var $activeRows = $('tr.' + LanguageModule.classes.enabled, LanguageModule.table.table().container());
251 LanguageModule.updateButtonStatus('cancel');
252 LanguageModule.topMenu.removeClass(LanguageModule.classes.processing);
253 $activeRows.removeClass(LanguageModule.classes.processing);
254 LanguageModule.abortAjaxRequest();
255 };
256
257 /**
258 * Update an extension translation
259 *
260 * @param {HTMLElement} triggerElement
261 * @param {Object} parameters
262 */
263 LanguageModule.updateTranslationAction = function(triggerElement, parameters) {
264 var $row = $(triggerElement).closest('tr'),
265 $cell = $(triggerElement).closest('td'),
266 extension = $row.data('extension'),
267 locale = LanguageModule.table.cell($cell).data().locale;
268
269 $cell.addClass(LanguageModule.classes.processing);
270 LanguageModule.loadTranslationByExtensionAndLocale(extension, locale, function(status, data, response) {
271 if (status === 'success') {
272 LanguageModule.displaySuccess(LanguageModule.labels.updateComplete);
273 $cell.removeClass(LanguageModule.classes.processing).addClass(LanguageModule.classes.complete);
274 } else if (status === 'error') {
275 LanguageModule.displayError(LanguageModule.labels.errorOccurred);
276 }
277 });
278 };
279
280 /**
281 * Build icons
282 *
283 * @returns {{activate: (*|jQuery), deactivate: (*|jQuery), download: (*|jQuery), loading: (*|jQuery), complete: (*|jQuery), progressBar: (*|jQuery)}}
284 */
285 LanguageModule.buildIcons = function() {
286 return {
287 activate: $(LanguageModule.identifiers.activateIcon, LanguageModule.context).html(),
288 deactivate: $(LanguageModule.identifiers.deactivateIcon, LanguageModule.context).html(),
289 download: $(LanguageModule.identifiers.downloadIcon, LanguageModule.context).html(),
290 remove: $(LanguageModule.identifiers.removeIcon, LanguageModule.context).html(),
291 loading: $(LanguageModule.identifiers.loadingIcon, LanguageModule.context).html(),
292 complete: $(LanguageModule.identifiers.completeIcon, LanguageModule.context).html(),
293 progressBar: $(LanguageModule.identifiers.progressBar, LanguageModule.context).html()
294 }
295 };
296
297 /**
298 * Build labels
299 *
300 * @returns {{processing: *, search: *, loadingRecords: *, zeroRecords: *, emptyTable: *, dateFormat: *, errorHeader: *, infoHeader: *, successHeader: *, languageActivated: *, errorOccurred: *, languageDeactivated: *, languageRemoved: *, updateComplete: *}}
301 */
302 LanguageModule.buildLabels = function() {
303 return {
304 processing: TYPO3.lang['table.processing'],
305 search: TYPO3.lang['table.search'],
306 loadingRecords: TYPO3.lang['table.loadingRecords'],
307 zeroRecords: TYPO3.lang['table.zeroRecords'],
308 emptyTable: TYPO3.lang['table.emptyTable'],
309 dateFormat: TYPO3.lang['table.dateFormat'],
310 errorHeader: TYPO3.lang['flashmessage.error'],
311 infoHeader: TYPO3.lang['flashmessage.information'],
312 successHeader: TYPO3.lang['flashmessage.success'],
313 languageActivated: TYPO3.lang['flashmessage.languageActivated'],
314 errorOccurred: TYPO3.lang['flashmessage.errorOccurred'],
315 languageDeactivated: TYPO3.lang['flashmessage.languageDeactivated'],
316 languageRemoved: TYPO3.lang['flashmessage.languageRemoved'],
317 noLanguageActivated: TYPO3.lang['flashmessage.noLanguageActivated'],
318 updateComplete: TYPO3.lang['flashmessage.updateComplete'],
319 canceled: TYPO3.lang['flashmessage.canceled']
320 }
321 };
322
323 /**
324 * Build language table
325 *
326 * @param {HTMLElement} tableElement
327 * @returns {Object}
328 */
329 LanguageModule.buildLanguageTable = function(tableElement) {
330 return $(tableElement).DataTable({
331 dom: 'lrtip',
332 serverSide: false,
333 stateSave: true,
334 paging: false,
335 info: false,
336 ordering: true,
337 language: LanguageModule.labels,
338 order: [[1, 'asc']]
339 });
340 };
341
342 /**
343 * Initialize translation table
344 *
345 * @param {HTMLElement} tableElement
346 * @returns {Object}
347 */
348 LanguageModule.buildTranslationTable = function(tableElement) {
349 var languageCount = $(tableElement).data('languageCount'),
350 columns = [
351 {
352 render: function(data, type, row) {
353 return LanguageModule.buildImage(data.icon, data.title, data.title, data.width, data.height);
354 },
355 width: '20px',
356 orderable: false,
357 targets: 0
358 }, {
359 render: function(data, type, row) {
360 return data.title;
361 },
362 className: LanguageModule.classes.extension,
363 targets: 1
364 }
365 ];
366
367 for (var i = 0; i < languageCount; i++) {
368 columns.push({
369 render: function(data, type, row) {
370 var links = [
371 LanguageModule.buildActionLink('updateTranslation', data, LanguageModule.icons.download),
372 LanguageModule.buildActionLink('removeTranslation', data, LanguageModule.icons.remove),
373 LanguageModule.buildLoadingIndicator(),
374 LanguageModule.buildCompleteIndicator()
375 ];
376 return links.join('');
377 },
378 className: 'dt-center',
379 targets: (i + 2)
380 });
381 }
382
383 return $(tableElement).DataTable({
384 dom: 'lrtip',
385 serverSide: false,
386 stateSave: true,
387 paging: false,
388 info: false,
389 ordering: true,
390 language: LanguageModule.labels,
391 ajax: LanguageModule.settings.listTranslationsUri,
392 order: [[1, 'asc']],
393 columnDefs: columns,
394 createdRow: function (row, data, index) {
395 var $row = $(row);
396 $row.attr('id', LanguageModule.identifiers.extensionPrefix + data[1].key);
397 $row.attr('data-extension', data[1].key);
398 }
399 });
400 };
401
402 /**
403 * Initialize search field
404 */
405 LanguageModule.initializeSearchField = function() {
406 var getVars = LanguageModule.getUrlVars();
407 var currentSearch = (getVars['search'] ? getVars['search'] : LanguageModule.table.search());
408 $(LanguageModule.identifiers.searchField)
409 .val(currentSearch)
410 .on('input', function() {
411 LanguageModule.table.search($(this).val()).draw();
412 })
413 .clearable({
414 onClear: function() {
415 if (LanguageModule.table !== null) {
416 LanguageModule.table.search('').draw();
417 }
418 }
419 })
420 .parents('form').on('submit', function() {
421 return false;
422 });
423 };
424
425 /**
426 * Initialize event handler, redirect clicks to controller actions
427 */
428 LanguageModule.initializeEventHandler = function() {
429 $(document).on('click', function(event) {
430 var $element = $(event.target);
431 var $parent = $element.closest('[data-action]');
432
433 if ($element.data('action') !== undefined) {
434 LanguageModule.handleActionEvent($element, event);
435 } else if ($parent.data('action') !== undefined) {
436 LanguageModule.handleActionEvent($parent, event);
437 }
438 });
439 };
440
441 /**
442 * Initialize buttons
443 */
444 LanguageModule.initializeButtons = function() {
445 LanguageModule.buttons.update = LanguageModule.topMenu.find('.t3js-button-update');
446 LanguageModule.buttons.cancel = LanguageModule.topMenu.find('.t3js-button-cancel');
447 };
448
449 /**
450 * Update buttons in top menu
451 *
452 * @param {String} action
453 */
454 LanguageModule.updateButtonStatus = function(action) {
455 switch (action) {
456 case 'update':
457 LanguageModule.buttons.update.data('action', 'cancelLanguageUpdate');
458 LanguageModule.buttons.cancel.removeClass('disabled');
459 Icons.getIcon('spinner-circle-dark', Icons.sizes.small).done(function(spinner) {
460 LanguageModule.buttons.update.find('span.icon').replaceWith(spinner);
461 });
462 break;
463 case 'cancel':
464 LanguageModule.buttons.update.data('action', 'updateActiveLanguages');
465 LanguageModule.buttons.cancel.addClass('disabled');
466 Icons.getIcon('actions-system-extension-download', Icons.sizes.small).done(function(download) {
467 LanguageModule.buttons.update.find('span.icon').replaceWith(download);
468 });
469 break;
470 }
471 };
472
473 /**
474 * Handler for "action" events
475 *
476 * @param {Object} element
477 * @param {Event} event
478 */
479 LanguageModule.handleActionEvent = function(element, event) {
480 event.preventDefault();
481 var data = element.data();
482 var actionName = data.action + 'Action';
483 if (actionName in LanguageModule) {
484 LanguageModule[actionName](element, data);
485 }
486 };
487
488 /**
489 * Load translations for all extensions by given locale
490 *
491 * @param {String} locale
492 * @param {function} callback
493 * @param {Number} counter
494 */
495 LanguageModule.loadTranslationsByLocale = function(locale, callback, counter) {
496 counter = counter || 0;
497 var data = {locale: locale, count: counter};
498 LanguageModule.executeAjaxRequest(LanguageModule.settings.updateLanguageUri, data, function(response, status) {
499 if (status === 'success' && response.success) {
500 if (parseFloat(response.progress) < 100) {
501 callback('progress', data, response);
502 counter++;
503 LanguageModule.loadTranslationsByLocale(locale, callback, counter);
504 } else {
505 callback('success', data, response);
506 }
507 } else {
508 callback('error', data, response);
509 }
510 });
511 };
512
513 /**
514 * Load translations for all extensions by given rows
515 *
516 * @param {Object} rows
517 * @param {function} callback
518 */
519 LanguageModule.loadTranslationsByRows = function(rows, callback) {
520 if (rows) {
521 rows = $(rows).toArray();
522 var $row = $(rows.shift()),
523 locale = $row.data('locale');
524
525 LanguageModule.loadTranslationsByLocale(locale, function(status, data, response) {
526 callback($row, status, data, response);
527 if (status === 'success') {
528 if (rows.length) {
529 LanguageModule.loadTranslationsByRows(rows, callback);
530 } else {
531 callback($row, 'finished', data, response);
532 }
533 }
534 });
535 }
536 };
537
538 /**
539 * Load translation for one extension by given locale
540 *
541 * @param {String} extension
542 * @param {String} locale
543 * @param {function} callback
544 */
545 LanguageModule.loadTranslationByExtensionAndLocale = function(extension, locale, callback) {
546 var data = {extension: extension, locale: locale};
547 LanguageModule.executeAjaxRequest(LanguageModule.settings.updateTranslationUri, data, function(response, status) {
548 if (status === 'success' && response.success) {
549 callback('success', data, response);
550 } else {
551 callback('error', data, response);
552 }
553 });
554 };
555
556 /**
557 * Execute AJAX request
558 *
559 * @param {String} uri
560 * @param {Object} data
561 * @param {function} callback
562 */
563 LanguageModule.executeAjaxRequest = function(uri, data, callback) {
564 var newData = {};
565 newData[LanguageModule.settings.prefix] = {
566 data: data
567 };
568 LanguageModule.currentRequest = $.ajax({
569 type: 'POST',
570 cache: false,
571 url: uri,
572 data: newData,
573 dataType: 'json',
574 success: function(response, status) {
575 if (typeof callback === 'function') {
576 callback(response, status, '');
577 }
578 },
579 error: function(response, status, error) {
580 if (typeof callback === 'function') {
581 callback(response, status, error);
582 }
583 }
584 });
585 };
586
587 /**
588 * Abort current AJAX request
589 */
590 LanguageModule.abortAjaxRequest = function() {
591 if (LanguageModule.currentRequest) {
592 LanguageModule.userAbortRequest = true;
593 LanguageModule.currentRequest.abort();
594 }
595 };
596
597 /**
598 * Display error flash message
599 *
600 * @param {String} label
601 */
602 LanguageModule.displayError = function(label) {
603 if (LanguageModule.userAbortRequest) {
604 LanguageModule.displaySuccess(LanguageModule.labels.canceled);
605 } else if (typeof label === 'string' && label !== '') {
606 Notification.error(LanguageModule.labels.errorHeader, label);
607 }
608 };
609
610 /**
611 * Display information flash message
612 *
613 * @param {String} label
614 */
615 LanguageModule.displayInformation = function(label) {
616 if (typeof label === 'string' && label !== '') {
617 Notification.info(LanguageModule.labels.infoHeader, label);
618 }
619 };
620
621 /**
622 * Display success flash message
623 *
624 * @param {String} label
625 */
626 LanguageModule.displaySuccess = function(label) {
627 if (typeof label === 'string' && label !== '') {
628 Notification.success(LanguageModule.labels.successHeader, label);
629 }
630 };
631
632 /**
633 * Build action link
634 *
635 * @param {String} action
636 * @param {Object} parameters
637 * @param {String} content
638 * @returns {Object}
639 */
640 LanguageModule.buildActionLink = function(action, parameters, content) {
641 var $link = $('<a>');
642
643 $link.addClass(action + 'Link');
644 $link.attr('data-action', action);
645 for (var name in parameters) {
646 if (parameters.hasOwnProperty(name)) {
647 $link.attr('data-' + name, parameters[name]);
648 }
649 }
650 $link.html(content);
651 return $link.wrap('<span>').parent().html();
652 };
653
654 /**
655 * Build progress bar
656 *
657 * @returns {Object}
658 */
659 LanguageModule.buildProgressBar = function() {
660 var $span = $('<span>');
661 $span.addClass(LanguageModule.classes.progressBar);
662 $span.html(LanguageModule.icons.progressBar);
663 return $span.wrap('<span>').parent().html();
664 };
665
666 /**
667 * Build loading indicator
668 *
669 * @returns {Object}
670 */
671 LanguageModule.buildLoadingIndicator = function() {
672 var $span = $('<span>');
673 $span.addClass(LanguageModule.classes.loading);
674 $span.html(LanguageModule.icons.loading);
675 return $span.wrap('<span>').parent().html();
676 };
677
678 /**
679 * Build complete state indicator
680 *
681 * @returns {Object}
682 */
683 LanguageModule.buildCompleteIndicator = function() {
684 var $span = $('<span>');
685 $span.addClass(LanguageModule.classes.complete);
686 $span.html(LanguageModule.icons.complete);
687 return $span.wrap('<span>').parent().html();
688 };
689
690 /**
691 * Build image
692 *
693 * @param {String} uri
694 * @param {String} alt
695 * @param {String} title
696 * @param {Number} width
697 * @param {Number} heigth
698 * @returns {Object}
699 */
700 LanguageModule.buildImage = function(uri, alt, title, width, heigth) {
701 var $image = $('<img>');
702 $image.attr('src', uri);
703 $image.attr('alt', alt ? alt : '');
704 $image.attr('title', title ? title : '');
705 $image.attr('style', 'width: ' + width + 'px; height: ' + heigth + 'px;');
706 var $span = $('<span>');
707 $span.addClass('typo3-app-icon');
708 $span.attr('style', 'background: none; text-align: center;');
709 $span.html($image);
710 return $span.wrap('<span>').parent().html();
711 };
712
713 /**
714 * Format date
715 *
716 * @param {Number} timestamp
717 * @returns {*}
718 */
719 LanguageModule.formatDate = function(timestamp) {
720 return moment.unix(timestamp).format(LanguageModule.labels.dateFormat);
721 };
722
723 /**
724 * Set progress bar progress
725 *
726 * @param {Object} progressBar
727 * @param {String} progress
728 */
729 LanguageModule.setProgress = function(progressBar, progress) {
730 var $inner = $(LanguageModule.identifiers.progressBarInner, progressBar),
731 $text = $(LanguageModule.identifiers.progressBarText, progressBar);
732 $inner.css({width: progress + '%'});
733 $inner.attr('aria-valuenow', progress);
734 $text.text(Math.round(progress) + '%');
735 };
736
737 /**
738 * Utility method to retrieve query parameters
739 *
740 * @returns {Array}
741 */
742 LanguageModule.getUrlVars = function getUrlVars() {
743 var vars = [], hash;
744 var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
745 for (var i = 0; i < hashes.length; i++) {
746 hash = hashes[i].split('=');
747 vars.push(hash[0]);
748 vars[hash[0]] = hash[1];
749 }
750 return vars;
751 };
752
753 $(function() {
754 if ($('#typo3-language-list').length) {
755 LanguageModule.initializeLanguageTable('div.typo3-module-lang', '#typo3-language-list');
756 } else if ($('#typo3-translation-list').length) {
757 LanguageModule.initializeTranslationTable('div.typo3-module-lang', '#typo3-translation-list');
758 }
759 });
760
761 return LanguageModule;
762 });