Merge remote-tracking branch 'dries/8.x' into dbtngtng

8.0.x
Larry Garfield 2012-02-02 23:50:39 -06:00
commit 1bc5b98e6c
67 changed files with 849 additions and 554 deletions

View File

@ -51,12 +51,12 @@ interface ArchiverInterface {
* @param $files
* Optionally specify a list of files to be extracted. Files are
* relative to the root of the archive. If not specified, all files
* in the archive will be extracted
* in the archive will be extracted.
*
* @return ArchiverInterface
* The called object.
*/
public function extract($path, Array $files = array());
public function extract($path, array $files = array());
/**
* Lists all files in the archive.

View File

@ -1956,7 +1956,7 @@ function drupal_block_denied($ip) {
*/
function drupal_random_bytes($count) {
// $random_state does not use drupal_static as it stores random bytes.
static $random_state, $bytes;
static $random_state, $bytes, $php_compatible;
// Initialize on the first call. The contents of $_SERVER includes a mix of
// user-specific and system information that varies a little with each page.
if (!isset($random_state)) {
@ -1968,6 +1968,11 @@ function drupal_random_bytes($count) {
$bytes = '';
}
if (strlen($bytes) < $count) {
// PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
// locking on Windows and rendered it unusable.
if (!isset($php_compatible)) {
$php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
}
// /dev/urandom is available on many *nix systems and is considered the
// best commonly available pseudo-random source.
if ($fh = @fopen('/dev/urandom', 'rb')) {
@ -1977,6 +1982,11 @@ function drupal_random_bytes($count) {
$bytes .= fread($fh, max(4096, $count));
fclose($fh);
}
// openssl_random_pseudo_bytes() will find entropy in a system-dependent
// way.
elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
$bytes .= openssl_random_pseudo_bytes($count - strlen($bytes));
}
// If /dev/urandom is not available or returns no bytes, this loop will
// generate a good set of pseudo-random bytes on any system.
// Note that it may be important that our $random_state is passed
@ -2694,6 +2704,41 @@ function language_list($only_enabled = FALSE) {
return $only_enabled ? $languages['enabled'] : $languages['all'];
}
/**
* Loads a language object from the database.
*
* @param $langcode
* The language code.
*
* @return
* A fully-populated language object or FALSE.
*/
function language_load($langcode) {
$languages = language_list();
return isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
}
/**
* Produced the printed name for a language for display.
*
* @param $langcode
* The language code.
*
* @return
* The printed name of the language.
*/
function language_name($langcode) {
if ($langcode == LANGUAGE_NONE) {
return t('None');
}
if ($language = language_load($langcode)) {
return $language->name;
}
return t('Unknown (@langcode)', array('@langcode' => $langcode));
}
/**
* Returns the default language used on the site.
*

View File

@ -11,8 +11,8 @@
* By default, this returns an instance of the Drupal\Core\Cache\DatabaseBackend
* class.
*
* Classes implementing Drupal\Core\Cache\CacheBackendInterface can register themselves
* both as a default implementation and for specific bins.
* Classes implementing Drupal\Core\Cache\CacheBackendInterface can register
* themselves both as a default implementation and for specific bins.
*
* @param $bin
* The cache bin for which the cache object should be returned, defaults to

View File

@ -1852,7 +1852,9 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) {
* A UNIX timestamp to format.
* @param $type
* (optional) The format to use, one of:
* - 'short', 'medium', or 'long' (the corresponding built-in date formats).
* - One of the built-in formats: 'short', 'medium', 'long', 'html_datetime',
* 'html_date', 'html_time', 'html_yearless_date', 'html_week',
* 'html_month', 'html_year'.
* - The name of a date type defined by a module in hook_date_format_types(),
* if it's been assigned a format.
* - The machine name of an administrator-defined date format.
@ -1905,6 +1907,34 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
$format = variable_get('date_format_long', 'l, F j, Y - H:i');
break;
case 'html_datetime':
$format = variable_get('date_format_html_datetime', 'Y-m-d\TH:i:sO');
break;
case 'html_date':
$format = variable_get('date_format_html_date', 'Y-m-d');
break;
case 'html_time':
$format = variable_get('date_format_html_time', 'H:i:s');
break;
case 'html_yearless_date':
$format = variable_get('date_format_html_yearless_date', 'm-d');
break;
case 'html_week':
$format = variable_get('date_format_html_week', 'Y-\WW');
break;
case 'html_month':
$format = variable_get('date_format_html_month', 'Y-m');
break;
case 'html_year':
$format = variable_get('date_format_html_year', 'Y');
break;
case 'custom':
// No change to format.
break;
@ -6722,6 +6752,9 @@ function drupal_common_theme() {
'render element' => 'elements',
'template' => 'region',
),
'datetime' => array(
'variables' => array('timestamp' => NULL, 'text' => NULL, 'attributes' => array(), 'html' => FALSE),
),
'status_messages' => array(
'variables' => array('display' => NULL),
),
@ -6755,6 +6788,9 @@ function drupal_common_theme() {
'table' => array(
'variables' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE, 'empty' => ''),
),
'meter' => array(
'variables' => array('display_value' => NULL, 'form' => NULL, 'high' => NULL, 'low' => NULL, 'max' => NULL, 'min' => NULL, 'optimum' => NULL, 'value' => NULL, 'percentage' => NULL, 'attributes' => array()),
),
'tablesort_indicator' => array(
'variables' => array('style' => NULL),
),

View File

@ -447,18 +447,10 @@ function menu_get_item($path = NULL, $router_item = NULL) {
}
$original_map = arg(NULL, $path);
// Since there is no limit to the length of $path, use a hash to keep it
// short yet unique.
$cid = 'menu_item:' . hash('sha256', $path);
if ($cached = cache('menu')->get($cid)) {
$router_item = $cached->data;
}
else {
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
$ancestors = menu_get_ancestors($parts);
$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
cache('menu')->set($cid, $router_item);
}
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
$ancestors = menu_get_ancestors($parts);
$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
if ($router_item) {
// Allow modules to alter the router item before it is translated and
// checked for access.

View File

@ -1474,6 +1474,66 @@ function theme_disable($theme_list) {
* @{
*/
/**
* Preprocess variables for theme_datetime().
*/
function template_preprocess_datetime(&$variables) {
// Format the 'datetime' attribute based on the timestamp.
// @see http://www.w3.org/TR/html5-author/the-time-element.html#attr-time-datetime
if (!isset($variables['attributes']['datetime']) && isset($variables['timestamp'])) {
$variables['attributes']['datetime'] = format_date($variables['timestamp'], 'html_datetime', '', 'UTC');
}
// If no text was provided, try to auto-generate it.
if (!isset($variables['text'])) {
// Format and use a human-readable version of the timestamp, if any.
if (isset($variables['timestamp'])) {
$variables['text'] = format_date($variables['timestamp']);
$variables['html'] = FALSE;
}
// Otherwise, use the literal datetime attribute.
elseif (isset($variables['attributes']['datetime'])) {
$variables['text'] = $variables['attributes']['datetime'];
$variables['html'] = FALSE;
}
}
}
/**
* Returns HTML for a date / time.
*
* @param $variables
* An associative array containing:
* - timestamp: (optional) A UNIX timestamp for the datetime attribute. If the
* datetime cannot be represented as a UNIX timestamp, use a valid datetime
* attribute value in $variables['attributes']['datetime'].
* - text: (optional) The content to display within the <time> element. Set
* 'html' to TRUE if this value is already sanitized for output in HTML.
* Defaults to a human-readable representation of the timestamp value or the
* datetime attribute value using format_date().
* When invoked as #theme or #theme_wrappers of a render element, the
* rendered #children are autoamtically taken over as 'text', unless #text
* is explicitly set.
* - attributes: (optional) An associative array of HTML attributes to apply
* to the <time> element. A datetime attribute in 'attributes' overrides the
* 'timestamp'. To create a valid datetime attribute value from a UNIX
* timestamp, use format_date() with one of the predefined 'html_*' formats.
* - html: (optional) Whether 'text' is HTML markup (TRUE) or plain-text
* (FALSE). Defaults to FALSE. For example, to use a SPAN tag within the
* TIME element, this must be set to TRUE, or the SPAN tag will be escaped.
* It is the responsibility of the caller to properly sanitize the value
* contained in 'text' (or within the SPAN tag in aforementioned example).
*
* @see template_preprocess_datetime()
* @see http://www.w3.org/TR/html5-author/the-time-element.html#attr-time-datetime
*/
function theme_datetime($variables) {
$output = '<time' . drupal_attributes($variables['attributes']) . '>';
$output .= !empty($variables['html']) ? $variables['text'] : check_plain($variables['text']);
$output .= '</time>';
return $output;
}
/**
* Returns HTML for status and/or error messages, grouped by type.
*
@ -2142,6 +2202,49 @@ function theme_progress_bar($variables) {
return $output;
}
/**
* Returns HTML for a meter.
*
* @param $variables
* An associative array containing:
* - display_value: The textual representation of the meter bar.
* - form: A string specifying one or more forms to which the <meter> element
* belongs separated by spaces.
* - high: A number specifying the range that is considered to be a high
* value.
* - low: A number specifying the range that is considered to be a low value.
* - max: A number specifying the maximum value of the range.
* - min: A number specifying the minimum value of the range.
* - optimum: A number specifying what value is the optimal value for the
* gauge.
* - value: A number specifying the current value of the gauge.
* - percentage: A number specifying the current percentage of the gauge.
* - attributes: Associative array of attributes to be placed in the meter
* tag.
*/
function theme_meter($variables) {
$attributes = $variables['attributes'];
foreach (array('form', 'high', 'low', 'max', 'min', 'optimum', 'value') as $attribute) {
if (!empty($variables[$attribute])) {
// This function was initially designed for the <meter> tag, but due to
// the lack of browser and styling support for it, we're currently using
// it's attributes as HTML5 data attributes.
$attributes['data-' . $attribute] = $variables[$attribute];
}
}
$output = '<div' . drupal_attributes($attributes) . '>';
$output .= ' <div style="width: '. $variables['percentage'] .'%;" class="foreground"></div>';
$output .= "</div>\n";
if (!empty($variables['display_value'])) {
$output .= '<div class="percent">' . $variables['display_value'] . '</div>';
}
return $output;
}
/**
* Returns HTML for an indentation div; used for drag and drop tables.
*

View File

@ -330,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);
}
}

View File

@ -32,7 +32,7 @@ Drupal.behaviors.autocomplete = {
Drupal.autocompleteSubmit = function () {
return $('#autocomplete').each(function () {
this.owner.hidePopup();
}).size() == 0;
}).length == 0;
};
/**
@ -41,7 +41,7 @@ Drupal.autocompleteSubmit = function () {
Drupal.jsAC = function ($input, db) {
var ac = this;
this.input = $input[0];
this.ariaLive = $('#' + $input.attr('id') + '-autocomplete-aria-live');
this.ariaLive = $('#' + this.input.id + '-autocomplete-aria-live');
this.db = db;
$input
@ -123,7 +123,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));
}
}
@ -227,7 +227,7 @@ 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'));
}

View File

@ -21,7 +21,7 @@ Drupal.behaviors.states = {
new states.Dependent({
element: $(selector),
state: states.State.sanitize(state),
dependees: settings.states[selector][state]
constraints: settings.states[selector][state]
});
}
}
@ -40,12 +40,14 @@ Drupal.behaviors.states = {
* Object with the following keys (all of which are required):
* - element: A jQuery object of the dependent element
* - state: A State object describing the state that is dependent
* - dependees: An object with dependency specifications. Lists all elements
* that this element depends on.
* - constraints: An object with dependency specifications. Lists all elements
* that this element depends on. It can be nested and can contain arbitrary
* AND and OR clauses.
*/
states.Dependent = function (args) {
$.extend(this, { values: {}, oldValue: undefined }, args);
$.extend(this, { values: {}, oldValue: null }, args);
this.dependees = this.getDependees();
for (var selector in this.dependees) {
this.initializeDependee(selector, this.dependees[selector]);
}
@ -69,7 +71,7 @@ states.Dependent.comparisons = {
// as a string before applying the strict comparison in compare(). Otherwise
// numeric keys in the form's #states array fail to match string values
// returned from jQuery's val().
return (value.constructor.name === 'String') ? compare(String(reference), value) : compare(reference, value);
return (typeof value === 'string') ? compare(reference.toString(), value) : compare(reference, value);
}
};
@ -84,26 +86,33 @@ states.Dependent.prototype = {
* dependee's compliance status.
*/
initializeDependee: function (selector, dependeeStates) {
var self = this;
var state;
// Cache for the states of this dependee.
self.values[selector] = {};
this.values[selector] = {};
$.each(dependeeStates, function (state, value) {
state = states.State.sanitize(state);
for (var i in dependeeStates) {
if (dependeeStates.hasOwnProperty(i)) {
state = dependeeStates[i];
// Make sure we're not initializing this selector/state combination twice.
if ($.inArray(state, dependeeStates) === -1) {
continue;
}
// Initialize the value of this state.
self.values[selector][state.pristine] = undefined;
state = states.State.sanitize(state);
// Monitor state changes of the specified state for this dependee.
$(selector).bind('state:' + state, function (e) {
var complies = self.compare(value, e.value);
self.update(selector, state, complies);
});
// Initialize the value of this state.
this.values[selector][state.name] = null;
// Make sure the event we just bound ourselves to is actually fired.
new states.Trigger({ selector: selector, state: state });
});
// Monitor state changes of the specified state for this dependee.
$(selector).bind('state:' + state, $.proxy(function (e) {
this.update(selector, state, e.value);
}, this));
// Make sure the event we just bound ourselves to is actually fired.
new states.Trigger({ selector: selector, state: state });
}
}
},
/**
@ -111,12 +120,16 @@ states.Dependent.prototype = {
*
* @param reference
* The value used for reference.
* @param value
* The value to compare with the reference value.
* @param selector
* CSS selector describing the dependee.
* @param state
* A State object describing the dependee's updated state.
*
* @return
* true, undefined or false.
* true or false.
*/
compare: function (reference, value) {
compare: function (reference, selector, state) {
var value = this.values[selector][state.name];
if (reference.constructor.name in states.Dependent.comparisons) {
// Use a custom compare function for certain reference value types.
return states.Dependent.comparisons[reference.constructor.name](reference, value);
@ -139,8 +152,8 @@ states.Dependent.prototype = {
*/
update: function (selector, state, value) {
// Only act when the 'new' value is actually new.
if (value !== this.values[selector][state.pristine]) {
this.values[selector][state.pristine] = value;
if (value !== this.values[selector][state.name]) {
this.values[selector][state.name] = value;
this.reevaluate();
}
},
@ -149,16 +162,8 @@ states.Dependent.prototype = {
* Triggers change events in case a state changed.
*/
reevaluate: function () {
var value = undefined;
// Merge all individual values to find out whether this dependee complies.
for (var selector in this.values) {
for (var state in this.values[selector]) {
state = states.State.sanitize(state);
var complies = this.values[selector][state.pristine];
value = ternary(value, invert(complies, state.invert));
}
}
// Check whether any constraint for this dependent state is satisifed.
var value = this.verifyConstraints(this.constraints);
// Only invoke a state change event when the value actually changed.
if (value !== this.oldValue) {
@ -173,6 +178,124 @@ states.Dependent.prototype = {
// infinite loops.
this.element.trigger({ type: 'state:' + this.state, value: value, trigger: true });
}
},
/**
* Evaluates child constraints to determine if a constraint is satisfied.
*
* @param constraints
* A constraint object or an array of constraints.
* @param selector
* The selector for these constraints. If undefined, there isn't yet a
* selector that these constraints apply to. In that case, the keys of the
* object are interpreted as the selector if encountered.
*
* @return
* true or false, depending on whether these constraints are satisfied.
*/
verifyConstraints: function(constraints, selector) {
var result;
if ($.isArray(constraints)) {
// This constraint is an array (OR or XOR).
var hasXor = $.inArray('xor', constraints) === -1;
for (var i = 0, len = constraints.length; i < len; i++) {
if (constraints[i] != 'xor') {
var constraint = this.checkConstraints(constraints[i], selector, i);
// Return if this is OR and we have a satisfied constraint or if this
// is XOR and we have a second satisfied constraint.
if (constraint && (hasXor || result)) {
return hasXor;
}
result = result || constraint;
}
}
}
// Make sure we don't try to iterate over things other than objects. This
// shouldn't normally occur, but in case the condition definition is bogus,
// we don't want to end up with an infinite loop.
else if ($.isPlainObject(constraints)) {
// This constraint is an object (AND).
for (var n in constraints) {
if (constraints.hasOwnProperty(n)) {
result = ternary(result, this.checkConstraints(constraints[n], selector, n));
// False and anything else will evaluate to false, so return when any
// false condition is found.
if (result === false) { return false; }
}
}
}
return result;
},
/**
* Checks whether the value matches the requirements for this constraint.
*
* @param value
* Either the value of a state or an array/object of constraints. In the
* latter case, resolving the constraint continues.
* @param selector
* The selector for this constraint. If undefined, there isn't yet a
* selector that this constraint applies to. In that case, the state key is
* propagates to a selector and resolving continues.
* @param state
* The state to check for this constraint. If undefined, resolving
* continues.
* If both selector and state aren't undefined and valid non-numeric
* strings, a lookup for the actual value of that selector's state is
* performed. This parameter is not a State object but a pristine state
* string.
*
* @return
* true or false, depending on whether this constraint is satisfied.
*/
checkConstraints: function(value, selector, state) {
// Normalize the last parameter. If it's non-numeric, we treat it either as
// a selector (in case there isn't one yet) or as a trigger/state.
if (typeof state !== 'string' || (/[0-9]/).test(state[0])) {
state = null;
}
else if (typeof selector === 'undefined') {
// Propagate the state to the selector when there isn't one yet.
selector = state;
state = null;
}
if (state !== null) {
// constraints is the actual constraints of an element to check for.
state = states.State.sanitize(state);
return invert(this.compare(value, selector, state), state.invert);
}
else {
// Resolve this constraint as an AND/OR operator.
return this.verifyConstraints(value, selector);
}
},
/**
* Gathers information about all required triggers.
*/
getDependees: function() {
var cache = {};
// Swivel the lookup function so that we can record all available selector-
// state combinations for initialization.
var _compare = this.compare;
this.compare = function(reference, selector, state) {
(cache[selector] || (cache[selector] = [])).push(state.name);
// Return nothing (=== undefined) so that the constraint loops are not
// broken.
};
// This call doesn't actually verify anything but uses the resolving
// mechanism to go through the constraints array, trying to look up each
// value. Since we swivelled the compare function, this comparison returns
// undefined and lookup continues until the very end. Instead of lookup up
// the value, we record that combination of selector and state so that we
// can initialize all triggers.
this.verifyConstraints(this.constraints);
// Restore the original function.
this.compare = _compare;
return cache;
}
};
@ -192,7 +315,6 @@ states.Trigger = function (args) {
states.Trigger.prototype = {
initialize: function () {
var self = this;
var trigger = states.Trigger.states[this.state];
if (typeof trigger == 'function') {
@ -200,9 +322,11 @@ states.Trigger.prototype = {
trigger.call(window, this.element);
}
else {
$.each(trigger, function (event, valueFn) {
self.defaultTrigger(event, valueFn);
});
for (var event in trigger) {
if (trigger.hasOwnProperty(event)) {
this.defaultTrigger(event, trigger[event]);
}
}
}
// Mark this trigger as initialized for this element.
@ -210,23 +334,22 @@ states.Trigger.prototype = {
},
defaultTrigger: function (event, valueFn) {
var self = this;
var oldValue = valueFn.call(this.element);
// Attach the event callback.
this.element.bind(event, function (e) {
var value = valueFn.call(self.element, e);
this.element.bind(event, $.proxy(function (e) {
var value = valueFn.call(this.element, e);
// Only trigger the event if the value has actually changed.
if (oldValue !== value) {
self.element.trigger({ type: 'state:' + self.state, value: value, oldValue: oldValue });
this.element.trigger({ type: 'state:' + this.state, value: value, oldValue: oldValue });
oldValue = value;
}
});
}, this));
states.postponed.push(function () {
states.postponed.push($.proxy(function () {
// Trigger the event once for initialization purposes.
self.element.trigger({ type: 'state:' + self.state, value: oldValue, oldValue: undefined });
});
this.element.trigger({ type: 'state:' + this.state, value: oldValue, oldValue: null });
}, this));
}
};
@ -286,7 +409,7 @@ states.Trigger.states = {
collapsed: {
'collapsed': function(e) {
return (e !== undefined && 'value' in e) ? e.value : this.is('.collapsed');
return (typeof e !== 'undefined' && 'value' in e) ? e.value : this.is('.collapsed');
}
}
};
@ -318,7 +441,7 @@ states.State = function(state) {
};
/**
* Create a new State object by sanitizing the passed value.
* Creates a new State object by sanitizing the passed value.
*/
states.State.sanitize = function (state) {
if (state instanceof states.State) {
@ -363,72 +486,71 @@ states.State.prototype = {
* bubble up to these handlers. We use this system so that themes and modules
* can override these state change handlers for particular parts of a page.
*/
{
$(document).bind('state:disabled', function(e) {
// Only act when this change was triggered by a dependency and not by the
// element monitoring itself.
if (e.trigger) {
$(e.target)
.attr('disabled', e.value)
.filter('.form-element')
.closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'addClass' : 'removeClass']('form-disabled');
// Note: WebKit nightlies don't reflect that change correctly.
// See https://bugs.webkit.org/show_bug.cgi?id=23789
}
});
$(document).bind('state:disabled', function(e) {
// Only act when this change was triggered by a dependency and not by the
// element monitoring itself.
if (e.trigger) {
$(e.target)
.attr('disabled', e.value)
.filter('.form-element')
.closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'addClass' : 'removeClass']('form-disabled');
$(document).bind('state:required', function(e) {
if (e.trigger) {
if (e.value) {
$(e.target).closest('.form-item, .form-wrapper').find('label').append('<abbr class="form-required" title="' + Drupal.t('This field is required.') + '">*</abbr>');
}
else {
$(e.target).closest('.form-item, .form-wrapper').find('label .form-required').remove();
}
}
});
// Note: WebKit nightlies don't reflect that change correctly.
// See https://bugs.webkit.org/show_bug.cgi?id=23789
}
});
$(document).bind('state:visible', function(e) {
if (e.trigger) {
$(e.target).closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'show' : 'hide']();
$(document).bind('state:required', function(e) {
if (e.trigger) {
if (e.value) {
$(e.target).closest('.form-item, .form-wrapper').find('label').append('<abbr class="form-required" title="' + Drupal.t('This field is required.') + '">*</abbr>');
}
});
else {
$(e.target).closest('.form-item, .form-wrapper').find('label .form-required').remove();
}
}
});
$(document).bind('state:checked', function(e) {
if (e.trigger) {
$(e.target).attr('checked', e.value);
}
});
$(document).bind('state:visible', function(e) {
if (e.trigger) {
$(e.target).closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'show' : 'hide']();
}
});
$(document).bind('state:collapsed', function(e) {
if (e.trigger) {
if ($(e.target).is('.collapsed') !== e.value) {
$('> legend a', e.target).click();
}
$(document).bind('state:checked', function(e) {
if (e.trigger) {
$(e.target).attr('checked', e.value);
}
});
$(document).bind('state:collapsed', function(e) {
if (e.trigger) {
if ($(e.target).is('.collapsed') !== e.value) {
$('> legend a', e.target).click();
}
});
}
}
});
/**
* These are helper functions implementing addition "operators" and don't
* implement any logic that is particular to states.
*/
{
// Bitwise AND with a third undefined state.
function ternary (a, b) {
return a === undefined ? b : (b === undefined ? a : a && b);
};
// Inverts a (if it's not undefined) when invert is true.
function invert (a, invert) {
return (invert && a !== undefined) ? !a : a;
};
// Bitwise AND with a third undefined state.
function ternary (a, b) {
return typeof a === 'undefined' ? b : (typeof b === 'undefined' ? a : a && b);
}
// Compares two values while ignoring undefined values.
function compare (a, b) {
return (a === b) ? (a === undefined ? a : true) : (a === undefined || b === undefined);
}
// Inverts a (if it's not undefined) when invert is true.
function invert (a, invert) {
return (invert && typeof a !== 'undefined') ? !a : a;
}
// Compares two values while ignoring undefined values.
function compare (a, b) {
return (a === b) ? (typeof a === 'undefined' ? a : true) : (typeof a === 'undefined' || typeof b === 'undefined');
}
})(jQuery);

View File

@ -123,7 +123,7 @@ Drupal.tableDrag.prototype.initColumns = function () {
// Find the first field in this group.
for (var d in this.tableSettings[group]) {
var field = $('.' + this.tableSettings[group][d].target + ':first', this.table);
if (field.size() && this.tableSettings[group][d].hidden) {
if (field.length && this.tableSettings[group][d].hidden) {
var hidden = this.tableSettings[group][d].hidden;
var cell = field.closest('td');
break;
@ -256,7 +256,7 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) {
if ($('td:first .indentation:last', item).length) {
$('td:first .indentation:last', item).after(handle);
// Update the total width of indentation in this entire table.
self.indentCount = Math.max($('.indentation', item).size(), self.indentCount);
self.indentCount = Math.max($('.indentation', item).length, self.indentCount);
}
else {
$('td:first', item).prepend(handle);
@ -357,7 +357,7 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) {
if ($(item).is('.tabledrag-root')) {
// Swap with the previous top-level row.
var groupHeight = 0;
while (previousRow && $('.indentation', previousRow).size()) {
while (previousRow && $('.indentation', previousRow).length) {
previousRow = $(previousRow).prev('tr').get(0);
groupHeight += $(previousRow).is(':hidden') ? 0 : previousRow.offsetHeight;
}
@ -678,7 +678,7 @@ Drupal.tableDrag.prototype.updateField = function (changedRow, group) {
var sourceRow = changedRow;
if ($(previousRow).is('.draggable') && $('.' + group, previousRow).length) {
if (this.indentEnabled) {
if ($('.indentations', previousRow).size() == $('.indentations', changedRow)) {
if ($('.indentations', previousRow).length == $('.indentations', changedRow)) {
sourceRow = previousRow;
}
}
@ -688,7 +688,7 @@ Drupal.tableDrag.prototype.updateField = function (changedRow, group) {
}
else if ($(nextRow).is('.draggable') && $('.' + group, nextRow).length) {
if (this.indentEnabled) {
if ($('.indentations', nextRow).size() == $('.indentations', changedRow)) {
if ($('.indentations', nextRow).length == $('.indentations', changedRow)) {
sourceRow = nextRow;
}
}
@ -744,7 +744,7 @@ Drupal.tableDrag.prototype.updateField = function (changedRow, group) {
switch (rowSettings.action) {
case 'depth':
// Get the depth of the target row.
targetElement.value = $('.indentation', $(sourceElement).closest('tr')).size();
targetElement.value = $('.indentation', $(sourceElement).closest('tr')).length;
break;
case 'match':
// Update the value.
@ -874,7 +874,7 @@ Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxD
this.element = tableRow;
this.method = method;
this.group = [tableRow];
this.groupDepth = $('.indentation', tableRow).size();
this.groupDepth = $('.indentation', tableRow).length;
this.changed = false;
this.table = $(tableRow).closest('table').get(0);
this.indentEnabled = indentEnabled;
@ -882,12 +882,12 @@ Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxD
this.direction = ''; // Direction the row is being moved.
if (this.indentEnabled) {
this.indents = $('.indentation', tableRow).size();
this.indents = $('.indentation', tableRow).length;
this.children = this.findChildren(addClasses);
this.group = $.merge(this.group, this.children);
// Find the depth of this entire group.
for (var n = 0; n < this.group.length; n++) {
this.groupDepth = Math.max($('.indentation', this.group[n]).size(), this.groupDepth);
this.groupDepth = Math.max($('.indentation', this.group[n]).length, this.groupDepth);
}
}
};
@ -999,7 +999,7 @@ Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function (prevRow
// Minimum indentation:
// Do not orphan the next row.
minIndent = nextRow ? $('.indentation', nextRow).size() : 0;
minIndent = nextRow ? $('.indentation', nextRow).length : 0;
// Maximum indentation:
if (!prevRow || $(prevRow).is(':not(.draggable)') || $(this.element).is('.tabledrag-root')) {
@ -1011,7 +1011,7 @@ Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function (prevRow
}
else {
// Do not go deeper than as a child of the previous row.
maxIndent = $('.indentation', prevRow).size() + ($(prevRow).is('.tabledrag-leaf') ? 0 : 1);
maxIndent = $('.indentation', prevRow).length + ($(prevRow).is('.tabledrag-leaf') ? 0 : 1);
// Limit by the maximum allowed depth for the table.
if (this.maxDepth) {
maxIndent = Math.min(maxIndent, this.maxDepth - (this.groupDepth - this.indents));
@ -1032,8 +1032,8 @@ Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function (prevRow
Drupal.tableDrag.prototype.row.prototype.indent = function (indentDiff) {
// Determine the valid indentations interval if not available yet.
if (!this.interval) {
prevRow = $(this.element).prev('tr').get(0);
nextRow = $(this.group).filter(':last').next('tr').get(0);
var prevRow = $(this.element).prev('tr').get(0);
var nextRow = $(this.group).filter(':last').next('tr').get(0);
this.interval = this.validIndentInterval(prevRow, nextRow);
}

View File

@ -2,13 +2,14 @@
Drupal.behaviors.tableSelect = {
attach: function (context, settings) {
$('table:has(th.select-all)', context).once('table-select', Drupal.tableSelect);
// Select the inner-most table in case of nested tables.
$('th.select-all', context).closest('table').once('table-select', Drupal.tableSelect);
}
};
Drupal.tableSelect = function () {
// Do not add a "Select all" checkbox if there are no rows with checkboxes in the table
if ($('td input:checkbox', this).size() == 0) {
if ($('td input:checkbox', this).length == 0) {
return;
}

View File

@ -20,7 +20,6 @@ a.block-demo-backlink:link,
a.block-demo-backlink:visited {
background-color: #B4D7F0;
-moz-border-radius: 0 0 10px 10px;
-webkit-border-radius: 0 0 10px 10px;
border-radius: 0 0 10px 10px;
color: #000;
font-family: "Lucida Grande", Verdana, sans-serif;

View File

@ -153,7 +153,7 @@ Drupal.behaviors.blockDrag = {
}
}
// This region has become empty.
if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) {
$(this).removeClass('region-populated').addClass('region-empty');
}
// This region has become populated.

View File

@ -2149,24 +2149,26 @@ function template_preprocess_comment(&$variables) {
else {
$variables['status'] = ($comment->status == COMMENT_NOT_PUBLISHED) ? 'comment-unpublished' : 'comment-published';
}
// Gather comment classes.
if ($comment->uid == 0) {
// 'comment-published' class is not needed, it is either 'comment-preview' or
// 'comment-unpublished'.
if ($variables['status'] != 'comment-published') {
$variables['classes_array'][] = $variables['status'];
}
if ($variables['new']) {
$variables['classes_array'][] = 'comment-new';
}
if (!$comment->uid) {
$variables['classes_array'][] = 'comment-by-anonymous';
}
else {
// Published class is not needed. It is either 'comment-preview' or 'comment-unpublished'.
if ($variables['status'] != 'comment-published') {
$variables['classes_array'][] = $variables['status'];
}
if ($comment->uid === $variables['node']->uid) {
if ($comment->uid == $variables['node']->uid) {
$variables['classes_array'][] = 'comment-by-node-author';
}
if ($comment->uid === $variables['user']->uid) {
if ($comment->uid == $variables['user']->uid) {
$variables['classes_array'][] = 'comment-by-viewer';
}
if ($variables['new']) {
$variables['classes_array'][] = 'comment-new';
}
}
}

View File

@ -291,8 +291,6 @@ class CommentInterfaceTest extends CommentHelperCase {
$comment = $this->postComment($this->node, $comment_text);
$comment_loaded = comment_load($comment->id);
$this->assertTrue($this->commentExists($comment), t('Comment found.'));
$by_viewer_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-viewer")]', array(':comment_id' => 'comment-' . $comment->id));
$this->assertTrue(!empty($by_viewer_class), t('HTML class for comments by viewer found.'));
// Set comments to have subject and preview to required.
$this->drupalLogout();
@ -379,11 +377,6 @@ class CommentInterfaceTest extends CommentHelperCase {
$this->assertTrue($this->commentExists($reply, TRUE), t('Page two exists. %s'));
$this->setCommentsPerPage(50);
// Create comment #5 to assert HTML class.
$comment = $this->postComment($this->node, $this->randomName(), $this->randomName());
$by_node_author_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-node-author")]', array(':comment_id' => 'comment-' . $comment->id));
$this->assertTrue(!empty($by_node_author_class), t('HTML class for node author found.'));
// Attempt to post to node with comments disabled.
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_HIDDEN));
$this->assertTrue($this->node, t('Article node created.'));
@ -482,6 +475,111 @@ class CommentInterfaceTest extends CommentHelperCase {
$this->assertTrue(count($count) == 2, print_r($count, TRUE));
}
/**
* Tests CSS classes on comments.
*/
function testCommentClasses() {
// Create all permutations for comments, users, and nodes.
$parameters = array(
'node_uid' => array(0, $this->web_user->uid),
'comment_uid' => array(0, $this->web_user->uid, $this->admin_user->uid),
'comment_status' => array(COMMENT_PUBLISHED, COMMENT_NOT_PUBLISHED),
'user' => array('anonymous', 'authenticated', 'admin'),
);
$permutations = $this->generatePermutations($parameters);
foreach ($permutations as $case) {
// Create a new node.
$node = $this->drupalCreateNode(array('type' => 'article', 'uid' => $case['node_uid']));
// Add a comment.
$comment = entity_create('comment', array(
'nid' => $node->nid,
'uid' => $case['comment_uid'],
'status' => $case['comment_status'],
'subject' => $this->randomName(),
'language' => LANGUAGE_NONE,
'comment_body' => array(LANGUAGE_NONE => array($this->randomName())),
));
comment_save($comment);
// Adjust the current/viewing user.
switch ($case['user']) {
case 'anonymous':
$this->drupalLogout();
$case['user_uid'] = 0;
break;
case 'authenticated':
$this->drupalLogin($this->web_user);
$case['user_uid'] = $this->web_user->uid;
break;
case 'admin':
$this->drupalLogin($this->admin_user);
$case['user_uid'] = $this->admin_user->uid;
break;
}
// Request the node with the comment.
$this->drupalGet('node/' . $node->nid);
// Verify classes if the comment is visible for the current user.
if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
// Verify the comment-by-anonymous class.
$comments = $this->xpath('//*[contains(@class, "comment-by-anonymous")]');
if ($case['comment_uid'] == 0) {
$this->assertTrue(count($comments) == 1, 'comment-by-anonymous class found.');
}
else {
$this->assertFalse(count($comments), 'comment-by-anonymous class not found.');
}
// Verify the comment-by-node-author class.
$comments = $this->xpath('//*[contains(@class, "comment-by-node-author")]');
if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['node_uid']) {
$this->assertTrue(count($comments) == 1, 'comment-by-node-author class found.');
}
else {
$this->assertFalse(count($comments), 'comment-by-node-author class not found.');
}
// Verify the comment-by-viewer class.
$comments = $this->xpath('//*[contains(@class, "comment-by-viewer")]');
if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['user_uid']) {
$this->assertTrue(count($comments) == 1, 'comment-by-viewer class found.');
}
else {
$this->assertFalse(count($comments), 'comment-by-viewer class not found.');
}
}
// Verify the comment-unpublished class.
$comments = $this->xpath('//*[contains(@class, "comment-unpublished")]');
if ($case['comment_status'] == COMMENT_NOT_PUBLISHED && $case['user'] == 'admin') {
$this->assertTrue(count($comments) == 1, 'comment-unpublished class found.');
}
else {
$this->assertFalse(count($comments), 'comment-unpublished class not found.');
}
// Verify the comment-new class.
if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
$comments = $this->xpath('//*[contains(@class, "comment-new")]');
if ($case['user'] != 'anonymous') {
$this->assertTrue(count($comments) == 1, 'comment-new class found.');
// Request the node again. The comment-new class should disappear.
$this->drupalGet('node/' . $node->nid);
$comments = $this->xpath('//*[contains(@class, "comment-new")]');
$this->assertFalse(count($comments), 'comment-new class not found.');
}
else {
$this->assertFalse(count($comments), 'comment-new class not found.');
}
}
}
}
/**
* Tests the node comment statistics.
*/
@ -982,8 +1080,6 @@ class CommentAnonymous extends CommentHelperCase {
// Post anonymous comment without contact info.
$anonymous_comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName());
$this->assertTrue($this->commentExists($anonymous_comment1), t('Anonymous comment without contact info found.'));
$anonymous_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-anonymous")]', array(':comment_id' => 'comment-' . $anonymous_comment1->id));
$this->assertTrue(!empty($anonymous_class), t('HTML class for anonymous comments found.'));
// Allow contact info.
$this->drupalLogin($this->admin_user);

View File

@ -9,8 +9,6 @@ div.contextual-links-wrapper {
}
div.contextual-links-wrapper ul.contextual-links {
-moz-border-radius: 0 4px 4px 4px;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 4px;
border-radius: 0 4px 4px 4px;
left: 0;
right: auto;

View File

@ -40,7 +40,6 @@ a.contextual-links-trigger {
width: 28px;
overflow: hidden;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
a.contextual-links-trigger:hover,
@ -54,8 +53,6 @@ div.contextual-links-active a.contextual-links-trigger {
position: relative;
z-index: 1;
-moz-border-radius: 4px 4px 0 0;
-webkit-border-bottom-left-radius: 0;
-webkit-border-bottom-right-radius: 0;
border-radius: 4px 4px 0 0;
}
div.contextual-links-wrapper ul.contextual-links {
@ -70,10 +67,6 @@ div.contextual-links-wrapper ul.contextual-links {
top: 18px;
white-space: nowrap;
-moz-border-radius: 4px 0 4px 4px; /* LTR */
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-webkit-border-top-right-radius: 0; /* LTR */
-webkit-border-top-left-radius: 4px; /* LTR */
border-radius: 4px 0 4px 4px; /* LTR */
}
.contextual-links-region:hover a.contextual-links-trigger,

View File

@ -34,7 +34,6 @@
#dashboard .block-placeholder {
background: #E2E1DC;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
float: left; /* LTR */
margin: 3px 3px 3px 0; /* LTR */

View File

@ -617,8 +617,9 @@ function field_info_fields() {
*
* @param $field_name
* The name of the field to retrieve. $field_name can only refer to a
* non-deleted, active field. Use field_read_fields() to retrieve information
* on deleted or inactive fields.
* non-deleted, active field. For deleted fields, use
* field_info_field_by_id(). To retrieve information about inactive fields,
* use field_read_fields().
*
* @return
* The field array, as returned by field_read_fields(), with an
@ -639,7 +640,7 @@ function field_info_field($field_name) {
*
* @param $field_id
* The id of the field to retrieve. $field_id can refer to a
* deleted field.
* deleted field, but not an inactive one.
*
* @return
* The field array, as returned by field_read_fields(), with an

View File

@ -96,7 +96,7 @@ Drupal.file = Drupal.file || {
// Check if we're working with an "Upload" button.
var $enabledFields = [];
if ($(this).closest('div.form-managed-file').size() > 0) {
if ($(this).closest('div.form-managed-file').length > 0) {
$enabledFields = $(this).closest('div.form-managed-file').find('input.form-file');
}
@ -120,7 +120,7 @@ Drupal.file = Drupal.file || {
progressBar: function (event) {
var clickedButton = this;
var $progressId = $(clickedButton).closest('div.form-managed-file').find('input.file-progress');
if ($progressId.size()) {
if ($progressId.length) {
var originalName = $progressId.attr('name');
// Replace the name with the required identifier.

View File

@ -100,20 +100,6 @@ function language_theme() {
);
}
/**
* Loads a language object from the database.
*
* @param $langcode
* The language code.
*
* @return
* A fully-populated language object or FALSE.
*/
function language_load($langcode) {
$languages = language_list();
return isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
}
/**
* API function to add or update a language.
*

View File

@ -297,7 +297,6 @@ function locale_form_alter(&$form, &$form_state, $form_id) {
function locale_form_node_form_alter(&$form, &$form_state) {
if (isset($form['#node']->type) && locale_multilingual_node_type($form['#node']->type)) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('Language neutral'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
@ -306,6 +305,8 @@ function locale_form_node_form_alter(&$form, &$form_state) {
'#title' => t('Language'),
'#default_value' => (isset($form['#node']->language) ? $form['#node']->language : ''),
'#options' => $language_options,
'#empty_value' => LANGUAGE_NONE,
'#empty_option' => t('- None -'),
);
}
// Node type without language selector: assign the default for new nodes
@ -768,15 +769,6 @@ function locale_get_plural($count, $langcode = NULL) {
}
/**
* Returns a language name.
*/
function locale_language_name($langcode) {
// Consider enabled languages only.
$languages = language_list(TRUE);
return ($langcode && isset($languages[$langcode])) ? $languages[$langcode]->name : t('All');
}
/**
* Implements hook_modules_installed().
*/

View File

@ -1,47 +1,46 @@
(function ($) {
Drupal.behaviors.menuChangeParentItems = {
attach: function (context, settings) {
$('fieldset#edit-menu input').each(function () {
$(this).change(function () {
// Update list of available parent menu items.
Drupal.menu_update_parent_list();
});
Drupal.behaviors.menuChangeParentItems = {
attach: function (context, settings) {
$('fieldset#edit-menu input').each(function () {
$(this).change(function () {
// Update list of available parent menu items.
Drupal.menu_update_parent_list();
});
});
}
};
/**
* Function to set the options of the menu parent item dropdown.
*/
Drupal.menu_update_parent_list = function () {
var values = [];
$('input:checked', $('fieldset#edit-menu')).each(function () {
// Get the names of all checked menus.
values.push(Drupal.checkPlain($.trim($(this).val())));
});
var url = Drupal.settings.basePath + 'admin/structure/menu/parents';
$.ajax({
url: location.protocol + '//' + location.host + url,
type: 'POST',
data: {'menus[]' : values},
dataType: 'json',
success: function (options) {
// Save key of last selected element.
var selected = $('fieldset#edit-menu #edit-menu-parent :selected').val();
// Remove all exisiting options from dropdown.
$('fieldset#edit-menu #edit-menu-parent').children().remove();
// Add new options to dropdown.
jQuery.each(options, function(index, value) {
$('fieldset#edit-menu #edit-menu-parent').append(
$('<option ' + (index == selected ? ' selected="selected"' : '') + '></option>').val(index).text(value)
);
});
}
}
/**
* Function to set the options of the menu parent item dropdown.
*/
Drupal.menu_update_parent_list = function () {
var values = [];
$('input:checked', $('fieldset#edit-menu')).each(function () {
// Get the names of all checked menus.
values.push(Drupal.checkPlain($.trim($(this).val())));
});
var url = Drupal.settings.basePath + 'admin/structure/menu/parents';
$.ajax({
url: location.protocol + '//' + location.host + url,
type: 'POST',
data: {'menus[]' : values},
dataType: 'json',
success: function (options) {
// Save key of last selected element.
var selected = $('fieldset#edit-menu #edit-menu-parent :selected').val();
// Remove all exisiting options from dropdown.
$('fieldset#edit-menu #edit-menu-parent').children().remove();
// Add new options to dropdown.
jQuery.each(options, function(index, value) {
$('fieldset#edit-menu #edit-menu-parent').append(
$('<option ' + (index == selected ? ' selected="selected"' : '') + '></option>').val(index).text(value)
);
});
}
});
}
});
};
})(jQuery);

View File

@ -1,4 +1,3 @@
(function ($) {
Drupal.behaviors.menuFieldsetSummaries = {

View File

@ -109,14 +109,14 @@ function node_filters() {
// Language filter if the site is multilingual.
if (language_multilingual()) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('Language neutral'));
$language_options = array(LANGUAGE_NONE => t('- None -'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
$filters['language'] = array(
'title' => t('language'),
'options' => array(
'[any]' => t('any'),
'[any]' => t('- Any -'),
) + $language_options,
);
}
@ -175,7 +175,7 @@ function node_filter_form() {
$value = $value->name;
}
elseif ($type == 'language') {
$value = $value == LANGUAGE_NONE ? t('Language neutral') : module_invoke('locale', 'language_name', $value);
$value = language_name($value);
}
else {
$value = $filters[$type]['options'][$value];
@ -448,7 +448,7 @@ function node_admin_nodes() {
'changed' => array('data' => t('Updated'), 'field' => 'n.changed', 'sort' => 'desc')
);
if ($multilanguage) {
$header['language'] = array('data' => t('Language'), 'field' => 'n.language');
$header['language_name'] = array('data' => t('Language'), 'field' => 'n.language');
}
$header['operations'] = array('data' => t('Operations'));
@ -500,12 +500,7 @@ function node_admin_nodes() {
'changed' => format_date($node->changed, 'short'),
);
if ($multilanguage) {
if ($node->language == LANGUAGE_NONE || isset($languages[$node->language])) {
$options[$node->nid]['language'] = $node->language == LANGUAGE_NONE ? t('Language neutral') : $languages[$node->language]->name;
}
else {
$options[$node->nid]['language'] = t('Undefined language (@langcode)', array('@langcode' => $node->language));
}
$options[$node->nid]['language_name'] = language_name($node->language);
}
// Build a list of all the accessible operations for the current node.
$operations = array();

View File

@ -1452,7 +1452,7 @@ function node_build_content($node, $view_mode = 'full', $langcode = NULL) {
* viewed.
*
* @return
* A $page element suitable for use by drupal_page_render().
* A $page element suitable for use by drupal_render().
*
* @see node_menu()
*/

View File

@ -167,7 +167,7 @@ function node_access_entity_test_page() {
}
/**
* Implements hook_form_node_form_alter().
* Implements hook_form_BASE_FORM_ID_alter().
*/
function node_access_test_form_node_form_alter(&$form, $form_state) {
// Only show this checkbox for NodeAccessBaseTableTestCase.

View File

@ -7,7 +7,7 @@ Drupal.behaviors.openid = {
var cookie = $.cookie('Drupal.visitor.openid_identifier');
// This behavior attaches by ID, so is only valid once on a page.
if (!$('#edit-openid-identifier.openid-processed').size()) {
if (!$('#edit-openid-identifier.openid-processed').length) {
if (cookie) {
$('#edit-openid-identifier').val(cookie);
}

View File

@ -19,7 +19,6 @@ html {
#overlay-close:hover {
background: transparent url(images/close-rtl.png) no-repeat;
-moz-border-radius-topright: 0;
-webkit-border-top-right-radius: 0;
border-top-right-radius: 0;
}

View File

@ -65,7 +65,6 @@
#overlay-close:hover {
background: transparent url(images/close.png) no-repeat; /* LTR */
-moz-border-radius-topleft: 0; /* LTR */
-webkit-border-top-left-radius: 0; /* LTR */
border-top-left-radius: 0; /* LTR */
display: block;
height: 26px;
@ -98,8 +97,6 @@
#overlay-tabs li a:hover {
background-color: #a6a7a2;
-moz-border-radius: 8px 8px 0 0;
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
border-radius: 8px 8px 0 0;
color: #000;
display: inline-block;
@ -142,8 +139,6 @@
margin: -20px auto 20px;
width: 80%;
-moz-border-radius: 0 0 8px 8px;
-webkit-border-bottom-left-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
border-radius: 0 0 8px 8px;
}
.overlay-disable-message-focused {

View File

@ -14,9 +14,10 @@
function path_admin_overview($keys = NULL) {
// Add the filter form above the overview table.
$build['path_admin_filter_form'] = drupal_get_form('path_admin_filter_form', $keys);
// Enable language column if locale is enabled or if we have any alias with language
// Enable language column if language.module is enabled or if we have any
// alias with a language.
$alias_exists = (bool) db_query_range('SELECT 1 FROM {url_alias} WHERE langcode <> :langcode', 0, 1, array(':langcode' => LANGUAGE_NONE))->fetchField();
$multilanguage = (module_exists('locale') || $alias_exists);
$multilanguage = (module_exists('language') || $alias_exists);
$header = array();
$header[] = array('data' => t('Alias'), 'field' => 'alias', 'sort' => 'asc');
@ -44,7 +45,7 @@ function path_admin_overview($keys = NULL) {
$row['data']['alias'] = l($data->alias, $data->source);
$row['data']['source'] = l($data->source, $data->source, array('alias' => TRUE));
if ($multilanguage) {
$row['data']['langcode'] = module_invoke('locale', 'language_name', $data->langcode);
$row['data']['language_name'] = language_name($data->langcode);
}
$operations = array();
@ -130,10 +131,9 @@ function path_admin_form($form, &$form_state, $path = array('source' => '', 'ali
'#required' => TRUE,
);
// A hidden value unless locale module is enabled.
if (module_exists('locale')) {
// A hidden value unless language.module is enabled.
if (module_exists('language')) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('All languages'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
@ -142,9 +142,11 @@ function path_admin_form($form, &$form_state, $path = array('source' => '', 'ali
'#type' => 'select',
'#title' => t('Language'),
'#options' => $language_options,
'#empty_value' => LANGUAGE_NONE,
'#empty_option' => t('- None -'),
'#default_value' => $path['langcode'],
'#weight' => -10,
'#description' => t('A path alias set for a specific language will always be used when displaying this page in that language, and takes precedence over path aliases set for <em>All languages</em>.'),
'#description' => t('A path alias set for a specific language will always be used when displaying this page in that language, and takes precedence over path aliases set as <em>- None -</em>.'),
);
}
else {
@ -194,7 +196,8 @@ function path_admin_form_validate($form, &$form_state) {
$source = drupal_get_normal_path($source);
$alias = $form_state['values']['alias'];
$pid = isset($form_state['values']['pid']) ? $form_state['values']['pid'] : 0;
// Language is only set if locale module is enabled, otherwise save for all languages.
// Language is only set if language.module is enabled, otherwise save for all
// languages.
$langcode = isset($form_state['values']['langcode']) ? $form_state['values']['langcode'] : LANGUAGE_NONE;
$has_alias = db_query("SELECT COUNT(alias) FROM {url_alias} WHERE pid <> :pid AND alias = :alias AND langcode = :langcode", array(

View File

@ -1,26 +0,0 @@
<?php
/**
* @file
* Default theme implementation to display the bar for a single choice in a
* poll.
*
* Variables available:
* - $title: The title of the poll.
* - $votes: The number of votes for this choice
* - $total_votes: The number of votes for this choice
* - $percentage: The percentage of votes for this choice.
* - $vote: The choice number of the current user's vote.
* - $voted: Set to TRUE if the user voted for this choice.
*
* @see template_preprocess_poll_bar()
*/
?>
<div class="text"><?php print $title; ?></div>
<div class="bar">
<div style="width: <?php print $percentage; ?>%;" class="foreground"></div>
</div>
<div class="percent">
<?php print $percentage; ?>%
</div>

View File

@ -1,26 +0,0 @@
<?php
/**
* @file
* Default theme implementation to display the bar for a single choice in a
* poll.
*
* Variables available:
* - $title: The title of the poll.
* - $votes: The number of votes for this choice
* - $total_votes: The number of votes for this choice
* - $percentage: The percentage of votes for this choice.
* - $vote: The choice number of the current user's vote.
* - $voted: Set to TRUE if the user voted for this choice.
*
* @see template_preprocess_poll_bar()
*/
?>
<div class="text"><?php print $title; ?></div>
<div class="bar">
<div style="width: <?php print $percentage; ?>%;" class="foreground"></div>
</div>
<div class="percent">
<?php print $percentage; ?>% (<?php print format_plural($votes, '1 vote', '@count votes'); ?>)
</div>

View File

@ -1,28 +0,0 @@
<?php
/**
* @file
* Default theme implementation to display the poll results in a block.
*
* Variables available:
* - $title: The title of the poll.
* - $results: The results of the poll.
* - $votes: The total results in the poll.
* - $links: Links in the poll.
* - $nid: The nid of the poll
* - $cancel_form: A form to cancel the user's vote, if allowed.
* - $raw_links: The raw array of links. Should be run through theme('links')
* if used.
* - $vote: The choice number of the current user's vote.
*
* @see template_preprocess_poll_results()
*/
?>
<div class="poll">
<div class="title"><?php print $title ?></div>
<?php print $results ?>
<div class="total">
<?php print t('Total votes: @votes', array('@votes' => $votes)); ?>
</div>
</div>
<div class="links"><?php print $links; ?></div>

View File

@ -17,7 +17,10 @@
* @see template_preprocess_poll_results()
*/
?>
<div class="poll">
<article class="poll">
<?php if ($block): ?>
<h3 class="poll-title"><?php print $title; ?></h3>
<?php endif; ?>
<?php print $results; ?>
<div class="total">
<?php print t('Total votes: @votes', array('@votes' => $votes)); ?>
@ -25,4 +28,7 @@
<?php if (!empty($cancel_form)): ?>
<?php print $cancel_form; ?>
<?php endif; ?>
</div>
</article>
<?php if ($block): ?>
<div class="links"><?php print $links; ?></div>
<?php endif; ?>

View File

@ -5,6 +5,6 @@
.poll .percent {
text-align: left;
}
.poll .vote-form .choices {
.poll .vote-form {
text-align: right;
}

View File

@ -14,16 +14,16 @@
* @see template_preprocess_poll_vote()
*/
?>
<div class="poll">
<article class="poll">
<div class="vote-form">
<div class="choices">
<?php if ($block): ?>
<div class="title"><?php print $title; ?></div>
<?php endif; ?>
<?php print $choice; ?>
</div>
<?php if ($block): ?>
<h3 class="poll-title"><?php print $title; ?></h3>
<?php endif; ?>
<?php print $choice; ?>
<?php print $vote; ?>
</div>
<?php // This is the 'rest' of the form, in case items have been added. ?>
<?php print $rest ?>
</div>
</article>

View File

@ -24,12 +24,10 @@
.poll .vote-form {
text-align: center;
}
.poll .vote-form .choices {
.poll .vote-form {
text-align: left; /* LTR */
margin: 0 auto;
display: table;
}
.poll .vote-form .choices .title {
.poll .vote-form .poll-title {
font-weight: bold;
}
.node-form #edit-poll-more {

View File

@ -42,25 +42,8 @@ function poll_theme() {
'template' => 'poll-results',
'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
),
'poll_bar' => array(
'template' => 'poll-bar',
'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
),
);
// The theme system automatically discovers the theme's functions and
// templates that implement more targeted "suggestions" of generic theme
// hooks. But suggestions implemented by a module must be explicitly
// registered.
$theme_hooks += array(
'poll_results__block' => array(
'template' => 'poll-results--block',
'variables' => $theme_hooks['poll_results']['variables'],
),
'poll_bar__block' => array(
'template' => 'poll-bar--block',
'variables' => $theme_hooks['poll_bar']['variables'],
),
);
return $theme_hooks;
}
@ -832,15 +815,25 @@ function poll_view_results($node, $view_mode, $block = FALSE) {
}
}
$poll_results = '';
$poll_results = array();
foreach ($node->choice as $i => $choice) {
if (!empty($choice['chtext'])) {
$chvotes = isset($choice['chvotes']) ? $choice['chvotes'] : NULL;
$poll_results .= theme('poll_bar', array('title' => $choice['chtext'], 'votes' => $chvotes, 'total_votes' => $total_votes, 'vote' => isset($node->vote) && $node->vote == $i, 'block' => $block));
}
$chvotes = isset($choice['chvotes']) ? $choice['chvotes'] : NULL;
$percentage = round($chvotes * 100 / max($total_votes, 1));
$display_votes = !$block ? ' (' . format_plural($chvotes, '1 vote', '@count votes') . ')' : '';
$poll_results[] = array(
'#theme' => 'meter',
'#prefix' => '<div class="choice-title">' . check_plain($choice['chtext']) . '</div>',
'#display_value' => t('!percentage%', array('!percentage' => $percentage)) . $display_votes,
'#min' => 0,
'#max' => $total_votes,
'#value' => $chvotes,
'#percentage' => $percentage,
'#attributes' => array('class' => 'bar'),
);
}
return theme('poll_results', array('raw_title' => $node->title, 'results' => $poll_results, 'votes' => $total_votes, 'raw_links' => isset($node->links) ? $node->links : array(), 'block' => $block, 'nid' => $node->nid, 'vote' => isset($node->vote) ? $node->vote : NULL));
return theme('poll_results', array('raw_title' => $node->title, 'results' => drupal_render($poll_results), 'votes' => $total_votes, 'raw_links' => isset($node->links) ? $node->links : array(), 'block' => $block, 'nid' => $node->nid, 'vote' => isset($node->vote) ? $node->vote : NULL));
}
@ -917,27 +910,6 @@ function template_preprocess_poll_results(&$variables) {
$variables['cancel_form'] = drupal_render($elements);
}
$variables['title'] = check_plain($variables['raw_title']);
if ($variables['block']) {
$variables['theme_hook_suggestions'][] = 'poll_results__block';
}
}
/**
* Preprocess the poll_bar theme hook.
*
* Inputs: $title, $votes, $total_votes, $voted, $block
*
* @see poll-bar.tpl.php
* @see poll-bar--block.tpl.php
* @see theme_poll_bar()
*/
function template_preprocess_poll_bar(&$variables) {
if ($variables['block']) {
$variables['theme_hook_suggestions'][] = 'poll_bar__block';
}
$variables['title'] = check_plain($variables['title']);
$variables['percentage'] = round($variables['votes'] * 100 / max($variables['total_votes'], 1));
}
/**

View File

@ -228,10 +228,10 @@ class PollCreateTestCase extends PollTestCase {
$this->clickLink($title);
$this->assertText($new_option, 'New option found.');
$option = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="text"]');
$option = $this->xpath('//div[@id="node-1"]//article[@class="poll"]//div[@class="choice-title"]');
$this->assertEqual(end($option), $new_option, 'Last item is equal to new option.');
$votes = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="percent"]');
$votes = $this->xpath('//div[@id="node-1"]//article[@class="poll"]//div[@class="percent"]');
$this->assertTrue(strpos(end($votes), $vote_count) > 0, t("Votes saved."));
}

View File

@ -1,13 +0,0 @@
.search-advanced .criterion {
float: right;
margin-right: 0;
margin-left: 2em;
}
.search-advanced .action {
float: right;
clear: right;
}
.search-results .search-snippet-info {
padding-right: 1em; /* LTR */
}

View File

@ -1,34 +0,0 @@
.search-form {
margin-bottom: 1em;
}
.search-form input {
margin-top: 0;
margin-bottom: 0;
}
.search-results {
list-style: none;
}
.search-results p {
margin-top: 0;
}
.search-results .title {
font-size: 1.2em;
}
.search-results li {
margin-bottom: 1em;
}
.search-results .search-snippet-info {
padding-left: 1em; /* LTR */
}
.search-results .search-info {
font-size: 0.85em;
}
.search-advanced .criterion {
float: left; /* LTR */
margin-right: 2em; /* LTR */
}
.search-advanced .action {
float: left; /* LTR */
clear: left; /* LTR */
}

View File

@ -6,4 +6,4 @@ core = 8.x
files[] = search.extender.inc
files[] = search.test
configure = admin/config/search/settings
stylesheets[all][] = search.css
stylesheets[all][] = search.theme.css

View File

@ -31,8 +31,6 @@
.add-or-remove-shortcuts a:focus span.text,
.add-or-remove-shortcuts a:hover span.text {
-moz-border-radius: 5px 0 0 5px;
-webkit-border-top-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
border-radius: 5px 0 0 5px;
padding-left: 6px;
}

View File

@ -82,7 +82,7 @@ Drupal.behaviors.shortcutDrag = {
var statusName = statusRow.className.replace(/([^ ]+[ ]+)*shortcut-status-([^ ]+)([ ]+[^ ]+)*/, '$2');
var statusField = $('select.shortcut-status-select', rowObject.element);
statusField.val(statusName);
};
}
tableDrag.restripeTable = function () {
// :even and :odd are reversed because jQuery counts from 0 and

View File

@ -23,7 +23,6 @@
padding: 0 5px 0 5px;
margin-right: 5px; /* LTR */
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
@ -45,7 +44,6 @@
height: 30px;
margin-right: 5px; /* LTR */
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
@ -90,8 +88,6 @@
padding-right: 6px; /* LTR */
cursor: pointer;
-moz-border-radius: 0 5px 5px 0; /* LTR */
-webkit-border-top-right-radius: 5px; /* LTR */
-webkit-border-bottom-right-radius: 5px; /* LTR */
border-radius: 0 5px 5px 0; /* LTR */
}

View File

@ -16,7 +16,7 @@ Drupal.behaviors.simpleTestMenuCollapse = {
$('div.simpletest-image').click(function () {
var trs = $(this).closest('tbody').children('.' + settings.simpleTest[this.id].testClass);
var direction = settings.simpleTest[this.id].imageDirection;
var row = direction ? trs.size() - 1 : 0;
var row = direction ? trs.length - 1 : 0;
// If clicked in the middle of expanding a group, stop so we can switch directions.
if (timeout) {
@ -35,7 +35,7 @@ Drupal.behaviors.simpleTestMenuCollapse = {
}
}
else {
if (row < trs.size()) {
if (row < trs.length) {
$(trs[row]).removeClass('js-hide').show();
row++;
timeout = setTimeout(rowToggle, 20);

View File

@ -2394,6 +2394,14 @@ class CommonFormatDateTestCase extends DrupalWebTestCase {
$this->assertIdentical(format_date($timestamp, 'medium'), '25. marzo 2007 - 17:00', t('Test medium date format.'));
$this->assertIdentical(format_date($timestamp, 'short'), '2007 Mar 25 - 5:00pm', t('Test short date format.'));
$this->assertIdentical(format_date($timestamp), '25. marzo 2007 - 17:00', t('Test default date format.'));
// Test HTML time element formats.
$this->assertIdentical(format_date($timestamp, 'html_datetime'), '2007-03-25T17:00:00-0700', t('Test html_datetime date format.'));
$this->assertIdentical(format_date($timestamp, 'html_date'), '2007-03-25', t('Test html_date date format.'));
$this->assertIdentical(format_date($timestamp, 'html_time'), '17:00:00', t('Test html_time date format.'));
$this->assertIdentical(format_date($timestamp, 'html_yearless_date'), '03-25', t('Test html_yearless_date date format.'));
$this->assertIdentical(format_date($timestamp, 'html_week'), '2007-W12', t('Test html_week date format.'));
$this->assertIdentical(format_date($timestamp, 'html_month'), '2007-03', t('Test html_month date format.'));
$this->assertIdentical(format_date($timestamp, 'html_year'), '2007', t('Test html_year date format.'));
// Restore the original user and language, and enable session saving.
$user = $real_user;

View File

@ -592,3 +592,65 @@ class ThemeRegistryTestCase extends DrupalWebTestCase {
$this->assertTrue($registry['theme_test_template_test_2'], 'Offset was returned correctly from the theme registry');
}
}
/**
* Tests for theme_datetime().
*/
class ThemeDatetime extends DrupalWebTestCase {
protected $profile = 'testing';
public static function getInfo() {
return array(
'name' => 'Theme Datetime',
'description' => 'Test the theme_datetime() function.',
'group' => 'Theme',
);
}
/**
* Test function theme_datetime().
*/
function testThemeDatetime() {
// Create timestamp and formatted date for testing.
$timestamp = 280281600;
$date = format_date($timestamp);
// Test with timestamp.
$variables = array(
'timestamp' => $timestamp,
);
$this->assertEqual('<time datetime="1978-11-19T00:00:00+0000">' . $date . '</time>', theme('datetime', $variables));
// Test with text and timestamp.
$variables = array(
'timestamp' => $timestamp,
'text' => "Dries' birthday",
);
$this->assertEqual('<time datetime="1978-11-19T00:00:00+0000">Dries&#039; birthday</time>', theme('datetime', $variables));
// Test with datetime attribute.
$variables = array(
'attributes' => array(
'datetime' => '1978-11-19',
),
);
$this->assertEqual('<time datetime="1978-11-19">1978-11-19</time>', theme('datetime', $variables));
// Test with text and datetime attribute.
$variables = array(
'text' => "Dries' birthday",
'attributes' => array(
'datetime' => '1978-11-19',
),
);
$this->assertEqual('<time datetime="1978-11-19">Dries&#039; birthday</time>', theme('datetime', $variables));
// Test with HTML text.
$variables = array(
'timestamp' => $timestamp,
'text' => "<span>Dries' birthday</span>",
'html' => TRUE,
);
$this->assertEqual('<time datetime="1978-11-19T00:00:00+0000"><span>Dries\' birthday</span></time>', theme('datetime', $variables));
}
}

View File

@ -609,7 +609,11 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
* @endcode
* This 'abc' object will then be passed into the callback functions defined
* for the menu item, such as the page callback function mymodule_abc_edit()
* to replace the integer 1 in the argument array.
* to replace the integer 1 in the argument array. Note that a load function
* should return FALSE when it is unable to provide a loadable object. For
* example, the node_load() function for the 'node/%node/edit' menu item will
* return FALSE for the path 'node/999/edit' if a node with a node ID of 999
* does not exist. The menu routing system will return a 404 error in this case.
*
* You can also define a %wildcard_to_arg() function (for the example menu
* entry above this would be 'mymodule_abc_to_arg()'). The _to_arg() function
@ -786,7 +790,8 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
* "default" task, which should display the same page as the parent item.
* If the "type" element is omitted, MENU_NORMAL_ITEM is assumed.
* - "options": An array of options to be passed to l() when generating a link
* from this menu item.
* from this menu item. Note that the "options" parameter has no effect on
* MENU_LOCAL_TASK, MENU_DEFAULT_LOCAL_TASK, and MENU_LOCAL_ACTION items.
*
* For a detailed usage example, see page_example.module.
* For comprehensive documentation on the menu system, see

View File

@ -2747,8 +2747,8 @@ function system_region_list($theme_key, $show = REGIONS_ALL) {
* Implements hook_system_info_alter().
*/
function system_system_info_alter(&$info, $file, $type) {
// Remove page-top from the blocks UI since it is reserved for modules to
// populate from outside the blocks system.
// Remove page-top and page-bottom from the blocks UI since they are reserved for
// modules to populate from outside the blocks system.
if ($type == 'theme') {
$info['regions_hidden'][] = 'page_top';
$info['regions_hidden'][] = 'page_bottom';

View File

@ -45,13 +45,13 @@
* would be an in-memory queue backend which might lose items if it crashes.
* However, such a backend would be able to deal with significantly more writes
* than a reliable queue and for many tasks this is more important. See
* aggregator_cron() for an example of how can this not be a problem. Another
* example is doing Twitter statistics -- the small possibility of losing a few
* items is insignificant next to power of the queue being able to keep up with
* writes. As described in the processing section, regardless of the queue
* being reliable or not, the processing code should be aware that an item
* might be handed over for processing more than once (because the processing
* code might time out before it finishes).
* aggregator_cron() for an example of how to effectively utilize a
* non-reliable queue. Another example is doing Twitter statistics -- the small
* possibility of losing a few items is insignificant next to power of the
* queue being able to keep up with writes. As described in the processing
* section, regardless of the queue being reliable or not, the processing code
* should be aware that an item might be handed over for processing more than
* once (because the processing code might time out before it finishes).
*/
/**

View File

@ -2111,7 +2111,7 @@ class UpdateScriptFunctionalTest extends DrupalWebTestCase {
}
function setUp() {
parent::setUp('update_script_test');
parent::setUp(array('update_script_test', 'dblog'));
$this->update_url = $GLOBALS['base_url'] . '/core/update.php';
$this->update_user = $this->drupalCreateUser(array('administer software updates'));
}
@ -2212,6 +2212,56 @@ class UpdateScriptFunctionalTest extends DrupalWebTestCase {
$final_theme_data = db_query("SELECT * FROM {system} WHERE type = 'theme' ORDER BY name")->fetchAll();
$this->assertEqual($original_theme_data, $final_theme_data, t('Visiting update.php does not alter the information about themes stored in the database.'));
}
/**
* Tests update.php when there are no updates to apply.
*/
function testNoUpdateFunctionality() {
// Click through update.php with 'administer software updates' permission.
$this->drupalLogin($this->update_user);
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
$this->assertText(t('No pending updates.'));
$this->assertNoLink('Administration pages');
$this->clickLink('Front page');
$this->assertResponse(200);
// Click through update.php with 'access administration pages' permission.
$admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages'));
$this->drupalLogin($admin_user);
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
$this->assertText(t('No pending updates.'));
$this->clickLink('Administration pages');
$this->assertResponse(200);
}
/**
* Tests update.php after performing a successful update.
*/
function testSuccessfulUpdateFunctionality() {
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
// Click through update.php with 'administer software updates' permission.
$this->drupalLogin($this->update_user);
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
$this->drupalPost(NULL, array(), t('Apply pending updates'));
$this->assertText('Updates were attempted.');
$this->assertLink('site');
$this->assertNoLink('Administration pages');
$this->assertNoLink('logged');
$this->clickLink('Front page');
$this->assertResponse(200);
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
// Click through update.php with 'access administration pages' and
// 'access site reports' permissions.
$admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages', 'access site reports'));
$this->drupalLogin($admin_user);
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
$this->drupalPost(NULL, array(), t('Apply pending updates'));
$this->assertText('Updates were attempted.');
$this->assertLink('logged');
$this->clickLink('Administration pages');
$this->assertResponse(200);
}
}
/**

View File

@ -231,7 +231,6 @@ th.checkbox {
border-color: #666;
margin: 0 0.2em;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.progress .filled {

View File

@ -10,7 +10,7 @@ Drupal.behaviors.termDrag = {
attach: function (context, settings) {
var table = $('#taxonomy', context);
var tableDrag = Drupal.tableDrag.taxonomy; // Get the blocks tableDrag object.
var rows = $('tr', table).size();
var rows = $('tr', table).length;
// When a row is swapped, keep previous and next page classes set.
tableDrag.row.prototype.onSwap = function (swappedRow) {

View File

@ -1128,6 +1128,21 @@ class TaxonomyTermIndexTestCase extends TaxonomyWebTestCase {
))->fetchField();
$this->assertEqual(0, $index_count, t('Term 2 is not indexed.'));
}
/**
* Tests that there is a link to the parent term on the child term page.
*/
function testTaxonomyTermHierarchyBreadcrumbs() {
// Create two taxonomy terms and set term2 as the parent of term1.
$term1 = $this->createTerm($this->vocabulary);
$term2 = $this->createTerm($this->vocabulary);
$term1->parent = array($term2->tid);
taxonomy_term_save($term1);
// Verify that the page breadcrumbs include a link to the parent term.
$this->drupalGet('taxonomy/term/' . $term1->tid);
$this->assertRaw(l($term2->name, 'taxonomy/term/' . $term2->tid), t('Parent term link is displayed when viewing the node.'));
}
}
/**

View File

@ -109,7 +109,6 @@ body.toolbar-drawer {
#toolbar div.toolbar-menu ul li a {
padding: 0 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
#toolbar div.toolbar-menu ul li a:focus,

View File

@ -139,7 +139,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
// might need to distinguish between enabled and disabled languages, hence
// we divide them in two option groups.
if ($translator_widget) {
$options = array($groups[1] => array(LANGUAGE_NONE => t('Language neutral')));
$options = array($groups[1] => array(LANGUAGE_NONE => t('- None -')));
foreach (array(1, 0) as $status) {
$group = $groups[$status];
foreach ($grouped_languages[$status] as $langcode => $language) {

View File

@ -168,7 +168,7 @@ Drupal.evaluatePasswordStrength = function (password, translate) {
// Assemble the final message.
msg = translate.hasWeaknesses + '<ul><li>' + msg.join('</li><li>') + '</li></ul>';
return { strength: strength, message: msg, indicatorText: indicatorText }
return { strength: strength, message: msg, indicatorText: indicatorText };
};
@ -180,7 +180,7 @@ Drupal.behaviors.fieldUserRegistration = {
attach: function (context, settings) {
var $checkbox = $('form#field-ui-field-edit-form input#edit-instance-settings-user-register-form');
if ($checkbox.size()) {
if ($checkbox.length) {
$('input#edit-instance-required', context).once('user-register-form-checkbox', function () {
$(this).bind('change', function (e) {
if ($(this).attr('checked')) {

View File

@ -3478,23 +3478,27 @@ function user_preferred_language($account, $default = NULL) {
* @see drupal_mail()
*
* @param $op
* The operation being performed on the account. Possible values:
* 'register_admin_created': Welcome message for user created by the admin
* 'register_no_approval_required': Welcome message when user self-registers
* 'register_pending_approval': Welcome message, user pending admin approval
* 'password_reset': Password recovery request
* 'status_activated': Account activated
* 'status_blocked': Account blocked
* 'cancel_confirm': Account cancellation request
* 'status_canceled': Account canceled
* The operation being performed on the account. Possible values:
* - 'register_admin_created': Welcome message for user created by the admin.
* - 'register_no_approval_required': Welcome message when user
* self-registers.
* - 'register_pending_approval': Welcome message, user pending admin
* approval.
* - 'password_reset': Password recovery request.
* - 'status_activated': Account activated.
* - 'status_blocked': Account blocked.
* - 'cancel_confirm': Account cancellation request.
* - 'status_canceled': Account canceled.
*
* @param $account
* The user object of the account being notified. Must contain at
* least the fields 'uid', 'name', and 'mail'.
* The user object of the account being notified. Must contain at
* least the fields 'uid', 'name', and 'mail'.
* @param $language
* Optional language to use for the notification, overriding account language.
* Optional language to use for the notification, overriding account language.
*
* @return
* The return value from drupal_mail_system()->mail(), if ends up being called.
* The return value from drupal_mail_system()->mail(), if ends up being
* called.
*/
function _user_mail_notify($op, $account, $language = NULL) {
// By default, we always notify except for canceled and blocked.

View File

@ -1,3 +1,3 @@
This directory contains test case code for Drupal core Components and Subsystems.
Test classes should mirror the namespace of the code being tested. Supporting
code for test classes is allowed.
This directory contains test case code for Drupal core Components and
Subsystems. Test classes should mirror the namespace of the code being tested.
Supporting code for test classes is allowed.

View File

@ -58,10 +58,8 @@
background: rgba(255, 255, 255, 0.7);
text-shadow: 0 1px #eee;
-moz-border-radius-topleft: 8px;
-webkit-border-top-left-radius: 8px;
border-top-left-radius: 8px;
-moz-border-radius-topright: 8px;
-webkit-border-top-right-radius: 8px;
border-top-right-radius: 8px;
}
#preview-main-menu-links a:hover,

View File

@ -86,7 +86,6 @@ kbd {
display: inline-block;
padding: 0 6px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
pre {
@ -279,10 +278,6 @@ ul.tips {
padding: 1px 10px 2px 10px;
text-decoration: none;
-moz-border-radius: 0 0 10px 10px;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-left-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
border-radius: 0 0 10px 10px;
}
#skip-link a:hover,
@ -480,8 +475,6 @@ h1#site-name {
text-shadow: 0 1px #eee;
-moz-border-radius-topleft: 8px;
-moz-border-radius-topright: 8px;
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
@ -979,10 +972,8 @@ ul.links {
margin: 0;
text-shadow: 0 1px 0 #fff;
-moz-border-radius-topleft: 6px;
-webkit-border-top-left-radius: 6px;
border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-webkit-border-top-right-radius: 6px;
border-top-right-radius: 6px;
}
.tabs ul.primary li.active a {
@ -1009,7 +1000,6 @@ ul.links {
background: #f2f2f2;
border-bottom: none;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
ul.action-links {
@ -1094,7 +1084,6 @@ a.button {
margin-right: 0.6em; /* LTR */
padding: 4px 17px;
-moz-border-radius: 20px;
-webkit-border-radius: 15px;
border-radius: 15px;
}
a.button:link,
@ -1117,7 +1106,6 @@ fieldset {
position: relative;
top: 12px; /* Offsets the negative margin of legends */
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.fieldset-wrapper {
@ -1131,8 +1119,6 @@ fieldset {
padding: 1em 0 0.2em;
-moz-border-radius-topright: 0;
-moz-border-radius-topleft: 0;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
@ -1152,7 +1138,6 @@ fieldset {
fieldset.collapsed {
background: transparent;
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
}
fieldset legend {
@ -1172,15 +1157,12 @@ fieldset legend {
top: -12px;
width: 100%;
-moz-border-radius-topleft: 4px;
-webkit-border-top-left-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-topright: 4px;
-webkit-border-top-right-radius: 4px;
border-top-right-radius: 4px;
}
fieldset.collapsed legend {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
fieldset legend a {
@ -1251,27 +1233,22 @@ input.form-submit:focus {
.contact-form #edit-name {
width: 75%;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.contact-form #edit-mail {
width: 75%;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.contact-form #edit-subject {
width: 75%;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.contact-form #edit-message {
width: 76.3%;
-moz-border-radius-topleft: 4px;
-moz-border-radius-topright: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
@ -1279,8 +1256,6 @@ input.form-submit:focus {
width: 76%;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
@ -1323,7 +1298,6 @@ input.form-button-disabled:active,
.comment-form .form-select {
margin: 0;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.comment-form .form-type-textarea label {
@ -1368,8 +1342,6 @@ input.form-button-disabled:active,
.comment-form .form-textarea {
-moz-border-radius-topleft: 4px;
-moz-border-radius-topright: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
@ -1584,8 +1556,6 @@ div.admin-panel .description {
}
.poll .vote-form {
text-align: left; /* LTR */
}
.poll .vote-form .choices {
margin: 0;
}
.poll .percent {
@ -1596,7 +1566,7 @@ div.admin-panel .description {
float: right;
text-align: right;
}
.poll .text {
.poll .choice-title {
clear: right;
margin-right: 2.25em;
}

View File

@ -304,10 +304,8 @@
line-height: 20px;
border-bottom: solid 1px #ccc;
-moz-border-radius-bottomleft: 0;
-webkit-border-bottom-left-radius: 0;
border-bottom-left-radius: 0;
-moz-border-radius-bottomright: 0;
-webkit-border-bottom-right-radius: 0;
border-bottom-right-radius: 0;
}
.ui-tabs .ui-tabs-nav li {
@ -319,7 +317,6 @@
float: none;
padding: 0 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a {
@ -366,7 +363,6 @@
border-right-color: #D2D2D2;
background: url(images/buttons.png) 0 0 repeat-x;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
}
.ui-dialog .ui-dialog-buttonpane button:active {
@ -398,7 +394,6 @@
border-right-color: #D2D2D2;
background: url(images/buttons.png) 0 0 repeat-x;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.ui-slider a.ui-state-active,

View File

@ -166,10 +166,6 @@ pre {
padding: 1px 10px 2px 10px; /* LTR */
text-decoration: none;
-moz-border-radius: 0 0 10px 10px;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-left-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
border-radius: 0 0 10px 10px;
}
#skip-link a:hover,
@ -288,8 +284,6 @@ ul.primary li.active a {
border-style: solid;
border-color: #a6a7a2;
-moz-border-radius: 8px 8px 0 0;
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
border-radius: 8px 8px 0 0;
}
ul.primary li.active a,
@ -331,7 +325,6 @@ ul.secondary li.active a,
ul.secondary li.active a.active {
padding: 2px 10px;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
}
ul.secondary li a:hover,
@ -368,7 +361,6 @@ ul.secondary li.active a.active {
width: 80px;
overflow: hidden;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
#secondary-links ul.links li a:hover {
@ -663,7 +655,6 @@ a.button {
border-right-color: #d2d2d2;
background: url(images/buttons.png) 0 0 repeat-x;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
}
a.button:link,
@ -1003,6 +994,5 @@ div.add-or-remove-shortcuts {
background-color: #59a0d8;
color: #fff;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}

View File

@ -148,7 +148,9 @@ function update_helpful_links() {
// NOTE: we can't use l() here because the URL would point to
// 'core/update.php?q=admin'.
$links[] = '<a href="' . base_path() . '">Front page</a>';
$links[] = '<a href="' . base_path() . '?q=admin">Administration pages</a>';
if (user_access('access administration pages')) {
$links[] = '<a href="' . base_path() . '?q=admin">Administration pages</a>';
}
return $links;
}
@ -158,7 +160,7 @@ function update_results_page() {
update_task_list();
// Report end result.
if (module_exists('dblog')) {
if (module_exists('dblog') && user_access('access site reports')) {
$log_message = ' All errors have been <a href="' . base_path() . '?q=admin/reports/dblog">logged</a>.';
}
else {
@ -166,7 +168,7 @@ function update_results_page() {
}
if ($_SESSION['update_success']) {
$output = '<p>Updates were attempted. If you see no failures below, you may proceed happily to the <a href="' . base_path() . '?q=admin">administration pages</a>. Otherwise, you may need to update your database manually.' . $log_message . '</p>';
$output = '<p>Updates were attempted. If you see no failures below, you may proceed happily back to your <a href="' . base_path() . '">site</a>. Otherwise, you may need to update your database manually.' . $log_message . '</p>';
}
else {
list($module, $version) = array_pop(reset($_SESSION['updates_remaining']));

View File

@ -2,5 +2,5 @@
They should not be modified from their original form at any time. They should
be changed only to keep up to date with upstream projects.
Code in this directory MAY be licensed under a GPL-compatible non-GPL license. If
so, it must be properly documented in COPYRIGHT.txt.
Code in this directory MAY be licensed under a GPL-compatible non-GPL license.
If so, it must be properly documented in COPYRIGHT.txt.