This commit is contained in:
Izalia Mae 2022-09-03 19:07:14 -04:00
parent b793990748
commit 139151fddc
13 changed files with 233 additions and 84 deletions

View file

@ -1,3 +1,5 @@
from izzylib.misc import random_str
from .. import cache, var
from ..database import default_permissions
from ..exceptions import AccountNotFoundError, NoAccountsError
@ -36,6 +38,11 @@ class StatusBar(ComponentBase):
self.setup()
@property
def tab(self):
return self.window.active_tab
def bookmark_get_data(self):
data = DotDict()
@ -205,7 +212,7 @@ class StatusBar(ComponentBase):
except AttributeError:
pass
tab = self.window.active_tab
tab = self.tab
if name == 'debug':
self.window.notification('Merp!', 'INFO', timeout=0, system=True)
@ -310,7 +317,7 @@ class StatusBar(ComponentBase):
def handle_fedi_button(self, name):
post = self.window.active_tab.fedi_post
post = self.tab.fedi_post
if not post or not self.toot_set_account():
return
@ -355,13 +362,13 @@ class StatusBar(ComponentBase):
self.window.notification('Failed to boost post', 'error')
if post:
cache.posts.store(self.window.active_tab.url, post)
cache.posts.store(self.tab.url, post)
def handle_siteoptions_switch(self, name):
active = self[f'siteoptions-{name}'].get_active()
try:
host = self.window.active_tab.url.hostname()
host = self.tab.url.hostname()
except:
return
@ -375,7 +382,7 @@ class StatusBar(ComponentBase):
def handle_siteoptions_button(self, name):
if name == 'reset':
host = self.window.active_tab.url.hostname()
host = self.tab.url.hostname()
with self.db.session as s:
s.del_permission(host)
@ -391,18 +398,34 @@ class StatusBar(ComponentBase):
for widget in self['logins-unsaved-list']:
widget.handle_cancel()
elif name == 'passgen':
self.app.clipboard.set_text(random_str(extra=r'!@#$%^&*()_+-={}[]<>;:'), -1)
self.window.notification('Copied newly-generated password to clipboard', system=False)
self['logins-popover'].popdown()
def handle_logins_refresh(self):
login_list = self['logins-saved-list']
url = self.tab.url
unsaved = len(self['logins-unsaved-list'])
for child in login_list.get_children():
child.destroy()
with self.db.session as s:
for row in s.fetch('passwords', domain=self.window.active_tab.url.hostname()):
login_list.add(SavedLoginRow(row, self.window.active_tab.url)['container'])
for row in self.app.password.fetch(domain=url.hostname()):
## todo: fix searching by domain
if row.domain == url.hostname():
login_list.add(SavedLoginRow(row, url)['container'])
for name in ['scroll', 'label', 'clear']:
widget = self[f'logins-unsaved-{name}']
if unsaved:
widget.show()
else:
widget.hide()
def handle_toot_key_press(self, textview, event, *args):
@ -460,6 +483,7 @@ class StatusBar(ComponentBase):
## Logins
self.connect('logins-close', 'clicked', self.handle_logins_button, 'close')
self.connect('logins-unsaved-clear', 'clicked', self.handle_logins_button, 'clear')
self.connect('logins-saved-passgen', 'clicked', self.handle_logins_button, 'passgen')
## Bookmarks
self.connect('bookmark-save', 'clicked', self.handle_bookmark_button, 'save')

View file

@ -379,12 +379,12 @@ class WebTab(BuilderBase, Gtk.Box):
def set_favicon(self, icon=None):
icon = icon or self.favicon or 'image-x-generic'
logging.debug(f'Set icon for page: {class_name(icon)}, {self.url}')
for widget in ['label-favicon-icon', 'menu-favicon']:
set_image(self[widget], icon, 16)
self._data.favicon = icon != 'image-x-generic'
logging.debug(f'Set icon for page: {class_name(icon)}, {self.url.replace_properties(query=None, anchor=None)}')
def set_favicon_from_cache(self, url=None):

View file

@ -43,6 +43,7 @@ def get_paths(profile='DEFAULT'):
# browser paths
localweb = scriptpath.join('localweb'),
resources = scriptpath.join('resources'),
js = scriptpath.join('resources/ext_js'),
# data paths
profile = profilepath,

View file

@ -110,7 +110,7 @@ class Account(RowBase):
emojis = DotDict()
try:
if cache_path.mtime + timedelta(days=7) < datetime.now():
if cache_path.modified() + timedelta(days=7) < datetime.now():
raise FileNotFoundError('heck')
emojis.load_json(cache_path)

View file

@ -46,9 +46,14 @@ a:hover {
}
input, select, textarea {
display: inline-block;
padding: 5px;
}
input[type='text'] {
min-width: 200px;
}
input:not([type='checkbox']):not([type='button']), textarea {
margin: 1px 0;
color: var(--text);

View file

@ -1,3 +1,4 @@
from izzylib.misc import replace_strings
from mastodon import Mastodon
from .widgets import Box
@ -250,7 +251,8 @@ class SavedLoginRow(LoginRowBase):
self.ui = Gtk.Builder.new_from_file(self.app.path.resources.join('password_saved.ui'))
self.row = row
self['username'].set_text(self.row['username'])
self['username'].set_text(self.row.get('username', ''))
self['domain'].set_text(self.row.get('domain', ''))
self.connect('fill', 'clicked', self.handle_fill_password)
self.connect('copy-password', 'clicked', self.handle_copy_password)
@ -272,8 +274,15 @@ class SavedLoginRow(LoginRowBase):
def handle_fill_password(self):
with dirs.resources.join('ext_js/autofill.js').open() as fd:
self.tab.run_js(fd.read().replace('USERNAME_VALUE', self.row.username).replace('PASSWORD_VALUE', self.row.password))
self.tab.webview.grab_focus()
with self.app.path.js.join('autofill.js').open() as fd:
data = fd.read()
username = self.row.username
password = self.row.password
self.tab.run_js(data + f'\nfill_forms("{username}", "{password}");')
self.window['statusbar-logins-popover'].popdown()

View file

@ -146,6 +146,21 @@ class PasswordItem:
## dict methods
def get(self, key, default=None):
value = None
try:
value = self[key]
except KeyError:
pass
if value == None:
return default
return value
def items(self):
for key in self.keys():
yield (key, self[key])

View file

@ -1,28 +1,35 @@
function fetch_fields() {
var userfield = null;
var passfield = null;
function get_forms() {
const forms = [];
Array.from(document.forms).forEach((form) => {
Array.from(form.getElementsByTagName('input')).forEach((input) => {
if (input.type == 'password') {
passfield = input;
} else if (input.name.includes('user')) {
userfield = input;
for (let form of document.getElementsByTagName('form')) {
let fields = [null, null];
for (const elem of form.getElementsByTagName('input')) {
if (!fields.includes(null)) {
continue;
}
if (![userfield, passfield].includes(null)) {
return;
if (elem.type == 'password') {
fields[1] = elem;
} else if (elem.type != 'hidden') {
fields[0] = elem;
}
});
}
if (!fields.includes(null)) {
forms.push(fields);
}
}
return forms;
}
function fill_forms(username, password) {
const forms = get_forms();
forms.forEach(function(form){
form[0].value = username;
form[1].value = password;
});
return [userfield, passfield];
}
fields = fetch_fields();
if (!fields.includes(null)) {
fields[0].value = 'USERNAME_VALUE';
fields[1].value = 'PASSWORD_VALUE';
}

View file

@ -56,5 +56,34 @@ notebook > header > tabs > tab {
.statusbar-login-list {
background-color: @theme_base_color;
padding: 0px;
}
.password > button {
min-height: 0px;
min-width: 0px;
}
.password {
padding: 5px;
}
.password:nth-child(even) {
background-color: shade(@theme_bg_color, 0.75);
}
.password label {
padding: 0px;
margin: 0px;
}
.password .domain {
font-size: 0.8em;
color: shade(white, 0.60)
}
.url {
padding-top: 0px;
padding-bottom: 0px;
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkImage" id="bookmark-icon">
@ -417,6 +417,18 @@
<property name="pixel-size">24</property>
<property name="icon-name">window-close</property>
</object>
<object class="GtkImage" id="statusbar-logins-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Saved and unsaved passwords</property>
<property name="pixel-size">20</property>
<property name="icon-name">dialog-password</property>
</object>
<object class="GtkImage" id="statusbar-logins-saved-passgen-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">edit-copy</property>
</object>
<object class="GtkPopover" id="statusbar-logins-popover">
<property name="width-request">500</property>
<property name="height-request">400</property>
@ -436,7 +448,22 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkLabel">
<object class="GtkButton" id="statusbar-logins-saved-passgen">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Generate a new password and copy it to the clipboard</property>
<property name="image">statusbar-logins-saved-passgen-icon</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="statusbar-logins-saved-label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
@ -445,7 +472,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="position">1</property>
</packing>
</child>
<child>
@ -460,7 +487,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</object>
@ -484,7 +511,6 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<placeholder/>
</child>
@ -509,7 +535,7 @@
</packing>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="statusbar-logins-unsaved-label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Unsaved Logins</property>
@ -521,7 +547,7 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<object class="GtkScrolledWindow" id="statusbar-logins-unsaved-scroll">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
@ -534,7 +560,6 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<placeholder/>
</child>
@ -577,13 +602,6 @@
<class name="ui-element"/>
</style>
</object>
<object class="GtkImage" id="statusbar-logins-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Saved and unsaved passwords</property>
<property name="pixel-size">20</property>
<property name="icon-name">dialog-password</property>
</object>
<object class="GtkImage" id="statusbar-reply-icon">
<property name="name">toot-reply-icon</property>
<property name="visible">True</property>

View file

@ -1,65 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkBox" id="container">
<object class="GtkImage" id="copy-password-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">5</property>
<property name="icon-name">dialog-password</property>
</object>
<object class="GtkImage" id="copy-username-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">user-online</property>
</object>
<object class="GtkImage" id="fill-icon">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">edit-paste</property>
</object>
<!-- n-columns=4 n-rows=2 -->
<object class="GtkGrid" id="container">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="column-spacing">5</property>
<child>
<object class="GtkLabel" id="username">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="single-line-mode">True</property>
<property name="xalign">0</property>
<style>
<class name="username"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="copy-username">
<property name="label" translatable="yes">Username</property>
<object class="GtkLabel" id="domain">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Copy username to clipboard</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<property name="single-line-mode">True</property>
<property name="xalign">0</property>
<style>
<class name="domain"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="copy-password">
<property name="label" translatable="yes">Password</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Copy password to clipboard</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fill">
<property name="label" translatable="yes">Fill</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Fill in username and password fields on the page if possible</property>
<property name="image">fill-icon</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="left-attach">3</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="copy-username">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Copy username to clipboard</property>
<property name="image">copy-username-icon</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="copy-password">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Copy password to clipboard</property>
<property name="image">copy-password-icon</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
<property name="height">2</property>
</packing>
</child>
<style>
<class name="password"/>
</style>
</object>
</interface>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkImage" id="label-close-icon">
@ -259,6 +259,7 @@
<property name="input-purpose">url</property>
<style>
<class name="entry-recolor"/>
<class name="url"/>
</style>
</object>
<packing>

View file

@ -88,7 +88,7 @@ class Themes(ComponentBase, ObjectBase):
self.main = Gtk.CssProvider()
self.main.load_from_file(Gio.File.new_for_path(self.app.path.resources.join('main.css')))
Gtk.StyleContext.add_provider_for_screen(self.screen, self.main, StylePriority.FALLBACK)
Gtk.StyleContext.add_provider_for_screen(self.screen, self.main, StylePriority.SETTINGS)
def set(self, hash, save=True):