v1.0.1: Fix AMO warnings, add extension ID

This commit is contained in:
Bastian Gruber 2026-01-04 22:05:46 -04:00
parent f8f6a95b0f
commit 0fde22d6e2
Signed by: gruberb
GPG key ID: 426AF1CBA0530691
3 changed files with 126 additions and 42 deletions

View file

@ -1,11 +1,21 @@
{
"manifest_version": 2,
"name": "Embermarks",
"version": "1.0.0",
"version": "1.0.1",
"description": "Rediscover your forgotten bookmarks. Surface the ones you never visit.",
"author": "Bastian Gruber",
"homepage_url": "https://github.com/gruberb/embermarks",
"browser_specific_settings": {
"gecko": {
"id": "embermarks@gruberb.dev",
"strict_min_version": "109.0",
"data_collection_permissions": {
"required": false
}
}
},
"icons": {
"48": "icons/ember-48.svg",
"96": "icons/ember-96.svg"

View file

@ -20,7 +20,10 @@ document.addEventListener("DOMContentLoaded", async () => {
action: "getBookmarkFolders",
});
folderList.innerHTML = "";
// Clear loading text
while (folderList.firstChild) {
folderList.removeChild(folderList.firstChild);
}
for (const folder of folders) {
const item = document.createElement("div");
@ -28,11 +31,18 @@ document.addEventListener("DOMContentLoaded", async () => {
const isExcluded = settings.excludedFolders.includes(folder.id);
item.innerHTML = `
<input type="checkbox" id="folder-${folder.id}" value="${folder.id}" ${isExcluded ? "checked" : ""}>
<label for="folder-${folder.id}">📁 ${folder.title || "(unnamed)"}</label>
`;
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = `folder-${folder.id}`;
checkbox.value = folder.id;
checkbox.checked = isExcluded;
const label = document.createElement("label");
label.htmlFor = `folder-${folder.id}`;
label.textContent = `📁 ${folder.title || "(unnamed)"}`;
item.appendChild(checkbox);
item.appendChild(label);
folderList.appendChild(item);
}

View file

@ -20,13 +20,6 @@ function formatDaysAgo(days) {
return `${Math.floor(days / 365)}y ago`;
}
// Escape HTML
function escapeHtml(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML;
}
// Create a bookmark card element
function createBookmarkCard(bookmark) {
const card = document.createElement("a");
@ -35,20 +28,47 @@ function createBookmarkCard(bookmark) {
card.target = "_blank";
card.rel = "noopener";
const faviconUrl = getFaviconUrl(bookmark.url);
// Favicon container
const favicon = document.createElement("div");
favicon.className = "bookmark-favicon";
card.innerHTML = `
<div class="bookmark-favicon">
${faviconUrl ? `<img src="${faviconUrl}" alt="">` : "🔖"}
</div>
<div class="bookmark-info">
<div class="bookmark-title" title="${escapeHtml(bookmark.title)}">${escapeHtml(bookmark.title)}</div>
<div class="bookmark-meta">
${bookmark.visitCount} visit${bookmark.visitCount !== 1 ? "s" : ""} · Added ${formatDaysAgo(bookmark.daysSinceAdded)}
</div>
${bookmark.path ? `<div class="bookmark-folder">${escapeHtml(bookmark.path)}</div>` : ""}
</div>
`;
const faviconUrl = getFaviconUrl(bookmark.url);
if (faviconUrl) {
const img = document.createElement("img");
img.src = faviconUrl;
img.alt = "";
favicon.appendChild(img);
} else {
favicon.textContent = "🔖";
}
// Info container
const info = document.createElement("div");
info.className = "bookmark-info";
const title = document.createElement("div");
title.className = "bookmark-title";
title.title = bookmark.title;
title.textContent = bookmark.title;
const meta = document.createElement("div");
meta.className = "bookmark-meta";
const visitText =
bookmark.visitCount === 1 ? "1 visit" : `${bookmark.visitCount} visits`;
meta.textContent = `${visitText} · Added ${formatDaysAgo(bookmark.daysSinceAdded)}`;
info.appendChild(title);
info.appendChild(meta);
if (bookmark.path) {
const folder = document.createElement("div");
folder.className = "bookmark-folder";
folder.textContent = bookmark.path;
info.appendChild(folder);
}
card.appendChild(favicon);
card.appendChild(info);
return card;
}
@ -70,18 +90,66 @@ function showEmptyState(container, reason = "none") {
const msg = messages[reason] || messages.none;
container.innerHTML = `
<div class="empty-state">
<div class="icon">${msg.icon}</div>
<h2>${msg.title}</h2>
<p>${msg.text}</p>
</div>
`;
// Clear container
while (container.firstChild) {
container.removeChild(container.firstChild);
}
const emptyState = document.createElement("div");
emptyState.className = "empty-state";
const icon = document.createElement("div");
icon.className = "icon";
icon.textContent = msg.icon;
const heading = document.createElement("h2");
heading.textContent = msg.title;
const paragraph = document.createElement("p");
paragraph.textContent = msg.text;
emptyState.appendChild(icon);
emptyState.appendChild(heading);
emptyState.appendChild(paragraph);
container.appendChild(emptyState);
}
// Show loading state
function showLoading(container) {
container.innerHTML = '<div class="loading"></div>';
while (container.firstChild) {
container.removeChild(container.firstChild);
}
const loading = document.createElement("div");
loading.className = "loading";
container.appendChild(loading);
}
// Show error state
function showError(container) {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
const emptyState = document.createElement("div");
emptyState.className = "empty-state";
const icon = document.createElement("div");
icon.className = "icon";
icon.textContent = "!";
const heading = document.createElement("h2");
heading.textContent = "Oops";
const paragraph = document.createElement("p");
paragraph.textContent = "Failed to load bookmarks";
emptyState.appendChild(icon);
emptyState.appendChild(heading);
emptyState.appendChild(paragraph);
container.appendChild(emptyState);
}
// Load and display bookmarks
@ -93,7 +161,9 @@ async function loadBookmarks(container) {
action: "getForgottenBookmarks",
});
container.innerHTML = "";
while (container.firstChild) {
container.removeChild(container.firstChild);
}
if (!bookmarks || bookmarks.length === 0) {
showEmptyState(container, "none");
@ -105,12 +175,6 @@ async function loadBookmarks(container) {
}
} catch (error) {
console.error("Failed to load bookmarks:", error);
container.innerHTML = `
<div class="empty-state">
<div class="icon">!</div>
<h2>Oops</h2>
<p>Failed to load bookmarks</p>
</div>
`;
showError(container);
}
}