diff --git a/Sources/BBCode/Code1.php b/Sources/BBCode/Code1.php index 54afb73eaf..8310bfff29 100644 --- a/Sources/BBCode/Code1.php +++ b/Sources/BBCode/Code1.php @@ -39,7 +39,7 @@ class Code1 extends BBCode /** * */ - public ?string $content = '
{txt_code} {txt_code_select}
$1'; + public ?string $content = '
{txt_code}
$1
'; /** * @@ -63,53 +63,27 @@ public function validate(BBCodeInterface &$bbc, array|string &$data, array $disa if (!isset($disabled['code'])) { $code = \is_array($data) ? $data[0] : $data; - $add_begin = ( - \is_array($data) - && isset($data[1]) - && strtoupper($data[1]) === 'PHP' - && !str_contains($code, '<?php') - ); + $parts = preg_split('~(<\?php|\?>)~', $code, -1, PREG_SPLIT_DELIM_CAPTURE); - if ($add_begin) { - $code = '<?php ' . $code . '?>'; - $data[1] = 'PHP'; - } - - $php_parts = preg_split('~(<\?php|\?>)~', $code, -1, PREG_SPLIT_DELIM_CAPTURE); - - for ($php_i = 0, $php_n = \count($php_parts); $php_i < $php_n; $php_i++) { + for ($i = 0, $n = count($parts); $i < $n; $i++) { // Do PHP code coloring? - if ($php_parts[$php_i] != '<?php') { + if ($parts[$i] != '<?php') { continue; } - $php_string = ''; - - while ($php_i + 1 < \count($php_parts) && $php_parts[$php_i] != '?>') { - $php_string .= $php_parts[$php_i]; - $php_parts[$php_i++] = ''; - } - - $php_parts[$php_i] = Parser::highlightPhpCode($php_string . $php_parts[$php_i]); + $string = ''; - if (\is_array($data) && empty($data[1])) { - $data[1] = 'PHP'; + while ($i + 1 < $n && $parts[$i] != '?>') { + $string .= $parts[$i]; + $parts[$i++] = ''; } + $parts[$i] = Parser::highlightPhpCode($string . $parts[$i]); } - // Fix the PHP code stuff... - $code = str_replace("
\t
", "\t", implode('', $php_parts)); - - $code = str_replace("\t", "\t", $code); - - if ($add_begin) { - $code = preg_replace(['/^(.+?)<\?.{0,40}?php(?: |\s)/', '/\?>((?:\s*<\/(font|span)>)*)$/m'], '$1', $code, 2); - } - - if (\is_array($data)) { - $data[0] = $code; + if (is_array($data)) { + $data[0] = implode('', $parts); } else { - $data = $code; + $data = implode('', $parts); } } } diff --git a/Sources/BBCode/Code2.php b/Sources/BBCode/Code2.php index f4d97eed6b..40d911c431 100644 --- a/Sources/BBCode/Code2.php +++ b/Sources/BBCode/Code2.php @@ -39,7 +39,7 @@ class Code2 extends BBCode /** * */ - public ?string $content = '
{txt_code} ($2) {txt_code_select}
$1'; + public ?string $content = '
{txt_code} ($2)
$1
'; /** * @@ -63,53 +63,27 @@ public function validate(BBCodeInterface &$bbc, array|string &$data, array $disa if (!isset($disabled['code'])) { $code = \is_array($data) ? $data[0] : $data; - $add_begin = ( - \is_array($data) - && isset($data[1]) - && strtoupper($data[1]) === 'PHP' - && !str_contains($code, '<?php') - ); + $parts = preg_split('~(<\?php|\?>)~', $code, -1, PREG_SPLIT_DELIM_CAPTURE); - if ($add_begin) { - $code = '<?php ' . $code . '?>'; - $data[1] = 'PHP'; - } - - $php_parts = preg_split('~(<\?php|\?>)~', $code, -1, PREG_SPLIT_DELIM_CAPTURE); - - for ($php_i = 0, $php_n = \count($php_parts); $php_i < $php_n; $php_i++) { + for ($i = 0, $n = count($parts); $i < $n; $i++) { // Do PHP code coloring? - if ($php_parts[$php_i] != '<?php') { + if ($parts[$i] != '<?php') { continue; } - $php_string = ''; - - while ($php_i + 1 < \count($php_parts) && $php_parts[$php_i] != '?>') { - $php_string .= $php_parts[$php_i]; - $php_parts[$php_i++] = ''; - } - - $php_parts[$php_i] = Parser::highlightPhpCode($php_string . $php_parts[$php_i]); + $string = ''; - if (\is_array($data) && empty($data[1])) { - $data[1] = 'PHP'; + while ($i + 1 < $n && $parts[$i] != '?>') { + $string .= $parts[$i]; + $parts[$i++] = ''; } + $parts[$i] = Parser::highlightPhpCode($string . $parts[$i]); } - // Fix the PHP code stuff... - $code = str_replace("
\t
", "\t", implode('', $php_parts)); - - $code = str_replace("\t", "\t", $code); - - if ($add_begin) { - $code = preg_replace(['/^(.+?)<\?.{0,40}?php(?: |\s)/', '/\?>((?:\s*<\/(font|span)>)*)$/m'], '$1', $code, 2); - } - - if (\is_array($data)) { - $data[0] = $code; + if (is_array($data)) { + $data[0] = implode('', $parts); } else { - $data = $code; + $data = implode('', $parts); } } } diff --git a/Themes/default/css/jquery.sceditor.default.css b/Themes/default/css/jquery.sceditor.default.css index 9755a476a8..b1d90c3eca 100644 --- a/Themes/default/css/jquery.sceditor.default.css +++ b/Themes/default/css/jquery.sceditor.default.css @@ -1,5 +1,5 @@ /*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ -html, p, code::before, table { +html, p, .bbc_code code::before, table { margin: 0; padding: 0; font-family: Verdana, Arial, Helvetica, sans-serif; @@ -44,30 +44,22 @@ table, td { min-width: 0.5ch; } -code::before { +.bbc_code code::before { position: absolute; content: 'Code:'; top: -1.35em; left: 0; } -code[data-title]::before { +.bbc_code code[data-title]::before { content: 'Code: (' attr(data-title) ')'; } -code { +.bbc_code { margin-top: 1.5em; position: relative; background: #eee; border: 1px solid #aaa; white-space: pre-wrap; padding: .25em; - display: block; -} -.ie6 code, .ie7 code { - margin-top: 0; -} -code::before, code { - display: block; - text-align: left; } span.phpcode, font[face=monospace] { diff --git a/Themes/default/scripts/jquery.sceditor.smf.js b/Themes/default/scripts/jquery.sceditor.smf.js index 3f3d15c60e..a9c89c5b62 100644 --- a/Themes/default/scripts/jquery.sceditor.smf.js +++ b/Themes/default/scripts/jquery.sceditor.smf.js @@ -1652,11 +1652,13 @@ sceditor.formats.bbcode.set( sceditor.formats.bbcode.set( 'php', { tags: { - span: { - 'class': 'phpcode' + code: { + class: 'phpcode' } }, + allowsEmpty: true, isInline: true, + allowedChildren: ['#', '#newline'], format: '[php]{0}[/php]', html: function (element, attrs, content) { // If the content contains multiple lines, format as a code block. @@ -1684,23 +1686,41 @@ sceditor.formats.bbcode.set( sceditor.formats.bbcode.set( 'code', { tags: { - code: null + code: null, + div: { + class: 'codeheader' + }, + pre: { + class: 'bbc_code' + } }, isInline: false, allowedChildren: ['#', '#newline'], format: function (element, content) { - var - dom = sceditor.dom, - attr = dom.attr, - title = attr(element, 'data-title'), - from = title ?' =' + title : ''; + let title = element.getAttribute('data-title'); + + if (element.className === 'php') + return content; + else if (element.tagName === 'DIV') + return ''; + else if (element.tagName === 'PRE') + return content; + else if (element.parentNode.tagName === 'PRE' && !title) + { + const t = element.parentNode.previousSibling.textContent; + + if (t.indexOf('(') != -1) + title = t.replace(/^[^(]+\(/, '').replace(/\)? \[.+/, ''); + } + + const from = title ? ' =' + title : ''; - return '[code' + from + ']' + "\n" + content.replace('[', '[') + "\n" + '[/code]'; + return '[code' + from + ']' + content.replace('[', '[') + '[/code]'; }, html: function (element, attrs, content) { var from = attrs.defaultattr ? ' data-title="' + attrs.defaultattr + '"' : ''; - return '' + content.replace('[', '[').replaceAll(/\[tab\]/, '\t').replace(/^]*>/, '').replace(/]*>$/, '') + '' + return '
' + content.replace('[', '[').replaceAll(/\[tab\]/, '\t') + '
'; } } ); diff --git a/Themes/default/scripts/script.js b/Themes/default/scripts/script.js index bc5278d851..3417d62e46 100644 --- a/Themes/default/scripts/script.js +++ b/Themes/default/scripts/script.js @@ -1294,47 +1294,6 @@ function addLoadEvent(fNewOnload) aOnloadEvents[aOnloadEvents.length] = fNewOnload; } -// Get the text in a code tag. -function smfSelectText(oCurElement, bActOnElement) -{ - // The place we're looking for is one div up, and next door - if it's auto detect. - if (typeof(bActOnElement) == 'boolean' && bActOnElement) - var oCodeArea = document.getElementById(oCurElement); - else - var oCodeArea = oCurElement.parentNode.nextSibling; - - if (typeof(oCodeArea) != 'object' || oCodeArea == null) - return false; - - // Start off with my favourite, internet explorer. - if ('createTextRange' in document.body) - { - var oCurRange = document.body.createTextRange(); - oCurRange.moveToElementText(oCodeArea); - oCurRange.select(); - } - // Firefox at el. - else if (window.getSelection) - { - var oCurSelection = window.getSelection(); - // Safari is special! - if (oCurSelection.setBaseAndExtent) - { - oCurSelection.setBaseAndExtent(oCodeArea, 0, oCodeArea, oCodeArea.childNodes.length); - } - else - { - var curRange = document.createRange(); - curRange.selectNodeContents(oCodeArea); - - oCurSelection.removeAllRanges(); - oCurSelection.addRange(curRange); - } - } - - return false; -} - // A function used to clean the attachments on post page function cleanFileInput(idElement) { @@ -1598,40 +1557,6 @@ $(function() { return result; }); - // Generic event for smfSelectText() - $('.smf_select_text').on('click', function(e) { - e.preventDefault(); - - // Do you want to target yourself? - var actOnElement = $(this).attr('data-actonelement'); - - return typeof actOnElement !== "undefined" ? smfSelectText(actOnElement, true) : smfSelectText(this); - }); - - // Show the Expand bbc button if needed - $('.bbc_code').each(function(index, item) { - if($(item).css('max-height') == 'none') - return; - - if($(item).prop('scrollHeight') > parseInt($(item).css('max-height'), 10)) - $(item.previousSibling).find('.smf_expand_code').removeClass('hidden'); - }); - // Expand or Shrink the code bbc area - $('.smf_expand_code').on('click', function(e) { - e.preventDefault(); - - var oCodeArea = this.parentNode.nextSibling; - - if(oCodeArea.classList.contains('expand_code')) { - $(oCodeArea).removeClass('expand_code'); - $(this).html($(this).attr('data-expand-txt')); - } - else { - $(oCodeArea).addClass('expand_code'); - $(this).html($(this).attr('data-shrink-txt')); - } - }); - // Expand quotes if ((typeof(smf_quote_expand) != 'undefined') && (smf_quote_expand > 0)) { @@ -1683,6 +1608,8 @@ $(function() { }); }); } + + attachBbCodeEvents(document); }); function expand_quote_parent(oElement) @@ -1695,6 +1622,43 @@ function expand_quote_parent(oElement) }); } +function attachBbCodeEvents(parent) +{ + parent.querySelectorAll('.bbc_code').forEach(item => + { + const selectButton = document.createElement('button'); + selectButton.textContent = item.dataset.selectTxt; + selectButton.className = 'reset link'; + selectButton.addEventListener('click', function() + { + window.getSelection().selectAllChildren(item); + }); + item.previousSibling.append(' [', selectButton, ']'); + + // Show the Expand bbc button if needed + if (item.innerHeight < item.scrollHeight) + return; + + const expandButton = document.createElement('button'); + expandButton.textContent = item.dataset.expandTxt; + expandButton.className = 'reset link'; + expandButton.addEventListener('click', function() + { + if (item.classList.contains('expand_code')) + { + item.classList.remove('expand_code'); + this.textContent = item.dataset.expandTxt; + } + else + { + item.classList.add('expand_code'); + this.textContent = item.dataset.shrinkTxt; + } + }); + item.previousSibling.append(' [', expandButton, ']'); + }); +} + function avatar_fallback(e) { var e = window.e || e; var default_url = smf_avatars_url + '/default.png'; @@ -1819,14 +1783,7 @@ smc_preview_post.prototype.onDocSent = function (XMLDoc) bodyText += preview.getElementsByTagName('body')[0].childNodes[i].nodeValue; setInnerHTML(document.getElementById(this.opts.sPreviewBodyContainerID), bodyText); - $('#' + this.opts.sPreviewBodyContainerID + ' .smf_select_text').on('click', function(e) { - e.preventDefault(); - - // Do you want to target yourself? - var actOnElement = $(this).attr('data-actonelement'); - - return typeof actOnElement !== "undefined" ? smfSelectText(actOnElement, true) : smfSelectText(this); - }); + attachBbCodeEvents(document.getElementById(this.opts.sPreviewBodyContainerID)); document.getElementById(this.opts.sPreviewBodyContainerID).className = 'windowbg'; // Show a list of errors (if any).