29 * |
29 * |
30 * @since 4.8.1 |
30 * @since 4.8.1 |
31 * @var array |
31 * @var array |
32 */ |
32 */ |
33 protected $default_instance = array( |
33 protected $default_instance = array( |
34 'title' => '', |
34 'title' => '', |
35 'content' => '', |
35 'content' => '', |
36 ); |
36 ); |
37 |
37 |
38 /** |
38 /** |
39 * Sets up a new Custom HTML widget instance. |
39 * Sets up a new Custom HTML widget instance. |
40 * |
40 * |
41 * @since 4.8.1 |
41 * @since 4.8.1 |
42 */ |
42 */ |
43 public function __construct() { |
43 public function __construct() { |
44 $widget_ops = array( |
44 $widget_ops = array( |
45 'classname' => 'widget_custom_html', |
45 'classname' => 'widget_custom_html', |
46 'description' => __( 'Arbitrary HTML code.' ), |
46 'description' => __( 'Arbitrary HTML code.' ), |
47 'customize_selective_refresh' => true, |
47 'customize_selective_refresh' => true, |
48 ); |
48 ); |
49 $control_ops = array( |
49 $control_ops = array( |
50 'width' => 400, |
50 'width' => 400, |
51 'height' => 350, |
51 'height' => 350, |
52 ); |
52 ); |
53 parent::__construct( 'custom_html', __( 'Custom HTML' ), $widget_ops, $control_ops ); |
53 parent::__construct( 'custom_html', __( 'Custom HTML' ), $widget_ops, $control_ops ); |
54 } |
54 } |
55 |
55 |
128 |
128 |
129 /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ |
129 /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ |
130 $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); |
130 $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); |
131 |
131 |
132 // Prepare instance data that looks like a normal Text widget. |
132 // Prepare instance data that looks like a normal Text widget. |
133 $simulated_text_widget_instance = array_merge( $instance, array( |
133 $simulated_text_widget_instance = array_merge( |
134 'text' => isset( $instance['content'] ) ? $instance['content'] : '', |
134 $instance, |
135 'filter' => false, // Because wpautop is not applied. |
135 array( |
136 'visual' => false, // Because it wasn't created in TinyMCE. |
136 'text' => isset( $instance['content'] ) ? $instance['content'] : '', |
137 ) ); |
137 'filter' => false, // Because wpautop is not applied. |
|
138 'visual' => false, // Because it wasn't created in TinyMCE. |
|
139 ) |
|
140 ); |
138 unset( $simulated_text_widget_instance['content'] ); // Was moved to 'text' prop. |
141 unset( $simulated_text_widget_instance['content'] ); // Was moved to 'text' prop. |
139 |
142 |
140 /** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */ |
143 /** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */ |
141 $content = apply_filters( 'widget_text', $instance['content'], $simulated_text_widget_instance, $this ); |
144 $content = apply_filters( 'widget_text', $instance['content'], $simulated_text_widget_instance, $this ); |
|
145 |
|
146 // Adds noreferrer and noopener relationships, without duplicating values, to all HTML A elements that have a target. |
|
147 $content = wp_targeted_link_rel( $content ); |
142 |
148 |
143 /** |
149 /** |
144 * Filters the content of the Custom HTML widget. |
150 * Filters the content of the Custom HTML widget. |
145 * |
151 * |
146 * @since 4.8.1 |
152 * @since 4.8.1 |
177 * WP_Widget::form(). |
183 * WP_Widget::form(). |
178 * @param array $old_instance Old settings for this instance. |
184 * @param array $old_instance Old settings for this instance. |
179 * @return array Settings to save or bool false to cancel saving. |
185 * @return array Settings to save or bool false to cancel saving. |
180 */ |
186 */ |
181 public function update( $new_instance, $old_instance ) { |
187 public function update( $new_instance, $old_instance ) { |
182 $instance = array_merge( $this->default_instance, $old_instance ); |
188 $instance = array_merge( $this->default_instance, $old_instance ); |
183 $instance['title'] = sanitize_text_field( $new_instance['title'] ); |
189 $instance['title'] = sanitize_text_field( $new_instance['title'] ); |
184 if ( current_user_can( 'unfiltered_html' ) ) { |
190 if ( current_user_can( 'unfiltered_html' ) ) { |
185 $instance['content'] = $new_instance['content']; |
191 $instance['content'] = $new_instance['content']; |
186 } else { |
192 } else { |
187 $instance['content'] = wp_kses_post( $new_instance['content'] ); |
193 $instance['content'] = wp_kses_post( $new_instance['content'] ); |
193 * Loads the required scripts and styles for the widget control. |
199 * Loads the required scripts and styles for the widget control. |
194 * |
200 * |
195 * @since 4.9.0 |
201 * @since 4.9.0 |
196 */ |
202 */ |
197 public function enqueue_admin_scripts() { |
203 public function enqueue_admin_scripts() { |
198 $settings = wp_enqueue_code_editor( array( |
204 $settings = wp_enqueue_code_editor( |
199 'type' => 'text/html', |
205 array( |
200 'codemirror' => array( |
206 'type' => 'text/html', |
201 'indentUnit' => 2, |
207 'codemirror' => array( |
202 'tabSize' => 2, |
208 'indentUnit' => 2, |
203 ), |
209 'tabSize' => 2, |
204 ) ); |
210 ), |
|
211 ) |
|
212 ); |
205 |
213 |
206 wp_enqueue_script( 'custom-html-widgets' ); |
214 wp_enqueue_script( 'custom-html-widgets' ); |
207 if ( empty( $settings ) ) { |
215 if ( empty( $settings ) ) { |
208 $settings = array( |
216 $settings = array( |
209 'disabled' => true, |
217 'disabled' => true, |
214 $l10n = array( |
222 $l10n = array( |
215 'errorNotice' => array( |
223 'errorNotice' => array( |
216 /* translators: %d: error count */ |
224 /* translators: %d: error count */ |
217 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), |
225 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), |
218 /* translators: %d: error count */ |
226 /* translators: %d: error count */ |
219 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. |
227 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. |
220 ), |
228 ), |
221 ); |
229 ); |
222 wp_add_inline_script( 'custom-html-widgets', sprintf( 'jQuery.extend( wp.customHtmlWidgets.l10n, %s );', wp_json_encode( $l10n ) ), 'after' ); |
230 wp_add_inline_script( 'custom-html-widgets', sprintf( 'jQuery.extend( wp.customHtmlWidgets.l10n, %s );', wp_json_encode( $l10n ) ), 'after' ); |
223 } |
231 } |
224 |
232 |
260 </p> |
268 </p> |
261 |
269 |
262 <?php if ( ! current_user_can( 'unfiltered_html' ) ) : ?> |
270 <?php if ( ! current_user_can( 'unfiltered_html' ) ) : ?> |
263 <?php |
271 <?php |
264 $probably_unsafe_html = array( 'script', 'iframe', 'form', 'input', 'style' ); |
272 $probably_unsafe_html = array( 'script', 'iframe', 'form', 'input', 'style' ); |
265 $allowed_html = wp_kses_allowed_html( 'post' ); |
273 $allowed_html = wp_kses_allowed_html( 'post' ); |
266 $disallowed_html = array_diff( $probably_unsafe_html, array_keys( $allowed_html ) ); |
274 $disallowed_html = array_diff( $probably_unsafe_html, array_keys( $allowed_html ) ); |
267 ?> |
275 ?> |
268 <?php if ( ! empty( $disallowed_html ) ) : ?> |
276 <?php if ( ! empty( $disallowed_html ) ) : ?> |
269 <# if ( data.codeEditorDisabled ) { #> |
277 <# if ( data.codeEditorDisabled ) { #> |
270 <p> |
278 <p> |
271 <?php _e( 'Some HTML tags are not permitted, including:' ); ?> |
279 <?php _e( 'Some HTML tags are not permitted, including:' ); ?> |
286 * @since 4.9.0 |
294 * @since 4.9.0 |
287 */ |
295 */ |
288 public static function add_help_text() { |
296 public static function add_help_text() { |
289 $screen = get_current_screen(); |
297 $screen = get_current_screen(); |
290 |
298 |
291 $content = '<p>'; |
299 $content = '<p>'; |
292 $content .= __( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.' ); |
300 $content .= __( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.' ); |
293 $content .= '</p>'; |
301 $content .= '</p>'; |
294 |
302 |
295 if ( 'false' !== wp_get_current_user()->syntax_highlighting ) { |
303 if ( 'false' !== wp_get_current_user()->syntax_highlighting ) { |
296 $content .= '<p>'; |
304 $content .= '<p>'; |
297 $content .= sprintf( |
305 $content .= sprintf( |
298 /* translators: 1: link to user profile, 2: additional link attributes, 3: accessibility text */ |
306 /* translators: 1: link to user profile, 2: additional link attributes, 3: accessibility text */ |
299 __( 'The edit field automatically highlights code syntax. You can disable this in your <a href="%1$s" %2$s>user profile%3$s</a> to work in plain text mode.' ), |
307 __( 'The edit field automatically highlights code syntax. You can disable this in your <a href="%1$s" %2$s>user profile%3$s</a> to work in plain text mode.' ), |
300 esc_url( get_edit_profile_url() ), |
308 esc_url( get_edit_profile_url() ), |
301 'class="external-link" target="_blank"', |
309 'class="external-link" target="_blank"', |
302 sprintf( '<span class="screen-reader-text"> %s</span>', |
310 sprintf( |
|
311 '<span class="screen-reader-text"> %s</span>', |
303 /* translators: accessibility text */ |
312 /* translators: accessibility text */ |
304 __( '(opens in a new window)' ) |
313 __( '(opens in a new tab)' ) |
305 ) |
314 ) |
306 ); |
315 ); |
307 $content .= '</p>'; |
316 $content .= '</p>'; |
308 |
317 |
309 $content .= '<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>'; |
318 $content .= '<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>'; |
312 $content .= '<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>'; |
321 $content .= '<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>'; |
313 $content .= '<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>'; |
322 $content .= '<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>'; |
314 $content .= '</ul>'; |
323 $content .= '</ul>'; |
315 } |
324 } |
316 |
325 |
317 $screen->add_help_tab( array( |
326 $screen->add_help_tab( |
318 'id' => 'custom_html_widget', |
327 array( |
319 'title' => __( 'Custom HTML Widget' ), |
328 'id' => 'custom_html_widget', |
320 'content' => $content, |
329 'title' => __( 'Custom HTML Widget' ), |
321 ) ); |
330 'content' => $content, |
|
331 ) |
|
332 ); |
322 } |
333 } |
323 } |
334 } |