Quiz AI - Project Overview

Generate interactive quizzes from any webpage content using AI

Project Description

Quiz AI is a Chrome extension that generates interactive quizzes from any webpage content using artificial intelligence. The extension extracts content from the current webpage and uses Google's Gemini 1.5 Pro API to generate quizzes based on user preferences (quiz type, difficulty, and number of questions).

Users can take the generated quizzes, check their answers, and review correct answers to test their understanding of the webpage content.

Technology Stack

JavaScript
Chrome Extension API
HTML/CSS
Tailwind CSS
Google Gemini API
JSON

High-Level Architecture

graph TD User[User] --- Browser[Chrome Browser] Browser --- Extension[Quiz AI Extension] Extension --- Popup[Popup Interface] Extension --- ContentScript[Content Script] Extension --- BackgroundService[Background Service] ContentScript --- WebpageContent[Webpage Content] Popup --- GeminiAPI[Google Gemini API] subgraph "Extension Components" PopupUI[Popup UI] --- QuizConfig[Quiz Configuration] QuizConfig --- QuizGeneration[Quiz Generation] QuizGeneration --- QuizDisplay[Quiz Display] QuizDisplay --- Scoring[Scoring System] end subgraph "Content Script Components" ContentExtraction[Content Extraction] --- ContentCleaning[Content Cleaning] ContentCleaning --- ContentFormatting[Content Formatting] end Extension --- Extension_Components[Extension Components] ContentScript --- Content_Script_Components[Content Script Components] classDef browser fill:#d1e7dd,stroke:#20c997; classDef extension fill:#cfe2ff,stroke:#0d6efd; classDef content fill:#e2e3e5,stroke:#6c757d; classDef api fill:#f8d7da,stroke:#dc3545; class Browser browser; class Extension extension; class ContentScript content; class GeminiAPI api;

Detailed Component Architecture

graph TD subgraph "Popup" PopupHTML["popup.html"] --> UIElements["UI Elements"] UIElements --> QuizTypeSelect["Quiz Type Selection"] UIElements --> DifficultySelect["Difficulty Selection"] UIElements --> QuestionCountInput["Question Count Input"] UIElements --> GenerateButton["Generate Button"] UIElements --> LoadingIndicator["Loading Indicator"] UIElements --> QuizContainer["Quiz Container"] PopupJS["popup.js"] --> EventListeners["Event Listeners"] EventListeners --> GenerateButtonClick["Generate Button Click"] EventListeners --> FormSubmit["Form Submit"] EventListeners --> ShowAnswersClick["Show Answers Click"] PopupJS --> APIIntegration["API Integration"] APIIntegration --> GenerateQuizFunc["generateQuiz() Function"] APIIntegration --> ParseQuizFunc["parseQuizResponse() Function"] PopupJS --> UIFunctions["UI Functions"] UIFunctions --> DisplayQuizFunc["displayQuiz() Function"] UIFunctions --> CheckAnswersFunc["checkAnswers() Function"] UIFunctions --> DisplayAnswersFunc["displayAnswers() Function"] end subgraph "Content Script" ContentJS["content.js"] --> MessageListener["Message Listener"] MessageListener --> GetPageContentAction["getPageContent Action"] ContentJS --> ExtractContentFunc["extractPageContent() Function"] ExtractContentFunc --> ArticleExtraction["Article Extraction"] ExtractContentFunc --> MainExtraction["Main Tag Extraction"] ExtractContentFunc --> ContainerExtraction["Container Extraction"] ExtractContentFunc --> BodyCloneExtraction["Body Clone Extraction"] ExtractContentFunc --> ContentCleaning["Content Cleaning"] end subgraph "Background Service" BackgroundJS["background.js"] --> InstallListener["Install Listener"] BackgroundJS --> MessageListener2["Message Listener"] MessageListener2 --> SaveQuizAction["saveQuiz Action"] SaveQuizAction --> StorageAPI["Chrome Storage API"] end PopupJS -.-> ContentJS["Sends Messages"] ContentJS -.-> PopupJS["Returns Content"] PopupJS -.-> BackgroundJS["Sends Quiz Data"] classDef popup fill:#f0f7ff,stroke:#3b82f6; classDef content fill:#f0fdf4,stroke:#22c55e; classDef background fill:#fef3c7,stroke:#d97706; class Popup popup; class Content_Script content; class Background_Service background;

Project Structure

quiz-ai/ ├── manifest.json # Extension configuration ├── popup.html # User interface ├── popup.js # Main functionality ├── content.js # Page content extraction ├── background.js # Background service worker ├── images/ # Extension icons │ ├── icon16.png │ ├── icon48.png │ └── icon128.png ├── README.md # Documentation └── LICENSE # MIT License

Data Flow Diagram

sequenceDiagram participant User participant Popup as Popup UI participant Content as Content Script participant API as Gemini API participant Background as Background Service User->>Popup: Click Extension Icon Popup->>User: Display Quiz Configuration User->>Popup: Set Quiz Parameters User->>Popup: Click "Generate Quiz" Popup->>Popup: Show Loading State Popup->>Content: Request Page Content Content->>Content: Extract Content Content->>Popup: Return Page Content Popup->>API: Send Content + Parameters API->>Popup: Return Generated Quiz Popup->>Popup: Parse Quiz Response Popup->>Popup: Display Quiz User->>Popup: Complete Quiz User->>Popup: Submit Quiz Popup->>Popup: Calculate Score Popup->>Popup: Display Results User->>Popup: Click "Show Answers" Popup->>Popup: Display Correct Answers User->>Popup: Save Quiz (Optional) Popup->>Background: Send Quiz Data Background->>Background: Store Quiz

Detailed API Integration

graph LR subgraph "Chrome Extension API" Tabs["chrome.tabs"] --- Query["query()"] Tabs --- SendMessage["sendMessage()"] Scripting["chrome.scripting"] --- ExecuteScript["executeScript()"] Runtime["chrome.runtime"] --- OnMessage["onMessage"] Runtime --- SendMessage2["sendMessage()"] Storage["chrome.storage"] --- LocalSet["local.set()"] Storage --- LocalGet["local.get()"] end subgraph "Gemini API" GenerateContent["generateContent"] --- Prompt["Prompt Construction"] GenerateContent --- Response["Response Parsing"] GenerateContent --- Config["Generation Config"] Config --- Temperature["temperature"] Config --- MaxTokens["maxOutputTokens"] Config --- SafetySettings["safetySettings"] end Query --- GetActiveTab["Get Active Tab"] ExecuteScript --- InjectContentScript["Inject Content Script"] SendMessage --- RequestContent["Request Page Content"] OnMessage --- HandleMessages["Handle Messages"] SendMessage2 --- SaveQuiz["Save Quiz"] LocalSet --- StoreQuiz["Store Quiz Data"] GenerateContent --- CreateQuiz["Create Quiz"] Prompt --- ContentFormatting["Format Content"] Response --- ParseJSON["Parse JSON Response"] classDef chrome fill:#dbeafe,stroke:#3b82f6; classDef gemini fill:#dcfce7,stroke:#22c55e; class Chrome_Extension_API chrome; class Gemini_API gemini;

Extension Activation Flow

graph LR A["User Clicks Extension Icon"] --> B["Load popup.html"] B --> C["Execute popup.js"] C --> D["Add Event Listeners"] D --> E["Wait for User Input"] E --> F["User Configures Quiz"] F --> G["User Clicks Generate"] G --> H["Get Current Tab"] H --> I["Inject Content Script"] I --> J["Request Page Content"] J --> K["Process Content"] K --> L["Call Gemini API"] L --> M["Display Quiz"] style A fill:#d4f4e2,stroke:#34d399,stroke-width:3px,color:#065f46,font-weight:bold style B fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style C fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style D fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style E fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style F fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style G fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style H fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style I fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style J fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style K fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style L fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style M fill:#d4f4e2,stroke:#34d399,stroke-width:3px,color:#065f46,font-weight:bold

User Flow

graph LR A["Start"] --> B["Browse a Webpage"] B --> C["Click Quiz AI Icon"] C --> D["Select Quiz Type"] D --> E["Choose Difficulty"] E --> F["Set Question Count"] F --> G["Click Generate Quiz"] G --> H["Wait for Generation"] H --> I["Take Quiz"] I --> J["Submit Answers"] J --> K["View Score"] K --> L["Review Correct Answers"] style A fill:#d4f4e2,stroke:#34d399,stroke-width:3px,color:#065f46,font-weight:bold style B fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style C fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style D fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style E fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style F fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style G fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style H fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style I fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style J fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af style K fill:#fecaca,stroke:#ef4444,stroke-width:3px,color:#7f1d1d,font-weight:bold style L fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af

Content Extraction Implementation

graph TD subgraph "Content Extraction Process" Start[Start Extraction] --> CheckArticle[Check for Article Tag] CheckArticle --> ArticleExists{Article Exists?} ArticleExists -->|Yes| ExtractArticle[Extract Article Text] ArticleExists -->|No| CheckMain[Check for Main Tag] CheckMain --> MainExists{Main Exists?} MainExists -->|Yes| ExtractMain[Extract Main Text] MainExists -->|No| CheckContainers[Check Common Containers] CheckContainers --> ContainerExists{Container Exists?} ContainerExists -->|Yes| ExtractContainer[Extract Container Text] ContainerExists -->|No| CloneBody[Clone Body Element] CloneBody --> RemoveNonContent[Remove Non-Content Elements] RemoveNonContent --> ExtractBodyText[Extract Body Text] ExtractArticle --> CleanContent[Clean Content] ExtractMain --> CleanContent ExtractContainer --> CleanContent ExtractBodyText --> CleanContent CleanContent --> TrimWhitespace[Trim Whitespace] TrimWhitespace --> NormalizeSpaces[Normalize Spaces] NormalizeSpaces --> LimitLength[Limit Content Length] LimitLength --> ReturnContent[Return Content] end classDef process fill:#f0f7ff,stroke:#3b82f6; class Content_Extraction_Process process;

Quiz Generation Process

sequenceDiagram participant Popup as Popup.js participant API as Gemini API participant Parser as Response Parser participant Display as Quiz Display Popup->>Popup: Call generateQuiz() Popup->>Popup: Prepare API URL and Key Popup->>Popup: Construct Prompt Note over Popup: Include content, quiz type, difficulty, and question count Popup->>API: Send API Request API->>API: Process Content API->>API: Generate Quiz Questions API->>Popup: Return JSON Response Popup->>Parser: Parse Response Parser->>Parser: Extract JSON Parser->>Parser: Validate Structure Parser->>Popup: Return Structured Quiz Popup->>Display: Call displayQuiz() Display->>Display: Generate HTML Display->>Display: Add Event Listeners Display->>Popup: Show Quiz UI

Quiz Display Implementation

graph TD DisplayQuiz["displayQuiz() Function"] --> GenerateHTML["Generate Quiz HTML"] GenerateHTML --> CreateForm["Create Quiz Form"] CreateForm --> AddQuestions["Add Questions"] AddQuestions --> AddOptions["Add Answer Options"] AddOptions --> AddButtons["Add Submit/Show Answers Buttons"] AddButtons --> AttachListeners["Attach Event Listeners"] AttachListeners --> FormSubmit["Form Submit Listener"] AttachListeners --> ShowAnswersClick["Show Answers Button Listener"] FormSubmit --> CheckAnswers["checkAnswers() Function"] CheckAnswers --> CalculateScore["Calculate Score"] CheckAnswers --> DisplayScore["Display Score"] ShowAnswersClick --> DisplayAnswers["displayAnswers() Function"] DisplayAnswers --> ShowCorrectAnswers["Show Correct Answers"] DisplayAnswers --> HighlightOptions["Highlight Options"] classDef display fill:#f0f7ff,stroke:#3b82f6 class DisplayQuiz,GenerateHTML,CreateForm,AddQuestions,AddOptions,AddButtons,AttachListeners,FormSubmit,ShowAnswersClick,CheckAnswers,CalculateScore,DisplayScore,DisplayAnswers,ShowCorrectAnswers,HighlightOptions display

Message Passing Architecture

sequenceDiagram participant Popup as Popup (popup.js) participant Content as Content Script (content.js) participant Background as Background Service (background.js) Note over Popup,Background: Chrome Extension Message Passing Popup->>Content: chrome.tabs.sendMessage({action: "getPageContent"}) Content->>Content: Extract page content Content->>Popup: sendResponse({content, success: true}) Popup->>Background: chrome.runtime.sendMessage({action: "saveQuiz", quiz: quizData}) Background->>Background: Store quiz in chrome.storage.local Background->>Popup: sendResponse({success: true})

State Management Flow

graph TD subgraph "Extension State" ExtensionState[Extension State] --> UIState[UI State] ExtensionState --> QuizState[Quiz State] ExtensionState --> StorageState[Storage State] UIState --> LoadingState[Loading State] UIState --> QuizDisplayState[Quiz Display State] UIState --> ErrorState[Error State] QuizState --> QuizConfig[Quiz Configuration] QuizState --> QuizQuestions[Quiz Questions] QuizState --> UserAnswers[User Answers] QuizState --> QuizResults[Quiz Results] StorageState --> SavedQuizzes[Saved Quizzes] end classDef state fill:#f0f7ff,stroke:#3b82f6; class Extension_State state;

Quiz Response Format

graph TD subgraph "Quiz JSON Format" QuizJSON[Quiz JSON Array] --> Question1[Question 1] QuizJSON --> Question2[Question 2] QuizJSON --> QuestionN[Question N] Question1 --> Q1Text[question] Question1 --> Q1Options[options] Question1 --> Q1Answer[correct_answer] Q1Options --> Option1[Option 1] Q1Options --> Option2[Option 2] Q1Options --> Option3[Option 3] Q1Options --> Option4[Option 4] end classDef json fill:#f0f7ff,stroke:#3b82f6; class Quiz_JSON_Format json;

Development Workflow

sequenceDiagram participant Developer participant Git as Git Repository participant Chrome as Chrome Browser participant Extension as Extension Manager Developer->>Git: Clone Repository Developer->>Developer: Edit Source Files Developer->>Chrome: Open chrome://extensions Developer->>Extension: Enable Developer Mode Developer->>Extension: Load Unpacked Extension Chrome->>Developer: Test Extension Developer->>Developer: Make Changes Developer->>Chrome: Reload Extension Developer->>Git: Commit Changes

Future Enhancements

graph TD subgraph "Planned Features" Export[Export Functionality] --> ExportPDF[Export to PDF] Export --> ExportCSV[Export to CSV] Templates[Quiz Templates] --> SubjectTemplates[Subject-Specific Templates] Templates --> CustomTemplates[Custom Templates] Templates --> SavedTemplates[Saved Templates] History[Quiz History] --> SavedQuizzes[Saved Quizzes] History --> QuizStats[Quiz Statistics] History --> ProgressTracking[Progress Tracking] Integration[Additional Integrations] --> LMSIntegration[LMS Integration] Integration --> SocialSharing[Social Sharing] Integration --> AIImprovements[Enhanced AI Models] end classDef future fill:#f0f7ff,stroke:#3b82f6; class Planned_Features future;

Getting Started

To run the extension locally:

  1. Clone the repository
  2. Configure the API key:
  3. Load the extension in Chrome:
  4. Use the extension:

Conclusion

Quiz AI is a powerful Chrome extension that leverages artificial intelligence to generate interactive quizzes from any webpage content. With its intuitive interface and seamless integration with Google's Gemini API, Quiz AI makes it easy to test your understanding of any online material.

The extension's architecture utilizes Chrome's Extension API and modern web technologies to provide a smooth quiz generation and taking experience, while its modular design makes it easy to extend with new features in the future.