Use faster DOMUtils::hasClass()

I tried to benchmark this. It's not really a big bottleneck in this
codebase, but can still be seen. For example, the relative runtime
of the method CommentUtils::isCommentSeparator (the heaviest user of
this feature) goes down from 1.5% to 0.3%.

Depends-On: If9252a97562542e7a4bec29edcc6e8dee0fb8221
Change-Id: I6b94a2481b5c4f7983df78ee48d45c0d8a50e53b
This commit is contained in:
thiemowmde 2023-11-02 15:08:25 +01:00
parent 7acd730719
commit 3cc4e00647
3 changed files with 12 additions and 16 deletions

View file

@ -112,7 +112,7 @@ class CommentFormatter {
$wrapperNode = $headingElement->parentNode; $wrapperNode = $headingElement->parentNode;
if ( !( if ( !(
$wrapperNode instanceof Element && $wrapperNode instanceof Element &&
DOMCompat::getClassList( $wrapperNode )->contains( 'mw-heading' ) DOMUtils::hasClass( $wrapperNode, 'mw-heading' )
) ) { ) ) {
// Do not add the wrapper if the heading has attributes generated from wikitext (T353489). // Do not add the wrapper if the heading has attributes generated from wikitext (T353489).
// Only allow reserved attributes (e.g. 'data-mw', which can't be used in wikitext, but which // Only allow reserved attributes (e.g. 'data-mw', which can't be used in wikitext, but which
@ -379,7 +379,7 @@ class CommentFormatter {
$headings = DOMCompat::querySelectorAll( $container, 'h2' ); $headings = DOMCompat::querySelectorAll( $container, 'h2' );
foreach ( $headings as $headingElement ) { foreach ( $headings as $headingElement ) {
$wrapper = $headingElement->parentNode; $wrapper = $headingElement->parentNode;
if ( $wrapper instanceof Element && DOMCompat::getClassList( $wrapper )->contains( 'toctitle' ) ) { if ( $wrapper instanceof Element && DOMUtils::hasClass( $wrapper, 'toctitle' ) ) {
continue; continue;
} }
$headingElement = static::handleHeading( $headingElement ); $headingElement = static::handleHeading( $headingElement );

View file

@ -25,6 +25,7 @@ use Wikimedia\Parsoid\DOM\Element;
use Wikimedia\Parsoid\DOM\Node; use Wikimedia\Parsoid\DOM\Node;
use Wikimedia\Parsoid\DOM\Text; use Wikimedia\Parsoid\DOM\Text;
use Wikimedia\Parsoid\Utils\DOMCompat; use Wikimedia\Parsoid\Utils\DOMCompat;
use Wikimedia\Parsoid\Utils\DOMUtils;
use Wikimedia\Timestamp\TimestampException; use Wikimedia\Timestamp\TimestampException;
// TODO consider making timestamp parsing not a returned function // TODO consider making timestamp parsing not a returned function
@ -563,7 +564,7 @@ class CommentParser {
*/ */
private function getUsernameFromLink( Element $link ): ?array { private function getUsernameFromLink( Element $link ): ?array {
// Selflink: use title of current page // Selflink: use title of current page
if ( DOMCompat::getClassList( $link )->contains( 'mw-selflink' ) ) { if ( DOMUtils::hasClass( $link, 'mw-selflink' ) ) {
$title = $this->title; $title = $this->title;
} else { } else {
$titleString = CommentUtils::getTitleFromUrl( $link->getAttribute( 'href' ) ?? '', $this->config ) ?? ''; $titleString = CommentUtils::getTitleFromUrl( $link->getAttribute( 'href' ) ?? '', $this->config ) ?? '';
@ -739,9 +740,8 @@ class CommentParser {
) { ) {
return NodeFilter::FILTER_REJECT; return NodeFilter::FILTER_REJECT;
} }
$classList = DOMCompat::getClassList( $node );
// Don't attempt to parse blocks marked 'mw-notalk' // Don't attempt to parse blocks marked 'mw-notalk'
if ( $classList->contains( 'mw-notalk' ) ) { if ( DOMUtils::hasClass( $node, 'mw-notalk' ) ) {
return NodeFilter::FILTER_REJECT; return NodeFilter::FILTER_REJECT;
} }
// Don't detect comments within references. We can't add replies to them without bungling up // Don't detect comments within references. We can't add replies to them without bungling up
@ -749,7 +749,7 @@ class CommentParser {
if ( if (
// <ol class="references"> is the only reliably consistent thing between the two parsers // <ol class="references"> is the only reliably consistent thing between the two parsers
$tagName === 'ol' && $tagName === 'ol' &&
DOMCompat::getClassList( $node )->contains( 'references' ) DOMUtils::hasClass( $node, 'references' )
) { ) {
return NodeFilter::FILTER_REJECT; return NodeFilter::FILTER_REJECT;
} }

View file

@ -14,6 +14,7 @@ use Wikimedia\Parsoid\DOM\Element;
use Wikimedia\Parsoid\DOM\Node; use Wikimedia\Parsoid\DOM\Node;
use Wikimedia\Parsoid\DOM\Text; use Wikimedia\Parsoid\DOM\Text;
use Wikimedia\Parsoid\Utils\DOMCompat; use Wikimedia\Parsoid\Utils\DOMCompat;
use Wikimedia\Parsoid\Utils\DOMUtils;
class CommentUtils { class CommentUtils {
@ -85,7 +86,7 @@ class CommentUtils {
*/ */
public static function isOurGeneratedNode( Node $node ): bool { public static function isOurGeneratedNode( Node $node ): bool {
return $node instanceof Element && ( return $node instanceof Element && (
DOMCompat::getClassList( $node )->contains( 'ext-discussiontools-init-replylink-buttons' ) || DOMUtils::hasClass( $node, 'ext-discussiontools-init-replylink-buttons' ) ||
$node->hasAttribute( 'data-mw-comment-start' ) || $node->hasAttribute( 'data-mw-comment-start' ) ||
$node->hasAttribute( 'data-mw-comment-end' ) $node->hasAttribute( 'data-mw-comment-end' )
); );
@ -164,15 +165,10 @@ class CommentUtils {
return true; return true;
} }
$classList = DOMCompat::getClassList( $node ); // Anything marked as not containing comments
if ( // {{outdent}} templates
// Anything marked as not containing comments // {{tracked}} templates (T313097)
$classList->contains( 'mw-notalk' ) || if ( DOMUtils::hasClass( $node, 'mw-notalk|outdent-template|mw-trackedTemplate' ) ) {
// {{outdent}} templates
$classList->contains( 'outdent-template' ) ||
// {{tracked}} templates (T313097)
$classList->contains( 'mw-trackedTemplate' )
) {
return true; return true;
} }