/wp-includes/class.wp-scripts.php

  1. <?php 
  2. /** 
  3. * Dependencies API: WP_Scripts class 
  4. * 
  5. * @since 2.6.0 
  6. * 
  7. * @package WordPress 
  8. * @subpackage Dependencies 
  9. */ 
  10.  
  11. /** 
  12. * Core class used to register scripts. 
  13. * 
  14. * @package WordPress 
  15. * @uses WP_Dependencies 
  16. * @since 2.1.0 
  17. */ 
  18. class WP_Scripts extends WP_Dependencies { 
  19. /** 
  20. * Base URL for scripts. 
  21. * 
  22. * Full URL with trailing slash. 
  23. * 
  24. * @since 2.6.0 
  25. * @access public 
  26. * @var string 
  27. */ 
  28. public $base_url; 
  29.  
  30. /** 
  31. * URL of the content directory. 
  32. * 
  33. * @since 2.8.0 
  34. * @access public 
  35. * @var string 
  36. */ 
  37. public $content_url; 
  38.  
  39. /** 
  40. * Default version string for stylesheets. 
  41. * 
  42. * @since 2.6.0 
  43. * @access public 
  44. * @var string 
  45. */ 
  46. public $default_version; 
  47.  
  48. /** 
  49. * Holds handles of scripts which are enqueued in footer. 
  50. * 
  51. * @since 2.8.0 
  52. * @access public 
  53. * @var array 
  54. */ 
  55. public $in_footer = array(); 
  56.  
  57. /** 
  58. * Holds a list of script handles which will be concatenated. 
  59. * 
  60. * @since 2.8.0 
  61. * @access public 
  62. * @var string 
  63. */ 
  64. public $concat = ''; 
  65.  
  66. /** 
  67. * Holds a string which contains script handles and their version. 
  68. * 
  69. * @since 2.8.0 
  70. * @deprecated 3.4.0 
  71. * @access public 
  72. * @var string 
  73. */ 
  74. public $concat_version = ''; 
  75.  
  76. /** 
  77. * Whether to perform concatenation. 
  78. * 
  79. * @since 2.8.0 
  80. * @access public 
  81. * @var bool 
  82. */ 
  83. public $do_concat = false; 
  84.  
  85. /** 
  86. * Holds HTML markup of scripts and additional data if concatenation 
  87. * is enabled. 
  88. * 
  89. * @since 2.8.0 
  90. * @access public 
  91. * @var string 
  92. */ 
  93. public $print_html = ''; 
  94.  
  95. /** 
  96. * Holds inline code if concatenation is enabled. 
  97. * 
  98. * @since 2.8.0 
  99. * @access public 
  100. * @var string 
  101. */ 
  102. public $print_code = ''; 
  103.  
  104. /** 
  105. * Holds a list of script handles which are not in the default directory 
  106. * if concatenation is enabled. 
  107. * 
  108. * Unused in core. 
  109. * 
  110. * @since 2.8.0 
  111. * @access public 
  112. * @var string 
  113. */ 
  114. public $ext_handles = ''; 
  115.  
  116. /** 
  117. * Holds a string which contains handles and versions of scripts which 
  118. * are not in the default directory if concatenation is enabled. 
  119. * 
  120. * Unused in core. 
  121. * 
  122. * @since 2.8.0 
  123. * @access public 
  124. * @var string 
  125. */ 
  126. public $ext_version = ''; 
  127.  
  128. /** 
  129. * List of default directories. 
  130. * 
  131. * @since 2.8.0 
  132. * @access public 
  133. * @var array 
  134. */ 
  135. public $default_dirs; 
  136.  
  137. /** 
  138. * Constructor. 
  139. * 
  140. * @since 2.6.0 
  141. * @access public 
  142. */ 
  143. public function __construct() { 
  144. $this->init(); 
  145. add_action( 'init', array( $this, 'init' ), 0 ); 
  146.  
  147. /** 
  148. * Initialize the class. 
  149. * 
  150. * @since 3.4.0 
  151. * @access public 
  152. */ 
  153. public function init() { 
  154. /** 
  155. * Fires when the WP_Scripts instance is initialized. 
  156. * 
  157. * @since 2.6.0 
  158. * 
  159. * @param WP_Scripts &$this WP_Scripts instance, passed by reference. 
  160. */ 
  161. do_action_ref_array( 'wp_default_scripts', array(&$this) ); 
  162.  
  163. /** 
  164. * Prints scripts. 
  165. * 
  166. * Prints the scripts passed to it or the print queue. Also prints all necessary dependencies. 
  167. * 
  168. * @since 2.1.0 
  169. * @since 2.8.0 Added the `$group` parameter. 
  170. * @access public 
  171. * 
  172. * @param mixed $handles Optional. Scripts to be printed. (void) prints queue, (string) prints 
  173. * that script, (array of strings) prints those scripts. Default false. 
  174. * @param int $group Optional. If scripts were queued in groups prints this group number. 
  175. * Default false. 
  176. * @return array Scripts that have been printed. 
  177. */ 
  178. public function print_scripts( $handles = false, $group = false ) { 
  179. return $this->do_items( $handles, $group ); 
  180.  
  181. /** 
  182. * Prints extra scripts of a registered script. 
  183. * 
  184. * @since 2.1.0 
  185. * @since 2.8.0 Added the `$echo` parameter. 
  186. * @deprecated 3.3.0 
  187. * @access public 
  188. * 
  189. * @see print_extra_script() 
  190. * 
  191. * @param string $handle The script's registered handle. 
  192. * @param bool $echo Optional. Whether to echo the extra script instead of just returning it. 
  193. * Default true. 
  194. * @return bool|string|void Void if no data exists, extra scripts if `$echo` is true, true otherwise. 
  195. */ 
  196. public function print_scripts_l10n( $handle, $echo = true ) { 
  197. _deprecated_function( __FUNCTION__, '3.3.0', 'print_extra_script()' ); 
  198. return $this->print_extra_script( $handle, $echo ); 
  199.  
  200. /** 
  201. * Prints extra scripts of a registered script. 
  202. * 
  203. * @since 3.3.0 
  204. * @access public 
  205. * 
  206. * @param string $handle The script's registered handle. 
  207. * @param bool $echo Optional. Whether to echo the extra script instead of just returning it. 
  208. * Default true. 
  209. * @return bool|string|void Void if no data exists, extra scripts if `$echo` is true, true otherwise. 
  210. */ 
  211. public function print_extra_script( $handle, $echo = true ) { 
  212. if ( !$output = $this->get_data( $handle, 'data' ) ) 
  213. return; 
  214.  
  215. if ( !$echo ) 
  216. return $output; 
  217.  
  218. echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5 
  219. echo "/* <![CDATA[ */\n"; 
  220. echo "$output\n"; 
  221. echo "/* ]]> */\n"; 
  222. echo "</script>\n"; 
  223.  
  224. return true; 
  225.  
  226. /** 
  227. * Processes a script dependency. 
  228. * 
  229. * @since 2.6.0 
  230. * @since 2.8.0 Added the `$group` parameter. 
  231. * @access public 
  232. * 
  233. * @see WP_Dependencies::do_item() 
  234. * 
  235. * @param string $handle The script's registered handle. 
  236. * @param int|false $group Optional. Group level: (int) level, (false) no groups. Default false. 
  237. * @return bool True on success, false on failure. 
  238. */ 
  239. public function do_item( $handle, $group = false ) { 
  240. if ( !parent::do_item($handle) ) 
  241. return false; 
  242.  
  243. if ( 0 === $group && $this->groups[$handle] > 0 ) { 
  244. $this->in_footer[] = $handle; 
  245. return false; 
  246.  
  247. if ( false === $group && in_array($handle, $this->in_footer, true) ) 
  248. $this->in_footer = array_diff( $this->in_footer, (array) $handle ); 
  249.  
  250. $obj = $this->registered[$handle]; 
  251.  
  252. if ( null === $obj->ver ) { 
  253. $ver = ''; 
  254. } else { 
  255. $ver = $obj->ver ? $obj->ver : $this->default_version; 
  256.  
  257. if ( isset($this->args[$handle]) ) 
  258. $ver = $ver ? $ver . '&' . $this->args[$handle] : $this->args[$handle]; 
  259.  
  260. $src = $obj->src; 
  261. $cond_before = $cond_after = ''; 
  262. $conditional = isset( $obj->extra['conditional'] ) ? $obj->extra['conditional'] : ''; 
  263.  
  264. if ( $conditional ) { 
  265. $cond_before = "<!--[if {$conditional}]>\n"; 
  266. $cond_after = "<![endif]-->\n"; 
  267.  
  268. $before_handle = $this->print_inline_script( $handle, 'before', false ); 
  269. $after_handle = $this->print_inline_script( $handle, 'after', false ); 
  270.  
  271. if ( $before_handle ) { 
  272. $before_handle = sprintf( "<script type='text/javascript'>\n%s\n</script>\n", $before_handle ); 
  273.  
  274. if ( $after_handle ) { 
  275. $after_handle = sprintf( "<script type='text/javascript'>\n%s\n</script>\n", $after_handle ); 
  276.  
  277. if ( $this->do_concat ) { 
  278. /** 
  279. * Filters the script loader source. 
  280. * 
  281. * @since 2.2.0 
  282. * 
  283. * @param string $src Script loader source path. 
  284. * @param string $handle Script handle. 
  285. */ 
  286. $srce = apply_filters( 'script_loader_src', $src, $handle ); 
  287.  
  288. if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle ) ) { 
  289. $this->do_concat = false; 
  290.  
  291. // Have to print the so-far concatenated scripts right away to maintain the right order. 
  292. _print_scripts(); 
  293. $this->reset(); 
  294. } elseif ( $this->in_default_dir( $srce ) && ! $conditional ) { 
  295. $this->print_code .= $this->print_extra_script( $handle, false ); 
  296. $this->concat .= "$handle, "; 
  297. $this->concat_version .= "$handle$ver"; 
  298. return true; 
  299. } else { 
  300. $this->ext_handles .= "$handle, "; 
  301. $this->ext_version .= "$handle$ver"; 
  302.  
  303. $has_conditional_data = $conditional && $this->get_data( $handle, 'data' ); 
  304.  
  305. if ( $has_conditional_data ) { 
  306. echo $cond_before; 
  307.  
  308. $this->print_extra_script( $handle ); 
  309.  
  310. if ( $has_conditional_data ) { 
  311. echo $cond_after; 
  312.  
  313. // A single item may alias a set of items, by having dependencies, but no source. 
  314. if ( ! $obj->src ) { 
  315. return true; 
  316.  
  317. if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) { 
  318. $src = $this->base_url . $src; 
  319.  
  320. if ( ! empty( $ver ) ) 
  321. $src = add_query_arg( 'ver', $ver, $src ); 
  322.  
  323. /** This filter is documented in wp-includes/class.wp-scripts.php */ 
  324. $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) ); 
  325.  
  326. if ( ! $src ) 
  327. return true; 
  328.  
  329. $tag = "{$cond_before}{$before_handle}<script type='text/javascript' src='$src'></script>\n{$after_handle}{$cond_after}"; 
  330.  
  331. /** 
  332. * Filters the HTML script tag of an enqueued script. 
  333. * 
  334. * @since 4.1.0 
  335. * 
  336. * @param string $tag The `<script>` tag for the enqueued script. 
  337. * @param string $handle The script's registered handle. 
  338. * @param string $src The script's source URL. 
  339. */ 
  340. $tag = apply_filters( 'script_loader_tag', $tag, $handle, $src ); 
  341.  
  342. if ( $this->do_concat ) { 
  343. $this->print_html .= $tag; 
  344. } else { 
  345. echo $tag; 
  346.  
  347. return true; 
  348.  
  349. /** 
  350. * Adds extra code to a registered script. 
  351. * 
  352. * @since 4.5.0 
  353. * @access public 
  354. * 
  355. * @param string $handle Name of the script to add the inline script to. Must be lowercase. 
  356. * @param string $data String containing the javascript to be added. 
  357. * @param string $position Optional. Whether to add the inline script before the handle 
  358. * or after. Default 'after'. 
  359. * @return bool True on success, false on failure. 
  360. */ 
  361. public function add_inline_script( $handle, $data, $position = 'after' ) { 
  362. if ( ! $data ) { 
  363. return false; 
  364.  
  365. if ( 'after' !== $position ) { 
  366. $position = 'before'; 
  367.  
  368. $script = (array) $this->get_data( $handle, $position ); 
  369. $script[] = $data; 
  370.  
  371. return $this->add_data( $handle, $position, $script ); 
  372.  
  373. /** 
  374. * Prints inline scripts registered for a specific handle. 
  375. * 
  376. * @since 4.5.0 
  377. * @access public 
  378. * 
  379. * @param string $handle Name of the script to add the inline script to. Must be lowercase. 
  380. * @param string $position Optional. Whether to add the inline script before the handle 
  381. * or after. Default 'after'. 
  382. * @param bool $echo Optional. Whether to echo the script instead of just returning it. 
  383. * Default true. 
  384. * @return string|false Script on success, false otherwise. 
  385. */ 
  386. public function print_inline_script( $handle, $position = 'after', $echo = true ) { 
  387. $output = $this->get_data( $handle, $position ); 
  388.  
  389. if ( empty( $output ) ) { 
  390. return false; 
  391.  
  392. $output = trim( implode( "\n", $output ), "\n" ); 
  393.  
  394. if ( $echo ) { 
  395. printf( "<script type='text/javascript'>\n%s\n</script>\n", $output ); 
  396.  
  397. return $output; 
  398.  
  399. /** 
  400. * Localizes a script, only if the script has already been added. 
  401. * 
  402. * @since 2.1.0 
  403. * @access public 
  404. * 
  405. * @param string $handle 
  406. * @param string $object_name 
  407. * @param array $l10n 
  408. * @return bool 
  409. */ 
  410. public function localize( $handle, $object_name, $l10n ) { 
  411. if ( $handle === 'jquery' ) 
  412. $handle = 'jquery-core'; 
  413.  
  414. if ( is_array($l10n) && isset($l10n['l10n_print_after']) ) { // back compat, preserve the code in 'l10n_print_after' if present 
  415. $after = $l10n['l10n_print_after']; 
  416. unset($l10n['l10n_print_after']); 
  417.  
  418. foreach ( (array) $l10n as $key => $value ) { 
  419. if ( !is_scalar($value) ) 
  420. continue; 
  421.  
  422. $l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8'); 
  423.  
  424. $script = "var $object_name = " . wp_json_encode( $l10n ) . ';'; 
  425.  
  426. if ( !empty($after) ) 
  427. $script .= "\n$after;"; 
  428.  
  429. $data = $this->get_data( $handle, 'data' ); 
  430.  
  431. if ( !empty( $data ) ) 
  432. $script = "$data\n$script"; 
  433.  
  434. return $this->add_data( $handle, 'data', $script ); 
  435.  
  436. /** 
  437. * Sets handle group. 
  438. * 
  439. * @since 2.8.0 
  440. * @access public 
  441. * 
  442. * @see WP_Dependencies::set_group() 
  443. * 
  444. * @param string $handle Name of the item. Should be unique. 
  445. * @param bool $recursion Internal flag that calling function was called recursively. 
  446. * @param int|false $group Optional. Group level: (int) level, (false) no groups. Default false. 
  447. * @return bool Not already in the group or a lower group 
  448. */ 
  449. public function set_group( $handle, $recursion, $group = false ) { 
  450. if ( isset( $this->registered[$handle]->args ) && $this->registered[$handle]->args === 1 ) 
  451. $grp = 1; 
  452. else 
  453. $grp = (int) $this->get_data( $handle, 'group' ); 
  454.  
  455. if ( false !== $group && $grp > $group ) 
  456. $grp = $group; 
  457.  
  458. return parent::set_group( $handle, $recursion, $grp ); 
  459.  
  460. /** 
  461. * Determines script dependencies. 
  462. * 
  463. * @since 2.1.0 
  464. * @access public 
  465. * 
  466. * @see WP_Dependencies::all_deps() 
  467. * 
  468. * @param mixed $handles Item handle and argument (string) or item handles and arguments (array of strings). 
  469. * @param bool $recursion Internal flag that function is calling itself. 
  470. * @param int|false $group Optional. Group level: (int) level, (false) no groups. Default false. 
  471. * @return bool True on success, false on failure. 
  472. */ 
  473. public function all_deps( $handles, $recursion = false, $group = false ) { 
  474. $r = parent::all_deps( $handles, $recursion, $group ); 
  475. if ( ! $recursion ) { 
  476. /** 
  477. * Filters the list of script dependencies left to print. 
  478. * 
  479. * @since 2.3.0 
  480. * 
  481. * @param array $to_do An array of script dependencies. 
  482. */ 
  483. $this->to_do = apply_filters( 'print_scripts_array', $this->to_do ); 
  484. return $r; 
  485.  
  486. /** 
  487. * Processes items and dependencies for the head group. 
  488. * 
  489. * @since 2.8.0 
  490. * @access public 
  491. * 
  492. * @see WP_Dependencies::do_items() 
  493. * 
  494. * @return array Handles of items that have been processed. 
  495. */ 
  496. public function do_head_items() { 
  497. $this->do_items(false, 0); 
  498. return $this->done; 
  499.  
  500. /** 
  501. * Processes items and dependencies for the footer group. 
  502. * 
  503. * @since 2.8.0 
  504. * @access public 
  505. * 
  506. * @see WP_Dependencies::do_items() 
  507. * 
  508. * @return array Handles of items that have been processed. 
  509. */ 
  510. public function do_footer_items() { 
  511. $this->do_items(false, 1); 
  512. return $this->done; 
  513.  
  514. /** 
  515. * Whether a handle's source is in a default directory. 
  516. * 
  517. * @since 2.8.0 
  518. * @access public 
  519. * 
  520. * @param string $src The source of the enqueued script. 
  521. * @return bool True if found, false if not. 
  522. */ 
  523. public function in_default_dir( $src ) { 
  524. if ( ! $this->default_dirs ) { 
  525. return true; 
  526.  
  527. if ( 0 === strpos( $src, '/' . WPINC . '/js/l10n' ) ) { 
  528. return false; 
  529.  
  530. foreach ( (array) $this->default_dirs as $test ) { 
  531. if ( 0 === strpos( $src, $test ) ) { 
  532. return true; 
  533. return false; 
  534.  
  535. /** 
  536. * Resets class properties. 
  537. * 
  538. * @since 2.8.0 
  539. * @access public 
  540. */ 
  541. public function reset() { 
  542. $this->do_concat = false; 
  543. $this->print_code = ''; 
  544. $this->concat = ''; 
  545. $this->concat_version = ''; 
  546. $this->print_html = ''; 
  547. $this->ext_version = ''; 
  548. $this->ext_handles = ''; 
.