proscenium 0.9.1-aarch64-linux → 0.11.0.pre.1-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +423 -63
- data/lib/proscenium/builder.rb +126 -0
- data/lib/proscenium/css_module/path.rb +31 -0
- data/lib/proscenium/css_module/transformer.rb +76 -0
- data/lib/proscenium/css_module.rb +6 -28
- data/lib/proscenium/ensure_loaded.rb +27 -0
- data/lib/proscenium/ext/proscenium +0 -0
- data/lib/proscenium/ext/proscenium.h +19 -12
- data/lib/proscenium/helper.rb +62 -0
- data/lib/proscenium/importer.rb +110 -0
- data/lib/proscenium/libs/react-manager/index.jsx +88 -0
- data/lib/proscenium/libs/react-manager/react.js +2 -0
- data/lib/proscenium/libs/stimulus-loading.js +83 -0
- data/lib/proscenium/log_subscriber.rb +1 -2
- data/lib/proscenium/middleware/base.rb +1 -1
- data/lib/proscenium/middleware/esbuild.rb +3 -5
- data/lib/proscenium/middleware.rb +7 -1
- data/lib/proscenium/{side_load/monkey.rb → monkey.rb} +16 -12
- data/lib/proscenium/phlex/{resolve_css_modules.rb → css_modules.rb} +6 -20
- data/lib/proscenium/phlex/page.rb +2 -2
- data/lib/proscenium/phlex/react_component.rb +27 -64
- data/lib/proscenium/phlex.rb +10 -29
- data/lib/proscenium/railtie.rb +20 -22
- data/lib/proscenium/react_componentable.rb +94 -0
- data/lib/proscenium/resolver.rb +37 -0
- data/lib/proscenium/side_load.rb +13 -72
- data/lib/proscenium/source_path.rb +15 -0
- data/lib/proscenium/utils.rb +13 -0
- data/lib/proscenium/version.rb +1 -1
- data/lib/proscenium/view_component/css_modules.rb +11 -0
- data/lib/proscenium/view_component/react_component.rb +15 -28
- data/lib/proscenium/view_component/sideload.rb +4 -0
- data/lib/proscenium/view_component.rb +8 -31
- data/lib/proscenium.rb +24 -68
- metadata +21 -58
- data/lib/proscenium/css_module/class_names_resolver.rb +0 -66
- data/lib/proscenium/css_module/resolver.rb +0 -76
- data/lib/proscenium/current.rb +0 -9
- data/lib/proscenium/esbuild/golib.rb +0 -97
- data/lib/proscenium/esbuild.rb +0 -32
- data/lib/proscenium/phlex/component_concerns.rb +0 -27
- data/lib/proscenium/side_load/ensure_loaded.rb +0 -25
- data/lib/proscenium/side_load/helper.rb +0 -25
- data/lib/proscenium/view_component/tag_builder.rb +0 -23
data/lib/proscenium/side_load.rb
CHANGED
@@ -2,83 +2,24 @@
|
|
2
2
|
|
3
3
|
module Proscenium
|
4
4
|
class SideLoad
|
5
|
-
extend ActiveSupport::Autoload
|
6
|
-
|
7
|
-
NotIncludedError = Class.new(StandardError)
|
8
|
-
|
9
|
-
autoload :Monkey
|
10
|
-
autoload :Helper
|
11
|
-
autoload :EnsureLoaded
|
12
|
-
|
13
|
-
EXTENSIONS = %i[js css].freeze
|
14
|
-
EXTENSION_MAP = {
|
15
|
-
'.css' => :css,
|
16
|
-
# '.tsx' => :js,
|
17
|
-
'.ts' => :js,
|
18
|
-
# '.jsx' => :js,
|
19
|
-
'.js' => :js
|
20
|
-
}.freeze
|
21
|
-
|
22
|
-
attr_reader :path
|
23
|
-
|
24
5
|
class << self
|
25
|
-
# Side
|
26
|
-
# a Set of 'js' and 'css' asset paths. This is idempotent, so side loading will never include
|
27
|
-
# duplicates.
|
6
|
+
# Side loads the class, and its super classes that respond to `.source_path`.
|
28
7
|
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
# Side load the given `path` at `type`, without first resolving the path. This still respects
|
35
|
-
# idempotency of `Proscenium::Current.loaded`.
|
8
|
+
# Assign the `abstract_class` class variable to any abstract class, and it will not be side
|
9
|
+
# loaded. Additionally, if the class responds to `#sideload?`, and it returns false, it will
|
10
|
+
# not be side loaded.
|
36
11
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
def
|
40
|
-
return if Proscenium
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
ActiveSupport::Notifications.instrument('sideload.proscenium', identifier: value)
|
47
|
-
|
48
|
-
value
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# @param path [Pathname, String] The path of the file to be side loaded.
|
53
|
-
# @param extension_map [Hash] File extensions to side load.
|
54
|
-
def initialize(path, extension_map = EXTENSION_MAP)
|
55
|
-
@path = (path.is_a?(Pathname) ? path : Rails.root.join(path)).sub_ext('')
|
56
|
-
@extension_map = extension_map
|
57
|
-
|
58
|
-
Proscenium::Current.loaded ||= EXTENSIONS.index_with { |_e| Set.new }
|
59
|
-
end
|
60
|
-
|
61
|
-
def append
|
62
|
-
@extension_map.filter_map do |ext, type|
|
63
|
-
next unless (resolved_path = resolve_path(path.sub_ext(ext)))
|
64
|
-
|
65
|
-
# Make sure path is not already side loaded.
|
66
|
-
unless Proscenium::Current.loaded[type].include?(resolved_path)
|
67
|
-
Proscenium::Current.loaded[type] << log(resolved_path)
|
12
|
+
# If the class responds to `.sideload`, it will be called instead of the regular side loading.
|
13
|
+
# You can use this to customise what is side loaded.
|
14
|
+
def sideload_inheritance_chain(obj)
|
15
|
+
return if !Proscenium.config.side_load || (obj.respond_to?(:sideload?) && !obj.sideload?)
|
16
|
+
|
17
|
+
klass = obj.class
|
18
|
+
while klass.respond_to?(:source_path) && klass.source_path && !klass.abstract_class
|
19
|
+
klass.respond_to?(:sideload) ? klass.sideload : Importer.sideload(klass.source_path)
|
20
|
+
klass = klass.superclass
|
68
21
|
end
|
69
|
-
|
70
|
-
resolved_path
|
71
22
|
end
|
72
23
|
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def log(...)
|
77
|
-
self.class.log(...)
|
78
|
-
end
|
79
|
-
|
80
|
-
def resolve_path(path)
|
81
|
-
path.exist? ? Utils.resolve_path(path.to_s) : nil
|
82
|
-
end
|
83
24
|
end
|
84
25
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Include this into any class to expose a `source_path` class and instance method, which will return
|
4
|
+
# the absolute file system path to the current object.
|
5
|
+
module Proscenium::SourcePath
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def source_path
|
12
|
+
@source_path ||= name.nil? ? nil : Pathname.new(const_source_location(name).first)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Proscenium
|
4
|
+
module Utils
|
5
|
+
module_function
|
6
|
+
|
7
|
+
# @param value [#to_s] The value to create the digest from. This will usually be a `Pathname`.
|
8
|
+
# @return [String] digest of the given value.
|
9
|
+
def digest(value)
|
10
|
+
Digest::SHA1.hexdigest(value.to_s)[..7]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/proscenium/version.rb
CHANGED
@@ -1,35 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# Renders
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# component
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
class Proscenium::ViewComponent::ReactComponent < Proscenium::ViewComponent
|
15
|
-
self.abstract_class = true
|
3
|
+
module Proscenium
|
4
|
+
# Renders a <div> for use with React components, with data attributes specifying the component
|
5
|
+
# path and props.
|
6
|
+
#
|
7
|
+
# If a content block is given, that content will be rendered inside the component, allowing for a
|
8
|
+
# "loading" UI. If no block is given, then a "loading..." text will be rendered. It is intended
|
9
|
+
# that the component is mounted to this div, and the loading UI will then be replaced with the
|
10
|
+
# component's rendered output.
|
11
|
+
class ViewComponent::ReactComponent < ViewComponent
|
12
|
+
self.abstract_class = true
|
16
13
|
|
17
|
-
|
14
|
+
include ReactComponentable
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@props = props
|
24
|
-
@lazy = lazy
|
25
|
-
|
26
|
-
super
|
27
|
-
end
|
28
|
-
|
29
|
-
def call
|
30
|
-
tag.div class: ['componentManagedByProscenium', css_module(:component)],
|
31
|
-
data: { component: { path: virtual_path, props: props, lazy: lazy } } do
|
32
|
-
tag.div content || 'loading...'
|
16
|
+
def call
|
17
|
+
tag.send root_tag, data: data_attributes do
|
18
|
+
tag.div content || 'loading...'
|
19
|
+
end
|
33
20
|
end
|
34
21
|
end
|
35
22
|
end
|
@@ -4,52 +4,29 @@ require 'view_component'
|
|
4
4
|
|
5
5
|
class Proscenium::ViewComponent < ViewComponent::Base
|
6
6
|
extend ActiveSupport::Autoload
|
7
|
-
include Proscenium::CssModule
|
8
7
|
|
9
|
-
autoload :
|
8
|
+
autoload :Sideload
|
10
9
|
autoload :ReactComponent
|
10
|
+
autoload :CssModules
|
11
|
+
|
12
|
+
include Proscenium::SourcePath
|
13
|
+
include CssModules
|
11
14
|
|
12
|
-
# Side loads the class, and its super classes that respond to `.path`. Assign the `abstract_class`
|
13
|
-
# class variable to any abstract class, and it will not be side loaded.
|
14
15
|
module Sideload
|
15
16
|
def before_render
|
16
|
-
|
17
|
-
while !klass.abstract_class && klass.respond_to?(:path) && klass.path
|
18
|
-
Proscenium::SideLoad.append klass.path
|
19
|
-
klass = klass.superclass
|
20
|
-
end
|
17
|
+
Proscenium::SideLoad.sideload_inheritance_chain self
|
21
18
|
|
22
19
|
super
|
23
20
|
end
|
24
21
|
end
|
25
22
|
|
26
23
|
class << self
|
27
|
-
attr_accessor :
|
24
|
+
attr_accessor :abstract_class
|
28
25
|
|
29
26
|
def inherited(child)
|
30
|
-
child.
|
31
|
-
Pathname.new caller_locations(2, 1).first.path
|
32
|
-
else
|
33
|
-
Pathname.new caller_locations(1, 1).first.path
|
34
|
-
end
|
35
|
-
|
36
|
-
child.prepend Sideload if Rails.application.config.proscenium.side_load
|
27
|
+
child.prepend Sideload
|
37
28
|
|
38
29
|
super
|
39
30
|
end
|
40
31
|
end
|
41
|
-
|
42
|
-
# @override Auto compilation of class names to css modules.
|
43
|
-
def render_in(...)
|
44
|
-
cssm.compile_class_names(super(...))
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
# Overrides ActionView::Helpers::TagHelper::TagBuilder, allowing us to intercept the
|
50
|
-
# `css_module` option from the HTML options argument of the `tag` and `content_tag` helpers, and
|
51
|
-
# prepend it to the HTML `class` attribute.
|
52
|
-
def tag_builder
|
53
|
-
@tag_builder ||= Proscenium::ViewComponent::TagBuilder.new(self)
|
54
|
-
end
|
55
32
|
end
|
data/lib/proscenium.rb
CHANGED
@@ -5,18 +5,36 @@ require 'active_support/dependencies/autoload'
|
|
5
5
|
module Proscenium
|
6
6
|
extend ActiveSupport::Autoload
|
7
7
|
|
8
|
-
|
8
|
+
FILE_EXTENSIONS = ['js', 'mjs', 'ts', 'jsx', 'tsx', 'css', 'js.map', 'mjs.map', 'jsx.map',
|
9
|
+
'ts.map', 'tsx.map', 'css.map'].freeze
|
10
|
+
|
11
|
+
APPLICATION_INCLUDE_PATHS = ['config', 'app/assets', 'app/views', 'app/components', 'lib',
|
12
|
+
'node_modules'].freeze
|
13
|
+
|
14
|
+
# Environment variables that should always be passed to the builder.
|
15
|
+
DEFAULT_ENV_VARS = Set['RAILS_ENV', 'NODE_ENV'].freeze
|
16
|
+
|
17
|
+
autoload :SourcePath
|
18
|
+
autoload :Utils
|
19
|
+
autoload :Monkey
|
9
20
|
autoload :Middleware
|
21
|
+
autoload :EnsureLoaded
|
10
22
|
autoload :SideLoad
|
11
23
|
autoload :CssModule
|
24
|
+
autoload :ReactComponentable
|
12
25
|
autoload :ViewComponent
|
13
26
|
autoload :Phlex
|
14
27
|
autoload :Helper
|
15
|
-
autoload :
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
28
|
+
autoload :Builder
|
29
|
+
autoload :Importer
|
30
|
+
autoload :Resolver
|
31
|
+
|
32
|
+
class Deprecator
|
33
|
+
def deprecation_warning(name, message, _caller_backtrace = nil)
|
34
|
+
msg = "`#{name}` is deprecated and will be removed in a near future release of Proscenium"
|
35
|
+
msg << " (#{message})" if message
|
36
|
+
Kernel.warn msg
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
40
|
class PathResolutionFailed < StandardError
|
@@ -29,68 +47,6 @@ module Proscenium
|
|
29
47
|
"Path #{@path.inspect} cannot be resolved"
|
30
48
|
end
|
31
49
|
end
|
32
|
-
|
33
|
-
module Utils
|
34
|
-
module_function
|
35
|
-
|
36
|
-
# @param value [#to_s] The value to create the digest from. This will usually be a `Pathname`.
|
37
|
-
# @return [String] string digest of the given value.
|
38
|
-
def digest(value)
|
39
|
-
Digest::SHA1.hexdigest(value.to_s)[..7]
|
40
|
-
end
|
41
|
-
|
42
|
-
# Resolve the given `path` to a URL path.
|
43
|
-
#
|
44
|
-
# @param path [String] Can be URL path, file system path, or bare specifier (ie. NPM package).
|
45
|
-
# @return [String] URL path.
|
46
|
-
def resolve_path(path) # rubocop:disable Metrics/AbcSize
|
47
|
-
raise ArgumentError, 'path must be a string' unless path.is_a?(String)
|
48
|
-
|
49
|
-
if path.starts_with?('./', '../')
|
50
|
-
raise ArgumentError, 'path must be an absolute file system or URL path'
|
51
|
-
end
|
52
|
-
|
53
|
-
matched_gem = Proscenium.config.side_load_gems.find do |_, opts|
|
54
|
-
path.starts_with?("#{opts[:root]}/")
|
55
|
-
end
|
56
|
-
|
57
|
-
if matched_gem
|
58
|
-
sroot = "#{matched_gem[1][:root]}/"
|
59
|
-
relpath = path.delete_prefix(sroot)
|
60
|
-
|
61
|
-
if (package_name = matched_gem[1][:package_name] || matched_gem[0])
|
62
|
-
return Esbuild::Golib.resolve("#{package_name}/#{relpath}")
|
63
|
-
end
|
64
|
-
|
65
|
-
# TODO: manually resolve the path without esbuild
|
66
|
-
raise PathResolutionFailed, path
|
67
|
-
end
|
68
|
-
|
69
|
-
return path.delete_prefix(Rails.root.to_s) if path.starts_with?("#{Rails.root}/")
|
70
|
-
|
71
|
-
Esbuild::Golib.resolve(path)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Resolves CSS class `names` to CSS module names. Each name will be converted to a CSS module
|
75
|
-
# name, consisting of the camelCased name (lower case first character), and suffixed with the
|
76
|
-
# given `digest`.
|
77
|
-
#
|
78
|
-
# @param names [String, Array]
|
79
|
-
# @param digest: [String]
|
80
|
-
# @returns [Array] of class names generated from the given CSS module `names` and `digest`.
|
81
|
-
def css_modularise_class_names(*names, digest: nil)
|
82
|
-
names.flatten.compact.map { |name| css_modularise_class_name name, digest: digest }
|
83
|
-
end
|
84
|
-
|
85
|
-
def css_modularise_class_name(name, digest: nil)
|
86
|
-
sname = name.to_s
|
87
|
-
if sname.starts_with?('_')
|
88
|
-
"_#{sname[1..].camelize(:lower)}#{digest}"
|
89
|
-
else
|
90
|
-
"#{sname.camelize(:lower)}#{digest}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
50
|
end
|
95
51
|
|
96
52
|
require 'proscenium/railtie'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proscenium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0.pre.1
|
5
5
|
platform: aarch64-linux
|
6
6
|
authors:
|
7
7
|
- Joel Moss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,20 +44,6 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 1.15.5
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: nokogiri
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '1.13'
|
54
|
-
type: :runtime
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '1.13'
|
61
47
|
- !ruby/object:Gem::Dependency
|
62
48
|
name: oj
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,34 +58,6 @@ dependencies:
|
|
72
58
|
- - "~>"
|
73
59
|
- !ruby/object:Gem::Version
|
74
60
|
version: '3.13'
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: phlex
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - "~>"
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: 1.8.1
|
82
|
-
type: :runtime
|
83
|
-
prerelease: false
|
84
|
-
version_requirements: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - "~>"
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: 1.8.1
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: phlex-rails
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - "~>"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: 1.0.0
|
96
|
-
type: :runtime
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 1.0.0
|
103
61
|
- !ruby/object:Gem::Dependency
|
104
62
|
name: railties
|
105
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,34 +89,39 @@ files:
|
|
131
89
|
- LICENSE.txt
|
132
90
|
- README.md
|
133
91
|
- lib/proscenium.rb
|
92
|
+
- lib/proscenium/builder.rb
|
134
93
|
- lib/proscenium/css_module.rb
|
135
|
-
- lib/proscenium/css_module/
|
136
|
-
- lib/proscenium/css_module/
|
137
|
-
- lib/proscenium/
|
138
|
-
- lib/proscenium/esbuild.rb
|
139
|
-
- lib/proscenium/esbuild/golib.rb
|
94
|
+
- lib/proscenium/css_module/path.rb
|
95
|
+
- lib/proscenium/css_module/transformer.rb
|
96
|
+
- lib/proscenium/ensure_loaded.rb
|
140
97
|
- lib/proscenium/ext/proscenium
|
141
98
|
- lib/proscenium/ext/proscenium.h
|
142
99
|
- lib/proscenium/helper.rb
|
100
|
+
- lib/proscenium/importer.rb
|
101
|
+
- lib/proscenium/libs/react-manager/index.jsx
|
102
|
+
- lib/proscenium/libs/react-manager/react.js
|
103
|
+
- lib/proscenium/libs/stimulus-loading.js
|
143
104
|
- lib/proscenium/log_subscriber.rb
|
144
105
|
- lib/proscenium/middleware.rb
|
145
106
|
- lib/proscenium/middleware/base.rb
|
146
107
|
- lib/proscenium/middleware/esbuild.rb
|
147
108
|
- lib/proscenium/middleware/url.rb
|
109
|
+
- lib/proscenium/monkey.rb
|
148
110
|
- lib/proscenium/phlex.rb
|
149
|
-
- lib/proscenium/phlex/
|
111
|
+
- lib/proscenium/phlex/css_modules.rb
|
150
112
|
- lib/proscenium/phlex/page.rb
|
151
113
|
- lib/proscenium/phlex/react_component.rb
|
152
|
-
- lib/proscenium/phlex/resolve_css_modules.rb
|
153
114
|
- lib/proscenium/railtie.rb
|
115
|
+
- lib/proscenium/react_componentable.rb
|
116
|
+
- lib/proscenium/resolver.rb
|
154
117
|
- lib/proscenium/side_load.rb
|
155
|
-
- lib/proscenium/
|
156
|
-
- lib/proscenium/
|
157
|
-
- lib/proscenium/side_load/monkey.rb
|
118
|
+
- lib/proscenium/source_path.rb
|
119
|
+
- lib/proscenium/utils.rb
|
158
120
|
- lib/proscenium/version.rb
|
159
121
|
- lib/proscenium/view_component.rb
|
122
|
+
- lib/proscenium/view_component/css_modules.rb
|
160
123
|
- lib/proscenium/view_component/react_component.rb
|
161
|
-
- lib/proscenium/view_component/
|
124
|
+
- lib/proscenium/view_component/sideload.rb
|
162
125
|
homepage: https://github.com/joelmoss/proscenium
|
163
126
|
licenses:
|
164
127
|
- MIT
|
@@ -178,11 +141,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
141
|
version: 2.7.0
|
179
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
143
|
requirements:
|
181
|
-
- - "
|
144
|
+
- - ">"
|
182
145
|
- !ruby/object:Gem::Version
|
183
|
-
version:
|
146
|
+
version: 1.3.1
|
184
147
|
requirements: []
|
185
|
-
rubygems_version: 3.4.
|
148
|
+
rubygems_version: 3.4.17
|
186
149
|
signing_key:
|
187
150
|
specification_version: 4
|
188
151
|
summary: The engine powering your Rails frontend
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Proscenium
|
4
|
-
class CssModule::ClassNamesResolver
|
5
|
-
def initialize(class_names, phlex_path)
|
6
|
-
@class_names = class_names.split
|
7
|
-
@stylesheets = {}
|
8
|
-
@phlex_path = phlex_path.sub_ext('.module.css')
|
9
|
-
|
10
|
-
resolve_class_names
|
11
|
-
end
|
12
|
-
|
13
|
-
def class_names
|
14
|
-
@class_names.join(' ')
|
15
|
-
end
|
16
|
-
|
17
|
-
def stylesheets
|
18
|
-
@stylesheets.map { |_, values| values[:resolved_path] }
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def resolve_class_names
|
24
|
-
@class_names.map! do |class_name|
|
25
|
-
if class_name.include?('/')
|
26
|
-
if class_name.starts_with?('@')
|
27
|
-
# Scoped bare specifier (eg. "@scoped/package/lib/button@default").
|
28
|
-
_, path, name = class_name.split('@')
|
29
|
-
path = "@#{path}"
|
30
|
-
elsif class_name.starts_with?('/')
|
31
|
-
# Local path with leading slash.
|
32
|
-
path, name = class_name[1..].split('@')
|
33
|
-
else
|
34
|
-
# Bare specifier (eg. "mypackage/lib/button@default").
|
35
|
-
path, name = class_name.split('@')
|
36
|
-
end
|
37
|
-
|
38
|
-
path += '.module.css'
|
39
|
-
|
40
|
-
Utils.css_modularise_class_name name, digest: add_stylesheet(path)[:digest]
|
41
|
-
elsif class_name.starts_with?('@')
|
42
|
-
Utils.css_modularise_class_name class_name[1..],
|
43
|
-
digest: add_stylesheet(@phlex_path)[:digest]
|
44
|
-
else
|
45
|
-
class_name
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def add_stylesheet(path)
|
51
|
-
return @stylesheets[path] if @stylesheets.key?(path)
|
52
|
-
|
53
|
-
resolved_path = Utils.resolve_path(path.to_s)
|
54
|
-
|
55
|
-
unless Rails.root.join(resolved_path[1..]).exist?
|
56
|
-
raise CssModule::StylesheetNotFound, resolved_path
|
57
|
-
end
|
58
|
-
|
59
|
-
# Note that the digest is based on the resolved (URL) path, not the original path.
|
60
|
-
@stylesheets[path] = {
|
61
|
-
resolved_path: resolved_path,
|
62
|
-
digest: Utils.digest(resolved_path)
|
63
|
-
}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Proscenium
|
4
|
-
class CssModule::Resolver
|
5
|
-
attr_reader :side_loaded_paths
|
6
|
-
|
7
|
-
# @param path [Pathname] Absolute file system path to the Ruby file that will be side loaded.
|
8
|
-
def initialize(path, side_load: true, hash: nil)
|
9
|
-
raise ArgumentError, "'#{path}' must be a `Pathname`" unless path.is_a?(Pathname)
|
10
|
-
|
11
|
-
@path = path
|
12
|
-
@hash = hash
|
13
|
-
@css_module_path = path.sub_ext('.module.css')
|
14
|
-
@side_load = side_load
|
15
|
-
@side_loaded_paths = nil
|
16
|
-
end
|
17
|
-
|
18
|
-
# Parses the given `content` for CSS modules names ('class' attributes beginning with '@'), and
|
19
|
-
# returns the content with said CSS Modules replaced with the compiled class names.
|
20
|
-
#
|
21
|
-
# Example:
|
22
|
-
# <div class="@my_css_module_name"></div>
|
23
|
-
def compile_class_names(content)
|
24
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(content)
|
25
|
-
|
26
|
-
return content if (modules = doc.css('[class*="@"]')).empty?
|
27
|
-
|
28
|
-
modules.each do |ele|
|
29
|
-
classes = ele.classes.map { |cls| cls.starts_with?('@') ? class_names!(cls[1..]) : cls }
|
30
|
-
ele['class'] = classes.join(' ')
|
31
|
-
end
|
32
|
-
|
33
|
-
doc.to_html.html_safe
|
34
|
-
end
|
35
|
-
|
36
|
-
# Resolves the given CSS class names to CSS modules. This will also side load the stylesheet if
|
37
|
-
# it exists.
|
38
|
-
#
|
39
|
-
# @param names [String, Array]
|
40
|
-
# @returns [Array] of class names generated from the given CSS module `names`.
|
41
|
-
def class_names(*names)
|
42
|
-
side_load_css_module
|
43
|
-
Utils.css_modularise_class_names names, digest: @hash
|
44
|
-
end
|
45
|
-
|
46
|
-
# Like #class_names, but requires that the stylesheet exists.
|
47
|
-
#
|
48
|
-
# @param names [String, Array]
|
49
|
-
# @raises Proscenium::CssModule::NotFound if stylesheet does not exists.
|
50
|
-
# @see #class_names
|
51
|
-
def class_names!(...)
|
52
|
-
raise CssModule::StylesheetNotFound, @css_module_path unless @css_module_path.exist?
|
53
|
-
|
54
|
-
class_names(...)
|
55
|
-
end
|
56
|
-
|
57
|
-
def side_loaded?
|
58
|
-
@side_loaded_paths.present?
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def side_load_css_module
|
64
|
-
return if !@side_load || !Rails.application.config.proscenium.side_load
|
65
|
-
|
66
|
-
paths = SideLoad.append @path, { '.module.css' => :css }
|
67
|
-
|
68
|
-
@side_loaded_paths = if paths.empty?
|
69
|
-
nil
|
70
|
-
else
|
71
|
-
@hash = Utils.digest(paths[0])
|
72
|
-
paths
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|