#118026 by kkaefer with fixes from myself: JavaScript translation support and script.js as a default theme JS file to use, if found

6.x
Gábor Hojtsy 2007-06-08 12:51:59 +00:00
parent 9e0da3dc7c
commit 57c9a13e1f
15 changed files with 484 additions and 49 deletions

View File

@ -1686,13 +1686,14 @@ function drupal_clear_css_cache() {
* feature has been turned on under the performance section?
* @return
* If the first parameter is NULL, the JavaScript array that has been built so
* far for $scope is returned.
* far for $scope is returned. If the first three parameters are NULL,
* an array with all scopes is returned.
*/
function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE, $preprocess = TRUE) {
static $javascript = array();
// Add jquery.js and drupal.js the first time a Javascript file is added.
if ($data && empty($javascript)) {
if (isset($data) && empty($javascript)) {
$javascript['header'] = array(
'core' => array(
'misc/jquery.js' => array('cache' => TRUE, 'defer' => FALSE, 'preprocess' => TRUE),
@ -1701,11 +1702,11 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
'module' => array(), 'theme' => array(), 'setting' => array(), 'inline' => array(),
);
}
if (!isset($javascript[$scope])) {
if (isset($scope) && !isset($javascript[$scope])) {
$javascript[$scope] = array('core' => array(), 'module' => array(), 'theme' => array(), 'setting' => array(), 'inline' => array());
}
if (!isset($javascript[$scope][$type])) {
if (isset($type) && isset($scope) && !isset($javascript[$scope][$type])) {
$javascript[$scope][$type] = array();
}
@ -1723,7 +1724,12 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
}
}
return $javascript[$scope];
if (isset($scope)) {
return $javascript[$scope];
}
else {
return $javascript;
}
}
/**
@ -1743,6 +1749,10 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
* All JavaScript code segments and includes for the scope as HTML tags.
*/
function drupal_get_js($scope = 'header', $javascript = NULL) {
if (function_exists('locale_inc_callback')) {
locale_inc_callback('_locale_update_js_files');
}
if (!isset($javascript)) {
$javascript = drupal_add_js(NULL, NULL, $scope);
}
@ -2062,6 +2072,7 @@ function _packer_backreferences($match, $offset, $data) {
*/
function drupal_clear_js_cache() {
file_scan_directory(file_create_path('js'), '.*', array('.', '..', 'CVS'), 'file_delete', TRUE);
variable_set('javascript_parsed', '');
}
/**

View File

@ -1564,7 +1564,6 @@ function theme_textarea($element) {
if (!empty($element['#teaser'])) {
drupal_add_js('misc/teaser.js');
// Note: arrays are merged in drupal_get_js().
drupal_add_js(array('teaserButton' => array(t('Join summary'), t('Split summary at cursor'))), 'setting');
drupal_add_js(array('teaserCheckbox' => array($element['#id'] => $element['#teaser_checkbox'])), 'setting');
drupal_add_js(array('teaser' => array($element['#id'] => $element['#teaser'])), 'setting');
$class[] = 'teaser';

View File

@ -6,6 +6,8 @@
* Administration functions for locale.module.
*/
define('LOCALE_JS_STRING', '(?:(?:\'(?:\\\\\'|[^\'])*\'|"(?:\\\\"|[^"])*")(?:\s*\+\s*)?)+');
/**
* @defgroup locale-language-overview Language overview functionality
* @{
@ -792,7 +794,11 @@ function locale_translate_edit_form_submit($form, &$form_state) {
else {
db_query("INSERT INTO {locales_target} (lid, translation, language) VALUES (%d, '%s', '%s')", $lid, $value, $key);
}
// Refresh the JS file for this language.
_locale_rebuild_js($key);
}
drupal_set_message(t('The string has been saved.'));
// Refresh the locale cache.
@ -814,8 +820,12 @@ function locale_translate_edit_form_submit($form, &$form_state) {
* Delete a language string.
*/
function locale_translate_delete($lid) {
$langcode = db_result(db_query('SELECT language FROM {locales_source} WHERE lid = %d', $lid));
db_query('DELETE FROM {locales_source} WHERE lid = %d', $lid);
db_query('DELETE FROM {locales_target} WHERE lid = %d', $lid);
if ($langcode) {
_locale_rebuild_js($langcode);
}
locale_refresh_cache();
drupal_set_message(t('The string has been removed.'));
drupal_goto('admin/build/translate/search');
@ -897,47 +907,48 @@ function locale_add_language($langcode, $name = NULL, $native = NULL, $direction
*
* @param $file
* Drupal file object corresponding to the PO file to import
* @param $lang
* @param $langcode
* Language code
* @param $mode
* Should existing translations be replaced ('overwrite' or 'keep')
* @param $group
* Text group to import PO file into (eg. 'default' for interface translations)
*/
function _locale_import_po($file, $lang, $mode, $group = NULL) {
// If not in 'safe mode', increase the maximum execution time:
function _locale_import_po($file, $langcode, $mode, $group = NULL) {
// If not in 'safe mode', increase the maximum execution time.
if (!ini_get('safe_mode')) {
set_time_limit(240);
}
// Check if we have the language already in the database
if (!db_fetch_object(db_query("SELECT language FROM {languages} WHERE language = '%s'", $lang))) {
// Check if we have the language already in the database.
if (!db_fetch_object(db_query("SELECT language FROM {languages} WHERE language = '%s'", $langcode))) {
drupal_set_message(t('The language selected for import is not supported.'), 'error');
return FALSE;
}
// Get strings from file (returns on failure after a partial import, or on success)
$status = _locale_import_read_po('db-store', $file, $mode, $lang, $group);
$status = _locale_import_read_po('db-store', $file, $mode, $langcode, $group);
if ($status === FALSE) {
// error messages are set in _locale_import_read_po
// Error messages are set in _locale_import_read_po().
return FALSE;
}
// Get status information on import process
// Get status information on import process.
list($headerdone, $additions, $updates) = _locale_import_one_string('db-report');
if (!$headerdone) {
drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => $file->filename)), 'error');
}
// rebuild locale cache
cache_clear_all("locale:$lang", 'cache');
// Rebuild locale cache.
_locale_rebuild_js($langcode);
cache_clear_all("locale:$langcode", 'cache');
// rebuild the menu, strings may have changed
// Rebuild the menu, strings may have changed.
menu_rebuild();
drupal_set_message(t('The translation was successfully imported. There are %number newly created translated strings and %update strings were updated.', array('%number' => $additions, '%update' => $updates)));
watchdog('locale', 'Imported %file into %locale: %number new strings added and %update updated.', array('%file' => $file->filename, '%locale' => $lang, '%number' => $additions, '%update' => $updates));
watchdog('locale', 'Imported %file into %locale: %number new strings added and %update updated.', array('%file' => $file->filename, '%locale' => $langcode, '%number' => $additions, '%update' => $updates));
return TRUE;
}
@ -1552,6 +1563,102 @@ function _locale_import_parse_quoted($string) {
* @} End of "locale-api-import"
*/
/**
* This function checks all JavaScript files currently added via drupal_add_js()
* and invokes parsing if they have not yet been parsed for Drupal.t() calls.
*/
function _locale_update_js_files() {
global $language;
$parsed = variable_get('javascript_parsed', array());
// The first three parameters are NULL in order to get an array with all
// scopes. This is necessary to prevent recreation of JS translation files
// when new files are added for example in the footer.
$javascript = drupal_add_js(NULL, NULL, NULL);
$files = FALSE;
$parsed = array();
foreach ($javascript as $scope) {
foreach ($scope as $type => $data) {
if ($type != 'setting' && $type != 'inline') {
foreach ($data as $filepath => $info) {
$files = TRUE;
if (!in_array($filepath, $parsed)) {
_locale_parse_js_file($filepath);
watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath));
$parsed[] = $filepath;
}
}
}
}
}
// Update the parsed files storage array.
variable_set('javascript_parsed', $parsed);
_locale_rebuild_js();
// Add the translation JavaScript file to the page.
if ($files && !empty($language->javascript)) {
drupal_add_js(file_create_path(variable_get('locale_js_directory', 'languages') .'/'. $language->language .'_'. $language->javascript .'.js'), 'core');
}
}
/**
* Parses a JavaScript file, extracts strings wrapped in Drupal.t() and
* Drupal.formatPlural() and inserts them into the database.
*/
function _locale_parse_js_file($filepath) {
global $language;
// Load the JavaScript file.
$file = file_get_contents($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);
// 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);
// Loop through all matches and process them.
$all_matches = array_merge($plural_matches[1], $t_matches[1]);
foreach ($all_matches as $key => $string) {
$strings = array($string);
// If there is also a plural version of this string, add it to the strings array.
if (isset($plural_matches[2][$key])) {
$strings[] = $plural_matches[2][$key];
}
foreach ($strings as $key => $string) {
// Remove the quotes and string concatenations from the string.
$string = implode('', preg_split('~(?<!\\\\)[\'"]\s*\+\s*[\'"]~s', substr($string, 1, -1)));
$result = db_query("SELECT lid, location FROM {locales_source} WHERE source = '%s' AND textgroup = 'default'", $string);
if ($source = db_fetch_object($result)) {
// We already have this source string and now have to add the location
// to the location column, if this file is not yet present in there.
$locations = preg_split('~\s*;\s*~', $source->location);
if (!in_array($filepath, $locations)) {
$locations[] = $filepath;
$locations = implode('; ', $locations);
// Save the new locations string to the database.
db_query("UPDATE {locales_source} SET location = '%s' WHERE lid = %d", $locations, $source->lid);
}
}
else {
// We don't have the source string yet, thus we insert it into the database.
db_query("INSERT INTO {locales_source} (location, source, textgroup) VALUES ('%s', '%s', 'default')", $filepath, $string);
$lid = db_result(db_query("SELECT lid FROM {locales_source} WHERE source = '%s' AND textgroup = 'default'", $string));
db_query("INSERT INTO {locales_target} (lid, language, translation) VALUES (%d, '%s', '')", $lid, $language->language);
}
}
}
}
/**
* @defgroup locale-api-export Translation (template) export API.
* @{
@ -1868,6 +1975,128 @@ function _locale_translate_seek_query() {
return $query;
}
/**
* (Re-)Creates the JavaScript translation file for a language.
*
* @param $language
* The language, the translation file should be (re)created for.
*/
function _locale_rebuild_js($langcode = NULL) {
if (!isset($langcode)) {
global $language;
}
else {
// Get information about the locale.
$languages = language_list();
$language = $languages[$langcode];
}
// Construct the array for JavaScript translations.
// We sort on plural so that we have all plural forms before singular forms.
$result = db_query("SELECT s.lid, s.source, t.plid, t.plural, t.translation FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid WHERE t.language = '%s' AND s.location LIKE '%%.js%%' AND s.textgroup = 'default' ORDER BY t.plural DESC", $language->language);
$translations = $plurals = array();
while ($data = db_fetch_object($result)) {
// Only add this to the translations array when there is actually a translation.
if (!empty($data->translation)) {
if ($data->plural) {
// When the translation is a plural form, first add it to another array and
// wait for the singular (parent) translation.
if (!isset($plurals[$data->plid])) {
$plurals[$data->plid] = array($data->plural => $data->translation);
}
else {
$plurals[$data->plid] += array($data->plural => $data->translation);
}
}
elseif (isset($plurals[$data->lid])) {
// There are plural translations for this translation, so get them from
// the plurals array and add them to the final translations array.
$translations[$data->source] = array($data->plural => $data->translation) + $plurals[$data->lid];
unset($plurals[$data->lid]);
}
else {
// There are no plural forms for this translation, so just add it to
// the translations array.
$translations[$data->source] = $data->translation;
}
}
}
// Only operate when there are translations.
if (!empty($translations)) {
// Construct the JavaScript file.
$data = "Drupal.locale = { ";
if (!empty($language->formula)) {
$data .= "'pluralFormula': function(\$n) { return Number({$language->formula}); }, ";
}
$data .= "'strings': ". drupal_to_js($translations) ." };";
// Construct the directory where JS translation files are stored.
// There is (on purpose) no front end to edit that variable.
$dir = file_create_path(variable_get('locale_js_directory', 'languages'));
// Only create a new file if the content has changed.
$data_hash = md5($data);
if ($language->javascript != $data_hash) {
if (!empty($language->javascript)) {
// We are recreating the new file, so delete the old one.
file_delete(file_create_path($dir .'/'. $language->language .'_'. $language->javascript .'.js'));
$language->javascript = '';
}
else {
// The directory might not exist when there has not been a translation
// file before, so create it.
file_check_directory($dir, TRUE);
}
// The file name of the new JavaScript translation file.
$dest = $dir .'/'. $language->language .'_'. $data_hash .'.js';
$filepath = file_save_data($data, $dest);
// Update the global $language object.
$language->javascript = $filepath ? $data_hash : '';
// Save the new JavaScript hash.
db_query("UPDATE {languages} SET javascript = '%s' WHERE language = '%s'", $language->javascript, $language->language);
// Update the default language variable if the default language has been altered.
// This is necessary to keep the variable consistent with the database
// version of the language and to prevent checking against an outdated hash.
$default_langcode = language_default('language');
if ($default_langcode == $language->language) {
$default = db_fetch_object(db_query("SELECT * FROM {languages} WHERE language = '%s'", $default_langcode));
variable_set('language_default', $default);
}
// Only report updated or creation when there is actually a file created.
if ($filepath) {
// There has already been a translation file before.
if (!empty($language->javascript)) {
watchdog('locale', t('Updated JavaScript translation file for the language %language.', array('%language' => t($language->name))));
}
else {
watchdog('locale', t('Created JavaScript translation file for the language %language.', array('%language' => t($language->name))));
}
}
else {
watchdog('locale', t('An error occured during creation of the JavaScript translation file for the language %language.', array('%language' => t($language->name))));
}
}
}
// There are no strings for JavaScript translation. However, if there is a file,
// delete it and reset the database.
elseif (!empty($language->javascript)) {
// Delete the old JavaScript file
file_delete(file_create_path(variable_get('locale_js_directory', 'languages') .'/'. $language->language .'_'. $language->javascript .'.js'));
db_query("UPDATE {languages} SET javascript = '' WHERE language = '%s'", $language->language);
watchdog('locale', t('Deleted JavaScript translation file for the locale %language.', array('%language' => t($language->name))));
}
}
/**
* List languages in search result table
*/

View File

@ -115,6 +115,21 @@ function _init_theme($theme, $base_theme = array()) {
}
}
// Add the default script
if (!empty($theme->script)) {
drupal_add_js($theme->script, 'theme');
}
else {
// If we don't have a script of our own, look for the first
// base to have one and use its.
foreach ($base_theme as $base) {
if (!empty($base->script)) {
drupal_add_js($base->script, 'theme');
break;
}
}
}
$theme_engine = NULL;
// Initialize the theme.
@ -341,9 +356,12 @@ function list_themes($refresh = FALSE) {
while ($theme = db_fetch_object($result)) {
if (file_exists($theme->filename)) {
$theme->info = unserialize($theme->info);
if (isset($theme->info['stylesheet'])) {
if (!empty($theme->info['stylesheet']) && file_exists($theme->info['stylesheet'])) {
$theme->stylesheet = $theme->info['stylesheet'];
}
if (!empty($theme->info['script']) && file_exists($theme->info['script'])) {
$theme->script = $theme->info['script'];
}
if (isset($theme->info['engine'])) {
$theme->engine = $theme->info['engine'];
}
@ -1164,7 +1182,6 @@ function theme_table($header, $rows, $attributes = array(), $caption = NULL) {
* Returns a header cell for tables that have a select all functionality.
*/
function theme_table_select_header_cell() {
drupal_add_js(array('tableSelect' => array('selectAll' => t('Select all rows in this table'), 'selectNone' => t('Deselect all rows in this table'))), 'setting');
drupal_add_js('misc/tableselect.js');
return array('class' => 'select-all');

View File

@ -898,6 +898,8 @@ function install_configure_form() {
);
drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
// We add these strings as settings because JavaScript translation does not
// work on install time.
drupal_add_js(array('cleanURL' => array('success' => st('Your server has been successfully tested to support this feature.'), 'failure' => st('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.'), 'testing' => st('Testing clean URLs...'))), 'setting');
drupal_add_js('
// Global Killswitch

View File

@ -282,7 +282,7 @@ Drupal.ACDB.prototype.search = function (searchString) {
}
},
error: function (xmlhttp) {
alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
alert(Drupal.t("An HTTP error @status occured. \n@uri", { '@status': xmlhttp.status, '@uri': db.uri }));
}
});
}, this.delay);

View File

@ -1,6 +1,6 @@
// $Id$
var Drupal = Drupal || {};
var Drupal = Drupal || { 'settings': {}, 'themes': {}, 'locale': {} };
/**
* Set the variable that indicates if JavaScript behaviors should be applied
@ -21,6 +21,142 @@ Drupal.extend = function(obj) {
}
};
/**
* Encode special characters in a plain-text string for display as HTML.
*/
Drupal.checkPlain = function(str) {
str = String(str);
var replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
for (var character in replace) {
str = str.replace(character, replace[character]);
}
return str;
};
/**
* Translate strings to the page language or a given language.
*
* See the documentation of the server-side t() function for further details.
*
* @param str
* A string containing the English string to translate.
* @param args
* An object of replacements pairs to make after translation. Incidences
* of any key in this array are replaced with the corresponding value.
* Based on the first character of the key, the value is escaped and/or themed:
* - !variable: inserted as is
* - @variable: escape plain text to HTML (Drupal.checkPlain)
* - %variable: escape text and theme as a placeholder for user-submitted
* content (checkPlain + Drupal.theme('placeholder'))
* @return
* The translated string.
*/
Drupal.t = function(str, args) {
// Fetch the localized version of the string.
if (Drupal.locale.strings && Drupal.locale.strings[str]) {
str = Drupal.locale.strings[str];
}
if (args) {
// Transform arguments before inserting them
for (var key in args) {
switch (key.charAt(0)) {
// Escaped only
case '@':
args[key] = Drupal.checkPlain(args[key]);
break;
// Pass-through
case '!':
break;
// Escaped and placeholder
case '%':
default:
args[key] = Drupal.theme('placeholder', args[key]);
break;
}
str = str.replace(key, args[key]);
}
}
return str;
};
/**
* Format a string containing a count of items.
*
* This function ensures that the string is pluralized correctly. Since Drupal.t() is
* called by this function, make sure not to pass already-localized strings to it.
*
* See the documentation of the server-side format_plural() function for further details.
*
* @param count
* The item count to display.
* @param singular
* The string for the singular case. Please make sure it is clear this is
* singular, to ease translation (e.g. use "1 new comment" instead of "1 new").
* Do not use @count in the singular string.
* @param plural
* The string for the plural case. Please make sure it is clear this is plural,
* to ease translation. Use @count in place of the item count, as in "@count
* new comments".
* @param args
* An object of replacements pairs to make after translation. Incidences
* of any key in this array are replaced with the corresponding value.
* Based on the first character of the key, the value is escaped and/or themed:
* - !variable: inserted as is
* - @variable: escape plain text to HTML (Drupal.checkPlain)
* - %variable: escape text and theme as a placeholder for user-submitted
* content (checkPlain + Drupal.theme('placeholder'))
* Note that you do not need to include @count in this array.
* This replacement is done automatically for the plural case.
* @return
* A translated string.
*/
Drupal.formatPlural = function(count, singular, plural, args) {
var args = ars || {};
args['@count'] = count;
// Determine the index of the plural form.
var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
if (index == 0) {
return Drupal.t(singular, args);
}
else if (index == 1) {
return Drupal.t(plural, args);
}
else {
args['@count['+ index +']'] = args['@count'];
delete args['@count'];
return Drupal.t(plural.replace('@count', '@count['+ index +']'));
}
};
/**
* Generate the themed representation of a Drupal object.
*
* All requests for themed output must go through this function. It examines
* the request and routes it to the appropriate theme function. If the current
* theme does not provide an override function, the generic theme function is
* called.
*
* For example, to retrieve the HTML that is output by theme_placeholder(text),
* call Drupal.theme('placeholder', text).
*
* @param func
* The name of the theme function to call.
* @param ...
* Additional arguments to pass along to the theme function.
* @return
* Any data the theme function returns. This could be a plain HTML string,
* but also a complex object.
*/
Drupal.theme = function(func) {
for (var i = 1, args = []; i < arguments.length; i++) {
args.push(arguments[i]);
}
return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args);
};
/**
* Redirects a button's form submission to a hidden iframe and displays the result
* in a given wrapper. The iframe should contain a call to
@ -126,7 +262,7 @@ Drupal.mousePosition = function(e) {
*/
Drupal.parseJson = function (data) {
if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
return { status: 0, data: data.length ? data : 'Unspecified error' };
return { status: 0, data: data.length ? data : Drupal.t('Unspecified error') };
}
return eval('(' + data + ');');
};
@ -227,3 +363,21 @@ if (Drupal.jsEnabled) {
// 'js enabled' cookie
document.cookie = 'has_js=1';
}
/**
* The default themes.
*/
Drupal.theme.prototype = {
/**
* Formats text for emphasized display in a placeholder inside a sentence.
*
* @param str
* The text to format (plain-text).
* @return
* The formatted text (html).
*/
placeholder: function(str) {
return '<em>' + Drupal.checkPlain(str) + '</em>';
}
};

View File

@ -86,7 +86,7 @@ Drupal.progressBar.prototype.sendPing = function () {
pb.timer = setTimeout(function() { pb.sendPing(); }, pb.delay);
},
error: function (xmlhttp) {
pb.displayError('An HTTP error '+ xmlhttp.status +' occured.\n'+ pb.uri);
pb.displayError(Drupal.t("An HTTP error @status occured. \n@uri", { '@status': xmlhttp.status, '@uri': pb.uri }));
}
});
}

View File

@ -2,10 +2,11 @@
Drupal.tableSelect = function() {
// Keep track of the table, which checkbox is checked and alias the settings.
var table = this, selectAll, checkboxes, lastChecked, settings = Drupal.settings.tableSelect;
var table = this, selectAll, checkboxes, lastChecked;
var strings = { 'selectAll': Drupal.t('Select all rows in this table'), 'selectNone': Drupal.t('Deselect all rows in this table') };
// Store the select all checkbox in a variable as we need it quite often.
selectAll = $('<input type="checkbox" class="form-checkbox" />').attr('title', settings.selectAll).click(function() {
selectAll = $('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll).click(function() {
// Loop through all checkboxes and set their state to the select all checkbox' state.
checkboxes.each(function() {
this.checked = selectAll[0].checked;
@ -13,7 +14,7 @@ Drupal.tableSelect = function() {
$(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected');
});
// Update the title and the state of the check all box.
selectAll.attr('title', selectAll[0].checked ? settings.selectNone : settings.selectAll);
selectAll.attr('title', selectAll[0].checked ? strings.selectNone : strings.selectAll);
});
// Find all <th> with class select-all, and insert the check all checkbox.
@ -35,7 +36,7 @@ Drupal.tableSelect = function() {
// If all checkboxes are checked, make sure the select-all one is checked too, otherwise keep unchecked.
selectAll[0].checked = (checkboxes.length == $(checkboxes).filter(':checked').length);
// Set the title to the current action.
selectAll.attr('title', selectAll[0].checked ? settings.selectNone : settings.selectAll);
selectAll.attr('title', selectAll[0].checked ? strings.selectNone : strings.selectAll);
// Keep track of the last checked checkbox.
lastChecked = e.target;

View File

@ -29,7 +29,7 @@ Drupal.teaserAttach = function() {
$(teaser).attr('disabled', 'disabled');
$(teaser).parent().slideUp('fast');
// Change label
$(this).val(Drupal.settings.teaserButton[1]);
$(this).val(Drupal.t('Split summary at cursor'));
// Show separate teaser checkbox
$(checkbox).hide();
}
@ -48,7 +48,7 @@ Drupal.teaserAttach = function() {
$(teaser).attr('disabled', '');
$(teaser).parent().slideDown('fast');
// Change label
$(this).val(Drupal.settings.teaserButton[0]);
$(this).val(Drupal.t('Join summary'));
// Show separate teaser checkbox
$(checkbox).show();
}
@ -64,11 +64,11 @@ Drupal.teaserAttach = function() {
teaser[0].value = trim(text[0]);
body[0].value = trim(text[1]);
$(teaser).attr('disabled', '');
$('input', button).val(Drupal.settings.teaserButton[0]).toggle(join_teaser, split_teaser);
$('input', button).val(Drupal.t('Join summary')).toggle(join_teaser, split_teaser);
}
else {
$(teaser).hide();
$('input', button).val(Drupal.settings.teaserButton[1]).toggle(split_teaser, join_teaser);
$('input', button).val(Drupal.t('Split summary at cursor')).toggle(split_teaser, join_teaser);
$(checkbox).hide();
}

View File

@ -33,7 +33,7 @@ Drupal.jsUpload = function(uri, button, wrapper, hide) {
Drupal.jsUpload.prototype.onsubmit = function () {
// Insert progressbar and stretch to take the same space.
this.progress = new Drupal.progressBar('uploadprogress');
this.progress.setProgress(-1, 'Uploading file');
this.progress.setProgress(-1, Drupal.t('Uploading file'));
var hide = this.hide;
var el = this.progress.element;
@ -98,7 +98,7 @@ Drupal.jsUpload.prototype.oncomplete = function (data) {
* Handler for the form redirection error.
*/
Drupal.jsUpload.prototype.onerror = function (error) {
alert('An error occurred:\n\n'+ error);
alert(Drupal.t('An error occurred:\n\n@error', { '@error': error }));
// Remove progressbar
$(this.progress.element).remove();
this.progress = null;

View File

@ -12,7 +12,7 @@ function locale_install() {
// Create tables.
drupal_install_schema('locale');
db_query("INSERT INTO {languages} (language, name, native, direction, enabled, weight) VALUES ('en', 'English', 'English', '0', '1', '0')");
db_query("INSERT INTO {languages} (language, name, native, direction, enabled, weight, javascript) VALUES ('en', 'English', 'English', '0', '1', '0', '')");
}
/**
@ -91,6 +91,15 @@ function locale_update_6002() {
return $ret;
}
/**
* Adds a column to store the filename of the JavaScript translation file.
*/
function locale_update_6003() {
$ret = array();
db_add_field($rest, 'languages', 'javascript', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''));
return $ret;
}
/**
* @} End of "defgroup updates-5.x-to-6.x"
*/
@ -99,6 +108,14 @@ function locale_update_6002() {
* Implementation of hook_uninstall().
*/
function locale_uninstall() {
// Delete all JavaScript translation files
$files = db_query('SELECT javascript FROM {languages}');
while ($file = db_fetch_object($files)) {
if (!empty($file)) {
file_delete(file_create_path($file->javascript));
}
}
// Remove tables.
drupal_uninstall_schema('locale');
}

View File

@ -4,16 +4,17 @@
function locale_schema() {
$schema['languages'] = array(
'fields' => array(
'language' => array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''),
'name' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
'native' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
'direction' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'enabled' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'plurals' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'formula' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'domain' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'prefix' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0)
'language' => array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''),
'name' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
'native' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
'direction' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'enabled' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'plurals' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'formula' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'domain' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'prefix' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'javascript' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
),
'primary key' => array('language'),
);

View File

@ -9,18 +9,18 @@
*/
Drupal.cleanURLsSettingsCheck = function() {
var url = location.pathname +"admin/settings/clean-urls";
$("#clean-url .description span").html('<div id="testing">'+ Drupal.settings.cleanURL.testing +"</div>");
$("#clean-url .description span").html('<div id="testing">'+ Drupal.t('Testing clean URLs...') +"</div>");
$("#clean-url p").hide();
$.ajax({url: location.protocol +"//"+ location.host + url, type: "GET", data: " ", complete: function(response) {
$("#testing").toggle();
if (response.status == 200) {
// Check was successful.
$("#clean-url input.form-radio").attr("disabled", "");
$("#clean-url .description span").append('<div class="ok">'+ Drupal.settings.cleanURL.success +"</div>");
$("#clean-url .description span").append('<div class="ok">'+ Drupal.t('Your server has been successfully tested to support this feature.') +"</div>");
}
else {
// Check failed.
$("#clean-url .description span").append('<div class="warning">'+ Drupal.settings.cleanURL.failure +"</div>");
$("#clean-url .description span").append('<div class="warning">'+ Drupal.t('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.') +"</div>");
}
}});
};

View File

@ -615,7 +615,6 @@ function system_clean_url_settings() {
if (!variable_get('clean_url', 0)) {
if (strpos(request_uri(), '?q=') !== FALSE) {
drupal_add_js(array('cleanURL' => array('success' => t('Your server has been successfully tested to support this feature.'), 'failure' => t('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.'), 'testing' => t('Testing clean URLs...'))), 'setting');
drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
drupal_add_js('
// Global Killswitch
@ -1060,6 +1059,7 @@ function system_theme_default() {
'slogan'
),
'stylesheet' => 'style.css',
'script' => 'script.js',
'screenshot' => 'screenshot.png',
);
}
@ -1113,6 +1113,10 @@ function system_theme_data() {
if (!empty($themes[$key]->info['stylesheet'])) {
$themes[$key]->info['stylesheet'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['stylesheet'];
}
// Give the script proper path information.
if (!empty($themes[$key]->info['script'])) {
$themes[$key]->info['script'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['script'];
}
// Give the screenshot proper path information.
if (!empty($themes[$key]->info['screenshot'])) {
$themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot'];