lookbook 1.0.3 → 1.0.5
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/app/assets/lookbook/js/app.js +1 -0
- data/app/assets/lookbook/js/lib/socket.js +9 -5
- data/app/components/lookbook/base_component.rb +10 -2
- data/app/components/lookbook/copy_button/component.rb +1 -1
- data/app/components/lookbook/dimensions_display/component.rb +1 -4
- data/app/components/lookbook/embed/component.rb +1 -1
- data/app/components/lookbook/icon/component.rb +1 -5
- data/app/components/lookbook/nav/component.html.erb +1 -1
- data/app/components/lookbook/nav/item/component.rb +2 -2
- data/app/components/lookbook/params_editor/field/component.rb +1 -1
- data/app/components/lookbook/tabs/component.js +2 -2
- data/app/controllers/lookbook/application_controller.rb +10 -1
- data/app/controllers/lookbook/pages_controller.rb +0 -1
- data/app/controllers/lookbook/previews_controller.rb +9 -6
- data/app/helpers/lookbook/component_helper.rb +2 -1
- data/app/views/layouts/lookbook/application.html.erb +6 -36
- data/app/views/lookbook/index.html.erb +2 -2
- data/app/views/lookbook/previews/show.html.erb +1 -1
- data/config/routes.rb +1 -1
- data/lib/lookbook/config.rb +7 -4
- data/lib/lookbook/data.rb +2 -2
- data/lib/lookbook/engine.rb +35 -49
- data/lib/lookbook/parser.rb +19 -11
- data/lib/lookbook/preview.rb +22 -76
- data/lib/lookbook/preview_example.rb +11 -4
- data/lib/lookbook/source_inspector.rb +2 -2
- data/lib/lookbook/store.rb +2 -2
- data/lib/lookbook/version.rb +1 -1
- data/lib/tasks/lookbook_tasks.rake +1 -2
- data/public/lookbook-assets/css/lookbook.css +8 -34
- data/public/lookbook-assets/css/lookbook.css.map +1 -1
- data/public/lookbook-assets/js/lookbook.js +193 -139
- data/public/lookbook-assets/js/lookbook.js.map +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 060aa0a8fdc856787346c247d707f848e7e9aabdb6c19a44a50738ff6389191f
|
4
|
+
data.tar.gz: d1a6b2e6c0264c3d4cafb77d2a4dfd0e899f4bcae74259a25fad5c1aa512ad2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acf0e49fcdf7779e14522dc22a2e27b881e8a7432dd5153d82b5e8f2d7502f82c5c8a273738dc8c54b1162a716e4c7aaf3fd08741f16dff8a711fd551f7a867a
|
7
|
+
data.tar.gz: dcd91fceaf20c470dd763fecee7bb391c80e8fde538c5b5dbbe70cfbfbdf7424b85f67baed8ecbf88f3234d0ac4422eaf8cb365ec4fd06ce186aedea70dc6ea7
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { createConsumer } from "@rails/actioncable";
|
2
|
-
import debounce from "debounce";
|
2
|
+
import { debounce } from "throttle-debounce";
|
3
3
|
import { log } from "../plugins/logger";
|
4
4
|
|
5
5
|
export default function socket(endpoint) {
|
@@ -8,10 +8,14 @@ export default function socket(endpoint) {
|
|
8
8
|
return {
|
9
9
|
addListener(channel, callback) {
|
10
10
|
consumer.subscriptions.create(channel, {
|
11
|
-
received: debounce(
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
received: debounce(
|
12
|
+
200,
|
13
|
+
(data) => {
|
14
|
+
log.debug("Lookbook files changed");
|
15
|
+
callback(data);
|
16
|
+
},
|
17
|
+
{ atBegin: true }
|
18
|
+
),
|
15
19
|
connected() {
|
16
20
|
log.info("Lookbook websocket connected");
|
17
21
|
},
|
@@ -31,11 +31,19 @@ module Lookbook
|
|
31
31
|
nil
|
32
32
|
end
|
33
33
|
|
34
|
+
def alpine_encode(data)
|
35
|
+
if data.is_a? String
|
36
|
+
"\'#{json_escape data}\'"
|
37
|
+
else
|
38
|
+
json_escape data.to_json.tr("\"", "\'")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
34
42
|
def prepare_alpine_data(x_data = nil)
|
35
43
|
alpine_component_name = x_data || @html_attrs&.dig(:"x-data") || alpine_component
|
36
44
|
if alpine_component_name.present?
|
37
|
-
args = Array.wrap(alpine_data)
|
38
|
-
args.any? ? "#{alpine_component_name}(#{
|
45
|
+
args = Array.wrap(alpine_data).compact
|
46
|
+
args.any? ? "#{alpine_component_name}(#{args.join(",")})" : alpine_component_name
|
39
47
|
end
|
40
48
|
end
|
41
49
|
end
|
@@ -2,15 +2,12 @@ module Lookbook
|
|
2
2
|
class DimensionsDisplay::Component < Lookbook::BaseComponent
|
3
3
|
def initialize(target:, **html_attrs)
|
4
4
|
@target = target
|
5
|
+
@alpine_data = alpine_encode(@target)
|
5
6
|
super(**html_attrs)
|
6
7
|
end
|
7
8
|
|
8
9
|
protected
|
9
10
|
|
10
|
-
def alpine_data
|
11
|
-
@target.to_json
|
12
|
-
end
|
13
|
-
|
14
11
|
def alpine_component
|
15
12
|
"dimensionsDisplayComponent"
|
16
13
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class Icon::Component < Lookbook::BaseComponent
|
3
3
|
def initialize(name:, size: 4, **html_attrs)
|
4
|
-
@
|
4
|
+
@alpine_data = name.is_a?(Symbol) ? alpine_encode(name.to_s.tr("_", "-")) : name
|
5
5
|
@size = size || 4
|
6
6
|
super(**html_attrs)
|
7
7
|
end
|
@@ -12,10 +12,6 @@ module Lookbook
|
|
12
12
|
|
13
13
|
protected
|
14
14
|
|
15
|
-
def alpine_data
|
16
|
-
@icon_name
|
17
|
-
end
|
18
|
-
|
19
15
|
def alpine_component
|
20
16
|
"iconComponent"
|
21
17
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import debounce from "debounce";
|
1
|
+
import { debounce } from "throttle-debounce";
|
2
2
|
import tippy from "~/app/assets/lookbook/js/lib/tippy";
|
3
3
|
import { observeSize } from "@helpers/layout";
|
4
4
|
import { getElementSize } from "@helpers/dom";
|
@@ -49,7 +49,7 @@ export default function tabsComponent(store) {
|
|
49
49
|
|
50
50
|
this.parentObserver = observeSize(
|
51
51
|
this.$root.parentElement,
|
52
|
-
debounce(this.handleResize.bind(this)
|
52
|
+
debounce(10, this.handleResize.bind(this))
|
53
53
|
);
|
54
54
|
|
55
55
|
this.$watch("visibleTabsCount", (value) => {
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
-
|
3
|
+
if respond_to?(:content_security_policy)
|
4
|
+
content_security_policy false, if: -> { Rails.env.development? }
|
5
|
+
end
|
6
|
+
|
4
7
|
protect_from_forgery with: :exception
|
5
8
|
|
6
9
|
helper Lookbook::ApplicationHelper
|
@@ -8,6 +11,7 @@ module Lookbook
|
|
8
11
|
helper Lookbook::ComponentHelper
|
9
12
|
|
10
13
|
before_action :generate_theme_overrides
|
14
|
+
before_action :assign_collections
|
11
15
|
|
12
16
|
def self.controller_path
|
13
17
|
"lookbook"
|
@@ -28,6 +32,11 @@ module Lookbook
|
|
28
32
|
@theme_overrides ||= Lookbook.theme.to_css
|
29
33
|
end
|
30
34
|
|
35
|
+
def assign_collections
|
36
|
+
@previews = Preview.all
|
37
|
+
@pages = Page.all
|
38
|
+
end
|
39
|
+
|
31
40
|
def feature_enabled?(feature)
|
32
41
|
Lookbook::Features.enabled?(feature)
|
33
42
|
end
|
@@ -158,22 +158,25 @@ module Lookbook
|
|
158
158
|
|
159
159
|
def panels
|
160
160
|
return @panels if @panels.present?
|
161
|
-
|
162
|
-
|
161
|
+
inspector_data_hash = inspector_data.to_h
|
162
|
+
panel_counts = {}
|
163
|
+
|
164
|
+
@panels = Lookbook.config.inspector_panels.map do |name, config|
|
163
165
|
config_with_defaults = Lookbook.config.inspector_panel_defaults.merge(config)
|
166
|
+
panel_counts[config_with_defaults[:pane].to_sym] ||= 0
|
167
|
+
panel_counts[config_with_defaults[:pane].to_sym] += 1
|
164
168
|
|
165
169
|
callable_data = {
|
166
170
|
name: name.to_s,
|
167
|
-
index_position:
|
168
|
-
**
|
171
|
+
index_position: panel_counts[config_with_defaults[:pane].to_sym],
|
172
|
+
**inspector_data_hash
|
169
173
|
}
|
170
174
|
|
171
175
|
resolved_config = config_with_defaults.transform_values do |value|
|
172
176
|
value.instance_of?(Proc) ? value.call(Lookbook::Store.new(callable_data)) : value
|
173
177
|
end
|
174
178
|
resolved_config[:name] = name.to_s
|
175
|
-
|
176
|
-
@panels << Lookbook::Store.new(resolved_config, deep: false)
|
179
|
+
Store.new(resolved_config)
|
177
180
|
end
|
178
181
|
|
179
182
|
@panels = @panels.select(&:show).sort_by { |p| [p.position, p.label] }
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% content_for :shell do %>
|
2
|
-
<% if
|
2
|
+
<% if @previews.any? || @pages.any? %>
|
3
3
|
<%= render_component :split_layout,
|
4
4
|
alpine_data: "$store.layout.main",
|
5
5
|
":class": "$store.layout.mobile && '!block'" do |layout| %>
|
@@ -14,14 +14,14 @@
|
|
14
14
|
cloak: true do %>
|
15
15
|
|
16
16
|
<%= render_component :split_layout,
|
17
|
-
alpine_data: "$store.layout.#{
|
17
|
+
alpine_data: "$store.layout.#{@pages.any? && @previews.any? ? "sidebar" : "singleSectionSidebar"}",
|
18
18
|
style: "height: calc(100vh - 2.5rem);" do |layout| %>
|
19
19
|
|
20
|
-
<% if
|
20
|
+
<% if @previews.any? %>
|
21
21
|
<% layout.pane class: "overflow-hidden" do %>
|
22
22
|
<%= render_component :nav,
|
23
23
|
id: "previews-nav",
|
24
|
-
collection:
|
24
|
+
collection: @previews,
|
25
25
|
alpine_data: "$store.nav.previews",
|
26
26
|
collapse_singles: true do |nav| %>
|
27
27
|
<%= nav.toolbar do |toolbar| %>
|
@@ -34,11 +34,11 @@
|
|
34
34
|
<% end %>
|
35
35
|
<% end %>
|
36
36
|
|
37
|
-
<% if
|
37
|
+
<% if @pages.any? %>
|
38
38
|
<% layout.pane class: "overflow-hidden" do %>
|
39
39
|
<%= render_component :nav,
|
40
40
|
id: "pages-nav",
|
41
|
-
collection:
|
41
|
+
collection: @pages,
|
42
42
|
alpine_data: "$store.nav.pages" do |nav| %>
|
43
43
|
<%= nav.toolbar do |toolbar| %>
|
44
44
|
<% toolbar.section padded: true do %>
|
@@ -49,36 +49,6 @@
|
|
49
49
|
<% end %>
|
50
50
|
<% end %>
|
51
51
|
<% end %>
|
52
|
-
|
53
|
-
<% if Lookbook::Preview.errors.any? %>
|
54
|
-
<div x-data="{hidden: false}" class="flex-none border-t border-lookbook-divider absolute bottom-0 left-0 right-0" x-show="!hidden">
|
55
|
-
<%= render_component :toolbar do |toolbar| %>
|
56
|
-
<% toolbar.section padded: true, class: "flex items-center" do %>
|
57
|
-
<%= icon :alert_triangle, size: 4, class: "text-red-700" %>
|
58
|
-
<span class="ml-2">Preview load errors</span>
|
59
|
-
<% end %>
|
60
|
-
<% toolbar.section align: :right do %>
|
61
|
-
<% render_component :button, icon: :x, "@click": "hidden = !hidden" %>
|
62
|
-
<% end %>
|
63
|
-
<% end %>
|
64
|
-
|
65
|
-
<div class="h-full max-h-[300px] overflow-hidden">
|
66
|
-
<div class="bg-red-50 w-full overflow-auto h-full">
|
67
|
-
<ul class="text-sm divide-y divide-red-200">
|
68
|
-
<% Lookbook::Preview.errors.each do |error| %>
|
69
|
-
<% error = error.is_a?(Lookbook::Error) ? error : Lookbook::Error.new(error) %>
|
70
|
-
<li class="px-4 py-3">
|
71
|
-
<h4 class="break-all leading-tight text-xs ">
|
72
|
-
<%= error.file_name %><%= ":#{error.line_number}" if error.line_number %>
|
73
|
-
</h4>
|
74
|
-
<pre class="text-red-800 text-xs mt-2 whitespace-pre-wrap opacity-80 font-mono"><%= error.message %></pre>
|
75
|
-
</li>
|
76
|
-
<% end %>
|
77
|
-
</ul>
|
78
|
-
</div>
|
79
|
-
</div>
|
80
|
-
</div>
|
81
|
-
<% end %>
|
82
52
|
<% end %>
|
83
53
|
|
84
54
|
<% layout.pane id: "app-main", class: "overflow-hidden h-full", ":class": "$store.layout.mobile && 'w-screen'" do %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div id="landing" class="flex flex-col items-center justify-center h-full w-full">
|
2
|
-
<div class="text-center" id="landing-<%=
|
2
|
+
<div class="text-center" id="landing-<%= @previews.any? ? "with" : "no" %>-content">
|
3
3
|
<h5 class="text-base text-lookbook-blank-slate-title truncate uppercase font-black tracking-wider mb-2">
|
4
4
|
<%= config.project_name %>
|
5
5
|
</h5>
|
6
6
|
<div class="opacity-60">
|
7
|
-
<% if
|
7
|
+
<% if @previews.any? %>
|
8
8
|
<p>Select a preview from the nav to get started.</p>
|
9
9
|
<% else %>
|
10
10
|
<p><a class="underline" href="https://lookbook.build/guide/previews" target="_blank">Create a preview</a> to get started.</p>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
|
26
26
|
<% toolbar.section divide: :left, class: "flex-none relative z-10" do %>
|
27
27
|
<%= render_component :button_group do |group| %>
|
28
|
-
<% if
|
28
|
+
<% if @pages.any? %>
|
29
29
|
<% group.button icon: :code,
|
30
30
|
tooltip: "Copy page embed code",
|
31
31
|
copy: true do %>
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Lookbook::Engine.routes.draw do
|
2
2
|
if Lookbook::Engine.websocket?
|
3
|
-
mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path
|
3
|
+
mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path, :as => :cable
|
4
4
|
end
|
5
5
|
|
6
6
|
root to: "application#index", as: :lookbook_home
|
data/lib/lookbook/config.rb
CHANGED
@@ -5,7 +5,7 @@ require "lookbook/store"
|
|
5
5
|
module Lookbook
|
6
6
|
class Config
|
7
7
|
def initialize
|
8
|
-
@options = Store.new
|
8
|
+
@options = Store.new({}, true)
|
9
9
|
|
10
10
|
@options.set({
|
11
11
|
project_name: "Lookbook",
|
@@ -31,10 +31,9 @@ module Lookbook
|
|
31
31
|
listen_extensions: ["rb", "html.*"],
|
32
32
|
listen_use_polling: false,
|
33
33
|
|
34
|
-
cable_mount_path: "/
|
34
|
+
cable_mount_path: "/cable",
|
35
35
|
cable_logger: Lookbook.logger,
|
36
36
|
|
37
|
-
runtime_parsing: !Rails.env.production?,
|
38
37
|
parser_registry_path: "tmp/storage/.yardoc",
|
39
38
|
|
40
39
|
ui_theme: "indigo",
|
@@ -104,6 +103,10 @@ module Lookbook
|
|
104
103
|
})
|
105
104
|
end
|
106
105
|
|
106
|
+
def runtime_parsing=(value)
|
107
|
+
Lookbook.logger.warn "The `runtime_parsing` config option has been deprecated and will be removed in v2.0"
|
108
|
+
end
|
109
|
+
|
107
110
|
def project_name
|
108
111
|
@options.project_name == false ? nil : @options.project_name
|
109
112
|
end
|
@@ -245,7 +248,7 @@ module Lookbook
|
|
245
248
|
full_path = absolute_path(path)
|
246
249
|
full_path if Dir.exist?(full_path)
|
247
250
|
end.compact!
|
248
|
-
paths
|
251
|
+
paths.uniq
|
249
252
|
end
|
250
253
|
|
251
254
|
def absolute_path(path)
|
data/lib/lookbook/data.rb
CHANGED
data/lib/lookbook/engine.rb
CHANGED
@@ -35,7 +35,7 @@ module Lookbook
|
|
35
35
|
{
|
36
36
|
version: version,
|
37
37
|
env: Rails.env.to_s,
|
38
|
-
config: config
|
38
|
+
config: config.to_h
|
39
39
|
}
|
40
40
|
end
|
41
41
|
|
@@ -43,18 +43,10 @@ module Lookbook
|
|
43
43
|
Preview.all
|
44
44
|
end
|
45
45
|
|
46
|
-
def previews?
|
47
|
-
Preview.any?
|
48
|
-
end
|
49
|
-
|
50
46
|
def pages
|
51
47
|
Page.all
|
52
48
|
end
|
53
49
|
|
54
|
-
def pages?
|
55
|
-
Page.any?
|
56
|
-
end
|
57
|
-
|
58
50
|
def broadcast(event_name, data = {})
|
59
51
|
Engine.websocket&.broadcast(event_name.to_s, data)
|
60
52
|
end
|
@@ -99,6 +91,11 @@ module Lookbook
|
|
99
91
|
@preview_controller = Lookbook.config.preview_controller.constantize
|
100
92
|
@preview_controller.include(Lookbook::PreviewController)
|
101
93
|
|
94
|
+
parser.after_parse do |registry|
|
95
|
+
Preview.load!(registry.all(:class))
|
96
|
+
reload_ui
|
97
|
+
end
|
98
|
+
|
102
99
|
if Gem::Version.new(Rails.version) >= Gem::Version.new("6.1.3.1")
|
103
100
|
# Rails.application.server is only available for newer Rails versions
|
104
101
|
Rails.application.server do
|
@@ -111,19 +108,9 @@ module Lookbook
|
|
111
108
|
end
|
112
109
|
end
|
113
110
|
|
114
|
-
|
115
|
-
Lookbook::Engine.
|
116
|
-
else
|
117
|
-
unless File.exist?(config.lookbook.parser_registry_path)
|
118
|
-
Lookbook.logger.warn "
|
119
|
-
Runtime parsing is disabled but no registry file has been found.
|
120
|
-
Did you run `rake lookbook:preparse` before starting the app?
|
121
|
-
Expected to find registry file at #{config.lookbook.parser_registry_path}
|
122
|
-
"
|
123
|
-
end
|
111
|
+
parser.parse do
|
112
|
+
Lookbook::Engine.run_hooks(:after_initialize)
|
124
113
|
end
|
125
|
-
|
126
|
-
Lookbook::Engine.run_hooks(:after_initialize)
|
127
114
|
end
|
128
115
|
|
129
116
|
at_exit do
|
@@ -140,43 +127,42 @@ module Lookbook
|
|
140
127
|
return unless config.listen == true
|
141
128
|
Listen.logger = Lookbook.logger
|
142
129
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
130
|
+
if config.listen_paths.any?
|
131
|
+
preview_listener = Listen.to(
|
132
|
+
*config.listen_paths,
|
133
|
+
only: /\.(#{config.listen_extensions.join("|")})$/,
|
134
|
+
force_polling: config.listen_use_polling
|
135
|
+
) do |modified, added, removed|
|
136
|
+
parser.parse do
|
137
|
+
run_hooks(:after_change, {modified: modified, added: added, removed: removed})
|
138
|
+
end
|
152
139
|
end
|
153
|
-
|
154
|
-
reload_ui(changes)
|
155
|
-
run_hooks(:after_change, changes)
|
140
|
+
register_listener(preview_listener)
|
156
141
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
142
|
+
|
143
|
+
if config.page_paths.any?
|
144
|
+
page_listener = Listen.to(
|
145
|
+
*config.page_paths,
|
146
|
+
only: /\.(html.*|md.*)$/,
|
147
|
+
force_polling: config.listen_use_polling
|
148
|
+
) do |modified, added, removed|
|
149
|
+
changes = {modified: modified, added: added, removed: removed}
|
150
|
+
reload_ui
|
151
|
+
run_hooks(:after_change, changes)
|
152
|
+
end
|
153
|
+
register_listener(page_listener)
|
167
154
|
end
|
168
|
-
register_listener(page_listener)
|
169
155
|
end
|
170
156
|
|
171
157
|
def websocket
|
172
158
|
config = Lookbook.config
|
173
159
|
return @websocket unless @websocket.nil?
|
174
|
-
return unless config.auto_refresh == true
|
160
|
+
return unless config.auto_refresh == true && !Rails.env.test?
|
175
161
|
Lookbook.logger.info "Initializing websocket"
|
176
162
|
|
177
163
|
cable = ActionCable::Server::Configuration.new
|
178
164
|
cable.cable = {adapter: "async"}.with_indifferent_access
|
179
|
-
cable.mount_path =
|
165
|
+
cable.mount_path = nil
|
180
166
|
cable.connection_class = -> { Lookbook::Connection }
|
181
167
|
cable.logger = config.cable_logger
|
182
168
|
|
@@ -202,7 +188,7 @@ module Lookbook
|
|
202
188
|
end
|
203
189
|
|
204
190
|
def parser
|
205
|
-
@parser ||= Lookbook::Parser.new(config.lookbook.preview_paths
|
191
|
+
@parser ||= Lookbook::Parser.new(config.lookbook.preview_paths)
|
206
192
|
end
|
207
193
|
|
208
194
|
def log_level
|
@@ -237,8 +223,8 @@ module Lookbook
|
|
237
223
|
end
|
238
224
|
end
|
239
225
|
|
240
|
-
def reload_ui
|
241
|
-
websocket&.broadcast("reload",
|
226
|
+
def reload_ui
|
227
|
+
websocket&.broadcast("reload", {})
|
242
228
|
end
|
243
229
|
|
244
230
|
def prevent_listening?
|
data/lib/lookbook/parser.rb
CHANGED
@@ -3,24 +3,32 @@ require "yard"
|
|
3
3
|
module Lookbook
|
4
4
|
class Parser
|
5
5
|
attr_reader :registry_path
|
6
|
-
def initialize(paths
|
6
|
+
def initialize(paths)
|
7
7
|
@paths = paths.map { |p| "#{p}/**/*preview.rb" }
|
8
|
-
@
|
9
|
-
|
8
|
+
@after_parse_callbacks = []
|
9
|
+
@after_parse_once_callbacks = []
|
10
|
+
@parsing = false
|
11
|
+
|
12
|
+
YARD::Parser::SourceParser.after_parse_list do
|
13
|
+
[*@after_parse_callbacks, *@after_parse_once_callbacks].each do |callback|
|
14
|
+
callback.call(YARD::Registry)
|
15
|
+
end
|
16
|
+
@after_parse_once_callbacks = []
|
17
|
+
@parsing = false
|
18
|
+
end
|
10
19
|
end
|
11
20
|
|
12
|
-
def parse
|
13
|
-
|
14
|
-
|
21
|
+
def parse(&block)
|
22
|
+
unless @parsing
|
23
|
+
@parsing = true
|
24
|
+
@after_parse_once_callbacks << block if block
|
25
|
+
YARD::Registry.clear
|
15
26
|
YARD.parse(@paths)
|
16
|
-
YARD::Registry.save(false, registry_path)
|
17
27
|
end
|
18
28
|
end
|
19
29
|
|
20
|
-
def
|
21
|
-
|
22
|
-
registry.load!(registry_path)
|
23
|
-
registry.get(path)
|
30
|
+
def after_parse(&block)
|
31
|
+
@after_parse_callbacks << block
|
24
32
|
end
|
25
33
|
|
26
34
|
class << self
|