proscenium 0.9.1-aarch64-linux → 0.11.0-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 +451 -65
- data/lib/proscenium/builder.rb +144 -0
- data/lib/proscenium/css_module/path.rb +31 -0
- data/lib/proscenium/css_module/transformer.rb +82 -0
- data/lib/proscenium/css_module.rb +12 -25
- data/lib/proscenium/ensure_loaded.rb +27 -0
- data/lib/proscenium/ext/proscenium +0 -0
- data/lib/proscenium/ext/proscenium.h +20 -12
- data/lib/proscenium/helper.rb +85 -0
- data/lib/proscenium/importer.rb +110 -0
- data/lib/proscenium/libs/react-manager/index.jsx +101 -0
- data/lib/proscenium/libs/react-manager/react.js +2 -0
- data/lib/proscenium/libs/stimulus-loading.js +83 -0
- data/lib/proscenium/libs/test.js +1 -0
- data/lib/proscenium/log_subscriber.rb +1 -2
- data/lib/proscenium/middleware/base.rb +8 -8
- data/lib/proscenium/middleware/engines.rb +37 -0
- data/lib/proscenium/middleware/esbuild.rb +3 -5
- data/lib/proscenium/middleware/runtime.rb +18 -0
- data/lib/proscenium/middleware.rb +19 -4
- data/lib/proscenium/{side_load/monkey.rb → monkey.rb} +24 -12
- data/lib/proscenium/phlex/{resolve_css_modules.rb → css_modules.rb} +28 -16
- data/lib/proscenium/phlex/react_component.rb +27 -64
- data/lib/proscenium/phlex.rb +11 -30
- data/lib/proscenium/railtie.rb +49 -41
- data/lib/proscenium/react_componentable.rb +95 -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/templates/rescues/build_error.html.erb +30 -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 +23 -68
- metadata +25 -59
- 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/phlex/page.rb +0 -62
- 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
@@ -0,0 +1,83 @@
|
|
1
|
+
const controllerAttribute = "data-controller";
|
2
|
+
const controllerFilenameExtension = ".js";
|
3
|
+
|
4
|
+
export function lazyLoadControllersFrom(
|
5
|
+
under,
|
6
|
+
application,
|
7
|
+
element = document
|
8
|
+
) {
|
9
|
+
lazyLoadExistingControllers(under, application, element);
|
10
|
+
lazyLoadNewControllers(under, application, element);
|
11
|
+
}
|
12
|
+
|
13
|
+
function lazyLoadExistingControllers(under, application, element) {
|
14
|
+
queryControllerNamesWithin(element).forEach((controllerName) =>
|
15
|
+
loadController(controllerName, under, application)
|
16
|
+
);
|
17
|
+
}
|
18
|
+
|
19
|
+
function lazyLoadNewControllers(under, application, element) {
|
20
|
+
new MutationObserver((mutationsList) => {
|
21
|
+
for (const { attributeName, target, type } of mutationsList) {
|
22
|
+
switch (type) {
|
23
|
+
case "attributes": {
|
24
|
+
if (
|
25
|
+
attributeName == controllerAttribute &&
|
26
|
+
target.getAttribute(controllerAttribute)
|
27
|
+
) {
|
28
|
+
extractControllerNamesFrom(target).forEach((controllerName) =>
|
29
|
+
loadController(controllerName, under, application)
|
30
|
+
);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
case "childList": {
|
35
|
+
lazyLoadExistingControllers(under, application, target);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}).observe(element, {
|
40
|
+
attributeFilter: [controllerAttribute],
|
41
|
+
subtree: true,
|
42
|
+
childList: true,
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
function queryControllerNamesWithin(element) {
|
47
|
+
return Array.from(element.querySelectorAll(`[${controllerAttribute}]`))
|
48
|
+
.map(extractControllerNamesFrom)
|
49
|
+
.flat();
|
50
|
+
}
|
51
|
+
|
52
|
+
function extractControllerNamesFrom(element) {
|
53
|
+
return element
|
54
|
+
.getAttribute(controllerAttribute)
|
55
|
+
.split(/\s+/)
|
56
|
+
.filter((content) => content.length);
|
57
|
+
}
|
58
|
+
|
59
|
+
function loadController(name, under, application) {
|
60
|
+
if (canRegisterController(name, application)) {
|
61
|
+
import(controllerFilename(name, under))
|
62
|
+
.then((module) => registerController(name, module, application))
|
63
|
+
.catch((error) =>
|
64
|
+
console.error(`Failed to autoload controller: ${name}`, error)
|
65
|
+
);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
function controllerFilename(name, under) {
|
70
|
+
return `${under}/${name
|
71
|
+
.replace(/--/g, "/")
|
72
|
+
.replace(/-/g, "_")}_controller${controllerFilenameExtension}`;
|
73
|
+
}
|
74
|
+
|
75
|
+
function registerController(name, module, application) {
|
76
|
+
if (canRegisterController(name, application)) {
|
77
|
+
application.register(name, module.default);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
function canRegisterController(name, application) {
|
82
|
+
return !application.router.modulesByIdentifier.has(name);
|
83
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
console.log("/@proscenium/test.js");
|
@@ -12,12 +12,11 @@ module Proscenium
|
|
12
12
|
|
13
13
|
def build(event)
|
14
14
|
path = event.payload[:identifier]
|
15
|
-
path = path.start_with?(/https?%3A%2F%2F/)
|
15
|
+
path = CGI.unescape(path) if path.start_with?(/https?%3A%2F%2F/)
|
16
16
|
|
17
17
|
info do
|
18
18
|
message = +"[Proscenium] Building #{path}"
|
19
19
|
message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
|
20
|
-
message << "\n" if defined?(Rails.env) && Rails.env.development?
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|
@@ -34,12 +34,12 @@ module Proscenium
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def real_path
|
37
|
-
@request.path
|
37
|
+
@real_path ||= @request.path
|
38
38
|
end
|
39
39
|
|
40
40
|
# @return [String] the path to the file without the leading slash which will be built.
|
41
41
|
def path_to_build
|
42
|
-
@request.path[1..]
|
42
|
+
@path_to_build ||= @request.path[1..]
|
43
43
|
end
|
44
44
|
|
45
45
|
def sourcemap?
|
@@ -51,24 +51,24 @@ module Proscenium
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def file_readable?
|
54
|
-
return unless (path = clean_path(sourcemap? ? real_path[0...-4] : real_path))
|
54
|
+
return false unless (path = clean_path(sourcemap? ? real_path[0...-4] : real_path))
|
55
55
|
|
56
|
-
file_stat = File.stat(
|
56
|
+
file_stat = File.stat(root_for_readable.join(path.delete_prefix('/').b).to_s)
|
57
57
|
rescue SystemCallError
|
58
58
|
false
|
59
59
|
else
|
60
60
|
file_stat.file? && file_stat.readable?
|
61
61
|
end
|
62
62
|
|
63
|
+
def root_for_readable
|
64
|
+
Rails.root
|
65
|
+
end
|
66
|
+
|
63
67
|
def clean_path(file)
|
64
68
|
path = Rack::Utils.unescape_path file.chomp('/').delete_prefix('/')
|
65
69
|
Rack::Utils.clean_path_info path if Rack::Utils.valid_path? path
|
66
70
|
end
|
67
71
|
|
68
|
-
def root
|
69
|
-
@root ||= Rails.root.to_s
|
70
|
-
end
|
71
|
-
|
72
72
|
def content_type
|
73
73
|
case ::File.extname(path_to_build)
|
74
74
|
when '.js', '.mjs', '.ts', '.tsx', '.jsx' then 'application/javascript'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Proscenium
|
4
|
+
class Middleware
|
5
|
+
# This middleware handles requests for assets in Rails engines. An engine that wants to expose
|
6
|
+
# its assets via Proscenium to the application must add itself to the list of engines in the
|
7
|
+
# Proscenium config options `Proscenium.config.engines`.
|
8
|
+
#
|
9
|
+
# For example, we have a gem that exposes a Rails engine.
|
10
|
+
#
|
11
|
+
# module Gem1
|
12
|
+
# class Engine < ::Rails::Engine
|
13
|
+
# config.proscenium.engines << self
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# When this gem is installed in any Rails application, its assets will be available at the URL
|
18
|
+
# `/gem1/...`. For example, if the gem has a file `lib/styles.css`, it can be requested at
|
19
|
+
# `/gem1/lib/styles.css`.
|
20
|
+
#
|
21
|
+
class Engines < Esbuild
|
22
|
+
def real_path
|
23
|
+
@real_path ||= Pathname.new(@request.path.delete_prefix("/#{engine.engine_name}")).to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_for_readable
|
27
|
+
engine.root
|
28
|
+
end
|
29
|
+
|
30
|
+
def engine
|
31
|
+
@engine ||= Proscenium.config.engines.find do |engine|
|
32
|
+
@request.path.start_with?("/#{engine.engine_name}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -20,11 +20,9 @@ module Proscenium
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def attempt
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
rescue Proscenium::Esbuild::CompileError => e
|
23
|
+
render_response Builder.build(path_to_build, root: Rails.root.to_s,
|
24
|
+
base_url: @request.base_url)
|
25
|
+
rescue Builder::CompileError => e
|
28
26
|
raise self.class::CompileError, { file: @request.fullpath, detail: e.message }, caller
|
29
27
|
end
|
30
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Proscenium
|
4
|
+
class Middleware
|
5
|
+
class Runtime < Esbuild
|
6
|
+
private
|
7
|
+
|
8
|
+
def real_path
|
9
|
+
@real_path ||= Pathname.new(@request.path.sub(%r{^/@proscenium},
|
10
|
+
'/lib/proscenium/libs')).to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def root_for_readable
|
14
|
+
Proscenium::Railtie.root
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -9,16 +9,23 @@ module Proscenium
|
|
9
9
|
|
10
10
|
autoload :Base
|
11
11
|
autoload :Esbuild
|
12
|
+
autoload :Engines
|
13
|
+
autoload :Runtime
|
12
14
|
autoload :Url
|
13
15
|
|
14
16
|
def initialize(app)
|
15
17
|
@app = app
|
18
|
+
|
19
|
+
chunks_path = Rails.public_path.join('assets').to_s
|
20
|
+
headers = Rails.application.config.public_file_server.headers || {}
|
21
|
+
@chunk_handler = ::ActionDispatch::FileHandler.new(chunks_path, headers: headers)
|
16
22
|
end
|
17
23
|
|
18
24
|
def call(env)
|
19
25
|
request = Rack::Request.new(env)
|
20
26
|
|
21
27
|
return @app.call(env) if !request.get? && !request.head?
|
28
|
+
return @chunk_handler.attempt(request.env) if request.path.match?(%r{^/_asset_chunks/})
|
22
29
|
|
23
30
|
attempt(request) || @app.call(env)
|
24
31
|
end
|
@@ -35,12 +42,20 @@ module Proscenium
|
|
35
42
|
|
36
43
|
def find_type(request)
|
37
44
|
return Url if request.path.match?(%r{^/https?%3A%2F%2F})
|
38
|
-
return
|
45
|
+
return Runtime if request.path.match?(%r{^/@proscenium/})
|
46
|
+
return Esbuild if Pathname.new(request.path).fnmatch?(app_path_glob, File::FNM_EXTGLOB)
|
47
|
+
|
48
|
+
Engines if Pathname.new(request.path).fnmatch?(engines_path_glob, File::FNM_EXTGLOB)
|
39
49
|
end
|
40
50
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
51
|
+
def app_path_glob
|
52
|
+
"/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{FILE_EXTENSIONS.join(',')}}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def engines_path_glob
|
56
|
+
names = Proscenium.config.engines.map(&:engine_name)
|
57
|
+
|
58
|
+
"/{#{names.join(',')}}/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{FILE_EXTENSIONS.join(',')}}"
|
44
59
|
end
|
45
60
|
|
46
61
|
# TODO: handle precompiled assets
|
@@ -1,12 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
module Proscenium
|
4
4
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
5
5
|
module Monkey
|
6
|
+
module DebugView
|
7
|
+
def initialize(assigns)
|
8
|
+
paths = [RESCUES_TEMPLATE_PATH, Rails.root.join('lib', 'templates').to_s]
|
9
|
+
lookup_context = ActionView::LookupContext.new(paths)
|
10
|
+
super(lookup_context, assigns, nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
module TemplateRenderer
|
7
15
|
private
|
8
16
|
|
9
17
|
def render_template(view, template, layout_name, locals)
|
18
|
+
return super unless Proscenium.config.side_load
|
19
|
+
|
10
20
|
layout = find_layout(layout_name, locals.keys, [formats.first])
|
11
21
|
renderable = template.instance_variable_get(:@renderable)
|
12
22
|
|
@@ -14,20 +24,18 @@ class Proscenium::SideLoad
|
|
14
24
|
template.is_a?(ActionView::Template::Renderable) &&
|
15
25
|
renderable.class < ::ViewComponent::Base && renderable.class.format == :html
|
16
26
|
# Side load controller rendered ViewComponent
|
17
|
-
|
18
|
-
|
27
|
+
Importer.sideload "app/views/#{layout.virtual_path}" if layout
|
28
|
+
Importer.sideload "app/views/#{renderable.virtual_path}"
|
19
29
|
elsif template.respond_to?(:virtual_path) &&
|
20
30
|
template.respond_to?(:type) && template.type == :html
|
21
|
-
|
22
|
-
Proscenium::SideLoad.append "app/views/#{layout.virtual_path}" if layout
|
31
|
+
Importer.sideload "app/views/#{layout.virtual_path}" if layout
|
23
32
|
|
24
33
|
# Try side loading the variant template
|
25
34
|
if template.respond_to?(:variant) && template.variant
|
26
|
-
|
35
|
+
Importer.sideload "app/views/#{template.virtual_path}+#{template.variant}"
|
27
36
|
end
|
28
37
|
|
29
|
-
|
30
|
-
Proscenium::SideLoad.append "app/views/#{template.virtual_path}"
|
38
|
+
Importer.sideload "app/views/#{template.virtual_path}"
|
31
39
|
end
|
32
40
|
|
33
41
|
super
|
@@ -37,10 +45,14 @@ class Proscenium::SideLoad
|
|
37
45
|
module PartialRenderer
|
38
46
|
private
|
39
47
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
def render_partial_template(view, locals, template, layout, block)
|
49
|
+
if Proscenium.config.side_load && template.respond_to?(:virtual_path) &&
|
50
|
+
template.respond_to?(:type) && template.type == :html
|
51
|
+
Importer.sideload "app/views/#{layout.virtual_path}" if layout
|
52
|
+
Importer.sideload "app/views/#{template.virtual_path}"
|
53
|
+
end
|
54
|
+
|
55
|
+
super
|
44
56
|
end
|
45
57
|
end
|
46
58
|
end
|
@@ -1,15 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Proscenium
|
4
|
-
module Phlex::
|
5
|
-
|
4
|
+
module Phlex::CssModules
|
5
|
+
include Proscenium::CssModule
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
def self.included(base)
|
8
|
+
base.extend CssModule::Path
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# Set of CSS module paths that have been resolved after being transformed from 'class' HTML
|
14
|
+
# attributes. See #process_attributes. This is here because Phlex caches attributes. Which
|
15
|
+
# means while the CSS class names will be transformed, any resolved paths will be lost in
|
16
|
+
# subsequent requests.
|
17
|
+
attr_accessor :resolved_css_module_paths
|
9
18
|
end
|
10
19
|
|
11
20
|
def before_template
|
12
|
-
self.class.
|
21
|
+
self.class.resolved_css_module_paths ||= Concurrent::Set.new
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_template
|
26
|
+
self.class.resolved_css_module_paths.each do |path|
|
27
|
+
Proscenium::Importer.import path
|
28
|
+
end
|
29
|
+
|
13
30
|
super
|
14
31
|
end
|
15
32
|
|
@@ -44,24 +61,19 @@ module Proscenium
|
|
44
61
|
# end
|
45
62
|
# end
|
46
63
|
#
|
47
|
-
# The given class name should be underscored, and the resulting CSS module name will be
|
48
|
-
# `camelCased` with a lower case first character.
|
49
|
-
#
|
50
64
|
# @raise [Proscenium::CssModule::Resolver::NotFound] If a CSS module file is not found for the
|
51
65
|
# Phlex class file path.
|
52
66
|
def process_attributes(**attributes)
|
53
67
|
if attributes.key?(:class) && (attributes[:class] = tokens(attributes[:class])).include?('@')
|
54
|
-
|
55
|
-
|
56
|
-
attributes[:class] =
|
68
|
+
names = attributes[:class].is_a?(Array) ? attributes[:class] : attributes[:class].split
|
69
|
+
|
70
|
+
attributes[:class] = cssm.class_names(*names).map do |name, path|
|
71
|
+
self.class.resolved_css_module_paths << path if path
|
72
|
+
name
|
73
|
+
end
|
57
74
|
end
|
58
75
|
|
59
76
|
attributes
|
60
77
|
end
|
61
|
-
|
62
|
-
def after_template
|
63
|
-
super
|
64
|
-
self.class.side_load_cache&.each { |path| SideLoad.append! path, :css }
|
65
|
-
end
|
66
78
|
end
|
67
79
|
end
|
@@ -1,69 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# Renders a div for use with
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
class
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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 block is given, it will be yielded within the div, allowing for a custom "loading" UI. If
|
8
|
+
# no block is given, then a "loading..." text will be rendered. It is intended that the component
|
9
|
+
# is mounted to this div, and the loading UI will then be replaced with the component's rendered
|
10
|
+
# output.
|
11
|
+
#
|
12
|
+
# You can pass props to the component in the `:props` keyword argument.
|
13
|
+
class Phlex::ReactComponent < Phlex
|
14
|
+
self.abstract_class = true
|
15
|
+
|
16
|
+
include ReactComponentable
|
17
|
+
|
18
|
+
# Override this to provide your own loading UI.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# def template(**attributes, &block)
|
22
|
+
# super do
|
23
|
+
# 'Look at me! I am loading now...'
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# @yield the given block to a `div` within the top level component div.
|
28
|
+
def template(**attributes, &block)
|
29
|
+
send root_tag, **{ data: data_attributes }.deep_merge(attributes), &block
|
22
30
|
end
|
23
31
|
end
|
24
|
-
|
25
|
-
self.abstract_class = true
|
26
|
-
|
27
|
-
include Proscenium::Phlex::ComponentConcerns::CssModules
|
28
|
-
|
29
|
-
attr_writer :props, :lazy
|
30
|
-
|
31
|
-
# @param props: [Hash]
|
32
|
-
# @param lazy: [Boolean] Lazy load the component using IntersectionObserver. Default: true.
|
33
|
-
def initialize(props: {}, lazy: true) # rubocop:disable Lint/MissingSuper
|
34
|
-
@props = props
|
35
|
-
@lazy = lazy
|
36
|
-
end
|
37
|
-
|
38
|
-
# @yield the given block to a `div` within the top level component div. If not given,
|
39
|
-
# `<div>loading...</div>` will be rendered. Use this to display a loading UI while the component
|
40
|
-
# is loading and rendered.
|
41
|
-
def template(**attributes, &block)
|
42
|
-
component_root(:div, **attributes, &block)
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def component_root(element, **attributes, &block)
|
48
|
-
send element, data: { proscenium_component: component_data }, **attributes, &block
|
49
|
-
end
|
50
|
-
|
51
|
-
def props
|
52
|
-
@props ||= {}
|
53
|
-
end
|
54
|
-
|
55
|
-
def lazy
|
56
|
-
instance_variable_defined?(:@lazy) ? @lazy : (@lazy = false)
|
57
|
-
end
|
58
|
-
|
59
|
-
def component_data
|
60
|
-
{
|
61
|
-
path: virtual_path, lazy: lazy,
|
62
|
-
props: props.deep_transform_keys { |k| k.to_s.camelize :lower }
|
63
|
-
}.to_json
|
64
|
-
end
|
65
|
-
|
66
|
-
def virtual_path
|
67
|
-
path.to_s.delete_prefix(Rails.root.to_s)
|
68
|
-
end
|
69
32
|
end
|
data/lib/proscenium/phlex.rb
CHANGED
@@ -5,54 +5,35 @@ require 'phlex-rails'
|
|
5
5
|
module Proscenium
|
6
6
|
class Phlex < ::Phlex::HTML
|
7
7
|
extend ActiveSupport::Autoload
|
8
|
-
include Proscenium::CssModule
|
9
8
|
|
10
|
-
autoload :
|
9
|
+
autoload :CssModules
|
11
10
|
autoload :ReactComponent
|
12
|
-
autoload :ResolveCssModules
|
13
|
-
autoload :ComponentConcerns
|
14
11
|
|
15
12
|
extend ::Phlex::Rails::HelperMacros
|
16
13
|
include ::Phlex::Rails::Helpers::JavaScriptIncludeTag
|
17
14
|
include ::Phlex::Rails::Helpers::StyleSheetLinkTag
|
15
|
+
include Proscenium::SourcePath
|
16
|
+
include CssModules
|
18
17
|
|
19
|
-
define_output_helper :side_load_stylesheets
|
20
|
-
define_output_helper :
|
18
|
+
define_output_helper :side_load_stylesheets # deprecated
|
19
|
+
define_output_helper :include_stylesheets
|
20
|
+
define_output_helper :side_load_javascripts # deprecated
|
21
|
+
define_output_helper :include_javascripts
|
22
|
+
define_output_helper :declare_lazy_scripts
|
21
23
|
|
22
|
-
# Side loads the class, and its super classes that respond to `.path`. Assign the
|
23
|
-
# `abstract_class` class variable to any abstract class, and it will not be side loaded.
|
24
|
-
# Additionally, if the class responds to `side_load`, then that method is called.
|
25
24
|
module Sideload
|
26
25
|
def before_template
|
27
|
-
|
28
|
-
|
29
|
-
if !klass.abstract_class && respond_to?(:side_load, true)
|
30
|
-
side_load
|
31
|
-
klass = klass.superclass
|
32
|
-
end
|
33
|
-
|
34
|
-
while !klass.abstract_class && klass.respond_to?(:path) && klass.path
|
35
|
-
Proscenium::SideLoad.append klass.path
|
36
|
-
klass = klass.superclass
|
37
|
-
end
|
26
|
+
Proscenium::SideLoad.sideload_inheritance_chain self
|
38
27
|
|
39
28
|
super
|
40
29
|
end
|
41
30
|
end
|
42
31
|
|
43
32
|
class << self
|
44
|
-
attr_accessor :
|
33
|
+
attr_accessor :abstract_class
|
45
34
|
|
46
35
|
def inherited(child)
|
47
|
-
|
48
|
-
child.path = if caller_locations(1, 1).first.label == 'inherited'
|
49
|
-
Pathname.new caller_locations(2, 1).first.path
|
50
|
-
else
|
51
|
-
Pathname.new caller_locations(1, 1).first.path
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
child.prepend Sideload if Rails.application.config.proscenium.side_load
|
36
|
+
child.prepend Sideload
|
56
37
|
|
57
38
|
super
|
58
39
|
end
|