-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathadditional-javascript.php
More file actions
379 lines (339 loc) · 11.8 KB
/
additional-javascript.php
File metadata and controls
379 lines (339 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
<?php
/**
* Additional JavaScript
*
* @package Additional_JavaScript
* @author Per Soderlind
* @copyright 2018 Per Soderlind
* @license GPL-2.0+
*
* @wordpress-plugin
* Plugin Name: Additional JavaScript
* Plugin URI: https://github.com/soderlind/additional-javascript
* GitHub Plugin URI: https://github.com/soderlind/additional-javascript
* Description: Add additional JavaScript using the WordPress Customizer.
* Version: 1.1.6
* Author: Per Soderlind
* Author URI: https://soderlind.no
* Text Domain: additional-javascript
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
namespace Soderlind\Customizer;
if ( ! defined( 'ABSPATH' ) ) {
die();
}
define( 'ADDITIONAL_JAVASCRIPT_VERSION', '1.1.4' );
define( 'ADDITIONAL_JAVASCRIPT_FILE', __FILE__ );
define( 'ADDITIONAL_JAVASCRIPT_PATH', plugin_dir_path( ADDITIONAL_JAVASCRIPT_FILE ) );
require_once ADDITIONAL_JAVASCRIPT_PATH . 'vendor/autoload.php';
// Include the generic updater class
if ( ! class_exists( 'Soderlind\WordPress\GitHub_Plugin_Updater' ) ) {
require_once ADDITIONAL_JAVASCRIPT_PATH . 'class-github-plugin-updater.php';
}
// Initialize the updater with configuration.
$additional_javascript_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
'https://github.com/soderlind/additional-javascript',
ADDITIONAL_JAVASCRIPT_FILE,
'additional-javascript',
'/additional-javascript\.zip/',
'main'
);
add_action( 'init', __NAMESPACE__ . '\register_post_type_javascript', 0 );
add_action( 'wp_footer', __NAMESPACE__ . '\soderlind_custom_javascript_cb', 110 );
add_action( 'customize_register', __NAMESPACE__ . '\register_additional_javascript' );
add_action( 'customize_preview_init', __NAMESPACE__ . '\customize_preview_additional_javascript' );
add_action( 'customize_controls_enqueue_scripts', __NAMESPACE__ . '\on_customize_controls_enqueue_scripts' );
/**
* Plugin version - used for cache-busting assets
*/
/**
* Add a default JavaScript code.
*
* @return string
*/
function default_js_template(): string {
return <<<EOTEMPLATE
// Run code when the DOM is ready
document.addEventListener('DOMContentLoaded', function () {
// JavaScript code here.
});
EOTEMPLATE;
}
/**
* Register cpt JavaScript.
*
* @return void
*/
function register_post_type_javascript() {
register_post_type(
'custom_javascript',
[
'labels' => [
'name' => __( 'Custom JavaScript' ),
'singular_name' => __( 'Custom JavaScript' ),
],
'public' => false,
'hierarchical' => false,
'rewrite' => false,
'query_var' => false,
'delete_with_user' => false,
'can_export' => true,
// '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
'supports' => [ 'title', 'revisions' ],
'capabilities' => [
'delete_posts' => 'edit_theme_options',
'delete_post' => 'edit_theme_options',
'delete_published_posts' => 'edit_theme_options',
'delete_private_posts' => 'edit_theme_options',
'delete_others_posts' => 'edit_theme_options',
'edit_post' => 'unfiltered_html',
'edit_posts' => 'unfiltered_html',
'edit_others_posts' => 'unfiltered_html',
'edit_published_posts' => 'unfiltered_html',
'read_post' => 'read',
'read_private_posts' => 'read',
'publish_posts' => 'edit_theme_options',
],
]
);
}
/**
* Render the Custom JavaScript style element.
*
* @since 4.7.0
*/
function soderlind_custom_javascript_cb() {
$javascript = soderlind_get_custom_javascript();
if ( $javascript || is_customize_preview() ) {
wp_print_inline_script_tag( $javascript, [ 'id' => 'soderlind-custom-javascript' ] );
}
}
/**
* Add section, settings and control.
*
* @param \WP_Customize_Manager $wp_customize
* @return void
*/
function register_additional_javascript( \WP_Customize_Manager $wp_customize ) {
$wp_customize->add_section(
'custom_javascript',
[
'title' => _x( 'Additional JavaScript', 'customizer menu', 'dss-wp' ),
'priority' => 999,
]
);
require_once dirname( __FILE__ ) . '/class-custom-javascript-control.php';
$custom_javascript_setting = new Soderlind_Customize_Custom_JavaScript_Setting(
$wp_customize,
sprintf( 'custom_javascript[%s]', get_stylesheet() ),
[
'capability' => 'unfiltered_html',
'default' => default_js_template(),
]
);
$wp_customize->add_setting( $custom_javascript_setting );
$control = new \WP_Customize_Code_Editor_Control(
$wp_customize,
'custom_javascript',
[
'label' => 'Custom Javascript',
'code_type' => 'application/javascript',
'settings' => [ 'default' => $custom_javascript_setting->id ],
'section' => 'custom_javascript', // Site Identity section
]
);
$wp_customize->add_control( $control );
}
/**
* Fetch the `custom_javascript` post for a given theme.
*
* @since 4.7.0
*
* @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
* @return WP_Post|null The custom_javascript post or null if none exists.
*/
function soderlind_get_custom_javascript_post( string $stylesheet = '' ) {
if ( empty( $stylesheet ) ) {
$stylesheet = get_stylesheet();
}
$custom_javascript_query_vars = [
'post_type' => 'custom_javascript',
'post_status' => get_post_stati(),
'name' => sanitize_title( $stylesheet ),
'posts_per_page' => 1,
'no_found_rows' => true,
'cache_results' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'lazy_load_term_meta' => false,
];
$post = null;
if ( get_stylesheet() === $stylesheet ) {
$post_id = get_theme_mod( 'custom_javascript_post_id' );
if ( $post_id > 0 && get_post( $post_id ) ) {
$post = get_post( $post_id );
}
// `-1` indicates no post exists; no query necessary.
if ( ! $post && -1 !== $post_id ) {
$query = new \WP_Query( $custom_javascript_query_vars );
$post = $query->post;
/*
* Cache the lookup. See soderlind_update_custom_javascript_post().
* @todo This should get cleared if a custom_javascript post is added/removed.
*/
set_theme_mod( 'custom_javascript_post_id', $post ? $post->ID : -1 );
}
} else {
$query = new \WP_Query( $custom_javascript_query_vars );
$post = $query->post;
}
return $post;
}
/**
* Fetch the saved Custom JavaScript content for rendering.
*
* @since 4.7.0
*
* @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
* @return string The Custom JavaScript Post content.
*/
function soderlind_get_custom_javascript( $stylesheet = '' ) {
$javascript = '';
if ( empty( $stylesheet ) ) {
$stylesheet = get_stylesheet();
}
$post = soderlind_get_custom_javascript_post( $stylesheet );
if ( $post ) {
$javascript = $post->post_content;
}
/**
* Filters the Custom JavaScript Output into the <head>.
*
* @since 4.7.0
*
* @param string $javascript JavaScript pulled in from the Custom JavaScript CPT.
* @param string $stylesheet The theme stylesheet name.
*/
$javascript = apply_filters( 'soderlind_get_custom_javascript', $javascript, $stylesheet );
return $javascript;
}
/**
* Update the `custom_javascript` post for a given theme.
*
* Inserts a `custom_javascript` post when one doesn't yet exist.
*
* @since 4.7.0
*
* @param string $javascript JavaScript, stored in `post_content`.
* @param array $args {
* Args.
*
* @type string $preprocessed Pre-processed JavaScript, stored in `post_content_filtered`. Normally empty string. Optional.
* @type string $stylesheet Stylesheet (child theme) to update. Optional, defaults to current theme/stylesheet.
* }
* @return WP_Post|WP_Error Post on success, error on failure.
*/
function soderlind_update_custom_javascript_post( $javascript, $args = [] ) {
$args = wp_parse_args(
$args,
[
'preprocessed' => '',
'stylesheet' => get_stylesheet(),
]
);
$data = [
'javascript' => $javascript,
'preprocessed' => $args[ 'preprocessed' ],
];
/**
* Filters the `javascript` (`post_content`) and `preprocessed` (`post_content_filtered`) args for a `custom_javascript` post being updated.
*
* This filter can be used by plugin that offer JavaScript pre-processors, to store the original
* pre-processed JavaScript in `post_content_filtered` and then store processed JavaScript in `post_content`.
* When used in this way, the `post_content_filtered` should be supplied as the setting value
* instead of `post_content` via a the `customize_value_custom_javascript` filter, for example:
*
* <code>
* add_filter( 'customize_value_custom_javascript', function( $value, $setting ) {
* $post = soderlind_get_custom_javascript_post( $setting->stylesheet );
* if ( $post && ! empty( $post->post_content_filtered ) ) {
* $javascript = $post->post_content_filtered;
* }
* return $javascript;
* }, 10, 2 );
* </code>
*
* @since 4.7.0
* @param array $data {
* Custom JavaScript data.
*
* @type string $javascript JavaScript stored in `post_content`.
* @type string $preprocessed Pre-processed JavaScript stored in `post_content_filtered`. Normally empty string.
* }
* @param array $args {
* The args passed into `wp_update_custom_javascript_post()` merged with defaults.
*
* @type string $javascript The original JavaScript passed in to be updated.
* @type string $preprocessed The original preprocessed JavaScript passed in to be updated.
* @type string $stylesheet The stylesheet (theme) being updated.
* }
*/
$data = apply_filters( 'soderlind_update_custom_javascript_data', $data, array_merge( $args, compact( 'javascript' ) ) );
$post_data = [
'post_title' => $args[ 'stylesheet' ],
'post_name' => sanitize_title( $args[ 'stylesheet' ] ),
'post_type' => 'custom_javascript',
'post_status' => 'publish',
'post_content' => $data[ 'javascript' ],
'post_content_filtered' => $data[ 'preprocessed' ],
];
// Update post if it already exists, otherwise create a new one.
$post = soderlind_get_custom_javascript_post( $args[ 'stylesheet' ] );
if ( $post ) {
$post_data[ 'ID' ] = $post->ID;
$r = wp_update_post( wp_slash( $post_data ), true );
} else {
$r = wp_insert_post( wp_slash( $post_data ), true );
if ( ! is_wp_error( $r ) ) {
if ( get_stylesheet() === $args[ 'stylesheet' ] ) {
set_theme_mod( 'custom_javascript_post_id', $r );
}
// Trigger creation of a revision. This should be removed once #30854 is resolved.
if ( 0 === count( wp_get_post_revisions( $r ) ) ) {
wp_save_post_revision( $r );
}
}
}
if ( is_wp_error( $r ) ) {
return $r;
}
return get_post( $r );
}
/**
* Load script for customizer preview.
*
* @return void
*/
function customize_preview_additional_javascript() {
$handle = 'additional-javascript-preview';
$src = plugins_url( '/js/additional-javascript-preview.js', __FILE__ );
$deps = [ 'customize-preview' ];
if ( file_exists( plugin_dir_path( __FILE__ ) . 'js/additional-javascript-preview.js' ) ) {
wp_enqueue_script( $handle, $src, $deps, ADDITIONAL_JAVASCRIPT_VERSION, true );
}
}
/**
* Load styles for customizer control.
*
* @return void
*/
function on_customize_controls_enqueue_scripts() {
$suffix = is_rtl() ? '-rtl' : '';
$handle = 'additional-javascript-controls' . $suffix;
$src = plugins_url( "/css/customize-controls-custom-javascript{$suffix}.css", __FILE__ );
$deps = [ 'customize-controls' ];
if ( file_exists( plugin_dir_path( __FILE__ ) . "css/customize-controls-custom-javascript{$suffix}.css" ) ) {
wp_enqueue_style( $handle, $src, $deps, ADDITIONAL_JAVASCRIPT_VERSION );
}
}