Make WordPress Core

Opened 9 years ago

Closed 9 years ago

#2701 closed defect (bug) (fixed)

Centralize javascript inclusions

Reported by: mdawaffe Owned by: mdawaffe
Milestone: 2.1 Priority: normal
Severity: normal Version: 2.1
Component: General Keywords: javascript bg|has-patch bg|2nd-opinion bg|dev-feedback
Focuses: Cc:


WP should provide a built in means of including javascript files and their dependencies. This has been discussed on wp-hackers at least twice (most recently: http://comox.textdrive.com/pipermail/wp-hackers/2006-April/005917.html).

The attached patch establishes a method to define and use WP javascript, reworks the admin section to make use of this method, and calls this method both in admin-header.php and in the wp_head hook. The patch keeps track of all scripts and their dependencies, which scripts are slated for inclusion on the page, and which scripts have already been included on the page.

Perhaps a little overkill.

Attachments (10)

2701.diff (12.5 KB) - added by mdawaffe 9 years ago.
WP_Scripts class
2701b.diff (13.7 KB) - added by mdawaffe 9 years ago.
Good suggestions from skeltoac
2701c.diff (17.1 KB) - added by mdawaffe 9 years ago.
absolute links. Better dependencies check
2701d.diff (17.2 KB) - added by mdawaffe 9 years ago.
Just say no to array_combine(). Fixes bug found by ryanscheuermann.
2701e.diff (17.2 KB) - added by mdawaffe 9 years ago.
2701f.diff (18.1 KB) - added by mdawaffe 9 years ago.
2701g.diff (24.5 KB) - added by mdawaffe 9 years ago.
Allow parameter passing to scripts
2701h.diff (414 bytes) - added by mdawaffe 9 years ago.
Fix for call from wp_head
2701i.patch (572 bytes) - added by arnee 9 years ago.
Allow plugins to use DBX
2701j.diff (442 bytes) - added by mdawaffe 9 years ago.
Better fix for wp_head. Replaces 2701h.diff.

Download all attachments as: .zip

Change History (33)

@mdawaffe9 years ago

WP_Scripts class

comment:1 @mdawaffe9 years ago

  • Status changed from new to assigned

Forgot to mention that the patch also adds ?version=$wp_db_version to all the src attributes. A different method of cache busting could easily be swapped in.

comment:2 @skeltoac9 years ago


On cache busting, I wouldn't count on the db_version bumping the scripts on a bugfix release. How about this: Each script can have its own version number as an optional argument to the add method, then fall back on db_version.

Also, we have TinyMCE accepting ?ver= and passing that on when it loads its scripts and dialogs. So if you're going to change it to version you have to change TinyMCE as well. I'd stick with ver.

comment:3 @mdawaffe9 years ago

Thanks for the pointer about TinyMCE and ver. I've deprecated tinymce_include() and taken your suggestions for cache busting in the new patch.


  1. Optional version parameter in the addition functions.
  2. Native scripts have all been given versions. I used real version numbers where provided, real version numbers . _changeset where necessary, and changeset otherwise. I kept the date based version on TinyMCE. Whether we use dates or changesets for anything in the future won't matter. The changesets were easier to find, is all.
  3. src="blah?ver=( $script->ver ? $script->ver : $wp_db_version )"

@mdawaffe9 years ago

Good suggestions from skeltoac

comment:4 @skeltoac9 years ago

Changesets are better than dates as long as the committer sets them correctly. The patch writer doesn't know what the changeset will be, so should bump to a guessed number and make note in the ticket for the committer.

comment:5 @mdawaffe9 years ago

As an aside, this offers a nice pluggable way to disable scripts that pose accessibility concerns.

Plugin Name:  AJAX b0rked my screen reader.

add_action( 'wp_print_scripts', 'no_ajax' );

function no_ajax() {
 global $current_user;
 if ( $current_user->data->no_ajax )
  wp_deregister_script( 'sack' );

With this in mind, we should rewrite the printer such that it doesn't include JS with missing dependencies. That way, the plugin wouldn't have to try and non-robustly do wp_deregister_script( 'sack', 'ajaxcat', ... );, and the user wouldn't get a lot of JS errors.

@mdawaffe9 years ago

absolute links. Better dependencies check

comment:6 @mdawaffe9 years ago


  1. Absolute paths may be needed by some.
  2. Do not load scripts with missing (i.e. unregistered) dependencies.
  3. wp_print_scripts hook should fire first thing since wp_print_scripts() doesn't instantiate $wp_scripts.
  4. Some inline docs for the recursive or otherwise confusing functions.

comment:7 @mdawaffe9 years ago

  • Keywords bg|dev-feedback added

comment:8 @ryanscheuermann9 years ago

I've installed this patch, and I must say, this is some fine work. Definitely digging the dependencies, and the fact that plugins can call wp_print_scripts without worrying about whether or not it's already there.

As far as I can tell, everything seems to be functioning correctly. Still testing it, though.

Maybe one small suggestion: move the WP_Scripts and _WP_Script classes to classes.php?

comment:9 @ryanscheuermann9 years ago

OK, found a bug: WP_Scripts->all_deps() uses array_combine which is only available in PHP5 :-(


@mdawaffe9 years ago

Just say no to array_combine(). Fixes bug found by ryanscheuermann.

comment:10 @mdawaffe9 years ago

Good call. Thanks.


  1. Ditch array_combine(). Use something less complicated.

@mdawaffe9 years ago


comment:11 @mdawaffe9 years ago

As for the best place for the classes, I don't know. classes.php is fine, if that's where people want them.


  1. Oops: stray var_dump() fixed.

comment:12 @ryan9 years ago

This only needs to be loaded for the admin, right? I think it only needs to be loaded when admin-header.php is loaded. Maybe add WP_Scripts and friends to wp-admin/script-loader.php and include it from admin-header.php.

comment:13 @mdawaffe9 years ago

Ideally, people could use it to deal with JS in their themes and plugins as well. It gets called by the wp_head hook.

comment:14 @ryan9 years ago

Okay. How about putting the class and the wrapper functions into wp-includes/script-loader.php or something like that?

@mdawaffe9 years ago


comment:15 @mdawaffe9 years ago


  1. Move classes and wrappers to wp-includes/script-loader.php
  2. require script-loader.php from wp-settings.php
  3. Move tinymce_include to wp-includes/deprecated.php

comment:16 @mdawaffe9 years ago

If we allow query string like parameters to be passed through the enqueuers and printers, we can get rid of a lot of the inline JS. Everybody likes browser caching!


  1. Allow things like wp_enqueue_script( 'script?foo=bar' ) that calls script.js?ver=3000&foo=bar.
  2. Do this for the dbx stuff. Doesn't admin-header.php look pretty now?

This will give plugins a much better means of customizing the admin panels. Currently, a lot of WP's decisions to include or not include various JS bits is not accessible. Also, it's a nice resource for themes and "front-face" plugins.

@mdawaffe9 years ago

Allow parameter passing to scripts

comment:17 @ryanscheuermann9 years ago

Hey mdawaffe, first test found 1 small bug. dbx-admin-key-js.php needs to add 'link.php' to its test case:

	case 'link-add.php' :
	case 'link.php':
              $man = 'linkmeta';

Otherwise, when I edit a bookmark, I get a DBX error about an invalid session ID.

@mdawaffe9 years ago

Fix for call from wp_head

comment:19 @mdawaffe9 years ago

The wp_head hook passes an empty string to wp_print_scripts() which breaks the script loader since various pieces test that value for identicality with false (not equality).


  1. Fix for call from wp_head.

comment:20 @arnee9 years ago

Please allow plugins to use DBX. Patch for dbx-admin-key-js.php attached.

@arnee9 years ago

Allow plugins to use DBX

comment:21 @mdawaffe9 years ago

arnee, I had assumed that plugins would just create their own dbx-key javascript to register and enqueue (de-registering or dequeuing the normal dbx-key if necessary).

I suppose plugins which use the same DBX groupings as the core does (something I had not considered) would benefit from your patch.

@mdawaffe9 years ago

Better fix for wp_head. Replaces 2701h.diff.

comment:22 @mdawaffe9 years ago


  1. Fix call from wp_head. A slightly better patch than 2701h.diff.

arnee, I'm not sure of the security implications of allowing arbitrary JS injection (albeit from a restricted set of users).

So -1 to 2701i.diff. Plugins can register their own dbx-key JS as separate files.

comment:23 @ryan9 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

(In [4105]) script loader fix from mdawaffe. fixes #2701

Note: See TracTickets for help on using tickets.