heck
This commit is contained in:
parent
b793990748
commit
139151fddc
|
@ -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')
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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):
|
||||
|
|
Reference in a new issue