Compare commits
No commits in common. "0c1924d40a634d914b568c7341ced6a82a5292d0" and "b67c738b05771893e4c0578d02da5e6fc33835ff" have entirely different histories.
0c1924d40a
...
b67c738b05
11
BOARD.txt
11
BOARD.txt
|
@ -1,16 +1,12 @@
|
||||||
TODO
|
TODO
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
opt. maintain history between sessions
|
|
||||||
directory view for file scheme
|
|
||||||
search in page (ugh)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BACKLOG
|
BACKLOG
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
provide a plugin interface for schemes
|
click on links to open them
|
||||||
get/set config using command-line
|
get/set config using command-line
|
||||||
async event system
|
|
||||||
download without memory buffer
|
download without memory buffer
|
||||||
download in the background
|
download in the background
|
||||||
download view instead of last download
|
download view instead of last download
|
||||||
|
@ -26,11 +22,13 @@ response code 11 (if still there)
|
||||||
gopher?
|
gopher?
|
||||||
finger?
|
finger?
|
||||||
web????
|
web????
|
||||||
|
opt. maintain history between sessions
|
||||||
history (forward) (useful?)
|
history (forward) (useful?)
|
||||||
|
search in page (ugh)
|
||||||
remember scroll pos in history
|
remember scroll pos in history
|
||||||
identity management
|
identity management
|
||||||
"previous/next" pages
|
"previous/next" pages
|
||||||
configurable keybinds
|
directory view for file scheme
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,4 +56,3 @@ logging
|
||||||
home page
|
home page
|
||||||
different rendering mode
|
different rendering mode
|
||||||
preferences per site
|
preferences per site
|
||||||
basic mouse support
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ from bebop.tofu import get_cert_stash_path, load_cert_stash, save_cert_stash
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
argparser = argparse.ArgumentParser(description="Gemini browser")
|
argparser = argparse.ArgumentParser()
|
||||||
argparser.add_argument("url", nargs="?", default=None)
|
argparser.add_argument("url", nargs="?", default=None)
|
||||||
argparser.add_argument("-d", "--debug", action="store_true")
|
argparser.add_argument("-d", "--debug", action="store_true")
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
|
@ -25,7 +25,6 @@ from bebop.help import get_help
|
||||||
from bebop.history import History
|
from bebop.history import History
|
||||||
from bebop.identity import load_identities
|
from bebop.identity import load_identities
|
||||||
from bebop.links import Links
|
from bebop.links import Links
|
||||||
from bebop.metalines import LineType
|
|
||||||
from bebop.mime import MimeType
|
from bebop.mime import MimeType
|
||||||
from bebop.mouse import ButtonState
|
from bebop.mouse import ButtonState
|
||||||
from bebop.navigation import (
|
from bebop.navigation import (
|
||||||
|
@ -239,7 +238,7 @@ class Browser:
|
||||||
try:
|
try:
|
||||||
self.handle_mouse(*curses.getmouse())
|
self.handle_mouse(*curses.getmouse())
|
||||||
except curses.error:
|
except curses.error:
|
||||||
logging.error(f"Failed to get mouse information.")
|
pass
|
||||||
elif char == curses.KEY_RESIZE:
|
elif char == curses.KEY_RESIZE:
|
||||||
self.handle_resize()
|
self.handle_resize()
|
||||||
elif char == curses.ascii.ESC: # Can be ESC or ALT char.
|
elif char == curses.ascii.ESC: # Can be ESC or ALT char.
|
||||||
|
@ -358,6 +357,10 @@ class Browser:
|
||||||
This function assumes that the URL can be from an user and thus tries a
|
This function assumes that the URL can be from an user and thus tries a
|
||||||
few things to make it work.
|
few things to make it work.
|
||||||
|
|
||||||
|
If there is no current URL (e.g. we just started) or `assume_absolute`
|
||||||
|
is True, assume it is an absolute URL. In other cases, parse it normally
|
||||||
|
and later check if it has to be used relatively to the current URL.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- url: an URL string, may not be completely compliant.
|
- url: an URL string, may not be completely compliant.
|
||||||
- base_url: an URL string to use as base in case `url` is relative.
|
- base_url: an URL string to use as base in case `url` is relative.
|
||||||
|
@ -469,44 +472,12 @@ class Browser:
|
||||||
def handle_mouse(self, mouse_id: int, x: int, y: int, z: int, bstate: int):
|
def handle_mouse(self, mouse_id: int, x: int, y: int, z: int, bstate: int):
|
||||||
"""Handle mouse events.
|
"""Handle mouse events.
|
||||||
|
|
||||||
Vertical scrolling is handled, and clicking on links.
|
Right now, only vertical scrolling is handled.
|
||||||
"""
|
"""
|
||||||
if bstate & ButtonState.SCROLL_UP:
|
if bstate & ButtonState.SCROLL_UP:
|
||||||
self.scroll_page_vertically(-3)
|
self.scroll_page_vertically(-3)
|
||||||
elif bstate & ButtonState.SCROLL_DOWN:
|
elif bstate & ButtonState.SCROLL_DOWN:
|
||||||
self.scroll_page_vertically(3)
|
self.scroll_page_vertically(3)
|
||||||
elif bstate & ButtonState.LEFT_CLICKED:
|
|
||||||
self.handle_mouse_click(x, y)
|
|
||||||
|
|
||||||
def handle_mouse_click(self, x: int, y: int):
|
|
||||||
"""Handle a mouse click.
|
|
||||||
|
|
||||||
If the click is on a link (appropriate line and columns), open it.
|
|
||||||
"""
|
|
||||||
if not self.page_pad or not self.page_pad.current_page:
|
|
||||||
return
|
|
||||||
page = self.page_pad.current_page
|
|
||||||
px, py = self.page_pad.current_column, self.page_pad.current_line
|
|
||||||
line_pos = y + py
|
|
||||||
if line_pos >= len(page.metalines):
|
|
||||||
return
|
|
||||||
meta, line = page.metalines[line_pos]
|
|
||||||
if meta["type"] != LineType.LINK:
|
|
||||||
return
|
|
||||||
# "url" key is contained only in the first line of the link if its text
|
|
||||||
# is wrapped, so if the user did not click on the first line, rewind to
|
|
||||||
# get the URL.
|
|
||||||
while "url" not in meta:
|
|
||||||
line_pos -= 1
|
|
||||||
meta, line = page.metalines[line_pos]
|
|
||||||
url = meta["url"]
|
|
||||||
# The click is valid if it is on the link itself or the dimmed preview.
|
|
||||||
col_pos = x + px
|
|
||||||
if col_pos > len(line):
|
|
||||||
ch = self.page_pad.pad.instr(line_pos, col_pos, 1)
|
|
||||||
if ch == b' ':
|
|
||||||
return
|
|
||||||
self.open_url(url, base_url=self.current_url)
|
|
||||||
|
|
||||||
def handle_resize(self):
|
def handle_resize(self):
|
||||||
"""Try to not make everything collapse on resizes."""
|
"""Try to not make everything collapse on resizes."""
|
||||||
|
|
|
@ -37,7 +37,7 @@ def init_colors(bg: int =-1):
|
||||||
curses.init_pair(ColorPair.TITLE_2, curses.COLOR_MAGENTA, bg)
|
curses.init_pair(ColorPair.TITLE_2, curses.COLOR_MAGENTA, bg)
|
||||||
curses.init_pair(ColorPair.TITLE_3, curses.COLOR_MAGENTA, bg)
|
curses.init_pair(ColorPair.TITLE_3, curses.COLOR_MAGENTA, bg)
|
||||||
curses.init_pair(ColorPair.PREFORMATTED, curses.COLOR_YELLOW, bg)
|
curses.init_pair(ColorPair.PREFORMATTED, curses.COLOR_YELLOW, bg)
|
||||||
curses.init_pair(ColorPair.BLOCKQUOTE, curses.COLOR_BLUE, bg)
|
curses.init_pair(ColorPair.BLOCKQUOTE, curses.COLOR_CYAN, bg)
|
||||||
curses.init_pair(ColorPair.LINK_PREVIEW, curses.COLOR_WHITE, bg)
|
curses.init_pair(ColorPair.LINK_PREVIEW, curses.COLOR_WHITE, bg)
|
||||||
except curses.error:
|
except curses.error:
|
||||||
logging.error("Failed to init colors.")
|
logging.error("Failed to init colors.")
|
||||||
|
|
Reference in a new issue