Issue #2559969 by alexpott: Make SafeStringInterface extend \JsonSerializable so we don't have to do so much string casting
parent
18bb5abf35
commit
2ea19c7158
|
@ -33,7 +33,7 @@ namespace Drupal\Component\Utility;
|
||||||
* @see \Drupal\Component\Utility\SafeMarkup::isSafe()
|
* @see \Drupal\Component\Utility\SafeMarkup::isSafe()
|
||||||
* @see \Drupal\Core\Template\TwigExtension::escapeFilter()
|
* @see \Drupal\Core\Template\TwigExtension::escapeFilter()
|
||||||
*/
|
*/
|
||||||
interface SafeStringInterface {
|
interface SafeStringInterface extends \JsonSerializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a safe string.
|
* Returns a safe string.
|
||||||
|
|
|
@ -67,4 +67,14 @@ trait SafeStringTrait {
|
||||||
return Unicode::strlen($this->string);
|
return Unicode::strlen($this->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a representation of the object for use in JSON serialization.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The safe string content.
|
||||||
|
*/
|
||||||
|
public function jsonSerialize() {
|
||||||
|
return $this->__toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,15 +164,15 @@ class AjaxResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn
|
||||||
$resource_commands = array();
|
$resource_commands = array();
|
||||||
if ($css_assets) {
|
if ($css_assets) {
|
||||||
$css_render_array = $this->cssCollectionRenderer->render($css_assets);
|
$css_render_array = $this->cssCollectionRenderer->render($css_assets);
|
||||||
$resource_commands[] = new AddCssCommand((string) $this->renderer->renderPlain($css_render_array));
|
$resource_commands[] = new AddCssCommand($this->renderer->renderPlain($css_render_array));
|
||||||
}
|
}
|
||||||
if ($js_assets_header) {
|
if ($js_assets_header) {
|
||||||
$js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header);
|
$js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header);
|
||||||
$resource_commands[] = new PrependCommand('head', (string) $this->renderer->renderPlain($js_header_render_array));
|
$resource_commands[] = new PrependCommand('head', $this->renderer->renderPlain($js_header_render_array));
|
||||||
}
|
}
|
||||||
if ($js_assets_footer) {
|
if ($js_assets_footer) {
|
||||||
$js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer);
|
$js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer);
|
||||||
$resource_commands[] = new AppendCommand('body', (string) $this->renderer->renderPlain($js_footer_render_array));
|
$resource_commands[] = new AppendCommand('body', $this->renderer->renderPlain($js_footer_render_array));
|
||||||
}
|
}
|
||||||
foreach (array_reverse($resource_commands) as $resource_command) {
|
foreach (array_reverse($resource_commands) as $resource_command) {
|
||||||
$response->addCommand($resource_command, TRUE);
|
$response->addCommand($resource_command, TRUE);
|
||||||
|
|
|
@ -29,7 +29,7 @@ trait CommandWithAttachedAssetsTrait {
|
||||||
* If content is a render array, it may contain attached assets to be
|
* If content is a render array, it may contain attached assets to be
|
||||||
* processed.
|
* processed.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||||
* HTML rendered content.
|
* HTML rendered content.
|
||||||
*/
|
*/
|
||||||
protected function getRenderedContent() {
|
protected function getRenderedContent() {
|
||||||
|
@ -37,10 +37,10 @@ trait CommandWithAttachedAssetsTrait {
|
||||||
if (is_array($this->content)) {
|
if (is_array($this->content)) {
|
||||||
$html = \Drupal::service('renderer')->renderRoot($this->content);
|
$html = \Drupal::service('renderer')->renderRoot($this->content);
|
||||||
$this->attachedAssets = AttachedAssets::createFromRenderArray($this->content);
|
$this->attachedAssets = AttachedAssets::createFromRenderArray($this->content);
|
||||||
return (string) $html;
|
return $html;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (string) $this->content;
|
return $this->content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ class AjaxRenderer implements MainContentRendererInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$html = (string) $this->drupalRenderRoot($main_content);
|
$html = $this->drupalRenderRoot($main_content);
|
||||||
$response->setAttachments($main_content['#attached']);
|
$response->setAttachments($main_content['#attached']);
|
||||||
|
|
||||||
// The selector for the insert command is NULL as the new content will
|
// The selector for the insert command is NULL as the new content will
|
||||||
|
@ -72,7 +72,7 @@ class AjaxRenderer implements MainContentRendererInterface {
|
||||||
// behavior can be changed with #ajax['method'].
|
// behavior can be changed with #ajax['method'].
|
||||||
$response->addCommand(new InsertCommand(NULL, $html));
|
$response->addCommand(new InsertCommand(NULL, $html));
|
||||||
$status_messages = array('#type' => 'status_messages');
|
$status_messages = array('#type' => 'status_messages');
|
||||||
$output = (string) $this->drupalRenderRoot($status_messages);
|
$output = $this->drupalRenderRoot($status_messages);
|
||||||
if (!empty($output)) {
|
if (!empty($output)) {
|
||||||
$response->addCommand(new PrependCommand(NULL, $output));
|
$response->addCommand(new PrependCommand(NULL, $output));
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,4 +118,14 @@ class TranslationWrapper implements SafeStringInterface {
|
||||||
return array('string', 'arguments', 'options');
|
return array('string', 'arguments', 'options');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a representation of the object for use in JSON serialization.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The safe string content.
|
||||||
|
*/
|
||||||
|
public function jsonSerialize() {
|
||||||
|
return $this->__toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,4 +302,14 @@ class Attribute implements \ArrayAccess, \IteratorAggregate, SafeStringInterface
|
||||||
return $this->storage;
|
return $this->storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a representation of the object for use in JSON serialization.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The safe string content.
|
||||||
|
*/
|
||||||
|
public function jsonSerialize() {
|
||||||
|
return (string) $this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ContextualController implements ContainerAwareInterface {
|
||||||
'#type' => 'contextual_links',
|
'#type' => 'contextual_links',
|
||||||
'#contextual_links' => _contextual_id_to_links($id),
|
'#contextual_links' => _contextual_id_to_links($id),
|
||||||
);
|
);
|
||||||
$rendered[$id] = (string) $this->container->get('renderer')->renderRoot($element);
|
$rendered[$id] = $this->container->get('renderer')->renderRoot($element);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsonResponse($rendered);
|
return new JsonResponse($rendered);
|
||||||
|
|
|
@ -48,7 +48,7 @@ class EditorController extends ControllerBase {
|
||||||
// Direct text editing is only supported for single-valued fields.
|
// Direct text editing is only supported for single-valued fields.
|
||||||
$field = $entity->getTranslation($langcode)->$field_name;
|
$field = $entity->getTranslation($langcode)->$field_name;
|
||||||
$editable_text = check_markup($field->value, $field->format, $langcode, array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE));
|
$editable_text = check_markup($field->value, $field->format, $langcode, array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE));
|
||||||
$response->addCommand(new GetUntransformedTextCommand((string) $editable_text));
|
$response->addCommand(new GetUntransformedTextCommand($editable_text));
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ class QuickEditController extends ControllerBase {
|
||||||
$response->addCommand(new FieldFormSavedCommand($output, $other_view_modes));
|
$response->addCommand(new FieldFormSavedCommand($output, $other_view_modes));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$output = (string) $this->renderer->renderRoot($form);
|
$output = $this->renderer->renderRoot($form);
|
||||||
// When working with a hidden form, we don't want its CSS/JS to be loaded.
|
// When working with a hidden form, we don't want its CSS/JS to be loaded.
|
||||||
if ($request->request->get('nocssjs') !== 'true') {
|
if ($request->request->get('nocssjs') !== 'true') {
|
||||||
$response->setAttachments($form['#attached']);
|
$response->setAttachments($form['#attached']);
|
||||||
|
@ -228,7 +228,7 @@ class QuickEditController extends ControllerBase {
|
||||||
$status_messages = array(
|
$status_messages = array(
|
||||||
'#type' => 'status_messages'
|
'#type' => 'status_messages'
|
||||||
);
|
);
|
||||||
$response->addCommand(new FieldFormValidationErrorsCommand((string) $this->renderer->renderRoot($status_messages)));
|
$response->addCommand(new FieldFormValidationErrorsCommand($this->renderer->renderRoot($status_messages)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ class QuickEditController extends ControllerBase {
|
||||||
* The view mode the field should be rerendered in. Either an Entity Display
|
* The view mode the field should be rerendered in. Either an Entity Display
|
||||||
* view mode ID, or a custom one. See hook_quickedit_render_field().
|
* view mode ID, or a custom one. See hook_quickedit_render_field().
|
||||||
*
|
*
|
||||||
* @return string
|
* @return \Drupal\Component\Utility\SafeStringInterface
|
||||||
* Rendered HTML.
|
* Rendered HTML.
|
||||||
*
|
*
|
||||||
* @see hook_quickedit_render_field()
|
* @see hook_quickedit_render_field()
|
||||||
|
@ -275,7 +275,7 @@ class QuickEditController extends ControllerBase {
|
||||||
$output = $this->moduleHandler()->invoke($module, 'quickedit_render_field', $args);
|
$output = $this->moduleHandler()->invoke($module, 'quickedit_render_field', $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (string) $this->renderer->renderRoot($output);
|
return $this->renderer->renderRoot($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\Tests\Component\Utility;
|
||||||
|
|
||||||
use Drupal\Component\Utility\SafeMarkup;
|
use Drupal\Component\Utility\SafeMarkup;
|
||||||
use Drupal\Component\Utility\SafeStringInterface;
|
use Drupal\Component\Utility\SafeStringInterface;
|
||||||
|
use Drupal\Component\Utility\SafeStringTrait;
|
||||||
use Drupal\Tests\UnitTestCase;
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,19 +235,5 @@ class SafeMarkupTestString {
|
||||||
* SafeMarkup::set() is a global static that affects all tests.
|
* SafeMarkup::set() is a global static that affects all tests.
|
||||||
*/
|
*/
|
||||||
class SafeMarkupTestSafeString implements SafeStringInterface {
|
class SafeMarkupTestSafeString implements SafeStringInterface {
|
||||||
|
use SafeStringTrait;
|
||||||
protected $string;
|
|
||||||
|
|
||||||
public function __construct($string) {
|
|
||||||
$this->string = $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __toString() {
|
|
||||||
return $this->string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function create($string) {
|
|
||||||
$safe_string = new static($string);
|
|
||||||
return $safe_string;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue