File size: 4,818 Bytes
22feb09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Tab management
class TabManager {
    constructor() {
        this.tabs = [];
        this.activeTabId = null;
        this.tabCounter = 0;
        this.init();
    }

    init() {
        this.tabBar = document.getElementById('tab-bar');
        this.browserContainer = document.getElementById('browser-container');
        this.newTabBtn = document.getElementById('new-tab-btn');
        this.newTabBtn.addEventListener('click', () => this.addTab());
        
        // Add initial tab
        this.addTab();
    }

    addTab(url = '') {
        const tabId = ++this.tabCounter;
        const tab = {
            id: tabId,
            url: url || '',
            title: 'New Tab',
            favicon: '',
            iframe: document.createElement('iframe')
        };

        tab.iframe.className = 'w-full h-full rounded-lg hidden';
        tab.iframe.sandbox = 'allow-same-origin allow-scripts allow-popups allow-forms';
        this.browserContainer.appendChild(tab.iframe);

        const tabElement = document.createElement('button');
        tabElement.className = 'px-4 py-1 rounded-t-lg tab-inactive flex items-center space-x-2 smooth-transition';
        tabElement.dataset.tabId = tabId;

        const favicon = document.createElement('img');
        favicon.className = 'w-4 h-4';
        favicon.src = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDJDNi40ODcgMiAyIDYuNDg3IDIgMTJzNC40ODcgMTAgMTAgMTAgMTAtNC40ODcgMTAtMTBTMTcuNTEzIDIgMTIgMnptMCAxOGMtNC40MSAwLTgtMy41OS04LThzMy41OS04IDgtOCA4IDMuNTkgOCA4LTMuNTkgOC04IDh6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==';
        favicon.alt = '';

        const title = document.createElement('span');
        title.className = 'truncate max-w-xs';
        title.textContent = 'New Tab';

        const closeBtn = document.createElement('button');
        closeBtn.className = 'ml-2 hover:text-red-400';
        closeBtn.innerHTML = '<i data-feather="x" class="w-3 h-3"></i>';
        closeBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            this.closeTab(tabId);
        });

        tabElement.appendChild(favicon);
        tabElement.appendChild(title);
        tabElement.appendChild(closeBtn);

        tabElement.addEventListener('click', () => this.switchTab(tabId));

        this.tabBar.insertBefore(tabElement, this.newTabBtn);
        this.tabs.push({
            ...tab,
            element: tabElement,
            faviconElement: favicon,
            titleElement: title
        });

        this.switchTab(tabId);
        feather.replace();
    }

    switchTab(tabId) {
        this.tabs.forEach(tab => {
            const isActive = tab.id === tabId;
            tab.element.classList.toggle('tab-active', isActive);
            tab.element.classList.toggle('tab-inactive', !isActive);
            tab.iframe.classList.toggle('hidden', !isActive);
        });

        this.activeTabId = tabId;
        const activeTab = this.getActiveTab();
        
        // Focus the iframe
        if (activeTab.iframe.contentWindow) {
            activeTab.iframe.contentWindow.focus();
        }
    }

    closeTab(tabId) {
        if (this.tabs.length <= 1) {
            return; // Don't close the last tab
        }

        const tabIndex = this.tabs.findIndex(tab => tab.id === tabId);
        if (tabIndex === -1) return;

        const tab = this.tabs[tabIndex];
        this.browserContainer.removeChild(tab.iframe);
        this.tabBar.removeChild(tab.element);
        this.tabs.splice(tabIndex, 1);

        if (this.activeTabId === tabId) {
            this.switchTab(this.tabs[Math.max(0, tabIndex - 1)].id);
        }
    }

    getActiveTab() {
        return this.tabs.find(tab => tab.id === this.activeTabId);
    }

    navigateActiveTab(url) {
        const tab = this.getActiveTab();
        if (!tab) return;

        try {
            // Simple proxy handling - in a real proxy, you'd need server-side handling
            tab.iframe.src = url;
            tab.url = url;
            tab.titleElement.textContent = 'Loading...';
        } catch (error) {
            console.error('Navigation error:', error);
        }
    }
}

// Initialize the proxy when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    const tabManager = new TabManager();
    window.tabManager = tabManager; // Make it accessible for debugging

    // Example of how you might handle URL navigation
    // In a real implementation, you'd have a proper proxy backend
    document.getElementById('navigate-btn')?.addEventListener('click', () => {
        const urlInput = document.getElementById('url-input');
        if (urlInput && urlInput.value) {
            tabManager.navigateActiveTab(urlInput.value);
        }
    });
});