diff --git a/core/includes/schema.inc b/core/includes/schema.inc
index b74c2701289ca9ff8eee286bf8e42dbef92477d5..bba4eab46f07adb31bc219a5b80a075cfa09d47d 100644
--- a/core/includes/schema.inc
+++ b/core/includes/schema.inc
@@ -130,12 +130,6 @@ function drupal_install_schema($module) {
  *
  * @param string $module
  *   The module for which the tables will be removed.
- *
- * @return array
- *   An array of arrays with the following key/value pairs:
- *    - success: a boolean indicating whether the query succeeded.
- *    - query: the SQL query(s) executed, passed through
- *      \Drupal\Component\Utility\SafeMarkup::checkPlain().
  */
 function drupal_uninstall_schema($module) {
   $schema = drupal_get_module_schema($module);
diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index b442c57352fef898c57b7c6878abc840c2ae2303..2f26b26b5ea472cba8711913eb5c15a208957cd5 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -304,7 +304,7 @@ public static function setAllowedProtocols(array $protocols = array()) {
    * \Drupal\Component\Utility\Xss::filter(), but those functions return an
    * HTML-encoded string, so this function can be called independently when the
    * output needs to be a plain-text string for passing to functions that will
-   * call \Drupal\Component\Utility\SafeMarkup::checkPlain() separately.
+   * call \Drupal\Component\Utility\Html::escape() separately.
    *
    * @param string $uri
    *   A plain-text URI that might contain dangerous protocols.
diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php
index d61d82119a6554cfb26579bc0c90923e16bd14e7..423bde43d31bfb8cacac5f28c73f460950035eaa 100644
--- a/core/lib/Drupal/Component/Utility/Xss.php
+++ b/core/lib/Drupal/Component/Utility/Xss.php
@@ -106,7 +106,7 @@ public static function filter($string, array $html_tags = NULL) {
    *
    * Use only for fields where it is impractical to use the
    * whole filter system, but where some (mainly inline) mark-up
-   * is desired (so \Drupal\Component\Utility\SafeMarkup::checkPlain() is
+   * is desired (so \Drupal\Component\Utility\Html::escape() is
    * not acceptable).
    *
    * Allows all tags that can be used inside an HTML body, save
diff --git a/core/lib/Drupal/Core/Controller/TitleResolverInterface.php b/core/lib/Drupal/Core/Controller/TitleResolverInterface.php
index bedfd1781de0226b13bd9d5fcf95da3c72eaf76a..fa72e1141a026d3c76351c2d837cb7b47b62c67e 100644
--- a/core/lib/Drupal/Core/Controller/TitleResolverInterface.php
+++ b/core/lib/Drupal/Core/Controller/TitleResolverInterface.php
@@ -17,18 +17,20 @@ interface TitleResolverInterface {
   /**
    * Returns a static or dynamic title for the route.
    *
-   * The returned title string must be safe to output in HTML. For example, an
-   * implementation should call \Drupal\Component\Utility\SafeMarkup::checkPlain()
-   * or \Drupal\Component\Utility\Xss::filterAdmin() on the string, or use
-   * appropriate placeholders to sanitize dynamic content inside a localized
-   * string before returning it. The title may contain HTML such as EM tags.
+   * If the returned title can contain HTML that should not be escaped it should
+   * return a render array, for example:
+   * @code
+   * ['#markup' => 'title', '#allowed_tags' => ['em']]
+   * @endcode
+   * If the method returns a string and it is not marked safe then it will be
+   * auto-escaped.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The request object passed to the title callback.
    * @param \Symfony\Component\Routing\Route $route
    *   The route information of the route to fetch the title.
    *
-   * @return string|null
+   * @return array|string|null
    *   The title for the route.
    */
   public function getTitle(Request $request, Route $route);
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
index 6a2bd6c9dd3507fe98a815f77e6770ec4bca7d25..9e3f3c7e86fb63cc6641c1f7559a7a234bbf9fe9 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\EventSubscriber;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Logger\LoggerChannelFactoryInterface;
 use Drupal\Core\Utility\Error;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -45,7 +44,7 @@ public function __construct(LoggerChannelFactoryInterface $logger) {
    */
   public function on403(GetResponseForExceptionEvent $event) {
     $request = $event->getRequest();
-    $this->logger->get('access denied')->warning(SafeMarkup::checkPlain($request->getRequestUri()));
+    $this->logger->get('access denied')->warning('@uri', ['@uri' => $request->getRequestUri()]);
   }
 
   /**
@@ -56,7 +55,7 @@ public function on403(GetResponseForExceptionEvent $event) {
    */
   public function on404(GetResponseForExceptionEvent $event) {
     $request = $event->getRequest();
-    $this->logger->get('page not found')->warning(SafeMarkup::checkPlain($request->getRequestUri()));
+    $this->logger->get('page not found')->warning('@uri', ['@uri' => $request->getRequestUri()]);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index 6dfb99abf9298655bad12f4d3a4ea35387fb00b2..a7230875f9d15665f1a237816753591e7863def1 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Extension;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\State\StateInterface;
 
@@ -428,7 +427,7 @@ public function getName($theme) {
     if (!isset($themes[$theme])) {
       throw new \InvalidArgumentException("Requested the name of a non-existing theme $theme");
     }
-    return SafeMarkup::checkPlain($themes[$theme]->info['name']);
+    return $themes[$theme]->info['name'];
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Field/AllowedTagsXssTrait.php b/core/lib/Drupal/Core/Field/AllowedTagsXssTrait.php
index 95b18648ab06869df4d2a98db9b5e5d2c1cd4e67..c58096a1779f135874364202e9b8086639a25473 100644
--- a/core/lib/Drupal/Core/Field/AllowedTagsXssTrait.php
+++ b/core/lib/Drupal/Core/Field/AllowedTagsXssTrait.php
@@ -24,7 +24,7 @@ trait AllowedTagsXssTrait {
    *
    * Used for items entered by administrators, like field descriptions, allowed
    * values, where some (mainly inline) mark-up may be desired (so
-   * \Drupal\Component\Utility\SafeMarkup::checkPlain() is not acceptable).
+   * \Drupal\Component\Utility\Html::escape() is not acceptable).
    *
    * @param string $string
    *   The string with raw HTML in it.
diff --git a/core/lib/Drupal/Core/Form/form.api.php b/core/lib/Drupal/Core/Form/form.api.php
index 917323111dc6a9ccbb01a750af869f12a077ea41..12ce8d15d363265ae5aaee42fabac0cf6fc33b2a 100644
--- a/core/lib/Drupal/Core/Form/form.api.php
+++ b/core/lib/Drupal/Core/Form/form.api.php
@@ -5,8 +5,6 @@
  * Callbacks and hooks related to form system.
  */
 
-use Drupal\Component\Utility\SafeMarkup;
-
 /**
  * @addtogroup callbacks
  * @{
@@ -79,7 +77,7 @@ function callback_batch_operation($MULTIPLE_PARAMS, &$context) {
     node_save($node);
 
     // Store some result for post-processing in the finished callback.
-    $context['results'][] = SafeMarkup::checkPlain($node->title);
+    $context['results'][] = $node->title;
 
     // Update our progress information.
     $context['sandbox']['progress']++;
diff --git a/core/lib/Drupal/Core/Menu/menu.api.php b/core/lib/Drupal/Core/Menu/menu.api.php
index 3569b24ffc4eb3cf4f67bb03cc34b06645e08af5..0ae528f90e03f2c534e09e9cd8cd0ff06ca1490f 100644
--- a/core/lib/Drupal/Core/Menu/menu.api.php
+++ b/core/lib/Drupal/Core/Menu/menu.api.php
@@ -461,9 +461,6 @@ function hook_system_breadcrumb_alter(\Drupal\Core\Breadcrumb\Breadcrumb &$bread
  *       must be a string; other elements are more flexible, as they just need
  *       to work as an argument for the constructor of the class
  *       Drupal\Core\Template\Attribute($options['attributes']).
- *     - html: Whether or not HTML should be allowed as the link text. If FALSE,
- *       the text will be run through
- *       \Drupal\Component\Utility\SafeMarkup::checkPlain() before being output.
  *
  * @see \Drupal\Core\Routing\UrlGenerator::generateFromPath()
  * @see \Drupal\Core\Routing\UrlGenerator::generateFromRoute()
diff --git a/core/lib/Drupal/Core/Session/AccountInterface.php b/core/lib/Drupal/Core/Session/AccountInterface.php
index fa437c0205c6508b0e75dbd708ecb5e704457076..96aeb2d4a3aa2824fe506d46bad80f29fbfd4caf 100644
--- a/core/lib/Drupal/Core/Session/AccountInterface.php
+++ b/core/lib/Drupal/Core/Session/AccountInterface.php
@@ -116,10 +116,7 @@ public function getPreferredAdminLangcode($fallback_to_default = TRUE);
    * @see hook_user_format_name_alter()
    *
    * @return
-   *   An unsanitized string with the username to display. The code receiving
-   *   this result must ensure that \Drupal\Component\Utility\SafeMarkup::checkPlain()
-   *   is called on it before it is
-   *   printed to the page.
+   *   An unsanitized string with the username to display.
    */
   public function getUsername();
 
diff --git a/core/lib/Drupal/Core/Utility/Token.php b/core/lib/Drupal/Core/Utility/Token.php
index 9966726e5079f7bfefe50c6b1db870366906c885..f1f80cc8697acd1c7dec41f7e620d48e42a750df 100644
--- a/core/lib/Drupal/Core/Utility/Token.php
+++ b/core/lib/Drupal/Core/Utility/Token.php
@@ -164,8 +164,8 @@ public function __construct(ModuleHandlerInterface $module_handler, CacheBackend
    *     display to a web browser. Defaults to TRUE. Developers who set this
    *     option to FALSE assume responsibility for running
    *     \Drupal\Component\Utility\Xss::filter(),
-   *     \Drupal\Component\Utility\SafeMarkup::checkPlain() or other appropriate
-   *     scrubbing functions before displaying data to users.
+   *     \Drupal\Component\Utility\Html::escape() or other appropriate scrubbing
+   *     functions before displaying data to users.
    * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata|null
    *   (optional) An object to which static::generate() and the hooks and
    *   functions that it invokes will add their required bubbleable metadata.
@@ -285,8 +285,8 @@ public function scan($text) {
    *   - sanitize: A boolean flag indicating that tokens should be sanitized for
    *     display to a web browser. Developers who set this option to FALSE assume
    *     responsibility for running \Drupal\Component\Utility\Xss::filter(),
-   *     \Drupal\Component\Utility\SafeMarkup::checkPlain() or other appropriate
-   *     scrubbing functions before displaying data to users.
+   *     \Drupal\Component\Utility\Html::escape() or other appropriate scrubbing
+   *     functions before displaying data to users.
    * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
    *    The bubbleable metadata. This is passed to the token replacement
    *    implementations so that they can attach their metadata.
diff --git a/core/modules/block/src/Controller/BlockController.php b/core/modules/block/src/Controller/BlockController.php
index 66ecbbd0767d9c95a0c94f9915d8819225ed3e9f..32a6626683032ce1077ef23b06756422af8e2708 100644
--- a/core/modules/block/src/Controller/BlockController.php
+++ b/core/modules/block/src/Controller/BlockController.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\block\Controller;
 
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Extension\ThemeHandler;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -55,7 +56,7 @@ public static function create(ContainerInterface $container) {
    */
   public function demo($theme) {
     $page = [
-      '#title' => $this->themeHandler->getName($theme),
+      '#title' => Html::escape($this->themeHandler->getName($theme)),
       '#type' => 'page',
       '#attached' => array(
         'drupalSettings' => [
diff --git a/core/modules/block/src/Controller/CategoryAutocompleteController.php b/core/modules/block/src/Controller/CategoryAutocompleteController.php
index 0f6a011e91b4d05579f83195b4231fa09a5f1294..6d6842cc89614fe29f6c1cbeccf2719b64511a94 100644
--- a/core/modules/block/src/Controller/CategoryAutocompleteController.php
+++ b/core/modules/block/src/Controller/CategoryAutocompleteController.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\block\Controller;
 
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Block\BlockManagerInterface;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
@@ -59,7 +59,7 @@ public function autocomplete(Request $request) {
     $matches = array();
     foreach ($this->blockManager->getCategories() as $category) {
       if (stripos($category, $typed_category) === 0) {
-        $matches[] = array('value' => $category, 'label' => SafeMarkup::checkPlain($category));
+        $matches[] = array('value' => $category, 'label' => Html::escape($category));
       }
     }
     return new JsonResponse($matches);
diff --git a/core/modules/block/src/Tests/BlockUiTest.php b/core/modules/block/src/Tests/BlockUiTest.php
index 37fce6e60ae882c4d4a85e9bb89aebf4e3b6daa4..721a7e2e518cacc8598eb7c86f466a9689b886a7 100644
--- a/core/modules/block/src/Tests/BlockUiTest.php
+++ b/core/modules/block/src/Tests/BlockUiTest.php
@@ -86,6 +86,10 @@ public function testBlockDemoUiPage() {
     $this->clickLink(t('Demonstrate block regions (@theme)', array('@theme' => 'Classy')));
     $elements = $this->xpath('//div[contains(@class, "region-highlighted")]/div[contains(@class, "block-region") and contains(text(), :title)]', array(':title' => 'Highlighted'));
     $this->assertTrue(!empty($elements), 'Block demo regions are shown.');
+
+    \Drupal::service('theme_handler')->install(array('test_theme'));
+    $this->drupalGet('admin/structure/block/demo/test_theme');
+    $this->assertEscaped('<strong>Test theme</strong>');
   }
 
   /**
diff --git a/core/modules/block/tests/src/Unit/CategoryAutocompleteTest.php b/core/modules/block/tests/src/Unit/CategoryAutocompleteTest.php
index 065a25b352e628d697eed4c8872f4077551094b1..812c68a595ca96884138acf7c194c0eac28764ee 100644
--- a/core/modules/block/tests/src/Unit/CategoryAutocompleteTest.php
+++ b/core/modules/block/tests/src/Unit/CategoryAutocompleteTest.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\Tests\block\Unit;
 
+use Drupal\Component\Utility\Html;
 use Drupal\block\Controller\CategoryAutocompleteController;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -48,7 +48,7 @@ protected function setUp() {
    */
   public function testAutocompleteSuggestions($string, $suggestions) {
     $suggestions = array_map(function ($suggestion) {
-      return array('value' => $suggestion, 'label' => SafeMarkup::checkPlain($suggestion));
+      return array('value' => $suggestion, 'label' => Html::escape($suggestion));
     }, $suggestions);
     $result = $this->autocompleteController->autocomplete(new Request(array('q' => $string)));
     $this->assertSame($suggestions, json_decode($result->getContent(), TRUE));
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index edd20a05d0b20c9af58c080cc6217fbb95ed7605..9240ce6ef36f66c40b2ac4a24b736e127ea1ff96 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -16,7 +16,6 @@
 use Drupal\comment\Entity\CommentType;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -579,7 +578,7 @@ function comment_preview(CommentInterface $comment, FormStateInterface $form_sta
 
     if (!empty($account) && $account->isAuthenticated()) {
       $comment->setOwner($account);
-      $comment->setAuthorName(SafeMarkup::checkPlain($account->getUsername()));
+      $comment->setAuthorName($account->getUsername());
     }
     elseif (empty($author_name)) {
       $comment->setAuthorName(\Drupal::config('user.settings')->get('anonymous'));
diff --git a/core/modules/comment/src/Plugin/views/argument/UserUid.php b/core/modules/comment/src/Plugin/views/argument/UserUid.php
index 5195a7a0a80343984430a0e65b6005257a5dbaef..c408f31ebea70e685b58a8e1c0c1944d089f990f 100644
--- a/core/modules/comment/src/Plugin/views/argument/UserUid.php
+++ b/core/modules/comment/src/Plugin/views/argument/UserUid.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\comment\Plugin\views\argument;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Database\Connection;
 use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -65,7 +64,7 @@ function title() {
       return $this->t('No user');
     }
 
-    return SafeMarkup::checkPlain($title);
+    return $title;
   }
 
   protected function defaultActions($which = NULL) {
diff --git a/core/modules/comment/src/Tests/CommentPreviewTest.php b/core/modules/comment/src/Tests/CommentPreviewTest.php
index a1d0804eac39f25a916551eee0be0644c9a3317c..ae92de083a28d82087b47942bd7bef828b011e29 100644
--- a/core/modules/comment/src/Tests/CommentPreviewTest.php
+++ b/core/modules/comment/src/Tests/CommentPreviewTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\comment\Tests;
 
 use Drupal\comment\CommentManagerInterface;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\comment\Entity\Comment;
 
@@ -39,17 +40,31 @@ function testCommentPreview() {
     $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
     $this->drupalLogout();
 
-    // Login as web user and add a user picture.
+    // Login as web user.
     $this->drupalLogin($this->webUser);
-    $image = current($this->drupalGetTestFiles('image'));
-    $edit['files[user_picture_0]'] = drupal_realpath($image->uri);
-    $this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $edit, t('Save'));
 
-    // As the web user, fill in the comment form and preview the comment.
+    // Test escaping of the username on the preview form.
+    \Drupal::service('module_installer')->install(['user_hooks_test']);
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
     $edit = array();
     $edit['subject[0][value]'] = $this->randomMachineName(8);
     $edit['comment_body[0][value]'] = $this->randomMachineName(16);
     $this->drupalPostForm('node/' . $this->node->id(), $edit, t('Preview'));
+    $this->assertEscaped('<em>' . $this->webUser->id() . '</em>');
+
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
+    $this->drupalPostForm('node/' . $this->node->id(), $edit, t('Preview'));
+    $this->assertTrue(SafeMarkup::isSafe($this->webUser->getUsername()), 'Username is marked safe');
+    $this->assertNoEscaped('<em>' . $this->webUser->id() . '</em>');
+    $this->assertRaw('<em>' . $this->webUser->id() . '</em>');
+
+    // Add a user picture.
+    $image = current($this->drupalGetTestFiles('image'));
+    $user_edit['files[user_picture_0]'] = drupal_realpath($image->uri);
+    $this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $user_edit, t('Save'));
+
+    // As the web user, fill in the comment form and preview the comment.
+    $this->drupalPostForm('node/' . $this->node->id(), $edit, t('Preview'));
 
     // Check that the preview is displaying the title and body.
     $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".');
diff --git a/core/modules/field_ui/src/Form/FieldConfigEditForm.php b/core/modules/field_ui/src/Form/FieldConfigEditForm.php
index 2bbd68e3366af8685887b086e2d0027d41bdc14d..ba972a9f99763ccbe0484433c5e283fc04e76110 100644
--- a/core/modules/field_ui/src/Form/FieldConfigEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldConfigEditForm.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\field_ui\Form;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Field\AllowedTagsXssTrait;
 use Drupal\Core\Field\FieldFilteredString;
@@ -203,7 +202,7 @@ public function save(array $form, FormStateInterface $form_state) {
    *   The label of the field.
    */
   public function getTitle(FieldConfigInterface $field_config) {
-    return SafeMarkup::checkPlain($field_config->label());
+    return $field_config->label();
   }
 
 }
diff --git a/core/modules/field_ui/src/Tests/ManageFieldsTest.php b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
index 1f3d1916ffdd77d0f658b85c06d801a322e5755e..f1db4d4afe35e020668b3f9081d438de7fa35b4b 100644
--- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
@@ -80,8 +80,8 @@ protected function setUp() {
     $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
     $this->contentType = $type->id();
 
-    // Create random field name.
-    $this->fieldLabel = $this->randomMachineName(8);
+    // Create random field name with markup to test escaping.
+    $this->fieldLabel = '<em>' . $this->randomMachineName(8) . '</em>';
     $this->fieldNameInput =  strtolower($this->randomMachineName(8));
     $this->fieldName = 'field_'. $this->fieldNameInput;
 
@@ -194,6 +194,7 @@ function updateField() {
     $field_id = 'node.' . $this->contentType . '.' . $this->fieldName;
     // Go to the field edit page.
     $this->drupalGet('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field_id . '/storage');
+    $this->assertEscaped($this->fieldLabel);
 
     // Populate the field settings with new settings.
     $string = 'updated dummy test string';
diff --git a/core/modules/filter/src/Tests/FilterUnitTest.php b/core/modules/filter/src/Tests/FilterUnitTest.php
index cc9da598d150f0939295f585aeceee39e183fd38..f441342dff421ee0ad5f301251580d29b153847e 100644
--- a/core/modules/filter/src/Tests/FilterUnitTest.php
+++ b/core/modules/filter/src/Tests/FilterUnitTest.php
@@ -479,8 +479,6 @@ function testNoFollowFilter() {
 
   /**
    * Tests the HTML escaping filter.
-   *
-   * \Drupal\Component\Utility\SafeMarkup::checkPlain() is not tested here.
    */
   function testHtmlEscapeFilter() {
     // Get FilterHtmlEscape object.
diff --git a/core/modules/node/src/Controller/NodePreviewController.php b/core/modules/node/src/Controller/NodePreviewController.php
index 96b65b5bc0a08e2fb794e12efac12d9c196345c0..b1009be10fa30844806659d08eb42348303019da 100644
--- a/core/modules/node/src/Controller/NodePreviewController.php
+++ b/core/modules/node/src/Controller/NodePreviewController.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\node\Controller;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\Controller\EntityViewController;
 
@@ -61,7 +60,7 @@ public function view(EntityInterface $node_preview, $view_mode_id = 'full', $lan
    *   The page title.
    */
   public function title(EntityInterface $node_preview) {
-    return SafeMarkup::checkPlain($this->entityManager->getTranslationFromContext($node_preview)->label());
+    return $this->entityManager->getTranslationFromContext($node_preview)->label();
   }
 
 }
diff --git a/core/modules/node/src/Plugin/views/argument/Type.php b/core/modules/node/src/Plugin/views/argument/Type.php
index 26ab17afcb1f06a148b053a82a465aab772e13fa..62ab17dbbfaf822b8ddd03f7fae3c1d46ab5e060 100644
--- a/core/modules/node/src/Plugin/views/argument/Type.php
+++ b/core/modules/node/src/Plugin/views/argument/Type.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\node\Plugin\views\argument;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\views\Plugin\views\argument\StringArgument;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -76,7 +75,7 @@ function title() {
   function node_type($type_name) {
     $type = $this->nodeTypeStorage->load($type_name);
     $output = $type ? $type->label() : $this->t('Unknown content type');
-    return SafeMarkup::checkPlain($output);
+    return $output;
   }
 
 }
diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php
index 098012f76e1e03400c8e7b63e24620377ea61755..e73d527285f3db6efd9a20c180a5b9e669f50acd 100644
--- a/core/modules/node/src/Plugin/views/row/Rss.php
+++ b/core/modules/node/src/Plugin/views/row/Rss.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\node\Plugin\views\row;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\views\Plugin\views\row\RssPluginBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -78,7 +77,7 @@ public function buildOptionsForm_summary_options() {
 
   public function summaryTitle() {
     $options = $this->buildOptionsForm_summary_options();
-    return SafeMarkup::checkPlain($options[$this->options['view_mode']]);
+    return $options[$this->options['view_mode']];
   }
 
   public function preRender($values) {
diff --git a/core/modules/node/src/Tests/PagePreviewTest.php b/core/modules/node/src/Tests/PagePreviewTest.php
index 1c2d2259c0c28ea13c5cb212fa1a7fc1342a0e3f..6408e4d5cd49edfe82f9d984b407e5cce518ee7e 100644
--- a/core/modules/node/src/Tests/PagePreviewTest.php
+++ b/core/modules/node/src/Tests/PagePreviewTest.php
@@ -139,7 +139,7 @@ function testPagePreview() {
 
     // Fill in node creation form and preview node.
     $edit = array();
-    $edit[$title_key] = $this->randomMachineName(8);
+    $edit[$title_key] = '<em>' . $this->randomMachineName(8) . '</em>';
     $edit[$body_key] = $this->randomMachineName(16);
     $edit[$term_key] = $this->term->getName();
 
@@ -153,7 +153,7 @@ function testPagePreview() {
 
     // Check that the preview is displaying the title, body and term.
     $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
-    $this->assertText($edit[$title_key], 'Title displayed.');
+    $this->assertEscaped($edit[$title_key], 'Title displayed and escaped.');
     $this->assertText($edit[$body_key], 'Body displayed.');
     $this->assertText($edit[$term_key], 'Term displayed.');
     $this->assertLink(t('Back to content editing'));
@@ -185,7 +185,7 @@ function testPagePreview() {
     // Return to page preview to check everything is as expected.
     $this->drupalPostForm(NULL, array(), t('Preview'));
     $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
-    $this->assertText($edit[$title_key], 'Title displayed.');
+    $this->assertEscaped($edit[$title_key], 'Title displayed and escaped.');
     $this->assertText($edit[$body_key], 'Body displayed.');
     $this->assertText($edit[$term_key], 'Term displayed.');
     $this->assertLink(t('Back to content editing'));
diff --git a/core/modules/node/src/Tests/Views/NodeIntegrationTest.php b/core/modules/node/src/Tests/Views/NodeIntegrationTest.php
index b4188b705355454c498f20f2ab83216f8ec47f9f..86daefa9508e07ad6215a9086004495c88bb7561 100644
--- a/core/modules/node/src/Tests/Views/NodeIntegrationTest.php
+++ b/core/modules/node/src/Tests/Views/NodeIntegrationTest.php
@@ -29,7 +29,7 @@ public function testNodeViewTypeArgument() {
     $types = array();
     $all_nids = array();
     for ($i = 0; $i < 2; $i++) {
-      $type = $this->drupalCreateContentType();
+      $type = $this->drupalCreateContentType(['name' => '<em>' . $this->randomMachineName() . '</em>']);
       $types[] = $type;
 
       for ($j = 0; $j < 5; $j++) {
@@ -49,6 +49,7 @@ public function testNodeViewTypeArgument() {
 
     foreach ($types as $type) {
       $this->drupalGet("test-node-view/{$type->id()}");
+      $this->assertEscaped($type->label());
       $this->assertNids(array_keys($nodes[$type->id()]));
     }
   }
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
index f9c2bdf1e674564c500e1e8ee941be6eb52e6e3c..c5cf7f65fbffee25c9f97980b1a6a2fe25b5d4ab 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
@@ -167,8 +167,8 @@ display:
             value: all
             title_enable: false
             title: All
-          title_enable: false
-          title: ''
+          title_enable: true
+          title: '{{ arguments.type }}'
           default_argument_type: fixed
           default_argument_options:
             argument: ''
diff --git a/core/modules/options/src/Plugin/views/argument/NumberListField.php b/core/modules/options/src/Plugin/views/argument/NumberListField.php
index 4e22f9c6400025e2fb91507b11dad82303e8dc71..a96f27ef71f975812de5b2401d548f8464425156 100644
--- a/core/modules/options/src/Plugin/views/argument/NumberListField.php
+++ b/core/modules/options/src/Plugin/views/argument/NumberListField.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\options\Plugin\views\argument;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Field\AllowedTagsXssTrait;
 use Drupal\Core\Field\FieldFilteredString;
 use Drupal\Core\Form\FormStateInterface;
@@ -85,7 +84,7 @@ public function summaryName($data) {
     }
     // Else, fallback to the key.
     else {
-      return SafeMarkup::checkPlain($value);
+      return $value;
     }
   }
 
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index c96c275793f3220f2b1e8d3ff46cc79900016957..8fdbec46d7b5d7ddf776358c5bd1121823a7032a 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -395,7 +395,7 @@ public function testUIFieldAlias() {
       $expected[] = $expected_row;
     }
 
-    $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $expected);
+    $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
 
     // Test a random aliases for fields, they should be replaced.
     $alias_map = array(
@@ -430,7 +430,7 @@ public function testUIFieldAlias() {
       $expected[] = $expected_row;
     }
 
-    $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $expected);
+    $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
   }
 
   /**
diff --git a/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php
index 87e8887366354e1bf555fe26d2f49fb6a3683230..eb1a80c66119e1470c091d8ac261b793b98e07d4 100644
--- a/core/modules/simpletest/src/AssertContentTrait.php
+++ b/core/modules/simpletest/src/AssertContentTrait.php
@@ -437,7 +437,7 @@ protected function assertNoLinkByHrefInMainRegion($href, $message = '', $group =
    */
   protected function assertRaw($raw, $message = '', $group = 'Other') {
     if (!$message) {
-      $message = SafeMarkup::format('Raw "@raw" found', array('@raw' => $raw));
+      $message = 'Raw "' . Html::escape($raw) . '" found';
     }
     return $this->assert(strpos($this->getRawContent(), (string) $raw) !== FALSE, $message, $group);
   }
@@ -465,7 +465,7 @@ protected function assertRaw($raw, $message = '', $group = 'Other') {
    */
   protected function assertNoRaw($raw, $message = '', $group = 'Other') {
     if (!$message) {
-      $message = SafeMarkup::format('Raw "@raw" not found', array('@raw' => $raw));
+      $message = 'Raw "' . Html::escape($raw) . '" not found';
     }
     return $this->assert(strpos($this->getRawContent(), (string) $raw) === FALSE, $message, $group);
   }
@@ -493,7 +493,7 @@ protected function assertNoRaw($raw, $message = '', $group = 'Other') {
    */
   protected function assertEscaped($raw, $message = '', $group = 'Other') {
     if (!$message) {
-      $message = SafeMarkup::format('Escaped "@raw" found', array('@raw' => $raw));
+      $message = 'Escaped "' . Html::escape($raw) . '" found';
     }
     return $this->assert(strpos($this->getRawContent(), Html::escape($raw)) !== FALSE, $message, $group);
   }
@@ -522,7 +522,7 @@ protected function assertEscaped($raw, $message = '', $group = 'Other') {
    */
   protected function assertNoEscaped($raw, $message = '', $group = 'Other') {
     if (!$message) {
-      $message = SafeMarkup::format('Escaped "@raw" not found', array('@raw' => $raw));
+      $message = 'Escaped "' . Html::escape($raw) . '" not found';
     }
     return $this->assert(strpos($this->getRawContent(), Html::escape($raw)) === FALSE, $message, $group);
   }
diff --git a/core/modules/system/src/Tests/System/ThemeTest.php b/core/modules/system/src/Tests/System/ThemeTest.php
index c04560e8174c32605532139b5cd11b2aa90fc705..cde72e06b26e4fba41f5ef327824ecee12bf8f27 100644
--- a/core/modules/system/src/Tests/System/ThemeTest.php
+++ b/core/modules/system/src/Tests/System/ThemeTest.php
@@ -348,9 +348,9 @@ function testUninstallingThemes() {
    */
   function testInstallAndSetAsDefault() {
     $this->drupalGet('admin/appearance');
-    // Bartik is uninstalled in the test profile and has the second "Install and
+    // Bartik is uninstalled in the test profile and has the third "Install and
     // set as default" link.
-    $this->clickLink(t('Install and set as default'), 1);
+    $this->clickLink(t('Install and set as default'), 2);
     // Test the confirmation message.
     $this->assertText('Bartik is now the default theme.');
     // Make sure Bartik is now set as the default theme in config.
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.info.yml b/core/modules/system/tests/themes/test_theme/test_theme.info.yml
index e9d6602531374aabf8fb0188dd46e3abeb1a6a87..8f613bf2ccf6706876a1752ea60f3a2d33eab205 100644
--- a/core/modules/system/tests/themes/test_theme/test_theme.info.yml
+++ b/core/modules/system/tests/themes/test_theme/test_theme.info.yml
@@ -8,7 +8,7 @@
 # here in order for a test to ensure that this correctly prevents the module
 # version from being loaded, and that errors aren't caused by the lack of this
 # file within the theme folder.
-name: 'Test theme'
+name: '<strong>Test theme</strong>'
 type: theme
 description: 'Theme for testing the theme system'
 version: VERSION
diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
index f5bd524d75a9991848383a6ee6f05bf36204d049..e2df37fadb8ffdbd550c1b36c9cb48aac01dfe8f 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
@@ -11,7 +11,6 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\taxonomy\Entity\Term;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -140,7 +139,7 @@ public function query($group_by = FALSE) {
   function title() {
     $term = $this->termStorage->load($this->argument);
     if (!empty($term)) {
-      return SafeMarkup::checkPlain($term->getName());
+      return $term->getName();
     }
     // TODO review text
     return $this->t('No name');
diff --git a/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php b/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php
index ca365974f85de3976e62e77615297f9fe6250454..ecf27f9d4269cddc218599c6994ed7138b2aafa3 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\views\Plugin\views\argument\NumericArgument;
-use Drupal\Component\Utility\SafeMarkup;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -56,7 +55,7 @@ function title() {
     if ($this->argument) {
       $term = $this->termStorage->load($this->argument);
       if (!empty($term)) {
-        return SafeMarkup::checkPlain($term->getName());
+        return $term->getName();
       }
     }
     // TODO review text
diff --git a/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php b/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php
index 7aedd518e0828b26ea399fd548354716cb04127f..80c27b8308c74797961126f5186d658475c92e41 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php
@@ -8,7 +8,6 @@
 namespace Drupal\taxonomy\Plugin\views\argument;
 
 use Drupal\views\Plugin\views\argument\NumericArgument;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\taxonomy\VocabularyStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -63,7 +62,7 @@ public static function create(ContainerInterface $container, array $configuratio
   function title() {
     $vocabulary = $this->vocabularyStorage->load($this->argument);
     if ($vocabulary) {
-      return SafeMarkup::checkPlain($vocabulary->label());
+      return $vocabulary->label();
     }
 
     return $this->t('No vocabulary');
diff --git a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
index 3f40fc8f0b568eeb83676715f3756ed278681e79..3049f6f7f20d69666f57d28717c0ad7e7a061c44 100644
--- a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
@@ -11,7 +11,6 @@
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\field\PrerenderList;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\taxonomy\Entity\Vocabulary;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\taxonomy\VocabularyStorageInterface;
@@ -153,7 +152,7 @@ public function preRender(&$values) {
           $this->items[$node_nid][$tid]['name'] = \Drupal::entityManager()->getTranslationFromContext($term)->label();
           $this->items[$node_nid][$tid]['tid'] = $tid;
           $this->items[$node_nid][$tid]['vocabulary_vid'] = $term->getVocabularyId();
-          $this->items[$node_nid][$tid]['vocabulary'] = SafeMarkup::checkPlain($vocabularies[$term->getVocabularyId()]->label());
+          $this->items[$node_nid][$tid]['vocabulary'] = $vocabularies[$term->getVocabularyId()]->label();
 
           if (!empty($this->options['link_to_taxonomy'])) {
             $this->items[$node_nid][$tid]['make_link'] = TRUE;
diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
index 5c46a85129a52fbaf878304e8f3c7f0c7f2f97c6..01086b08b69efc8e4e0e346c30c5aa23dbc36ec2 100644
--- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
@@ -16,7 +16,6 @@
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\filter\ManyToOne;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Tags;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -359,7 +358,7 @@ public function adminSummary() {
       $this->value = array_filter($this->value);
       $terms = Term::loadMultiple($this->value);
       foreach ($terms as $term) {
-        $this->valueOptions[$term->id()] = SafeMarkup::checkPlain(\Drupal::entityManager()->getTranslationFromContext($term)->label());
+        $this->valueOptions[$term->id()] = \Drupal::entityManager()->getTranslationFromContext($term)->label();
       }
     }
     return parent::adminSummary();
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php
index aeae56719c83d2df66f6f38909e16397f692296c..fc9371ea55544c1ebb8af7f2d58c3200c5a0370c 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php
@@ -59,4 +59,14 @@ public function testTermPath() {
     $expected = $this->term1->id();
     $this->assertEqual($expected, $view->argument['tid']->getDefaultArgument());
   }
+
+  /**
+   * Tests escaping of page title when the taxonomy plugin provides it.
+   */
+  public function testTermTitleEscaping() {
+    $this->term1->setName('<em>Markup</em>')->save();
+    $this->drupalGet('taxonomy_default_argument_test/'. $this->term1->id());
+    $this->assertEscaped($this->term1->label());
+  }
+
 }
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
index 8329d040362bec906ac7f49eaa83b17790806f72..a913fa6544358c0645cbd2d2dce2ba24b1d8a164 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
@@ -28,6 +28,7 @@ class TaxonomyFieldAllTermsTest extends TaxonomyTestBase {
    * Tests the "all terms" field handler.
    */
   public function testViewsHandlerAllTermsField() {
+    $this->term1->setName('<em>Markup</em>')->save();
     $view = Views::getView('taxonomy_all_terms_test');
     $this->executeView($view);
     $this->drupalGet('taxonomy_all_terms_test');
@@ -36,6 +37,7 @@ public function testViewsHandlerAllTermsField() {
     $this->assertEqual(count($actual), 2, 'Correct number of taxonomy term1 links');
     $this->assertEqual($actual[0]->__toString(), $this->term1->label());
     $this->assertEqual($actual[1]->__toString(), $this->term1->label());
+    $this->assertEscaped($this->term1->label());
 
     $actual = $this->xpath('//a[@href="' . $this->term2->url() . '"]');
     $this->assertEqual(count($actual), 2, 'Correct number of taxonomy term2 links');
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e4f74a93ca61b31005de68af192810be3ca311aa
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Tests\Views\TaxonomyTermArgumentDepthTest.
+ */
+
+namespace Drupal\taxonomy\Tests\Views;
+
+/**
+ * Tests the taxonomy term with depth argument.
+ *
+ * @group taxonomy
+ */
+class TaxonomyTermArgumentDepthTest extends TaxonomyTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['taxonomy', 'taxonomy_test_views', 'views', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $testViews = ['test_argument_taxonomy_index_tid_depth'];
+
+  /**
+   * @var \Drupal\taxonomy\TermInterface[]
+   */
+  protected $terms = [];
+
+  /**
+   * @var \Drupal\views\ViewExecutable
+   */
+  protected $view;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Create a term with markup in the label.
+    $first = $this->createTerm(['name' => '<em>First</em>']);
+
+    // Create a node w/o any terms.
+    $settings = ['type' => 'article'];
+
+    // Create a node with linked to the term.
+    $settings['field_views_testing_tags'][0]['target_id'] = $first->id();
+    $this->nodes[] = $this->drupalCreateNode($settings);
+
+    $this->terms[0] = $first;
+  }
+
+  /**
+   * Tests title escaping.
+   */
+  public function testTermWithDepthArgumentTitleEscaping() {
+    $this->drupalGet('test_argument_taxonomy_index_tid_depth/' . $this->terms[0]->id());
+    $this->assertEscaped($this->terms[0]->label());
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
index 615972b7380ff8ac5e5ae4228b20b047409959dd..2f556af5a185b63adb96b112359d0e8636f5bc27 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
@@ -163,3 +163,10 @@ display:
           entity_type: taxonomy_term
           entity_field: tid
       rendering_language: '***LANGUAGE_entity_translation***'
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: null
+    display_options:
+      path: taxonomy_default_argument_test
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth.yml
new file mode 100644
index 0000000000000000000000000000000000000000..103f4f75e0b969e3209ae230c71d165b8ec61327
--- /dev/null
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth.yml
@@ -0,0 +1,227 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+    - taxonomy
+    - user
+id: test_argument_taxonomy_index_tid_depth
+label: test_argument_taxonomy_index_tid_depth
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+      filters:
+        status:
+          value: true
+          table: node_field_data
+          field: status
+          plugin_id: boolean
+          entity_type: node
+          entity_field: status
+          id: status
+          expose:
+            operator: ''
+          group: 1
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          order: DESC
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments:
+        term_node_tid_depth:
+          id: term_node_tid_depth
+          table: node_field_data
+          field: term_node_tid_depth
+          relationship: none
+          group_type: group
+          admin_label: ''
+          default_action: ignore
+          exception:
+            value: all
+            title_enable: false
+            title: All
+          title_enable: true
+          title: '{{ arguments.term_node_tid_depth }}'
+          default_argument_type: fixed
+          default_argument_options:
+            argument: ''
+          default_argument_skip_url: false
+          summary_options:
+            base_path: ''
+            count: true
+            items_per_page: 25
+            override: false
+          summary:
+            sort_order: asc
+            number_of_records: 0
+            format: default_summary
+          specify_validation: false
+          validate:
+            type: none
+            fail: 'not found'
+          validate_options: {  }
+          depth: 0
+          break_phrase: false
+          use_taxonomy_term_path: false
+          entity_type: node
+          plugin_id: taxonomy_index_tid_depth
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: test_argument_taxonomy_index_tid_depth
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
index 13d15c92547368ccf9b3b21e1d2d9f6e8eee0901..a3697e8cee54e23652f3242121fdaf4ff5eb0f49 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
@@ -43,7 +43,6 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
    * {@inheritdoc}
    */
   public function applyDefaultValue($notify = TRUE) {
-    // Default to a simple \Drupal\Component\Utility\SafeMarkup::checkPlain().
     // @todo: Add in the filter default format here.
     $this->setValue(array('format' => NULL), $notify);
     return $this;
diff --git a/core/modules/text/src/TextProcessed.php b/core/modules/text/src/TextProcessed.php
index 364937b52f5c3e72746cf9fda4e7722125638e8d..d41cb92b89a27b01a87b32c821b700f11a059732 100644
--- a/core/modules/text/src/TextProcessed.php
+++ b/core/modules/text/src/TextProcessed.php
@@ -49,8 +49,7 @@ public function getValue($langcode = NULL) {
     $item = $this->getParent();
     $text = $item->{($this->definition->getSetting('text source'))};
 
-    // Avoid running check_markup() or
-    // \Drupal\Component\Utility\SafeMarkup::checkPlain() on empty strings.
+    // Avoid running check_markup() on empty strings.
     if (!isset($text) || $text === '') {
       $this->processed = '';
     }
diff --git a/core/modules/tracker/src/Controller/TrackerUserTab.php b/core/modules/tracker/src/Controller/TrackerUserTab.php
index ae215487a50484ab0fc2e455ad0a86e3f24dfcc7..3aca4c07b833421fa92bd93ba189c12d89c14742 100644
--- a/core/modules/tracker/src/Controller/TrackerUserTab.php
+++ b/core/modules/tracker/src/Controller/TrackerUserTab.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\user\UserInterface;
-use Drupal\Component\Utility\SafeMarkup;
 
 /**
  * Controller for tracker.user_tab route.
@@ -28,6 +27,6 @@ public function getContent(UserInterface $user) {
    * Title callback for the tracker.user_tab route.
    */
   public function getTitle(UserInterface $user) {
-    return SafeMarkup::checkPlain($user->getUsername());
+    return $user->getUsername();
   }
 }
diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/src/Tests/TrackerTest.php
index 7450ba9732cc130e603dcdc230c33840fb7ee3a3..0b0a91ece93bb33f5a52b200d072631a66a5dc93 100644
--- a/core/modules/tracker/src/Tests/TrackerTest.php
+++ b/core/modules/tracker/src/Tests/TrackerTest.php
@@ -198,6 +198,17 @@ function testTrackerUser() {
     $this->drupalPostForm('comment/1/edit', array('status' => CommentInterface::NOT_PUBLISHED), t('Save'));
     $this->drupalGet('user/' . $this->user->id() . '/activity');
     $this->assertNoText($other_published_my_comment->label(), 'Unpublished comments are not counted on the tracker listing.');
+
+    // Test escaping of title on user's tracker tab.
+    \Drupal::service('module_installer')->install(['user_hooks_test']);
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
+    $this->drupalGet('user/' . $this->user->id() . '/activity');
+    $this->assertEscaped('<em>' . $this->user->id() . '</em>');
+
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
+    $this->drupalGet('user/' . $this->user->id() . '/activity');
+    $this->assertNoEscaped('<em>' . $this->user->id() . '</em>');
+    $this->assertRaw('<em>' . $this->user->id() . '</em>');
   }
 
   /**
diff --git a/core/modules/user/src/Plugin/Condition/UserRole.php b/core/modules/user/src/Plugin/Condition/UserRole.php
index 3316cbc7b90b06546292aa8d15976508a02fafce..f6ddb87d44f92101aab7856edef71f878b8d748b 100644
--- a/core/modules/user/src/Plugin/Condition/UserRole.php
+++ b/core/modules/user/src/Plugin/Condition/UserRole.php
@@ -33,7 +33,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#type' => 'checkboxes',
       '#title' => $this->t('When the user has the following roles'),
       '#default_value' => $this->configuration['roles'],
-      '#options' => array_map('\Drupal\Component\Utility\SafeMarkup::checkPlain', user_role_names()),
+      '#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
       '#description' => $this->t('If you select no roles, the condition will evaluate to TRUE for all users.'),
     );
     return parent::buildConfigurationForm($form, $form_state);
diff --git a/core/modules/user/src/Plugin/views/access/Role.php b/core/modules/user/src/Plugin/views/access/Role.php
index cd3a32233b2e12586c86401aec7aad3e4046f04f..42404cea50433ff77754bb6004e2353607532799 100644
--- a/core/modules/user/src/Plugin/views/access/Role.php
+++ b/core/modules/user/src/Plugin/views/access/Role.php
@@ -97,7 +97,7 @@ public function summaryTitle() {
     else {
       $rids = user_role_names();
       $rid = reset($this->options['role']);
-      return SafeMarkup::checkPlain($rids[$rid]);
+      return $rids[$rid];
     }
   }
 
diff --git a/core/modules/user/src/Plugin/views/field/Roles.php b/core/modules/user/src/Plugin/views/field/Roles.php
index 00a1918c19be6a7538081ecd9e9a75a82bc996ea..e00da614fc6dd4e652531fa630f16a12da4e5a8b 100644
--- a/core/modules/user/src/Plugin/views/field/Roles.php
+++ b/core/modules/user/src/Plugin/views/field/Roles.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\user\Plugin\views\field;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Database\Connection;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
@@ -81,7 +80,7 @@ public function preRender(&$values) {
       $roles = user_roles();
       $result = $this->database->query('SELECT u.entity_id as uid, u.roles_target_id as rid FROM {user__roles} u WHERE u.entity_id IN ( :uids[] ) AND u.roles_target_id IN ( :rids[] )', array(':uids[]' => $uids, ':rids[]' => array_keys($roles)));
       foreach ($result as $role) {
-        $this->items[$role->uid][$role->rid]['role'] = SafeMarkup::checkPlain($roles[$role->rid]->label());
+        $this->items[$role->uid][$role->rid]['role'] = $roles[$role->rid]->label();
         $this->items[$role->uid][$role->rid]['rid'] = $role->rid;
       }
       // Sort the roles for each user by role weight.
diff --git a/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php b/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php
index 0072d678f61ce19fd2cabe1d2557f6cabff14206..9434925d552f47f22e6f2ea0f1d62448859e4882 100644
--- a/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php
+++ b/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user\Tests\Views;
 
+use Drupal\Component\Utility\Html;
 use Drupal\views\Views;
 use Drupal\user\Entity\User;
 
@@ -28,7 +29,7 @@ class HandlerFieldRoleTest extends UserTestBase {
   public function testRole() {
     // Create a couple of roles for the view.
     $rolename_a = 'a' . $this->randomMachineName(8);
-    $this->drupalCreateRole(array('access content'), $rolename_a, $rolename_a, 9);
+    $this->drupalCreateRole(array('access content'), $rolename_a, '<em>' . $rolename_a . '</em>', 9);
 
     $rolename_b = 'b' . $this->randomMachineName(8);
     $this->drupalCreateRole(array('access content'), $rolename_b, $rolename_b, 8);
@@ -42,16 +43,10 @@ public function testRole() {
     $user->addRole($rolename_b);
     $user->save();
 
-    debug(db_query('SELECT * FROM {user__roles}')->fetchAll());
-
-    $view = Views::getView('test_views_handler_field_role');
-    $this->executeView($view);
-    // The role field is populated during preRender.
-    $view->field['roles_target_id']->preRender($view->result);
-    $render = $view->field['roles_target_id']->advancedRender($view->result[0]);
-
-    $this->assertEqual($rolename_b . $rolename_a, $render, 'View test_views_handler_field_role renders role assigned to user in the correct order.');
-    $this->assertFalse(strpos($render, $rolename_not_assigned), 'View test_views_handler_field_role does not render a role not assigned to a user.');
+    $this->drupalLogin($this->createUser(['access user profiles']));
+    $this->drupalGet('/test-views-handler-field-role');
+    $this->assertText($rolename_b . Html::escape('<em>' . $rolename_a . '</em>'), 'View test_views_handler_field_role renders role assigned to user in the correct order and markup in role names is escaped.');
+    $this->assertNoText($rolename_not_assigned, 'View test_views_handler_field_role does not render a role not assigned to a user.');
   }
 
 }
diff --git a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2e56f1736d677b75be054d104e28d73349f45bfc
--- /dev/null
+++ b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml
@@ -0,0 +1,6 @@
+name: 'User module hooks tests'
+type: module
+description: 'Support module for user hooks testing.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module
new file mode 100644
index 0000000000000000000000000000000000000000..a036c65c6b0f0c6d3973203ff9a9568b12dbcf76
--- /dev/null
+++ b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Support module for user hooks testing.
+ */
+
+use Drupal\Component\Utility\SafeMarkup;
+
+/**
+ * Implements hook_user_format_name_alter().
+ */
+function user_hooks_test_user_format_name_alter(&$name, $account) {
+  if (\Drupal::state()->get('user_hooks_test_user_format_name_alter', FALSE)) {
+    if (\Drupal::state()->get('user_hooks_test_user_format_name_alter_safe', FALSE)) {
+      $name = SafeMarkup::format('<em>@uid</em>', array('@uid' => $account->id()));
+    }
+    else {
+      $name = '<em>' . $account->id() . '</em>';
+    }
+  }
+}
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 4f8289b381ce651d3116d305babfaaa03123d10f..70e4a0c00b3ee9b0dcfe763641263617a9fc8676 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -413,9 +413,7 @@ function user_preprocess_block(&$variables) {
  *   The account object for the user whose name is to be formatted.
  *
  * @return string
- *   An unsanitized string with the username to display. The code receiving
- *   this result must ensure that \Drupal\Component\Utility\SafeMarkup::checkPlain()
- *   is called on it before it is printed to the page.
+ *   An unsanitized string with the username to display.
  *
  * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
  *   Use \Drupal\Core\Session\AccountInterface::getUsername().
@@ -453,9 +451,7 @@ function user_template_preprocess_default_variables_alter(&$variables) {
  *   - account: The user account (\Drupal\Core\Session\AccountInterface).
  *
  * Modules that make any changes to variables like 'name' or 'extra' must ensure
- * that the final string is safe to include directly in the output by using
- * \Drupal\Component\Utility\SafeMarkup::checkPlain() or
- * \Drupal\Component\Utility\Xss::filter().
+ * that the final string is safe.
  */
 function template_preprocess_username(&$variables) {
   $account = $variables['account'] ?: new AnonymousUserSession();
diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php
index 2bf57afb47ae8c0bb783d3f3550452adc69796ad..7b5fe3aa780cef07f8dd7de6b7e1bfc5a392acfa 100644
--- a/core/modules/views/src/Plugin/views/HandlerBase.php
+++ b/core/modules/views/src/Plugin/views/HandlerBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Plugin\views;
 
-use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
@@ -16,6 +16,7 @@
 use Drupal\Core\Render\Element;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
+use Drupal\views\Render\ViewsRenderPipelineSafeString;
 use Drupal\views\ViewExecutable;
 use Drupal\Core\Database\Database;
 use Drupal\views\Views;
@@ -229,13 +230,13 @@ public function sanitizeValue($value, $type = NULL) {
         $value = Xss::filterAdmin($value);
         break;
       case 'url':
-        $value = SafeMarkup::checkPlain(UrlHelper::stripDangerousProtocols($value));
+        $value = Html::escape(UrlHelper::stripDangerousProtocols($value));
         break;
       default:
-        $value = SafeMarkup::checkPlain($value);
+        $value = Html::escape($value);
         break;
     }
-    return $value;
+    return ViewsRenderPipelineSafeString::create($value);
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php
index 4dff979a376426a01cc8cfe5750b4a2c875f0e57..b8b7a30ed8286b354c66618ea843c3986792b0ba 100644
--- a/core/modules/views/src/Plugin/views/PluginBase.php
+++ b/core/modules/views/src/Plugin/views/PluginBase.php
@@ -8,7 +8,6 @@
 namespace Drupal\views\Plugin\views;
 
 use Drupal\Component\Plugin\DependentPluginInterface;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
@@ -314,9 +313,9 @@ public function summaryTitle() {
   public function pluginTitle() {
     // Short_title is optional so its defaults to an empty string.
     if (!empty($this->definition['short_title'])) {
-      return SafeMarkup::checkPlain($this->definition['short_title']);
+      return $this->definition['short_title'];
     }
-    return SafeMarkup::checkPlain($this->definition['title']);
+    return $this->definition['title'];
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/ViewsHandlerInterface.php b/core/modules/views/src/Plugin/views/ViewsHandlerInterface.php
index 1775d99885ed4c0093e6fec7d751ea26ec86b44c..8a230863b98cf524fddf78bddb7ed9ff392283da 100644
--- a/core/modules/views/src/Plugin/views/ViewsHandlerInterface.php
+++ b/core/modules/views/src/Plugin/views/ViewsHandlerInterface.php
@@ -72,9 +72,10 @@ public function getJoin();
    * @param $value
    *   The value being rendered.
    * @param $type
-   *   The type of sanitization needed. If not provided, SafeMarkup::checkPlain() is used.
+   *   The type of sanitization needed. If not provided,
+   *   \Drupal\Component\Utility\Html::escape() is used.
    *
-   * @return string
+   * @return \Drupal\views\Render\ViewsRenderPipelineSafeString
    *   Returns the safe value.
    */
   public function sanitizeValue($value, $type = NULL);
diff --git a/core/modules/views/src/Plugin/views/area/Result.php b/core/modules/views/src/Plugin/views/area/Result.php
index 02017e3a4c078827e108b863f653d9d51420287c..3079f0da9cd30abfdf8e31d2cf5367971d80fcaa 100644
--- a/core/modules/views/src/Plugin/views/area/Result.php
+++ b/core/modules/views/src/Plugin/views/area/Result.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Plugin\views\area;
 
-use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\style\DefaultSummary;
@@ -87,7 +87,7 @@ public function render($empty = FALSE) {
     // @TODO: Maybe use a possible is views empty functionality.
     // Not every view has total_rows set, use view->result instead.
     $total = isset($this->view->total_rows) ? $this->view->total_rows : count($this->view->result);
-    $label = SafeMarkup::checkPlain($this->view->storage->label());
+    $label = Html::escape($this->view->storage->label());
     if ($per_page === 0) {
       $page_count = 1;
       $start = 1;
diff --git a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
index b179245e5ab024b0555401ba0c6f358082acf039..0a9fec7be01b5a4c01489f81ba3100d942f0524e 100644
--- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
+++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
@@ -10,7 +10,6 @@
 use Drupal\Component\Plugin\DependentPluginInterface;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\views\Plugin\CacheablePluginInterface;
@@ -938,7 +937,7 @@ public function summaryName($data) {
     if (empty($value) && !empty($this->definition['empty field name'])) {
       $value = $this->definition['empty field name'];
     }
-    return SafeMarkup::checkPlain($value);
+    return $value;
   }
 
   /**
@@ -957,7 +956,7 @@ public function query($group_by = FALSE) {
    * This usually needs to be overridden to provide a proper title.
    */
   function title() {
-    return SafeMarkup::checkPlain($this->argument);
+    return $this->argument;
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/argument/FieldList.php b/core/modules/views/src/Plugin/views/argument/FieldList.php
index 36c50ac5f78e686190bbbc7880c1f9c1093d9bce..54b7883d95bd537dfd44e6b2d6855d85c982f517 100644
--- a/core/modules/views/src/Plugin/views/argument/FieldList.php
+++ b/core/modules/views/src/Plugin/views/argument/FieldList.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\views\Plugin\views\argument;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Field\AllowedTagsXssTrait;
 use Drupal\Core\Field\FieldFilteredString;
 use Drupal\Core\Form\FormStateInterface;
@@ -75,7 +74,7 @@ public function summaryName($data) {
     }
     // else fallback to the key.
     else {
-      return SafeMarkup::checkPlain($value);
+      return $value;
     }
   }
 
diff --git a/core/modules/views/src/Plugin/views/display/Attachment.php b/core/modules/views/src/Plugin/views/display/Attachment.php
index dcc4282e4006c2bbfa4b463d35d8daaa670ef51b..ef691bec54caa1c91dbb55ff2a49044497e5020a 100644
--- a/core/modules/views/src/Plugin/views/display/Attachment.php
+++ b/core/modules/views/src/Plugin/views/display/Attachment.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\views\Plugin\views\display;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\ViewExecutable;
 
@@ -92,7 +91,7 @@ public function optionsSummary(&$categories, &$options) {
     elseif (count($displays) == 1) {
       $display = array_shift($displays);
       if ($display = $this->view->storage->getDisplay($display)) {
-        $attach_to = SafeMarkup::checkPlain($display['display_title']);
+        $attach_to = $display['display_title'];
       }
     }
 
@@ -204,7 +203,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
           '#title' => $this->t('Displays'),
           '#type' => 'checkboxes',
           '#description' => $this->t('Select which display or displays this should attach to.'),
-          '#options' => $displays,
+          '#options' => array_map('\Drupal\Component\Utility\Html::escape', $displays),
           '#default_value' => $this->getOption('displays'),
         );
         break;
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index 216a67592231e0da86399f474761feb902b6ddc5..c78d23bcd6d74e87e7b916eae4aff895c0dbedfd 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\views\Plugin\views\display;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableResponse;
 use Drupal\Core\Form\FormStateInterface;
@@ -204,7 +203,7 @@ public function optionsSummary(&$categories, &$options) {
       $display = array_shift($displays);
       $displays = $this->view->storage->get('display');
       if (!empty($displays[$display])) {
-        $attach_to = SafeMarkup::checkPlain($displays[$display]['display_title']);
+        $attach_to = $displays[$display]['display_title'];
       }
     }
 
@@ -256,7 +255,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
           '#title' => $this->t('Displays'),
           '#type' => 'checkboxes',
           '#description' => $this->t('The feed icon will be available only to the selected displays.'),
-          '#options' => $displays,
+          '#options' => array_map('\Drupal\Component\Utility\Html::escape', $displays),
           '#default_value' => $this->getOption('displays'),
         );
         break;
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 7ed1033d66d3d53e3fc36d387e09cc8141051e13..29abf887c3008064ff47bbd1f5e04246df3a8328 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1396,8 +1396,8 @@ protected function renderAsLink($alter, $text, $tokens) {
       $path = preg_replace(['/(\%7B){2}(\%20)*/', '/(\%20)*(\%7D){2}/'], ['{{','}}'], $path);
 
       // Use strip tags as there should never be HTML in the path.
-      // However, we need to preserve special characters like " that
-      // were removed by SafeMarkup::checkPlain().
+      // However, we need to preserve special characters like " that are escaped
+      // by \Drupal\Component\Utility\Html::escape().
       $path = strip_tags(Html::decodeEntities($this->viewsTokenReplace($path, $tokens)));
 
       if (!empty($alter['path_case']) && $alter['path_case'] != 'none' && !$alter['url']->isRouted()) {
@@ -1483,8 +1483,7 @@ protected function renderAsLink($alter, $text, $tokens) {
       $options['attributes']['rel'] = $rel;
     }
 
-    // Not sure if this SafeMarkup::checkPlain() is needed here?
-    $target = SafeMarkup::checkPlain(trim($this->viewsTokenReplace($alter['target'], $tokens)));
+    $target = trim($this->viewsTokenReplace($alter['target'], $tokens));
     if (!empty($target)) {
       $options['attributes']['target'] = $target;
     }
diff --git a/core/modules/views/src/Plugin/views/field/MachineName.php b/core/modules/views/src/Plugin/views/field/MachineName.php
index 0c289cddce57bae925e2b8a51f41f2092362e225..a31d7f25544c4c5a00ca76eebb981c7ada14e20e 100644
--- a/core/modules/views/src/Plugin/views/field/MachineName.php
+++ b/core/modules/views/src/Plugin/views/field/MachineName.php
@@ -83,7 +83,7 @@ public function preRender(&$values) {
   public function render(ResultRow $values) {
     $value = $values->{$this->field_alias};
     if (!empty($this->options['machine_name']) || !isset($this->valueOptions[$value])) {
-      $result = SafeMarkup::checkPlain($value);
+      $result = $this->sanitizeValue($value);
     }
     else {
       $result = $this->valueOptions[$value];
diff --git a/core/modules/views/src/Plugin/views/field/PrerenderList.php b/core/modules/views/src/Plugin/views/field/PrerenderList.php
index ce0caee45d96cace53e4a70b2ad83db78c488c52..4a1caeade1bfaae1ebdf1c4f491bc32614c83466 100644
--- a/core/modules/views/src/Plugin/views/field/PrerenderList.php
+++ b/core/modules/views/src/Plugin/views/field/PrerenderList.php
@@ -78,17 +78,24 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function renderItems($items) {
     if (!empty($items)) {
       if ($this->options['type'] == 'separator') {
-        return implode($this->sanitizeValue($this->options['separator'], 'xss_admin'), $items);
+        $render = [
+          '#type' => 'inline_template',
+          '#template' => '{{ items|safe_join(separator) }}',
+          '#context' => [
+            'items' => $items,
+            'separator' => $this->sanitizeValue($this->options['separator'], 'xss_admin')
+          ]
+        ];
       }
       else {
-        $item_list = array(
+        $render = array(
           '#theme' => 'item_list',
           '#items' => $items,
           '#title' => NULL,
           '#list_type' => $this->options['type'],
         );
-        return drupal_render($item_list);
       }
+      return drupal_render($render);
     }
   }
 
diff --git a/core/modules/views/src/Plugin/views/field/Serialized.php b/core/modules/views/src/Plugin/views/field/Serialized.php
index f7f5a222842f9f2198d920a4f1db1838427f6beb..b2fd7443a3a83a366eb3df2f00129b36d43a1149 100644
--- a/core/modules/views/src/Plugin/views/field/Serialized.php
+++ b/core/modules/views/src/Plugin/views/field/Serialized.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\views\Plugin\views\field;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\ResultRow;
 
@@ -76,11 +75,11 @@ public function render(ResultRow $values) {
     $value = $values->{$this->field_alias};
 
     if ($this->options['format'] == 'unserialized') {
-      return SafeMarkup::checkPlain(print_r(unserialize($value), TRUE));
+      return $this->sanitizeValue(print_r(unserialize($value), TRUE));
     }
     elseif ($this->options['format'] == 'key' && !empty($this->options['key'])) {
       $value = (array) unserialize($value);
-      return SafeMarkup::checkPlain($value[$this->options['key']]);
+      return $this->sanitizeValue($value[$this->options['key']]);
     }
 
     return $value;
diff --git a/core/modules/views/src/Views.php b/core/modules/views/src/Views.php
index 33570ae96da7086556ca09e88ac134afe3217739..6f11b4add1fa497abd53b6399b8680295ed950b4 100644
--- a/core/modules/views/src/Views.php
+++ b/core/modules/views/src/Views.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\views;
 
-use Drupal\Component\Utility\SafeMarkup;
-
 /**
  * Static service container wrapper for views.
  */
@@ -398,8 +396,8 @@ public static function pluginList() {
           if (!isset($plugins[$key])) {
             $plugins[$key] = array(
               'type' => $type,
-              'title' => SafeMarkup::checkPlain($info[$name]['title']),
-              'provider' => SafeMarkup::checkPlain($info[$name]['provider']),
+              'title' => $info[$name]['title'],
+              'provider' => $info[$name]['provider'],
               'views' => array(),
             );
           }
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
index 17bcdb7d4e399129f28062a336ec83c917d6d6a1..529ea0a3977fde6f02106c7a9a80f31da3d9f867 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
@@ -67,7 +67,7 @@ display:
       path: test_attachment_ui_feed
   page_1:
     display_plugin: page
-    display_title: Page
+    display_title: <em>Page</em>
     display_options:
       path: test_attachment_ui
     id: page_1
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
index 452d9347bb8abfca7fbe39fa16052a115fe67e22..2c35726c6077f4279b1be4f3649a893ce30002fc 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
@@ -123,6 +123,6 @@ display:
     display_options:
       path: test-feed-display
     display_plugin: page
-    display_title: Page
+    display_title: <em>Page</em>
     id: page
     position: 0
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
index 1342c70a86d7836cc2c4ad611667e4c6fac190aa..bb856ce938a02cacdfe863878e84b728c0822614 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
@@ -295,7 +295,7 @@ display:
   page:
     display_plugin: page
     id: page_1
-    display_title: Page
+    display_title: <em>Page</em>
     position: 1
     display_options:
       path: test-opml-style
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 22424a124ac45371de9d912b01c71e116cf67ed5..19af30df925481a2f14b5bad7fc5cafd77c1b012 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -67,8 +67,8 @@ function views_views_pre_render($view) {
         'views_dom_id:' . $view->dom_id => array(
           'view_name' => $view->storage->id(),
           'view_display_id' => $view->current_display,
-          'view_args' => SafeMarkup::checkPlain(implode('/', $view->args)),
-          'view_path' => SafeMarkup::checkPlain(Url::fromRoute('<current>')->toString()),
+          'view_args' => Html::escape(implode('/', $view->args)),
+          'view_path' => Html::escape(Url::fromRoute('<current>')->toString()),
           'view_base_path' => $view->getPath(),
           'view_dom_id' => $view->dom_id,
           // To fit multiple views on a page, the programmer may have
diff --git a/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php b/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php
index 68fa2b3d7501cbd575d7ecaaa3666d6380d7b056..455ae9fc8fe4cfb78718bc091faaad4f51f529d2 100644
--- a/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php
+++ b/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php
@@ -33,6 +33,8 @@ public function testAttachmentUI() {
 
     $attachment_display_url = 'admin/structure/views/nojs/display/test_attachment_ui/attachment_1/displays';
     $this->drupalGet($attachment_display_url);
+    // Display labels should be escaped.
+    $this->assertEscaped('<em>Page</em>');
 
     foreach (array('default', 'page-1') as $display_id) {
       $this->assertNoFieldChecked("edit-displays-$display_id", format_string('Make sure the @display_id can be marked as attached', array('@display_id' => $display_id)));
@@ -40,6 +42,9 @@ public function testAttachmentUI() {
 
     // Save the attachments and test the value on the view.
     $this->drupalPostForm($attachment_display_url, array('displays[page_1]' => 1), t('Apply'));
+    // Options summary should be escaped.
+    $this->assertEscaped('<em>Page</em>');
+    $this->assertNoRaw('<em>Page</em>');
     $result = $this->xpath('//a[@id = :id]', array(':id' => 'views-attachment-1-displays'));
     $this->assertEqual($result[0]->attributes()->title, t('Page'));
     $this->drupalPostForm(NULL, array(), t('Save'));
diff --git a/core/modules/views_ui/src/Tests/DisplayFeedTest.php b/core/modules/views_ui/src/Tests/DisplayFeedTest.php
index 78a3fdcfa9c045007c162391beb91500ce05f240..cc52ca5bca01ee15a910e109b975a6b003d945a0 100644
--- a/core/modules/views_ui/src/Tests/DisplayFeedTest.php
+++ b/core/modules/views_ui/src/Tests/DisplayFeedTest.php
@@ -55,6 +55,8 @@ protected function checkFeedViewUi($view_name) {
 
     // Check the attach TO interface.
     $this->drupalGet('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays');
+    // Display labels should be escaped.
+    $this->assertEscaped('<em>Page</em>');
 
     // Load all the options of the checkbox.
     $result = $this->xpath('//div[@id="edit-displays"]/div');
@@ -71,8 +73,12 @@ protected function checkFeedViewUi($view_name) {
 
     // Post and save this and check the output.
     $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', array('displays[page]' => 'page'), t('Apply'));
+    // Options summary should be escaped.
+    $this->assertEscaped('<em>Page</em>');
+    $this->assertNoRaw('<em>Page</em>');
+
     $this->drupalGet('admin/structure/views/view/' . $view_name . '/edit/feed_1');
-    $this->assertFieldByXpath('//*[@id="views-feed-1-displays"]', 'Page');
+    $this->assertFieldByXpath('//*[@id="views-feed-1-displays"]', '<em>Page</em>');
 
     // Add the default display, so there should now be multiple displays.
     $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', array('displays[default]' => 'default'), t('Apply'));
diff --git a/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
index 178a662568487802af9d5b624124ba689013d53c..28a2846032cffac881585d9b795be895af0ec156 100644
--- a/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php
@@ -231,7 +231,7 @@ public function testDecodeEntities($text, $expected) {
   /**
    * Data provider for testDecodeEntities().
    *
-   * @see testCheckPlain()
+   * @see testDecodeEntities()
    */
   public function providerDecodeEntities() {
     return array(
@@ -272,7 +272,7 @@ public function testEscape($expected, $text) {
   /**
    * Data provider for testEscape().
    *
-   * @see testCheckPlain()
+   * @see testEscape()
    */
   public function providerEscape() {
     return array(
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index 3d7263337b5109dcbe042def5659879c1fd7cd40..4d0dec5f2f8eb2f91593736e5e677467a65db4cd 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -740,7 +740,7 @@ public function testRenderCacheProperties(array $expected_results) {
       'child1' => ['#markup' => SafeString::create('1')],
       'child2' => ['#markup' => SafeString::create('2')],
       // Mark the value as safe.
-      '#custom_property' => SafeMarkup::checkPlain('custom_value'),
+      '#custom_property' => SafeString::create('custom_value'),
       '#custom_property_array' => ['custom value'],
     ];