Skip to main content

Overview

The tab system enables users to view different types of information (Summary, Define, Facts, AI, Translate) about selected text. Tabs are defined in a configuration array and rendered dynamically with icons, labels, and optional beta badges.

Tab Definitions

All tabs are configured in the TABS array:
content.js:25-39
const TABS = [
  { id: 'summary', label: 'Summary', labelAr: 'ملخص',
    svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>' },
  { id: 'define', label: 'Define', labelAr: 'تعريف',
    svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>' },
  { id: 'facts', label: 'Facts', labelAr: 'حقائق',
    svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>' },
  { id: 'ai', label: 'AI', labelAr: 'ذكاء',
    svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a4 4 0 0 1 4 4v1h1a3 3 0 0 1 3 3v1a3 3 0 0 1-3 3h-1v4a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2v-4H7a3 3 0 0 1-3-3v-1a3 3 0 0 1 3-3h1V6a4 4 0 0 1 4-4z"/><circle cx="9.5" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="14.5" cy="10" r="1" fill="currentColor" stroke="none"/></svg>' },
  { id: 'translate', label: 'Translate', labelAr: 'ترجمة', beta: true,
    svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m5 8 6 6"/><path d="m4 14 6-6 2-3"/><path d="M2 5h12"/><path d="M7 2h1"/><path d="m22 22-5-10-5 10"/><path d="M14 18h6"/></svg>' }
];
Tab Properties:
  • id - Unique identifier for routing and state management
  • label - English display label
  • labelAr - Arabic display label (for RTL support)
  • svg - Inline SVG icon markup
  • beta (optional) - Shows a “beta” badge on the tab
SVG icons are inlined to avoid external dependencies and ensure consistent rendering across all web pages.

Creating the Tab Bar

The createTabBar() function iterates through the TABS array and builds the navigation:
content.js:256-292
function createTabBar(language) {
  const tabBar = document.createElement('div');
  tabBar.className = 'wiki-tooltip-tabs';

  TABS.forEach(tab => {
    const tabEl = document.createElement('button');
    tabEl.className = 'wiki-tooltip-tab' + (tab.id === activeTab ? ' active' : '');
    tabEl.dataset.tab = tab.id;

    const icon = document.createElement('span');
    icon.className = 'wiki-tooltip-tab-icon';
    icon.innerHTML = tab.svg;

    tabEl.appendChild(icon);

    const label = document.createElement('span');
    label.className = 'wiki-tooltip-tab-label';
    label.textContent = language === 'ar' ? tab.labelAr : tab.label;
    tabEl.appendChild(label);

    if (tab.beta) {
      const badge = document.createElement('span');
      badge.className = 'wiki-tab-beta-badge';
      badge.textContent = 'beta';
      tabEl.appendChild(badge);
    }

    tabEl.addEventListener('click', () => {
      switchTab(tab.id);
    });

    tabBar.appendChild(tabEl);
  });

  return tabBar;
}
Rendering Steps:
  1. Create tab button with appropriate active class
  2. Add SVG icon
  3. Add localized label (English or Arabic)
  4. Conditionally render beta badge
  5. Attach click handler for tab switching
The active tab is determined by the activeTab global state variable, which defaults to 'summary'.

Tab Switching

When a user clicks a tab, switchTab() updates the UI and loads content:
content.js:294-307
function switchTab(tabId) {
  if (activeTab === tabId) return;
  activeTab = tabId;

  // Update tab UI
  const tabs = tooltip.querySelectorAll('.wiki-tooltip-tab');
  tabs.forEach(t => {
    t.classList.toggle('active', t.dataset.tab === tabId);
  });

  // Load tab content
  loadTabContent(tabId);
}
State Management:
  • Prevents redundant switching if already on the target tab
  • Updates activeTab global state
  • Toggles CSS classes for visual feedback
  • Triggers content loading for the new tab

Content Loading

The loadTabContent() function routes to the appropriate data source:
content.js:309-350
function loadTabContent(tabId) {
  const contentArea = tooltip.querySelector('#wiki-tooltip-content-area');
  if (!contentArea) return;

  // AI and Translate tabs have their own async state management
  if (tabId === 'ai') {
    loadAITab(contentArea);
    return;
  }

  if (tabId === 'translate') {
    loadTranslateTab(contentArea);
    return;
  }

  const cleanedTerm = cleanSearchTerm(currentSearchTerm, currentLanguage);

  // Check cache
  const cached = getFromCache(cleanedTerm, tabId);
  if (cached) {
    renderTabContent(tabId, cached, contentArea);
    return;
  }

  // Show loading
  clearElement(contentArea);
  contentArea.appendChild(createLoadingIndicator());

  // Fetch data
  switch (tabId) {
    case 'summary':
      fetchSummaryData(cleanedTerm);
      break;
    case 'define':
      fetchDefineData(cleanedTerm);
      break;
    case 'facts':
      fetchFactsData(cleanedTerm);
      break;
  }
}
Content Loading Flow:
  1. Check cache - Return instantly if data is cached
  2. Show loading indicator - Display spinner while fetching
  3. Fetch data - Call appropriate API via background script
  4. Render content - Display results in content area
AI and Translate tabs require API key validation, so they use specialized loading functions instead of the standard cache-and-fetch flow.

Content Rendering

Once data is available, renderTabContent() delegates to tab-specific renderers:
content.js:352-372
function renderTabContent(tabId, data, contentArea) {
  clearElement(contentArea);
  switch (tabId) {
    case 'summary':
      renderSummaryContent(data, contentArea);
      break;
    case 'define':
      renderDefineContent(data, contentArea);
      break;
    case 'facts':
      renderFactsContent(data, contentArea);
      break;
    case 'ai':
      renderAITab(contentArea);
      break;
    case 'translate':
      renderTranslateTab(contentArea, data);
      break;
  }
}

Adding New Tabs

To add a new tab:
  1. Add to TABS array:
{ id: 'mynew', label: 'My New Tab', labelAr: 'تبويب جديد',
  svg: '<svg>...</svg>', beta: true }
  1. Add routing in loadTabContent():
case 'mynew':
  fetchMyNewData(cleanedTerm);
  break;
  1. Add renderer in renderTabContent():
case 'mynew':
  renderMyNewContent(data, contentArea);
  break;
New tabs automatically inherit RTL support, caching, and loading indicators through the shared infrastructure.

Build docs developers (and LLMs) love