@@ -67,6 +67,46 @@ function perflab_render_settings_page(): void {
67
67
<?php
68
68
}
69
69
70
+ /**
71
+ * Gets dismissed admin pointer IDs.
72
+ *
73
+ * @since n.e.x.t
74
+ *
75
+ * @return non-empty-string[] Dismissed admin pointer IDs.
76
+ */
77
+ function perflab_get_dismissed_admin_pointer_ids (): array {
78
+ return array_filter (
79
+ explode (
80
+ ', ' ,
81
+ (string ) get_user_meta ( get_current_user_id (), 'dismissed_wp_pointers ' , true )
82
+ )
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Gets the admin pointers.
88
+ *
89
+ * @since n.e.x.t
90
+ *
91
+ * @return array<non-empty-string, string> Admin pointer messages with the admin pointer IDs as the keys.
92
+ */
93
+ function perflab_get_admin_pointers (): array {
94
+ $ pointers = array (
95
+ 'perflab-admin-pointer ' => __ ( 'You can now test upcoming WordPress performance features. ' , 'performance-lab ' ),
96
+ 'perflab-feature-view-transitions ' => __ ( 'New <strong>View Transitions</strong> feature now available. ' , 'performance-lab ' ),
97
+ );
98
+
99
+ if (
100
+ defined ( 'SPECULATION_RULES_VERSION ' )
101
+ &&
102
+ version_compare ( SPECULATION_RULES_VERSION , '1.6.0 ' , '>= ' )
103
+ ) {
104
+ $ pointers ['perflab-feature-speculation-rules-auth ' ] = __ ( '<strong>Speculative Loading</strong> now includes an opt-in setting for logged-in users. ' , 'performance-lab ' );
105
+ }
106
+
107
+ return $ pointers ;
108
+ }
109
+
70
110
/**
71
111
* Initializes admin pointer.
72
112
*
@@ -83,19 +123,29 @@ function perflab_admin_pointer( ?string $hook_suffix = '' ): void {
83
123
if ( is_network_admin () || is_user_admin () ) {
84
124
return ;
85
125
}
86
- $ current_user = get_current_user_id ();
87
- $ dismissed = array_filter ( explode ( ', ' , (string ) get_user_meta ( get_current_user_id (), 'dismissed_wp_pointers ' , true ) ) );
88
126
89
- if ( in_array ( 'perflab-admin-pointer ' , $ dismissed , true ) ) {
127
+ $ admin_pointers = perflab_get_admin_pointers ();
128
+ $ admin_pointer_ids = array_keys ( $ admin_pointers );
129
+ $ dismissed_pointer_ids = perflab_get_dismissed_admin_pointer_ids ();
130
+
131
+ // All pointers have been dismissed already.
132
+ if ( count ( array_diff ( $ admin_pointer_ids , $ dismissed_pointer_ids ) ) === 0 ) {
90
133
return ;
91
134
}
92
135
136
+ // Do not show the admin pointer when not on the dashboard or plugins list table.
93
137
if ( ! in_array ( $ hook_suffix , array ( 'index.php ' , 'plugins.php ' ), true ) ) {
94
138
95
- // Do not show on the settings page and dismiss the pointer.
96
- if ( isset ( $ _GET ['page ' ] ) && PERFLAB_SCREEN === $ _GET ['page ' ] && ( ! in_array ( 'perflab-admin-pointer ' , $ dismissed , true ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
97
- $ dismissed [] = 'perflab-admin-pointer ' ;
98
- update_user_meta ( $ current_user , 'dismissed_wp_pointers ' , implode ( ', ' , $ dismissed ) );
139
+ // And if we're on the Performance screen, automatically dismiss the pointers.
140
+ if ( isset ( $ _GET ['page ' ] ) && PERFLAB_SCREEN === $ _GET ['page ' ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
141
+ update_user_meta (
142
+ get_current_user_id (),
143
+ 'dismissed_wp_pointers ' ,
144
+ implode (
145
+ ', ' ,
146
+ array_unique ( array_merge ( $ dismissed_pointer_ids , $ admin_pointer_ids ) )
147
+ )
148
+ );
99
149
}
100
150
101
151
return ;
@@ -104,69 +154,89 @@ function perflab_admin_pointer( ?string $hook_suffix = '' ): void {
104
154
// Enqueue pointer CSS and JS.
105
155
wp_enqueue_style ( 'wp-pointer ' );
106
156
wp_enqueue_script ( 'wp-pointer ' );
107
- add_action ( 'admin_print_footer_scripts ' , 'perflab_render_pointer ' , 10 , 0 );
108
- }
109
- add_action ( 'admin_enqueue_scripts ' , 'perflab_admin_pointer ' );
110
157
111
- /**
112
- * Renders the Admin Pointer.
113
- *
114
- * Handles the rendering of the admin pointer.
115
- *
116
- * @since 1.0.0
117
- * @since 2.4.0 Optional arguments were added to make the function reusable for different pointers.
118
- *
119
- * @param string $pointer_id Optional. ID of the pointer. Default 'perflab-admin-pointer'.
120
- * @param array{heading?: string, content?: string} $args Optional. Pointer arguments. Supports 'heading' and 'content' entries.
121
- * Defaults are the heading and content for the 'perflab-admin-pointer'.
122
- */
123
- function perflab_render_pointer ( string $ pointer_id = 'perflab-admin-pointer ' , array $ args = array () ): void {
124
- if ( ! isset ( $ args ['heading ' ] ) ) {
125
- $ args ['heading ' ] = __ ( 'Performance Lab ' , 'performance-lab ' );
126
- }
127
- if ( ! isset ( $ args ['content ' ] ) ) {
128
- $ args ['content ' ] = sprintf (
129
- /* translators: %s: settings page link */
130
- esc_html__ ( 'You can now test upcoming WordPress performance features. Open %s to individually toggle the performance features. ' , 'performance-lab ' ),
131
- '<a href=" ' . esc_url ( add_query_arg ( 'page ' , PERFLAB_SCREEN , admin_url ( 'options-general.php ' ) ) ) . '"> ' . esc_html__ ( 'Settings > Performance ' , 'performance-lab ' ) . '</a> '
132
- );
158
+ $ new_install_pointer_id = 'perflab-admin-pointer ' ;
159
+ if ( ! in_array ( $ new_install_pointer_id , $ dismissed_pointer_ids , true ) ) {
160
+ $ needed_pointer_ids = array ( $ new_install_pointer_id );
161
+ } else {
162
+ $ needed_pointer_ids = array_diff ( $ admin_pointer_ids , $ dismissed_pointer_ids );
133
163
}
134
164
165
+ $ args = array (
166
+ 'heading ' => __ ( 'Performance Lab ' , 'performance-lab ' ),
167
+ );
168
+
169
+ $ args ['content ' ] = implode (
170
+ '' ,
171
+ array_map (
172
+ static function ( string $ needed_pointer ) use ( $ admin_pointers ): string {
173
+ return '<p> ' . $ admin_pointers [ $ needed_pointer ] . '</p> ' ;
174
+ },
175
+ $ needed_pointer_ids
176
+ )
177
+ );
178
+
179
+ $ args ['content ' ] .= '<p> ' . sprintf (
180
+ /* translators: %s: settings page link */
181
+ esc_html__ ( 'Open %s to individually toggle the performance features and access any relevant settings. ' , 'performance-lab ' ),
182
+ '<a href=" ' . esc_url ( add_query_arg ( 'page ' , PERFLAB_SCREEN , admin_url ( 'options-general.php ' ) ) ) . '"> ' . esc_html__ ( 'Settings > Performance ' , 'performance-lab ' ) . '</a> '
183
+ ) . '</p> ' ;
184
+
135
185
$ wp_kses_options = array (
136
- 'a ' => array (
186
+ 'a ' => array (
137
187
'href ' => array (),
138
188
),
189
+ 'p ' => array (),
190
+ 'strong ' => array (),
139
191
);
140
192
193
+ $ pointer_ids_to_dismiss = array_values ( array_diff ( $ admin_pointer_ids , $ dismissed_pointer_ids ) );
194
+
195
+ ob_start ();
141
196
?>
142
- <script id=" <?php echo esc_attr ( $ pointer_id ); ?> " type="text/javascript" >
197
+ <script>
143
198
jQuery( function() {
199
+ const pointerIdsToDismiss = <?php echo wp_json_encode ( $ pointer_ids_to_dismiss , JSON_OBJECT_AS_ARRAY ); ?> ;
200
+ const nonce = <?php echo wp_json_encode ( wp_create_nonce ( 'dismiss_pointer ' ) ); ?> ;
201
+
202
+ function dismissNextPointer() {
203
+ const pointerId = pointerIdsToDismiss.shift();
204
+ if ( ! pointerId ) {
205
+ return;
206
+ }
207
+
208
+ jQuery.post(
209
+ window.ajaxurl,
210
+ {
211
+ pointer: pointerId,
212
+ action: 'dismiss-wp-pointer',
213
+ _wpnonce: nonce,
214
+ }
215
+ ).then( dismissNextPointer );
216
+ }
217
+
144
218
// Pointer Options.
145
219
const options = {
146
- content: <?php echo wp_json_encode ( '<h3> ' . esc_html ( $ args ['heading ' ] ) . '</h3><p> ' . wp_kses ( $ args ['content ' ], $ wp_kses_options ) . ' </p> ' ); ?> ,
220
+ content: <?php echo wp_json_encode ( '<h3> ' . esc_html ( $ args ['heading ' ] ) . '</h3> ' . wp_kses ( $ args ['content ' ], $ wp_kses_options ) ); ?> ,
147
221
position: {
148
222
edge: 'left',
149
223
align: 'right',
150
224
},
151
225
pointerClass: 'wp-pointer arrow-top',
152
226
pointerWidth: 420,
153
- close: function() {
154
- jQuery.post(
155
- window.ajaxurl,
156
- {
157
- pointer: <?php echo wp_json_encode ( $ pointer_id ); ?> ,
158
- action: 'dismiss-wp-pointer',
159
- _wpnonce: <?php echo wp_json_encode ( wp_create_nonce ( 'dismiss_pointer ' ) ); ?> ,
160
- }
161
- );
162
- }
227
+ close: dismissNextPointer
163
228
};
164
229
165
230
jQuery( '#menu-settings' ).pointer( options ).pointer( 'open' );
166
231
} );
167
232
</script>
168
233
<?php
234
+ $ processor = new WP_HTML_Tag_Processor ( (string ) ob_get_clean () );
235
+ if ( $ processor ->next_tag ( array ( 'tag_name ' => 'SCRIPT ' ) ) ) {
236
+ wp_add_inline_script ( 'wp-pointer ' , $ processor ->get_modifiable_text () );
237
+ }
169
238
}
239
+ add_action ( 'admin_enqueue_scripts ' , 'perflab_admin_pointer ' );
170
240
171
241
/**
172
242
* Adds a link to the features page to the plugin's entry in the plugins list table.
@@ -207,7 +277,11 @@ function perflab_plugin_action_links_add_settings( $links ) {
207
277
* @since 2.3.0
208
278
*/
209
279
function perflab_dismiss_wp_pointer_wrapper (): void {
210
- if ( isset ( $ _POST ['pointer ' ] ) && 'perflab-admin-pointer ' !== $ _POST ['pointer ' ] ) {
280
+ if (
281
+ isset ( $ _POST ['pointer ' ] )
282
+ &&
283
+ ! in_array ( $ _POST ['pointer ' ], array_keys ( perflab_get_admin_pointers () ), true )
284
+ ) {
211
285
// Another plugin's pointer, do nothing.
212
286
return ;
213
287
}
0 commit comments