css_defer_external option does not work if CSS URL contains characters not allowed by the regex

Created on 26 July 2023, 11 months ago
Updated 15 February 2024, 4 months ago

Problem/Motivation

DeferCss::defer() detects external <link> tags with this regex:

/<link rel=["\']stylesheet["\'](.*)(href="[a-zA-Z0-9\/_\.\-\?\:]*")(.*)\/\>/

This is very restrictive and will not match URL that contain characters that are not allowed.

Steps to reproduce

For example, it will not match this tag:

<link rel="stylesheet" media="all" href="https://fonts.bunny.net/css?family=eb-garamond:400,500,500i,700,700i|roboto-condensed:400,700&amp;display=swap" />

Proposed resolution

The module should probably parse the HTML (with Html::load()) instead of using a regex.

πŸ› Bug report
Status

Needs work

Version

5.0

Component

Code

Created by

πŸ‡«πŸ‡·France prudloff Lille

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

Comments & Activities

  • Issue created by @prudloff
  • First commit to issue fork.
  • πŸ‡¦πŸ‡·Argentina tguerineau

    I've been working on the feedback provided and have made some updates to the module in a new branch. Here's a brief summary:

    1. DOM Parsing over Regex: I've switched the logic from using regex patterns to a DOM-based approach. This helps in addressing the limitations of regex in parsing HTML and provides a more robust and flexible way of handling different <link> tags in the document.

    2. Maintaining <link> attributes: The new changes ensure that attributes such as media are retained when the <link> tags are modified.

    3. Selective Handling of External Links: The new logic respects the css_defer_external setting, ensuring that only the desired links (either internal, external, or both) are deferred based on the configuration.

    I've pushed these updates to a new branch on the issue fork.

    Testing: I've conducted preliminary tests, and the changes seem to work as expected. However, I'd appreciate it if others could also test and share their feedback.

    I kindly request everyone to review the changes. I believe these changes address the concerns raised in this issue, but I'm open to further improvements.

  • Status changed to Needs review 10 months ago
  • @tguerineau opened merge request.
  • πŸ‡¦πŸ‡·Argentina tguerineau

    Hi @prudloff,

    I've been working on implementing a solution for deferring scripts effectively using the suggested Html::load() and Html::serialize() methods. The initial approach we discussed seemed promising, but during implementation and testing, we've encountered some significant challenges that I'd like to outline:

    1. Document Structure Changes: Utilizing Html::load() for the entire document inadvertently modifies the structure. Specifically, elements that are originally in the <head> tag are being moved into the <body> tag. This is problematic as it alters the expected layout and behavior of the page, leading to visual discrepancies and potential functional issues.
    2. DOM Manipulation Side Effects: In an attempt to circumvent the above issue, I tried various methods to isolate the manipulation to the <head> content. This included wrapping content in temporary containers and placeholders to maintain structure. Unfortunately, these methods introduced additional complexity without resolving the core issue - that Html::load() and Html::serialize() are not preserving the placement of head elements when serializing the document back to HTML.
    3. First Approach Functionality: It is worth mentioning that the initial non-DOMDocument approach we developed does not encounter these structure-related issues and works as expected. It effectively transforms the <link> elements for CSS without disrupting the document structure.

    Given the problems faced with the current Html::load() and Html::serialize() strategy, I propose revisiting the initial approach for further consideration. It offers a stable solution with the desired functionality without compromising the document's integrity.

    I am open to feedback and any suggestions on alternative methods.

  • Status changed to Needs work 4 months ago
  • πŸ‡ΊπŸ‡ΈUnited States SocialNicheGuru
Production build 0.69.0 2024