Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
65a2ef6
Sync branch [skip ci]
pirate-bot Aug 20, 2025
22a086e
Sync branch [skip ci]
pirate-bot Aug 20, 2025
4615059
fix: Incompatibility with JetEngine
RaduCristianPopescu Aug 29, 2025
20ccfbb
fix: use replace content for JetEngine compatiblity
RaduCristianPopescu Sep 2, 2025
9bbafa5
chore: phpcs
RaduCristianPopescu Sep 2, 2025
4fac9b9
fix: image storage selection
RaduCristianPopescu Sep 3, 2025
6b030bd
remove: console message
RaduCristianPopescu Sep 3, 2025
8c9d8db
fix: rollback issue
RaduCristianPopescu Sep 4, 2025
4743a1e
fix: jetpack incompatibility
RaduCristianPopescu Sep 12, 2025
fba8ba5
chore: type missmatch
RaduCristianPopescu Sep 12, 2025
afe13c6
fix: fetch the image samples for quality on effect event
Soare-Robert-Daniel Sep 12, 2025
b3ada65
chore: phpcs
RaduCristianPopescu Sep 12, 2025
b1276ff
chore: removed redundant code
RaduCristianPopescu Sep 12, 2025
fa2a8f6
chore: code styling
RaduCristianPopescu Sep 12, 2025
aa390de
Merge pull request #958 from Codeinwp/fix/sample-image-quality
selul Sep 16, 2025
d0e3652
Merge pull request #957 from Codeinwp/fix/jetpack
selul Sep 16, 2025
3986b1e
Merge branch 'development' into fix/jetengine-comp
selul Sep 16, 2025
3b66c03
Merge pull request #952 from Codeinwp/fix/jetengine-comp
selul Sep 16, 2025
adbbd36
feat: enhance debug logging and improve content processing logic
selul Sep 16, 2025
6441cca
feat: add missing dimensions detection https://github.com/Codeinwp/op…
selul Sep 16, 2025
2c8e2d0
refactor: modularize image detection and optimize background image ha…
selul Sep 16, 2025
cd9b6e2
refactor: update optimizer to run profiling instead of finding above-…
selul Sep 16, 2025
8ab7474
feat: add srcset detection and handling for images, enhancing respons…
selul Sep 17, 2025
eed8be3
feat: implement waitForViewportImages utility and enhance srcset dete…
selul Sep 17, 2025
3d71060
refactor: improve code readability by standardizing spacing and forma…
selul Sep 17, 2025
0ebc797
refactor: update lazyload logic to conditionally load profiler based …
selul Sep 17, 2025
736baf5
test: update assertions in lazyload tests to reflect changes in loadi…
selul Sep 17, 2025
b560789
remove: csat
RaduCristianPopescu Sep 18, 2025
d4ff144
fix: php
RaduCristianPopescu Sep 18, 2025
c37a3f9
refactor: replace lazyload checks with profiler loading logic across …
selul Sep 18, 2025
87a2e9c
update: modified limit_height
RaduCristianPopescu Sep 18, 2025
4205741
bump sdk
selul Sep 18, 2025
be5a6d5
add cf invalidation
selul Sep 18, 2025
a4cc39a
feat: enhance srcset detection to include crop status and improve log…
selul Sep 18, 2025
3648bcf
fix: phpunit tests
RaduCristianPopescu Sep 22, 2025
602d116
refactor: replace console logging with optmlLogger for improved debug…
selul Sep 22, 2025
032e673
dev: update PHPStan to v2
Soare-Robert-Daniel Aug 22, 2025
407e4fe
dev: fix reported PHPStan v2 errors
Soare-Robert-Daniel Aug 22, 2025
0eff1af
dev: set lv 6 phpstan and add baseline
Soare-Robert-Daniel Aug 28, 2025
5b37c09
dev: set to level 6 with baseline
Soare-Robert-Daniel Aug 28, 2025
759c4bc
dev: add ABSPATH as dynamic constant
Soare-Robert-Daniel Aug 28, 2025
a606223
fix: update parameter type hinting and return type for calculate_imag…
Soare-Robert-Daniel Sep 23, 2025
5b37f23
chore: phpcs
Soare-Robert-Daniel Sep 23, 2025
02eb5e7
feat: helper text for 'visits' metric
RaduCristianPopescu Sep 23, 2025
73ea28e
chore: phpcs
RaduCristianPopescu Sep 23, 2025
7d0f838
Merge pull request #962 from Codeinwp/remove/CSAT
selul Sep 24, 2025
5c9258d
Merge pull request #963 from Codeinwp/remove/height_cap
selul Sep 24, 2025
387be28
Merge pull request #951 from Codeinwp/dev/phpstan
selul Sep 24, 2025
aa69c4a
feat: add watermark to the advanced submenu
RaduCristianPopescu Sep 25, 2025
854d52a
chore: copilot suggestions
RaduCristianPopescu Sep 26, 2025
f5636ef
chore: copilot
RaduCristianPopescu Sep 26, 2025
ce97866
feat: added compatibility notices for lazy loading
RaduCristianPopescu Sep 19, 2025
21c4f2c
chore: phpstan
RaduCristianPopescu Sep 19, 2025
4003e22
feat: smush conflict
RaduCristianPopescu Sep 22, 2025
737d709
chore: incorrect path
RaduCristianPopescu Sep 22, 2025
3d7bb40
feat: litespeed conflict
RaduCristianPopescu Sep 22, 2025
9ea23d8
fix: logical errors
RaduCristianPopescu Sep 23, 2025
01e90e4
chore: phpcbf
RaduCristianPopescu Sep 23, 2025
f434d01
feat: autoptimize conflict handling
RaduCristianPopescu Sep 23, 2025
390a9f6
feat:perfmatters conflict handling
RaduCristianPopescu Sep 23, 2025
a404964
fix: jetpack conflict
RaduCristianPopescu Sep 26, 2025
95ab1e0
chore: phpstan
RaduCristianPopescu Sep 26, 2025
eafe7c7
chore: phpcs
RaduCristianPopescu Sep 26, 2025
e96dab9
refactor: welcome screen
RaduCristianPopescu Sep 19, 2025
2951f01
chore: background color
RaduCristianPopescu Sep 24, 2025
1ad40a7
chore: logic button error
RaduCristianPopescu Sep 29, 2025
bf6441d
feat: increase the visibility of rename/replace
RaduCristianPopescu Sep 29, 2025
bd82983
chore: copilot suggestions
RaduCristianPopescu Sep 29, 2025
213e883
fix: preset settings
RaduCristianPopescu Sep 30, 2025
85978d1
chore: copillot suggestions
RaduCristianPopescu Sep 30, 2025
3391017
chore: remove comment
RaduCristianPopescu Sep 30, 2025
eeda538
fix: logic error
RaduCristianPopescu Sep 30, 2025
0823ba9
refactor: default settings for compression
RaduCristianPopescu Sep 30, 2025
aef2b20
chore: fix tests
RaduCristianPopescu Sep 30, 2025
776792a
chore: phpcs
RaduCristianPopescu Sep 30, 2025
8bfc444
Merge pull request #964 from Codeinwp/feat/compability_notices
selul Sep 30, 2025
be4b22f
Merge pull request #965 from Codeinwp/refactor/welcome-screen
selul Sep 30, 2025
b5564ee
Merge pull request #966 from Codeinwp/feat/monthly_visit
selul Sep 30, 2025
d912ac3
Merge pull request #969 from Codeinwp/feat/watermark_submenu
selul Sep 30, 2025
70ba497
feat: improve the lazy loading tab
Soare-Robert-Daniel Sep 17, 2025
afb587a
chore: update functions
Soare-Robert-Daniel Sep 22, 2025
f5f5a63
chore: trigger survey
Soare-Robert-Daniel Sep 22, 2025
06aa954
chore: conditions checks
Soare-Robert-Daniel Sep 23, 2025
780b3ee
fix: image scale toggle
Soare-Robert-Daniel Sep 23, 2025
668511d
chore: add pre-filled support contact
Soare-Robert-Daniel Sep 23, 2025
a997281
chore: migrate "lazyload_type" `all` to `fixed` on dashboard settings
Soare-Robert-Daniel Sep 23, 2025
eddfd1a
chore: refactor
Soare-Robert-Daniel Sep 23, 2025
f05c4cd
fix: migration
Soare-Robert-Daniel Sep 23, 2025
f158c04
chore: exclude global type declaration since the current parser can n…
Soare-Robert-Daniel Sep 24, 2025
07c7ed1
chore: clean up
Soare-Robert-Daniel Sep 26, 2025
142f63b
chore: fix label names
Soare-Robert-Daniel Sep 30, 2025
8c9de99
chore: added learn more
Soare-Robert-Daniel Oct 1, 2025
26f3676
refactor: enhance cropping detection logic in srcset detector to incl…
selul Oct 1, 2025
bac97f3
fix: enable Network Optimizations
Soare-Robert-Daniel Oct 1, 2025
3eeca78
Merge remote-tracking branch 'origin/development' into feat/improved_…
selul Oct 1, 2025
fc21f61
fix phpstan reports
selul Oct 1, 2025
722faed
Fix PHPStan errors in inc/tag_replacer.php
selul Oct 1, 2025
deb4f96
feat: add force option to URL rebuilding in tag and URL replacers
selul Oct 1, 2025
a6ebbed
Merge pull request #961 from Codeinwp/refactor/lazy-scaling-ui
selul Oct 1, 2025
2963e8b
Merge pull request #955 from Codeinwp/fix/image_storage_selection
selul Oct 1, 2025
ec89c6e
Merge branch 'development' into feat/improved_scaling
selul Oct 1, 2025
3796848
Merge pull request #973 from Codeinwp/refactor/inc_visibility_feat
selul Oct 1, 2025
3be6810
Merge pull request #974 from Codeinwp/fix/preset_settings
selul Oct 1, 2025
c63f37b
feat: add HTML comment generation for profiling data and improve para…
selul Oct 1, 2025
3db479b
chore: enable Best Format and AVIF by default
Soare-Robert-Daniel Oct 3, 2025
b08acd8
chore: update tests for `f:best`
Soare-Robert-Daniel Oct 3, 2025
a2f890d
refactor: dashboard optimization status
RaduCristianPopescu Sep 25, 2025
656aa93
chore: tweaks
Soare-Robert-Daniel Oct 3, 2025
cc650ef
Sync branch [skip ci]
pirate-bot Oct 5, 2025
d2b6546
Remove new avif filter since we already have one.
selul Oct 6, 2025
72b0f72
refactor: clean up whitespace in Compression.js
selul Oct 6, 2025
6772278
Merge pull request #975 from Codeinwp/refactor/default_compression
selul Oct 6, 2025
c03d351
Merge branch 'refs/heads/development' into feat/improved_scaling
selul Oct 6, 2025
4cc2151
chore: remove user_status from check
Soare-Robert-Daniel Oct 6, 2025
5cc6744
implement purge cache compatibilities https://github.com/Codeinwp/opt…
selul Oct 6, 2025
06467e1
feat: add check for user scroll position before image detection https…
selul Oct 6, 2025
29e04d9
feat: limit above fold images to 6 and set maximum preloaded links to…
selul Oct 6, 2025
ffb256d
add more bg selectors https://github.com/Codeinwp/optimole-service/i…
selul Oct 6, 2025
0b74fb7
fix placeholder width/height calculator when image is offloaded
selul Oct 7, 2025
7744c6e
feat: enhance image detection with optimized dimensions support for l…
selul Oct 7, 2025
1f00f57
fix format
selul Oct 7, 2025
2ab152b
refactor: remove redundant missing type entries from phpstan baseline…
selul Oct 7, 2025
a71ebf9
refactor: update parameter type hint formatting in dam offload utils
selul Oct 7, 2025
9458d04
Merge pull request #967 from Codeinwp/refactor/dashboard_status
selul Oct 7, 2025
a207794
Merge branch 'development' into feat/improved_scaling
selul Oct 7, 2025
d42a41b
preload only lcp urls and fetch priority only on lcp
selul Oct 7, 2025
93f11a3
remove assertion for fetch priority in lazyload viewport tests
selul Oct 7, 2025
cb752e7
[skip ci] update comment
selul Oct 7, 2025
2d99367
fix: update anchor tag to include aria-label for improved accessibili…
selul Oct 7, 2025
7c68e4e
attempt to fix https://github.com/Codeinwp/optimole-wp/issues/979
selul Oct 7, 2025
929b722
chore: update .distignore and .gitignore to include coverage and test…
selul Oct 7, 2025
3d48b2b
fix: add missing rel attribute to anchor tag for proper link behavior
selul Oct 7, 2025
4ea9d8c
Merge branch 'development' into feat/improved_scaling
selul Oct 7, 2025
71bb263
chore: remove .babelrc configuration file and update Jest transform s…
selul Oct 7, 2025
f22f060
feat: use the new upgrade links
Soare-Robert-Daniel Oct 7, 2025
3bc227f
feat: add offload restrictions (#968)
Soare-Robert-Daniel Oct 8, 2025
c556bfa
chore: use production env for Formbricks
Soare-Robert-Daniel Oct 8, 2025
49a757f
refactor: remove unused width step size configuration and enhance res…
selul Oct 8, 2025
e564154
fix: correct indentation in Profile.php and update device type in tes…
selul Oct 8, 2025
c865ec8
feat: add 'kinsta' to the cache types
selul Oct 8, 2025
4dd6b62
fix: prioritize config over api domain
selul Oct 8, 2025
9857da6
fix formatting
selul Oct 8, 2025
5df00c9
feat: add offloads metrics with optional shortcuts (#970)
RaduCristianPopescu Oct 8, 2025
68dc8d4
Merge pull request #960 from Codeinwp/feat/improved_scaling
selul Oct 8, 2025
13f5ebd
feat: update lazyload_type setting to support viewport option
selul Oct 8, 2025
f6e14ff
fix: small tweaks for Lazy Load tab (#986)
Soare-Robert-Daniel Oct 8, 2025
24754f4
refactor: update lazyload data availability checks and adjust skip se…
selul Oct 8, 2025
e788a91
Merge remote-tracking branch 'origin/development' into development
selul Oct 8, 2025
e94b426
style: fix whitespace inconsistencies in tag_replacer and Profile cla…
selul Oct 8, 2025
8d4376c
Improve quality setting handling in Compression settings
ineagu Oct 1, 2025
be3acff
fixed linting
ineagu Oct 1, 2025
b0c2099
Update settings.php
ineagu Oct 3, 2025
bd08b9e
refactor: streamline lazyload image checks by removing viewport condi…
selul Oct 8, 2025
0ae5eb7
enhance lazyload image checks for viewport conditions
selul Oct 8, 2025
1fe91ed
fix: handle `mauto` for quality value on saving
Soare-Robert-Daniel Oct 8, 2025
124434d
chore: phpstan
Soare-Robert-Daniel Oct 8, 2025
6580b45
fix console errors
selul Oct 8, 2025
7e9bf78
Merge pull request #987 from Codeinwp/fix/multiple-custom-domains
selul Oct 8, 2025
bca649d
Merge pull request #985 from Codeinwp/feat/upgrade-links
selul Oct 9, 2025
d08e039
Merge pull request #978 from Codeinwp/fix/1516
selul Oct 9, 2025
c5e8406
fix rocketnet compat
selul Oct 9, 2025
7585417
Merge remote-tracking branch 'origin/development' into development
selul Oct 9, 2025
4ee2eae
fix: update domain DNS handling and improve custom domain retrieval l…
selul Oct 9, 2025
0cf5b2b
fix: update visitor limit display to reflect new quota of 2000
selul Oct 9, 2025
bcf6460
fix: adjust scroll position in background lazyload test
selul Oct 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .distignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ phpcs.xml
phpunit.xml
phpunit-cc.xml
phpmd.xml
jest.config.js
jest.setup.js
package.json
package-lock.json
composer.json
Expand All @@ -31,16 +33,19 @@ tests
dist
artifact
assets/src
assets/js/modules/__tests__
coverage
.wporg
.nvmrc
.github
.eslintrc
postcss.config.js
tailwind.config.js
phpstan.neon
phpstan-baseline.neon
development.php
playwright.config.ts
test-results
wp-scripts.config.js
README.md
CHANGELOG.md
CHANGELOG.md
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"ecmaVersion": 2021,
"sourceType": "module"
},
"ignorePatterns": [ "node_modules", "assets/js" ],
"ignorePatterns": [ "node_modules", "assets/js", "**/*.d.ts" ],
"rules": {
"camelcase" : "off",
"indent": [
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,24 @@ jobs:
env:
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
- name: Make dist
run: npm run dist
- name: Upload Latest Version to S3
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET_DOWNLOADS }}
AWS_ACCESS_KEY_ID: ${{ secrets.S3_DOWNLOADS_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DOWNLOADS_AWS_SECRET_ACCESS_KEY }}
AWS_REGION: "us-west-1" # optional: defaults to us-east-1
SOURCE_DIR: "artifact" # optional: defaults to entire repository
DEST_DIR: products/optimole-wp/latest
- name: Clear Cloudfront Cache
uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ secrets.API_DIST_ID }}
PATHS: "/download/optimole/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.S3_DOWNLOADS_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DOWNLOADS_AWS_SECRET_ACCESS_KEY }}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ESLint
name: JavaScript Tests

on:
pull_request:
Expand All @@ -9,21 +9,36 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
run:
if: github.event.pull_request.draft == false
test:
if: github.event_name == 'push' || github.event.pull_request.draft == false
runs-on: ubuntu-latest
name: ESLint
name: ESLint & Jest Tests
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v3
with:
persist-credentials: false

- name: Setup Node
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 18
- name: Lint js files
cache: 'npm'

- name: Install dependencies
run: |
npm install -g npm
npm ci

- name: Run ESLint
run: |
npm run lint

- name: Run unit tests
run: |
npm test

- name: Run tests with coverage
run: |
npm run test:coverage

14 changes: 11 additions & 3 deletions .github/workflows/test-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,22 @@ jobs:
name: PHPStan on PHP 8.0
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Setup PHP version
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
extensions: simplexml, mysql
- name: Checkout source code
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
- name: Create the build file
run: |
npm ci
npm run build
- name: Install Composer dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: PHPStan Static Analysis
run: composer phpstan
run: composer phpstan
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ build
cc-test-reporter
assets/build
test-results
tests/assets/filestash
tests/assets/filestash
coverage
69 changes: 69 additions & 0 deletions assets/js/modal-attachment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
jQuery(document).ready(function($) {
if (!$('body').hasClass('upload-php')) {
return;
}

/**
* Helper function to add Replace or Rename button to attachment actions
* @param {Object} view - The attachment view instance
*/
function addReplaceRenameButton(view) {
var $el = view.$el;
var $actions = $el.find('.actions');

if (!$actions.length || $actions.find('.optml-replace-rename-link').length) {
return;
}

var attachmentId = view.model.get('id');

if (!attachmentId) {
return;
}

var editUrl = OptimoleModalAttachment.editPostURL + '?post=' + attachmentId +
'&action=edit&TB_iframe=true&width=90%&height=90%';

var $editLink = $actions.find('a[href*="post.php"]');

if ($editLink.length) {
$editLink.after(
' <span class="links-separator">|</span>' +
'<a href="' + editUrl + '" class="optml-replace-rename-link thickbox" title="' +
OptimoleModalAttachment.i18n.replaceOrRename + '"> ' +
OptimoleModalAttachment.i18n.replaceOrRename + '</a>'
);
}
}

/**
* Extend a WordPress media view with Replace/Rename functionality
* @param {Object} OriginalView - The original view to extend
* @returns {Object} Extended view
*/
function extendMediaView(OriginalView) {
return OriginalView.extend({
initialize: function() {
OriginalView.prototype.initialize.apply(this, arguments);
},

render: function() {
OriginalView.prototype.render.apply(this, arguments);
addReplaceRenameButton(this);
return this;
}
});
}

var originalAttachmentDetails = wp.media.view.Attachment.Details;
wp.media.view.Attachment.Details = extendMediaView(originalAttachmentDetails);

if (wp.media.view.Attachment.Details.TwoColumn) {
var originalTwoColumn = wp.media.view.Attachment.Details.TwoColumn;
wp.media.view.Attachment.Details.TwoColumn = extendMediaView(originalTwoColumn);
}

$(document).on('click', '.optml-replace-rename-link.thickbox', function() {
tb_init('a.thickbox');
});
});
14 changes: 14 additions & 0 deletions assets/js/modules/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Optimole JavaScript Modules - Agent Instructions


## Code standards
- **CRITICAL**: All functions must have JSDoc comments with `@param` and `@return` annotations
- Use ES6 modules with `import`/`export` syntax
- Follow camelCase naming for functions and variables
- Use `const`/`let` instead of `var`
- Always handle errors gracefully with try/catch blocks
- Use descriptive variable names and avoid abbreviations

## Testing instructions
- Use only unit tests

162 changes: 162 additions & 0 deletions assets/js/modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Optimole JavaScript Modules

This directory contains the modular JavaScript components for the Optimole image optimizer.

## Module Structure

### Core Modules

#### `logger.js`
- **Purpose**: Centralized logging functionality with debug mode support
- **Exports**: `optmlLogger` object
- **Key Features**:
- Debug mode detection via URL params or localStorage
- Structured logging with prefixes
- Table logging support
- Conditional logging based on debug state

#### `storage.js`
- **Purpose**: Session storage management for tracking processed pages
- **Exports**: `optmlStorage` object
- **Key Features**:
- Generate unique storage keys for URL/device combinations
- Check if page/device combinations have been processed
- Mark combinations as processed with timestamps
- Error handling for storage operations

#### `device.js`
- **Purpose**: Device type detection based on screen width
- **Exports**: `optmlDevice` object
- **Key Features**:
- Mobile/desktop detection using 600px breakpoint
- Device type constants (MOBILE: 1, DESKTOP: 2)
- Helper methods for device type checking
- PageSpeed Insights compatible detection logic

#### `api.js`
- **Purpose**: REST API communication with fallback mechanisms
- **Exports**: `optmlApi` object
- **Key Features**:
- Primary sendBeacon API for reliable data transmission
- Fetch API fallback for when sendBeacon fails
- Automatic storage marking on successful sends
- Error handling and logging

#### `dom-utils.js`
- **Purpose**: DOM manipulation and utility functions
- **Exports**: `optmlDomUtils` object
- **Key Features**:
- Debounce utility for performance optimization
- Unique CSS selector generation for elements
- Background image detection and URL extraction
- Page condition checking (viewport, visibility, load state)
- Promise-based waiting utilities

### Specialized Modules

#### `background.js`
- **Purpose**: Background image handling and lazy loading observation
- **Exports**: `optmlBackground` object
- **Key Features**:
- Background image lazy loading detection
- Mutation observer setup for class changes
- URL extraction from background images
- Selector processing and element observation

#### `lcp.js`
- **Purpose**: Largest Contentful Paint (LCP) element detection
- **Exports**: `optmlLcp` object
- **Key Features**:
- Performance Observer integration
- LCP element identification and processing
- Support for both image and background image LCP elements
- Timeout handling for LCP detection

#### `image-detector.js`
- **Purpose**: Image detection and dimension analysis
- **Exports**: `optmlImageDetector` object
- **Key Features**:
- Missing dimension detection for images
- Intersection Observer setup for above-fold detection
- Optimole image observation (`data-opt-id` attributes)
- Cleanup utilities for temporary attributes

#### `srcset-detector.js`
- **Purpose**: Srcset analysis and missing variation detection for eligible images
- **Exports**: `optmlSrcsetDetector` object
- **Key Features**:
- Smart image detection with improved skip logic:
- Includes images without `data-opt-src` (non-lazyload images)
- Includes images with `data-opt-src` AND `data-opt-lazy-loaded` (completed lazyload)
- Skips images with only `data-opt-src` (pending lazyload)
- **Aspect ratio detection for cropping requirements**:
- Compares natural vs. displayed aspect ratios to determine if cropping is needed
- Uses intelligent thresholds: 5% tolerance, 15% significant difference, 10% ratio change
- Prevents unnecessary cropping when aspect ratios match
- Returns separate crop status data as `imageId: cropStatus` mapping
- Calculates required srcset variations using comprehensive size ranges:
- Mobile range: 200w-500w (50w steps) for dense mobile coverage
- Tablet range: 500w-800w (100w steps) for tablet devices
- Desktop range: 800w-1200w (200w steps) for desktop screens
- High-res range: 1200w-1600w (200w steps) with strategic 2x DPR
- Configurable generation settings:
- `widthStepSize`: Step size for width variations (default: 100px)
- `minSize`: Minimum image size to consider (default: 200px)
- `maxVariations`: Maximum srcset variations per image (default: 8)
- `sizeTolerance`: Tolerance for existing sizes (default: 50px)
- Analyzes existing srcset attributes to identify missing sizes
- **Ultra-compact API payload**: Sends only essential fields with short names (w, h, d, s, b)
- **Separate crop status**: Returns crop requirements as `imageId: cropStatus` mapping instead of per-srcset flags
- **Full logging**: Complete analysis data available in console logs for debugging
- Smart selection from dense size grid for optimal responsive coverage

#### `main.js`
- **Purpose**: Main orchestrator coordinating all functionality
- **Exports**: `optmlMain` object
- **Key Features**:
- Complete above-the-fold detection workflow
- Module coordination and data aggregation
- API data preparation and submission with separate crop status
- Error handling and condition checking

## Data Structure

### API Payload Structure
The main module sends data to the REST API with the following structure:

```javascript
{
d: deviceType, // Device type (1=mobile, 2=desktop)
a: aboveTheFoldImages, // Array of above-fold image IDs
b: backgroundSelectors, // Background image selectors
u: url, // Page URL
t: timestamp, // Request timestamp
h: hmac, // Security hash
l: lcpData, // LCP (Largest Contentful Paint) data
m: missingDimensions, // Missing dimension data
s: srcsetData, // Srcset variations data
c: cropStatusData // Crop status mapping (imageId -> boolean)
}
```

### Srcset Data Structure
Individual srcset entries contain:
```javascript
{
w: width, // Image width
h: height, // Image height
d: dpr, // Device pixel ratio
s: descriptor, // Srcset descriptor (e.g., "300w")
b: breakpoint // CSS breakpoint
}
```

### Crop Status Data Structure
Crop requirements are stored separately:
```javascript
{
882936320: true, // Image ID -> requires cropping
123456789: false // Image ID -> no cropping needed
}
```

Loading
Loading