Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shortcode support for [quote] #3074

Merged
merged 7 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 9 additions & 3 deletions app/Support/Shortcode/Shortcode.php
wescopeland marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function __construct()
->add('code', fn (ShortcodeInterface $s) => $this->renderCode($s))
->add('url', fn (ShortcodeInterface $s) => $this->renderUrlLink($s))
->add('link', fn (ShortcodeInterface $s) => $this->renderLink($s))
->add('quote', fn (ShortcodeInterface $s) => $this->renderQuote($s))
->add('spoiler', fn (ShortcodeInterface $s) => $this->renderSpoiler($s))
->add('ach', fn (ShortcodeInterface $s) => $this->embedAchievement((int) ($s->getBbCode() ?: $s->getContent())))
->add('game', fn (ShortcodeInterface $s) => $this->embedGame((int) ($s->getBbCode() ?: $s->getContent())))
Expand Down Expand Up @@ -148,11 +149,11 @@ public static function stripAndClamp(
'~\[ticket(=)?(\d+)]~i' => 'Ticket $2',

// Fragments: opening tags without closing tags.
'~\[(b|i|u|s|img|code|url|link|spoiler|ach|game|ticket|user)\b[^\]]*?\]~i' => '',
'~\[(b|i|u|s|img|code|url|link|spoiler|ach|game|ticket|user)\b[^\]]*?$~i' => '...',
'~\[(b|i|u|s|img|code|url|link|quote|spoiler|ach|game|ticket|user)\b[^\]]*?\]~i' => '',
'~\[(b|i|u|s|img|code|url|link|quote|spoiler|ach|game|ticket|user)\b[^\]]*?$~i' => '...',

// Fragments: closing tags without opening tags.
'~\[/?(b|i|u|s|img|code|url|link|spoiler|ach|game|ticket|user)\]~i' => '',
'~\[/?(b|i|u|s|img|code|url|link|quote|spoiler|ach|game|ticket|user)\]~i' => '',
];

foreach ($stripPatterns as $stripPattern => $replacement) {
Expand Down Expand Up @@ -315,6 +316,11 @@ private function renderCode(ShortcodeInterface $shortcode): string
return '<pre class="codetags">' . str_replace('<br>', '', $shortcode->getContent() ?? '') . '</pre>';
}

private function renderQuote(ShortcodeInterface $shortcode): string
{
return '<p class="quotedtext">' . $shortcode->getContent() . '</p>';
}

private function renderSpoiler(ShortcodeInterface $shortcode): string
{
$content = $shortcode->getContent() ?? '';
Expand Down
1 change: 1 addition & 0 deletions lang/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@
"Underline": "Underline",
"Strikethrough": "Strikethrough",
"Code": "Code",
"Quote": "Quote",
"Spoiler": "Spoiler",
"Image": "Image",
"Link": "Link",
Expand Down
9 changes: 9 additions & 0 deletions resources/css/devbox.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
box-sizing: border-box;
}

.quotedtext {
border-left: 3px solid var(--text-color-muted);
padding: 4px 6px 5px 8px;
margin: 3px 0px;
background: var(--box-bg-color);
width: 100%;
display: inline-block;
}
wescopeland marked this conversation as resolved.
Show resolved Hide resolved

.devbox > .spoiler {
display: none;
border-style: dashed;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { render, screen } from '@/test';

import { ShortcodeQuote } from './ShortcodeQuote';

describe('Component: ShortcodeQuote', () => {
it('renders without crashing', () => {
// ARRANGE
const { container } = render(<ShortcodeQuote>Test content</ShortcodeQuote>);

// ASSERT
expect(container).toBeTruthy();
});

it('given a simple string child, renders it inside a span with the quotedtext class', () => {
// ARRANGE
render(<ShortcodeQuote>test content</ShortcodeQuote>);

// ASSERT
const spanEl = screen.getByText(/test content/i);

expect(spanEl).toBeVisible();
expect(spanEl).toHaveClass('quotedtext');
});
});
wescopeland marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { FC, ReactNode } from 'react';

interface ShortcodeQuoteProps {
children: ReactNode;
}

export const ShortcodeQuote: FC<ShortcodeQuoteProps> = ({ children }) => {
return <span className="quotedtext">{children}</span>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ShortcodeQuote';
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ describe('Component: ShortcodeRenderer', () => {
expect(textEl).toHaveClass('codetags');
});

it('given a body with a quote tag, renders the quote shortcode component', () => {
// ARRANGE
const body = '[quote]this is some stuff inside quote tags[/quote]';

render(<ShortcodeRenderer body={body} />);

// ASSERT
const textEl = screen.getByText(/this is some stuff/i);

expect(textEl).toBeVisible();
expect(textEl.nodeName).toEqual('SPAN');
expect(textEl).toHaveClass('quotedtext');
});

it('given a body with a spoiler tag, renders the spoiler shortcode component', () => {
// ARRANGE
const body = '[spoiler]this is a spoiler![/spoiler]';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ShortcodeAch } from './ShortcodeAch';
import { ShortcodeCode } from './ShortcodeCode';
import { ShortcodeGame } from './ShortcodeGame';
import { ShortcodeImg } from './ShortcodeImg';
import { ShortcodeQuote } from './ShortcodeQuote';
import { ShortcodeSpoiler } from './ShortcodeSpoiler';
import { ShortcodeTicket } from './ShortcodeTicket';
import { ShortcodeUrl } from './ShortcodeUrl';
Expand Down Expand Up @@ -41,6 +42,11 @@ const retroachievementsPreset = presetReact.extend((tags) => ({
tag: ShortcodeCode,
}),

quote: (node) => ({
...node,
tag: ShortcodeQuote,
}),

spoiler: (node) => ({
...node,
tag: ShortcodeSpoiler,
Expand Down Expand Up @@ -111,6 +117,7 @@ export const ShortcodeRenderer: FC<ShortcodeRendererProps> = ({ body }) => {
'u',
's',
'code',
'quote',
'spoiler',
'img',
'url',
Expand Down
2 changes: 2 additions & 0 deletions resources/js/features/forums/hooks/useShortcodesList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
LuEyeOff,
LuItalic,
LuLink,
LuQuote,
LuStrikethrough,
LuUnderline,
} from 'react-icons/lu';
Expand All @@ -23,6 +24,7 @@ export function useShortcodesList() {
{ icon: LuUnderline, t_label: t('Underline'), start: '[u]', end: '[/u]' },
{ icon: LuStrikethrough, t_label: t('Strikethrough'), start: '[s]', end: '[/s]' },
{ icon: LuCode2, t_label: t('Code'), start: '[code]', end: '[/code]' },
{ icon: LuQuote, t_label: t('Quote'), start: '[quote]', end: '[/quote]' },
{ icon: LuEyeOff, t_label: t('Spoiler'), start: '[spoiler]', end: '[/spoiler]' },
{ icon: BsImageFill, t_label: t('Image'), start: '[img=', end: ']' },
{ icon: LuLink, t_label: t('Link'), start: '[url=', end: ']' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
{{-- x-tooltip="tooltip" --}} title="{{ __('Code') }}">
<x-fas-code />
</button>
<button type="button" class="btn" onclick="injectShortcode('{{ $id }}', '[spoiler]', '[/spoiler]')"
<button type="button" class="btn" onclick="injectShortcode('{{ $id }}', '[quote]', '[/quote]')"
{{-- x-tooltip="tooltip" --}} title="{{ __('Quote') }}">
<x-fas-quote-right />
</button>
<button type="button" class="btn" onclick="injectShortcode('{{ $id }}', '[spoiler]', '[/spoiler]')"
{{-- x-tooltip="tooltip" --}} title="{{ __('Spoiler') }}">
Spoiler
<x-fas-eye-slash />
</button>
<button type="button" class="btn" onclick="injectShortcode('{{ $id }}', '[img=', ']')"
{{-- x-tooltip="tooltip" --}} title="{{ __('Image') }}">
Expand Down
5 changes: 5 additions & 0 deletions tests/Feature/Community/ShortcodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ public function testStripAndClampFormatters(): void
Shortcode::stripAndClamp('[code]Hello[/code]')
);

$this->assertSame(
'Hello',
Shortcode::stripAndClamp('[quote]Hello[/quote]')
);

$this->assertSame(
'Hello',
Shortcode::stripAndClamp('[url=abc.xyz]Hello[/url]')
Expand Down