Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.00% covered (warning)
80.00%
16 / 20
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
AddLinkAttributes
80.00% covered (warning)
80.00%
16 / 20
0.00% covered (danger)
0.00%
0 / 1
9.65
0.00% covered (danger)
0.00%
0 / 1
 run
80.00% covered (warning)
80.00%
16 / 20
0.00% covered (danger)
0.00%
0 / 1
9.65
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Wt2Html\PP\Processors;
5
6use Wikimedia\Parsoid\Config\Env;
7use Wikimedia\Parsoid\DOM\DocumentFragment;
8use Wikimedia\Parsoid\DOM\Element;
9use Wikimedia\Parsoid\DOM\Node;
10use Wikimedia\Parsoid\Utils\DOMCompat;
11use Wikimedia\Parsoid\Utils\DOMUtils;
12use Wikimedia\Parsoid\Utils\WTUtils;
13use Wikimedia\Parsoid\Wt2Html\Wt2HtmlDOMProcessor;
14
15class AddLinkAttributes implements Wt2HtmlDOMProcessor {
16    /**
17     * @inheritDoc
18     */
19    public function run(
20        Env $env, Node $root, array $options = [], bool $atTopLevel = false
21    ): void {
22        '@phan-var Element|DocumentFragment $root';  // @var Element|DocumentFragment $root
23        // Add class info to ExtLink information.
24        // Currently positions the class immediately after the rel attribute
25        // to keep tests stable.
26        $extLinks = DOMCompat::querySelectorAll( $root, 'a[rel~="mw:ExtLink"]' );
27        foreach ( $extLinks as $a ) {
28            if ( $a->firstChild ) {
29                // The "external free" class is reserved for links which
30                // are syntactically unbracketed; see commit
31                // 65fcb7a94528ea56d461b3c7b9cb4d4fe4e99211 in core.
32                if ( WTUtils::isATagFromURLLinkSyntax( $a ) ) {
33                    $classInfoText = 'external free';
34                } elseif ( WTUtils::isATagFromMagicLinkSyntax( $a ) ) {
35                    // PHP uses specific suffixes for RFC/PMID/ISBN (the last of
36                    // which is an internal link, not an mw:ExtLink), but we'll
37                    // keep it simple since magic links are deprecated.
38                    $classInfoText = 'external mw-magiclink';
39                } else {
40                    $classInfoText = 'external text';
41                }
42            } else {
43                $classInfoText = 'external autonumber';
44            }
45            $a->setAttribute( 'class', $classInfoText );
46            $href = DOMCompat::getAttribute( $a, 'href' ) ?? '';
47            $attribs = $env->getExternalLinkAttribs( $href );
48            foreach ( $attribs as $key => $val ) {
49                if ( $key === 'rel' ) {
50                    foreach ( $val as $v ) {
51                        DOMUtils::addRel( $a, $v );
52                    }
53                } else {
54                    $a->setAttribute( $key, $val );
55                }
56            }
57        }
58        // Add classes to Interwiki links
59        $iwLinks = DOMCompat::querySelectorAll( $root, 'a[rel~="mw:WikiLink/Interwiki"]' );
60        foreach ( $iwLinks as $a ) {
61            DOMCompat::getClassList( $a )->add( 'extiw' );
62        }
63    }
64}