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
17 changes: 17 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
--color-snow-flurry-200: #a2fd00;
--color-snow-flurry-300: #97ed00;

/* Torchlight code surface (matches the material-theme-palenight theme) */
--color-torchlight-surface: #292d3e;
--color-torchlight-text: #a6accd;

--font-poppins: 'Poppins', Verdana, sans-serif;
}

Expand Down Expand Up @@ -296,6 +300,19 @@ nav.docs-navigation li:has(.third-tier .exact-active) > .subsection-header {
@apply block min-w-max py-4;
}

/*
Fallback for blocks Torchlight returns un-highlighted (e.g. a language
its API can't tokenise, like the Svelte snippets on some plugin pages).
These come back with an empty `style` attribute and no per-token color
spans, so without this they have no background and inherit prose's light
text color, rendering the block invisible. Successfully highlighted
blocks set `background-color` inline, so they're excluded here and keep
their own theme colors.
*/
.prose pre code.torchlight:not([style*='background-color']) {
@apply bg-torchlight-surface text-torchlight-text;
}

/*
Horizontal line padding.
*/
Expand Down
58 changes: 58 additions & 0 deletions tests/Feature/TorchlightCodeBlockTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Tests\Feature;

use App\Support\CommonMark\CommonMark;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

class TorchlightCodeBlockTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();

// A token is required for Torchlight to attempt highlighting (it throws
// outside production otherwise), and faking the API forces its built-in
// "un-highlighted" fallback — the same state produced in the wild when
// Torchlight cannot tokenise a block. This keeps the test deterministic
// and offline regardless of whether a real token is present locally.
config(['torchlight.token' => 'test-token']);
Http::fake([
'*' => Http::response(['blocks' => []], 200),
]);
}

public function test_fenced_code_renders_as_a_torchlight_block(): void
{
$html = CommonMark::convertToHtml("```php\necho 'hello';\n```");

$this->assertStringContainsString("class='torchlight'", $html);
}

public function test_unhighlighted_block_carries_torchlight_class_for_css_fallback(): void
{
// When Torchlight cannot highlight a block (e.g. a language its API
// can't tokenise, such as the Svelte snippet below) it returns the
// block un-highlighted with an empty `style` attribute and no per-token
// color spans. The fallback CSS targets
// `code.torchlight:not([style*='background-color'])` to give these
// otherwise-invisible blocks a background and readable text, so the
// markup must still carry the `torchlight` class without an inline
// background color.
$svelte = <<<'MD'
```svelte
<div>
{#if status}<p>{status}</p>{/if}
<button on:click={tap} disabled={!ready}>Tap</button>
</div>
```
MD;

$html = CommonMark::convertToHtml($svelte);

$this->assertStringContainsString("class='torchlight'", $html);
$this->assertStringContainsString("style=''", $html);
$this->assertStringNotContainsString('background-color', $html);
}
}
Loading