add files
This commit is contained in:
216
assets/wvbrowser_ui/controls_ui/tabs.js
Normal file
216
assets/wvbrowser_ui/controls_ui/tabs.js
Normal file
@ -0,0 +1,216 @@
|
||||
var tabs = new Map();
|
||||
var tabIdCounter = 0;
|
||||
var activeTabId = 0;
|
||||
const INVALID_TAB_ID = 0;
|
||||
|
||||
function getNewTabId() {
|
||||
return ++tabIdCounter;
|
||||
}
|
||||
|
||||
function isValidTabId(tabId) {
|
||||
return tabId != INVALID_TAB_ID && tabs.has(tabId);
|
||||
}
|
||||
|
||||
function createNewTab(shouldBeActive) {
|
||||
const tabId = getNewTabId();
|
||||
|
||||
var message = {
|
||||
message: commands.MG_CREATE_TAB,
|
||||
args: {
|
||||
tabId: parseInt(tabId),
|
||||
active: shouldBeActive || false
|
||||
}
|
||||
};
|
||||
|
||||
window.chrome.webview.postMessage(message);
|
||||
|
||||
tabs.set(parseInt(tabId), {
|
||||
title: 'New Tab',
|
||||
uri: '',
|
||||
uriToShow: '',
|
||||
favicon: 'img/favicon.png',
|
||||
isFavorite: false,
|
||||
isLoading: false,
|
||||
canGoBack: false,
|
||||
canGoForward: false,
|
||||
securityState: 'unknown',
|
||||
historyItemId: INVALID_HISTORY_ID
|
||||
});
|
||||
|
||||
loadTabUI(tabId);
|
||||
|
||||
if (shouldBeActive) {
|
||||
switchToTab(tabId, false);
|
||||
}
|
||||
}
|
||||
|
||||
function switchToTab(id, updateOnHost) {
|
||||
if (!id) {
|
||||
console.log('ID not provided');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the tab to switch to is valid
|
||||
if (!isValidTabId(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to switch if the tab is already active
|
||||
if (id == activeTabId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the tab element to switch to
|
||||
var tab = document.getElementById(`tab-${id}`);
|
||||
if (!tab) {
|
||||
console.log(`Can't switch to tab ${id}: element does not exist`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Change the style for the previously active tab
|
||||
if (isValidTabId(activeTabId)) {
|
||||
const activeTabElement = document.getElementById(`tab-${activeTabId}`);
|
||||
|
||||
// Check the previously active tab element does actually exist
|
||||
if (activeTabElement) {
|
||||
activeTabElement.className = 'tab';
|
||||
}
|
||||
}
|
||||
|
||||
// Set tab as active
|
||||
tab.className = 'tab-active';
|
||||
activeTabId = id;
|
||||
|
||||
// Instruct host app to switch tab
|
||||
if (updateOnHost) {
|
||||
var message = {
|
||||
message: commands.MG_SWITCH_TAB,
|
||||
args: {
|
||||
tabId: parseInt(activeTabId)
|
||||
}
|
||||
};
|
||||
|
||||
window.chrome.webview.postMessage(message);
|
||||
}
|
||||
|
||||
updateNavigationUI(commands.MG_SWITCH_TAB);
|
||||
}
|
||||
|
||||
function closeTab(id) {
|
||||
// If closing tab was active, switch tab or close window
|
||||
if (id == activeTabId) {
|
||||
if (tabs.size == 1) {
|
||||
// Last tab is closing, shut window down
|
||||
tabs.delete(id);
|
||||
closeWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
// Other tabs are open, switch to rightmost tab
|
||||
var tabsEntries = Array.from(tabs.entries());
|
||||
var lastEntry = tabsEntries.pop();
|
||||
if (lastEntry[0] == id) {
|
||||
lastEntry = tabsEntries.pop();
|
||||
}
|
||||
switchToTab(lastEntry[0], true);
|
||||
}
|
||||
|
||||
// Remove tab element
|
||||
var tabElement = document.getElementById(`tab-${id}`);
|
||||
if (tabElement) {
|
||||
tabElement.parentNode.removeChild(tabElement);
|
||||
}
|
||||
// Remove tab from map
|
||||
tabs.delete(id);
|
||||
|
||||
var message = {
|
||||
message: commands.MG_CLOSE_TAB,
|
||||
args: {
|
||||
tabId: id
|
||||
}
|
||||
};
|
||||
|
||||
window.chrome.webview.postMessage(message);
|
||||
}
|
||||
|
||||
function updateFaviconURI(tabId, src) {
|
||||
let tab = tabs.get(tabId);
|
||||
if (tab.favicon != src) {
|
||||
let img = new Image();
|
||||
|
||||
// Update favicon element on successful load
|
||||
img.onload = () => {
|
||||
console.log('Favicon loaded');
|
||||
tab.favicon = src;
|
||||
|
||||
if (tabId == activeTabId) {
|
||||
updatedFaviconURIHandler(tabId, tab);
|
||||
}
|
||||
};
|
||||
|
||||
if (src) {
|
||||
// Try load from root on failed load
|
||||
img.onerror = () => {
|
||||
console.log('Cannot load favicon from link, trying with root');
|
||||
updateFaviconURI(tabId, '');
|
||||
};
|
||||
} else {
|
||||
// No link for favicon, try loading from root
|
||||
try {
|
||||
let tabURI = new URL(tab.uri);
|
||||
src = `${tabURI.origin}/favicon.ico`;
|
||||
} catch(e) {
|
||||
console.log(`Could not parse tab ${tabId} URI`);
|
||||
}
|
||||
|
||||
img.onerror = () => {
|
||||
console.log('No favicon in site root. Using default favicon.');
|
||||
tab.favicon = 'img/favicon.png';
|
||||
updatedFaviconURIHandler(tabId, tab);
|
||||
};
|
||||
}
|
||||
|
||||
img.src = src;
|
||||
}
|
||||
}
|
||||
|
||||
function updatedFaviconURIHandler(tabId, tab) {
|
||||
updateNavigationUI(commands.MG_UPDATE_FAVICON);
|
||||
|
||||
// Update favicon in history item
|
||||
if (tab.historyItemId != INVALID_HISTORY_ID) {
|
||||
updateHistoryItem(tab.historyItemId, historyItemFromTab(tabId));
|
||||
}
|
||||
}
|
||||
|
||||
function favoriteFromTab(tabId) {
|
||||
if (!isValidTabId(tabId)) {
|
||||
console.log('Invalid tab ID');
|
||||
return;
|
||||
}
|
||||
|
||||
let tab = tabs.get(tabId);
|
||||
let favicon = tab.favicon == 'img/favicon.png' ? '../controls_ui/' + tab.favicon : tab.favicon;
|
||||
return {
|
||||
uri: tab.uri,
|
||||
uriToShow: tab.uriToShow,
|
||||
title: tab.title,
|
||||
favicon: favicon
|
||||
};
|
||||
}
|
||||
|
||||
function historyItemFromTab(tabId) {
|
||||
if (!isValidTabId(tabId)) {
|
||||
console.log('Invalid tab ID');
|
||||
return;
|
||||
}
|
||||
|
||||
let tab = tabs.get(tabId);
|
||||
let favicon = tab.favicon == 'img/favicon.png' ? '../controls_ui/' + tab.favicon : tab.favicon;
|
||||
return {
|
||||
uri: tab.uri,
|
||||
title: tab.title,
|
||||
favicon: favicon,
|
||||
timestamp: new Date()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user