External fonts cannot be loaded via add_css ajax command

Created on 9 November 2023, about 1 year ago
Updated 26 January 2024, 11 months ago

Problem/Motivation

In #3110517 we implemented ability to use loadjs library for the add_css ajax command. This library checks if the file name starts with css! or ends with .css /(^css!|\.css$)/. If for instance, we want to load Google fonts inside Ckeditor like here in this test module from the core, it will simply fail. Because loadjs will create script element instead of link Which will lead to such error:
Refused to execute script from 'https://fonts.googleapis.com/css?family=Open+Sans' because its MIME type ('text/css') is not executable, and strict MIME type checking is enabled.

Steps to reproduce

1. Add external fonts to the ckeditor5 in your theme.info.yml file like this:

ckeditor5-stylesheets:
  - https://fonts.googleapis.com/css?family=Open+Sans

See example from core

2. Create a node that has comments in it, and enable ckeditor5 for the comments.

And magically comments form will not be loaded at all, because if only one command from the big_pipe plaholder fails to execute all others are skipped.

The second way would be to simply attach a library that contains an external font inside the big_pipe placeholder.

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Render\Markup;
use Drupal\Core\Security\TrustedCallbackInterface;

class CustomBlock extends BlockBase implements TrustedCallbackInterface {
  public function build(): array {
    return [
      '#lazy_builder' => ['\Drupal\custom_module\Plugin\Block\CustomBlock::render', []],
      '#create_placeholder' => TRUE,
    ];
  }

  public static function render() {
    return [
      // This text will not be rendered because library will fail to load.
      '#markup' => Markup::create('<p>is Lazy</p>'),
      '#attached' => [
        'library' => [
          'custom_module/contains_external_font',

        ],
      ],
    ];
  }
  public static function trustedCallbacks() {
    return ['render'];
  }

}


Proposed resolution

Loadjs library provides a way to force treat file as CSS stylesheet:

loadjs(['css!/path/to/cssfile.custom'], function() {
  /* cssfile.custom loaded as stylesheet */
});

So all we need to do is to ensure that css! is appended to the filename.

Remaining tasks

Implemented ability to force treat file as CSS stylesheet in add_css command.

User interface changes

-

API changes

-

Data model changes

-

Release notes snippet

-

🐛 Bug report
Status

Fixed

Version

11.0 🔥

Component
Ajax 

Last updated 2 days ago

Created by

🇺🇦Ukraine dinazaur

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @dinazaur
  • @dinazaur opened merge request.
  • 🇺🇦Ukraine dinazaur

    Okay, so I committed only to test without the fix. As you can see test failed.

  • Status changed to Needs review about 1 year ago
  • 🇺🇦Ukraine dinazaur

    Okay, with the fix tests are green. I tried to run 🩹 Test-only changes but could not, it didn't even run. I'm not sure how to use it properly, maybe it's broken for now. Anyway, the issue is ready for review.

  • 🇺🇦Ukraine dinazaur

    Ah, and since this bug can lead to missing content on the site, I'm changing the status of this one to critical. In our case comment form was not rendered at all, only the big_pipe placeholder was in place. This is because we added Google fonts into ckeditor5-stylesheet like here in core

  • First commit to issue fork.
  • 🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

    This happens to me also, the patch resolves the problem.

    I rebase the MR and run Test-only changes but it's failing because changes in core/modules/system/tests/modules/ajax_test are discarded by the job.

  • First commit to issue fork.
  • Status changed to RTBC about 1 year ago
  • Status changed to Needs work about 1 year ago
  • 🇫🇷France nod_ Lille

    umm can we have the test use an ajax command instead of bigpipe? seems wrong to have a dependency on that module for all the command tests.

    I'd expect to have some more code around this, not a whole new method

        // Tests the 'add_css' command.
        $page->pressButton("AJAX 'add_css' command");
        $this->assertWaitPageContains('my/file.css');
    
  • Issue was unassigned.
  • 🇺🇦Ukraine dinazaur

    Ah, I was hoping that no one would notice :). I have no time to implement a proper test now that's why I made a PoC with big_pipe. If someone can, please make a proper test.

  • Status changed to Needs review about 1 year ago
  • 🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

    I created a separate MR without big_pipe for test.

  • Status changed to RTBC about 1 year ago
  • 🇺🇦Ukraine dinazaur

    Looks good to me.

  • Status changed to Needs work about 1 year ago
  • 🇫🇷France nod_ Lille

    Can you replace the domain but keep the rest of the URL intact please? also in the test no need to test for the whole link tag.

    So just like it was before, and replacing the google domain with example.com

  • Status changed to Needs review about 1 year ago
  • 🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

    Added back query param

    I find it odd not to test the whole link tag without the closing tag

        $this->assertWaitPageContains('<link rel="stylesheet" href="https://example.com/css?family=Open+Sans"');
    

    I removed the media attribute instead so the test is like this

        $this->assertWaitPageContains('<link rel="stylesheet" href="https://example.com/css?family=Open+Sans">');
    
  • Status changed to RTBC about 1 year ago
  • We had the same issue in a project.
    Can confirm that MR changes resolve it. And tests correctly identify an issue.

    Since @nod_ already took a look and all threads on MR seem to be resolved, moving to RTBC.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    alexpott changed the visibility of the branch 3400359-external-fonts-cannot to hidden.

  • Status changed to Needs work 12 months ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I think we need to adjust the test slightly. ONce that's done an passing this can be set to rtbc again.

  • Status changed to Needs review 11 months ago
  • 🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7
  • Status changed to RTBC 11 months ago
  • 🇺🇸United States smustgrave

    Restoring status, as this was marked critical.

    • nod_ committed 62498926 on 11.x
      Issue #3400359 by el7cosmos, dinazaur, alexpott, ReINFaTe: External...
    • nod_ committed 0bc86cf5 on 10.2.x
      Issue #3400359 by el7cosmos, dinazaur, alexpott, ReINFaTe: External...
  • Status changed to Fixed 11 months ago
  • 🇫🇷France nod_ Lille

    Committed 6249892 and pushed to 11.x. Thanks!

    backported to 10.2.x

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024