# JavaScript Guide - UI Bundle

This document explains the structure, usage, and best practices for JavaScript modules in the UI Bundle.

## Table of Contents

1. [Architecture Overview](#architecture-overview)
2. [Modules](#modules)
3. [Tools](#tools)
4. [DOM](#dom)
5. [Services](#services)
6. [Constants](#constants)
7. [Consent](#consent)
8. [Best Practices](#best-practices)
9. [Naming Conventions](#naming-conventions)

---

## Architecture Overview

The JavaScript files are organized in a hierarchical structure that mirrors the Twig template and SCSS organization:

```
assets/js/
├── constant/                 # Constants (DOM elements, classes)
├── dom/                      # DOM manipulation utilities
├── tools/                    # Utility functions
├── services/                 # Service layer (events, SEO)
├── consent/                  # Consent management modules
└── module/                   # Feature-specific modules
```

### Usage in Distant Projects

The JavaScript files from this UI Bundle are consumed by distant projects using entry points located under a `/univers` folder. These entry points serve as the integration layer between the UI Bundle and the consuming projects, allowing them to import and use the JavaScript modules while maintaining the proper import order and dependencies. When integrating these modules, projects should reference the entry points rather than importing individual files directly, ensuring consistency and proper dependency resolution.

The files from the UI Bundle are accessed via the `@Ui` alias, which is configured in the webpack configuration of the distant project, allowing for clean and consistent imports across the codebase.

### Hierarchy and Dependencies

- **Modules** can use **Tools**, **DOM**, **Services**, **Constants**, and other **Modules**
- **Tools** can use **DOM**, **Services**, and **Constants**
- **DOM** can use **Constants**
- **Services** can use **Tools** and **DOM**
- **Constants** are the foundation - no dependencies
- **Consent** modules can use **Tools**, **DOM**, and **Services**

### Import Order

When importing JavaScript modules, follow this pattern:
1. **Constants** (DOM elements, classes)
2. **DOM** utilities (events, classes, scroll)
3. **Tools** (debounce, lazyload, cookie)
4. **Services** (eventEmitter, SEO)
5. **Modules** (feature-specific modules)

---

## Modules

### Purpose

Modules are **feature-specific JavaScript modules** that correspond to Twig modules and SCSS modules. They handle interactive functionality for specific UI features.

### Location

```
assets/js/module/
```

### Characteristics

- **Feature-based**: Organized by feature/domain (e.g., `header/`, `bottomBar/`, `roller/`)
- **Initializable**: Export default initialization functions
- **Configurable**: Accept configuration objects with sensible defaults
- **Stateful**: Maintain internal state and provide state getters
- **Event-driven**: Use EventEmitter for inter-module communication
- **DOM-aware**: Manipulate DOM elements and handle user interactions

### Module Subdirectory Structure

Modules are organized by feature:

```
module/
├── header/
│   ├── index.js
│   ├── headerMin.js
│   └── utils.js
├── bottomBar/
│   └── index.js
├── roller/
│   └── index.js
├── overlay/
│   └── index.js
├── player/
│   └── index.js
├── search/
│   └── index.js
├── share/
│   └── share.js
├── advertising/
│   └── utils.js
├── darkMode/
│   └── index.js
├── fullScreen/
│   └── index.js
├── nativePlacements/
│   ├── bannerCountdown.js
│   ├── bannerShowtimes.js
│   ├── trackingElement.js
│   └── trackingPlayer.js
├── sponsoredLink/
│   └── loadOutbrain.js
├── tracking/
│   ├── index.js
│   └── pixel.js
└── ...
```

### Examples

- `header/index.js` - Main header navigation and menu functionality
- `bottomBar/index.js` - Mobile bottom navigation bar
- `roller/index.js` - Horizontal scrolling carousel
- `overlay/index.js` - Overlay/modal functionality
- `player/index.js` - Media player controls
- `search/index.js` - Search functionality
- `share/share.js` - Social sharing functionality
- `darkMode/index.js` - Dark mode toggle functionality
- `fullScreen/index.js` - Fullscreen functionality
- `nativePlacements/` - Native placements tracking (banner countdown, showtimes, element/player tracking)
- `sponsoredLink/loadOutbrain.js` - Sponsored link functionality (Outbrain integration)
- `advertising/utils.js` - Advertising utilities
- `tracking/` - Tracking and pixel functionality

### Module Pattern

Modules follow a consistent pattern for initialization, configuration, and state management:

- **Imports**: Modules import dependencies from DOM utilities, tools, services, and constants at the top of the file
- **State Variables**: Modules maintain internal state using module-level variables (e.g., `isInitialized`, `isOpen`, `container`, `moduleConfig`)
- **Default Configuration**: Modules define a `defaultConfig` object with sensible defaults that can be overridden
- **Initialization Function**: The default export is an initialization function (e.g., `initModule`) that:
  - Accepts an optional configuration object
  - Checks if already initialized to prevent double initialization
  - Merges provided config with defaults
  - Sets up DOM elements and event listeners
  - Uses `requestAnimationFrame` for DOM updates
  - Returns a Promise for async initialization
- **State Getters**: Modules export a `getModuleState()` function that returns the current state of the module
- **Event Communication**: Modules use EventEmitter to emit events for state changes and listen to events from other modules
- **Private Functions**: Internal helper functions handle specific responsibilities (DOM creation, event handling, state management)

### Best Practices for Modules

1. **Export default initialization** - Default export should be the init function
2. **Provide state getters** - Export `getModuleState()` for state queries
3. **Use configuration objects** - Accept config objects with defaults
4. **Guard against double initialization** - Check `isInitialized` flag
5. **Use EventEmitter** - Communicate with other modules via events
6. **Request animation frame** - Use `requestAnimationFrame` for DOM updates
7. **Return promises** - Initialize functions can return promises for async operations
8. **Clean up events** - Remove event listeners when appropriate

---

## Tools

### Purpose

Tools are **utility functions** that provide reusable functionality for common JavaScript patterns and operations.

### Location

```
assets/js/tools/
```

### Characteristics

- **Pure functions**: Most tools are pure functions with no side effects
- **Reusable**: Used across different modules
- **Focused**: Single responsibility per tool
- **Well-documented**: Include JSDoc comments

### Examples

- `debounce.js` - Debounce function calls
- `lazyload.js` - Lazy loading utilities using IntersectionObserver
- `cookie.js` - Cookie management (get, set, remove)
- `request.js` - HTTP request utilities
- `loadAssets.js` - Asset loading utilities
- `loadFonts.js` - Font loading utilities
- `loadGtm.js` - Google Tag Manager loading
- `intersectionObserverItems.js` - IntersectionObserver helpers
- `idleRequestCb.js` - Idle request callbacks
- `ads.js` - Ad blocking detection
- `string.js` - String manipulation utilities
- `yScroll.js` - Vertical scroll utilities
- `testFullscreenApi.js` - Fullscreen API detection
- `testIosDevice.js` - iOS device detection
- `noop.js` - No-operation function

### Tool Pattern

Tools follow a consistent pattern for utility functions:

- **Pure Functions**: Most tools are pure functions that take inputs and return outputs without side effects
- **Default Parameters**: Tools use default parameters for optional arguments
- **JSDoc Documentation**: Tools include JSDoc comments describing parameters and return types
- **Browser Compatibility**: Tools check for browser support and provide fallbacks when needed
- **Export Pattern**: Tools use default exports for single functions, named exports for multiple utilities

### Best Practices for Tools

1. **Keep functions pure** - Minimize side effects
2. **Provide defaults** - Use default parameters for optional arguments
3. **Document with JSDoc** - Include parameter and return type documentation
4. **Handle edge cases** - Check for browser support and edge cases
5. **Export clearly** - Use named exports for multiple functions, default for single function

---

## DOM

### Purpose

DOM utilities provide **DOM manipulation helpers** for common operations like event handling, class manipulation, and element queries.

### Location

```
assets/js/dom/
```

### Characteristics

- **Element-focused**: Work with DOM elements
- **Safe**: Check for element existence before operations
- **Consistent**: Provide consistent API across browsers
- **Well-documented**: Include JSDoc comments

### Examples

- `events.js` - Event listener management (on, off, once, deferToLoad)
- `classes.js` - Class manipulation (addClass, removeClass, toggleClass, hasClass, replaceClass)
- `anchor.js` - Anchor element utilities
- `scrollTo.js` - Smooth scrolling utilities
- `mqState.js` - Media query state management
- `setTouchEvent.js` - Touch event utilities

### DOM Pattern

DOM utilities follow a consistent pattern for element manipulation:

- **Element Safety**: All utilities check for element existence before performing operations
- **Consistent API**: Utilities provide a consistent interface across different browsers
- **JSDoc Documentation**: All utilities include JSDoc comments with parameter types and return values
- **Named Exports**: DOM utilities use named exports for multiple functions
- **Event Handling**: Event utilities provide `on`, `off`, and `once` functions for event listener management
- **Class Manipulation**: Class utilities provide `addClass`, `removeClass`, `toggleClass`, `hasClass`, and `replaceClass` functions

### Best Practices for DOM

1. **Check element existence** - Always verify element exists before manipulation
2. **Use consistent API** - Follow established patterns for DOM operations
3. **Document parameters** - Include JSDoc comments
4. **Handle edge cases** - Account for browser differences and edge cases
5. **Export named functions** - Use named exports for multiple utilities

---

## Services

### Purpose

Services provide **shared functionality and infrastructure** that modules can use, such as event communication, SEO utilities, and other cross-cutting concerns.

### Location

```
assets/js/services/
```

### Structure

```
services/
├── events/
│   └── eventEmitter.js
└── seo/
    └── deobfuscation.js
```

### Event Emitter Service

**Location**: `services/events/eventEmitter.js`

**Purpose**: Provides a centralized event system for inter-module communication

**Key Features**:

- Event type constants
- EventEmitter instance
- Type-safe event names

**Usage Pattern**:

- Import the eventEmitter instance and EventsTypes constants
- Emit events using `eventEmitter.emit(EventsTypes.EVENT_NAME)`
- Listen to events using `eventEmitter.on(EventsTypes.EVENT_NAME, callback)`
- Listen once using `eventEmitter.once(EventsTypes.EVENT_NAME, callback)`

**Event Types**:

- `DESOBFUSCATION_DONE` - SEO deobfuscation completed
- `MQ_STATE` - Media query state changed
- `ADSERVER_LOADED` - Ad server loaded
- `MENU_OPEN` - Menu opened
- `MENU_CLOSE` - Menu closed
- `SEARCH_OPEN` - Search opened
- `SEARCH_CLOSE` - Search closed

### SEO Service

**Location**: `services/seo/deobfuscation.js`

**Purpose**: Handles URL deobfuscation for SEO purposes

**Key Features**:

- URL deobfuscation
- Deferred execution callbacks
- Automatic deobfuscation on page load

**Usage Pattern**:

- Import the `runAfterDeobfuscation` function
- Pass a callback function that will execute after deobfuscation is complete
- The callback is executed immediately if deobfuscation is already done, or waits for the deobfuscation event

### Best Practices for Services

1. **Centralize shared logic** - Services should provide shared functionality
2. **Use event system** - Leverage EventEmitter for loose coupling
3. **Export constants** - Export event type constants for type safety
4. **Provide utilities** - Export helper functions for common operations

---

## Constants

### Purpose

Constants provide **shared values** that are used across multiple modules, such as DOM element references and CSS class names.

### Location

```
assets/js/constant/
```

### Examples

- `dom.js` - DOM element constants and CSS class names

### Constants Pattern

Constants follow a consistent pattern for shared values:

- **Element Constants**: DOM element references (e.g., `BODY`, `HEADER_MAIN`)
- **Class Constants**: CSS class names organized by category (e.g., `CLASS_BODY_OVERLAY_OPEN`, `HIDDEN_AD_CLASS`)
- **UPPER_SNAKE_CASE**: All constants use uppercase with underscores for naming
- **Named Exports**: Constants are exported as named exports
- **Grouped by Category**: Constants are organized by purpose (elements, classes, ad classes, etc.)

### Best Practices for Constants

1. **Use descriptive names** - Constants should be self-documenting
2. **Group by category** - Organize constants by purpose
3. **Export clearly** - Use named exports for constants
4. **Keep in sync** - Ensure constants match SCSS class names
5. **Use uppercase** - Follow UPPER_SNAKE_CASE convention

---

## Consent

### Purpose

Consent modules handle **consent management** functionality, including cookie banners, GDPR compliance, and consent tracking.

### Location

```
assets/js/consent/
```

### Examples

- `cookieBanner.js` - Cookie banner functionality
- `didomi.js` - Didomi consent management integration
- `tcfApi.js` - TCF (Transparency and Consent Framework) API integration

### Consent Pattern

Consent modules follow a consistent pattern for consent management:

- **Cookie Management**: Consent modules use cookie utilities to store and retrieve consent state
- **Element Checking**: Modules check for required DOM elements before initialization
- **State Persistence**: Consent state is persisted using cookies with appropriate expiration
- **DOM Manipulation**: Modules use DOM utilities to show/hide consent banners
- **Event Handling**: Modules attach event listeners to consent buttons
- **Default Export**: Consent modules export default initialization functions

### Best Practices for Consent

1. **Respect user choice** - Honor cookie preferences
2. **Store consent state** - Use cookies to persist consent
3. **Check before showing** - Verify consent hasn't been given before showing banner
4. **Integrate with services** - Use consent management services when available

---

## Best Practices

### General Guidelines

1. **Use ES6 Modules**
   - Always use `import`/`export` syntax
   - Use default exports for main functionality
   - Use named exports for utilities and state getters

2. **Follow Import Order**
   - Constants first
   - DOM utilities
   - Tools
   - Services
   - Other modules

3. **Initialization Pattern**
   - Check if already initialized
   - Merge config with defaults
   - Return promises for async operations
   - Export state getters

4. **Event-Driven Communication**
   - Use EventEmitter for inter-module communication
   - Emit events for state changes
   - Listen to events from other modules
   - Use event type constants

5. **DOM Manipulation**
   - Use requestAnimationFrame for DOM updates
   - Check element existence before manipulation
   - Use DOM utilities from `dom/` folder
   - Avoid direct DOM manipulation in modules

6. **Error Handling**
   - Check for element existence
   - Handle browser compatibility
   - Provide fallbacks when possible
   - Log errors appropriately


### Performance Considerations

1. **Use requestAnimationFrame** - For DOM updates and animations
2. **Debounce expensive operations** - Use debounce for scroll, resize handlers
3. **Lazy load content** - Use IntersectionObserver for lazy loading
4. **Clean up events** - Remove event listeners when no longer needed
5. **Cache DOM queries** - Store frequently accessed DOM elements

### Accessibility

1. **Keyboard navigation** - Support keyboard interactions
2. **ARIA attributes** - Add ARIA labels and roles where appropriate
3. **Focus management** - Manage focus for modals and overlays
4. **Screen reader support** - Ensure content is accessible to screen readers

---

## Naming Conventions

### Files

- **Modules**: `module_name/index.js` or `feature/module_name.js` (e.g., `header/index.js`, `bottomBar/index.js`)
- **Tools**: `tool_name.js` (e.g., `debounce.js`, `lazyload.js`)
- **DOM**: `utility_name.js` (e.g., `events.js`, `classes.js`)
- **Services**: `service_name.js` or `feature/service_name.js` (e.g., `eventEmitter.js`, `deobfuscation.js`)
- **Constants**: `category_name.js` (e.g., `dom.js`)

### Variables

- **camelCase** for variables: `container`, `isInitialized`, `moduleConfig`
- **UPPER_SNAKE_CASE** for constants: `BODY`, `CLASS_BODY_OVERLAY_OPEN`
- **Descriptive names**: `isMenuOpen` not `menu`, `headerMainElement` not `header`

### Functions

- **camelCase** for functions: `initModule`, `handleClick`, `toggleMenu`
- **Verb-noun pattern**: `createContainer`, `handleScroll`, `getModuleState`
- **Initialization functions**: Prefix with `init` (e.g., `initHeader`, `initBottomBar`)

### Classes

- **PascalCase** for classes (if used): `EventEmitter`, `ModuleManager`

### Exports

- **Default export**: Main initialization function or primary functionality
- **Named exports**: Utilities, state getters, and helper functions
- **State getters**: Prefix with `get` (e.g., `getModuleState`, `getBottomBarState`)

---

## Summary

| Type | Purpose | Location | Key Feature |
|------|---------|----------|-------------|
| **Module** | Feature-specific functionality | `module/` | Initializable, configurable |
| **Tool** | Utility functions | `tools/` | Pure, reusable |
| **DOM** | DOM manipulation helpers | `dom/` | Element-focused, safe |
| **Service** | Shared infrastructure | `services/` | Cross-cutting concerns |
| **Constant** | Shared values | `constant/` | DOM elements, classes |
| **Consent** | Consent management | `consent/` | Cookie banners, GDPR |

### Relationship to Twig Templates and SCSS

- **Modules** (JS) ↔ **Modules** (Twig) ↔ **Modules** (SCSS) - Feature-specific functionality
- **DOM utilities** (JS) ↔ **DOM manipulation** - Class toggling, event handling
- **Constants** (JS) ↔ **Classes** (SCSS) - CSS class names and DOM element references

### Remember

- **Modules** = Feature functionality - One folder per feature
- **Tools** = Utilities - Pure functions for common operations
- **DOM** = DOM helpers - Safe element manipulation
- **Services** = Infrastructure - Event system, SEO utilities
- **Constants** = Shared values - DOM elements and classes
- **Consent** = Consent management - Cookie banners and GDPR

