Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ set(SOURCES
"src/Browser.cpp"
"src/AdBlocker.h"
"src/AdBlocker.cpp"
"src/BookmarkStore.h"
"src/BookmarkStore.cpp"
"src/DownloadManager.h"
"src/DownloadManager.cpp"
"src/ExtensionManager.h"
Expand Down
224 changes: 223 additions & 1 deletion assets/static-sties/google-static.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,138 @@
@keyframes ul_fade_in { from { opacity: 0; } to { opacity: 1; } }
@-webkit-keyframes ul_fade_in { from { opacity: 0; } to { opacity: 1; } }
</style>

<style>
/* Bookmark Bar Styles */
.bookmark-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(29, 29, 33, 0.92);
padding: 6px 16px;
display: flex;
align-items: center;
gap: 4px;
flex-wrap: nowrap;
min-height: 36px;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(60, 60, 70, 0.4);
z-index: 1000;
overflow-x: auto;
overflow-y: hidden;
}

.bookmark-bar::-webkit-scrollbar {
height: 4px;
}

.bookmark-bar::-webkit-scrollbar-track {
background: transparent;
}

.bookmark-bar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 2px;
}

.bookmark-bar-empty {
color: #9aa0a6;
font-size: 0.8em;
padding: 4px 8px;
white-space: nowrap;
}

.bookmark-item {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 6px;
text-decoration: none;
color: #e8eaed;
font-size: 0.8em;
transition: all 0.15s ease;
max-width: 160px;
background: transparent;
white-space: nowrap;
flex-shrink: 0;
}

.bookmark-item:hover {
background: rgba(255, 255, 255, 0.1);
color: white;
}

.bookmark-item:active {
transform: scale(0.97);
}

.bookmark-item img {
width: 16px;
height: 16px;
border-radius: 3px;
flex-shrink: 0;
}

.bookmark-item .default-icon {
width: 16px;
height: 16px;
background: linear-gradient(135deg, #4285f4, #5e35b1);
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 9px;
color: white;
font-weight: 600;
flex-shrink: 0;
}

.bookmark-item span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.bookmark-item .remove-btn {
display: none;
width: 14px;
height: 14px;
border-radius: 50%;
background: rgba(255, 100, 100, 0.8);
color: white;
font-size: 10px;
line-height: 14px;
text-align: center;
cursor: pointer;
margin-left: 2px;
flex-shrink: 0;
}

.bookmark-item:hover .remove-btn {
display: block;
}

.bookmark-item .remove-btn:hover {
background: rgba(255, 60, 60, 1);
}

/* Adjust main container for bookmark bar */
.main-container {
padding-top: 50px;
}
</style>
</head>

<body>

<!-- Bookmark Bar -->
<div class="bookmark-bar" id="bookmarkBar">
<span class="bookmark-bar-empty" id="emptyMessage">Click the ★ icon to add bookmarks</span>
</div>

<div class="main-container">
<!-- Official Google Logo Geometry (SVG) -->
<svg class="logo-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 272 92">
Expand Down Expand Up @@ -229,7 +357,101 @@
</a>
</footer>


<script>
// Helper to get first letter of domain for default icon
function getFirstLetter(url) {
try {
const hostname = new URL(url).hostname;
return hostname.replace('www.', '').charAt(0).toUpperCase();
} catch (e) {
return url.charAt(0).toUpperCase();
}
}

// Create a bookmark element
function createBookmarkElement(bookmark) {
const item = document.createElement('a');
item.className = 'bookmark-item';
item.href = bookmark.url;
item.title = bookmark.title || bookmark.url;

// Icon (favicon or default)
if (bookmark.favicon && bookmark.favicon.startsWith('data:')) {
const img = document.createElement('img');
img.src = bookmark.favicon;
img.onerror = function() {
const defaultIcon = document.createElement('div');
defaultIcon.className = 'default-icon';
defaultIcon.textContent = getFirstLetter(bookmark.url);
this.replaceWith(defaultIcon);
};
item.appendChild(img);
} else {
const defaultIcon = document.createElement('div');
defaultIcon.className = 'default-icon';
defaultIcon.textContent = getFirstLetter(bookmark.url);
item.appendChild(defaultIcon);
}

// Title
const title = document.createElement('span');
title.textContent = bookmark.title || bookmark.url;
item.appendChild(title);

// Remove button
const removeBtn = document.createElement('div');
removeBtn.className = 'remove-btn';
removeBtn.textContent = '×';
removeBtn.onclick = function(e) {
e.preventDefault();
e.stopPropagation();
if (window.removeBookmark) {
window.removeBookmark(bookmark.id);
loadBookmarks();
}
};
item.appendChild(removeBtn);

return item;
}

// Load and display bookmarks
function loadBookmarks() {
const bar = document.getElementById('bookmarkBar');
const emptyMsg = document.getElementById('emptyMessage');

bar.querySelectorAll('.bookmark-item').forEach(el => el.remove());

let bookmarks = [];
if (window.getBookmarkBar) {
try {
const json = window.getBookmarkBar();
bookmarks = JSON.parse(json);
} catch (e) {
console.error('Error parsing bookmarks:', e);
}
}

if (bookmarks.length === 0) {
emptyMsg.style.display = 'block';
} else {
emptyMsg.style.display = 'none';
bookmarks.forEach(bm => {
const item = createBookmarkElement(bm);
bar.appendChild(item);
});
}
}

// Load bookmarks when page is ready
document.addEventListener('DOMContentLoaded', function() {
setTimeout(loadBookmarks, 100);
});

if (document.readyState === 'complete' || document.readyState === 'interactive') {
setTimeout(loadBookmarks, 100);
}
</script>

</body>

Expand Down
22 changes: 22 additions & 0 deletions assets/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,28 @@ svg#icon_defs path {
fill: #8a83ff;
}

/* Bookmark toggle coloring: highlight when page is bookmarked */
#toggle-bookmark {
color: #b6b3c9;
fill: #b6b3c9;
transition: color 0.075s ease, fill 0.075s ease;
}

#toggle-bookmark:hover {
color: #cbc9d8;
fill: #cbc9d8;
}

#toggle-bookmark.bookmarked {
color: #FFD700;
fill: #FFD700;
}

#toggle-bookmark.bookmarked:hover {
color: #ffe44d;
fill: #ffe44d;
}

/* Dropdown menu styles */
.menu-dropdown {
position: absolute;
Expand Down
53 changes: 53 additions & 0 deletions assets/ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
<path
d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z" />
</g>
<g id="svg_bookmark_outline">
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="none" stroke="currentColor" stroke-width="2"/>
</g>
<g id="svg_bookmark_filled">
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="currentColor"/>
</g>
</defs>
</svg>

Expand Down Expand Up @@ -63,6 +69,12 @@
<input onfocus="select_next_mouseup = true;"
onmouseup="if (select_next_mouseup) this.select(); select_next_mouseup = false;" type="text"
id="address"></input>
<span id="toggle-bookmark" class="icon" role="button" tabindex="0" aria-label="Toggle bookmark"
data-tooltip="Bookmark this page">
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" id="bookmark-icon">
<use xlink:href="#svg_bookmark_outline" />
</svg>
</span>
<span id="toggle-tools" class="icon" role="button" tabindex="0" aria-label="Toggle inspector"
data-tooltip="Inspector">
<svg viewBox="0 0 24 24" width="18" height="18">
Expand Down Expand Up @@ -157,6 +169,26 @@
chromeTabs.removeTab(tab);
}

// Update bookmark button state (called from C++)
function updateBookmarkButton(isBookmarked) {
const btn = document.getElementById('toggle-bookmark');
const icon = document.getElementById('bookmark-icon');
if (!btn || !icon) return;

const useEl = icon.querySelector('use');
if (useEl) {
if (isBookmarked) {
useEl.setAttribute('xlink:href', '#svg_bookmark_filled');
btn.classList.add('bookmarked');
btn.setAttribute('data-tooltip', 'Remove bookmark');
} else {
useEl.setAttribute('xlink:href', '#svg_bookmark_outline');
btn.classList.remove('bookmarked');
btn.setAttribute('data-tooltip', 'Bookmark this page');
}
}
}

// Session Restore Bar Functions
function showSessionRestoreBar(tabCount, wasCrash) {
const bar = document.getElementById('session-restore-bar');
Expand Down Expand Up @@ -215,6 +247,27 @@
document.querySelector('#forward').addEventListener('click', event => OnForward());
document.querySelector('#refresh').addEventListener('click', event => OnRefresh());
document.querySelector('#stop').addEventListener('click', event => OnStop());

// Bookmark button handler
const bookmarkBtn = document.querySelector('#toggle-bookmark');
if (bookmarkBtn) {
const toggleBookmark = () => {
if (window.OnToggleBookmark) {
OnToggleBookmark();
}
};
bookmarkBtn.addEventListener('click', event => {
event.stopPropagation();
toggleBookmark();
});
bookmarkBtn.addEventListener('keydown', event => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
toggleBookmark();
}
});
}

const inspectorBtn = document.querySelector('#toggle-tools');
if (inspectorBtn) {
const toggleInspector = () => { if (window.OnToggleTools) OnToggleTools(); };
Expand Down
Loading
Loading