Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assets (Sprockets 4.1.1 and Sprockets-rails 3.4.2) not work correctly with images within engine with third party libraries #507

Open
Sega100500 opened this issue Jul 1, 2022 · 11 comments

Comments

@Sega100500
Copy link

Sega100500 commented Jul 1, 2022

System configuration

  • Sprockets version is 4.1.1
  • Sprockets-rails is 3.4.2
  • Ruby version 3.1.2
  • Ruby on Rails 7.0.3
  • jQuery-UI 1.13.1 (third-party js-library stored local)
  • gem ckeditor 5.1.1 (with third-party js-library ckeditor stored local)

Problem

I use my own engine "Admin", in which I connect the jQuery-UI library.
With sprockets 3.7.2 and sprockets-rails 3.2.2 all work fine! ... but later versions not working correctly
(config.assets.compile = true)

Directory of engine is 'admin'.
Config manifest file for admin: admin/app/assets/config/admin.js:

//= link_tree ../images/admin
//= link_directory ../javascripts/admin .js
//= link_directory ../stylesheets/admin .css

//= link_tree ../javascripts/admin/lib .js

//= link_tree ../stylesheets/admin/lib .css
//= link_tree ../stylesheets/admin/lib .png
//= link_tree ../stylesheets/admin/lib .jpg
//= link_tree ../stylesheets/admin/lib .jpeg
//= link_tree ../stylesheets/admin/lib .gif

(replace with require_tree also not work)

connect library jQuery-UI with stylesheet_link_tag and javascript_include_tag

jQuery-UI files placed in:
admin/app/assets/javascripts/admin/lib/jquery-ui
admin/app/assets/stylesheets/admin/lib/jquery-ui

in initializer I also add:

Rails.application.config.assets.precompile += %w( admin/*.js admin/*.css admin/**/*.js admin/**/*.css )
Rails.application.config.assets.precompile += %w( admin/*.png admin/**/*.png admin/*.gif admin/**/*.gif )
Rails.application.config.assets.precompile += %w( admin/*.jpg admin/**/*.jpg admin/*.jpeg admin/**/*.jpeg )

Rails.application.config.assets.precompile += Ckeditor.assets
Rails.application.config.assets.precompile += %w( ckeditor/*.js ckeditor/**/*.js ckeditor/*.css ckeditor/**/*.css ckeditor/*.md ckeditor/*.txt ckeditor/*.html )
Rails.application.config.assets.precompile += %w( ckeditor/*.png ckeditor/**/*.png ckeditor/*.gif ckeditor/**/*.gif )

Rails.application.config.assets.paths << Admin::Engine.root.join('app','assets','images')
Rails.application.config.assets.paths << Admin::Engine.root.join('app','assets','images','admin')

Rails.application.config.assets.paths << Admin::Engine.root.join('app','assets','javascripts','admin')
Rails.application.config.assets.paths << Admin::Engine.root.join('app','assets','stylesheets','admin')

jQuery-UI library is loaded, but background images of elements are not displayed

Inspection of example jQuery-UI element show this style:

.ui-widget-header {
  border: 1px solid #4297d7;
  background: #5c9ccc url(/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x;
  color: #fff;
  font-weight: bold;
}

Also I use gem ckeditor, in this case not showing icons images and images placed in page.
Images loaded in ckeditor with mini_magic and ActiveStorage and link to image is like this:

'/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--a6378272645dcac2d56fb1a971b3e8fc3a682b86/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJYW5CbkJqb0dSVlE2QzNKbGMybDZaVWtpQ1Rnd01ENEdPd1pVIiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--2ccbd7d12a252e03eb26bb2401505e4efaeff669/7d85fe9c160bb2f3b559a45303cc8ce4.jpg'

With sprockets 3.7.2 and sprockets-rails 3.2.2 all work fine! ... but later versions not working correctly

What could be wrong? I tried many options for specifying paths, direct specifying files, but it does not work as it should.
Please, help!...

gems for non-digest assets are not helped to me:
non-digest-assets gem.
sprockets-redirect gem.
smart_assets gem.

@Sega100500 Sega100500 changed the title Assets (Sprockets 4.1.1 and Sprockets-rails 3.4.2) not work correctly with images in engine with third party libraries Assets (Sprockets 4.1.1 and Sprockets-rails 3.4.2) not work correctly with images within engine with third party libraries Jul 1, 2022
@Sega100500
Copy link
Author

Sega100500 commented Jul 2, 2022

@Sega100500
Copy link
Author

Sega100500 commented Jul 2, 2022

I found in sprockets-rails 3.2.2 → 3.3.0 changes that make it. It is from version sprockets 3.3.0 that such incorrect processing is observed.

in file data/lib/sprockets/rails/asset_url_processor.rb ADDED

module Sprockets
  module Rails
    # Rewrites urls in CSS files with the digested paths
    class AssetUrlProcessor
      REGEX = /url\(\s*["']?(?!(?:\#|data|http))([^"'\s)]+)\s*["']?\)/
      
      def self.call(input)
        context = input[:environment].context_class.new(input)
        data    = input[:data].gsub(REGEX) { |_match| "url(#{context.asset_path($1)})" }

        { data: data }
      end
    end
  end
end

This section of code does the conversion:

from background: #5c9ccc url("images/ui-bg_gloss-wave_55_5c9ccc_500x100.png") 50% 50% repeat-x;
to: background: #5c9ccc url(/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x;

But why do this for stylesheets of third-party?...

Problem not in REGEX, but in substitution path in context.asset_path($1)

code sprockets-rails 3.4.2 :

module Sprockets
  module Rails
    # Resolve assets referenced in CSS `url()` calls and replace them with the digested paths
    class AssetUrlProcessor
      REGEX = /url\(\s*["']?(?!(?:\#|data|http))(?<relativeToCurrentDir>\.\/)?(?<path>[^"'\s)]+)\s*["']?\)/
      def self.call(input)
        context = input[:environment].context_class.new(input)
        data    = input[:data].gsub(REGEX) do |_match|
          path = Regexp.last_match[:path]
          "url(#{context.asset_path(path)})"
        end

        context.metadata.merge(data: data)
      end
    end
  end
end

again in this code path - is valid, but context.asset_path(path) - path with leading slash /images/ui-bg_gloss-wave_55_5c9ccc_500x100.png - wrong

@Sega100500
Copy link
Author

Sega100500 commented Jul 2, 2022

In sprockets-rails 3.4.2, they probably noticed that there can be a relative path, but for some reason they decided that it must begin with ./:

REGEX = /url\(\s*["']?(?!(?:\#|data|http))(?<relativeToCurrentDir>\.\/)?(?<path>[^"'\s)]+)\s*["']?\)/

BUT! relative path may be without any leading slashes and dots, like this one background: #5c9ccc url("images/ui-bg_gloss-wave_55_5c9ccc_500x100.png") 50% 50% repeat-x; - this start with subdirectory name.

Even if we assume that a path without initial slashes is found, then it would be most correct to add ./ to the beginning of the path, but not /.

@Sega100500
Copy link
Author

Sega100500 commented Jul 2, 2022

The patch that fixed the bug

For experiment I a little patch file lib/sprockets/rails/asset_url_processor.rb

module Sprockets
  module Rails
    # Resolve assets referenced in CSS `url()` calls and replace them with the digested paths
    class AssetUrlProcessor
      REGEX = /url\(\s*["']?(?!(?:\#|data|http))(?<relativeToCurrentDir>\.\/)?(?<path>[^"'\s)]+)\s*["']?\)/
      def self.call(input)
        context = input[:environment].context_class.new(input)
        data    = input[:data].gsub(REGEX) do |_match|
          path = Regexp.last_match[:path]
          # original: "url(#{context.asset_path(path)})"
         
          # my patch
          orig_path = path
          path = context.asset_path(path)
          path = (path == "/#{orig_path}") ? ".#{path}" : path
          "url(#{path})"

        end

        context.metadata.merge(data: data)
      end
    end
  end
end

... and all works correctly in development and production environments! This patch works correctly with relative paths in both assets and third-paty css-styles.

Of course, these are not full-fledged corrections and the method context.asset_path(path) must be corrected. But I clearly and specifically showed exactly what the problem is.

Please fix this bug in the library.

@rafaelfranca
Copy link
Member

Please fix this bug in the library.

Please feel free to submit a pull request. Thank you!

@Sega100500
Copy link
Author

@rafaelfranca

Read Contributing to Sprockets Rails and I try:

git clone https://github.com/contributor/sprockets-rails.git

Answer:

Cloning into 'sprockets-rails'...
Username for 'https://github.com': Sega100500
Password for 'https://[email protected]':
remote: Repository not found.
fatal: repository 'https://github.com/contributor/sprockets-rails.git/' not found

@yahonda
Copy link
Member

yahonda commented Jul 5, 2022

Here contributor is GitHub username that have sprockets-rails repository.

git clone https://github.com/contributor/sprockets-rails.git

Once you have cloned https://github.com/rails/sprockets-rails/ to your account the correct address should be

git clone https://github.com/Sega100500/sprockets-rails.git

I have opened a pull request #508 to update it.

@Sega100500
Copy link
Author

Sega100500 commented Jul 6, 2022

@yahonda , @rafaelfranca

Both git clone https://github.com/contributor/sprockets-rails.git and git clone https://github.com/Sega100500/sprockets-rails.git output these:

ruby@inet:~/devel$ git clone https://github.com/contributor/sprockets-rails.git
Cloning into 'sprockets-rails'...
Username for 'https://github.com': Sega100500
Password for 'https://[email protected]':
remote: Repository not found.
fatal: repository 'https://github.com/contributor/sprockets-rails.git/' not found

ruby@inet:~/devel$ git clone https://github.com/Sega100500/sprockets-rails.git
Cloning into 'sprockets-rails'...
Username for 'https://github.com': Sega100500
Password for 'https://[email protected]':
remote: Repository not found.
fatal: repository 'https://github.com/Sega100500/sprockets-rails.git/' not found

@rafaelfranca
Copy link
Member

Did you fork the project before cloning?

@Sega100500
Copy link
Author

Sega100500 commented Jul 7, 2022

@rafaelfranca

No, I don't know much about Git workflows. Especially when it comes to making changes to other people's projects. I just followed the instructions Contributing to Sprockets Rails and I thought that at the same time I would learn how to do it, but I stumbled on the first step. Although I have 2FA and token in my profile Github.

Fork the Project

Fork the project on Github and check out your copy.

git clone https://github.com/contributor/sprockets-rails.git
cd sprockets-rails
git remote add upstream https://github.com/rails/sprockets-rails.git

But this happen (above):

...
remote: Repository not found.
fatal: repository 'https://github.com/Sega100500/sprockets-rails.git/' not found

I didn't get any files from the repository.

@Sega100500
Copy link
Author

Sega100500 commented Jul 15, 2022

@rafaelfranca

Pull request

But in one test is fail... Somesing wrong with rmdir in one test...

P.S. It's strange that I was only able to do this using Git Desktop, but not command line...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants