Skip to content
Draft
5 changes: 4 additions & 1 deletion packages/actions/resources/views/components/modals.blade.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
@if ($this instanceof \Filament\Actions\Contracts\HasActions && (! $this->hasActionsModalRendered))
<style nonce="{{ \Filament\csp_nonce() }}">
.fi-internal-components-modals {height: 0;}
</style>
<div
wire:partial="action-modals"
x-data="filamentActionModals({
livewireId: @js($this->getId()),
})"
style="height: 0"
class="fi-internal-components-modals"
>
@foreach ($this->getMountedActions() as $action)
@if ((! $loop->last) || $this->mountedActionShouldOpenModal())
Expand Down
5 changes: 4 additions & 1 deletion packages/forms/resources/views/components/textarea.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ class="fi-fo-textarea-wrp"
])
"
>
<div wire:ignore.self style="height: '{{ $initialHeight . 'rem' }}'">
<style nonce="{{ \Filament\csp_nonce() }}">
.fi-internal-components-textarea {height: '{{ $initialHeight . 'rem' }}'; }
</style>
<div wire:ignore.self class="fi-internal-components-textarea">
<textarea
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('textarea', 'filament/forms') }}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
namespace Filament\Forms\Components\RichEditor\Actions;

use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\RichEditor\EditorCommand;
use Filament\Forms\Components\RichEditor\TextColor;
use Filament\Forms\Components\Select;
use Filament\Support\Enums\Width;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class TextColorAction
{
Expand All @@ -26,13 +28,26 @@ public static function make(): Action
->schema(function (RichEditor $component) {
$options = Arr::mapWithKeys(
$component->getTextColors(),
fn (TextColor $color, string $name): array => [$name => <<<HTML
<div class="fi-fo-rich-editor-text-color-select-option">
<div class="fi-fo-rich-editor-text-color-select-option-preview" style="--color: {$color->getColor()}; --dark-color: {$color->getDarkColor()}"></div>
function (TextColor $color, string $name): array {
$uniqueClass = 'fi-unique-' . Str::random();
$nonce = Filament::getCspNonce();

<div>{$color->getSafeLabelHtml()}</div>
</div>
HTML],
return [
$name => <<<HTML
<div class="fi-fo-rich-editor-text-color-select-option">
<style nonce="{$nonce}">
.{$uniqueClass} {
--color: '{$color->getColor()}';
--dark-color: '{$color->getColor()}';
}
</style>
<div class="fi-fo-rich-editor-text-color-select-option-preview {$uniqueClass}" ></div>

<div>{$color->getSafeLabelHtml()}</div>
</div>
HTML
];
},
);

return [
Expand Down
12 changes: 9 additions & 3 deletions packages/infolists/src/Components/RepeatableEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Js;
use function Filament\csp_nonce;

class RepeatableEntry extends Entry implements HasEmbeddedView
{
Expand Down Expand Up @@ -185,6 +186,13 @@ protected function toEmbeddedTableHtml(): string

ob_start(); ?>

<style nonce="<?= csp_nonce() ?>">
<?php foreach (array_filter(array_unique(array_map(static fn ($column): string => $column->getWidth(), $tableColumns)), static fn (string $value) => trim($value) !== '') as $width) { ?>
<?= '.fi-internal-components-repeatable-' . $width ?> {
width: <?= $width ?>;
}
<?php } ?>
</style>
<div <?= $attributes->toHtml() ?>>
<table>
<thead>
Expand All @@ -194,10 +202,8 @@ protected function toEmbeddedTableHtml(): string
class="<?= Arr::toCssClasses([
'fi-wrapped' => $column->canHeaderWrap(),
(($columnAlignment = $column->getAlignment()) instanceof Alignment) ? ('fi-align-' . $columnAlignment->value) : $columnAlignment,
'fi-internal-components-repeatable-' . ($columnWidth = $column->getWidth()) => filled($columnWidth),
]) ?>"
<?php if (filled($columnWidth = $column->getWidth())) { ?>
style="width: <?= $columnWidth ?>"
<?php } ?>
>
<?php if (! $column->isHeaderLabelHidden()) { ?>
<?= e($column->getLabel()) ?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class="fi-no-database"

@if ($broadcastChannel = $this->getBroadcastChannel())
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($broadcastChannel)).listen(
'.database-notifications.sent',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

@if ($broadcastChannel = $this->getBroadcastChannel())
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($broadcastChannel)).notification(
(notification) => {
Expand Down
14 changes: 7 additions & 7 deletions packages/panels/resources/views/components/layout/base.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::STYLES_BEFORE, scopes: $renderHookScopes) }}

<style>
<style nonce="{{ \Filament\csp_nonce() }}">
[x-cloak=''],
[x-cloak='x-cloak'],
[x-cloak='1'] {
Expand Down Expand Up @@ -73,7 +73,7 @@
{{ filament()->getMonoFontHtml() }}
{{ filament()->getSerifFontHtml() }}

<style>
<style nonce="{{ \Filament\csp_nonce() }}">
:root {
--font-family: '{!! filament()->getFontFamily() !!}';
--mono-font-family: '{!! filament()->getMonoFontFamily() !!}';
Expand All @@ -89,15 +89,15 @@
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::STYLES_AFTER, scopes: $renderHookScopes) }}

@if (! filament()->hasDarkMode())
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
localStorage.setItem('theme', 'light')
</script>
@elseif (filament()->hasDarkModeForced())
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
localStorage.setItem('theme', 'dark')
</script>
@else
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
const loadDarkMode = () => {
window.theme = localStorage.getItem('theme') ?? @js(filament()->getDefaultThemeMode()->value)

Expand Down Expand Up @@ -141,15 +141,15 @@
@filamentScripts(withCore: true)

@if (filament()->hasBroadcasting() && config('filament.broadcasting.echo'))
<script data-navigate-once>
<script nonce="{{ \Filament\csp_nonce() }}" data-navigate-once>
window.Echo = new window.EchoFactory(@js(config('filament.broadcasting.echo')))

window.dispatchEvent(new CustomEvent('EchoLoaded'))
</script>
@endif

@if (filament()->hasDarkMode() && (! filament()->hasDarkModeForced()))
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
loadDarkMode()
</script>
@endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class="fi-page-main-sub-navigation-mobile-menu-render-hook-ctn"
@if (method_exists($this, 'hasUnsavedDataChangesAlert') && $this->hasUnsavedDataChangesAlert())
@if (\Filament\Support\Facades\FilamentView::hasSpaMode())
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
setUpSpaModeUnsavedDataChangesAlert({
body: @js(__('filament-panels::unsaved-changes-alert.body')),
resolveLivewireComponentUsing: () => @this,
Expand All @@ -160,7 +160,7 @@ class="fi-page-main-sub-navigation-mobile-menu-render-hook-ctn"
@endscript
@else
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
setUpUnsavedDataChangesAlert({ $wire })
</script>
@endscript
Expand All @@ -169,7 +169,7 @@ class="fi-page-main-sub-navigation-mobile-menu-render-hook-ctn"

@if (! app()->hasDebugModeEnabled())
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
window.filamentErrorNotifications = @js($this->hasErrorNotifications() ? $this->getErrorNotifications() : null)
</script>
@endscript
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@if (filament()->hasUnsavedChangesAlerts())
@script
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
setUpUnsavedActionChangesAlert({
resolveLivewireComponentUsing: () => @this,
$wire,
Expand Down
2 changes: 1 addition & 1 deletion packages/panels/resources/views/livewire/sidebar.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class="fi-sidebar-close-collapse-sidebar-btn"
@endforeach
</ul>

<script>
<script nonce="{{ \Filament\csp_nonce() }}">
var collapsedGroups = JSON.parse(
localStorage.getItem('collapsedGroups'),
)
Expand Down
2 changes: 2 additions & 0 deletions packages/panels/src/Facades/Filament.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@
* @method static void setCurrentPanel(Panel | string | null $panel = null)
* @method static void setServingStatus(bool $condition = true)
* @method static void setTenant(Model | null $tenant = null, bool $isQuiet = false)
* @method static void setCspNonce(string|Closure|null $nonce)
* @method static string|null getCspNonce()
*
* @see FilamentManager
*/
Expand Down
15 changes: 15 additions & 0 deletions packages/panels/src/FilamentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class FilamentManager

protected ?Model $tenant = null;

protected string|Closure|null $cspNonce = null;

public function auth(): Guard
{
return $this->getCurrentOrDefaultPanel()->auth();
Expand Down Expand Up @@ -1104,4 +1106,17 @@ public function getErrorNotifications(): array
{
return $this->getCurrentOrDefaultPanel()->getErrorNotifications();
}

/**
* @param string|(\Closure(): string)|null $nonce
*/
public function useCspNonce(string|Closure|null $nonce): void
{
$this->cspNonce = $nonce;
}

public function getCspNonce(): ?string
{
return value($this->cspNonce);
}
}
7 changes: 7 additions & 0 deletions packages/panels/src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,10 @@ function get_authorization_response(UnitEnum | string $action, Model | string $m
return $response;
}
}

if (!function_exists('Filament\csp_nonce')) {
function csp_nonce(): ?string
{
return Filament::getCspNonce();
}
}
4 changes: 2 additions & 2 deletions packages/support/resources/views/assets.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@if (isset($data))
<script>
<script nonce="{{ \Filament\csp_nonce() }}">
window.filamentData = @js($data)
</script>
@endif
Expand All @@ -10,7 +10,7 @@
@endif
@endforeach

<style>
<style nonce="{{ \Filament\csp_nonce() }}">
:root {
@foreach ($cssVariables ?? [] as $cssVariableName => $cssVariableValue) --{{ $cssVariableName }}:{{ $cssVariableValue }}; @endforeach
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,14 @@
@endif

@if ($image)
@php($uniqueClass = 'fi-unique-' . \Illuminate\Support\Str::random())
<style nonce="{{ \Filament\csp_nonce() }}">
.{{ $uniqueClass }} {
background-image: url('{{ $image }}');
}
</style>
<div
class="fi-dropdown-list-item-image"
style="background-image: url('{{ $image }}')"
class="fi-dropdown-list-item-image {{ $uniqueClass }}"
@if ($hasLoadingIndicator)
wire:loading.remove.delay.{{ config('filament.livewire_loading_delay', 'default') }}
wire:target="{{ $loadingIndicatorTarget }}"
Expand Down
5 changes: 5 additions & 0 deletions packages/support/src/Assets/Js.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace Filament\Support\Assets;

use Filament\Facades\Filament;
use Filament\Support\Facades\FilamentView;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\HtmlString;
use function Filament\csp_nonce;

class Js extends Asset
{
Expand Down Expand Up @@ -116,6 +118,8 @@ public function getHtml(): Htmlable
$defer = $this->isDeferred() ? 'defer' : '';
$module = $this->isModule() ? 'type="module"' : '';
$extraAttributesHtml = $this->getExtraAttributesHtml();
$cspNonce = Filament::getCspNonce();
$cspNonce = $cspNonce === null || $cspNonce === '' ? '' : 'nonce="' . $cspNonce . '"';

$hasSpaMode = FilamentView::hasSpaMode();

Expand All @@ -132,6 +136,7 @@ public function getHtml(): Htmlable
{$extraAttributesHtml}
{$navigateOnce}
{$navigateTrack}
{$cspNonce}
></script>
",
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<title>{{ config('app.name') }}</title>

<style>
<style nonce="{{ \Filament\csp_nonce() }}">
[x-cloak] {
display: none !important;
}
Expand Down
10 changes: 9 additions & 1 deletion packages/widgets/resources/views/chart-widget.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,18 @@ class="fi-wi-chart-filter-content-actions-ctn"
])
}}
>
<style nonce="{{ \Filament\csp_nonce() }}">
@if ($maxHeight)
.fi-internal-views-chart-widget-{{ $maxHeight }} {
max-height: {{ $maxHeight }};
}
@endif
</style>

<canvas
x-ref="canvas"
@if ($maxHeight)
style="max-height: {{ $maxHeight }}"
class="fi-internal-views-chart-widget-{{ $maxHeight }}"
@endif
></canvas>

Expand Down