functions.wp-scripts.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. <?php
  2. /**
  3. * Dependencies API: Scripts functions
  4. *
  5. * @since 2.6.0
  6. *
  7. * @package WordPress
  8. * @subpackage Dependencies
  9. */
  10. /**
  11. * Initialize $wp_scripts if it has not been set.
  12. *
  13. * @global WP_Scripts $wp_scripts
  14. *
  15. * @since 4.2.0
  16. *
  17. * @return WP_Scripts WP_Scripts instance.
  18. */
  19. function wp_scripts() {
  20. global $wp_scripts;
  21. if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  22. $wp_scripts = new WP_Scripts();
  23. }
  24. return $wp_scripts;
  25. }
  26. /**
  27. * Helper function to output a _doing_it_wrong message when applicable.
  28. *
  29. * @ignore
  30. * @since 4.2.0
  31. * @since 5.5.0 Added the `$handle` parameter.
  32. *
  33. * @param string $function Function name.
  34. * @param string $handle Optional. Name of the script or stylesheet that was
  35. * registered or enqueued too early. Default empty.
  36. */
  37. function _wp_scripts_maybe_doing_it_wrong( $function, $handle = '' ) {
  38. if ( did_action( 'init' ) || did_action( 'wp_enqueue_scripts' )
  39. || did_action( 'admin_enqueue_scripts' ) || did_action( 'login_enqueue_scripts' )
  40. ) {
  41. return;
  42. }
  43. $message = sprintf(
  44. /* translators: 1: wp_enqueue_scripts, 2: admin_enqueue_scripts, 3: login_enqueue_scripts */
  45. __( 'Scripts and styles should not be registered or enqueued until the %1$s, %2$s, or %3$s hooks.' ),
  46. '<code>wp_enqueue_scripts</code>',
  47. '<code>admin_enqueue_scripts</code>',
  48. '<code>login_enqueue_scripts</code>'
  49. );
  50. if ( $handle ) {
  51. $message .= ' ' . sprintf(
  52. /* translators: %s: Name of the script or stylesheet. */
  53. __( 'This notice was triggered by the %s handle.' ),
  54. '<code>' . $handle . '</code>'
  55. );
  56. }
  57. _doing_it_wrong(
  58. $function,
  59. $message,
  60. '3.3.0'
  61. );
  62. }
  63. /**
  64. * Prints scripts in document head that are in the $handles queue.
  65. *
  66. * Called by admin-header.php and {@see 'wp_head'} hook. Since it is called by wp_head on every page load,
  67. * the function does not instantiate the WP_Scripts object unless script names are explicitly passed.
  68. * Makes use of already-instantiated $wp_scripts global if present. Use provided {@see 'wp_print_scripts'}
  69. * hook to register/enqueue new scripts.
  70. *
  71. * @see WP_Scripts::do_item()
  72. * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts.
  73. *
  74. * @since 2.1.0
  75. *
  76. * @param string|bool|array $handles Optional. Scripts to be printed. Default 'false'.
  77. * @return string[] On success, an array of handles of processed WP_Dependencies items; otherwise, an empty array.
  78. */
  79. function wp_print_scripts( $handles = false ) {
  80. global $wp_scripts;
  81. /**
  82. * Fires before scripts in the $handles queue are printed.
  83. *
  84. * @since 2.1.0
  85. */
  86. do_action( 'wp_print_scripts' );
  87. if ( '' === $handles ) { // For 'wp_head'.
  88. $handles = false;
  89. }
  90. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
  91. if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  92. if ( ! $handles ) {
  93. return array(); // No need to instantiate if nothing is there.
  94. }
  95. }
  96. return wp_scripts()->do_items( $handles );
  97. }
  98. /**
  99. * Adds extra code to a registered script.
  100. *
  101. * Code will only be added if the script is already in the queue.
  102. * Accepts a string $data containing the Code. If two or more code blocks
  103. * are added to the same script $handle, they will be printed in the order
  104. * they were added, i.e. the latter added code can redeclare the previous.
  105. *
  106. * @since 4.5.0
  107. *
  108. * @see WP_Scripts::add_inline_script()
  109. *
  110. * @param string $handle Name of the script to add the inline script to.
  111. * @param string $data String containing the JavaScript to be added.
  112. * @param string $position Optional. Whether to add the inline script before the handle
  113. * or after. Default 'after'.
  114. * @return bool True on success, false on failure.
  115. */
  116. function wp_add_inline_script( $handle, $data, $position = 'after' ) {
  117. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  118. if ( false !== stripos( $data, '</script>' ) ) {
  119. _doing_it_wrong(
  120. __FUNCTION__,
  121. sprintf(
  122. /* translators: 1: <script>, 2: wp_add_inline_script() */
  123. __( 'Do not pass %1$s tags to %2$s.' ),
  124. '<code>&lt;script&gt;</code>',
  125. '<code>wp_add_inline_script()</code>'
  126. ),
  127. '4.5.0'
  128. );
  129. $data = trim( preg_replace( '#<script[^>]*>(.*)</script>#is', '$1', $data ) );
  130. }
  131. return wp_scripts()->add_inline_script( $handle, $data, $position );
  132. }
  133. /**
  134. * Register a new script.
  135. *
  136. * Registers a script to be enqueued later using the wp_enqueue_script() function.
  137. *
  138. * @see WP_Dependencies::add()
  139. * @see WP_Dependencies::add_data()
  140. *
  141. * @since 2.1.0
  142. * @since 4.3.0 A return value was added.
  143. *
  144. * @param string $handle Name of the script. Should be unique.
  145. * @param string|false $src Full URL of the script, or path of the script relative to the WordPress root directory.
  146. * If source is set to false, script is an alias of other scripts it depends on.
  147. * @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array.
  148. * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
  149. * as a query string for cache busting purposes. If version is set to false, a version
  150. * number is automatically added equal to current installed WordPress version.
  151. * If set to null, no version is added.
  152. * @param bool $in_footer Optional. Whether to enqueue the script before `</body>` instead of in the `<head>`.
  153. * Default 'false'.
  154. * @return bool Whether the script has been registered. True on success, false on failure.
  155. */
  156. function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) {
  157. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  158. $wp_scripts = wp_scripts();
  159. $registered = $wp_scripts->add( $handle, $src, $deps, $ver );
  160. if ( $in_footer ) {
  161. $wp_scripts->add_data( $handle, 'group', 1 );
  162. }
  163. return $registered;
  164. }
  165. /**
  166. * Localize a script.
  167. *
  168. * Works only if the script has already been registered.
  169. *
  170. * Accepts an associative array $l10n and creates a JavaScript object:
  171. *
  172. * "$object_name" = {
  173. * key: value,
  174. * key: value,
  175. * ...
  176. * }
  177. *
  178. * @see WP_Scripts::localize()
  179. * @link https://core.trac.wordpress.org/ticket/11520
  180. * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts.
  181. *
  182. * @since 2.2.0
  183. *
  184. * @todo Documentation cleanup
  185. *
  186. * @param string $handle Script handle the data will be attached to.
  187. * @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable.
  188. * Example: '/[a-zA-Z0-9_]+/'.
  189. * @param array $l10n The data itself. The data can be either a single or multi-dimensional array.
  190. * @return bool True if the script was successfully localized, false otherwise.
  191. */
  192. function wp_localize_script( $handle, $object_name, $l10n ) {
  193. global $wp_scripts;
  194. if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  195. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  196. return false;
  197. }
  198. return $wp_scripts->localize( $handle, $object_name, $l10n );
  199. }
  200. /**
  201. * Sets translated strings for a script.
  202. *
  203. * Works only if the script has already been registered.
  204. *
  205. * @see WP_Scripts::set_translations()
  206. * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts.
  207. *
  208. * @since 5.0.0
  209. * @since 5.1.0 The `$domain` parameter was made optional.
  210. *
  211. * @param string $handle Script handle the textdomain will be attached to.
  212. * @param string $domain Optional. Text domain. Default 'default'.
  213. * @param string $path Optional. The full file path to the directory containing translation files.
  214. * @return bool True if the text domain was successfully localized, false otherwise.
  215. */
  216. function wp_set_script_translations( $handle, $domain = 'default', $path = '' ) {
  217. global $wp_scripts;
  218. if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  219. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  220. return false;
  221. }
  222. return $wp_scripts->set_translations( $handle, $domain, $path );
  223. }
  224. /**
  225. * Remove a registered script.
  226. *
  227. * Note: there are intentional safeguards in place to prevent critical admin scripts,
  228. * such as jQuery core, from being unregistered.
  229. *
  230. * @see WP_Dependencies::remove()
  231. *
  232. * @since 2.1.0
  233. *
  234. * @global string $pagenow The filename of the current screen.
  235. *
  236. * @param string $handle Name of the script to be removed.
  237. */
  238. function wp_deregister_script( $handle ) {
  239. global $pagenow;
  240. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  241. /**
  242. * Do not allow accidental or negligent de-registering of critical scripts in the admin.
  243. * Show minimal remorse if the correct hook is used.
  244. */
  245. $current_filter = current_filter();
  246. if ( ( is_admin() && 'admin_enqueue_scripts' !== $current_filter ) ||
  247. ( 'wp-login.php' === $pagenow && 'login_enqueue_scripts' !== $current_filter )
  248. ) {
  249. $not_allowed = array(
  250. 'jquery',
  251. 'jquery-core',
  252. 'jquery-migrate',
  253. 'jquery-ui-core',
  254. 'jquery-ui-accordion',
  255. 'jquery-ui-autocomplete',
  256. 'jquery-ui-button',
  257. 'jquery-ui-datepicker',
  258. 'jquery-ui-dialog',
  259. 'jquery-ui-draggable',
  260. 'jquery-ui-droppable',
  261. 'jquery-ui-menu',
  262. 'jquery-ui-mouse',
  263. 'jquery-ui-position',
  264. 'jquery-ui-progressbar',
  265. 'jquery-ui-resizable',
  266. 'jquery-ui-selectable',
  267. 'jquery-ui-slider',
  268. 'jquery-ui-sortable',
  269. 'jquery-ui-spinner',
  270. 'jquery-ui-tabs',
  271. 'jquery-ui-tooltip',
  272. 'jquery-ui-widget',
  273. 'underscore',
  274. 'backbone',
  275. );
  276. if ( in_array( $handle, $not_allowed, true ) ) {
  277. _doing_it_wrong(
  278. __FUNCTION__,
  279. sprintf(
  280. /* translators: 1: Script name, 2: wp_enqueue_scripts */
  281. __( 'Do not deregister the %1$s script in the administration area. To target the front-end theme, use the %2$s hook.' ),
  282. "<code>$handle</code>",
  283. '<code>wp_enqueue_scripts</code>'
  284. ),
  285. '3.6.0'
  286. );
  287. return;
  288. }
  289. }
  290. wp_scripts()->remove( $handle );
  291. }
  292. /**
  293. * Enqueue a script.
  294. *
  295. * Registers the script if $src provided (does NOT overwrite), and enqueues it.
  296. *
  297. * @see WP_Dependencies::add()
  298. * @see WP_Dependencies::add_data()
  299. * @see WP_Dependencies::enqueue()
  300. *
  301. * @since 2.1.0
  302. *
  303. * @param string $handle Name of the script. Should be unique.
  304. * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory.
  305. * Default empty.
  306. * @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array.
  307. * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
  308. * as a query string for cache busting purposes. If version is set to false, a version
  309. * number is automatically added equal to current installed WordPress version.
  310. * If set to null, no version is added.
  311. * @param bool $in_footer Optional. Whether to enqueue the script before `</body>` instead of in the `<head>`.
  312. * Default 'false'.
  313. */
  314. function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $in_footer = false ) {
  315. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  316. $wp_scripts = wp_scripts();
  317. if ( $src || $in_footer ) {
  318. $_handle = explode( '?', $handle );
  319. if ( $src ) {
  320. $wp_scripts->add( $_handle[0], $src, $deps, $ver );
  321. }
  322. if ( $in_footer ) {
  323. $wp_scripts->add_data( $_handle[0], 'group', 1 );
  324. }
  325. }
  326. $wp_scripts->enqueue( $handle );
  327. }
  328. /**
  329. * Remove a previously enqueued script.
  330. *
  331. * @see WP_Dependencies::dequeue()
  332. *
  333. * @since 3.1.0
  334. *
  335. * @param string $handle Name of the script to be removed.
  336. */
  337. function wp_dequeue_script( $handle ) {
  338. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  339. wp_scripts()->dequeue( $handle );
  340. }
  341. /**
  342. * Determines whether a script has been added to the queue.
  343. *
  344. * For more information on this and similar theme functions, check out
  345. * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
  346. * Conditional Tags} article in the Theme Developer Handbook.
  347. *
  348. * @since 2.8.0
  349. * @since 3.5.0 'enqueued' added as an alias of the 'queue' list.
  350. *
  351. * @param string $handle Name of the script.
  352. * @param string $list Optional. Status of the script to check. Default 'enqueued'.
  353. * Accepts 'enqueued', 'registered', 'queue', 'to_do', and 'done'.
  354. * @return bool Whether the script is queued.
  355. */
  356. function wp_script_is( $handle, $list = 'enqueued' ) {
  357. _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle );
  358. return (bool) wp_scripts()->query( $handle, $list );
  359. }
  360. /**
  361. * Add metadata to a script.
  362. *
  363. * Works only if the script has already been registered.
  364. *
  365. * Possible values for $key and $value:
  366. * 'conditional' string Comments for IE 6, lte IE 7, etc.
  367. *
  368. * @since 4.2.0
  369. *
  370. * @see WP_Dependencies::add_data()
  371. *
  372. * @param string $handle Name of the script.
  373. * @param string $key Name of data point for which we're storing a value.
  374. * @param mixed $value String containing the data to be added.
  375. * @return bool True on success, false on failure.
  376. */
  377. function wp_script_add_data( $handle, $key, $value ) {
  378. return wp_scripts()->add_data( $handle, $key, $value );
  379. }