klenod-build 0.0.1
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 +7 -0
- data/README.md +29 -0
- data/lib/klenod/build/asset.rb +235 -0
- data/lib/klenod/build/asset_compression.rb +58 -0
- data/lib/klenod/build/asset_generation_queue.rb +50 -0
- data/lib/klenod/build/cli/application.rb +108 -0
- data/lib/klenod/build/cli.rb +3 -0
- data/lib/klenod/build/config.rb +142 -0
- data/lib/klenod/build/context.rb +370 -0
- data/lib/klenod/build/dependency.rb +21 -0
- data/lib/klenod/build/errors.rb +175 -0
- data/lib/klenod/build/filesystem_resolver.rb +147 -0
- data/lib/klenod/build/graph/invalidator.rb +246 -0
- data/lib/klenod/build/graph.rb +864 -0
- data/lib/klenod/build/graphviz.rb +282 -0
- data/lib/klenod/build/hashing.rb +21 -0
- data/lib/klenod/build/invalidation_result.rb +55 -0
- data/lib/klenod/build/load_result.rb +7 -0
- data/lib/klenod/build/loaded_module.rb +38 -0
- data/lib/klenod/build/module_id.rb +100 -0
- data/lib/klenod/build/module_record.rb +22 -0
- data/lib/klenod/build/plugin.rb +35 -0
- data/lib/klenod/build/plugins/class_names_runtime.rb +125 -0
- data/lib/klenod/build/plugins/component_defaults.rb +12 -0
- data/lib/klenod/build/plugins/data_plugin.rb +117 -0
- data/lib/klenod/build/plugins/gem_import_plugin.rb +125 -0
- data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.json +17687 -0
- data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.rb +105 -0
- data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.txt +31 -0
- data/lib/klenod/build/plugins/google_fonts_plugin.rb +387 -0
- data/lib/klenod/build/plugins/haml_plugin/companions.rb +40 -0
- data/lib/klenod/build/plugins/haml_plugin/errors.rb +114 -0
- data/lib/klenod/build/plugins/haml_plugin/helper_source.rb +123 -0
- data/lib/klenod/build/plugins/haml_plugin/parser.rb +85 -0
- data/lib/klenod/build/plugins/haml_plugin/transformer/ruby_builder.rb +1039 -0
- data/lib/klenod/build/plugins/haml_plugin/transformer.rb +766 -0
- data/lib/klenod/build/plugins/haml_plugin.rb +369 -0
- data/lib/klenod/build/plugins/image_plugin.rb +401 -0
- data/lib/klenod/build/plugins/intl_plugin.rb +34 -0
- data/lib/klenod/build/plugins/markdown_compiler.rb +180 -0
- data/lib/klenod/build/plugins/markdown_plugin.rb +161 -0
- data/lib/klenod/build/plugins/router_plugin.rb +942 -0
- data/lib/klenod/build/plugins/ruby_plugin.rb +34 -0
- data/lib/klenod/build/plugins/svg_plugin.rb +197 -0
- data/lib/klenod/build/plugins.rb +22 -0
- data/lib/klenod/build/profiler.rb +79 -0
- data/lib/klenod/build/resolution_error_formatter.rb +42 -0
- data/lib/klenod/build/resolver.rb +95 -0
- data/lib/klenod/build/ruby_import_rewriter.rb +436 -0
- data/lib/klenod/build/source_map/editor.rb +110 -0
- data/lib/klenod/build/source_map/map.rb +168 -0
- data/lib/klenod/build/source_map/vlq.rb +68 -0
- data/lib/klenod/build/source_map.rb +12 -0
- data/lib/klenod/build/transform_result.rb +12 -0
- data/lib/klenod/build/version.rb +7 -0
- data/lib/klenod/build/watched_pattern.rb +11 -0
- data/lib/klenod/build/watcher.rb +141 -0
- data/lib/klenod/build.rb +15 -0
- metadata +310 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Klenod
|
|
4
|
+
module Build
|
|
5
|
+
module Plugins
|
|
6
|
+
module HamlPlugin
|
|
7
|
+
module HelperSource
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def haml_helper_dependency(module_id)
|
|
11
|
+
Dependency
|
|
12
|
+
.create(
|
|
13
|
+
specifier: HAML_HELPER_SPECIFIER,
|
|
14
|
+
importer_id: module_id,
|
|
15
|
+
kind: :haml_helper
|
|
16
|
+
)
|
|
17
|
+
.with(id: "#{module_id}:haml_helper")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def haml_helper_source
|
|
21
|
+
<<~RUBY
|
|
22
|
+
# frozen_string_literal: true
|
|
23
|
+
|
|
24
|
+
module Default
|
|
25
|
+
def self.merge_props(component_class, *sources)
|
|
26
|
+
result = {}
|
|
27
|
+
classes = []
|
|
28
|
+
|
|
29
|
+
sources.each do |source|
|
|
30
|
+
next unless source
|
|
31
|
+
|
|
32
|
+
source.each do |key, value|
|
|
33
|
+
key = normalize_prop_key(key)
|
|
34
|
+
if key == :class
|
|
35
|
+
collect_class_values(classes, value)
|
|
36
|
+
else
|
|
37
|
+
result[key] = value
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class_name = class_name(component_class, classes)
|
|
43
|
+
result[:class] = class_name if class_name
|
|
44
|
+
result
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.normalize_prop_key(key)
|
|
48
|
+
return key if key.is_a?(Symbol) && !key.to_s.include?("-")
|
|
49
|
+
|
|
50
|
+
key.to_s.tr("-", "_").to_sym
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.collect_class_values(classes, value)
|
|
54
|
+
case value
|
|
55
|
+
when nil, false
|
|
56
|
+
nil
|
|
57
|
+
when Array
|
|
58
|
+
value.each { |item| collect_class_values(classes, item) }
|
|
59
|
+
else
|
|
60
|
+
classes << value
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.class_name(component_class, classes)
|
|
65
|
+
return nil if classes.empty?
|
|
66
|
+
|
|
67
|
+
styles = component_class.const_defined?(:ClassNames, false) ? component_class::ClassNames : nil
|
|
68
|
+
return nil unless styles.respond_to?(:class_name)
|
|
69
|
+
|
|
70
|
+
styles.class_name(*classes)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.render_slot(component, name = nil, fallback = nil)
|
|
74
|
+
children =
|
|
75
|
+
if component.respond_to?(:children)
|
|
76
|
+
name ? component.children[name] : component.children
|
|
77
|
+
elsif component.respond_to?(:__slots)
|
|
78
|
+
component.__slots[name&.to_sym]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return children if children && !children.empty?
|
|
82
|
+
|
|
83
|
+
fallback
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.freeze_static(value, seen = {})
|
|
87
|
+
return value if value.nil? || value == true || value == false || value.is_a?(Symbol) || value.is_a?(Numeric)
|
|
88
|
+
|
|
89
|
+
object_id = value.object_id
|
|
90
|
+
return value if seen[object_id]
|
|
91
|
+
|
|
92
|
+
seen[object_id] = true
|
|
93
|
+
|
|
94
|
+
case value
|
|
95
|
+
when String
|
|
96
|
+
nil
|
|
97
|
+
when Array
|
|
98
|
+
value.each { |child| freeze_static(child, seen) }
|
|
99
|
+
when Hash
|
|
100
|
+
value.each do |key, child|
|
|
101
|
+
freeze_static(key, seen)
|
|
102
|
+
freeze_static(child, seen)
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
value.deconstruct.each { |child| freeze_static(child, seen) } if value.respond_to?(:deconstruct)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
value.freeze
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
RUBY
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def haml_helper_needed?(source, styleable:)
|
|
115
|
+
return true if styleable
|
|
116
|
+
|
|
117
|
+
source.match?(STATIC_CLASS_SOURCE_PATTERN) || source.match?(/^\s*%slot\b/)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ripper"
|
|
4
|
+
require "syntax_tree/haml"
|
|
5
|
+
|
|
6
|
+
module Klenod
|
|
7
|
+
module Build
|
|
8
|
+
module Plugins
|
|
9
|
+
module HamlPlugin
|
|
10
|
+
def self.parse_haml(source, module_id: nil)
|
|
11
|
+
parser = ParserWithMetadata.new({})
|
|
12
|
+
parser.call(source)
|
|
13
|
+
rescue ::Haml::SyntaxError => error
|
|
14
|
+
raise ParseError.new(error, source: source, module_id: module_id)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ParserWithMetadata < ::Haml::Parser
|
|
18
|
+
def initialize(...)
|
|
19
|
+
@tag_metadata_by_line = Hash.new { |hash, key| hash[key] = [] }
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def call(source)
|
|
24
|
+
root = super
|
|
25
|
+
annotate_tag_nodes(root)
|
|
26
|
+
root
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def parse_tag(text)
|
|
32
|
+
result = super
|
|
33
|
+
_, shorthand_attributes, attribute_hashes = result
|
|
34
|
+
@tag_metadata_by_line[@line.index + 1] << class_metadata(shorthand_attributes, attribute_hashes)
|
|
35
|
+
result
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def annotate_tag_nodes(root)
|
|
39
|
+
queue = root.children.dup
|
|
40
|
+
until queue.empty?
|
|
41
|
+
node = queue.shift
|
|
42
|
+
if node.type == :tag
|
|
43
|
+
metadata = @tag_metadata_by_line.fetch(node.line, []).shift
|
|
44
|
+
node.value[:klenod_class_metadata] = metadata if metadata
|
|
45
|
+
end
|
|
46
|
+
queue.concat(node.children)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def class_metadata(shorthand_attributes, attribute_hashes)
|
|
51
|
+
shorthand = ::Haml::Parser.parse_class_and_id(shorthand_attributes).fetch("class", "").split
|
|
52
|
+
literal = []
|
|
53
|
+
|
|
54
|
+
if (new_attributes = attribute_hashes[:new])
|
|
55
|
+
literal.concat(Array(new_attributes.fetch(0)["class"]).flat_map { it.to_s.split })
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if (old_attributes = attribute_hashes[:old])
|
|
59
|
+
literal.concat(literal_class_names_from_old_attributes(old_attributes))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
{shorthand: shorthand, literal: literal}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def literal_class_names_from_old_attributes(source)
|
|
66
|
+
parsed = ::Haml::AttributeParser.parse(source)
|
|
67
|
+
return [] unless parsed&.key?("class")
|
|
68
|
+
|
|
69
|
+
value = static_string_literal_value(parsed.fetch("class"))
|
|
70
|
+
value ? value.split : []
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def static_string_literal_value(source)
|
|
74
|
+
case Ripper.sexp(source)
|
|
75
|
+
in [:program, [[:string_literal, [:string_content, [:@tstring_content, String => value, _location]]]]]
|
|
76
|
+
value
|
|
77
|
+
else
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|