dial 0.5.2 → 0.6.0
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/CHANGELOG.md +5 -0
- data/README.md +2 -1
- data/lib/dial/configuration.rb +1 -0
- data/lib/dial/constants.rb +1 -0
- data/lib/dial/engine/routes.rb +30 -32
- data/lib/dial/middleware/panel.rb +84 -1
- data/lib/dial/version.rb +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: d3b2e0414c826c6c8e7237a5b1033b102ee9079491e1d2863db6ffb961a3fda2
|
|
4
|
+
data.tar.gz: 859585a4e0bcf37eb6c36c2f71e1d16cad9e351c4435cc91981c9254704d21bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dd66117fe0e8c2fcfac7dacb5348cda5eee119e8f199ead4a5161a5af024e52c50f52765dcdcb0804fcbbd53c061d4f9073287322d0146300f7508d82c9c6823
|
|
7
|
+
data.tar.gz: 6bad07093895c0e2c4d09fd53afecce8d344f189d07eb576d29202ba308009f67eff06a1263ac8d27c2587ca3d3c46f650ffafc499761d56d3f2a092d396d402
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -32,7 +32,7 @@ bundle install
|
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
34
|
# this will mount the engine at /dial
|
|
35
|
-
mount Dial::Engine, at: "/"
|
|
35
|
+
mount Dial::Engine, at: "/dial"
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
4. (Optional) Configure the gem in an initializer:
|
|
@@ -66,6 +66,7 @@ Option | Description | Default
|
|
|
66
66
|
`storage` | Storage adapter class for profile data. | `Dial::Storage::FileAdapter`
|
|
67
67
|
`storage_options` | Options hash passed to storage adapter. | `{ ttl: 3600 }`
|
|
68
68
|
`content_security_policy_nonce` | Sets the content security policy nonce to use when inserting Dial's script. Can be a string, or a Proc which receives `env` and response `headers` as arguments and returns the nonce string. | Rails generated nonce or `nil`
|
|
69
|
+
`toggle_shortcut_keys` | Array of keys for keyboard shortcut to toggle panel visibility. | `["Alt", "Shift", "D"]`
|
|
69
70
|
`vernier_interval` | Sets the `interval` option for vernier. | `200`
|
|
70
71
|
`vernier_allocation_interval` | Sets the `allocation_interval` option for vernier. | `2_000`
|
|
71
72
|
`prosopite_ignore_queries` | Sets the `ignore_queries` option for prosopite. | `[/schema_migrations/i]`
|
data/lib/dial/configuration.rb
CHANGED
|
@@ -18,6 +18,7 @@ module Dial
|
|
|
18
18
|
storage: Storage::FileAdapter,
|
|
19
19
|
storage_options: { ttl: STORAGE_TTL },
|
|
20
20
|
content_security_policy_nonce: -> env, _headers { env[NONCE] || EMPTY_NONCE },
|
|
21
|
+
toggle_shortcut_keys: TOGGLE_SHORTCUT_KEYS,
|
|
21
22
|
vernier_interval: VERNIER_INTERVAL,
|
|
22
23
|
vernier_allocation_interval: VERNIER_ALLOCATION_INTERVAL,
|
|
23
24
|
prosopite_ignore_queries: PROSOPITE_IGNORE_QUERIES,
|
data/lib/dial/constants.rb
CHANGED
data/lib/dial/engine/routes.rb
CHANGED
|
@@ -3,41 +3,39 @@
|
|
|
3
3
|
require "uri"
|
|
4
4
|
|
|
5
5
|
Dial::Engine.routes.draw do
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
end
|
|
6
|
+
get "/profile", to: lambda { |env|
|
|
7
|
+
query_params = URI.decode_www_form(env[::Rack::QUERY_STRING]).to_h
|
|
8
|
+
profile_key = query_params["key"]
|
|
9
|
+
unless profile_key && profile_key.match?(/\A[0-9a-f-]+_vernier\z/i)
|
|
10
|
+
return [
|
|
11
|
+
400,
|
|
12
|
+
{ "Content-Type" => "text/plain" },
|
|
13
|
+
["Bad Request"]
|
|
14
|
+
]
|
|
15
|
+
end
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
[
|
|
29
|
-
404,
|
|
30
|
-
{ "Content-Type" => "text/plain" },
|
|
31
|
-
["Not Found"]
|
|
32
|
-
]
|
|
33
|
-
end
|
|
34
|
-
rescue
|
|
17
|
+
profile_storage_key = Dial::Storage.profile_storage_key profile_key
|
|
18
|
+
begin
|
|
19
|
+
content = Dial::Storage.fetch profile_storage_key
|
|
20
|
+
if content
|
|
21
|
+
[
|
|
22
|
+
200,
|
|
23
|
+
{ "Content-Type" => "application/json", "Access-Control-Allow-Origin" => Dial::VERNIER_VIEWER_URL },
|
|
24
|
+
[content]
|
|
25
|
+
]
|
|
26
|
+
else
|
|
35
27
|
[
|
|
36
|
-
|
|
28
|
+
404,
|
|
37
29
|
{ "Content-Type" => "text/plain" },
|
|
38
|
-
["
|
|
30
|
+
["Not Found"]
|
|
39
31
|
]
|
|
40
32
|
end
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
rescue
|
|
34
|
+
[
|
|
35
|
+
500,
|
|
36
|
+
{ "Content-Type" => "text/plain" },
|
|
37
|
+
["Internal Server Error"]
|
|
38
|
+
]
|
|
39
|
+
end
|
|
40
|
+
}
|
|
43
41
|
end
|
|
@@ -71,6 +71,8 @@ module Dial
|
|
|
71
71
|
</div>
|
|
72
72
|
</div>
|
|
73
73
|
|
|
74
|
+
<div id="dial-hidden-indicator">Dial</div>
|
|
75
|
+
|
|
74
76
|
<script nonce="#{configured_nonce env, headers}">
|
|
75
77
|
#{script}
|
|
76
78
|
</script>
|
|
@@ -149,19 +151,80 @@ module Dial
|
|
|
149
151
|
color: black;
|
|
150
152
|
}
|
|
151
153
|
}
|
|
154
|
+
|
|
155
|
+
#dial-hidden-indicator {
|
|
156
|
+
all: initial;
|
|
157
|
+
position: fixed;
|
|
158
|
+
bottom: 0.5rem;
|
|
159
|
+
right: 0.5rem;
|
|
160
|
+
z-index: 9999;
|
|
161
|
+
background-color: white;
|
|
162
|
+
color: black;
|
|
163
|
+
padding: 0.25rem 0.5rem;
|
|
164
|
+
border-radius: 0.25rem;
|
|
165
|
+
font-size: 0.75rem;
|
|
166
|
+
cursor: pointer;
|
|
167
|
+
display: none;
|
|
168
|
+
box-shadow: -0.2rem -0.2rem 0.4rem rgba(0, 0, 0, 0.5);
|
|
169
|
+
}
|
|
152
170
|
CSS
|
|
153
171
|
end
|
|
154
172
|
|
|
155
173
|
def script
|
|
174
|
+
shortcut_keys = Dial._configuration.toggle_shortcut_keys
|
|
175
|
+
|
|
156
176
|
<<~JS
|
|
177
|
+
var dialPanel = document.getElementById("dial");
|
|
157
178
|
var dialPreview = document.getElementById("dial-preview");
|
|
158
179
|
var dialDetails = document.getElementById("dial-details");
|
|
180
|
+
var dialHiddenIndicator = document.getElementById("dial-hidden-indicator");
|
|
181
|
+
|
|
182
|
+
function getDialHiddenState() {
|
|
183
|
+
var stored = localStorage.getItem("dial_panel_hidden");
|
|
184
|
+
if (!stored) return false;
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
var data = JSON.parse(stored);
|
|
188
|
+
var expiresAt = new Date(data.expiresAt);
|
|
189
|
+
if (new Date() > expiresAt) {
|
|
190
|
+
localStorage.removeItem("dial_panel_hidden");
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return data.hidden;
|
|
194
|
+
} catch (e) {
|
|
195
|
+
localStorage.removeItem("dial_panel_hidden");
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function setDialHiddenState(hidden) {
|
|
201
|
+
var expiresAt = new Date();
|
|
202
|
+
expiresAt.setTime(expiresAt.getTime() + (24 * 60 * 60 * 1000));
|
|
203
|
+
localStorage.setItem("dial_panel_hidden", JSON.stringify({
|
|
204
|
+
hidden: hidden,
|
|
205
|
+
expiresAt: expiresAt.toISOString()
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function toggleDialPanel() {
|
|
210
|
+
var isHidden = dialPanel.style.display === "none";
|
|
211
|
+
dialPanel.style.display = isHidden ? "flex" : "none";
|
|
212
|
+
dialHiddenIndicator.style.display = isHidden ? "none" : "block";
|
|
213
|
+
setDialHiddenState(!isHidden);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (getDialHiddenState()) {
|
|
217
|
+
dialPanel.style.display = "none";
|
|
218
|
+
dialHiddenIndicator.style.display = "block";
|
|
219
|
+
}
|
|
159
220
|
|
|
160
221
|
dialPreview.addEventListener("click", () => {
|
|
161
222
|
var isCollapsed = ["", "none"].includes(dialDetails.style.display);
|
|
162
223
|
dialDetails.style.display = isCollapsed ? "block" : "none";
|
|
163
224
|
});
|
|
164
225
|
|
|
226
|
+
dialHiddenIndicator.addEventListener("click", toggleDialPanel);
|
|
227
|
+
|
|
165
228
|
document.addEventListener("click", (event) => {
|
|
166
229
|
if (!dialPreview.contains(event.target) && !dialDetails.contains(event.target)) {
|
|
167
230
|
dialDetails.style.display = "none";
|
|
@@ -172,6 +235,26 @@ module Dial
|
|
|
172
235
|
});
|
|
173
236
|
}
|
|
174
237
|
});
|
|
238
|
+
|
|
239
|
+
document.addEventListener("keydown", (event) => {
|
|
240
|
+
var keys = #{shortcut_keys.to_json};
|
|
241
|
+
var expectedKey = keys[keys.length - 1].toLowerCase();
|
|
242
|
+
var keyPressed = event.code.toLowerCase() === "key" + expectedKey || event.key.toLowerCase() === expectedKey;
|
|
243
|
+
var modifiersMatch = true;
|
|
244
|
+
|
|
245
|
+
for (var i = 0; i < keys.length - 1; i++) {
|
|
246
|
+
var modifier = keys[i].toLowerCase();
|
|
247
|
+
if (modifier === "alt" && !event.altKey) modifiersMatch = false;
|
|
248
|
+
if (modifier === "ctrl" && !event.ctrlKey) modifiersMatch = false;
|
|
249
|
+
if (modifier === "shift" && !event.shiftKey) modifiersMatch = false;
|
|
250
|
+
if (modifier === "meta" && !event.metaKey) modifiersMatch = false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (keyPressed && modifiersMatch) {
|
|
254
|
+
event.preventDefault();
|
|
255
|
+
toggleDialPanel();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
175
258
|
JS
|
|
176
259
|
end
|
|
177
260
|
|
|
@@ -192,7 +275,7 @@ module Dial
|
|
|
192
275
|
def formatted_profile_output env, profile_key
|
|
193
276
|
url_base = ::Rails.application.routes.url_helpers.dial_url host: env[::Rack::HTTP_HOST]
|
|
194
277
|
prefix = "/" unless url_base.end_with? "/"
|
|
195
|
-
profile_out_url = URI.encode_www_form_component url_base + "#{prefix}
|
|
278
|
+
profile_out_url = URI.encode_www_form_component url_base + "#{prefix}profile?key=#{profile_key}"
|
|
196
279
|
|
|
197
280
|
"<a href='https://vernier.prof/from-url/#{profile_out_url}' target='_blank'>View profile</a>"
|
|
198
281
|
end
|
data/lib/dial/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dial
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Young
|
|
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
144
|
version: '0'
|
|
145
145
|
requirements: []
|
|
146
|
-
rubygems_version:
|
|
146
|
+
rubygems_version: 4.0.0.dev
|
|
147
147
|
specification_version: 4
|
|
148
148
|
summary: A modern profiler for your Rails application
|
|
149
149
|
test_files: []
|