diff --git a/app/Models/DeviceModel.php b/app/Models/DeviceModel.php index f2a757f..fbc104f 100644 --- a/app/Models/DeviceModel.php +++ b/app/Models/DeviceModel.php @@ -4,11 +4,13 @@ declare(strict_types=1); namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; /** + * @property-read array $css_variables * @property-read DevicePalette|null $palette */ final class DeviceModel extends Model @@ -76,4 +78,33 @@ final class DeviceModel extends Model { return $this->belongsTo(DevicePalette::class, 'palette_id'); } + + /** + * Returns css_variables with --screen-w and --screen-h filled from width/height + * when puppeteer_window_size_strategy is v2 and they are not set. + * + * @return Attribute, array> + */ + protected function cssVariables(): Attribute + { + return Attribute::get(function (mixed $value, array $attributes): array { + $vars = is_array($value) ? $value : (is_string($value) ? (json_decode($value, true) ?? []) : []); + + if (config('app.puppeteer_window_size_strategy') !== 'v2') { + return $vars; + } + + $width = $attributes['width'] ?? null; + $height = $attributes['height'] ?? null; + + if (empty($vars['--screen-w']) && $width !== null && $width !== '') { + $vars['--screen-w'] = is_numeric($width) ? (int) $width.'px' : (string) $width; + } + if (empty($vars['--screen-h']) && $height !== null && $height !== '') { + $vars['--screen-h'] = is_numeric($height) ? (int) $height.'px' : (string) $height; + } + + return $vars; + }); + } } diff --git a/app/Services/ImageGenerationService.php b/app/Services/ImageGenerationService.php index 903a493..fa6f325 100644 --- a/app/Services/ImageGenerationService.php +++ b/app/Services/ImageGenerationService.php @@ -528,7 +528,7 @@ class ImageGenerationService 'deviceOrientation' => $deviceOrientation, 'colorDepth' => $colorDepth, 'scaleLevel' => $scaleLevel, - 'cssVariables' => $device->deviceModel?->css_variables, + 'cssVariables' => $device->deviceModel?->css_variables ?? [], ]; // Add plugin name for error screens diff --git a/tests/Feature/ScreenCssVariablesTest.php b/tests/Feature/ScreenCssVariablesTest.php new file mode 100644 index 0000000..f5bfc12 --- /dev/null +++ b/tests/Feature/ScreenCssVariablesTest.php @@ -0,0 +1,100 @@ + '
test
', + 'cssVariables' => [ + '--screen-w' => '800px', + '--screen-h' => '480px', + ], + ])->render(); + + expect($html)->toContain(':root'); + expect($html)->toContain('--screen-w: 800px'); + expect($html)->toContain('--screen-h: 480px'); +}); + +test('DeviceModel css_variables attribute merges --screen-w and --screen-h from dimensions when not set', function (): void { + $deviceModel = DeviceModel::factory()->create([ + 'width' => 800, + 'height' => 480, + 'css_variables' => null, + ]); + + $vars = $deviceModel->css_variables; + + expect($vars)->toHaveKey('--screen-w', '800px'); + expect($vars)->toHaveKey('--screen-h', '480px'); +}); + +test('DeviceModel css_variables attribute does not override --screen-w and --screen-h when already set', function (): void { + $deviceModel = DeviceModel::factory()->create([ + 'width' => 800, + 'height' => 480, + 'css_variables' => [ + '--screen-w' => '1200px', + '--screen-h' => '900px', + ], + ]); + + $vars = $deviceModel->css_variables; + + expect($vars['--screen-w'])->toBe('1200px'); + expect($vars['--screen-h'])->toBe('900px'); +}); + +test('DeviceModel css_variables attribute fills only missing --screen-w or --screen-h from dimensions', function (): void { + $deviceModel = DeviceModel::factory()->create([ + 'width' => 800, + 'height' => 480, + 'css_variables' => [ + '--screen-w' => '640px', + ], + ]); + + $vars = $deviceModel->css_variables; + + expect($vars['--screen-w'])->toBe('640px'); + expect($vars['--screen-h'])->toBe('480px'); +}); + +test('DeviceModel css_variables attribute returns raw vars when strategy is not v2', function (): void { + Config::set('app.puppeteer_window_size_strategy', 'v1'); + + $deviceModel = DeviceModel::factory()->create([ + 'width' => 800, + 'height' => 480, + 'css_variables' => ['--custom' => 'value'], + ]); + + $vars = $deviceModel->css_variables; + + expect($vars)->toBe(['--custom' => 'value']); +}); + +test('device model css_variables are available via device relationship for rendering', function (): void { + Config::set('app.puppeteer_window_size_strategy', 'v2'); + + $deviceModel = DeviceModel::factory()->create([ + 'width' => 800, + 'height' => 480, + 'css_variables' => null, + ]); + $device = Device::factory()->create([ + 'device_model_id' => $deviceModel->id, + ]); + $device->load('deviceModel'); + + $vars = $device->deviceModel?->css_variables ?? []; + + expect($vars)->toHaveKey('--screen-w', '800px'); + expect($vars)->toHaveKey('--screen-h', '480px'); +});