Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

588 righe
14 KiB

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