Wordpress 2.3.3
[autoinstalls/wordpress.git] / wp-includes / script-loader.php
1 <?php
2 class WP_Scripts {
3         var $scripts = array();
4         var $queue = array();
5         var $to_print = array();
6         var $printed = array();
7         var $args = array();
8
9         function WP_Scripts() {
10                 $this->default_scripts();
11         }
12
13         function default_scripts() {
14                 $this->add( 'dbx', '/wp-includes/js/dbx.js', false, '2.05' );
15
16                 $this->add( 'fat', '/wp-includes/js/fat.js', false, '1.0-RC1_3660' );
17
18                 $this->add( 'sack', '/wp-includes/js/tw-sack.js', false, '1.6.1' );
19
20                 $this->add( 'quicktags', '/wp-includes/js/quicktags.js', false, '3958' );
21                 $this->localize( 'quicktags', 'quicktagsL10n', array(
22                         'quickLinks' => __('(Quick Links)'),
23                         'wordLookup' => __('Enter a word to look up:'),
24                         'dictionaryLookup' => attribute_escape(__('Dictionary lookup')),
25                         'lookup' => attribute_escape(__('lookup')),
26                         'closeAllOpenTags' => attribute_escape(__('Close all open tags')),
27                         'closeTags' => attribute_escape(__('close tags')),
28                         'enterURL' => __('Enter the URL'),
29                         'enterImageURL' => __('Enter the URL of the image'),
30                         'enterImageDescription' => __('Enter a description of the image')
31                 ) );
32
33                 $this->add( 'colorpicker', '/wp-includes/js/colorpicker.js', false, '3517' );
34
35                 $this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '20070528' );
36                 $mce_config = apply_filters('tiny_mce_config_url', '/wp-includes/js/tinymce/tiny_mce_config.php');
37                 $this->add( 'wp_tiny_mce', $mce_config, array('tiny_mce'), '20070528' );
38
39                 $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.5.1.1');
40
41                 $this->add( 'autosave', '/wp-includes/js/autosave.js', array('prototype', 'sack'), '20070306');
42                 $this->localize( 'autosave', 'autosaveL10n', array(
43                         'autosaveInterval' => apply_filters('autosave_interval', '120'),
44                         'errorText' => __('Error: %response%'),
45                         'saveText' => __('Saved at %time%.'),
46                         'requestFile' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php',
47                         'savingText' => __('Saving Draft...')
48                 ) );
49
50                 $this->add( 'wp-ajax', '/wp-includes/js/wp-ajax.js', array('prototype'), '20070306');
51                 $this->localize( 'wp-ajax', 'WPAjaxL10n', array(
52                         'defaultUrl' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php',
53                         'permText' => __("You don't have permission to do that."),
54                         'strangeText' => __("Something strange happened.  Try refreshing the page."),
55                         'whoaText' => __("Slow down, I'm still sending your data!")
56                 ) );
57
58                 $this->add( 'listman', '/wp-includes/js/list-manipulation.js', array('wp-ajax', 'fat'), '20070306' );
59                 $this->localize( 'listman', 'listManL10n', array(
60                         'jumpText' => __('Jump to new item'),
61                         'delText' => __('Are you sure you want to delete this %thing%?')
62                 ) );
63
64                 $this->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/scriptaculous.js', array('prototype'), '1.7.1-b3');
65                 $this->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.7.1-b3');
66                 $this->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.7.1-b3');
67                 $this->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.7.1-b3');
68                 $this->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.7.1-b3');
69                 $this->add( 'scriptaculous-sound', '/wp-includes/js/scriptaculous/sound.js', array( 'scriptaculous-root' ), '1.7.1-b3' );
70                 $this->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.7.1-b3');
71                 $this->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.7.1-b3');
72
73                 $this->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop'), '20070118');
74
75                 $this->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.1.4');
76                 $this->add( 'jquery-form', '/wp-includes/js/jquery/jquery.form.js', array('jquery'), '1.0.3');
77                 $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2');
78
79                 if ( is_admin() ) {
80                         global $pagenow;
81                         $man = false;
82                         switch ( $pagenow ) :
83                         case 'post.php' :
84                         case 'post-new.php' :
85                                 $man = 'postmeta';
86                                 break;
87                         case 'page.php' :
88                         case 'page-new.php' :
89                                 $man = 'pagemeta';
90                                 break;
91                         case 'link-add.php' :
92                         case 'link.php' :
93                                 $man = 'linkmeta';
94                                 break;
95                         endswitch;
96                         if ( $man ) {
97                                 $this->add( 'dbx-admin-key', '/wp-admin/js/dbx-admin-key.js', array('dbx'), '20070417' );
98                                 $this->localize( 'dbx-admin-key', 'dbxL10n', array(
99                                         'manager' => $man,
100                                         'open' => __('open'),
101                                         'close' => __('close'),
102                                         'moveMouse' => __('click-down and drag to move this box'),
103                                         'toggleMouse' => __('click to %toggle% this box'),
104                                         'moveKey' => __('use the arrow keys to move this box'),
105                                         'toggleKey' => __(', or press the enter key to %toggle% it'),
106                                 ) );
107                         }
108                         $this->add( 'ajaxcat', '/wp-admin/js/cat.js', array('listman'), '20070724' );
109                         $this->localize( 'ajaxcat', 'catL10n', array(
110                                 'add' => attribute_escape(__('Add')),
111                                 'how' => __('Separate multiple categories with commas.')
112                         ) );
113                         $this->add( 'ajaxlinkcat', '/wp-admin/js/link-cat.js', array('listman'), '200700601' );
114                         $this->localize( 'ajaxlinkcat', 'linkcatL10n', array(
115                                 'add' => attribute_escape(__('Add')),
116                                 'how' => __('Separate multiple categories with commas.')
117                         ) );
118                         $this->add( 'admin-categories', '/wp-admin/js/categories.js', array('listman'), '3684' );
119                         $this->add( 'admin-custom-fields', '/wp-admin/js/custom-fields.js', array('listman'), '3733' );
120                         $this->add( 'admin-comments', '/wp-admin/js/edit-comments.js', array('listman'), '20070327' );
121                         $this->add( 'admin-users', '/wp-admin/js/users.js', array('listman'), '4583' );
122                         $this->add( 'xfn', '/wp-admin/js/xfn.js', false, '3517' );
123                         $this->add( 'upload', '/wp-admin/js/upload.js', array('jquery'), '20070518' );
124                         $this->localize( 'upload', 'uploadL10n', array(
125                                 'browseTitle' => attribute_escape(__('Browse your files')),
126                                 'back' => __('&laquo; Back'),
127                                 'directTitle' => attribute_escape(__('Direct link to file')),
128                                 'edit' => __('Edit'),
129                                 'thumb' => __('Thumbnail'),
130                                 'full' => __('Full size'),
131                                 'icon' => __('Icon'),
132                                 'title' => __('Title'),
133                                 'show' => __('Show:'),
134                                 'link' => __('Link to:'),
135                                 'file' => __('File'),
136                                 'page' => __('Page'),
137                                 'none' => __('None'),
138                                 'editorText' => attribute_escape(__('Send to editor &raquo;')),
139                                 'insert' => __('Insert'),
140                                 'urlText' => __('URL'),
141                                 'desc' => __('Description'),
142                                 'deleteText' => attribute_escape(__('Delete File')),
143                                 'saveText' => attribute_escape(__('Save &raquo;')),
144                                 'confirmText' => __("Are you sure you want to delete the file '%title%'?\nClick ok to delete or cancel to go back.")
145                         ) );
146                 }
147         }
148
149         /**
150          * Prints script tags
151          *
152          * Prints the scripts passed to it or the print queue.  Also prints all necessary dependencies.
153          *
154          * @param mixed handles (optional) Scripts to be printed.  (void) prints queue, (string) prints that script, (array of strings) prints those scripts.
155          * @return array Scripts that have been printed
156          */
157         function print_scripts( $handles = false ) {
158                 global $wp_db_version;
159
160                 // Print the queue if nothing is passed.  If a string is passed, print that script.  If an array is passed, print those scripts.
161                 $handles = false === $handles ? $this->queue : (array) $handles;
162                 $this->all_deps( $handles );
163
164                 $to_print = apply_filters( 'print_scripts_array', array_keys($this->to_print) );
165
166                 foreach( $to_print as $handle ) {
167                         if ( !in_array($handle, $this->printed) && isset($this->scripts[$handle]) ) {
168                                 if ( $this->scripts[$handle]->src ) { // Else it defines a group.
169                                         $ver = $this->scripts[$handle]->ver ? $this->scripts[$handle]->ver : $wp_db_version;
170                                         if ( isset($this->args[$handle]) )
171                                                 $ver .= '&amp;' . $this->args[$handle];
172                                         $src = 0 === strpos($this->scripts[$handle]->src, 'http://') ? $this->scripts[$handle]->src : get_option( 'siteurl' ) . $this->scripts[$handle]->src;
173                                         $src = $this->scripts[$handle]->src;
174
175                                         if (!preg_match('|^https?://|', $src)) {
176                                                 $src = get_option('siteurl') . $src;
177                                         }
178
179                                         $src = add_query_arg('ver', $ver, $src);
180                                         $src = clean_url(apply_filters( 'script_loader_src', $src ));
181                                         echo "<script type='text/javascript' src='$src'></script>\n";
182                                         $this->print_scripts_l10n( $handle );
183                                 }
184                                 $this->printed[] = $handle;
185                         }
186                 }
187
188                 $this->to_print = array();
189                 return $this->printed;
190         }
191
192         function print_scripts_l10n( $handle ) {
193                 if ( empty($this->scripts[$handle]->l10n_object) || empty($this->scripts[$handle]->l10n) || !is_array($this->scripts[$handle]->l10n) )
194                         return;
195
196                 $object_name = $this->scripts[$handle]->l10n_object;
197
198                 echo "<script type='text/javascript'>\n";
199                 echo "/* <![CDATA[ */\n";
200                 echo "\t$object_name = {\n";
201                 $eol = '';
202                 foreach ( $this->scripts[$handle]->l10n as $var => $val ) {
203                         echo "$eol\t\t$var: \"" . js_escape( $val ) . '"';
204                         $eol = ",\n";
205                 }
206                 echo "\n\t}\n";
207                 echo "/* ]]> */\n";
208                 echo "</script>\n";
209         }
210
211         /**
212          * Determines dependencies of scripts
213          *
214          * Recursively builds array of scripts to print taking dependencies into account.  Does NOT catch infinite loops.
215          *
216          * @param mixed handles Accepts (string) script name or (array of strings) script names
217          * @param bool recursion Used internally when function calls itself
218          */
219         function all_deps( $handles, $recursion = false ) {
220                 if ( !$handles = (array) $handles )
221                         return false;
222
223                 foreach ( $handles as $handle ) {
224                         $handle = explode('?', $handle);
225                         if ( isset($handle[1]) )
226                                 $this->args[$handle[0]] = $handle[1];
227                         $handle = $handle[0];
228
229                         if ( isset($this->to_print[$handle]) ) // Already grobbed it and its deps
230                                 continue;
231
232                         $keep_going = true;
233                         if ( !isset($this->scripts[$handle]) )
234                                 $keep_going = false; // Script doesn't exist
235                         elseif ( $this->scripts[$handle]->deps && array_diff($this->scripts[$handle]->deps, array_keys($this->scripts)) )
236                                 $keep_going = false; // Script requires deps which don't exist (not a necessary check.  efficiency?)
237                         elseif ( $this->scripts[$handle]->deps && !$this->all_deps( $this->scripts[$handle]->deps, true ) )
238                                 $keep_going = false; // Script requires deps which don't exist
239
240                         if ( !$keep_going ) { // Either script or its deps don't exist.
241                                 if ( $recursion )
242                                         return false; // Abort this branch.
243                                 else
244                                         continue; // We're at the top level.  Move on to the next one.
245                         }                                       
246
247                         $this->to_print[$handle] = true;
248                 }
249
250                 return true;
251         }
252
253         /**
254          * Adds script
255          *
256          * Adds the script only if no script of that name already exists
257          *
258          * @param string handle Script name
259          * @param string src Script url
260          * @param array deps (optional) Array of script names on which this script depends
261          * @param string ver (optional) Script version (used for cache busting)
262          * @return array Hierarchical array of dependencies
263          */
264         function add( $handle, $src, $deps = array(), $ver = false ) {
265                 if ( isset($this->scripts[$handle]) )
266                         return false;
267                 $this->scripts[$handle] = new _WP_Script( $handle, $src, $deps, $ver );
268                 return true;
269         }
270
271         /**
272          * Localizes a script
273          *
274          * Localizes only if script has already been added
275          *
276          * @param string handle Script name
277          * @param string object_name Name of JS object to hold l10n info
278          * @param array l10n Array of JS var name => localized string
279          * @return bool Successful localization
280          */
281         function localize( $handle, $object_name, $l10n ) {
282                 if ( !isset($this->scripts[$handle]) )
283                         return false;
284                 return $this->scripts[$handle]->localize( $object_name, $l10n );
285         }
286
287         function remove( $handles ) {
288                 foreach ( (array) $handles as $handle )
289                         unset($this->scripts[$handle]);
290         }
291
292         function enqueue( $handles ) {
293                 foreach ( (array) $handles as $handle ) {
294                         $handle = explode('?', $handle);
295                         if ( !in_array($handle[0], $this->queue) && isset($this->scripts[$handle[0]]) ) {
296                                 $this->queue[] = $handle[0];
297                                 if ( isset($handle[1]) )
298                                         $this->args[$handle[0]] = $handle[1];
299                         }
300                 }
301         }
302
303         function dequeue( $handles ) {
304                 foreach ( (array) $handles as $handle )
305                         unset( $this->queue[$handle] );
306         }
307
308         function query( $handle, $list = 'scripts' ) { // scripts, queue, or printed
309                 switch ( $list ) :
310                 case 'scripts':
311                         if ( isset($this->scripts[$handle]) )
312                                 return $this->scripts[$handle];
313                         break;
314                 default:
315                         if ( in_array($handle, $this->$list) )
316                                 return true;
317                         break;
318                 endswitch;
319                 return false;
320         }
321
322 }
323
324 class _WP_Script {
325         var $handle;
326         var $src;
327         var $deps = array();
328         var $ver = false;
329         var $l10n_object = '';
330         var $l10n = array();
331
332         function _WP_Script() {
333                 @list($this->handle, $this->src, $this->deps, $this->ver) = func_get_args();
334                 if ( !is_array($this->deps) )
335                         $this->deps = array();
336                 if ( !$this->ver )
337                         $this->ver = false;
338         }
339
340         function localize( $object_name, $l10n ) {
341                 if ( !$object_name || !is_array($l10n) )
342                         return false;
343                 $this->l10n_object = $object_name;
344                 $this->l10n = $l10n;
345                 return true;
346         }
347 }
348
349 /**
350  * Prints script tags in document head
351  *
352  * Called by admin-header.php and by wp_head hook. Since it is called by wp_head on every page load,
353  * the function does not instantiate the WP_Scripts object unless script names are explicitly passed.
354  * Does make use of already instantiated $wp_scripts if present.
355  * Use provided wp_print_scripts hook to register/enqueue new scripts.
356  *
357  * @see WP_Scripts::print_scripts()
358  */
359 function wp_print_scripts( $handles = false ) {
360         do_action( 'wp_print_scripts' );
361         if ( '' === $handles ) // for wp_head
362                 $handles = false;
363
364         global $wp_scripts;
365         if ( !is_a($wp_scripts, 'WP_Scripts') ) {
366                 if ( !$handles )
367                         return array(); // No need to instantiate if nothing's there.
368                 else
369                         $wp_scripts = new WP_Scripts();
370         }
371
372         return $wp_scripts->print_scripts( $handles );
373 }
374
375 function wp_register_script( $handle, $src, $deps = array(), $ver = false ) {
376         global $wp_scripts;
377         if ( !is_a($wp_scripts, 'WP_Scripts') )
378                 $wp_scripts = new WP_Scripts();
379
380         $wp_scripts->add( $handle, $src, $deps, $ver );
381 }
382
383 /**
384  * Localizes a script
385  *
386  * Localizes only if script has already been added
387  *
388  * @see WP_Script::localize()
389  */
390 function wp_localize_script( $handle, $object_name, $l10n ) {
391         global $wp_scripts;
392         if ( !is_a($wp_scripts, 'WP_Scripts') )
393                 return false;
394
395         return $wp_scripts->localize( $handle, $object_name, $l10n );
396 }
397
398 function wp_deregister_script( $handle ) {
399         global $wp_scripts;
400         if ( !is_a($wp_scripts, 'WP_Scripts') )
401                 $wp_scripts = new WP_Scripts();
402
403         $wp_scripts->remove( $handle );
404 }
405
406 /**
407  * Equeues script
408  *
409  * Registers the script if src provided (does NOT overwrite) and enqueues.
410  *
411  * @see WP_Script::add(), WP_Script::enqueue()
412 */
413 function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false ) {
414         global $wp_scripts;
415         if ( !is_a($wp_scripts, 'WP_Scripts') )
416                 $wp_scripts = new WP_Scripts();
417
418         if ( $src ) {
419                 $_handle = explode('?', $handle);
420                 $wp_scripts->add( $_handle[0], $src, $deps, $ver );
421         }
422         $wp_scripts->enqueue( $handle );
423 }
424
425 function wp_prototype_before_jquery( $js_array ) {
426         if ( false === $jquery = array_search( 'jquery', $js_array ) )
427                 return $js_array;
428
429         if ( false === $prototype = array_search( 'prototype', $js_array ) )
430                 return $js_array;
431
432         if ( $prototype < $jquery )
433                 return $js_array;
434
435         unset($js_array[$prototype]);
436
437         array_splice( $js_array, $jquery, 0, 'prototype' );
438
439         return $js_array;
440 }
441
442 add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' );
443
444 ?>