Skip to content

Commit dd36eed

Browse files
committed
[3.0] Support Youtube embed videos with a timestamp
Fixes #7118 Syntax: ``` [youtube]sF80I-TQiW0[/youtube] [youtube start=23363]sF80I-TQiW0[/youtube] ```
1 parent 6fca102 commit dd36eed

File tree

4 files changed

+114
-8
lines changed

4 files changed

+114
-8
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
/**
1919
* Represents the youtube BBCode.
2020
*/
21-
class YouTube extends BBCode
21+
class YouTube1 extends BBCode
2222
{
2323
/*******************
2424
* Public properties

Sources/BBCode/YouTube2.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/**
4+
* Simple Machines Forum (SMF)
5+
*
6+
* @package SMF
7+
* @author Simple Machines https://www.simplemachines.org
8+
* @copyright 2025 Simple Machines and individual contributors
9+
* @license https://www.simplemachines.org/about/smf/license.php BSD
10+
*
11+
* @version 3.0 Alpha 3
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace SMF\BBCode;
17+
18+
/**
19+
* Represents the youtube BBCode.
20+
*/
21+
class YouTube2 extends BBCode
22+
{
23+
/*******************
24+
* Public properties
25+
*******************/
26+
27+
/**
28+
*
29+
*/
30+
public string $tag = 'youtube';
31+
32+
/**
33+
*
34+
*/
35+
public ?string $type = BBCode::TYPE_UNPARSED_CONTENT;
36+
37+
/**
38+
*
39+
*/
40+
public ?array $parameters = [
41+
'start' => ['match' => '(\d+)'],
42+
];
43+
44+
/**
45+
*
46+
*/
47+
public ?string $content = '<div class="videocontainer"><div><iframe frameborder="0" src="https://www.youtube.com/embed/$1?origin={hosturl}&wmode=opaque&start={start}" data-youtube-id="$1" data-start="{start}" allowfullscreen loading="lazy"></iframe></div></div>';
48+
49+
/**
50+
*
51+
*/
52+
public ?string $disabled_content = '<a href="https://www.youtube.com/watch?v=$1&start={start}" target="_blank" rel="noopener">https://www.youtube.com/watch?v=$1&t={start}</a>';
53+
54+
/**
55+
*
56+
*/
57+
public bool $block_level = true;
58+
}

Sources/Parsers/BBCodeParser.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ class BBCodeParser extends Parser
318318
['class' => \SMF\BBCode\Url1::class],
319319
['class' => \SMF\BBCode\Url2::class],
320320
['class' => \SMF\BBCode\White::class],
321-
['class' => \SMF\BBCode\YouTube::class],
321+
['class' => \SMF\BBCode\YouTube1::class],
322+
['class' => \SMF\BBCode\YouTube2::class],
322323
];
323324

324325
/**

Themes/default/scripts/sceditor.plugins.smf.js

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -810,11 +810,31 @@ sceditor.command.set(
810810
sceditor.command.set(
811811
'youtube', {
812812
exec: function (caller) {
813-
var editor = this;
813+
const editor = this;
814814

815-
editor.commands.youtube._dropDown(editor, caller, function (id, time) {
816-
editor.wysiwygEditorInsertHtml('<div class="videocontainer"><div><iframe frameborder="0" allowfullscreen src="https://www.youtube-nocookie.com/embed/' + id + '?wmode=opaque&start=' + time + '" data-youtube-id="' + id + '" loading="lazy"></iframe></div></div>');
815+
editor.commands.youtube._dropDown(editor, caller, function (id, start) {
816+
if (typeof start !== "undefined" && start > 0) {
817+
editor.wysiwygEditorInsertHtml('<div class="videocontainer"><div><iframe frameborder="0" allowfullscreen src="https://www.youtube-nocookie.com/embed/' + id + '?wmode=opaque&start=' + start + '" data-youtube-id="' + id + '" data-start="' + start + '" loading="lazy"></iframe></div></div>');
818+
} else {
819+
editor.wysiwygEditorInsertHtml('<div class="videocontainer"><div><iframe frameborder="0" allowfullscreen src="https://www.youtube-nocookie.com/embed/' + id + '?wmode=opaque" data-youtube-id="' + id + '" loading="lazy"></iframe></div></div>');
820+
}
817821
});
822+
},
823+
txtExec: function (caller) {
824+
const editor = this;
825+
826+
editor.commands.youtube._dropDown(
827+
editor,
828+
caller,
829+
function (id, start) {
830+
if (typeof start !== "undefined" && start > 0) {
831+
editor.insertText('[youtube start=' + start + ']' + id + '[/youtube]');
832+
} else {
833+
editor.insertText('[youtube]' + id + '[/youtube]');
834+
}
835+
836+
}
837+
);
818838
}
819839
}
820840
).set(
@@ -1669,14 +1689,41 @@ sceditor.formats.bbcode.set(
16691689
isInline: false,
16701690
skipLastLineBreak: true,
16711691
format: function (element, content) {
1672-
youtube_id = $(element).find('iframe').data('youtube-id');
1692+
const
1693+
iframe = $(element).find('iframe'),
1694+
youtube_id = iframe.data('youtube-id');
1695+
let attribs = '';
1696+
1697+
if (iframe.attr('data-start')) {
1698+
attribs += " start=" + iframe.attr('data-start');
1699+
}
16731700

16741701
if (typeof youtube_id !== "undefined")
1675-
return '[youtube]' + youtube_id + '[/youtube]';
1702+
return '[youtube' + attribs + ']' + youtube_id + '[/youtube]';
16761703
else
16771704
return content;
16781705
},
1679-
html: '<div class="videocontainer"><div><iframe frameborder="0" src="https://www.youtube-nocookie.com/embed/{0}?wmode=opaque" data-youtube-id="{0}" loading="lazy" allowfullscreen></iframe></div></div>'
1706+
html: function (token, attrs, content) {
1707+
const
1708+
id_match = /^[a-zA-Z0-9_\-]{11}$/g,
1709+
start = typeof attrs.start !== "undefined" ? attrs.start : 0;
1710+
let attribs = '';
1711+
1712+
if (content.match(id_match) === null || (start.length > 0 && !$.isNumeric(start) || Math.floor(start) != +start || +start <= 0)) {
1713+
if (attrs.start !== "undefined") {
1714+
attribs += " start=" + attrs.start;
1715+
}
1716+
1717+
return '[youtube' + attribs + ']' + content + '[/youtube]';
1718+
}
1719+
1720+
if (attrs.start !== "undefined") {
1721+
return '<div class="videocontainer"><div><iframe frameborder="0" src="https://www.youtube-nocookie.com/embed/{0}?wmode=opaque&start=' + attrs.start + '" data-youtube-id="' + content + '" data-start="' + attrs.start + '" loading="lazy" allowfullscreen></iframe></div></div>'
1722+
}
1723+
else {
1724+
return '<div class="videocontainer"><div><iframe frameborder="0" src="https://www.youtube-nocookie.com/embed/{0}?wmode=opaque" data-youtube-id="' + content + '" loading="lazy" allowfullscreen></iframe></div></div>'
1725+
}
1726+
}
16801727
}
16811728
);
16821729

0 commit comments

Comments
 (0)