Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.00% covered (warning)
75.00%
24 / 32
50.00% covered (danger)
50.00%
6 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
GadgetResourceLoaderModule
75.00% covered (warning)
75.00%
24 / 32
50.00% covered (danger)
50.00%
6 / 12
31.27
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGadget
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
3.33
 getPages
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
6
 getRequireKey
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 validateScriptFile
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 isPackaged
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDependencies
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getMessages
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSkins
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 requiresES6
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGroup
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace MediaWiki\Extension\Gadgets;
4
5use InvalidArgumentException;
6use MediaWiki\MediaWikiServices;
7use MediaWiki\ResourceLoader as RL;
8
9/**
10 * Class representing a list of resources for one gadget, basically a wrapper
11 * around the Gadget class.
12 */
13class GadgetResourceLoaderModule extends RL\WikiModule {
14    /**
15     * @var string
16     */
17    private $id;
18
19    /**
20     * @var Gadget
21     */
22    private $gadget;
23
24    public function __construct( array $options ) {
25        $this->id = $options['id'];
26    }
27
28    /**
29     * @return Gadget instance this module is about
30     */
31    private function getGadget() {
32        if ( !$this->gadget ) {
33            /** @var GadgetRepo $repo */
34            $repo = MediaWikiServices::getInstance()->getService( 'GadgetsRepo' );
35            try {
36                $this->gadget = $repo->getGadget( $this->id );
37            } catch ( InvalidArgumentException ) {
38                // Fallback to a placeholder object...
39                $this->gadget = Gadget::newEmptyGadget( $this->id );
40            }
41        }
42
43        return $this->gadget;
44    }
45
46    /**
47     * @param RL\Context $context
48     * @return array
49     */
50    protected function getPages( RL\Context $context ) {
51        $gadget = $this->getGadget();
52        $pages = [];
53
54        foreach ( $gadget->getStyles() as $style ) {
55            $pages[$style] = [ 'type' => 'style' ];
56        }
57
58        if ( $gadget->supportsResourceLoader() ) {
59            foreach ( $gadget->getScripts() as $script ) {
60                $pages[$script] = [ 'type' => 'script' ];
61            }
62            if ( $gadget->isPackaged() ) {
63                foreach ( $gadget->getJSONs() as $json ) {
64                    $pages[$json] = [ 'type' => 'data' ];
65                }
66            }
67        }
68
69        return $pages;
70    }
71
72    /**
73     * @param string $titleText
74     * @return string
75     */
76    public function getRequireKey( $titleText ): string {
77        /** @var GadgetRepo $repo */
78        $repo = MediaWikiServices::getInstance()->getService( 'GadgetsRepo' );
79        return $repo->titleWithoutPrefix( $titleText, $this->id );
80    }
81
82    /**
83     * @param string $fileName
84     * @param string $contents
85     * @return string
86     */
87    protected function validateScriptFile( $fileName, $contents ) {
88        // Temporary solution to support gadgets in ES6 by disabling validation
89        // for them and putting them in a separate resource group to avoid a syntax error in them
90        // from corrupting core/extension-loaded scripts or other non-ES6 gadgets.
91        if ( $this->requiresES6() ) {
92            return $contents;
93        }
94        return parent::validateScriptFile( $fileName, $contents );
95    }
96
97    /**
98     * Returns whether this gadget is packaged.
99     */
100    public function isPackaged(): bool {
101        return $this->getGadget()->isPackaged();
102    }
103
104    /**
105     * @param RL\Context|null $context
106     * @return string[] Names of resources this module depends on
107     */
108    public function getDependencies( ?RL\Context $context = null ) {
109        return $this->getGadget()->getDependencies();
110    }
111
112    /**
113     * @return string RL\Module::LOAD_STYLES or RL\Module::LOAD_GENERAL
114     */
115    public function getType() {
116        return $this->getGadget()->getType() === 'styles'
117            ? RL\Module::LOAD_STYLES
118            : RL\Module::LOAD_GENERAL;
119    }
120
121    /** @inheritDoc */
122    public function getMessages() {
123        return $this->getGadget()->getMessages();
124    }
125
126    /** @inheritDoc */
127    public function getSkins(): ?array {
128        return $this->getGadget()->getRequiredSkins() ?: null;
129    }
130
131    /** @inheritDoc */
132    public function requiresES6(): bool {
133        return $this->getGadget()->requiresES6();
134    }
135
136    /** @inheritDoc */
137    public function getGroup() {
138        return $this->requiresES6() ? 'es6-gadget' : self::GROUP_SITE;
139    }
140}