From fa9ccad7dd5aa0f4adbfaa1bc8db849d0abb8668 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Fri, 12 May 2023 17:37:58 +0200
Subject: [PATCH 01/17] Add back to top block

---
 docs/reference-guides/core-blocks.md          |  9 +++++
 lib/blocks.php                                |  2 +
 .../block-library/src/back-to-top/block.json  | 18 +++++++++
 .../block-library/src/back-to-top/edit.js     | 22 +++++++++++
 .../block-library/src/back-to-top/index.js    | 20 ++++++++++
 .../block-library/src/back-to-top/index.php   | 38 +++++++++++++++++++
 .../block-library/src/back-to-top/init.js     |  6 +++
 packages/block-library/src/index.js           |  2 +
 8 files changed, 117 insertions(+)
 create mode 100644 packages/block-library/src/back-to-top/block.json
 create mode 100644 packages/block-library/src/back-to-top/edit.js
 create mode 100644 packages/block-library/src/back-to-top/index.js
 create mode 100644 packages/block-library/src/back-to-top/index.php
 create mode 100644 packages/block-library/src/back-to-top/init.js

diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index e5d20bb7b1edd5..a55c660383dfa0 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -35,6 +35,15 @@ Add a user’s avatar. ([Source](https://github.com/WordPress/gutenberg/tree/tru
 -	**Supports:** align, anchor, color (~~background~~, ~~text~~), spacing (margin, padding), ~~alignWide~~, ~~html~~
 -	**Attributes:** isLink, linkTarget, size, userId
 
+## Back to top
+
+A link that takes you back to the top. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/back-to-top))
+
+-	**Name:** core/back-to-top
+-	**Category:** design
+-	**Supports:** ~~html~~
+-	**Attributes:** text
+
 ## Reusable block
 
 Create and save content to reuse across your site. Update the block, and the changes apply everywhere it’s used. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/block))
diff --git a/lib/blocks.php b/lib/blocks.php
index bbee108b71c5f5..0b21ea60394ab8 100644
--- a/lib/blocks.php
+++ b/lib/blocks.php
@@ -15,6 +15,7 @@ function gutenberg_reregister_core_block_types() {
 		__DIR__ . '/../build/block-library/blocks/' => array(
 			'block_folders' => array(
 				'audio',
+				'back-to-top',
 				'button',
 				'buttons',
 				'freeform',
@@ -48,6 +49,7 @@ function gutenberg_reregister_core_block_types() {
 			'block_names'   => array(
 				'archives.php'                     => 'core/archives',
 				'avatar.php'                       => 'core/avatar',
+				'back-to-top.php'                  => 'core/back-to-top',
 				'block.php'                        => 'core/block',
 				'calendar.php'                     => 'core/calendar',
 				'categories.php'                   => 'core/categories',
diff --git a/packages/block-library/src/back-to-top/block.json b/packages/block-library/src/back-to-top/block.json
new file mode 100644
index 00000000000000..ddd59126092a29
--- /dev/null
+++ b/packages/block-library/src/back-to-top/block.json
@@ -0,0 +1,18 @@
+{
+	"$schema": "https://schemas.wp.org/trunk/block.json",
+	"apiVersion": 2,
+	"name": "core/back-to-top",
+	"title": "Back to top",
+	"category": "design",
+	"description": "A link that takes you back to the top.",
+	"keywords": [ "top", "skip link" ],
+	"textdomain": "default",
+	"attributes": {
+		"text": {
+			"type": "string"
+		}
+	},
+	"supports": {
+		"html": false
+	}
+}
diff --git a/packages/block-library/src/back-to-top/edit.js b/packages/block-library/src/back-to-top/edit.js
new file mode 100644
index 00000000000000..98ee43b578809a
--- /dev/null
+++ b/packages/block-library/src/back-to-top/edit.js
@@ -0,0 +1,22 @@
+/**
+ * WordPress dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { useBlockProps, RichText } from '@wordpress/block-editor';
+
+export default function BackToTopEdit( { attributes, setAttributes } ) {
+	const { text } = attributes;
+	return (
+		<p { ...useBlockProps() }>
+			<RichText
+				tagName="a"
+				href="#top"
+				value={ text ? text : __( 'Back to Top' ) }
+				withoutInteractiveFormatting={ true }
+				onChange={ ( newLinkText ) =>
+					setAttributes( { text: newLinkText } )
+				}
+			/>
+		</p>
+	);
+}
diff --git a/packages/block-library/src/back-to-top/index.js b/packages/block-library/src/back-to-top/index.js
new file mode 100644
index 00000000000000..05e2c05bffe9bd
--- /dev/null
+++ b/packages/block-library/src/back-to-top/index.js
@@ -0,0 +1,20 @@
+/**
+ * WordPress dependencies
+ */
+import { arrowUp as icon } from '@wordpress/icons';
+
+/**
+ * Internal dependencies
+ */
+import initBlock from '../utils/init-block';
+import edit from './edit';
+import metadata from './block.json';
+
+const { name } = metadata;
+export { metadata, name };
+export const settings = {
+	icon,
+	edit,
+};
+
+export const init = () => initBlock( { name, metadata, settings } );
diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
new file mode 100644
index 00000000000000..315f5a16f995f0
--- /dev/null
+++ b/packages/block-library/src/back-to-top/index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Server-side rendering of the `core/back-to-top` block.
+ *
+ * @package WordPress
+ */
+
+/**
+ * Renders the `core/back-to-top` block on the server.
+ *
+ * @param array    $attributes Block attributes.
+ * @param string   $content    Block default content.
+ * @param WP_Block $block      Block instance.
+ * @return string Return the back to top link.
+ */
+function render_block_core_back_to_top( $attributes ) {
+	$link_text = isset( $attributes[ 'text' ] ) ? $attributes[ 'text' ] : __( 'Back to top' );
+	$wrapper_attributes = get_block_wrapper_attributes();
+
+	return sprintf(
+		'<p %1$s><a href="#top">%2$s</a></p>',
+		$wrapper_attributes,
+		wp_kses_post( $link_text )
+	);
+}
+
+/**
+ * Registers the `core/back_to_top` block on the server.
+ */
+function register_block_core_back_to_top() {
+	register_block_type_from_metadata(
+		__DIR__ . '/back-to-top',
+		array(
+			'render_callback' => 'render_block_core_back_to_top',
+		)
+	);
+}
+add_action( 'init', 'register_block_core_back_to_top' );
diff --git a/packages/block-library/src/back-to-top/init.js b/packages/block-library/src/back-to-top/init.js
new file mode 100644
index 00000000000000..79f0492c2cb2f8
--- /dev/null
+++ b/packages/block-library/src/back-to-top/init.js
@@ -0,0 +1,6 @@
+/**
+ * Internal dependencies
+ */
+import { init } from './';
+
+export default init();
diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js
index a0c7b75eac19b8..f100caa3d3cd2b 100644
--- a/packages/block-library/src/index.js
+++ b/packages/block-library/src/index.js
@@ -23,6 +23,7 @@ import {
 import * as archives from './archives';
 import * as avatar from './avatar';
 import * as audio from './audio';
+import * as backToTop from './back-to-top';
 import * as button from './button';
 import * as buttons from './buttons';
 import * as calendar from './calendar';
@@ -137,6 +138,7 @@ const getAllBlocks = () => {
 		// Register all remaining core blocks.
 		archives,
 		audio,
+		backToTop,
 		button,
 		buttons,
 		calendar,

From fee0a393c5b14af52116db901a2fe7b587b8ae72 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Sat, 13 May 2023 03:22:36 +0200
Subject: [PATCH 02/17] Add fixtures

---
 test/integration/fixtures/blocks/core__back-to-top.html  | 1 +
 test/integration/fixtures/blocks/core__back-to-top.json  | 8 ++++++++
 .../fixtures/blocks/core__back-to-top.parsed.json        | 9 +++++++++
 .../fixtures/blocks/core__back-to-top.serialized.html    | 1 +
 4 files changed, 19 insertions(+)
 create mode 100644 test/integration/fixtures/blocks/core__back-to-top.html
 create mode 100644 test/integration/fixtures/blocks/core__back-to-top.json
 create mode 100644 test/integration/fixtures/blocks/core__back-to-top.parsed.json
 create mode 100644 test/integration/fixtures/blocks/core__back-to-top.serialized.html

diff --git a/test/integration/fixtures/blocks/core__back-to-top.html b/test/integration/fixtures/blocks/core__back-to-top.html
new file mode 100644
index 00000000000000..efbe819d59be4f
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__back-to-top.html
@@ -0,0 +1 @@
+<!-- wp:back-to-top /-->
diff --git a/test/integration/fixtures/blocks/core__back-to-top.json b/test/integration/fixtures/blocks/core__back-to-top.json
new file mode 100644
index 00000000000000..8f8325f34e6d5d
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__back-to-top.json
@@ -0,0 +1,8 @@
+[
+	{
+		"name": "core/back-to-top",
+		"isValid": true,
+		"attributes": {},
+		"innerBlocks": []
+	}
+]
diff --git a/test/integration/fixtures/blocks/core__back-to-top.parsed.json b/test/integration/fixtures/blocks/core__back-to-top.parsed.json
new file mode 100644
index 00000000000000..dbc8929d2bc31a
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__back-to-top.parsed.json
@@ -0,0 +1,9 @@
+[
+	{
+		"blockName": "core/back-to-top",
+		"attrs": {},
+		"innerBlocks": [],
+		"innerHTML": "",
+		"innerContent": []
+	}
+]
diff --git a/test/integration/fixtures/blocks/core__back-to-top.serialized.html b/test/integration/fixtures/blocks/core__back-to-top.serialized.html
new file mode 100644
index 00000000000000..efbe819d59be4f
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__back-to-top.serialized.html
@@ -0,0 +1 @@
+<!-- wp:back-to-top /-->

From 1cc688aacd5345d6b8f1d7398c6d51af01df5c25 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Sat, 13 May 2023 03:25:45 +0200
Subject: [PATCH 03/17] Update index.php

---
 packages/block-library/src/back-to-top/index.php | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 315f5a16f995f0..6abe205eea394a 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -8,13 +8,11 @@
 /**
  * Renders the `core/back-to-top` block on the server.
  *
- * @param array    $attributes Block attributes.
- * @param string   $content    Block default content.
- * @param WP_Block $block      Block instance.
+ * @param array   $attributes Block attributes.
  * @return string Return the back to top link.
  */
 function render_block_core_back_to_top( $attributes ) {
-	$link_text = isset( $attributes[ 'text' ] ) ? $attributes[ 'text' ] : __( 'Back to top' );
+	$link_text          = isset( $attributes['text'] ) ? $attributes['text'] : __( 'Back to top' );
 	$wrapper_attributes = get_block_wrapper_attributes();
 
 	return sprintf(

From 7ee4f4ba7ce82dd30661b5e17f46e144983d4c1f Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Sat, 13 May 2023 03:33:16 +0200
Subject: [PATCH 04/17] Update index.php

---
 packages/block-library/src/back-to-top/index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 6abe205eea394a..cc29738f928ba7 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -8,7 +8,7 @@
 /**
  * Renders the `core/back-to-top` block on the server.
  *
- * @param array   $attributes Block attributes.
+ * @param array $attributes Block attributes.
  * @return string Return the back to top link.
  */
 function render_block_core_back_to_top( $attributes ) {

From 3d2cf38a4908de0ac55313f0ed1be2499e226cb3 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Mon, 15 May 2023 08:22:11 +0200
Subject: [PATCH 05/17] Add a viewScript that moves focus

---
 .../block-library/src/back-to-top/block.json    |  3 ++-
 packages/block-library/src/back-to-top/view.js  | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 packages/block-library/src/back-to-top/view.js

diff --git a/packages/block-library/src/back-to-top/block.json b/packages/block-library/src/back-to-top/block.json
index ddd59126092a29..c98dfdf60e089c 100644
--- a/packages/block-library/src/back-to-top/block.json
+++ b/packages/block-library/src/back-to-top/block.json
@@ -14,5 +14,6 @@
 	},
 	"supports": {
 		"html": false
-	}
+	},
+	"viewScript": "file:./view.min.js"
 }
diff --git a/packages/block-library/src/back-to-top/view.js b/packages/block-library/src/back-to-top/view.js
new file mode 100644
index 00000000000000..5f1ea3b4082095
--- /dev/null
+++ b/packages/block-library/src/back-to-top/view.js
@@ -0,0 +1,17 @@
+window.addEventListener( 'load', () => {
+	const backToTopBlocks = document.querySelectorAll(
+		'.wp-block-back-to-top'
+	);
+	function moveFocusToTop() {
+		const topAnchor = document.getElementById( 'top' );
+		if ( topAnchor ) {
+			topAnchor.querySelector( 'a' ).focus();
+			return;
+		}
+		document.querySelector( 'body a' ).focus();
+	}
+
+	backToTopBlocks.forEach( ( backToTop ) => {
+		backToTop.addEventListener( 'click', moveFocusToTop );
+	} );
+} );

From 615cc8c963fd56251be72050b2100dc6c34c14fb Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Fri, 19 May 2023 09:40:37 +0200
Subject: [PATCH 06/17] Add aria-label to the RichText, and change the
 capitalization of "top"

---
 packages/block-library/src/back-to-top/edit.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/edit.js b/packages/block-library/src/back-to-top/edit.js
index 98ee43b578809a..2d27e0d9771c49 100644
--- a/packages/block-library/src/back-to-top/edit.js
+++ b/packages/block-library/src/back-to-top/edit.js
@@ -11,7 +11,8 @@ export default function BackToTopEdit( { attributes, setAttributes } ) {
 			<RichText
 				tagName="a"
 				href="#top"
-				value={ text ? text : __( 'Back to Top' ) }
+				aria-label={ __( 'Back to top link text' ) }
+				value={ text ? text : __( 'Back to top' ) }
 				withoutInteractiveFormatting={ true }
 				onChange={ ( newLinkText ) =>
 					setAttributes( { text: newLinkText } )

From f5ac6fc630ced220985fd398399d1c8916f82b50 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 24 May 2023 05:16:46 +0200
Subject: [PATCH 07/17] Remove the viewscript and a div with the target id to
 the body.

---
 .../block-library/src/back-to-top/block.json    |  3 +--
 packages/block-library/src/back-to-top/edit.js  |  2 +-
 .../block-library/src/back-to-top/index.php     | 10 +++++++++-
 packages/block-library/src/back-to-top/view.js  | 17 -----------------
 4 files changed, 11 insertions(+), 21 deletions(-)
 delete mode 100644 packages/block-library/src/back-to-top/view.js

diff --git a/packages/block-library/src/back-to-top/block.json b/packages/block-library/src/back-to-top/block.json
index c98dfdf60e089c..ddd59126092a29 100644
--- a/packages/block-library/src/back-to-top/block.json
+++ b/packages/block-library/src/back-to-top/block.json
@@ -14,6 +14,5 @@
 	},
 	"supports": {
 		"html": false
-	},
-	"viewScript": "file:./view.min.js"
+	}
 }
diff --git a/packages/block-library/src/back-to-top/edit.js b/packages/block-library/src/back-to-top/edit.js
index 2d27e0d9771c49..e1b1be66cdf87a 100644
--- a/packages/block-library/src/back-to-top/edit.js
+++ b/packages/block-library/src/back-to-top/edit.js
@@ -10,7 +10,7 @@ export default function BackToTopEdit( { attributes, setAttributes } ) {
 		<p { ...useBlockProps() }>
 			<RichText
 				tagName="a"
-				href="#top"
+				href="#wp-back-to-top"
 				aria-label={ __( 'Back to top link text' ) }
 				value={ text ? text : __( 'Back to top' ) }
 				withoutInteractiveFormatting={ true }
diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index cc29738f928ba7..8c03d79e52687f 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -16,7 +16,7 @@ function render_block_core_back_to_top( $attributes ) {
 	$wrapper_attributes = get_block_wrapper_attributes();
 
 	return sprintf(
-		'<p %1$s><a href="#top">%2$s</a></p>',
+		'<p %1$s><a href="#wp-back-to-top">%2$s</a></p>',
 		$wrapper_attributes,
 		wp_kses_post( $link_text )
 	);
@@ -34,3 +34,11 @@ function register_block_core_back_to_top() {
 	);
 }
 add_action( 'init', 'register_block_core_back_to_top' );
+
+/**
+ * Add the target id to top of each page.
+ */
+function block_core_back_to_top_target() {
+	echo '<div id="wp-back-to-top"></div>';
+}
+add_action( 'wp_body_open', 'block_core_back_to_top_target' );
diff --git a/packages/block-library/src/back-to-top/view.js b/packages/block-library/src/back-to-top/view.js
deleted file mode 100644
index 5f1ea3b4082095..00000000000000
--- a/packages/block-library/src/back-to-top/view.js
+++ /dev/null
@@ -1,17 +0,0 @@
-window.addEventListener( 'load', () => {
-	const backToTopBlocks = document.querySelectorAll(
-		'.wp-block-back-to-top'
-	);
-	function moveFocusToTop() {
-		const topAnchor = document.getElementById( 'top' );
-		if ( topAnchor ) {
-			topAnchor.querySelector( 'a' ).focus();
-			return;
-		}
-		document.querySelector( 'body a' ).focus();
-	}
-
-	backToTopBlocks.forEach( ( backToTop ) => {
-		backToTop.addEventListener( 'click', moveFocusToTop );
-	} );
-} );

From 7fe0fbd61bc9fed43030f81d39674a598e43b3fa Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 24 May 2023 05:25:11 +0200
Subject: [PATCH 08/17] fix a small typo

---
 packages/block-library/src/back-to-top/index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 8c03d79e52687f..a1d6c4249e4dd3 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -36,7 +36,7 @@ function register_block_core_back_to_top() {
 add_action( 'init', 'register_block_core_back_to_top' );
 
 /**
- * Add the target id to top of each page.
+ * Add the target id to the top of each page.
  */
 function block_core_back_to_top_target() {
 	echo '<div id="wp-back-to-top"></div>';

From c84f3a96d524a6e21d5065cd3e9e393db6cfa12a Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 24 May 2023 11:48:56 +0200
Subject: [PATCH 09/17] Block themes: Only add the target id if the block
 exists on the page

---
 packages/block-library/src/back-to-top/index.php | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index a1d6c4249e4dd3..b2e8c5ddf3583d 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -36,9 +36,19 @@ function register_block_core_back_to_top() {
 add_action( 'init', 'register_block_core_back_to_top' );
 
 /**
- * Add the target id to the top of each page.
+ * Block themes: If the block exists on the page, add the target id.
+ * Classic themes: We can't check if the block is in use, so we always add the target id.
  */
 function block_core_back_to_top_target() {
 	echo '<div id="wp-back-to-top"></div>';
 }
-add_action( 'wp_body_open', 'block_core_back_to_top_target' );
+if ( wp_is_block_theme() ) {
+	add_filter( 'render_block', function( $html, $block ) {
+		if ( 'core/back-to-top' === $block['blockName'] ) {
+			add_action( 'wp_body_open', 'block_core_back_to_top_target' );
+		}
+		return $html;
+	}, 10,2 );
+} else {
+	add_action( 'wp_body_open', 'block_core_back_to_top_target' );
+}

From 27239b49c369660f523ba7994b80d706edc996d7 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 24 May 2023 12:12:04 +0200
Subject: [PATCH 10/17] Update index.php

---
 packages/block-library/src/back-to-top/index.php | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index b2e8c5ddf3583d..40e22a881eca07 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -43,12 +43,16 @@ function block_core_back_to_top_target() {
 	echo '<div id="wp-back-to-top"></div>';
 }
 if ( wp_is_block_theme() ) {
-	add_filter( 'render_block', function( $html, $block ) {
-		if ( 'core/back-to-top' === $block['blockName'] ) {
-			add_action( 'wp_body_open', 'block_core_back_to_top_target' );
-		}
-		return $html;
-	}, 10,2 );
+	add_filter(
+		'render_block',
+		function( $html, $block ) {
+			if ( 'core/back-to-top' === $block['blockName'] ) {
+				add_action( 'wp_body_open', 'block_core_back_to_top_target' );
+			}
+			return $html;
+		},
+		10,2
+	);
 } else {
 	add_action( 'wp_body_open', 'block_core_back_to_top_target' );
 }

From 2b51162c3d0ff6f0205edcebe372c8c03eededd4 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 24 May 2023 13:10:25 +0200
Subject: [PATCH 11/17] Update index.php

---
 packages/block-library/src/back-to-top/index.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 40e22a881eca07..c8a86bc69b3762 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -51,7 +51,8 @@ function( $html, $block ) {
 			}
 			return $html;
 		},
-		10,2
+		10,
+		2
 	);
 } else {
 	add_action( 'wp_body_open', 'block_core_back_to_top_target' );

From ba1eebfa2e40fa67387349e228130bb76e4ac947 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Mon, 29 May 2023 12:59:03 +0200
Subject: [PATCH 12/17] Try to use the JavaScript file as a fallback for
 classic themes

---
 .../block-library/src/back-to-top/index.php   | 28 +++++++++++++++++++
 .../block-library/src/back-to-top/view.js     | 21 ++++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 packages/block-library/src/back-to-top/view.js

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index c8a86bc69b3762..7a5061ba1a4689 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -57,3 +57,31 @@ function( $html, $block ) {
 } else {
 	add_action( 'wp_body_open', 'block_core_back_to_top_target' );
 }
+
+/**
+ * Enqueue the fallback view.js file if the classic theme does not
+ * use `wp_body_open()`.
+ */
+function enqueue_block_core_back_to_top_classic_fallback() {
+	if ( ! wp_is_block_theme() && 0 === did_action( 'wp_body_open' ) ) {
+		// If the Gutenberg plugin is active, use the script from the plugin.
+		if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
+			wp_enqueue_script(
+				'wp-block-library-back-to-top-fallback',
+				plugins_url( 'back-to-top/view.min.js', __FILE__ ),
+				array(),
+				filemtime( plugin_dir_path( __FILE__ ) . 'back-to-top/view.min.js' ),
+				true
+			);
+		} else {
+			wp_enqueue_script(
+				'wp-block-library-back-to-top-fallback',
+				includes_url( 'blocks/back-to-top/view.min.js', __DIR__ ),
+				array(),
+				'',
+				true
+			);
+		}
+	}
+}
+add_action( 'wp_enqueue_scripts', 'enqueue_block_core_back_to_top_classic_fallback' );
diff --git a/packages/block-library/src/back-to-top/view.js b/packages/block-library/src/back-to-top/view.js
new file mode 100644
index 00000000000000..fba398c90509aa
--- /dev/null
+++ b/packages/block-library/src/back-to-top/view.js
@@ -0,0 +1,21 @@
+/**
+ * This script is loaded on the front as a fallback
+ * if the classic theme does not include wp_body_open().
+ */
+window.addEventListener( 'load', () => {
+	const backToTopBlocks = document.querySelectorAll(
+		'.wp-block-back-to-top'
+	);
+	function moveFocusToTop() {
+		const topAnchor = document.getElementById( '#wp-back-to-top' );
+		if ( topAnchor ) {
+			topAnchor.querySelector( 'a' ).focus();
+			return;
+		}
+		document.querySelector( 'body a' ).focus();
+	}
+
+	backToTopBlocks.forEach( ( backToTop ) => {
+		backToTop.addEventListener( 'click', moveFocusToTop );
+	} );
+} );

From b972cf7b9653f38fd8b7a2e688801554c8e248c7 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Fri, 16 Jun 2023 09:12:58 +0200
Subject: [PATCH 13/17] Try moving the JavaScript fallback

---
 packages/block-library/src/back-to-top/index.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 7a5061ba1a4689..2b76e3803df8d6 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -15,6 +15,8 @@ function render_block_core_back_to_top( $attributes ) {
 	$link_text          = isset( $attributes['text'] ) ? $attributes['text'] : __( 'Back to top' );
 	$wrapper_attributes = get_block_wrapper_attributes();
 
+	enqueue_block_core_back_to_top_classic_fallback();
+
 	return sprintf(
 		'<p %1$s><a href="#wp-back-to-top">%2$s</a></p>',
 		$wrapper_attributes,
@@ -84,4 +86,3 @@ function enqueue_block_core_back_to_top_classic_fallback() {
 		}
 	}
 }
-add_action( 'wp_enqueue_scripts', 'enqueue_block_core_back_to_top_classic_fallback' );

From 63a302b39c1ee154e12e4dc6a85315a07b1cdfc7 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Mon, 26 Jun 2023 13:33:53 +0200
Subject: [PATCH 14/17] Update apiVersion from 2 to 3.

---
 packages/block-library/src/back-to-top/block.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/block.json b/packages/block-library/src/back-to-top/block.json
index ddd59126092a29..28ce04434e997c 100644
--- a/packages/block-library/src/back-to-top/block.json
+++ b/packages/block-library/src/back-to-top/block.json
@@ -1,6 +1,6 @@
 {
 	"$schema": "https://schemas.wp.org/trunk/block.json",
-	"apiVersion": 2,
+	"apiVersion": 3,
 	"name": "core/back-to-top",
 	"title": "Back to top",
 	"category": "design",

From 9f83e8545d2e3d6ec7f02ac01c2e57011657b88c Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Fri, 18 Aug 2023 12:39:42 +0200
Subject: [PATCH 15/17] rename fallback function

---
 packages/block-library/src/back-to-top/index.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 2b76e3803df8d6..49e2dce0534d27 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -15,7 +15,7 @@ function render_block_core_back_to_top( $attributes ) {
 	$link_text          = isset( $attributes['text'] ) ? $attributes['text'] : __( 'Back to top' );
 	$wrapper_attributes = get_block_wrapper_attributes();
 
-	enqueue_block_core_back_to_top_classic_fallback();
+	block_core_back_to_top_classic_fallback();
 
 	return sprintf(
 		'<p %1$s><a href="#wp-back-to-top">%2$s</a></p>',
@@ -64,7 +64,7 @@ function( $html, $block ) {
  * Enqueue the fallback view.js file if the classic theme does not
  * use `wp_body_open()`.
  */
-function enqueue_block_core_back_to_top_classic_fallback() {
+function block_core_back_to_top_classic_fallback() {
 	if ( ! wp_is_block_theme() && 0 === did_action( 'wp_body_open' ) ) {
 		// If the Gutenberg plugin is active, use the script from the plugin.
 		if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {

From 69f1ca1e0224128046dd93089db38b5cbad7d8c3 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 11 Oct 2023 11:44:26 +0200
Subject: [PATCH 16/17] Add more focusable elements to the view script. Update
 doc blocks.

---
 .../block-library/src/back-to-top/index.php   |  9 ++++---
 .../block-library/src/back-to-top/view.js     | 25 ++++++++++++++++---
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 49e2dce0534d27..769fc14b3e8302 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -38,8 +38,9 @@ function register_block_core_back_to_top() {
 add_action( 'init', 'register_block_core_back_to_top' );
 
 /**
- * Block themes: If the block exists on the page, add the target id.
- * Classic themes: We can't check if the block is in use, so we always add the target id.
+ * Adds the target id 'wp-back-to-top' to the top of the page, so that focus can be moved.
+ * Block themes: Add the target id if the back to top block exists on the page.
+ * Classic themes with 'wp_body_open()': Always add the target id.
  */
 function block_core_back_to_top_target() {
 	echo '<div id="wp-back-to-top"></div>';
@@ -61,8 +62,8 @@ function( $html, $block ) {
 }
 
 /**
- * Enqueue the fallback view.js file if the classic theme does not
- * use `wp_body_open()`.
+ * For classic themes that do not use `wp_body_open()`,
+ * view.js is needed to move focus to the first focusable element on the top of the page.
  */
 function block_core_back_to_top_classic_fallback() {
 	if ( ! wp_is_block_theme() && 0 === did_action( 'wp_body_open' ) ) {
diff --git a/packages/block-library/src/back-to-top/view.js b/packages/block-library/src/back-to-top/view.js
index fba398c90509aa..ae0b058b1048c2 100644
--- a/packages/block-library/src/back-to-top/view.js
+++ b/packages/block-library/src/back-to-top/view.js
@@ -1,6 +1,6 @@
 /**
- * This script is loaded on the front as a fallback
- * if the classic theme does not include wp_body_open().
+ * This script is needed to move the focus to the first focusable element on the page.
+ * It is only intended to be loaded on the front of classic themes that does not include wp_body_open().
  */
 window.addEventListener( 'load', () => {
 	const backToTopBlocks = document.querySelectorAll(
@@ -12,7 +12,26 @@ window.addEventListener( 'load', () => {
 			topAnchor.querySelector( 'a' ).focus();
 			return;
 		}
-		document.querySelector( 'body a' ).focus();
+		// This list is not exhaustive, but covers common elements that can recieve focus.
+		const focusable = [
+			'a[href]',
+			'audio',
+			'button:not([disabled])',
+			'[contenteditable]',
+			'details',
+			'embed',
+			'iframe',
+			'input:not([disabled]):not([type="hidden"])',
+			'object',
+			'[role="button"][tabindex="0"]',
+			'[role="link"][tabindex="0"]',
+			'select:not([disabled])',
+			'summary',
+			'textarea:not([disabled])',
+			'video',
+			'[tabindex]:not([tabindex="-1"])',
+		];
+		document.querySelector( focusable.join( ', ' ) ).focus();
 	}
 
 	backToTopBlocks.forEach( ( backToTop ) => {

From 8ba2e3f678abb9171c7d8076ae7e7e5dd09ebbb2 Mon Sep 17 00:00:00 2001
From: Carolina Nymark <hi@themesbycarolina.com>
Date: Wed, 11 Oct 2023 13:28:36 +0200
Subject: [PATCH 17/17] Fix CS spacing issue

---
 packages/block-library/src/back-to-top/index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/block-library/src/back-to-top/index.php b/packages/block-library/src/back-to-top/index.php
index 769fc14b3e8302..39be602f4dbc21 100644
--- a/packages/block-library/src/back-to-top/index.php
+++ b/packages/block-library/src/back-to-top/index.php
@@ -48,7 +48,7 @@ function block_core_back_to_top_target() {
 if ( wp_is_block_theme() ) {
 	add_filter(
 		'render_block',
-		function( $html, $block ) {
+		function ( $html, $block ) {
 			if ( 'core/back-to-top' === $block['blockName'] ) {
 				add_action( 'wp_body_open', 'block_core_back_to_top_target' );
 			}