Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

design overhaul & improved keyboard accessibility #325

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 105 additions & 96 deletions conex-background.js

Large diffs are not rendered by default.

34 changes: 28 additions & 6 deletions conex-browser-action.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,36 @@
<meta content="utf-8" http-equiv="encoding">
</head>

<body id='browseraction'>
<body id='browseraction' theme='dark'>
<form id='search-form'>
<input tabindex='1' id='search' type='search' autocomplete="off" placeholder="search for title or url" autofocus></input>
<a id='new-container-button' href="#" title='create new container'>+</a>
<span id="search-span">
<label for="search">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</label>
<input tabindex='1' id='search' type='search' autocomplete="off" placeholder="search for title or url" autofocus>
</span>
<a id='new-container-button' tabindex="1" href="#" title='create new container'>
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd">
</path>
</svg>
</a>
</form>
<form id='new-container-form'>
<div id='new-container'>
<input id='new-container-name' placeholder='container name' type='text'></input>
<button id="back-to-search-button"><svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"></path>
</svg></button>
<span id="new-container-span">
<input id='new-container-name' placeholder='container name' type='text'>
</span>
<select id='color'>
<option class='blue' val="blue">&#9679;</option>
<option class='turquoise' val='turquoise'>&#9679;</option>
Expand All @@ -24,7 +46,7 @@
<option class='pink' val='pink'>&#9679;</option>
<option class='purple' val='purple'>&#9679;</option>
</select>
<input type='submit' value='add'></input>
<input type='submit' value='add'>
</div>
</form>
<div id='tabcontainers'></div>
Expand All @@ -36,4 +58,4 @@
<script type="text/javascript" src="conex-browser-action.js"></script>
</body>

</html>
</html>
254 changes: 140 additions & 114 deletions conex-browser-action.js

Large diffs are not rendered by default.

100 changes: 55 additions & 45 deletions conex-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,63 @@ const bg = browser.extension.getBackgroundPage();
//
// <div class='foo'><span class='bar1' data-foo='bar'>baz1</span><span class='bar2'>baz2</span></div>
//
const $e = function(name, attributes, children) {
const $e = function (name, attributes, children) {
const e = document.createElement(name);
for(const key in attributes) {
if(key == 'content') {
for (const key in attributes) {
if (key == 'content') {
e.appendChild(document.createTextNode(attributes[key]));
} else {
e.setAttribute(key.replace(/_/g, '-'), attributes[key]);
}
}

for(const child of children || []) {
for (const child of children || []) {
e.appendChild(child);
}

return e;
};

function createHeaderElement(value) {
return $e('h2', {content: value});
return $e('h2', { content: value });
}

function createTabContainerHeaderElement(id, color, name, tabindex, icon, containsAudibleTab) {
let iconElement = $e('span', {class: 'icon', title: 'expand container list'}, [$e('span', {class: 'arrow-right'})]);
if(color == "bookmarks" || color == "history") {
iconElement = $e('span', {class: 'icon'}, [$e('span', { class: `icon-${color}`, content: icon || ' ' })]);
let iconElement = $e('span', { class: 'icon', title: 'expand container list' }, [$e('span', { class: 'arrow-right' })]);
if (color == "bookmarks" || color == "history") {
iconElement = $e('span', { class: 'icon' }, [$e('span', { class: `icon-${color}`, content: icon || ' ' })]);
// iconElement = $e('span', { class: 'icon' }, [$e('span', { class: `icon-${color}`, content: '' })]);
}
const tooltip = id == 'firefox-default' ? 'close all tabs' : 'delete this container';
const data_match = id == '' ? 'false' : 'true';

const elment =
$e('ul', {id: id, data_expanded: 'false', class: color}, [
$e('li', {tabindex: tabindex || 1, class: 'section', data_match: data_match, data_name: name, data_cookie_store: id, title: 'enter: to expand\nctrl-enter: switch to container\nctrl-shift-enter: new tab in container'}, [
$e('div', {class: 'delete-container-confirmation'}, [
$e('span', {class: 'confirmation-tabs-count'}),
$e('span', {content: 'yes', class: 'yes', title: 'yes, delete container on all its tabs'}),
$e('span', {content: 'no', class: 'no', title: "abort mission -- abort mission!"}),
]),
iconElement,
$e('span', { class: 'name', title: 'change to this container (x tabs)', content: name }),
$e('img', { class: `audible-${containsAudibleTab}`, src: 'icons/loudspeaker.svg'}),
$e('span', { class: 'tabs-count', content: '(x tabs)'}),
$e('span', { class: 'toolbar new-tab-button', title: 'open new tab in this container', content: '+'}),
$e('span', { class: 'toolbar delete-container-button', data_name: name, data_cookie_store: id, title: tooltip, content: 'x'})
const element =
$e('ul', { id: id, data_expanded: 'false', class: color }, [
$e('li', { tabindex: tabindex || 1, class: 'section', data_match: data_match, data_name: name, data_cookie_store: id, title: 'enter: to expand\nctrl-enter: switch to container\nctrl-shift-enter: new tab in container' }, [
$e('div', { class: 'delete-container-confirmation' }, [
$e('span', { class: 'confirmation-tabs-count' }),
$e('span', { content: 'yes', class: 'yes', title: 'yes, delete container on all its tabs' }),
$e('span', { content: 'no', class: 'no', title: "abort mission -- abort mission!" }),
]),
iconElement,
$e('span', { class: 'name', title: 'change to this container (x tabs)', content: name }),
$e('img', { class: `audible-${containsAudibleTab}`, src: 'icons/loudspeaker.svg' }),
$e('span', { class: 'tabs-count', content: 'x tabs' }),
$e('span', { class: 'toolbar new-tab-button', title: 'open new tab in this container', content: '' }, [
$e('span', { class: 'plus-sign', title: 'open new tab in this container', content: '' })
]),
// $e('span', { class: 'toolbar delete-container-button', data_name: name, data_cookie_store: id, title: tooltip, content: 'x'})
$e('span', { class: 'toolbar delete-container-button', data_name: name, data_cookie_store: id, title: tooltip, content: '' }, [
$e('span', { class: 'delete-sign', title: tooltip, content: '' })
])
])
]);

return elment;
return element;
}

function createTabElement(tab, isBookmarkUrl) {
if(!tab.id || tab.id == browser.tabs.TAB_ID_NONE) {
if (!tab.id || tab.id == browser.tabs.TAB_ID_NONE) {
return;
}

Expand All @@ -82,15 +88,15 @@ function createHistoryOrBookmarkElement(historyItem) {
element.style.display = "";

element.addEventListener('click', _ => {
bg.openContainerSelector(element.dataset.url, element.dataset.title);
window.close();
}
bg.openContainerSelector(element.dataset.url, element.dataset.title);
window.close();
}
);

return element;
}

const renderEntry = function(url, title, id, favIconUrl, drawBookmarkIcon, drawAudibleIcon) {
const renderEntry = function (url, title, id, favIconUrl, drawBookmarkIcon, drawAudibleIcon) {
const isHistoryOrBookmark = (id == 0);
const defaultFavIconUrl = './favicon.ico';
const elClass = drawBookmarkIcon ? 'tab is-bookmark' : 'tab';
Expand All @@ -99,28 +105,32 @@ const renderEntry = function(url, title, id, favIconUrl, drawBookmarkIcon, drawA
const tooltip = isHistoryOrBookmark ? 'enter: re-open tab' : 'enter: jump to tab\nbackspace: close tab';

let thumbnailElement = $e('span');
if(bg.settings['show-favicons']) {
if (bg.settings['show-favicons']) {
thumbnailElement = $e('img', { src: defaultFavIconUrl, class: 'no-thumbnail' });
}
if(bg.settings['create-thumbnail']) {
if (bg.settings['create-thumbnail']) {
thumbnailElement = $e('div', { class: 'image', data_bg_set: 'false', style: `background:url('${defaultFavIconUrl}')` }, [
$e('img', { src: defaultFavIconUrl })
]);
}

const element =
$e('li', {tabindex: 1, class: elClass, data_match: 'true', data_title: title.toLowerCase(), data_url: url, data_tab_id: id,
style: 'display:none', title: tooltip } ,[
$e('li', {
tabindex: 1, class: elClass, data_match: 'true', data_title: title.toLowerCase(), data_url: url, data_tab_id: id,
style: 'display:none', title: tooltip
}, [
$e('div', {}, [
thumbnailElement,
$e('div', {class: 'text'}, [
$e('div', {class: 'tab-title', content: title}),
$e('div', {class: 'tab-url', content: url})
$e('div', { class: 'text' }, [
$e('div', { class: 'tab-title', content: title }),
$e('div', { class: 'tab-url', content: url })
]),
$e('div', {class: 'close', style: isHistoryOrBookmark ? 'display: none' : ''}, [
$e('span', {content: '★', title: 'this tab is a bookmark', class: 'bookmark-marker', data_tab_id: id}),
$e('span', {content: '╳', title: 'close this tab', class: 'close-button', data_tab_id: id}),
$e('img', {src: 'icons/loudspeaker.svg', title: 'this tab is playing audio', class: `audible-${drawAudibleIcon}`}),
$e('div', { class: 'close', style: isHistoryOrBookmark ? 'display: none' : '' }, [
$e('span', { content: '★', title: 'this tab is a bookmark', class: 'bookmark-marker', data_tab_id: id }),
$e('span', { content: '', title: 'close this tab', class: 'close-button', data_tab_id: id }, [
$e('span', { content: '', title: 'close this tab', class: 'close-button-sign', data_tab_id: id })
]),
$e('img', { src: 'icons/loudspeaker.svg', title: 'this tab is playing audio', class: `audible-${drawAudibleIcon}` }),
])
]),
]);
Expand All @@ -133,9 +143,9 @@ const renderEntry = function(url, title, id, favIconUrl, drawBookmarkIcon, drawA
return element;
}

const setFavIcon = async function(url, favIconUrl, imgElement) {
const setFavIcon = async function (url, favIconUrl, imgElement) {
const defaultFavIconUrl = './favicon.ico';
if(favIconUrl && favIconUrl.startsWith('data:image')) {
if (favIconUrl && favIconUrl.startsWith('data:image')) {
imgElement.src = favIconUrl;
return;
}
Expand All @@ -147,7 +157,7 @@ const setFavIcon = async function(url, favIconUrl, imgElement) {
imgElement.src = cache[cleanedUrl].favicon;
return;
}
} catch(e) { console.debug(`error cache for ${url}: ${e}`); }
} catch (e) { console.debug(`error cache for ${url}: ${e}`); }

const favIconKey = `favicon:${cleanedUrl.split("/")[0]}`;
try {
Expand All @@ -156,16 +166,16 @@ const setFavIcon = async function(url, favIconUrl, imgElement) {
imgElement.src = cache[favIconKey].favicon;
return;
}
} catch(e) { console.debug(`error cache for ${url}: ${e}`); }
} catch (e) { console.debug(`error cache for ${url}: ${e}`); }

if(favIconUrl && favIconUrl.startsWith('http')) {
if (favIconUrl && favIconUrl.startsWith('http')) {
try {
const res = await fetch(favIconUrl, { method: "GET", });
if (res.ok) {
imgElement.src = favIconUrl;
return;
}
} catch(e) { console.debug(`error getting favicon ${favIconUrl}`); }
} catch (e) { console.debug(`error getting favicon ${favIconUrl}`); }
}

imgElement.src = defaultFavIconUrl;
Expand Down
10 changes: 6 additions & 4 deletions conex-helper.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// alias for document.querySelectorAll
const $ = function(s, parent){ return (parent || document).querySelectorAll(s); };
const $ = function (s, parent) { return (parent || document).querySelectorAll(s); };

// alias for document.querySelector
const $1 = function(s, parent){ return (parent || document).querySelector(s); };
const $1 = function (s, parent) { return (parent || document).querySelector(s); };

const cleanUrl = function(url) {
return url.replace('http://','').replace('https://','').toLowerCase();
const cleanUrl = function (url) {
return url.replace('http://', '').replace('https://', '').toLowerCase();
};

var settings = {};

function _refreshSettings() {
return new Promise((resolve, reject) => {
browser.storage.local.get([
'conex/settings/use-system-theme',
'conex/settings/enable-dark-theme',
'conex/settings/create-thumbnail',
'conex/settings/experimental-features',
'conex/settings/hide-tabs',
Expand Down
Loading