cani 0.2.2 → 0.3.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/Gemfile.lock +1 -1
- data/lib/cani/api/feature.rb +9 -4
- data/lib/cani/api/feature/viewer.rb +145 -56
- data/lib/cani/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: 1df7e81ecfee9fcb8dde134bf7d3c6db8ae21520c3185b28055bfdefbf2f2f94
|
4
|
+
data.tar.gz: c3c2eb816e5ea8fb0707db1a49c19f5fbdd8ac9122f4e8678713e5a9d184b3d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5ca259ccc81e38e8646feb058863231439831a1fbc1f6adc06d32240286cf19cb68bbccefd0d9b3275f9d05a7d495472c11a7570056fddafb03a51307c8d3a8
|
7
|
+
data.tar.gz: a77833ff65dd10cfe9f71ba665d5979acf7d95dcb45042b0083afd023e979bdaebc98846bcc0a8a54682b54ee0595de4a92b03e4643cc746a2bbac1d06f3115a
|
data/Gemfile.lock
CHANGED
data/lib/cani/api/feature.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cani
|
2
2
|
class Api
|
3
3
|
class Feature
|
4
|
-
attr_reader :title, :status, :spec, :stats, :percent, :name
|
4
|
+
attr_reader :title, :status, :spec, :stats, :percent, :name, :browser_note_nums, :notes, :notes_by_num
|
5
5
|
|
6
6
|
STATUSES = {
|
7
7
|
'rec' => 'rc',
|
@@ -25,9 +25,14 @@ module Cani
|
|
25
25
|
@status = STATUSES.fetch attributes['status'], attributes['status']
|
26
26
|
@spec = attributes['spec']
|
27
27
|
@percent = attributes['usage_perc_y']
|
28
|
-
@
|
29
|
-
|
30
|
-
|
28
|
+
@notes = attributes['notes'].split "\n"
|
29
|
+
@notes_by_num = attributes['notes_by_num']
|
30
|
+
@stats, @browser_note_nums = attributes['stats'].each_with_object([{}, {}]) do |(browser, info), (stts, notes)|
|
31
|
+
stts[browser], notes[browser] = info.each_with_object([{}, {}]) do |(version, stat), (st, nt)|
|
32
|
+
version.split('-').each do |v|
|
33
|
+
nt[v] = stat.scan(/#(\d+)/).flatten
|
34
|
+
st[v] = stat[' d '] ? 'd' : stat[0]
|
35
|
+
end
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
@@ -7,31 +7,43 @@ module Cani
|
|
7
7
|
COLOR_PAIRS = {
|
8
8
|
# foreground colors
|
9
9
|
69 => [70, -1], # green on default (legend supported, feature status, percentage counter)
|
10
|
-
213 => [
|
11
|
-
195 => [
|
12
|
-
133 => [
|
10
|
+
213 => [208, -1], # orange on default (legend partial, percentage counter)
|
11
|
+
195 => [160, -1], # red on default (legend unsupported, percentage counter)
|
12
|
+
133 => [134, -1], # magenta on default (legend flag, current feature status)
|
13
13
|
12 => [75, -1], # blue on default (legend prefix)
|
14
14
|
204 => [205, -1], # pink on default (legend polyfill)
|
15
|
-
99 => [
|
15
|
+
99 => [239, -1], # gray on default (legend unknown)
|
16
16
|
|
17
|
+
# note background + foreground colors
|
18
|
+
71 => [22, 70], # dark green on green (supported feature)
|
19
|
+
209 => [130, 208], # dark orange on orange (partial feature)
|
20
|
+
197 => [88, 160], # dark red on red (unsupported feature)
|
21
|
+
135 => [91, 134], # dark magenta on magenta (flag features)
|
22
|
+
13 => [27, 75], # dark blue on blue (prefix feature)
|
23
|
+
101 => [235, 239], # dark gray on gray (unknown features)
|
24
|
+
206 => [127, 205], # dark pink on pink (polyfill features)
|
17
25
|
|
18
26
|
# background colors
|
19
27
|
70 => [7, 70], # white on green (supported feature)
|
20
|
-
208 => [7,
|
21
|
-
196 => [7,
|
22
|
-
134 => [7,
|
28
|
+
208 => [7, 208], # white on orange (partial feature)
|
29
|
+
196 => [7, 160], # white on red (unsupported feature)
|
30
|
+
134 => [7, 134], # white on magenta (flag features)
|
23
31
|
11 => [7, 75], # white on blue (prefix feature)
|
24
|
-
100 => [7,
|
32
|
+
100 => [7, 239], # white on gray (unknown features)
|
25
33
|
205 => [7, 205], # white on pink (polyfill features)
|
26
34
|
|
27
35
|
# misc / one-off
|
28
36
|
254 => [238, 255], # black on light gray (browser names, legend title)
|
37
|
+
239 => [232, 236]
|
29
38
|
}.freeze
|
30
39
|
|
31
40
|
COLORS = {
|
32
41
|
# table headers
|
33
42
|
header: {fg: Curses.color_pair(254), bg: Curses.color_pair(254)},
|
34
43
|
|
44
|
+
# current era border
|
45
|
+
era_border: {fg: Curses.color_pair(239), bg: Curses.color_pair(239)},
|
46
|
+
|
35
47
|
# support types
|
36
48
|
default: {fg: Curses.color_pair(69), bg: Curses.color_pair(70)},
|
37
49
|
partial: {fg: Curses.color_pair(213), bg: Curses.color_pair(208)},
|
@@ -46,6 +58,16 @@ module Cani
|
|
46
58
|
ot: {fg: Curses.color_pair(133), bg: Curses.color_pair(134)}
|
47
59
|
}.freeze
|
48
60
|
|
61
|
+
NOTE_COLORS = {
|
62
|
+
default: {fg: Curses.color_pair(71), bg: Curses.color_pair(70)},
|
63
|
+
partial: {fg: Curses.color_pair(209), bg: Curses.color_pair(208)},
|
64
|
+
prefix: {fg: Curses.color_pair(13), bg: Curses.color_pair(11)},
|
65
|
+
polyfill: {fg: Curses.color_pair(206), bg: Curses.color_pair(205)},
|
66
|
+
flag: {fg: Curses.color_pair(135), bg: Curses.color_pair(134)},
|
67
|
+
unsupported: {fg: Curses.color_pair(197), bg: Curses.color_pair(196)},
|
68
|
+
unknown: {fg: Curses.color_pair(101), bg: Curses.color_pair(100)},
|
69
|
+
}
|
70
|
+
|
49
71
|
PERCENT_COLORS = {
|
50
72
|
70..101 => {fg: Curses.color_pair(69), bg: Curses.color_pair(70)},
|
51
73
|
40..70 => {fg: Curses.color_pair(213), bg: Curses.color_pair(208)},
|
@@ -67,7 +89,6 @@ module Cani
|
|
67
89
|
Curses.init_screen
|
68
90
|
Curses.curs_set 0
|
69
91
|
Curses.noecho
|
70
|
-
Curses.cbreak
|
71
92
|
|
72
93
|
if Curses.has_colors?
|
73
94
|
Curses.use_default_colors
|
@@ -93,14 +114,10 @@ module Cani
|
|
93
114
|
status_format = "[#{feature.status}]"
|
94
115
|
percent_label = compact? ? '' : 'support: '
|
95
116
|
legend_format = 'legend'.center table_width
|
117
|
+
notes_format = 'notes'.center table_width
|
96
118
|
|
97
|
-
title_size = [table_width - percent_num.size - percent_label.size - status_format.size - 3, 1].max
|
98
|
-
title_size += status_format.size if compact?
|
99
|
-
title_chunks = feature.title.chars.each_slice(title_size).map { |chrs| chrs.compact.join }
|
100
|
-
|
101
|
-
type_count = Feature::TYPES.keys.size
|
102
119
|
offset_x = ((width - table_width) / 2.0).floor
|
103
|
-
offset_y =
|
120
|
+
offset_y = 1
|
104
121
|
cy = 0
|
105
122
|
|
106
123
|
# positioning and drawing of percentage
|
@@ -119,6 +136,10 @@ module Cani
|
|
119
136
|
end
|
120
137
|
|
121
138
|
# draw possibly multi-line feature title
|
139
|
+
title_size = [table_width - percent_num.size - percent_label.size - status_format.size - 3, 1].max
|
140
|
+
title_size += status_format.size if compact?
|
141
|
+
title_chunks = feature.title.chars.each_slice(title_size).map(&:join)
|
142
|
+
|
122
143
|
title_chunks.each do |part|
|
123
144
|
Curses.setpos offset_y + cy, offset_x
|
124
145
|
Curses.addstr part
|
@@ -138,6 +159,8 @@ module Cani
|
|
138
159
|
Curses.addstr status_format
|
139
160
|
end
|
140
161
|
|
162
|
+
compact_height = height <= 40
|
163
|
+
|
141
164
|
# meaty part, loop through browsers to create
|
142
165
|
# the final feature table
|
143
166
|
browsers[0...viewable].each.with_index do |browser, x|
|
@@ -156,39 +179,51 @@ module Cani
|
|
156
179
|
|
157
180
|
# accordingly increment current browser y for the table header (browser names)
|
158
181
|
# and an additional empty line below the table header
|
159
|
-
by +=
|
182
|
+
by += 3
|
160
183
|
|
161
184
|
# draw era's for the current browser
|
162
185
|
era_range.each.with_index do |cur_era, y|
|
163
|
-
era
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
186
|
+
era = browser.eras[cur_era].to_s
|
187
|
+
supp_type = feature.support_in(browser.name, era)
|
188
|
+
colr = color supp_type
|
189
|
+
is_current = cur_era == era_idx
|
190
|
+
past_curr = cur_era > era_idx
|
191
|
+
top_pad = 1
|
192
|
+
bot_pad = compact_height ? 0 : 1
|
193
|
+
ey = by + (y * (2 + top_pad + bot_pad)) + (bot_pad.zero? && past_curr ? 1 : 0)
|
194
|
+
note_nums = feature.browser_note_nums.fetch(browser.name, {})
|
195
|
+
.fetch(era, [])
|
196
|
+
|
197
|
+
if is_current
|
198
|
+
Curses.setpos ey - top_pad - 1, bx - 1
|
199
|
+
Curses.attron(color(:era_border)) { Curses.addstr ' ' * (col_width + 2) }
|
200
|
+
|
201
|
+
Curses.setpos ey + (is_current ? 1 : bot_pad) + 1, bx - 1
|
202
|
+
Curses.attron(color(:era_border)) { Curses.addstr ' ' * (col_width + 2) }
|
203
|
+
end
|
172
204
|
|
173
|
-
# only show relevant browsers
|
205
|
+
# only show visible / relevant browsers
|
174
206
|
if browser.usage[era].to_i >= 0.5 || (!era.empty? && cur_era >= era_idx)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
207
|
+
((ey - top_pad)..(ey + (is_current ? 1 : bot_pad))).each do |ry|
|
208
|
+
txt = (bot_pad.zero? && !is_current) ? (ry >= ey + (is_current ? 1 : bot_pad) ? era.to_s : ' ')
|
209
|
+
: (ry == ey ? era.to_s : ' ')
|
210
|
+
|
211
|
+
Curses.setpos ry, bx
|
212
|
+
Curses.attron(colr) { Curses.addstr txt.center(col_width) }
|
213
|
+
|
214
|
+
if is_current
|
215
|
+
Curses.setpos ry, bx - 1
|
216
|
+
Curses.attron(color(:era_border)) { Curses.addstr ' ' }
|
179
217
|
|
180
|
-
|
181
|
-
|
182
|
-
# this snippet fills the line before and after the current era
|
183
|
-
# with the same color that the era has for that browser / feature
|
184
|
-
if cur_era == era_idx
|
185
|
-
[-1, 1].each do |relative_y|
|
186
|
-
Curses.setpos ey - relative_y, bx
|
187
|
-
Curses.attron colr do
|
188
|
-
Curses.addstr ' ' * col_width
|
189
|
-
end
|
218
|
+
Curses.setpos ry, offset_x + table_width + 2
|
219
|
+
Curses.attron(color(:era_border)) { Curses.addstr ' ' }
|
190
220
|
end
|
191
221
|
end
|
222
|
+
|
223
|
+
if note_nums.any?
|
224
|
+
Curses.setpos ey - top_pad, bx
|
225
|
+
Curses.attron(note_color(supp_type)) { Curses.addstr ' ' + note_nums.join(' ') }
|
226
|
+
end
|
192
227
|
end
|
193
228
|
end
|
194
229
|
end
|
@@ -197,12 +232,14 @@ module Cani
|
|
197
232
|
# plus the 4 lines around the current era
|
198
233
|
# plus the 1 line of browser names
|
199
234
|
# plus the 2 blank lines above and below the eras
|
200
|
-
cy += ERAS +
|
235
|
+
cy += (ERAS - 1) * (compact_height ? 3 : 4) + ERAS
|
201
236
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
Curses.
|
237
|
+
if height > cy + 3
|
238
|
+
# print legend header
|
239
|
+
Curses.setpos offset_y + cy, offset_x
|
240
|
+
Curses.attron color(:header) do
|
241
|
+
Curses.addstr legend_format
|
242
|
+
end
|
206
243
|
end
|
207
244
|
|
208
245
|
# increment current y by 2
|
@@ -212,16 +249,64 @@ module Cani
|
|
212
249
|
|
213
250
|
# loop through all features to create a legend
|
214
251
|
# showing which label belongs to which color
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
Curses.
|
252
|
+
if height > cy + 1
|
253
|
+
Feature::TYPES.values.each_slice viewable do |group|
|
254
|
+
group.compact.each.with_index do |type, lx|
|
255
|
+
Curses.setpos offset_y + cy, offset_x + lx * col_width + lx
|
256
|
+
Curses.attron color(type[:name], :fg) do
|
257
|
+
Curses.addstr "#{type[:short]}(#{type[:symbol]})".center(col_width)
|
258
|
+
end
|
220
259
|
end
|
260
|
+
|
261
|
+
# if there is more than one group, print the next
|
262
|
+
# group on a new line
|
263
|
+
cy += 1
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# add extra empty line after legend
|
268
|
+
cy += 1
|
269
|
+
|
270
|
+
notes_chunked = feature.notes.map { |nt| nt.chars.each_slice(table_width).map(&:join).map(&:strip) }
|
271
|
+
num_chunked = feature.notes_by_num.each_with_object({}) { |(k, nt), h| h[k] = nt.chars.each_slice(table_width - 5).map(&:join).map(&:strip) }
|
272
|
+
notes_total = notes_chunked.map(&:size).sum + num_chunked.map(&:size).sum
|
273
|
+
|
274
|
+
if height > cy + 2 && (notes_chunked.any? || num_chunked.any?)
|
275
|
+
# print notes header
|
276
|
+
Curses.setpos offset_y + cy, offset_x
|
277
|
+
Curses.attron color(:header) do
|
278
|
+
Curses.addstr notes_format
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
# add two new lines, one for the notes header
|
283
|
+
# and one empty line below it
|
284
|
+
cy += 2
|
285
|
+
|
286
|
+
notes_chunked.each do |chunks|
|
287
|
+
break if cy + 1 + chunks.size > height
|
288
|
+
chunks.each do |part|
|
289
|
+
Curses.setpos offset_y + cy, offset_x
|
290
|
+
Curses.addstr part
|
291
|
+
cy += 1
|
292
|
+
end
|
293
|
+
|
294
|
+
cy += 1
|
295
|
+
end
|
296
|
+
|
297
|
+
num_chunked.each do |num, chunks|
|
298
|
+
break if cy + 1 + chunks.size > height
|
299
|
+
Curses.setpos offset_y + cy, offset_x
|
300
|
+
Curses.attron color(:header) do
|
301
|
+
Curses.addstr num.center(3)
|
302
|
+
end
|
303
|
+
|
304
|
+
chunks.each do |part|
|
305
|
+
Curses.setpos offset_y + cy, offset_x + 5
|
306
|
+
Curses.addstr part
|
307
|
+
cy += 1
|
221
308
|
end
|
222
309
|
|
223
|
-
# if there is more than one group, print the next
|
224
|
-
# group on a new line
|
225
310
|
cy += 1
|
226
311
|
end
|
227
312
|
|
@@ -262,20 +347,24 @@ module Cani
|
|
262
347
|
end
|
263
348
|
|
264
349
|
@col_width = [colw, Feature::TYPES.map { |(_, h)| h[:short].size }.max + 3].max
|
265
|
-
@table_width = tablew
|
350
|
+
@table_width = tablew - 2 # vertical padding at start and end of current era line
|
266
351
|
end
|
267
352
|
|
268
353
|
def compact?
|
269
354
|
width < COMPACT
|
270
355
|
end
|
271
356
|
|
272
|
-
def color(key, type = :bg)
|
357
|
+
def color(key, type = :bg, source = COLORS)
|
273
358
|
target = key.to_s.downcase.to_sym
|
274
359
|
type = type.to_sym
|
275
360
|
|
276
|
-
|
361
|
+
source.find { |(k, _)| k == target }.to_a
|
277
362
|
.fetch(1, {})
|
278
|
-
.fetch(type,
|
363
|
+
.fetch(type, source[:default][type])
|
364
|
+
end
|
365
|
+
|
366
|
+
def note_color(status)
|
367
|
+
color status, :fg, NOTE_COLORS
|
279
368
|
end
|
280
369
|
|
281
370
|
def status_color(status)
|
data/lib/cani/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cani
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sidney Liebrand
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|