Skip to content

Commit

Permalink
Merge pull request #260 from craftcms/bugfix/258-normalize-pre-tags
Browse files Browse the repository at this point in the history
normalize pre tags after redactor conversion
  • Loading branch information
brandonkelly authored Aug 15, 2024
2 parents 353c12a + 7e06345 commit 4dda672
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Added `craft\ckeditor\events\ModifyConfigEvent::$toolbar`. ([#233](https://github.com/craftcms/ckeditor/pull/233))
- Fixed a bug where code blocks created by a Redactor field only had `<pre>` tags with no `<code>` tags inside them. ([#258](https://github.com/craftcms/ckeditor/issues/258))

## 3.8.3 - 2024-03-28

Expand Down
39 changes: 39 additions & 0 deletions src/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,9 @@ protected function prepValueForInput($value, ?ElementInterface $element): string
// Redactor to CKEditor syntax for <figure>
// (https://github.com/craftcms/ckeditor/issues/96)
$value = $this->_normalizeFigures($value);
// Redactor to CKEditor syntax for <pre>
// (https://github.com/craftcms/ckeditor/issues/258)
$value = $this->_normalizePreTags($value);
}

return parent::prepValueForInput($value, $element);
Expand All @@ -554,6 +557,9 @@ public function serializeValue(mixed $value, ?ElementInterface $element = null):
// Redactor to CKEditor syntax for <figure>
// (https://github.com/craftcms/ckeditor/issues/96)
$value = $this->_normalizeFigures($value);
// Redactor to CKEditor syntax for <pre>
// (https://github.com/craftcms/ckeditor/issues/258)
$value = $this->_normalizePreTags($value);
}

return parent::serializeValue($value, $element);
Expand Down Expand Up @@ -618,6 +624,39 @@ function(array $match) use ($previewsInData) {
return $value;
}

/**
* Normalizes <pre> tags, ensuring they have a <code> tag inside them.
* If there's no <code> tag in there, ensure it's added with class="language-plaintext".
*
* @param string $value
* @return string
*/
private function _normalizePreTags(string $value): string
{
$offset = 0;
while (preg_match('/<pre\b[^>]*>\s*(.*?)<\/pre>/is', $value, $match, PREG_OFFSET_CAPTURE, $offset)) {
/** @var int $startPos */
$startPos = $match[1][1];
$endPos = $startPos + strlen($match[1][0]);
$preContent = $match[1][0];

// if there's already a <code tag inside, leave it alone and carry on
if (str_starts_with($preContent, '<code')) {
$offset = $startPos + strlen($preContent);
continue;
}

$preContent = Html::tag('code', $preContent, [
'class' => 'language-plaintext',
]);

$value = substr($value, 0, $startPos) . $preContent . substr($value, $endPos);
$offset = $startPos + strlen($preContent);
}

return $value;
}

/**
* Returns the field’s CKEditor config.
*
Expand Down

0 comments on commit 4dda672

Please sign in to comment.