Expected: drupal_add_js('something.js', array('scope' => 'footer')) (or the library definition equivalent) is listed in drupalSettings.ajaxPageState.js.
Result: only the JS files that are in the 'header' scope are listed in drupalSettings.ajaxPageState.js.

Proposed resolution

diff --git a/core/includes/ b/core/includes/
index 10b09d6..70c0b81 100644
--- a/core/includes/
+++ b/core/includes/
@@ -3831,7 +3831,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
       // Provide the page with information about the individual JavaScript files
       // used, information not otherwise available when aggregation is enabled.
-      $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
+      $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($javascript), 1);
       // Provide the page with information about the individual CSS files used,

This is analogous to how the CSS page state is stored. $items only contains the items for the current scope; and since settings on most pages are added when $scope == 'header', that explains why only JS files that are in the 'header' scope get added to the page state.

Remaining tasks

Get proper test coverage. In my initial testing it turned out to be impossible to reproduce the same problem in the tests, likely because WebTestBase does not actually execute JavaScript, it merely simulates the crucial aspects.

User interface changes


API changes


#1 1864944-1.patch732 bytesWim Leers
PASSED: [[SimpleTest]]: [MySQL] 49,300 pass(es).
[ View ]


Status:Active» Needs review
Issue tags:+JavaScript
new732 bytes
PASSED: [[SimpleTest]]: [MySQL] 49,300 pass(es).
[ View ]

Now that #1824500: In-place editing for Fields has landed, this is super easy to reproduce.

  1. Install D8 using the Standard install profile (which has Edit enabled).
  2. Go to the front page.
  3. Open your browser's console and type drupalSettings.ajaxPageState.js.
  4. Check whether edit.js is listed there (which has 'scope' => 'footer') . It's not. This is the bug.

Status:Needs review» Reviewed & tested by the community

Works well as a stop-gap measure. It's the whole API that needs to be worked on to avoid this kind of uglyness, see #1871596: Create a PartialResponse class to encapsulate html-level data [Moving to sandbox].

In the meanwhile, this works.

Status:Reviewed & tested by the community» Fixed

Hm. Unfortunately, doesn't sound like it's possible to work #2 into a test since it's JS-only. :(

Committed and pushed to 8.x. Thanks!

It is in fact possible to add tests for this, similarly to how I'm doing tests over at #1875632: JS settings merging behavior: preserve integer keys (allow for array literals in drupalSettings): using json_decode().

However, all of this will change in the issue that nod_ pointed to in #3 so it's not clear if it's worth the effort. I personally believe it's worth it, even if only because that'll ensure tests in #1871596: Create a PartialResponse class to encapsulate html-level data [Moving to sandbox] will test this edge case too. Thoughts?

Title:ajaxPageState does not contain JS files that are in scopes other than 'header'Tests for ajaxPageState does not contain JS files that are in scopes other than 'header'
Category:bug» task
Status:Fixed» Active
Issue tags:+Needs tests

Yeah, let's do it. That issue can always remove the test if it turns out to not be relevant.

Switching some metadata around.

I'll likely get this done tomorrow.