Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
77c613e3
Commit
77c613e3
authored
Dec 09, 2014
by
Nathaniel Catchpole
Browse files
Issue
#2382533
by Wim Leers: Attach assets only via the asset library system
parent
cd0cb0d7
Changes
34
Expand all
Hide whitespace changes
Inline
Side-by-side
core/includes/common.inc
View file @
77c613e3
...
...
@@ -871,9 +871,7 @@ function _drupal_add_html_head_link($attributes, $header = FALSE) {
* If CSS aggregation/compression is enabled, all cascading style sheets added
* with $options['preprocess'] set to TRUE will be merged into one aggregate
* file and compressed by removing all extraneous white space.
* Preprocessed inline stylesheets will not be aggregated into this single file;
* instead, they are just compressed upon output on the page. Externally hosted
* stylesheets are never aggregated or compressed.
* Externally hosted stylesheets are never aggregated or compressed.
*
* The reason for aggregating the files is outlined quite thoroughly here:
* http://www.die.net/musings/page_load_time/ "Load fewer external objects. Due
...
...
@@ -899,18 +897,15 @@ function _drupal_add_html_head_link($attributes, $header = FALSE) {
* override module-supplied CSS files based on their filenames, and this
* prefixing helps prevent confusing name collisions for theme developers.
* See drupal_get_css() where the overrides are performed.
* - 'inline': A string of CSS that should be placed in the given scope. Note
* that it is better practice to use 'file' stylesheets, rather than
* 'inline', as the CSS would then be aggregated and cached.
* - 'external': The absolute path to an external CSS file that is not hosted
* on the local server. These files will not be aggregated if CSS
* aggregation is enabled.
* @param $options
* (optional) A string defining the 'type' of CSS that is being added in the
* $data parameter ('file'
, 'inline',
or 'external'), or an array which can
*
have any or
all of the following keys:
* - 'type': The type of stylesheet being added. Available options are 'file'
,
*
'inline'
or 'external'. Defaults to 'file'.
* $data parameter ('file' or 'external'), or an array which can
have any or
* all of the following keys:
* - 'type': The type of stylesheet being added. Available options are 'file'
* or 'external'. Defaults to 'file'.
* - 'basename': Force a basename for the file being added. Modules are
* expected to use stylesheets with unique filenames, but integration of
* external libraries may make this impossible. The basename of
...
...
@@ -1027,12 +1022,6 @@ function _drupal_add_css($data = NULL, $options = NULL) {
// Add the data to the CSS array depending on the type.
switch
(
$options
[
'type'
])
{
case
'inline'
:
// For inline stylesheets, we don't want to use the $data as the array
// key as $data could be a very long string of CSS.
$css
[]
=
$options
;
break
;
case
'file'
:
// Local CSS files are keyed by basename; if a file with the same
// basename is added more than once, it gets overridden.
...
...
@@ -1278,21 +1267,12 @@ function drupal_clean_id_identifier($id) {
}
/**
* Adds a JavaScript file
,
setting
, or inline code
to the page.
* Adds a JavaScript file
or
setting to the page.
*
* The behavior of this function depends on the parameters it is called with.
* Generally, it handles the addition of JavaScript to the page, either as
* reference to an existing file or as inline code. The following actions can be
* performed using this function:
* Generally, it handles the addition of JavaScript to the page. The following
* actions can be performed using this function:
* - Add a file ('file'): Adds a reference to a JavaScript file to the page.
* - Add inline JavaScript code ('inline'): Executes a piece of JavaScript code
* on the current page by placing the code directly in the page (for example,
* to tell the user that a new message arrived, by opening a pop up, alert
* box, etc.). This should only be used for JavaScript that cannot be executed
* from a file. When adding inline code, make sure that you are not relying on
* $() being the jQuery function. Wrap your code in
* @code (function ($) {... })(jQuery); @endcode
* or use jQuery() instead of $().
* - Add external JavaScript ('external'): Allows the inclusion of external
* JavaScript files that are not hosted on the local server. Note that these
* external JavaScript references do not get aggregated when preprocessing is
...
...
@@ -1305,10 +1285,6 @@ function drupal_clean_id_identifier($id) {
* @code
* _drupal_add_js('core/misc/collapse.js');
* _drupal_add_js('core/misc/collapse.js', 'file');
* _drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline');
* _drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });',
* array('type' => 'inline', 'scope' => 'footer', 'weight' => 5)
* );
* _drupal_add_js('http://example.com/example.js', 'external');
* _drupal_add_js(array('myModule' => array('key' => 'value')), 'setting');
* @endcode
...
...
@@ -1318,7 +1294,6 @@ function drupal_clean_id_identifier($id) {
*
* If JavaScript aggregation is enabled, all JavaScript files added with
* $options['preprocess'] set to TRUE will be merged into one aggregate file.
* Preprocessed inline JavaScript will not be aggregated into this single file.
* Externally hosted JavaScripts are never aggregated.
*
* The reason for aggregating the files is outlined quite thoroughly here:
...
...
@@ -1338,7 +1313,6 @@ function drupal_clean_id_identifier($id) {
* (optional) If given, the value depends on the $options parameter, or
* $options['type'] if $options is passed as an associative array:
* - 'file': Path to the file relative to base_path().
* - 'inline': The JavaScript code that should be placed in the given scope.
* - 'external': The absolute path to an external JavaScript file that is not
* hosted on the local server. These files will not be aggregated if
* JavaScript aggregation is enabled.
...
...
@@ -1350,11 +1324,11 @@ function drupal_clean_id_identifier($id) {
* added to the existing settings array.
* @param $options
* (optional) A string defining the type of JavaScript that is being added in
* the $data parameter ('file'/'setting'/'
inline'/'
external'), or an
*
associative array.
JavaScript settings should always pass the string
*
'setting' only. Other
types can have the following elements in the array:
* the $data parameter ('file'/'setting'/'external'), or an
associative array.
* JavaScript settings should always pass the string
'setting' only. Other
* types can have the following elements in the array:
* - type: The type of JavaScript that is to be added to the page. Allowed
* values are 'file',
'inline',
'external' or 'setting'. Defaults
* values are 'file', 'external' or 'setting'. Defaults
* to 'file'.
* - scope: The location in which you want to place the script. Possible
* values are 'header' or 'footer'. If your theme implements different
...
...
@@ -1467,15 +1441,9 @@ function _drupal_add_js($data = NULL, $options = NULL) {
'data'
=>
array
(),
);
}
// All JavaScript settings are placed in the header of the page with
// the library weight so that inline scripts appear afterwards.
$javascript
[
'drupalSettings'
][
'data'
]
=
NestedArray
::
mergeDeepArray
([
$javascript
[
'drupalSettings'
][
'data'
],
$data
],
TRUE
);
break
;
case
'inline'
:
$javascript
[]
=
$options
;
break
;
default
:
// 'file' and 'external'
// Local and external files must keep their name as the associative key
// so the same JavaScript file is not added twice.
...
...
@@ -1515,8 +1483,8 @@ function drupal_js_defaults($data = NULL) {
*
* References to JavaScript files are placed in a certain order: first, all
* 'core' files, then all 'module' and finally all 'theme' JavaScript files
* are added to the page. Then, all settings are output
, followed by 'inline'
*
JavaScript code. If running update.php,
all preprocessing is disabled.
* are added to the page. Then, all settings are output
. If running update.php,
* all preprocessing is disabled.
*
* Note that hook_js_alter(&$javascript) is called during this function call
* to allow alterations of the JavaScript during its presentation. Calls to
...
...
@@ -1694,44 +1662,40 @@ function drupal_merge_attached(array $a, array $b) {
/**
* Adds attachments to a render() structure.
*
* Libraries, JavaScript
, CSS and other types of custom structures are attached
* to elements using the #attached property. The #attached property
is an
* associative array, where the keys are the
the
attachment types and the
values
* are the attached data. For example:
* Libraries, JavaScript
settings, feeds, HTML <head> tags and HTML <head> links
*
are attached
to elements using the #attached property. The #attached property
*
is an
associative array, where the keys are the attachment types and the
*
values
are the attached data. For example:
*
* @code
* $build['#attached'] = array(
* 'library' => array(array('taxonomy', 'taxonomy')),
* 'css' => array(drupal_get_path('module', 'taxonomy') . '/css/taxonomy.module.css'),
* );
* $build['#attached'] = [
* 'library' => ['core/jquery']
* ];
* @endcode
*
* 'js', 'css', and 'library' are types that get special handling. For any
* other kind of attached data, the array key must be the full name of the
* callback function and each value an array of arguments. For example:
* The available keys are:
* - 'library' (asset libraries)
* - 'drupalSettings' (JavaScript settings)
* - 'feed' (RSS feeds)
* - 'html_head' (tags in HTML <head>)
* - 'html_head_link' (<link> tags in HTML <head>)
* - 'http_header' (HTTP headers)
*
* For example:
* @code
* $build['#attached']['http_header'] = array(
* array('Content-Type', 'application/rss+xml; charset=utf-8'),
* );
* @endcode
*
* External 'js' and 'css' files can also be loaded. For example:
* @code
* $build['#attached']['js'] = array(
* 'http://code.jquery.com/jquery-1.4.2.min.js' => array(
* 'type' => 'external',
* ),
* );
* @endcode
*
* @param $elements
* @param array $elements
* The structured array describing the data being rendered.
* @param $dependency_check
* @param
bool
$dependency_check
* When TRUE, will exit if a given library's dependencies are missing. When
* set to FALSE, will continue to add the libraries, even though one or more
* dependencies are missing. Defaults to FALSE.
*
* @return
* @return
bool
* FALSE if there were any missing library dependencies; TRUE if all library
* dependencies were met.
*
...
...
@@ -1740,12 +1704,10 @@ function drupal_merge_attached(array $a, array $b) {
* @see _drupal_add_css()
* @see drupal_render()
*/
function
drupal_process_attached
(
$elements
,
$dependency_check
=
FALSE
)
{
function
drupal_process_attached
(
array
$elements
,
$dependency_check
=
FALSE
)
{
// Add defaults to the special attached structures that should be processed differently.
$elements
[
'#attached'
]
+=
array
(
'library'
=>
array
(),
'js'
=>
array
(),
'css'
=>
array
(),
);
// Add the libraries first.
...
...
@@ -1761,30 +1723,8 @@ function drupal_process_attached($elements, $dependency_check = FALSE) {
}
unset
(
$elements
[
'#attached'
][
'library'
]);
// Add both the JavaScript and the CSS.
// The parameters for _drupal_add_js() and _drupal_add_css() require special
// handling.
foreach
(
array
(
'js'
,
'css'
)
as
$type
)
{
foreach
(
$elements
[
'#attached'
][
$type
]
as
$data
=>
$options
)
{
// If the value is not an array, it's a filename and passed as first
// (and only) argument.
if
(
!
is_array
(
$options
))
{
$data
=
$options
;
$options
=
NULL
;
}
// In some cases, the first parameter ($data) is an array. Arrays can't be
// passed as keys in PHP, so we have to get $data from the value array.
if
(
is_numeric
(
$data
))
{
$data
=
$options
[
'data'
];
unset
(
$options
[
'data'
]);
}
call_user_func
(
'_drupal_add_'
.
$type
,
$data
,
$options
);
}
unset
(
$elements
[
'#attached'
][
$type
]);
}
// Convert every JavaScript settings asset into a regular JavaScript asset.
// @todo Clean this up in https://www.drupal.org/node/23
82533
// @todo Clean this up in https://www.drupal.org/node/23
68797
if
(
!
empty
(
$elements
[
'#attached'
][
'drupalSettings'
]))
{
_drupal_add_js
(
$elements
[
'#attached'
][
'drupalSettings'
],
[
'type'
=>
'setting'
]);
unset
(
$elements
[
'#attached'
][
'drupalSettings'
]);
...
...
@@ -1994,22 +1934,21 @@ function _drupal_add_library($library_name, $every_page = NULL) {
// Add all components within the library.
$elements
[
'#attached'
]
=
array
(
'library'
=>
$library
[
'dependencies'
],
'js'
=>
$library
[
'js'
],
'css'
=>
$library
[
'css'
],
);
if
(
isset
(
$library
[
'drupalSettings'
]))
{
$elements
[
'#attached'
][
'drupalSettings'
]
=
$library
[
'drupalSettings'
];
}
$added
[
$extension
][
$name
]
=
drupal_process_attached
(
$elements
,
TRUE
);
// Add both the JavaScript and the CSS.
// The parameters for _drupal_add_js() and _drupal_add_css() require special
// handling.
foreach
(
array
(
'js'
,
'css'
)
as
$type
)
{
foreach
(
$elements
[
'#attached'
][
$type
]
as
$data
=>
$options
)
{
// Set the every_page flag if one was passed.
if
(
isset
(
$every_page
))
{
$elements
[
'#attached'
][
$type
][
$data
][
'every_page'
]
=
$every_page
;
}
foreach
(
$library
[
$type
]
as
$options
)
{
call_user_func
(
'_drupal_add_'
.
$type
,
$options
[
'data'
],
$options
);
}
unset
(
$elements
[
'#attached'
][
$type
]);
}
$added
[
$extension
][
$name
]
=
drupal_process_attached
(
$elements
,
TRUE
);
}
else
{
// Requested library does not exist.
...
...
core/lib/Drupal/Core/Asset/CssCollectionRenderer.php
View file @
77c613e3
...
...
@@ -158,21 +158,6 @@ public function render(array $css_assets) {
}
break
;
// Output a STYLE tag for an inline CSS asset. The asset's 'data'
// property contains the CSS content.
case
'inline'
:
$element
=
$style_element_defaults
;
$element
[
'#value'
]
=
$css_asset
[
'data'
];
$element
[
'#attributes'
][
'media'
]
=
$css_asset
[
'media'
];
$element
[
'#browsers'
]
=
$css_asset
[
'browsers'
];
// For inline CSS to validate as XHTML, all CSS containing XHTML needs
// to be wrapped in CDATA. To make that backwards compatible with HTML
// 4, we need to comment out the CDATA-tag.
$element
[
'#value_prefix'
]
=
"
\n
/* <![CDATA[ */
\n
"
;
$element
[
'#value_suffix'
]
=
"
\n
/* ]]> */
\n
"
;
$elements
[]
=
$element
;
break
;
// Output a LINK tag for an external CSS asset. The asset's 'data'
// property contains the full URL.
case
'external'
:
...
...
core/lib/Drupal/Core/Asset/JsCollectionRenderer.php
View file @
77c613e3
...
...
@@ -72,14 +72,8 @@ public function render(array $js_assets) {
$element
[
'#value_suffix'
]
=
$embed_suffix
;
break
;
case
'inline'
:
$element
[
'#value_prefix'
]
=
$embed_prefix
;
$element
[
'#value'
]
=
$js_asset
[
'data'
];
$element
[
'#value_suffix'
]
=
$embed_suffix
;
break
;
case
'file'
:
$query_string
=
empty
(
$js_asset
[
'version'
]
)
?
$default_query_string
:
'v='
.
$js_asset
[
'version'
];
$query_string
=
$js_asset
[
'version'
]
==
-
1
?
$default_query_string
:
'v='
.
$js_asset
[
'version'
];
$query_string_separator
=
(
strpos
(
$js_asset
[
'data'
],
'?'
)
!==
FALSE
)
?
'&'
:
'?'
;
$element
[
'#attributes'
][
'src'
]
=
file_create_url
(
$js_asset
[
'data'
]);
// Only add the cache-busting query string if this isn't an aggregate
...
...
core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
View file @
77c613e3
...
...
@@ -197,12 +197,6 @@ public function buildByExtension($extension) {
$library
[
$type
][]
=
$options
;
}
}
// @todo Convert all uses of #attached[library][]=array('provider','name')
// into #attached[library][]='provider/name' and remove this.
foreach
(
$library
[
'dependencies'
]
as
$i
=>
$dependency
)
{
$library
[
'dependencies'
][
$i
]
=
$dependency
;
}
}
return
$libraries
;
...
...
core/modules/comment/comment.libraries.yml
View file @
77c613e3
...
...
@@ -30,7 +30,7 @@ drupal.comment-new-indicator:
-
core/jquery
-
core/jquery.once
-
core/drupal
-
history/
drupal.history
-
history/
api
-
core/drupal.displace
drupal.node-new-comments-link
:
...
...
@@ -41,4 +41,4 @@ drupal.node-new-comments-link:
-
core/jquery
-
core/jquery.once
-
core/drupal
-
history/
drupal.history
-
history/
api
core/modules/history/history.libraries.yml
View file @
77c613e3
drupal.history
:
api
:
version
:
VERSION
js
:
js/history.js
:
{}
...
...
@@ -7,3 +7,10 @@ drupal.history:
-
core/drupalSettings
-
core/drupal
-
core/drupal.ajax
mark-as-read
:
version
:
VERSION
js
:
js/mark-as-read.js
:
{
scope
:
footer
}
dependencies
:
-
history/api
core/modules/history/history.module
View file @
77c613e3
...
...
@@ -138,11 +138,8 @@ function history_node_view_alter(array &$build, EntityInterface $node, EntityVie
// When the window's "load" event is triggered, mark the node as read.
// This still allows for Drupal behaviors (which are triggered on the
// "DOMContentReady" event) to add "new" and "updated" indicators.
$build
[
'#attached'
][
'js'
][]
=
array
(
'data'
=>
'window.addEventListener("load",function(){Drupal.history.markAsRead('
.
$node
->
id
()
.
');},false);'
,
'type'
=>
'inline'
,
);
$build
[
'#attached'
][
'library'
][]
=
'history/drupal.history'
;
$build
[
'#attached'
][
'library'
][]
=
'history/mark-as-read'
;
$build
[
'#attached'
][
'drupalSettings'
][
'history'
][
'nodesToMarkAsRead'
][
$node
->
id
()]
=
TRUE
;
}
}
...
...
core/modules/history/js/mark-as-read.js
0 → 100644
View file @
77c613e3
/**
* Marks the nodes listed in drupalSettings.history.nodesToMarkAsRead as read.
*
* Uses the History module JavaScript API.
*/
(
function
(
window
,
Drupal
,
drupalSettings
)
{
"
use strict
"
;
// When the window's "load" event is triggered, mark all enumerated nodes as
// read. This still allows for Drupal behaviors (which are triggered on the
// "DOMContentReady" event) to add "new" and "updated" indicators.
window
.
addEventListener
(
'
load
'
,
function
()
{
if
(
drupalSettings
.
history
&&
drupalSettings
.
history
.
nodesToMarkAsRead
)
{
Object
.
keys
(
drupalSettings
.
history
.
nodesToMarkAsRead
).
forEach
(
Drupal
.
history
.
markAsRead
);
}
});
})(
window
,
Drupal
,
drupalSettings
);
core/modules/history/src/Tests/HistoryTest.php
View file @
77c613e3
...
...
@@ -119,8 +119,9 @@ function testHistory() {
$this
->
drupalGet
(
'node/'
.
$nid
);
// JavaScript present to record the node read.
$settings
=
$this
->
getDrupalSettings
();
$this
->
assertTrue
(
isset
(
$settings
[
'ajaxPageState'
][
'js'
][
'core/modules/history/js/history.js'
]),
'drupal.history library is present.'
);
$this
->
assertRaw
(
'Drupal.history.markAsRead('
.
$nid
.
')'
,
'History module JavaScript API call to mark node as read present on page.'
);
$this
->
assertTrue
(
isset
(
$settings
[
'ajaxPageState'
][
'js'
][
'core/modules/history/js/history.js'
]),
'history/api library is present.'
);
$this
->
assertTrue
(
isset
(
$settings
[
'ajaxPageState'
][
'js'
][
'core/modules/history/js/mark-as-read.js'
]),
'history/mark-as-read library is present.'
);
$this
->
assertEqual
([
$nid
=>
TRUE
],
$settings
[
'history'
][
'nodesToMarkAsRead'
],
'drupalSettings to mark node as read are present.'
);
// Simulate JavaScript: perform HTTP request to mark node as read.
$response
=
$this
->
markNodeAsRead
(
$nid
);
...
...
core/modules/quickedit/quickedit.module
View file @
77c613e3
...
...
@@ -99,7 +99,8 @@ function quickedit_library_alter(array &$library, $name, $theme = NULL) {
}
if
(
isset
(
$info
[
'quickedit_stylesheets'
])
&&
is_array
(
$info
[
'quickedit_stylesheets'
]))
{
foreach
(
$info
[
'quickedit_stylesheets'
]
as
$path
)
{
$library
[
'css'
][
$theme_path
.
'/'
.
$path
]
=
array
(
$library
[
'css'
][]
=
array
(
'data'
=>
$theme_path
.
'/'
.
$path
,
'group'
=>
CSS_AGGREGATE_THEME
,
'weight'
=>
CSS_THEME
,
);
...
...
core/modules/system/src/Tests/Ajax/FrameworkTest.php
View file @
77c613e3
...
...
@@ -35,44 +35,18 @@ public function testAJAXRender() {
* Tests AjaxResponse::prepare() AJAX commands ordering.
*/
public
function
testOrder
()
{
$path
=
drupal_get_path
(
'module'
,
'system'
);
$expected_commands
=
array
();
// Expected commands, in a very specific order.
$expected_commands
[
0
]
=
new
SettingsCommand
(
array
(
'ajax'
=>
'test'
),
TRUE
);
drupal_static_reset
(
'_drupal_add_css'
);
$attached
=
array
(
'#attached'
=>
array
(
'css'
=>
array
(
$path
.
'/css/system.admin.css'
=>
array
(),
$path
.
'/css/system.maintenance.css'
=>
array
()
),
),
);
drupal_render
(
$attached
);
drupal_process_attached
(
$attached
);
$build
[
'#attached'
][
'library'
][]
=
'ajax_test/order-css-command'
;
drupal_process_attached
(
$build
);
$expected_commands
[
1
]
=
new
AddCssCommand
(
drupal_get_css
(
_drupal_add_css
(),
TRUE
));
drupal_static_reset
(
'_drupal_add_js'
);
$attached
=
array
(
'#attached'
=>
array
(
'js'
=>
array
(
$path
.
'/system.js'
=>
array
(),
),
),
);
drupal_render
(
$attached
);
drupal_process_attached
(
$attached
);
$build
[
'#attached'
][
'library'
][]
=
'ajax_test/order-js-command'
;
drupal_process_attached
(
$build
);
$expected_commands
[
2
]
=
new
PrependCommand
(
'head'
,
drupal_get_js
(
'header'
,
_drupal_add_js
(),
TRUE
));
drupal_static_reset
(
'_drupal_add_js'
);
$attached
=
array
(
'#attached'
=>
array
(
'js'
=>
array
(
$path
.
'/system.modules.js'
=>
array
(
'scope'
=>
'footer'
),
),
),
);
drupal_render
(
$attached
);
drupal_process_attached
(
$attached
);
$expected_commands
[
3
]
=
new
AppendCommand
(
'body'
,
drupal_get_js
(
'footer'
,
_drupal_add_js
(),
TRUE
));
$expected_commands
[
4
]
=
new
HtmlCommand
(
'body'
,
'Hello, world!'
);
...
...
core/modules/system/src/Tests/Common/AttachedAssetsTest.php
0 → 100644
View file @
77c613e3
<?php
/**
* @file
* Contains \Drupal\system\Tests\Common\JavaScriptTest.
*/
namespace
Drupal\system\Tests\Common
;
use
Drupal\Component\Serialization\Json
;
use
Drupal\Component\Utility\Unicode
;
use
Drupal\Component\Utility\Crypt
;
use
Drupal\simpletest\KernelTestBase
;
/**
* Tests #attached assets: attached asset libraries and JavaScript settings.
*
* i.e. tests:
*
* @code
* $build['#attached']['library'] = …
* $build['#attached']['drupalSettings'] = …
* @endcode
*
* @group Common
* @group Asset
*/
class
AttachedAssetsTest
extends
KernelTestBase
{
/**
* {@inheritdoc}
*/
public
static
$modules
=
array
(
'language'
,
'simpletest'
,
'common_test'
,
'system'
);
/**
* {@inheritdoc}
*/
protected
function
setUp
()
{
parent
::
setUp
();
// Disable preprocessing.
\
Drupal
::
config
(
'system.performance'
)
->
set
(
'css.preprocess'
,
FALSE
)
->
set
(
'js.preprocess'
,
FALSE
)
->
save
();
// Reset _drupal_add_css() and _drupal_add_js() statics before each test.
drupal_static_reset
(
'_drupal_add_css'
);
drupal_static_reset
(
'_drupal_add_js'
);
$this
->
installSchema
(
'system'
,
'router'
);
\
Drupal
::
service
(
'router.builder'
)
->
rebuild
();
}
/**
* Tests that default CSS and JavaScript is empty.
*/
function
testDefault
()
{
$build
[
'#attached'
]
=
[];
drupal_process_attached
(
$build
);
$this
->
assertEqual
(
array
(),
_drupal_add_css
(),
'Default CSS is empty.'
);
$this
->
assertEqual
(
array
(),
_drupal_add_js
(),
'Default JavaScript is empty.'
);
}
/**
* Tests non-existing libraries.
*/
function
testLibraryUnknown
()
{
$build
[
'#attached'
][
'library'
][]
=
'unknown/unknown'
;
drupal_process_attached
(
$build
);
$scripts
=
drupal_get_js
();
$this
->
assertTrue
(
strpos
(
$scripts
,
'unknown'
)
===
FALSE
,
'Unknown library was not added to the page.'
);
}
/**
* Tests adding a CSS and a JavaScript file.
*/
function
testAddFiles
()
{
$build
[
'#attached'
][
'library'
][]
=
'common_test/files'
;
drupal_process_attached
(
$build
);
$css
=
_drupal_add_css
();
$js
=
_drupal_add_js
();
$this
->
assertTrue
(
array_key_exists
(
'bar.css'
,
$css
),
'CSS files are correctly added.'
);
$this
->
assertTrue
(
array_key_exists
(
'core/modules/system/tests/modules/common_test/foo.js'
,
$js
),
'JavaScript files are correctly added.'
);
$rendered_css
=
drupal_get_css
();
$rendered_js
=
drupal_get_js
();
$query_string
=
$this
->
container
->
get
(
'state'
)
->
get
(
'system.css_js_query_string'
)
?:
'0'
;
$this
->
assertNotIdentical
(
strpos
(
$rendered_css
,
'<link rel="stylesheet" href="'
.
file_create_url
(
'core/modules/system/tests/modules/common_test/bar.css'
)
.
'?'
.
$query_string
.
'" media="all" />'
),
FALSE
,
'Rendering an external CSS file.'
);
$this
->
assertNotIdentical
(
strpos
(
$rendered_js
,
'<script src="'
.
file_create_url
(
'core/modules/system/tests/modules/common_test/foo.js'
)
.
'?'
.
$query_string
.
'"></script>'
),
FALSE
,
'Rendering an external JavaScript file.'
);
}
/**
* Tests adding JavaScript settings.
*/
function
testAddJsSettings
()
{
// Add a file in order to test default settings.
$build
[
'#attached'
][
'library'
][]
=
'core/drupalSettings'
;
drupal_process_attached
(
$build
);
$javascript
=
_drupal_add_js
();
$this
->
assertTrue
(
array_key_exists
(
'currentPath'
,
$javascript
[
'drupalSettings'
][
'data'
][
'path'
]),
'The current path JavaScript setting is set correctly.'
);
$javascript
=
_drupal_add_js
(
array
(
'drupal'
=>
'rocks'
,
'dries'
=>
280342800
),
'setting'
);
$this
->
assertEqual
(
280342800
,
$javascript
[
'drupalSettings'
][
'data'
][
'dries'
],
'JavaScript setting is set correctly.'
);
$this
->
assertEqual
(
'rocks'
,
$javascript
[
'drupalSettings'
][
'data'
][
'drupal'
],
'The other JavaScript setting is set correctly.'
);
}
/**
* Tests adding external CSS and JavaScript files.
*/
function
testAddExternalFiles
()
{
$build
[
'#attached'
][
'library'
][]
=
'common_test/external'
;
drupal_process_attached
(
$build
);
$css
=
_drupal_add_css
();
$js
=
_drupal_add_js
();
$this
->
assertTrue
(
array_key_exists
(
'http://example.com/stylesheet.css'
,
$css
),
'External CSS files are correctly added.'
);
$this
->
assertTrue
(
array_key_exists
(
'http://example.com/script.js'
,
$js
),
'External JavaScript files are correctly added.'
);
$rendered_css
=
drupal_get_css
();
$rendered_js
=
drupal_get_js
();
$this
->
assertNotIdentical
(
strpos
(
$rendered_css
,
'<link rel="stylesheet" href="http://example.com/stylesheet.css" media="all" />'
),
FALSE
,
'Rendering an external CSS file.'
);
$this
->
assertNotIdentical
(
strpos
(
$rendered_js
,
'<script src="http://example.com/script.js"></script>'
),
FALSE
,
'Rendering an external JavaScript file.'
);
}
/**
* Tests adding JavaScript files with additional attributes.
*/
function
testAttributes
()
{
$build
[
'#attached'
][
'library'
][]
=
'common_test/js-attributes'
;
drupal_process_attached
(
$build
);
$rendered_js
=
drupal_get_js
();