brrowser 0.1.4 → 0.1.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/bin/brrowser +37 -5
- data/lib/brrowser/renderer.rb +33 -14
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1502511b56f9175cb771635ca305bad614c6230d342c85b44205f4de29a79cc3
|
|
4
|
+
data.tar.gz: ec1f738931d99d5783b9a0e45f4085b785a3a70c3c6efb11cfd63da3f7b06d5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 737df9f08305e342142bcefa5e6a80a30dc060998fc91f3f71fbfd623167e17ec3b8f0021d9c24189fd27d7c088fb998d89b474f81b9e6ee0c2a7649b5290466
|
|
7
|
+
data.tar.gz: 24ecf86ab13aaadabd05eacecbfeeeda13dedafd05c77eacf11b5406428918b36d65065e6ecfd3f179c23bb0f134157cbc1f8d060754f03326987fb19821409a
|
data/bin/brrowser
CHANGED
|
@@ -457,7 +457,7 @@ module Brrowser
|
|
|
457
457
|
label = tab.title.to_s.empty? ? "New Tab" : tab.title.to_s
|
|
458
458
|
label = label[0..20] + "..." if label.length > 23
|
|
459
459
|
if i == @current_tab
|
|
460
|
-
" #{label} ".fg(220).
|
|
460
|
+
" #{label} ".fg(220).bd
|
|
461
461
|
else
|
|
462
462
|
" #{label} ".fg(245)
|
|
463
463
|
end
|
|
@@ -609,6 +609,22 @@ module Brrowser
|
|
|
609
609
|
response = @fetcher.fetch(src)
|
|
610
610
|
next if response[:status] != 200
|
|
611
611
|
ct = response[:content_type].to_s
|
|
612
|
+
# Handle oEmbed JSON responses (e.g. YouTube playlists)
|
|
613
|
+
if ct.match?(/json/) && src.include?("oembed")
|
|
614
|
+
begin
|
|
615
|
+
data = JSON.parse(response[:body])
|
|
616
|
+
thumb = data["thumbnail_url"]
|
|
617
|
+
next unless thumb
|
|
618
|
+
response = @fetcher.fetch(thumb)
|
|
619
|
+
next if response[:status] != 200
|
|
620
|
+
ct = response[:content_type].to_s
|
|
621
|
+
ext = File.extname(URI.parse(thumb).path)[0..5]
|
|
622
|
+
ext = ".jpg" if ext.empty?
|
|
623
|
+
local = File.join(@img_dir, "#{Digest::MD5.hexdigest(src)}#{ext}")
|
|
624
|
+
rescue
|
|
625
|
+
next
|
|
626
|
+
end
|
|
627
|
+
end
|
|
612
628
|
next unless ct.match?(/image/) || src.match?(/\.(png|jpe?g|gif|bmp|webp|svg|ico)/i)
|
|
613
629
|
File.binwrite(local, response[:body])
|
|
614
630
|
if src.match?(/\.svg/i) || ct.include?("svg")
|
|
@@ -816,9 +832,25 @@ module Brrowser
|
|
|
816
832
|
lines[@highlighted_line] = lines[@highlighted_line]
|
|
817
833
|
.gsub("\e[7m", "").gsub("\e[27m", "")
|
|
818
834
|
end
|
|
819
|
-
# Highlight
|
|
835
|
+
# Highlight the specific element (not the whole line)
|
|
820
836
|
if elem[:line] < lines.length
|
|
821
|
-
|
|
837
|
+
line = lines[elem[:line]]
|
|
838
|
+
highlighted = false
|
|
839
|
+
if elem[:type] == :link
|
|
840
|
+
link_text = Regexp.escape(elem[:data][:text])
|
|
841
|
+
idx = Regexp.escape("[#{elem[:data][:index]}]")
|
|
842
|
+
# Match the ANSI-wrapped link text + label as rendered:
|
|
843
|
+
# text.fg(81).ul => \e[4m\e[38;5;81m...text...\e[39m\e[24m
|
|
844
|
+
# "[N]".fg(39) => \e[38;5;39m[N]\e[39m
|
|
845
|
+
re = /(\e\[4m\e\[38;5;81m#{link_text}\e\[39m\e\[24m\e\[38;5;39m#{idx}\e\[39m)/
|
|
846
|
+
if line.match?(re)
|
|
847
|
+
lines[elem[:line]] = line.sub(re, "\e[7m\\1\e[27m")
|
|
848
|
+
highlighted = true
|
|
849
|
+
end
|
|
850
|
+
end
|
|
851
|
+
unless highlighted
|
|
852
|
+
lines[elem[:line]] = "\e[7m#{line}\e[27m"
|
|
853
|
+
end
|
|
822
854
|
@highlighted_line = elem[:line]
|
|
823
855
|
end
|
|
824
856
|
current_tab.content = lines.join("\n")
|
|
@@ -1732,7 +1764,7 @@ module Brrowser
|
|
|
1732
1764
|
sel = 0
|
|
1733
1765
|
|
|
1734
1766
|
build = lambda do
|
|
1735
|
-
lines = [" brrowser Preferences".
|
|
1767
|
+
lines = [" brrowser Preferences".bd]
|
|
1736
1768
|
lines << " h/l:change H/L:+/-10 Enter:edit ESC:close".fg(245)
|
|
1737
1769
|
lines << ""
|
|
1738
1770
|
PREF_SETTINGS.each_with_index do |(label, key, type), i|
|
|
@@ -1745,7 +1777,7 @@ module Brrowser
|
|
|
1745
1777
|
end
|
|
1746
1778
|
prefix = i == sel ? " \u25b6 ".fg(220) : " "
|
|
1747
1779
|
line = "#{prefix}#{label.ljust(18)} \u25c4 #{disp.to_s.ljust(14)} \u25b6"
|
|
1748
|
-
line = line.
|
|
1780
|
+
line = line.rv if i == sel
|
|
1749
1781
|
lines << line
|
|
1750
1782
|
end
|
|
1751
1783
|
popup.text = lines.join("\n")
|
data/lib/brrowser/renderer.rb
CHANGED
|
@@ -103,24 +103,24 @@ module Brrowser
|
|
|
103
103
|
when "h1"
|
|
104
104
|
ensure_blank_line
|
|
105
105
|
text = collect_text(node)
|
|
106
|
-
@line << text.
|
|
106
|
+
@line << text.bd.fg(220)
|
|
107
107
|
flush_line
|
|
108
108
|
@line << ("═" * [text.gsub(ANSI_RE, "").length, @width].min).fg(220)
|
|
109
109
|
flush_line
|
|
110
110
|
ensure_blank_line
|
|
111
111
|
when "h2"
|
|
112
112
|
ensure_blank_line
|
|
113
|
-
inline_walk(node, :
|
|
113
|
+
inline_walk(node, :bd, 214)
|
|
114
114
|
flush_line
|
|
115
115
|
ensure_blank_line
|
|
116
116
|
when "h3"
|
|
117
117
|
ensure_blank_line
|
|
118
|
-
inline_walk(node, :
|
|
118
|
+
inline_walk(node, :bd, 208)
|
|
119
119
|
flush_line
|
|
120
120
|
ensure_blank_line
|
|
121
121
|
when "h4", "h5", "h6"
|
|
122
122
|
ensure_blank_line
|
|
123
|
-
inline_walk(node, :
|
|
123
|
+
inline_walk(node, :bd, 252)
|
|
124
124
|
flush_line
|
|
125
125
|
ensure_blank_line
|
|
126
126
|
when "p", "div", "section", "article", "aside", "main",
|
|
@@ -187,7 +187,7 @@ module Brrowser
|
|
|
187
187
|
ensure_blank_line
|
|
188
188
|
when "dt"
|
|
189
189
|
flush_line if @col > 0
|
|
190
|
-
inline_walk(node, :
|
|
190
|
+
inline_walk(node, :bd, 252)
|
|
191
191
|
flush_line
|
|
192
192
|
when "dd"
|
|
193
193
|
old_indent = @indent
|
|
@@ -212,7 +212,7 @@ module Brrowser
|
|
|
212
212
|
walk(node)
|
|
213
213
|
@in_link = nil
|
|
214
214
|
else
|
|
215
|
-
@line << text.fg(81).
|
|
215
|
+
@line << text.fg(81).ul
|
|
216
216
|
@col += text.length
|
|
217
217
|
end
|
|
218
218
|
label = "[#{link_index}]"
|
|
@@ -227,11 +227,11 @@ module Brrowser
|
|
|
227
227
|
end
|
|
228
228
|
end
|
|
229
229
|
when "strong", "b"
|
|
230
|
-
inline_walk(node, :
|
|
230
|
+
inline_walk(node, :bd)
|
|
231
231
|
when "em", "i"
|
|
232
|
-
inline_walk(node, :
|
|
232
|
+
inline_walk(node, :it)
|
|
233
233
|
when "u"
|
|
234
|
-
inline_walk(node, :
|
|
234
|
+
inline_walk(node, :ul)
|
|
235
235
|
when "s", "strike", "del"
|
|
236
236
|
text = collect_text(node)
|
|
237
237
|
@line << text.fg(240)
|
|
@@ -253,7 +253,8 @@ module Brrowser
|
|
|
253
253
|
src = resolve_url(src) unless src.empty?
|
|
254
254
|
if src.match?(%r{youtube\.com/embed/|youtube-nocookie\.com/embed/})
|
|
255
255
|
video_id = src[%r{/embed/([^?&/]+)}, 1]
|
|
256
|
-
|
|
256
|
+
playlist_id = src[/[?&]list=([^&]+)/, 1]
|
|
257
|
+
if video_id && video_id != "playlist" && video_id != "videoseries"
|
|
257
258
|
ensure_blank_line
|
|
258
259
|
# Add YouTube thumbnail as image
|
|
259
260
|
thumb_url = "https://img.youtube.com/vi/#{video_id}/hqdefault.jpg"
|
|
@@ -267,10 +268,28 @@ module Brrowser
|
|
|
267
268
|
link_index = @links.length
|
|
268
269
|
link_line = @output.length
|
|
269
270
|
@links << { index: link_index, href: video_url, text: "Watch on YouTube", line: link_line }
|
|
270
|
-
@line << "\u25b6 Watch on YouTube".fg(196).
|
|
271
|
+
@line << "\u25b6 Watch on YouTube".fg(196).bd + "[#{link_index}]".fg(39)
|
|
271
272
|
@col += 19 + "[#{link_index}]".length
|
|
272
273
|
flush_line
|
|
273
274
|
ensure_blank_line
|
|
275
|
+
elsif playlist_id
|
|
276
|
+
ensure_blank_line
|
|
277
|
+
# Playlist embed: use oEmbed to resolve thumbnail
|
|
278
|
+
oembed_url = "https://www.youtube.com/oembed?url=https://www.youtube.com/playlist?list=#{playlist_id}&format=json"
|
|
279
|
+
flush_line if @col > 0
|
|
280
|
+
line_num = @output.length
|
|
281
|
+
@images << { src: oembed_url, alt: "YouTube playlist", line: line_num, height: IMG_RESERVE }
|
|
282
|
+
@output << "[YouTube playlist]".fg(236)
|
|
283
|
+
(IMG_RESERVE - 1).times { @output << "" }
|
|
284
|
+
# Add link to playlist
|
|
285
|
+
playlist_url = "https://www.youtube.com/playlist?list=#{playlist_id}"
|
|
286
|
+
link_index = @links.length
|
|
287
|
+
link_line = @output.length
|
|
288
|
+
@links << { index: link_index, href: playlist_url, text: "YouTube Playlist", line: link_line }
|
|
289
|
+
@line << "\u25b6 YouTube Playlist".fg(196).bd + "[#{link_index}]".fg(39)
|
|
290
|
+
@col += 20 + "[#{link_index}]".length
|
|
291
|
+
flush_line
|
|
292
|
+
ensure_blank_line
|
|
274
293
|
end
|
|
275
294
|
elsif !src.empty?
|
|
276
295
|
ensure_blank_line
|
|
@@ -294,7 +313,7 @@ module Brrowser
|
|
|
294
313
|
action = resolve_url(action) unless action.empty?
|
|
295
314
|
method = (node["method"] || "get").downcase
|
|
296
315
|
@current_form = { action: action, method: method, fields: [], line: @output.length }
|
|
297
|
-
@line << "[Form]".fg(208).
|
|
316
|
+
@line << "[Form]".fg(208).bd
|
|
298
317
|
flush_line
|
|
299
318
|
walk(node)
|
|
300
319
|
# Check if form has password field
|
|
@@ -456,7 +475,7 @@ module Brrowser
|
|
|
456
475
|
cell.length > w ? cell[0...w] : cell.ljust(w)
|
|
457
476
|
end
|
|
458
477
|
line = parts.join(" \u2502 ".fg(240))
|
|
459
|
-
line = line.
|
|
478
|
+
line = line.bd if ri == 0 && table_node.at_css("th")
|
|
460
479
|
@output << (" " * @indent) + line
|
|
461
480
|
|
|
462
481
|
if ri == 0 && table_node.at_css("th")
|
|
@@ -474,7 +493,7 @@ module Brrowser
|
|
|
474
493
|
row.each_with_index do |cell, ci|
|
|
475
494
|
next if cell.strip.empty?
|
|
476
495
|
label = headers && headers[ci] ? headers[ci] : "Col #{ci + 1}"
|
|
477
|
-
@output << (" " * @indent) + "#{label}: ".fg(245).
|
|
496
|
+
@output << (" " * @indent) + "#{label}: ".fg(245).bd + cell
|
|
478
497
|
end
|
|
479
498
|
@output << (" " * @indent) + ("\u2500" * 20).fg(240)
|
|
480
499
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brrowser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rcurses
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '7.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '7.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: nokogiri
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|