mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Added SRI support for Requirements::css, Requirements::javascript (#9139)
This commit is contained in:
parent
79fa61edf8
commit
cb91f5fa06
@ -194,10 +194,13 @@ class Requirements implements Flushable
|
||||
* @param string $file The CSS file to load, relative to site root
|
||||
* @param string $media Comma-separated list of media types to use in the link tag
|
||||
* (e.g. 'screen,projector')
|
||||
* @param array $options List of options. Available options include:
|
||||
* - 'integrity' : SubResource Integrity hash
|
||||
* - 'crossorigin' : Cross-origin policy for the resource
|
||||
*/
|
||||
public static function css($file, $media = null)
|
||||
public static function css($file, $media = null, $options = [])
|
||||
{
|
||||
self::backend()->css($file, $media);
|
||||
self::backend()->css($file, $media, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,6 +400,8 @@ class Requirements_Backend
|
||||
* - 'async' : Boolean value to set async attribute to script tag
|
||||
* - 'defer' : Boolean value to set defer attribute to script tag
|
||||
* - 'type' : Override script type= value.
|
||||
* - 'integrity' : SubResource Integrity hash
|
||||
* - 'crossorigin' : Cross-origin policy for the resource
|
||||
*/
|
||||
public function javascript($file, $options = array())
|
||||
{
|
||||
@ -431,10 +433,15 @@ class Requirements_Backend
|
||||
&& $this->javascript[$file]['defer'] == true
|
||||
)
|
||||
);
|
||||
$integrity = $options['integrity'] ?? null;
|
||||
$crossorigin = $options['crossorigin'] ?? null;
|
||||
|
||||
$this->javascript[$file] = array(
|
||||
'async' => $async,
|
||||
'defer' => $defer,
|
||||
'type' => $type,
|
||||
'integrity' => $integrity,
|
||||
'crossorigin' => $crossorigin,
|
||||
);
|
||||
|
||||
// Record scripts included in this file
|
||||
@ -631,13 +638,21 @@ class Requirements_Backend
|
||||
* @param string $file The CSS file to load, relative to site root
|
||||
* @param string $media Comma-separated list of media types to use in the link tag
|
||||
* (e.g. 'screen,projector')
|
||||
* @param array $options List of options. Available options include:
|
||||
* - 'integrity' : SubResource Integrity hash
|
||||
* - 'crossorigin' : Cross-origin policy for the resource
|
||||
*/
|
||||
public function css($file, $media = null)
|
||||
public function css($file, $media = null, $options = [])
|
||||
{
|
||||
$file = ModuleResourceLoader::singleton()->resolvePath($file);
|
||||
|
||||
$integrity = $options['integrity'] ?? null;
|
||||
$crossorigin = $options['crossorigin'] ?? null;
|
||||
|
||||
$this->css[$file] = [
|
||||
"media" => $media
|
||||
"media" => $media,
|
||||
"integrity" => $integrity,
|
||||
"crossorigin" => $crossorigin,
|
||||
];
|
||||
}
|
||||
|
||||
@ -814,6 +829,12 @@ class Requirements_Backend
|
||||
if (!empty($attributes['defer'])) {
|
||||
$htmlAttributes['defer'] = 'defer';
|
||||
}
|
||||
if (!empty($attributes['integrity'])) {
|
||||
$htmlAttributes['integrity'] = $attributes['integrity'];
|
||||
}
|
||||
if (!empty($attributes['crossorigin'])) {
|
||||
$htmlAttributes['crossorigin'] = $attributes['crossorigin'];
|
||||
}
|
||||
$jsRequirements .= HTML::createTag('script', $htmlAttributes);
|
||||
$jsRequirements .= "\n";
|
||||
}
|
||||
@ -838,6 +859,12 @@ class Requirements_Backend
|
||||
if (!empty($params['media'])) {
|
||||
$htmlAttributes['media'] = $params['media'];
|
||||
}
|
||||
if (!empty($params['integrity'])) {
|
||||
$htmlAttributes['integrity'] = $params['integrity'];
|
||||
}
|
||||
if (!empty($params['crossorigin'])) {
|
||||
$htmlAttributes['crossorigin'] = $params['crossorigin'];
|
||||
}
|
||||
$requirements .= HTML::createTag('link', $htmlAttributes);
|
||||
$requirements .= "\n";
|
||||
}
|
||||
@ -1136,7 +1163,7 @@ class Requirements_Backend
|
||||
}
|
||||
switch ($type) {
|
||||
case 'css':
|
||||
$this->css($path, (isset($options['media']) ? $options['media'] : null));
|
||||
$this->css($path, (isset($options['media']) ? $options['media'] : null), $options);
|
||||
break;
|
||||
case 'js':
|
||||
$this->javascript($path, $options);
|
||||
@ -1283,7 +1310,11 @@ class Requirements_Backend
|
||||
if (!in_array($css, $fileList)) {
|
||||
$newCSS[$css] = $spec;
|
||||
} elseif (!$included && $combinedURL) {
|
||||
$newCSS[$combinedURL] = array('media' => (isset($options['media']) ? $options['media'] : null));
|
||||
$newCSS[$combinedURL] = array(
|
||||
'media' => $options['media'] ?? null,
|
||||
'integrity' => $options['integrity'] ?? null,
|
||||
'crossorigin' => $options['crossorigin'] ?? null,
|
||||
);
|
||||
$included = true;
|
||||
}
|
||||
// If already included, or otherwise blocked, then don't add into CSS
|
||||
|
@ -1183,4 +1183,29 @@ EOS
|
||||
$this->assertArrayHasKey('i18n/en-us.js', $actual);
|
||||
$this->assertArrayHasKey('i18n/fr.js', $actual);
|
||||
}
|
||||
|
||||
public function testSriAttributes()
|
||||
{
|
||||
/** @var Requirements_Backend $backend */
|
||||
$backend = Injector::inst()->create(Requirements_Backend::class);
|
||||
$this->setupRequirements($backend);
|
||||
|
||||
$backend->javascript('javascript/RequirementsTest_a.js', ['integrity' => 'abc', 'crossorigin' => 'use-credentials']);
|
||||
$backend->css('css/RequirementsTest_a.css', null, ['integrity' => 'def', 'crossorigin' => 'anonymous']);
|
||||
$html = $backend->includeInHTML(self::$html_template);
|
||||
|
||||
/* Javascript has correct attributes */
|
||||
$this->assertRegExp(
|
||||
'#<script type="application/javascript" src=".*/javascript/RequirementsTest_a.js.*" integrity="abc" crossorigin="use-credentials"#',
|
||||
$html,
|
||||
'javascript has correct sri attributes'
|
||||
);
|
||||
|
||||
/* CSS has correct attributes */
|
||||
$this->assertRegExp(
|
||||
'#<link .*href=".*/RequirementsTest_a\.css.*" integrity="def" crossorigin="anonymous"#',
|
||||
$html,
|
||||
'css has correct sri attributes'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user