Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • rklusman2/UNL-CMS
  • yzha1/UNL-CMS
  • pear/UNL-CMS
  • bbieber2/UNL-CMS
  • tsteiner2/UNL-CMS
  • erasmussen2/UNL-CMS
  • UNL-Information-Services/UNL-CMS
7 results
Select Git revision
Loading items
Show changes
Showing with 678 additions and 247 deletions
<?php
// $Id: unicode.inc,v 1.47 2010/08/11 10:58:22 dries Exp $
/**
* @file
* Provides Unicode-related conversions and operations.
*/
/**
* Indicates an error during check for PHP unicode support.
......@@ -20,8 +24,6 @@ define('UNICODE_MULTIBYTE', 1);
/**
* Matches Unicode characters that are word boundaries.
*
* @see http://unicode.org/glossary
*
* Characters with the following General_category (gc) property values are used
* as word boundaries. While this does not fully conform to the Word Boundaries
* algorithm described in http://unicode.org/reports/tr29, as PCRE does not
......@@ -40,6 +42,8 @@ define('UNICODE_MULTIBYTE', 1);
* Note that the PCRE property matcher is not used because we wanted to be
* compatible with Unicode 5.2.0 regardless of the PCRE version used (and any
* bugs in PCRE property tables).
*
* @see http://unicode.org/glossary
*/
define('PREG_CLASS_UNICODE_WORD_BOUNDARY',
'\x{0}-\x{2F}\x{3A}-\x{40}\x{5B}-\x{60}\x{7B}-\x{A9}\x{AB}-\x{B1}\x{B4}' .
......@@ -74,7 +78,7 @@ define('PREG_CLASS_UNICODE_WORD_BOUNDARY',
'\x{A836}-\x{A839}\x{A874}-\x{A877}\x{A8CE}-\x{A8CF}\x{A8F8}-\x{A8FA}' .
'\x{A92E}-\x{A92F}\x{A95F}\x{A9C1}-\x{A9CD}\x{A9DE}-\x{A9DF}' .
'\x{AA5C}-\x{AA5F}\x{AA77}-\x{AA79}\x{AADE}-\x{AADF}\x{ABEB}' .
'\x{D800}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}' .
'\x{E000}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}' .
'\x{FE10}-\x{FE19}\x{FE30}-\x{FE6B}\x{FEFF}-\x{FF0F}\x{FF1A}-\x{FF20}' .
'\x{FF3B}-\x{FF40}\x{FF5B}-\x{FF65}\x{FFE0}-\x{FFFD}');
......@@ -97,7 +101,7 @@ function unicode_check() {
* Whether to report any fatal errors with form_set_error().
*/
function _unicode_check() {
// Ensure translations don't break at install time
// Ensure translations don't break during installation.
$t = get_t();
// Check for mbstring extension
......@@ -126,10 +130,10 @@ function _unicode_check() {
}
/**
* Return Unicode library status and errors.
* Returns Unicode library status and errors.
*/
function unicode_requirements() {
// Ensure translations don't break at install time
// Ensure translations don't break during installation.
$t = get_t();
$libraries = array(
......@@ -158,19 +162,19 @@ function unicode_requirements() {
}
/**
* Prepare a new XML parser.
* Prepares a new XML parser.
*
* This is a wrapper around xml_parser_create() which extracts the encoding from
* the XML data first and sets the output encoding to UTF-8. This function should
* be used instead of xml_parser_create(), because PHP 4's XML parser doesn't
* check the input encoding itself. "Starting from PHP 5, the input encoding is
* automatically detected, so that the encoding parameter specifies only the
* output encoding."
* This is a wrapper around xml_parser_create() which extracts the encoding
* from the XML data first and sets the output encoding to UTF-8. This function
* should be used instead of xml_parser_create(), because PHP 4's XML parser
* doesn't check the input encoding itself. "Starting from PHP 5, the input
* encoding is automatically detected, so that the encoding parameter specifies
* only the output encoding."
*
* This is also where unsupported encodings will be converted. Callers should
* take this into account: $data might have been changed after the call.
*
* @param &$data
* @param $data
* The XML data which will be parsed later.
*
* @return
......@@ -214,14 +218,14 @@ function drupal_xml_parser_create(&$data) {
}
/**
* Convert data to UTF-8
* Converts data to UTF-8.
*
* Requires the iconv, GNU recode or mbstring PHP extension.
*
* @param $data
* The data to be converted.
* @param $encoding
* The encoding that the data is in
* The encoding that the data is in.
*
* @return
* Converted data or FALSE.
......@@ -245,15 +249,15 @@ function drupal_convert_to_utf8($data, $encoding) {
}
/**
* Truncate a UTF-8-encoded string safely to a number of bytes.
* Truncates a UTF-8-encoded string safely to a number of bytes.
*
* If the end position is in the middle of a UTF-8 sequence, it scans backwards
* until the beginning of the byte sequence.
*
* Use this function whenever you want to chop off a string at an unsure
* location. On the other hand, if you're sure that you're splitting on a
* character boundary (e.g. after using strpos() or similar), you can safely use
* substr() instead.
* character boundary (e.g. after using strpos() or similar), you can safely
* use substr() instead.
*
* @param $string
* The string to truncate.
......@@ -290,10 +294,10 @@ function drupal_truncate_bytes($string, $len) {
* non-Latin languages; see PREG_CLASS_UNICODE_WORD_BOUNDARY for more
* information. If a word boundary cannot be found that would make the length
* of the returned string fall within length guidelines (see parameters
* $max_return_length and $min_wordsafe_length), word boundaries are ignored.
* $max_length and $min_wordsafe_length), word boundaries are ignored.
* @param $add_ellipsis
* If TRUE, add t('...') to the end of the truncated string (defaults to
* FALSE). The string length will still fall within $max_return_length.
* FALSE). The string length will still fall within $max_length.
* @param $min_wordsafe_length
* If $wordsafe is TRUE, the minimum acceptable length for truncation (before
* adding an ellipsis, if $add_ellipsis is TRUE). Has no effect if $wordsafe
......@@ -307,7 +311,7 @@ function drupal_truncate_bytes($string, $len) {
* boundaries, giving you "See myverylongurl..." (assuming you had set
* $add_ellipses to TRUE).
*
* @return
* @return string
* The truncated string.
*/
function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis = FALSE, $min_wordsafe_length = 1) {
......@@ -357,8 +361,7 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
}
/**
* Encodes MIME/HTTP header values that contain non-ASCII, UTF-8 encoded
* characters.
* Encodes MIME/HTTP header values that contain incorrectly encoded characters.
*
* For example, mime_header_encode('tést.txt') returns "=?UTF-8?B?dMOpc3QudHh0?=".
*
......@@ -370,6 +373,14 @@ function truncate_utf8($string, $max_length, $wordsafe = FALSE, $add_ellipsis =
* each chunk starts and ends on a character boundary.
* - Using \n as the chunk separator may cause problems on some systems and may
* have to be changed to \r\n or \r.
*
* @param $string
* The header to encode.
*
* @return string
* The mime-encoded header.
*
* @see mime_header_decode()
*/
function mime_header_encode($string) {
if (preg_match('/[^\x20-\x7E]/', $string)) {
......@@ -389,7 +400,15 @@ function mime_header_encode($string) {
}
/**
* Complement to mime_header_encode
* Decodes MIME/HTTP encoded header values.
*
* @param $header
* The header to decode.
*
* @return string
* The mime-decoded header.
*
* @see mime_header_encode()
*/
function mime_header_decode($header) {
// First step: encoded chunks followed by other encoded chunks (need to collapse whitespace)
......@@ -399,7 +418,17 @@ function mime_header_decode($header) {
}
/**
* Helper function to mime_header_decode
* Decodes encoded header data passed from mime_header_decode().
*
* Callback for preg_replace_callback() within mime_header_decode().
*
* @param $matches
* The array of matches from preg_replace_callback().
*
* @return string
* The mime-decoded string.
*
* @see mime_header_decode()
*/
function _mime_header_decode($matches) {
// Regexp groups:
......@@ -416,9 +445,9 @@ function _mime_header_decode($matches) {
/**
* Decodes all HTML entities (including numerical ones) to regular UTF-8 bytes.
*
* Double-escaped entities will only be decoded once ("&amp;lt;" becomes "&lt;",
* not "<"). Be careful when using this function, as decode_entities can revert
* previous sanitization efforts (&lt;script&gt; will become <script>).
* Double-escaped entities will only be decoded once ("&amp;lt;" becomes "&lt;"
* , not "<"). Be careful when using this function, as decode_entities can
* revert previous sanitization efforts (&lt;script&gt; will become <script>).
*
* @param $text
* The text to decode entities in.
......@@ -431,8 +460,15 @@ function decode_entities($text) {
}
/**
* Count the amount of characters in a UTF-8 string. This is less than or
* equal to the byte count.
* Counts the number of characters in a UTF-8 string.
*
* This is less than or equal to the byte count.
*
* @param $text
* The string to run the operation on.
*
* @return integer
* The length of the string.
*
* @ingroup php_wrappers
*/
......@@ -450,6 +486,12 @@ function drupal_strlen($text) {
/**
* Uppercase a UTF-8 string.
*
* @param $text
* The string to run the operation on.
*
* @return string
* The string in uppercase.
*
* @ingroup php_wrappers
*/
function drupal_strtoupper($text) {
......@@ -469,6 +511,12 @@ function drupal_strtoupper($text) {
/**
* Lowercase a UTF-8 string.
*
* @param $text
* The string to run the operation on.
*
* @return string
* The string in lowercase.
*
* @ingroup php_wrappers
*/
function drupal_strtolower($text) {
......@@ -486,15 +534,28 @@ function drupal_strtolower($text) {
}
/**
* Helper function for case conversion of Latin-1.
* Used for flipping U+C0-U+DE to U+E0-U+FD and back.
* Flips U+C0-U+DE to U+E0-U+FD and back.
*
* @param $matches
* An array of matches.
*
* @return array
* The Latin-1 version of the array of matches.
*
* @see drupal_strtolower()
*/
function _unicode_caseflip($matches) {
return $matches[0][0] . chr(ord($matches[0][1]) ^ 32);
}
/**
* Capitalize the first letter of a UTF-8 string.
* Capitalizes the first letter of a UTF-8 string.
*
* @param $text
* The string to convert.
*
* @return
* The string with the first letter as uppercase.
*
* @ingroup php_wrappers
*/
......@@ -504,12 +565,21 @@ function drupal_ucfirst($text) {
}
/**
* Cut off a piece of a string based on character indices and counts. Follows
* the same behavior as PHP's own substr() function.
* Cuts off a piece of a string based on character indices and counts.
*
* Follows the same behavior as PHP's own substr() function. Note that for
* cutting off a string at a known character/substring location, the usage of
* PHP's normal strpos/substr is safe and much faster.
*
* Note that for cutting off a string at a known character/substring
* location, the usage of PHP's normal strpos/substr is safe and
* much faster.
* @param $text
* The input string.
* @param $start
* The position at which to start reading.
* @param $length
* The number of characters to read.
*
* @return
* The shortened string.
*
* @ingroup php_wrappers
*/
......
<?php
/**
* Special setup for UNL specific features.
*/
function unl_bootstrap() {
unl_bootstrap_short_hostname_redirect();
unl_bootstrap_multisite_without_symlinks();
unl_bootstrap_proxy_pass_support();
}
/**
* Check that the hostname resolves to an IP Address.
* If it doesn't redirect to <hostname>.unl.edu.
*/
function unl_bootstrap_short_hostname_redirect() {
// Don't do a redirect when using the command line.
if (PHP_SAPI == 'cli') {
return;
}
$hostname = $_SERVER['HTTP_HOST'];
if (gethostbynamel($hostname)) {
// The provided host name is just fine.
return;
}
// Otherwise, try adding .unl.edu.
$hostname .= '.unl.edu';
if (gethostbynamel($hostname)) {
// If its a valid domain, redirect to it.
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$uri = 'https://';
}
else {
$uri = 'http://';
}
$uri .= $hostname . $_SERVER['REQUEST_URI'];
header('Location: ' . $uri);
exit;
}
}
/**
* Enable the set up of multiple sites without making symbolics links.
* Instead, a few entries in .htaccess and sites.php will be all that is needed.
*/
function unl_bootstrap_multisite_without_symlinks() {
$original_script_name = $_SERVER['SCRIPT_NAME'];
$php_file = basename($original_script_name);
......@@ -37,3 +83,42 @@ function unl_bootstrap() {
conf_path(TRUE, TRUE);
}
/**
* Fix some paths when used through a ProxyPass.
*/
function unl_bootstrap_proxy_pass_support() {
if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && isset($_SERVER['HTTP_X_FORWARDED_PATH'])) {
$GLOBALS['base_url'] = 'http://' . $_SERVER['HTTP_X_FORWARDED_HOST'] . $_SERVER['HTTP_X_FORWARDED_PATH'];
$GLOBALS['cookie_domain'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_FORWARDED_PATH'] . '/' . request_path();
if (isset($_SERVER['QUERY_STRING'])) {
$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
}
}
}
/**
* This will be called during update.php's bootstrap to remove any
* shared table prefixes from the database config.
* This allows the same updates to be run on all sites, even if
* they would normally be applied to the same table.
*/
function unl_bootstrap_update() {
foreach ($GLOBALS['databases'] as $key1 => $databases) {
foreach ($databases as $key2 => $database) {
if ($key2 == 'slave') {
foreach ($database as $key3 => $slave) {
if (is_array($slave['prefix'])) {
$GLOBALS['databases'][$key1][$key2][$key3]['prefix'] = $slave['prefix']['default'];
}
}
}
else {
if (is_array($database['prefix'])) {
$GLOBALS['databases'][$key1][$key2]['prefix'] = $database['prefix']['default'];
}
}
}
}
}
<?php
// $Id: update.inc,v 1.78 2010/10/22 15:41:45 webchick Exp $
/**
* @file
......@@ -39,7 +38,7 @@ function update_fix_compatibility() {
}
/**
* Helper function to test compatibility of a module or theme.
* Tests the compatibility of a module or theme.
*/
function update_check_incompatibility($name, $type = 'module') {
static $themes, $modules;
......@@ -62,8 +61,7 @@ function update_check_incompatibility($name, $type = 'module') {
if (!isset($file)
|| !isset($file->info['core'])
|| $file->info['core'] != DRUPAL_CORE_COMPATIBILITY
|| version_compare(phpversion(), $file->info['php']) < 0
|| ($type == 'module' && empty($file->info['files']))) {
|| version_compare(phpversion(), $file->info['php']) < 0) {
return TRUE;
}
return FALSE;
......@@ -85,6 +83,8 @@ function update_prepare_d7_bootstrap() {
// still being used.
include_once DRUPAL_ROOT . '/includes/install.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
require_once DRUPAL_ROOT . '/includes/unl_bootstrap.inc';
unl_bootstrap_update();
global $databases, $db_url, $db_prefix, $update_rewrite_settings;
if (empty($databases) && !empty($db_url)) {
$databases = update_parse_db_url($db_url, $db_prefix);
......@@ -156,7 +156,38 @@ function update_prepare_d7_bootstrap() {
'description' => $has_required_schema ? '' : 'Please update your Drupal 6 installation to the most recent version before attempting to upgrade to Drupal 7',
),
);
// Make sure that the database environment is properly set up.
try {
db_run_tasks(db_driver());
}
catch (DatabaseTaskException $e) {
$requirements['database tasks'] = array(
'title' => 'Database environment',
'value' => 'There is a problem with your database environment',
'severity' => REQUIREMENT_ERROR,
'description' => $e->getMessage(),
);
}
update_extra_requirements($requirements);
// Allow a D6 session to work, since the upgrade has not been performed yet.
$d6_session_name = update_get_d6_session_name();
if (!empty($_COOKIE[$d6_session_name])) {
// Set the current sid to the one found in the D6 cookie.
$sid = $_COOKIE[$d6_session_name];
$_COOKIE[session_name()] = $sid;
session_id($sid);
}
// Upgrading from D6 to D7.{0,1,2,3,4,8,...} is different than upgrading
// from D6 to D7.{5,6,7} which should be considered broken. To be able to
// properly handle this difference in node_update_7012 we need to keep track
// of whether a D6 > D7 upgrade or a D7 > D7 update is running.
// Since variable_set() is not available here, the D6 status is being saved
// in a local variable to be able to store it later.
$update_d6 = TRUE;
}
// Create the registry tables.
......@@ -281,6 +312,11 @@ function update_prepare_d7_bootstrap() {
// Set the timezone for this request only.
$GLOBALS['conf']['date_default_timezone'] = 'UTC';
}
// This allows update functions to tell if an upgrade from D6 is running.
if (!empty($update_d6)) {
variable_set('update_d6', TRUE);
}
}
/**
......@@ -334,6 +370,12 @@ function update_fix_d7_block_deltas(&$sandbox, $renamed_deltas, $moved_deltas) {
))
->fetchField();
if ($block_exists) {
// Delete any existing blocks with the new module+delta.
db_delete($table)
->condition('module', $module)
->condition('delta', $new_delta)
->execute();
// Rename the old block to the new module+delta.
db_update($table)
->fields(array('delta' => $new_delta))
->condition('module', $module)
......@@ -351,6 +393,12 @@ function update_fix_d7_block_deltas(&$sandbox, $renamed_deltas, $moved_deltas) {
))
->fetchField();
if ($block_exists) {
// Delete any existing blocks with the new module+delta.
db_delete($table)
->condition('module', $new_module)
->condition('delta', $delta)
->execute();
// Rename the old block to the new module+delta.
db_update($table)
->fields(array('module' => $new_module))
->condition('module', $old_module)
......@@ -364,15 +412,18 @@ function update_fix_d7_block_deltas(&$sandbox, $renamed_deltas, $moved_deltas) {
// Initialize batch update information.
$sandbox['progress'] = 0;
$sandbox['last_user_processed'] = -1;
$sandbox['max'] = db_query("SELECT COUNT(*) FROM {users} WHERE data IS NOT NULL")->fetchField();
$sandbox['max'] = db_query("SELECT COUNT(*) FROM {users} WHERE data LIKE :block", array(
':block' => '%' . db_like(serialize('block')) . '%',
))
->fetchField();
}
// Now do the batch update of the user-specific block visibility settings.
$limit = 100;
$result = db_select('users', 'u')
->fields('u', array('uid', 'data'))
->condition('uid', $sandbox['last_user_processed'], '>')
->condition('data', '%' . db_like(serialize('block')) . '%', 'LIKE')
->orderBy('uid', 'ASC')
->where('data IS NOT NULL')
->range(0, $limit)
->execute();
foreach ($result as $row) {
......@@ -467,6 +518,9 @@ function update_fix_d7_requirements() {
db_add_index('system', 'system_list', array('weight', 'name'));
// Add the cache_path table.
if (db_table_exists('cache_path')) {
db_drop_table('cache_path');
}
require_once('./modules/system/system.install');
$schema['cache_path'] = system_schema_cache_7054();
$schema['cache_path']['description'] = 'Cache table used for path alias lookups.';
......@@ -694,15 +748,22 @@ function update_fix_d7_requirements() {
db_add_field('locales_source', 'context', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'The context this string applies to.'));
}
// Rename 'site_offline_message' variable to 'maintenance_mode_message'.
// Rename 'site_offline_message' variable to 'maintenance_mode_message'
// and 'site_offline' variable to 'maintenance_mode'.
// Old variable is removed in update for system.module, see
// system_update_7036().
// system_update_7072().
if ($message = variable_get('site_offline_message', NULL)) {
variable_set('maintenance_mode_message', $message);
}
// Old variable is removed in update for system.module, see
// system_update_7069().
$site_offline = variable_get('site_offline', -1);
if ($site_offline != -1) {
variable_set('maintenance_mode', $site_offline);
}
// Add ssid column and index.
db_add_field('sessions', 'ssid', array('description' => "Secure session ID. The value is generated by PHP's Session API.", 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
db_add_field('sessions', 'ssid', array('description' => "Secure session ID. The value is generated by Drupal's session handlers.", 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
db_add_index('sessions', 'ssid', array('ssid'));
// Drop existing primary key.
db_drop_primary_key('sessions');
......@@ -726,12 +787,12 @@ function update_fix_d7_requirements() {
/**
* Register the currently installed profile in the system table.
*
* Install profiles are now treated as modules by Drupal, and have an upgrade
* path based on their schema version in the system table.
* Installation profiles are now treated as modules by Drupal, and have an
* upgrade path based on their schema version in the system table.
*
* The install profile will be set to schema_version 0, as it has already been
* installed. Any other hook_update_N functions provided by the install profile
* will be run by update.php.
* The installation profile will be set to schema_version 0, as it has already
* been installed. Any other hook_update_N functions provided by the
* installation profile will be run by update.php.
*/
function update_fix_d7_install_profile() {
$profile = drupal_get_profile();
......@@ -759,9 +820,6 @@ function update_fix_d7_install_profile() {
'files' => array(),
);
// The install profile is always required.
$file->info['required'] = TRUE;
$values = array(
'filename' => $filename,
'name' => $profile,
......@@ -772,10 +830,10 @@ function update_fix_d7_install_profile() {
'owner' => '',
);
// Install profile hooks are always executed last by the module system
// Installation profile hooks are always executed last by the module system
$values['weight'] = 1000;
// Initializing the system table entry for the install profile
// Initializing the system table entry for the installation profile
db_insert('system')
->fields(array_keys($values))
->values($values)
......@@ -784,7 +842,8 @@ function update_fix_d7_install_profile() {
// Reset the cached schema version.
drupal_get_installed_schema_version($profile, TRUE);
// Load the updates again to make sure the install profile updates are loaded
// Load the updates again to make sure the installation profile updates
// are loaded.
drupal_load_updates();
}
}
......@@ -820,7 +879,38 @@ function update_parse_db_url($db_url, $db_prefix) {
}
/**
* Perform one update and store the results for display on finished page.
* Constructs a session name compatible with a D6 environment.
*
* @return
* D6-compatible session name string.
*
* @see drupal_settings_initialize()
*/
function update_get_d6_session_name() {
global $base_url, $cookie_domain;
$cookie_secure = ini_get('session.cookie_secure');
// If a custom cookie domain is set in settings.php, that variable forms
// the basis of the session name. Re-compute the D7 hashing method to find
// out if $cookie_domain was used as the session name.
if (($cookie_secure ? 'SSESS' : 'SESS') . substr(hash('sha256', $cookie_domain), 0, 32) == session_name()) {
$session_name = $cookie_domain;
}
else {
// Otherwise use $base_url as session name, without the protocol
// to use the same session identifiers across HTTP and HTTPS.
list( , $session_name) = explode('://', $base_url, 2);
}
if ($cookie_secure) {
$session_name .= 'SSL';
}
return 'SESS' . md5($session_name);
}
/**
* Performs one update and stores the results for display on the results page.
*
* If an update function completes successfully, it should return a message
* as a string indicating success, for example:
......@@ -883,7 +973,8 @@ function update_do_one($module, $number, $dependency_map, &$context) {
require_once DRUPAL_ROOT . '/includes/errors.inc';
$variables = _drupal_decode_exception($e);
$ret['#abort'] = array('success' => FALSE, 'query' => t('%type: %message in %function (line %line of %file).', $variables));
// The exception message is run through check_plain() by _drupal_decode_exception().
$ret['#abort'] = array('success' => FALSE, 'query' => t('%type: !message in %function (line %line of %file).', $variables));
}
}
......@@ -919,7 +1010,7 @@ function update_do_one($module, $number, $dependency_map, &$context) {
class DrupalUpdateException extends Exception { }
/**
* Start the database update batch process.
* Starts the database update batch process.
*
* @param $start
* An array whose keys contain the names of modules to be updated during the
......@@ -989,7 +1080,7 @@ function update_batch($start, $redirect = NULL, $url = NULL, $batch = array(), $
}
/**
* Finish the update process and store results for eventual display.
* Finishes the update process and stores the results for eventual display.
*
* After the updates run, all caches are flushed. The update results are
* stored into the session (for example, to be displayed on the update results
......@@ -1006,6 +1097,10 @@ function update_batch($start, $redirect = NULL, $url = NULL, $batch = array(), $
* @see update_batch()
*/
function update_finished($success, $results, $operations) {
// Remove the D6 upgrade flag variable so that subsequent update runs do not
// get the wrong context.
variable_del('update_d6');
// Clear the caches in case the data has been updated.
drupal_flush_all_caches();
......@@ -1022,7 +1117,7 @@ function update_finished($success, $results, $operations) {
}
/**
* Return a list of all the pending database updates.
* Returns a list of all the pending database updates.
*
* @return
* An associative array keyed by module name which contains all information
......@@ -1316,7 +1411,7 @@ function update_already_performed($module, $number) {
}
/**
* Invoke hook_update_dependencies() in all installed modules.
* Invokes hook_update_dependencies() in all installed modules.
*
* This function is similar to module_invoke_all(), with the main difference
* that it does not require that a module be enabled to invoke its hook, only
......@@ -1334,7 +1429,7 @@ function update_retrieve_dependencies() {
$return = array();
// Get a list of installed modules, arranged so that we invoke their hooks in
// the same order that module_invoke_all() does.
$modules = db_query("SELECT name FROM {system} WHERE type = 'module' AND schema_version != :schema ORDER BY weight ASC, name ASC", array(':schema' => SCHEMA_UNINSTALLED))->fetchCol();
$modules = db_query("SELECT name FROM {system} WHERE type = 'module' AND schema_version <> :schema ORDER BY weight ASC, name ASC", array(':schema' => SCHEMA_UNINSTALLED))->fetchCol();
foreach ($modules as $module) {
$function = $module . '_update_dependencies';
if (function_exists($function)) {
......@@ -1382,17 +1477,3 @@ function update_retrieve_dependencies() {
return $return;
}
/**
* @defgroup update-api-6.x-to-7.x Update versions of API functions.
* @{
* Functions similar to normal API function but not firing hooks.
*
* During update, it is impossible to judge the consequences of firing a hook
* as it might hit a module not yet updated. So simplified versions of some
* core APIs are provided.
*/
/**
* @} End of "defgroup update-api-6.x-to-7.x"
*/
<?php
// $Id: updater.inc,v 1.7 2010/09/01 20:08:17 dries Exp $
/**
* @file
......@@ -137,12 +136,12 @@ class Updater {
* Path to the info file.
*/
public static function findInfoFile($directory) {
$info_files = file_scan_directory($directory, '/.*\.info/');
$info_files = file_scan_directory($directory, '/.*\.info$/');
if (!$info_files) {
return FALSE;
}
foreach ($info_files as $info_file) {
if (drupal_substr($info_file->filename, 0, -5) == basename($directory)) {
if (drupal_substr($info_file->filename, 0, -5) == drupal_basename($directory)) {
// Info file Has the same name as the directory, return it.
return $info_file->uri;
}
......@@ -164,7 +163,7 @@ class Updater {
* The name of the project.
*/
public static function getProjectName($directory) {
return basename($directory);
return drupal_basename($directory);
}
/**
......@@ -179,8 +178,11 @@ class Updater {
public static function getProjectTitle($directory) {
$info_file = self::findInfoFile($directory);
$info = drupal_parse_info_file($info_file);
if (!$info) {
throw new UpdaterException(t('Unable to parse info file.'));
if (empty($info)) {
throw new UpdaterException(t('Unable to parse info file: %info_file.', array('%info_file' => $info_file)));
}
if (empty($info['name'])) {
throw new UpdaterException(t("The info file (%info_file) does not define a 'name' attribute.", array('%info_file' => $info_file)));
}
return $info['name'];
}
......@@ -328,7 +330,7 @@ class Updater {
}
catch (FileTransferException $e) {
$message = t($e->getMessage(), $e->arguments);
$throw_message = t('Unable to create %directory due to the following: %reason', array('%directory' => $install_location, '%reason' => $message));
$throw_message = t('Unable to create %directory due to the following: %reason', array('%directory' => $directory, '%reason' => $message));
throw new UpdaterException($throw_message);
}
}
......
<?php
// $Id: utility.inc,v 1.2 2010/07/24 17:28:25 dries Exp $
/**
* @file
......@@ -12,7 +11,8 @@
* @param $var
* The variable to export.
* @param $prefix
* A prefix that will be added at the begining of every lines of the output.
* A prefix that will be added at the beginning of every lines of the output.
*
* @return
* The variable exported in a way compatible to Drupal's coding standards.
*/
......@@ -47,6 +47,13 @@ function drupal_var_export($var, $prefix = '') {
$output = "'" . $var . "'";
}
}
elseif (is_object($var) && get_class($var) === 'stdClass') {
// var_export() will export stdClass objects using an undefined
// magic method __set_state() leaving the export broken. This
// workaround avoids this by casting the object as an array for
// export and casting it back to an object when evaluated.
$output = '(object) ' . drupal_var_export((array) $var, $prefix);
}
else {
$output = var_export($var, TRUE);
}
......
<?php
// $Id: xmlrpc.inc,v 1.69 2010/08/14 03:15:01 dries Exp $
/**
* @file
......@@ -623,4 +622,3 @@ function xmlrpc_error_msg() {
function xmlrpc_clear_error() {
xmlrpc_error(NULL, NULL, TRUE);
}
<?php
// $Id: xmlrpcs.inc,v 1.42 2010/10/02 01:22:41 dries Exp $
/**
* @file
......@@ -337,7 +336,7 @@ function xmlrpc_server_get_capabilities() {
}
/**
* Returns the method signature of a function.
* Returns one method signature for a function.
*
* This is the function mapped to the XML-RPC method system.methodSignature.
*
......@@ -349,8 +348,8 @@ function xmlrpc_server_get_capabilities() {
* Name of method to return a method signature for.
*
* @return array
* An array of types representing the method signature of the function that
* $methodname maps to.
* An array of arrays of types, each of the arrays representing one method
* signature of the function that $methodname maps to.
*/
function xmlrpc_server_method_signature($methodname) {
$xmlrpc_server = xmlrpc_server_get();
......@@ -365,7 +364,7 @@ function xmlrpc_server_method_signature($methodname) {
foreach ($xmlrpc_server->signatures[$methodname] as $type) {
$return[] = $type;
}
return $return;
return array($return);
}
/**
......@@ -383,4 +382,3 @@ function xmlrpc_server_method_help($method) {
$xmlrpc_server = xmlrpc_server_get();
return $xmlrpc_server->help[$method];
}
<?php
// $Id: index.php,v 1.99 2009/10/15 14:07:25 dries Exp $
/**
* @file
......
<?php
// $Id: install.php,v 1.238 2010/10/22 02:53:19 webchick Exp $
/**
* @file
......@@ -7,12 +6,12 @@
*/
/**
* Root directory of Drupal installation.
* Defines the root directory of the Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());
/**
* Global flag to indicate that site is in installation mode.
* Global flag to indicate the site is in installation mode.
*/
define('MAINTENANCE_MODE', 'install');
......
// $Id: ajax.js,v 1.25 2010/10/21 19:31:39 dries Exp $
(function ($) {
/**
* Provides AJAX page updating via jQuery $.ajax (Asynchronous JavaScript and XML).
* Provides Ajax page updating via jQuery $.ajax (Asynchronous JavaScript and XML).
*
* AJAX is a method of making a request via Javascript while viewing an HTML
* Ajax is a method of making a request via JavaScript while viewing an HTML
* page. The request returns an array of commands encoded in JSON, which is
* then executed to make any changes that are necessary to the page.
*
* Drupal uses this file to enhance form elements with #ajax['path'] and
* #ajax['wrapper'] properties. If set, this file will automatically be included
* to provide AJAX capabilities.
* to provide Ajax capabilities.
*/
Drupal.ajax = Drupal.ajax || {};
/**
* Attaches the AJAX behavior to each AJAX form element.
* Attaches the Ajax behavior to each Ajax form element.
*/
Drupal.behaviors.AJAX = {
attach: function (context, settings) {
// Load all AJAX behaviors specified in the settings.
// Load all Ajax behaviors specified in the settings.
for (var base in settings.ajax) {
if (!$('#' + base + '.ajax-processed').length) {
var element_settings = settings.ajax[base];
if (typeof element_settings.selector == 'undefined') {
element_settings.selector = '#' + base;
}
$(element_settings.selector).each(function () {
element_settings.element = this;
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
......@@ -34,9 +36,11 @@ Drupal.behaviors.AJAX = {
}
}
// Bind AJAX behaviors to all items showing the class.
// Bind Ajax behaviors to all items showing the class.
$('.use-ajax:not(.ajax-processed)').addClass('ajax-processed').each(function () {
var element_settings = {};
// Clicked links look better with the throbber than the progress bar.
element_settings.progress = { 'type': 'throbber' };
// For anchor tags, these will go to the target of the anchor rather
// than the usual location.
......@@ -48,11 +52,11 @@ Drupal.behaviors.AJAX = {
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
});
// This class means to submit the form to the action using AJAX.
// This class means to submit the form to the action using Ajax.
$('.use-ajax-submit:not(.ajax-processed)').addClass('ajax-processed').each(function () {
var element_settings = {};
// AJAX submits specified in this manner automatically submit to the
// Ajax submits specified in this manner automatically submit to the
// normal form action.
element_settings.url = $(this.form).attr('action');
// Form submit button clicks need to tell the form what was clicked so
......@@ -70,13 +74,13 @@ Drupal.behaviors.AJAX = {
};
/**
* AJAX object.
* Ajax object.
*
* All AJAX objects on a page are accessible through the global Drupal.ajax
* All Ajax objects on a page are accessible through the global Drupal.ajax
* object and are keyed by the submit button's ID. You can access them from
* your module's JavaScript file to override properties or functions.
*
* For example, if your AJAX enabled button has the ID 'edit-submit', you can
* For example, if your Ajax enabled button has the ID 'edit-submit', you can
* redefine the function that is called to insert the new content like this
* (inside a Drupal.behaviors attach block):
* @code
......@@ -98,11 +102,11 @@ Drupal.ajax = function (base, element, element_settings) {
keypress: true,
selector: '#' + base,
effect: 'none',
speed: 'slow',
speed: 'none',
method: 'replaceWith',
progress: {
type: 'bar',
message: 'Please wait...'
type: 'throbber',
message: Drupal.t('Please wait...')
},
submit: {
'js': true
......@@ -112,14 +116,24 @@ Drupal.ajax = function (base, element, element_settings) {
$.extend(this, defaults, element_settings);
this.element = element;
this.element_settings = element_settings;
// Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let
// the server detect when it needs to degrade gracefully.
this.url = element_settings.url.replace(/\/nojs(\/|$)/g, '/ajax$1');
// There are five scenarios to check for:
// 1. /nojs/
// 2. /nojs$ - The end of a URL string.
// 3. /nojs? - Followed by a query (with clean URLs enabled).
// E.g.: path/nojs?destination=foobar
// 4. /nojs& - Followed by a query (without clean URLs enabled).
// E.g.: ?q=path/nojs&destination=foobar
// 5. /nojs# - Followed by a fragment.
// E.g.: path/nojs#myfragment
this.url = element_settings.url.replace(/\/nojs(\/|$|\?|&|#)/g, '/ajax$1');
this.wrapper = '#' + element_settings.wrapper;
// If there isn't a form, jQuery.ajax() will be used instead, allowing us to
// bind AJAX to links as well.
// bind Ajax to links as well.
if (this.element.form) {
this.form = $(this.element.form);
}
......@@ -137,6 +151,10 @@ Drupal.ajax = function (base, element, element_settings) {
ajax.ajaxing = true;
return ajax.beforeSubmit(form_values, element_settings, options);
},
beforeSend: function (xmlhttprequest, options) {
ajax.ajaxing = true;
return ajax.beforeSend(xmlhttprequest, options);
},
success: function (response, status) {
// Sanity check for browser support (object expected).
// When using iFrame uploads, responses must be returned as a string.
......@@ -156,7 +174,64 @@ Drupal.ajax = function (base, element, element_settings) {
};
// Bind the ajaxSubmit function to the element event.
$(this.element).bind(element_settings.event, function () {
$(ajax.element).bind(element_settings.event, function (event) {
return ajax.eventResponse(this, event);
});
// If necessary, enable keyboard submission so that Ajax behaviors
// can be triggered through keyboard input as well as e.g. a mousedown
// action.
if (element_settings.keypress) {
$(ajax.element).keypress(function (event) {
return ajax.keypressResponse(this, event);
});
}
// If necessary, prevent the browser default action of an additional event.
// For example, prevent the browser default action of a click, even if the
// AJAX behavior binds to mousedown.
if (element_settings.prevent) {
$(ajax.element).bind(element_settings.prevent, false);
}
};
/**
* Handle a key press.
*
* The Ajax object will, if instructed, bind to a key press response. This
* will test to see if the key press is valid to trigger this event and
* if it is, trigger it for us and prevent other keypresses from triggering.
* In this case we're handling RETURN and SPACEBAR keypresses (event codes 13
* and 32. RETURN is often used to submit a form when in a textfield, and
* SPACE is often used to activate an element without submitting.
*/
Drupal.ajax.prototype.keypressResponse = function (element, event) {
// Create a synonym for this to reduce code confusion.
var ajax = this;
// Detect enter key and space bar and allow the standard response for them,
// except for form elements of type 'text' and 'textarea', where the
// spacebar activation causes inappropriate activation if #ajax['keypress'] is
// TRUE. On a text-type widget a space should always be a space.
if (event.which == 13 || (event.which == 32 && element.type != 'text' && element.type != 'textarea')) {
$(ajax.element_settings.element).trigger(ajax.element_settings.event);
return false;
}
};
/**
* Handle an event that triggers an Ajax response.
*
* When an event that triggers an Ajax response happens, this method will
* perform the actual Ajax call. It is bound to the event using
* bind() in the constructor, and it uses the options specified on the
* ajax object.
*/
Drupal.ajax.prototype.eventResponse = function (element, event) {
// Create a synonym for this to reduce code confusion.
var ajax = this;
// Do not perform another ajax command if one is already in progress.
if (ajax.ajaxing) {
return false;
}
......@@ -170,7 +245,7 @@ Drupal.ajax = function (base, element, element_settings) {
// ajaxSubmit that tells the system which element got clicked to
// trigger the submit. Without it there would be no 'op' or
// equivalent.
this.form.clk = this;
element.form.clk = element;
}
ajax.form.ajaxSubmit(ajax.options);
......@@ -181,30 +256,27 @@ Drupal.ajax = function (base, element, element_settings) {
}
}
catch (e) {
// Unset the ajax.ajaxing flag here because it won't be unset during
// the complete response.
ajax.ajaxing = false;
alert("An error occurred while attempting to process " + ajax.options.url + ": " + e.message);
}
return false;
});
// If necessary, enable keyboard submission so that AJAX behaviors
// can be triggered through keyboard input as well as e.g. a mousedown
// action.
if (element_settings.keypress) {
$(element_settings.element).keypress(function (event) {
// Detect enter key.
if (event.keyCode == 13) {
$(element_settings.element).trigger(element_settings.event);
return false;
// For radio/checkbox, allow the default event. On IE, this means letting
// it actually check the box.
if (typeof element.type != 'undefined' && (element.type == 'checkbox' || element.type == 'radio')) {
return true;
}
});
else {
return false;
}
};
/**
* Handler for the form serialization.
*
* Runs before the beforeSubmit() handler (see below), and unlike that one, runs
* Runs before the beforeSend() handler (see below), and unlike that one, runs
* before field data is collected.
*/
Drupal.ajax.prototype.beforeSerialize = function (element, options) {
......@@ -241,10 +313,49 @@ Drupal.ajax.prototype.beforeSerialize = function (element, options) {
};
/**
* Handler for the form redirection submission.
* Modify form values prior to form submission.
*/
Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
// Disable the element that received the change.
// This function is left empty to make it simple to override for modules
// that wish to add functionality here.
};
/**
* Prepare the Ajax request before it is sent.
*/
Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) {
// For forms without file inputs, the jQuery Form plugin serializes the form
// values, and then calls jQuery's $.ajax() function, which invokes this
// handler. In this circumstance, options.extraData is never used. For forms
// with file inputs, the jQuery Form plugin uses the browser's normal form
// submission mechanism, but captures the response in a hidden IFRAME. In this
// circumstance, it calls this handler first, and then appends hidden fields
// to the form to submit the values in options.extraData. There is no simple
// way to know which submission mechanism will be used, so we add to extraData
// regardless, and allow it to be ignored in the former case.
if (this.form) {
options.extraData = options.extraData || {};
// Let the server know when the IFRAME submission mechanism is used. The
// server can use this information to wrap the JSON response in a TEXTAREA,
// as per http://jquery.malsup.com/form/#file-upload.
options.extraData.ajax_iframe_upload = '1';
// The triggering element is about to be disabled (see below), but if it
// contains a value (e.g., a checkbox, textfield, select, etc.), ensure that
// value is included in the submission. As per above, submissions that use
// $.ajax() are already serialized prior to the element being disabled, so
// this is only needed for IFRAME submissions.
var v = $.fieldValue(this.element);
if (v !== null) {
options.extraData[this.element.name] = v;
}
}
// Disable the element that received the change to prevent user interface
// interaction while the Ajax request is in progress. ajax.ajaxing prevents
// the element from triggering a new request, but does not prevent the user
// from changing its value.
$(this.element).addClass('progress-disabled').attr('disabled', true);
// Insert progressbar or throbber.
......@@ -280,12 +391,12 @@ Drupal.ajax.prototype.success = function (response, status) {
if (this.progress.object) {
this.progress.object.stopMonitoring();
}
$(this.element).removeClass('progress-disabled').attr('disabled', false);
$(this.element).removeClass('progress-disabled').removeAttr('disabled');
Drupal.freezeHeight();
for (var i in response) {
if (response[i]['command'] && this.commands[response[i]['command']]) {
if (response.hasOwnProperty(i) && response[i]['command'] && this.commands[response[i]['command']]) {
this.commands[response[i]['command']](this, response[i], status);
}
}
......@@ -348,7 +459,7 @@ Drupal.ajax.prototype.error = function (response, uri) {
// Undo hide.
$(this.wrapper).show();
// Re-enable the element.
$(this.element).removeClass('progress-disabled').attr('disabled', false);
$(this.element).removeClass('progress-disabled').removeAttr('disabled');
// Reattach behaviors, if they were detached in beforeSerialize().
if (this.form) {
var settings = response.settings || this.settings || Drupal.settings;
......@@ -383,7 +494,7 @@ Drupal.ajax.prototype.commands = {
// sufficiently tested whether attachBehaviors() can be successfully called
// with a context object that includes top-level text nodes. However, to
// give developers full control of the HTML appearing in the page, and to
// enable AJAX content to be inserted in places where DIV elements are not
// enable Ajax content to be inserted in places where DIV elements are not
// allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new
// content satisfies the requirement of a single top-level element, and
// only use the container DIV created above when it doesn't. For more
......@@ -486,6 +597,14 @@ Drupal.ajax.prototype.commands = {
$(response.selector).data(response.name, response.value);
},
/**
* Command to apply a jQuery method.
*/
invoke: function (ajax, response, status) {
var $element = $(response.selector);
$element[response.method].apply($element, response.arguments);
},
/**
* Command to restripe a table.
*/
......
// $Id: authorize.js,v 1.3 2010/01/04 16:08:52 webchick Exp $
/**
* @file
......@@ -17,7 +16,6 @@ Drupal.behaviors.authorizeFileTransferForm = {
// Removes the float on the select box (used for non-JS interface).
if ($('.connection-settings-update-filetransfer-default-wrapper').length > 0) {
console.log($('.connection-settings-update-filetransfer-default-wrapper'));
$('.connection-settings-update-filetransfer-default-wrapper').css('float', 'none');
}
// Hides the submit button for non-js users.
......
// $Id: autocomplete.js,v 1.37 2010/06/13 05:31:02 dries Exp $
(function ($) {
/**
......@@ -12,10 +11,16 @@ Drupal.behaviors.autocomplete = {
if (!acdb[uri]) {
acdb[uri] = new Drupal.ACDB(uri);
}
var input = $('#' + this.id.substr(0, this.id.length - 13))
.attr('autocomplete', 'OFF')[0];
$(input.form).submit(Drupal.autocompleteSubmit);
new Drupal.jsAC(input, acdb[uri]);
var $input = $('#' + this.id.substr(0, this.id.length - 13))
.attr('autocomplete', 'OFF')
.attr('aria-autocomplete', 'list');
$($input[0].form).submit(Drupal.autocompleteSubmit);
$input.parent()
.attr('role', 'application')
.append($('<span class="element-invisible" aria-live="assertive"></span>')
.attr('id', $input.attr('id') + '-autocomplete-aria-live')
);
new Drupal.jsAC($input, acdb[uri]);
});
}
};
......@@ -27,18 +32,19 @@ Drupal.behaviors.autocomplete = {
Drupal.autocompleteSubmit = function () {
return $('#autocomplete').each(function () {
this.owner.hidePopup();
}).size() == 0;
}).length == 0;
};
/**
* An AutoComplete object.
*/
Drupal.jsAC = function (input, db) {
Drupal.jsAC = function ($input, db) {
var ac = this;
this.input = input;
this.input = $input[0];
this.ariaLive = $('#' + this.input.id + '-autocomplete-aria-live');
this.db = db;
$(this.input)
$input
.keydown(function (event) { return ac.onkeydown(this, event); })
.keyup(function (event) { ac.onkeyup(this, event); })
.blur(function () { ac.hidePopup(); ac.db.cancel(); });
......@@ -93,10 +99,12 @@ Drupal.jsAC.prototype.onkeyup = function (input, e) {
return true;
default: // All other keys.
if (input.value.length > 0)
if (input.value.length > 0 && !input.readOnly) {
this.populatePopup();
else
}
else {
this.hidePopup(e.keyCode);
}
return true;
}
};
......@@ -117,7 +125,7 @@ Drupal.jsAC.prototype.selectDown = function () {
}
else if (this.popup) {
var lis = $('li', this.popup);
if (lis.size() > 0) {
if (lis.length > 0) {
this.highlight(lis.get(0));
}
}
......@@ -141,6 +149,7 @@ Drupal.jsAC.prototype.highlight = function (node) {
}
$(node).addClass('selected');
this.selected = node;
$(this.ariaLive).html($(this.selected).html());
};
/**
......@@ -149,6 +158,7 @@ Drupal.jsAC.prototype.highlight = function (node) {
Drupal.jsAC.prototype.unhighlight = function (node) {
$(node).removeClass('selected');
this.selected = false;
$(this.ariaLive).empty();
};
/**
......@@ -166,12 +176,15 @@ Drupal.jsAC.prototype.hidePopup = function (keycode) {
$(popup).fadeOut('fast', function () { $(popup).remove(); });
}
this.selected = false;
$(this.ariaLive).empty();
};
/**
* Positions the suggestions popup and starts a search.
*/
Drupal.jsAC.prototype.populatePopup = function () {
var $input = $(this.input);
var position = $input.position();
// Show popup.
if (this.popup) {
$(this.popup).remove();
......@@ -180,11 +193,12 @@ Drupal.jsAC.prototype.populatePopup = function () {
this.popup = $('<div id="autocomplete"></div>')[0];
this.popup.owner = this;
$(this.popup).css({
marginTop: this.input.offsetHeight + 'px',
width: (this.input.offsetWidth - 4) + 'px',
top: parseInt(position.top + this.input.offsetHeight, 10) + 'px',
left: parseInt(position.left, 10) + 'px',
width: $input.innerWidth() + 'px',
display: 'none'
});
$(this.input).before(this.popup);
$input.before(this.popup);
// Do search.
this.db.owner = this;
......@@ -215,8 +229,9 @@ Drupal.jsAC.prototype.found = function (matches) {
// Show popup with matches, if any.
if (this.popup) {
if (ul.children().size()) {
if (ul.children().length) {
$(this.popup).empty().append(ul).show();
$(this.ariaLive).html(Drupal.t('Autocomplete popup'));
}
else {
$(this.popup).css({ visibility: 'hidden' });
......@@ -229,6 +244,7 @@ Drupal.jsAC.prototype.setStatus = function (status) {
switch (status) {
case 'begin':
$(this.input).addClass('throbbing');
$(this.ariaLive).html(Drupal.t('Searching for matches...'));
break;
case 'cancel':
case 'error':
......@@ -273,10 +289,11 @@ Drupal.ACDB.prototype.search = function (searchString) {
this.timer = setTimeout(function () {
db.owner.setStatus('begin');
// Ajax GET request for autocompletion.
// Ajax GET request for autocompletion. We use Drupal.encodePath instead of
// encodeURIComponent to allow autocomplete search terms to contain slashes.
$.ajax({
type: 'GET',
url: db.uri + '/' + encodeURIComponent(searchString),
url: db.uri + '/' + Drupal.encodePath(searchString),
dataType: 'json',
success: function (matches) {
if (typeof matches.status == 'undefined' || matches.status != 0) {
......
// $Id: batch.js,v 1.10 2009/08/31 05:51:07 dries Exp $
(function ($) {
/**
......
// $Id: collapse.js,v 1.32 2010/05/14 16:45:56 dries Exp $
(function ($) {
/**
......@@ -59,9 +58,9 @@ Drupal.behaviors.collapse = {
$('fieldset.collapsible', context).once('collapse', function () {
var $fieldset = $(this);
// Expand fieldset if there are errors inside, or if it contains an
// element that is targeted by the uri fragment identifier.
// element that is targeted by the URI fragment identifier.
var anchor = location.hash && location.hash != '#' ? ', ' + location.hash : '';
if ($('.error' + anchor, $fieldset).length) {
if ($fieldset.find('.error' + anchor).length) {
$fieldset.removeClass('collapsed');
}
......
misc/configure.png

630 B | W: 0px | H: 0px

misc/configure.png

248 B | W: 0px | H: 0px

misc/configure.png
misc/configure.png
misc/configure.png
misc/configure.png
  • 2-up
  • Swipe
  • Onion skin
misc/draggable.png

338 B | W: 0px | H: 0px

misc/draggable.png

268 B | W: 0px | H: 0px

misc/draggable.png
misc/draggable.png
misc/draggable.png
misc/draggable.png
  • 2-up
  • Swipe
  • Onion skin
// $Id: drupal.js,v 1.69 2010/07/28 01:38:28 dries Exp $
var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'locale': {} };
......@@ -7,11 +6,32 @@ jQuery.noConflict();
(function ($) {
/**
* Override jQuery.fn.init to guard against XSS attacks.
*
* See http://bugs.jquery.com/ticket/9521
*/
var jquery_init = $.fn.init;
$.fn.init = function (selector, context, rootjQuery) {
// If the string contains a "#" before a "<", treat it as invalid HTML.
if (selector && typeof selector === 'string') {
var hash_position = selector.indexOf('#');
if (hash_position >= 0) {
var bracket_position = selector.indexOf('<');
if (bracket_position > hash_position) {
throw 'Syntax error, unrecognized expression: ' + selector;
}
}
}
return jquery_init.call(this, selector, context, rootjQuery);
};
$.fn.init.prototype = jquery_init.prototype;
/**
* Attach all registered behaviors to a page element.
*
* Behaviors are event-triggered actions that attach to page elements, enhancing
* default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors
* default non-JavaScript UIs. Behaviors are registered in the Drupal.behaviors
* object using the method 'attach' and optionally also 'detach' as follows:
* @code
* Drupal.behaviors.behaviorName = {
......@@ -25,7 +45,7 @@ jQuery.noConflict();
* @endcode
*
* Drupal.attachBehaviors is added below to the jQuery ready event and so
* runs on initial page load. Developers implementing AHAH/AJAX in their
* runs on initial page load. Developers implementing AHAH/Ajax in their
* solutions should also call this function after new page content has been
* loaded, feeding in an element to be processed, in order to attach all
* behaviors to the new content.
......@@ -61,7 +81,7 @@ Drupal.attachBehaviors = function (context, settings) {
/**
* Detach registered behaviors from a page element.
*
* Developers implementing AHAH/AJAX in their solutions should call this
* Developers implementing AHAH/Ajax in their solutions should call this
* function before page content is about to be removed, feeding in an element
* to be processed, in order to allow special behaviors to detach from the
* content.
......@@ -89,7 +109,7 @@ Drupal.attachBehaviors = function (context, settings) {
* IFRAME elements reload their "src" when being moved within the DOM,
* behaviors bound to IFRAME elements (like WYSIWYG editors) may need to
* take some action.
* - serialize: When an AJAX form is submitted, this is called with the
* - serialize: When an Ajax form is submitted, this is called with the
* form as the context. This provides every behavior within the form an
* opportunity to ensure that the field elements have correct content
* in them before the form is serialized. The canonical use-case is so
......@@ -112,42 +132,40 @@ Drupal.detachBehaviors = function (context, settings, trigger) {
/**
* Encode special characters in a plain-text string for display as HTML.
*
* @ingroup sanitization
*/
Drupal.checkPlain = function (str) {
var character, regex,
replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
str = String(str);
var replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
for (var character in replace) {
var regex = new RegExp(character, 'g');
for (character in replace) {
if (replace.hasOwnProperty(character)) {
regex = new RegExp(character, 'g');
str = str.replace(regex, 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.
* Replace placeholders with sanitized values in a string.
*
* @param str
* A string containing the English string to translate.
* A string with placeholders.
* @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:
* An object of replacements pairs to make. 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.
*
* @see Drupal.t()
* @ingroup sanitization
*/
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) {
Drupal.formatString = function(str, args) {
// Transform arguments before inserting them.
for (var key in args) {
switch (key.charAt(0)) {
......@@ -166,6 +184,39 @@ Drupal.t = function (str, args) {
}
str = str.replace(key, args[key]);
}
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.
* See Drupal.formatString().
*
* @param options
* - 'context' (defaults to the empty context): The context the source string
* belongs to.
*
* @return
* The translated string.
*/
Drupal.t = function (str, args, options) {
options = options || {};
options.context = options.context || '';
// Fetch the localized version of the string.
if (Drupal.locale.strings && Drupal.locale.strings[options.context] && Drupal.locale.strings[options.context][str]) {
str = Drupal.locale.strings[options.context][str];
}
if (args) {
str = Drupal.formatString(str, args);
}
return str;
};
......@@ -191,32 +242,30 @@ Drupal.t = function (str, args) {
* @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'))
* See Drupal.formatString().
* Note that you do not need to include @count in this array.
* This replacement is done automatically for the plural case.
* @param options
* The options to pass to the Drupal.t() function.
* @return
* A translated string.
*/
Drupal.formatPlural = function (count, singular, plural, args) {
Drupal.formatPlural = function (count, singular, plural, args, options) {
var args = args || {};
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);
return Drupal.t(singular, args, options);
}
else if (index == 1) {
return Drupal.t(plural, args);
return Drupal.t(plural, args, options);
}
else {
args['@count[' + index + ']'] = args['@count'];
delete args['@count'];
return Drupal.t(plural.replace('@count', '@count[' + index + ']'), args);
return Drupal.t(plural.replace('@count', '@count[' + index + ']'), args, options);
}
};
......@@ -228,8 +277,9 @@ Drupal.formatPlural = function (count, singular, plural, args) {
* 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).
* For example, to retrieve the HTML for text that should be emphasized and
* displayed as a placeholder inside a sentence, call
* Drupal.theme('placeholder', text).
*
* @param func
* The name of the theme function to call.
......@@ -240,9 +290,7 @@ Drupal.formatPlural = function (count, singular, plural, args) {
* but also a complex object.
*/
Drupal.theme = function (func) {
for (var i = 1, args = []; i < arguments.length; i++) {
args.push(arguments[i]);
}
var args = Array.prototype.slice.apply(arguments, [1]);
return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args);
};
......@@ -300,7 +348,7 @@ Drupal.getSelection = function (element) {
};
/**
* Build an error message from an AJAX response.
* Build an error message from an Ajax response.
*/
Drupal.ajaxError = function (xmlhttp, uri) {
var statusCode, statusText, pathText, responseText, readyStateText, message;
......@@ -312,8 +360,22 @@ Drupal.ajaxError = function (xmlhttp, uri) {
}
statusCode += "\n" + Drupal.t("Debugging information follows.");
pathText = "\n" + Drupal.t("Path: !uri", {'!uri': uri} );
statusText = xmlhttp.statusText ? ("\n" + Drupal.t("StatusText: !statusText", {'!statusText': $.trim(xmlhttp.statusText)})) : "";
responseText = xmlhttp.responseText ? ("\n" + Drupal.t("ResponseText: !responseText", {'!responseText': $.trim(xmlhttp.responseText)})) : "";
statusText = '';
// In some cases, when statusCode == 0, xmlhttp.statusText may not be defined.
// Unfortunately, testing for it with typeof, etc, doesn't seem to catch that
// and the test causes an exception. So we need to catch the exception here.
try {
statusText = "\n" + Drupal.t("StatusText: !statusText", {'!statusText': $.trim(xmlhttp.statusText)});
}
catch (e) {}
responseText = '';
// Again, we don't have a way to know for sure whether accessing
// xmlhttp.responseText is going to throw an exception. So we'll catch it.
try {
responseText = "\n" + Drupal.t("ResponseText: !responseText", {'!responseText': $.trim(xmlhttp.responseText) } );
} catch (e) {}
// Make the responseText more readable by stripping HTML tags and newlines.
responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,"");
responseText = responseText.replace(/[\n]+\s+/g,"\n");
......@@ -364,7 +426,7 @@ Drupal.theme.prototype = {
* The formatted text (html).
*/
placeholder: function (str) {
return '<em>' + Drupal.checkPlain(str) + '</em>';
return '<em class="placeholder">' + Drupal.checkPlain(str) + '</em>';
}
};
......
misc/druplicon.png

3.92 KiB | W: 0px | H: 0px

misc/druplicon.png

3.81 KiB | W: 0px | H: 0px

misc/druplicon.png
misc/druplicon.png
misc/druplicon.png
misc/druplicon.png
  • 2-up
  • Swipe
  • Onion skin
/* $Id: farbtastic.css,v 1.4 2010/04/28 20:08:38 dries Exp $ */
.farbtastic {
position: relative;
......
// $Id: farbtastic.js,v 1.8 2010/01/25 17:02:47 dries Exp $
(function(e){e.fn.farbtastic=function(f){e.farbtastic(this,f);return this};e.farbtastic=function(f,l){f=e(f).get(0);return f.farbtastic||(f.farbtastic=new e._farbtastic(f,l))};e._farbtastic=function(f,l){var a=this;e(f).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');var k=e(".farbtastic",f);a.wheel=e(".wheel",f).get(0);a.radius=84;a.square=100;a.width=194;navigator.appVersion.match(/MSIE [0-6]\./)&&
e("*",k).each(function(){if(this.currentStyle.backgroundImage!="none"){var b=this.currentStyle.backgroundImage;b=this.currentStyle.backgroundImage.substring(5,b.length-2);e(this).css({backgroundImage:"none",filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+b+"')"})}});a.linkTo=function(b){typeof a.callback=="object"&&e(a.callback).unbind("keyup",a.updateValue);a.color=null;if(typeof b=="function")a.callback=b;else if(typeof b=="object"||typeof b=="string"){a.callback=
e(b);a.callback.bind("keyup",a.updateValue);a.callback.get(0).value&&a.setColor(a.callback.get(0).value)}return this};a.updateValue=function(){this.value&&this.value!=a.color&&a.setColor(this.value)};a.setColor=function(b){var c=a.unpack(b);if(a.color!=b&&c){a.color=b;a.rgb=c;a.hsl=a.RGBToHSL(a.rgb);a.updateDisplay()}return this};a.setHSL=function(b){a.hsl=b;a.rgb=a.HSLToRGB(b);a.color=a.pack(a.rgb);a.updateDisplay();return this};a.widgetCoords=function(b){var c=e(a.wheel).offset();return{x:b.pageX-
......