Commit 1bc5b98e authored by Crell's avatar Crell

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

parents b9131de6 7500befb
......@@ -51,12 +51,12 @@ public function remove($path);
* @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.
......
......@@ -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.
*
......
......@@ -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
......
......@@ -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),
),
......
......@@ -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.
......
......@@ -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.
*
......
......@@ -330,7 +330,7 @@ public function prepareInstallDirectory(&$filetransfer, $directory) {
}
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);
}
}
......
......@@ -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'));
}
......
This diff is collapsed.
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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.
......
......@@ -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';
}
}
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -40,7 +40,6 @@ a.contextual-links-trigger {
width: 28px;
overflow: hidden;