Index: l10n_community/editor.css =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/editor.css,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 editor.css --- l10n_community/editor.css 26 Jan 2010 12:39:53 -0000 1.1.2.1 +++ l10n_community/editor.css 8 Feb 2010 16:13:46 -0000 @@ -1,3 +1,5 @@ +/* $Id$ */ + body { font-family:Verdana; font-size:12px; Index: l10n_community/editor.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/editor.js,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 editor.js --- l10n_community/editor.js 26 Jan 2010 12:39:53 -0000 1.1.2.1 +++ l10n_community/editor.js 8 Feb 2010 16:13:46 -0000 @@ -1,6 +1,16 @@ +/* $Id$ */ -(function ($) { - encode = function (str) { +/** + * @file + * Translation editor behaviors. + */ + +(function($) { + + /** + * Simple string encoding/escaping for proper HTML output. + */ + encode = function(str) { str = String(str); var replace = { '&': '&', '<': '<', '>': '>' }; for (var character in replace) { @@ -10,46 +20,55 @@ return str; }; + // Add behaviors to placeholders so that they highlight the corrsponding + // placeholder(s) with the same name on the same table row. $('em.l10n-placeholder') - .live('mouseover', function () { + .live('mouseover', function() { $(this).closest('tr').find('.l10n-placeholder:contains("' + $(this).text() + '")').addClass('highlight'); }) - .live('mouseout', function () { + .live('mouseout', function() { $('.l10n-placeholder.highlight').removeClass('highlight'); }); $(function () { - $('.l10n-more').click(function () { + + // Replace "More information" link with AJAX output. + $('.l10n-more').click(function() { $(this) .addClass('loading') .parent().load(this.href); return false; }); - var markup = function (string) { - // Highlight placeholders. + var markup = function(string) { + // Highlight placeholders with the l10n-placeholder class. string = string.replace(/([!@%]|<(ins|del)>[!@%]<\/(ins|del)>)(\w+|<(ins|del)>\w+<\/(ins|del)>)/g, '$&'); // Wrap HTML tags in tags. - string = string.replace(/(<.+?(>|$))/g, function (str) { + string = string.replace(/(<.+?(>|$))/g, function(str) { return '' + str.replace(/<[^>]+>/g, '$&') + ''; }); string = string.replace(/\\[^<]/g, '$&'); + + // Add markers for newlines. string = string.replace(/\n/g, '$&'); + return string; }; - $('td.translation').parent().each(function () { + $('td.translation').parent().each(function() { var all = $('li.translation', this); var strings = all.find('.l10n-string > span'); var source = $('td.source', this); - source.find('.l10n-string span').each(function () { + // Add special tags to the source markup cells. + source.find('.l10n-string span').each(function() { $(this).html(markup($(this).html())); }); - strings.each(function () { + // Initialize data for the worddiff tool. + strings.each(function() { var orig = $(this).html(), markedUp = markup(orig); $(this) .html(markedUp) @@ -57,20 +76,24 @@ .data('worddiff:markup', markedUp); }); - var setStatus = function (elem, status, value) { + // Method to set status classes based on associated checkbox value. + var setStatus = function(elem, status, value) { newValue = elem.find('.' + status + ' :checkbox').attr('checked', value).attr('checked'); elem[(newValue === undefined ? value : newValue) ? 'addClass' : 'removeClass']('is-' + status); }; var textareas = all.filter('.new-translation').find('textarea'); - $(this).find('ul.actions .edit').click(function () { + // Callback for when the edit button was pressed. + $(this).find('ul.actions .edit').click(function() { var translation = $(this).closest('td.source, li.translation'); var confirmed = undefined; - textareas.each(function (i) { + textareas.each(function(i) { var textarea = $(this); var val = textarea.val(); - if (confirmed || val === textarea.attr('defaultValue') || !val || (confirmed === undefined && (confirmed = confirm("Do you want to overwrite the current suggestion?")))) { + if (confirmed || val === textarea.attr('defaultValue') || !val || (confirmed === undefined && (confirmed = confirm(Drupal.t("Do you want to overwrite the current suggestion?"))))) { + // If not the default value, and still editing that means there was something + // added into the field without it being saved first, and is being edited again. textarea.val(translation.find('.l10n-string > span:eq('+ i +')').text()).keyup(); if (i == 0) { // Since we can't have multiple focuses, we jut focus the first textarea. @@ -80,68 +103,69 @@ }); }); - all.each(function () { + all.each(function() { var translation = $(this); var isTranslation = !translation.is('.no-translation'); var siblings = all.not(this).not('.no-translation'); - var removeDiff = function () { + var removeDiff = function() { strings.worddiffRevert(); }; - var updateDiff = function () { + var updateDiff = function() { removeDiff(); if (isTranslation) { var orig = siblings.filter('.is-active'); - if (!orig.length) + if (!orig.length) { orig = siblings.filter('.default'); - if (!orig.length) + } + if (!orig.length) { orig = all.not('.no-translation').eq(0).not(translation); + } if (orig.length) { orig = orig.find('.l10n-string > span'); - translation.find('.l10n-string > span').each(function (i) { + translation.find('.l10n-string > span').each(function(i) { $(this).worddiff(orig.get(i), markup); }); } } }; - translation.find('> .selector').click(function () { + translation.find('> .selector').click(function() { setStatus(translation, 'declined', false); - // Mark this as the active translation. + // Mark this as the active translation, update others. setStatus(translation.siblings('.is-active:not(.new-translation)'), 'declined', true); setStatus(translation.siblings('.is-active'), 'active', false); translation.addClass('is-active'); }); - translation.find('> .actions .declined :checkbox').change(function () { + // Update decline status based on checkbox values. + translation.find('> .actions .declined :checkbox').change(function() { setStatus(translation, 'declined', this.checked); }); - translation.find('> .actions .stable :checkbox').change(function () { - setStatus(translation, 'stable', this.checked); - }); - - translation.find('> .author span[title]').click(function () { + translation.find('> .author span[title]').click(function() { var $this = $(this), html = $this.html(); $this.html($this.attr('title')).attr('title', html); }); if (isTranslation) { - translation.find('.l10n-string').dblclick(function () { + // Add doubleclick behavior to decline all other suggestions. + translation.find('.l10n-string').dblclick(function() { translation.siblings().not('.new-translation').each(function () { setStatus($(this), 'declined', true); }); }); + // Add hover behavior to update and remove diffs. translation .mouseenter(updateDiff) .mouseleave(removeDiff); } if (translation.is('.new-translation')) { - translation.find('> .selector').click(function () { - textareas.each(function () { + translation.find('> .selector').click(function() { + textareas.each(function() { var textarea = $(this); if (textarea.val() === '' || textarea.val() === textarea.attr('defaultValue')) { textarea.focus(); @@ -151,7 +175,8 @@ }); }); - var hasContent = function () { + // Does any of the textareas have any content? + var hasContent = function() { for (var i = 0; i < textareas.length; i++) { if (textareas[i].value && textareas[i].value !== textareas[i].defaultValue) { return true; @@ -161,29 +186,32 @@ }; var blurTimeout; - textareas.each(function (n) { + textareas.each(function(n) { var wrapper = $(this); var textarea = $(this); var text = translation.find('.l10n-string > span').eq(n); textarea - .focus(function () { + .focus(function() { translation.addClass('focussed'); clearTimeout(blurTimeout); + // Empty textarea when focused. if (textarea.val() === textarea.attr('defaultValue')) { textarea.val(''); } }) - .blur(function () { - blurTimeout = setTimeout(function () { + .blur(function() { + blurTimeout = setTimeout(function() { translation.removeClass('focussed'); + // Add back default value if user moved out and kept the original text. if (textarea.val() === '') { textarea.val(textarea.attr('defaultValue')); } translation[hasContent() ? 'addClass' : 'removeClass']('has-content'); }, 1000); }) - .keyup(function () { + .keyup(function() { + // Encode and compute the diff for the text as text is typed. var val = encode(textarea.val()); text .data('worddiff:original', val) @@ -191,12 +219,14 @@ var oldPos = textarea.offset().top; updateDiff(); var diff = textarea.offset().top - oldPos; - if (diff) + if (diff) { window.scrollBy(0, diff); + } }); }); } }); }); }); + })(jQuery); Index: l10n_community/jquery.worddiff.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/jquery.worddiff.js,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 jquery.worddiff.js --- l10n_community/jquery.worddiff.js 3 Feb 2010 09:22:28 -0000 1.1.2.2 +++ l10n_community/jquery.worddiff.js 8 Feb 2010 16:13:46 -0000 @@ -1,3 +1,12 @@ +/* $Id$ */ + +/** + * @file + * jQuery worddif algorithm implementation. + * Originally created by Konstantin Kaefer in 2009. + * Based on http://en.wikipedia.org/wiki/Longest_common_subsequence_problem + */ + (function($) { /** Index: l10n_community/translate.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/translate.inc,v retrieving revision 1.1.2.7.2.31.2.3 diff -u -p -r1.1.2.7.2.31.2.3 translate.inc --- l10n_community/translate.inc 3 Feb 2010 15:37:02 -0000 1.1.2.7.2.31.2.3 +++ l10n_community/translate.inc 8 Feb 2010 16:13:46 -0000 @@ -368,6 +368,7 @@ function _l10n_community_translate_trans ), ); + // Active radio box is used to pick the approved translation. $form['active'] = array( '#type' => 'radio', '#theme' => 'l10n_community_translate_radio', @@ -506,6 +507,9 @@ function theme_l10n_community_in_context return ''; } +/** + * Theme a suggestion/translation. + */ function theme_l10n_community_translate_translation($element) { if (!isset($element['#attributes']['class'])) { $element['#attributes']['class'] = ''; @@ -527,6 +531,7 @@ function theme_l10n_community_translate_ $output = ''; $output .= theme('l10n_community_translate_actions', $element); + // Add the radio box to pick the active translation. $output .= drupal_render($element['active']); if (isset($element['author'])) { @@ -536,9 +541,12 @@ function theme_l10n_community_translate_ if (isset($element['value'])) { $output .= drupal_render($element['value']); } - return $output . ''; + return $output .''; } +/** + * Theme a radio button to pick the active translation. + */ function theme_l10n_community_translate_radio($element) { _form_set_class($element, array('form-radio')); $output = ' $string) { + + // Iterate inner structure built in _l10n_community_translate_form_item(). + // Form items have numeric $tid values and other keys here. foreach ($string as $tid => $options) { + // Store new suggestion. $empty_values = 0; + // $options['value'] is the result of (a series of) textareas. if (isset($options['value']) && is_array($options['value'])) { foreach ($options['value'] as $key => $value) { if ($value === t('')) { @@ -587,11 +603,14 @@ function l10n_community_translate_form_s $empty_values++; } } + // If we had value in any of the textareas, add new suggestion. if ($tid === 'new' && count($options['value']) > $empty_values) { $tid = l10n_community_add_suggestion($langcode, $sid, $options['value']); if ($tid) { l10n_community_counter(L10N_COUNT_ADDED); if ($string['active'] === 'new') { + // This new string was selected to be approved, so remember $tid + // for later, so we can save this as an approved translation. $string['active'] = $tid; } } @@ -601,11 +620,13 @@ function l10n_community_translate_form_s if (is_numeric($tid) && $tid > 0) { if ($tid == $string['active']) { if ($options['original']->is_suggestion) { + // $tid is a suggestion that was made active. l10n_community_approve_string($langcode, $sid, $tid); l10n_community_counter(L10N_COUNT_APPROVED); } } elseif (!empty($options['declined'])) { + // The decline checkbox for this suggestion was checked. l10n_community_counter($options['original']->is_suggestion ? L10N_COUNT_SUGGESTION_DECLINED : L10N_COUNT_DECLINED); l10n_community_decline_string($langcode, $sid, $tid); } @@ -613,6 +634,7 @@ function l10n_community_translate_form_s } } + // Tell the user what happened. l10n_community_update_message(); } @@ -790,7 +812,7 @@ function l10n_community_add_suggestion($ $tid = db_last_insert_id('l10n_community_translation', 'tid'); } - // Mark the existing or mock translation has having suggestions. + // Mark the existing or mock translation as having suggestions. l10n_community_update_suggestion_status($langcode, $sid); return $tid; @@ -825,16 +847,14 @@ function l10n_community_decline_string($ */ function l10n_community_update_suggestion_status($langcode, $sid) { // Let's see if we have any suggestions remaining in this language. - $count = db_result(db_query("SELECT COUNT(*) FROM {l10n_community_translation} - WHERE sid = %d AND is_suggestion = 1 AND is_active = 1 AND language = '%s'", $sid, $langcode)); + $count = db_result(db_query("SELECT COUNT(*) FROM {l10n_community_translation} WHERE sid = %d AND is_suggestion = 1 AND is_active = 1 AND language = '%s'", $sid, $langcode)); // Update the status according to the number of suggestions. - db_query("UPDATE {l10n_community_translation} SET has_suggestion = %d - WHERE sid = %d AND is_suggestion = 0 AND is_active = 1 AND language = '%s'", $count ? 1 : 0, $sid, $langcode); + db_query("UPDATE {l10n_community_translation} SET has_suggestion = %d WHERE sid = %d AND is_suggestion = 0 AND is_active = 1 AND language = '%s'", $count ? 1 : 0, $sid, $langcode); } /** - * Marks a translation as approve. + * Mark a translation as approved. * * @param $langcode * The language of the approved translation. @@ -853,7 +873,7 @@ function l10n_community_approve_string($ // Make the existing approved string a suggestion. db_query("UPDATE {l10n_community_translation} SET is_suggestion = 1 WHERE sid = %d AND language = '%s' AND is_suggestion = 0 AND is_active = 1", $sid, $langcode); - // Mark this exact suggestion as active, and set approval time. + // Mark this exact suggestion as active translation, and set approval time. db_query("UPDATE {l10n_community_translation} SET time_approved = %d, uid_approved = %d, is_suggestion = 0, is_active = 1 WHERE tid = %d;", time(), $user->uid, $tid); l10n_community_update_suggestion_status($langcode, $sid); }