# WebTalk Project Overview ## Project Description WebTalk is a pure JavaScript implementation of a HyperTalk interpreter, designed to run in modern web browsers without any server-side dependencies. It provides a nostalgic yet functional recreation of the classic HyperCard experience, allowing users to create interactive stacks with cards, buttons, fields, graphics, and multimedia objects, as well as write and execute HyperTalk scripts. ## Project Structure ### Core Files - **index.html**: Main application entry point with the message box and output area - **js/interpreter.js**: Core interpreter logic for parsing and executing HyperTalk commands - **js/extended-functions.js**: Extended functions and commands implementation - **js/objects.js**: Object definitions and management (buttons, fields, graphics, players) - **js/player.js**: Video player object implementation - **js/main.js**: Main application logic and event handling - **js/file-operations.js**: File handling operations - **css/style.css**: Main application styling - **testing-enhanced.html**: Enhanced test runner with expected output validation - **css/testing.css**: Test runner styling - **js/test-suite.js**: Test suite definitions and runner logic - **js/testing.js**: Unified test runner for all testing pages - **IMPORTANT!: I tend to never test by setting up a localhost, and I don't run this through python. I found that doing so just adds extra points of failure and is actually counter-productive for testing. Instead, I load the index.html in a browser manually and test any new changes or additions methodically. - **Also, I don't add tests to testing-enhanced.html until I know that my newly added function is manually tried and tested. ### Key Components #### Interpreter (interpreter.js) The interpreter is the core of the WebTalk system. It parses and executes HyperTalk commands and expressions. Key features include: - Command parsing and execution - Expression evaluation - Variable management - Property handling - Dialog creation (ask, answer, etc.) - Sound playback - Script execution - Object counting and property access The interpreter uses a token-based parsing approach rather than a formal grammar. It processes commands through pattern matching using regular expressions. #### Objects Management (objects.js) This module handles the creation and management of HyperTalk objects: - Buttons - Fields - Graphics - Lines (default) - Ovals - Various shapes (pentagon, hexagon, octagon, decagon, arrows) - Players (video objects) - Scrollbars - Cards - Context menus for objects - Script editor - Drag-and-drop functionality Objects are created with appropriate DOM elements and event listeners. Each object has properties that can be accessed and modified through HyperTalk scripts. #### Player Object (player.js) Implements video player functionality: - HTML5 video element creation and management - Video source setting via filename property - Aspect ratio maintenance during resizing - Mode-specific behavior (edit vs. browse mode) - Video controls in browse mode - Selection and resizing in edit mode #### File Operations (file-operations.js) This module handles saving and loading stacks: - Serializes all objects and their properties to JSON - Preserves object properties, scripts, and visual attributes - Handles special attributes for different object types - Integrates with objects.js to register loaded objects with the DOM - Extends the interpreter with 'save stack as' and 'load stack as' commands - Generic property handling for all object types The file operations system works by: 1. Collecting all objects from WebTalkObjects.objects Map 2. Serializing their properties, scripts, and type-specific attributes 3. Saving the data as a JSON file 4. When loading, recreating each object with the appropriate type and shape 5. Applying all saved properties and attributes to restore the exact state #### Main Application (main.js) Handles the core application logic: - Initializing the interpreter - Setting up event listeners - Running commands from the message box - Displaying output - Keyboard shortcuts (CTRL+M to toggle message box, CTRL+Enter to run commands) - Mode switching (browse/edit) - Palette command execution #### Extended Functions (extended-functions.js) Implements additional functions beyond the core HyperTalk language: - Mathematical functions - String manipulation - Date and time functions - Sound functions - List operations - Object counting functions #### Testing Framework (test-suite.js, testing.js) A comprehensive testing framework for validating the interpreter's functionality: - Test case definitions - Test execution - Result reporting - Expected output validation - Custom validators for complex outputs - Support for skipping dialog and sound tests ## Key Features ### HyperTalk Language Support - Variables and expressions - Control structures (if/then/else, repeat) - Object existence checking (if there is...) - Commands (put, get, ask, answer, etc.) - Functions (offset, length, matchText, replaceRegex, formatNumber, etc.) - Properties (the date, the time, etc.) - Object references (button "name", field "name", player "name", etc.) - Operators (+, -, *, /, &, etc.) - Object counting (the number of [objects] of [container]) - String operations (contains, is in, starts with, ends with) ### UI Features - Message box for command input - Output area for command results - Card area for objects - Context menus for objects - Script editor - Mode switching (browse/edit) - Keyboard shortcuts - Middle mouse button for mode toggle - Palette buttons for quick object creation ### Dialog Support - ask dialogs (with optional pre-filled input) - answer dialogs - ask password dialogs - ask list dialogs ### Multimedia Support - Play sound files - Play musical notes - Tempo control - Wait for completion option - Video playback via player objects ### Object Types - Buttons - Fields - Graphics (lines, ovals, various shapes) - Players (video objects) - Cards ### Field Styling Implementation - Field content uses a two-part approach to separate content from styling: - Raw text content is stored with simple `\n` newlines for line breaks - Styling is applied using `` tags with inline styles - Formatting commands are stored in a `formattingCommands` property for persistence - See the "// Store the formatting command for later restoration" comment in objects.js - Supported chunk expressions for styling: - Line chunks: `set the textsize of line 2 of field "myfield" to 24` - Character chunks: `set the textsize of char 1 to 4 of line 4 of field "myfield" to 9` - Word chunks: `set the textsize of word 1 of field "myfield" to tvar` - Word of line chunks: `set the textsize of word 3 of line 2 of field "myfield" to 18` - Supported style properties: - `textsize`: Font size in pixels - `textcolor`/`textcolour`: Text color - `textstyle`: Bold, italic, underline, or plain - `textfont`/`fontfamily`: Font family - `lineheight`: Line height ### Field Styling Implementation Notes #### Word of Line Styling Fix (2025-06-24) - **Issue**: The `set ... word ... of line ...` styling command was failing silently and halting script execution. - **Root Cause**: In `objects.js`, the `setWordProperty` function was reconstructing the entire field's content from plain text when styling a word in a specific line, which stripped all existing HTML formatting. - **Fix Implementation**: - Modified `setWordProperty` in `objects.js` to conditionally handle styling differently when a line number is provided. - When styling a word in a specific line, it now: 1. Isolates just the target line's HTML 2. Finds the target word within that line 3. Applies styling only to that word 4. Updates only that line in the field's content 5. Preserves all HTML formatting in other lines - For words without a line specifier, it continues to use the original approach. - This approach follows the same pattern used in `setLineProperty`, which was already working correctly. - **Files Modified**: - `/js/objects.js`: Updated `setWordProperty` function to conditionally handle line-specific word styling - `/js/interpreter.js`: Previously added regex and logic to handle `word ... of line ...` chunk expressions ## User Interface ### Main Interface (index.html) - Card area for displaying objects - Message box for entering commands - Output area for displaying results - CTRL+M toggles visibility of message box and output area - CTRL+Enter executes the current command - Middle mouse button click toggles between browse and edit modes - Palette buttons for creating various object types ### Testing Interface (testing-enhanced.html) - Test controls (Run Tests, Play Sounds, Show Dialogs) - Test summary (Tests Run, Tests Passed, Tests Failed, Tests Skipped) - Test results display with script, output, and expected output - Color-coded test results (green for passed, red for failed, orange for skipped) - Tests for enhanced ask command with pre-filled input ## Styling ### Main Application Styling (style.css) - Card styling - Message box styling - Output area styling - Object styling (buttons, fields, graphics, players) - Dialog styling - Context menu styling ### Testing Styling (testing.css) - Test controls styling - Test summary styling - Test results styling - Color-coding for test statuses ## Dialogs and Alerts All dialogs and alerts use the 'dialog-alert' class for consistent styling: - Background color: rgb(28, 28, 28) - Text color: white - Input fields with dark backgrounds - Buttons with appropriate styling - Support for pre-filled input in ask dialogs ## Recent Enhancements 1. **Video Player Object**: Implemented a new player object type for embedding and controlling video content. 2. **Enhanced Ask Command**: Updated the ask command to support pre-filled input fields with the syntax "ask [prompt] with [initial value]". 3. **Object Counting**: Added support for counting objects with "the number of [objects] of [container]" syntax. 4. **Palette Buttons**: Enhanced palette buttons with multi-line command sequences for creating objects with dynamic naming. 5. **Fixed duplicate output issue**: Modified the "put" command to avoid returning the value when the outputHandler is used. 6. **Added CTRL+M shortcut**: Toggle visibility of message box and output area. 7. **Added global CTRL+Enter**: Run commands from message box regardless of focus. 8. **Added middle mouse button mode toggle**: Click middle mouse button on card to toggle between edit and browse modes. 9. **Enhanced testing with expected outputs**: Modified testing framework to support expected output validation. 10. **Fixed "is in" operator**: Ensured proper string return values for boolean operations. 11. **Added script editing for graphics**: Enabled right-click context menu for graphics to edit scripts. 12. **Improved dialog styling**: Standardized dialog appearance with dark theme. 13. **Enhanced test result display**: Added clear visual distinction for skipped tests. 14. **Added oval graphics support**: Implemented oval graphics with properties and save/load functionality. 15. **Added "if there is..." condition**: Added support for checking object existence with "if there is a [type] [name] then..." syntax. 16. **Improved property handling**: Enhanced the property system with a more generic approach for saving and loading object properties. 17. **Added isOdd function**: Implemented isOdd() function to check if a number is odd, returning "true" or "false". 18. **Added isPrime function**: Implemented isPrime() function to determine if a number is prime, with optimized checks for efficiency. 19. **Added replaceRegex function**: Implemented replaceRegex(pattern, replacement, text, [flags]) function for powerful string manipulation using regular expressions. Supports all JavaScript regex features including optional flags for case-insensitivity and other options. 20. **Added scrollbarDrag message handler**: Implemented a scrollbarDrag message handler for field objects that gets triggered when a field is scrolled (via mouse wheel, programmatically with "set the vscroll", or scroll track). The handler receives the new scroll position as a parameter: `on scrollbarDrag pNewPosition`. ## Known Limitations 1. Some advanced HyperTalk features may not be fully implemented. 2. No built-in persistence for stacks (might require server-side components). ## Development Guidelines 1. Follow existing code patterns and conventions. 2. Use HyperTalk-style comments (-- for hypertalk scripts, and // for javascripts). 3. Test changes thoroughly, and manually. Use the testing framework. 4. Make minimal, targeted changes to avoid breaking existing functionality. 5. Maintain backward compatibility with existing scripts. 6. Document new features and changes. 7. When implementing new object types, follow the pattern in objects.js and create a dedicated file for complex implementations. 8. This implementation does NOT use Python. Test all changes in a browser manually to verify new additions work as expected ## Testing The project includes a comprehensive testing framework: 1. **Basic tests**: Verify core language features. 2. **Dialog tests**: Test dialog functionality (skipped unless "Show Dialogs" is checked). 3. **Sound tests**: Test sound playback (skipped unless "Play Sounds" is checked). 4. **Expected output validation**: Verify command outputs match expected values. 5. **Object functionality tests**: Verify object creation, property setting, and counting functionality. 5. **Custom validators**: Allow complex output validation for dynamic results. To run tests: 1. Open testing-enhanced.html in a browser. 2. Click "Run Tests" button. 3. Check "Play Sounds" to include sound tests. 4. Check "Show Dialogs" to include dialog tests. **Important Testing Notes**: - Do NOT use Python or any local hosting solutions for testing, as it will confuse matters. - All testing should be done manually by opening the HTML files directly in a browser. - Avoid setting up localhost servers as they add unnecessary points of failure. - This direct browser testing approach ensures a simpler and more reliable testing process. ## Wrapper Implementation WebTalk includes a native desktop wrapper built with Qt WebEngine that extends functionality beyond what's possible in standard browsers. ### Shell Command Support The wrapper enables shell command execution, allowing WebTalk scripts to interact with the operating system: #### Key Components: - **hasShell Flag**: Indicates whether shell command capability is available (true in wrapper, false in browsers) - **allowShell Flag**: Controls whether shell commands are actually enabled (requires user confirmation) - **shell.js**: Implements shell command functionality and security controls #### Security Implementation: 1. **Two-Level Security Model**: - `hasShell`: Determines if shell commands are technically possible (wrapper-only) - `allowShell`: User-controlled flag that must be explicitly enabled via confirmation dialog 2. **Confirmation Process**: - Users must run `set the allowShell to true` to enable shell commands - A HyperTalk-style confirmation dialog appears with "Leave it off" as the default option - Shell commands remain disabled unless explicitly confirmed 3. **State Persistence**: - Shell enabled state is persisted in localStorage when enabled - State is automatically restored in wrapper sessions #### Usage: ``` -- Check if shell commands are available put the hasShell -- Enable shell commands (shows confirmation dialog) set the allowShell to true -- Execute shell command and get output put shell("ls ~/") -- Execute shell command and store result put shell("echo Hello") into myVar ``` ### Browser CORS Bypass The wrapper bypasses browser CORS (Cross-Origin Resource Sharing) restrictions that normally prevent: 1. **Local File Access**: Direct reading/writing of files on the user's system 2. **Shell Command Execution**: Running terminal/command prompt commands 3. **Cross-Origin Requests**: Accessing resources from different domains without proper headers By implementing these features in a native Qt WebEngine wrapper: - WebTalk scripts can interact with the local file system - Shell commands can be executed with proper security controls - Sound files and other resources can be accessed from local paths - New windows can be opened without browser popup restrictions ### Other Wrapper Features - **Browser Console**: Accessible via F12 or Ctrl+Shift+I or via `show browser console` command - **Console Logging**: Browser console output is logged to console.log in the application directory - **Sound Playback**: Enhanced path resolution for audio files in the wrapper environment - **New Window Support**: Custom implementation of window.open() for popup windows ## Future Enhancements Potential areas for future development (in no particular order): 1. Additional HyperTalk commands and functions. 2. Partial Import/export functionality for stacks, using JSON format - want to expand upon this. 3. Mobile device support with gesture interactions. (not top of my list though).