diff --git a/includes/locale.inc b/includes/locale.inc index 9714319..726ade3 100644 --- a/includes/locale.inc +++ b/includes/locale.inc @@ -506,10 +506,40 @@ function _locale_parse_js_file($filepath) { // Match all calls to Drupal.t() in an array. // Note: \s also matches newlines with the 's' modifier. - preg_match_all('~[^\w]Drupal\s*\.\s*t\s*\(\s*(' . LOCALE_JS_STRING . ')\s*[,\)]~s', $file, $t_matches); + preg_match_all('~ + [^\w]Drupal\s*\.\s*t\s* # match "Drupal.t" with whitespace + \(\s* # match "(" argument list start + (' . LOCALE_JS_STRING . ')\s* # capture string argument + [,\)] # match ")" or "," to finish + ~sx', $file, $t_matches); // Match all Drupal.formatPlural() calls in another array. - preg_match_all('~[^\w]Drupal\s*\.\s*formatPlural\s*\(\s*.+?\s*,\s*(' . LOCALE_JS_STRING . ')\s*,\s*((?:(?:\'(?:\\\\\'|[^\'])*@count(?:\\\\\'|[^\'])*\'|"(?:\\\\"|[^"])*@count(?:\\\\"|[^"])*")(?:\s*\+\s*)?)+)\s*[,\)]~s', $file, $plural_matches); + preg_match_all('~ + [^\w]Drupal\s*\.\s*formatPlural\s* # match "Drupal.formatPlural" with whitespace + \( # match "(" argument list start + \s*.+?\s*,\s* # match count argument + (' . LOCALE_JS_STRING . ')\s*,\s* # match singular string argument + ( # capture plural string argument + (?: # non-capturing group to repeat string pieces + (?: + \' # match start of single-quoted string + (?:\\\\\'|[^\'])* # match any character except unescaped single-quote + @count # match "@count" + (?:\\\\\'|[^\'])* # match any character except unescaped single-quote + \' # match end of single-quoted string + | + " # match start of double-quoted string + (?:\\\\"|[^"])* # match any character except unescaped double-quote + @count # match "@count" + (?:\\\\"|[^"])* # match any character except unescaped double-quote + " # match end of double-quoted string + ) + (?:\s*\+\s*)? # match "+" with possible whitespace, for str concat + )+ # match multiple because we supports concatenating strs + )\s* # end capturing of plural string argument + [,\)] + ~sx', $file, $plural_matches); + // Loop through all matches and process them. $all_matches = array_merge($plural_matches[1], $t_matches[1]); diff --git a/modules/locale/locale.test b/modules/locale/locale.test index 854bd24..30ed398 100644 --- a/modules/locale/locale.test +++ b/modules/locale/locale.test @@ -177,6 +177,73 @@ class LocaleConfigurationTest extends DrupalWebTestCase { } /** + * Functional tests for JavaScript parsing for translatable strings. + */ +class LocaleJavascriptTranslationTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Javascript translation', + 'description' => 'Tests parsing js files for translatable strings', + 'group' => 'Locale', + ); + } + + function setUp() { + parent::setUp('locale', 'locale_test'); + } + + function testFileParsing() { + + $filename = drupal_get_path('module', 'locale_test') . '/locale_test.js'; + + // Parse the file to look for source strings. + _locale_parse_js_file($filename); + + // Get all of the source strings that were found. + $source_strings = db_select('locales_source', 's') + ->fields('s', array('source', 'lid')) + ->condition('s.location', $filename) + ->execute() + ->fetchAllKeyed(); + + // List of all strings that should be in the file. + $test_strings = array( + "Standard Call t", + "Whitespace Call t", + + "Single Quote t", + "Single Quote \\'Escaped\\' t", + "Single Quote Concat strings t", + + "Double Quote t", + "Double Quote \\\"Escaped\\\" t", + "Double Quote Concat strings t", + + "Standard Call plural", + "Standard Call @count plural", + "Whitespace Call plural", + "Whitespace Call @count plural", + + "Single Quote plural", + "Single Quote @count plural", + "Single Quote \\'Escaped\\' plural", + "Single Quote \\'Escaped\\' @count plural", + + "Double Quote plural", + "Double Quote @count plural", + "Double Quote \\\"Escaped\\\" plural", + "Double Quote \\\"Escaped\\\" @count plural", + ); + + // Assert that all strings were found properly. + foreach ($test_strings as $str) { + $this->assertTrue(isset($source_strings[$str]), t("Found source string: %source", array('%source' => $str))); + } + + $this->assertEqual(count($source_strings), count($test_strings), t("Found correct number of source strings.")); + } +} +/** * Functional test for string translation and validation. */ class LocaleTranslationFunctionalTest extends DrupalWebTestCase { diff --git a/modules/locale/tests/locale_test.js b/modules/locale/tests/locale_test.js new file mode 100644 index 0000000..251d115 --- /dev/null +++ b/modules/locale/tests/locale_test.js @@ -0,0 +1,35 @@ + +Drupal.t("Standard Call t"); +Drupal +. +t +( +"Whitespace Call t" +) +; + +Drupal.t('Single Quote t'); +Drupal.t('Single Quote \'Escaped\' t'); +Drupal.t('Single Quote ' + 'Concat ' + 'strings ' + 't'); + +Drupal.t("Double Quote t"); +Drupal.t("Double Quote \"Escaped\" t"); +Drupal.t("Double Quote " + "Concat " + "strings " + "t"); + + +Drupal.formatPlural(1, "Standard Call plural", "Standard Call @count plural"); +Drupal +. +formatPlural +( +1, +"Whitespace Call plural", +"Whitespace Call @count plural", +) +; + +Drupal.formatPlural(1, 'Single Quote plural', 'Single Quote @count plural'); +Drupal.formatPlural(1, 'Single Quote \'Escaped\' plural', 'Single Quote \'Escaped\' @count plural'); + +Drupal.formatPlural(1, "Double Quote plural", "Double Quote @count plural"); +Drupal.formatPlural(1, "Double Quote \"Escaped\" plural", "Double Quote \"Escaped\" @count plural");