Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
/infection.json5 export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore

# Vendored/minified frontend libraries: treat as binary to keep diffs readable
src/view/frontend/web/js/lib/alpine.min.js binary
13 changes: 10 additions & 3 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,10 @@ jobs:

# Verify Alpine.js auto-loading in template
echo "Verifying Alpine.js auto-loading for non-Hyvä themes:"
if grep -q "jsdelivr.net/npm/alpinejs" "$INSPECTOR_TPL"; then
echo "✓ Template includes Alpine.js CDN loading"
if grep -q "getAlpineJsUrl" "$INSPECTOR_TPL"; then
echo "✓ Template includes local Alpine.js fallback loading"
else
echo "✗ Template missing Alpine.js auto-loading"
echo "✗ Template missing local Alpine.js fallback loading"
exit 1
fi

Expand All @@ -214,6 +214,13 @@ jobs:
exit 1
fi

if grep -q "jsdelivr.net/npm/alpinejs" "$INSPECTOR_TPL"; then
echo "✗ Template still references external Alpine.js CDN"
exit 1
else
echo "✓ Template no longer relies on external Alpine.js CDN"
fi

# Test Luma theme (non-Hyvä)
echo "Testing Inspector with Luma theme (non-Hyvä):"
bin/magento config:set design/theme/theme_id 4 # Luma theme ID
Expand Down
10 changes: 10 additions & 0 deletions src/Block/Inspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
private readonly DeveloperAccessChecker $developerAccessChecker,
array $data = [],
) {
parent::__construct($context, $data);

Check warning on line 36 in src/Block/Inspector.php

View workflow job for this annotation

GitHub Actions / Mutation Tests (Infection)

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private readonly DeveloperAccessChecker $developerAccessChecker, array $data = [], ) { - parent::__construct($context, $data); + } /**
}

/**
Expand Down Expand Up @@ -101,6 +101,16 @@
return $this->getViewFileUrl('OpenForgeProject_MageForge::js/toolbar.js');
}

/**
* Get local Alpine.js fallback URL
*
* @return string
*/
public function getAlpineJsUrl(): string
{
return $this->getViewFileUrl('OpenForgeProject_MageForge::js/lib/alpine.min.js');
}

/**
* Whether button labels should be displayed in the toolbar
*
Expand Down
11 changes: 0 additions & 11 deletions src/etc/frontend/csp_whitelist.xml

This file was deleted.

24 changes: 12 additions & 12 deletions src/view/frontend/templates/inspector.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ declare(strict_types=1);
* Initializes the Alpine.js inspector component.
* The floating button and info badge are created dynamically via JavaScript.
*
* Note: Loads Alpine.js from CDN if not already available (for non-Hyvä themes like Luma)
* Note: Loads bundled Alpine.js locally as fallback if not already available
* (e.g. for non-Hyvä themes like Luma). No external CDN is used.
*
* @var \OpenForgeProject\MageForge\Block\Inspector $block
*/
Expand All @@ -17,47 +18,46 @@ declare(strict_types=1);
<link rel="stylesheet" type="text/css" href="<?= $escaper->escapeUrl($block->getToolbarCssUrl()) ?>" />
<link rel="stylesheet" type="text/css" href="<?= $escaper->escapeUrl($block->getCssUrl()) ?>" />

<!-- Alpine.js Bootstrap (load only if not already present) -->
<!-- Alpine.js Bootstrap (load local fallback only if not already present) -->
Comment thread
dermatz marked this conversation as resolved.
<?php

$alpineJsUrl = json_encode($block->getAlpineJsUrl(), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
$alpineBootstrap = <<<JS
(function() {
'use strict';

function loadAlpineFromCDN() {
function loadAlpineLocally() {
// Check if Alpine.js is already loaded (Hyvä themes) to avoid conflicts
if (typeof Alpine !== 'undefined') {
console.log('[MageForge Inspector] Alpine.js already loaded');
return;
}

console.log('[MageForge Inspector] Loading Alpine.js from CDN');
console.log('[MageForge Inspector] Loading bundled Alpine.js');

var alpineScript = document.createElement('script');
alpineScript.src = 'https://cdn.jsdelivr.net/npm/alpinejs@3.15.11/dist/cdn.min.js';
alpineScript.integrity = 'sha256-vuumPQiVb2T6Bg9rainIejQb8Gn7lslFnCIsb9QuWK4=';
alpineScript.crossOrigin = 'anonymous';
alpineScript.src = {$alpineJsUrl};
alpineScript.onload = function() {
console.log('[MageForge Inspector] Alpine.js loaded successfully');
};
alpineScript.onerror = function() {
console.error('[MageForge Inspector] Failed to load Alpine.js');
console.error('[MageForge Inspector] Failed to load bundled Alpine.js');
};

document.head.appendChild(alpineScript);
}

// Use a short microtask delay after DOMContentLoaded so that all deferred
// and module scripts (including Hyvä's Alpine bundle) have had a chance to
// run before we decide to load Alpine from CDN.
// run before we decide to load the local Alpine fallback.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
// setTimeout(0) yields to the script queue, giving defer/module
// scripts priority over this CDN fallback.
setTimeout(loadAlpineFromCDN, 0);
// scripts priority over this local fallback.
setTimeout(loadAlpineLocally, 0);
});
} else {
setTimeout(loadAlpineFromCDN, 0);
setTimeout(loadAlpineLocally, 0);
}
})();
JS;
Expand Down
2 changes: 1 addition & 1 deletion src/view/frontend/web/css/audits/tab-order.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
align-items: center;
justify-content: center;
transform: translate(-50%, -50%);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
box-shadow: 0 1px 4px rgba(var(--mageforge-color-black-rgb), 0.4);
}

.mageforge-tab-order-badge--negative {
Expand Down
Loading
Loading