diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php index a5fa35458..adb7e4a82 100644 --- a/wp-admin/admin-ajax.php +++ b/wp-admin/admin-ajax.php @@ -63,6 +63,18 @@ case 'ajax-tag-search' : echo join( $results, "\n" ); die; break; +case 'wp-compression-test' : + if ( !current_user_can( 'manage_options' ) ) + die('-1'); + + if ( isset($_GET['tested']) ) { + if ( 1 == $_GET['tested'] ) + update_option('can_compress_scripts', 1); + elseif ( 0 == $_GET['tested'] ) + update_option('can_compress_scripts', 0); + } + die('0'); + break; default : do_action( 'wp_ajax_' . $_GET['action'] ); die('0'); diff --git a/wp-admin/admin-footer.php b/wp-admin/admin-footer.php index 87d953fa2..dc3cb88a5 100644 --- a/wp-admin/admin-footer.php +++ b/wp-admin/admin-footer.php @@ -22,7 +22,14 @@ echo '' . __('Thank you for creating with

- + - \ No newline at end of file + + diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php index 1c51632bc..0319a947d 100644 --- a/wp-admin/includes/template.php +++ b/wp-admin/includes/template.php @@ -3387,4 +3387,37 @@ function screen_icon($name = '') { + + + diff --git a/wp-admin/load-scripts.php b/wp-admin/load-scripts.php new file mode 100644 index 000000000..a24949b1f --- /dev/null +++ b/wp-admin/load-scripts.php @@ -0,0 +1,160 @@ +registered) ) + continue; + + $path = ABSPATH . $wp_scripts->registered[$handle]->src; + $out .= get_file($path) . "\n"; +} + +header('Content-Type: application/x-javascript; charset=UTF-8'); +header('Vary: Accept-Encoding'); // Handle proxies +header('Expires: ' . gmdate( "D, d M Y H:i:s", time() + $expires_offset ) . ' GMT'); +header("Cache-Control: public, max-age=$expires_offset"); + +if ( $compress && ! ini_get('zlib.output_compression') ) { + if ( false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'deflate') && function_exists('gzdeflate') ) { + header('Content-Encoding: deflate'); + $out = gzdeflate( $out, 3 ); + } elseif ( false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') && function_exists('gzencode') ) { + header('Content-Encoding: gzip'); + $out = gzencode( $out, 3 ); + } +} + +echo $out; +exit; diff --git a/wp-admin/load-styles.php b/wp-admin/load-styles.php new file mode 100644 index 000000000..f7e61ff1e --- /dev/null +++ b/wp-admin/load-styles.php @@ -0,0 +1,141 @@ +registered) ) + continue; + + $style = $wp_styles->registered[$handle]; + $path = ABSPATH . $style->src; + + $content = get_file($path) . "\n"; + + if ( $rtl && isset($style->extra['rtl']) && $style->extra['rtl'] ) { + $rtl_path = is_bool($style->extra['rtl']) ? str_replace( '.css', '-rtl.css', $path ) : ABSPATH . $style->extra['rtl']; + $content .= get_file($rtl_path) . "\n"; + } + + $out .= str_replace( '../images/', 'images/', $content ); +} + +header('Content-Type: text/css'); +header('Vary: Accept-Encoding'); // Handle proxies +header('Expires: ' . gmdate( "D, d M Y H:i:s", time() + $expires_offset ) . ' GMT'); +header("Cache-Control: public, max-age=$expires_offset"); + +if ( $compress && ! ini_get('zlib.output_compression') ) { + if ( false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'deflate') && function_exists('gzdeflate') ) { + header('Content-Encoding: deflate'); + $out = gzdeflate( $out, 3 ); + } elseif ( false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') && function_exists('gzencode') ) { + header('Content-Encoding: gzip'); + $out = gzencode( $out, 3 ); + } +} + +echo $out; +exit; diff --git a/wp-includes/class.wp-dependencies.php b/wp-includes/class.wp-dependencies.php index e4c9c450b..fbec18fcd 100644 --- a/wp-includes/class.wp-dependencies.php +++ b/wp-includes/class.wp-dependencies.php @@ -22,6 +22,8 @@ class WP_Dependencies { var $to_do = array(); var $done = array(); var $args = array(); + var $groups = array(); + var $group = 0; function WP_Dependencies() { $args = func_get_args(); @@ -38,21 +40,26 @@ class WP_Dependencies { * @param mixed handles (optional) items to be processed. (void) processes queue, (string) process that item, (array of strings) process those items * @return array Items that have been processed */ - function do_items( $handles = false ) { + function do_items( $handles = false, $group = false ) { // Print the queue if nothing is passed. If a string is passed, print that script. If an array is passed, print those scripts. $handles = false === $handles ? $this->queue : (array) $handles; $this->all_deps( $handles ); - foreach( $this->to_do as $handle ) { + foreach( $this->to_do as $key => $handle ) { if ( !in_array($handle, $this->done) && isset($this->registered[$handle]) ) { - if ( $this->registered[$handle]->src ) { // Else it defines a group. - $this->do_item( $handle ); + + if ( ! $this->registered[$handle]->src ) { // Defines a group. + $this->done[] = $handle; + continue; } - $this->done[] = $handle; + + if ( $this->do_item( $handle, $group ) ) + $this->done[] = $handle; + + unset( $this->to_do[$key] ); } } - $this->to_do = array(); return $this->done; } @@ -69,25 +76,31 @@ class WP_Dependencies { * @param mixed handles Accepts (string) dep name or (array of strings) dep names * @param bool recursion Used internally when function calls itself */ - function all_deps( $handles, $recursion = false ) { + function all_deps( $handles, $recursion = false, $group = false ) { if ( !$handles = (array) $handles ) return false; foreach ( $handles as $handle ) { - $handle = explode('?', $handle); - if ( isset($handle[1]) ) - $this->args[$handle[0]] = $handle[1]; - $handle = $handle[0]; + $handle_parts = explode('?', $handle); + $handle = $handle_parts[0]; - if ( isset($this->to_do[$handle]) ) // Already grobbed it and its deps + if ( in_array($handle, $this->done, true) ) // Already done continue; + $this->set_group( $handle, $recursion, $group ); + + if ( in_array($handle, $this->to_do, true) ) // Already grobbed it and its deps + continue; + + if ( isset($handle_parts[1]) ) + $this->args[$handle] = $handle_parts[1]; + $keep_going = true; if ( !isset($this->registered[$handle]) ) $keep_going = false; // Script doesn't exist elseif ( $this->registered[$handle]->deps && array_diff($this->registered[$handle]->deps, array_keys($this->registered)) ) $keep_going = false; // Script requires deps which don't exist (not a necessary check. efficiency?) - elseif ( $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true ) ) + elseif ( $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $group ) ) $keep_going = false; // Script requires deps which don't exist if ( !$keep_going ) { // Either script or its deps don't exist. @@ -97,11 +110,9 @@ class WP_Dependencies { continue; // We're at the top level. Move on to the next one. } - $this->to_do[$handle] = true; + $this->to_do[] = $handle; } - if ( !$recursion ) // at the end - $this->to_do = array_keys( $this->to_do ); return true; } @@ -181,6 +192,21 @@ class WP_Dependencies { return false; } + function set_group( $handle, $recursion, $group ) { + $group = (int) $group; + + if ( $recursion ) + $group = min($this->group, $group); + else + $this->group = $group; + + if ( isset($this->groups[$handle]) && $this->groups[$handle] <= $group ) + return false; + + $this->groups[$handle] = $group; + return true; + } + } class _WP_Dependency { diff --git a/wp-includes/class.wp-scripts.php b/wp-includes/class.wp-scripts.php index 9b098aba1..d3c8b0dd8 100644 --- a/wp-includes/class.wp-scripts.php +++ b/wp-includes/class.wp-scripts.php @@ -18,7 +18,15 @@ */ class WP_Scripts extends WP_Dependencies { var $base_url; // Full URL with trailing slash + var $content_url; var $default_version; + var $in_footer = array(); + var $concat = ''; + var $concat_version = ''; + var $do_concat = false; + var $print_html = ''; + var $print_code = ''; + var $default_dirs; function __construct() { do_action_ref_array( 'wp_default_scripts', array(&$this) ); @@ -30,57 +38,84 @@ class WP_Scripts extends WP_Dependencies { * Prints the scripts passed to it or the print queue. Also prints all necessary dependencies. * * @param mixed handles (optional) Scripts to be printed. (void) prints queue, (string) prints that script, (array of strings) prints those scripts. + * @param int group (optional) If scripts were queued in groups prints this group number. * @return array Scripts that have been printed */ - function print_scripts( $handles = false ) { - return $this->do_items( $handles ); + function print_scripts( $handles = false, $group = false ) { + return $this->do_items( $handles, $group ); } - function print_scripts_l10n( $handle ) { + function print_scripts_l10n( $handle, $echo = true ) { if ( empty($this->registered[$handle]->extra['l10n']) || empty($this->registered[$handle]->extra['l10n'][0]) || !is_array($this->registered[$handle]->extra['l10n'][1]) ) return false; $object_name = $this->registered[$handle]->extra['l10n'][0]; - echo "\n"; + $data .= "\n};\n"; + $data .= isset($after) ? "$after\n" : ''; - return true; + if ( $echo ) { + echo "\n"; + return true; + } else { + return $data; + } } - function do_item( $handle ) { + function do_item( $handle, $group = false ) { if ( !parent::do_item($handle) ) return false; + if ( 0 === $group && $this->groups[$handle] > 0 ) { + $this->in_footer[] = $handle; + return false; + } + + if ( false === $group && in_array($handle, $this->in_footer, true) ) + $this->in_footer = array_diff( $this->in_footer, (array) $handle ); + $ver = $this->registered[$handle]->ver ? $this->registered[$handle]->ver : $this->default_version; if ( isset($this->args[$handle]) ) $ver .= '&' . $this->args[$handle]; $src = $this->registered[$handle]->src; - if ( !preg_match('|^https?://|', $src) && !preg_match('|^' . preg_quote(WP_CONTENT_URL) . '|', $src) ) { + + if ( $this->do_concat ) { + $srce = apply_filters( 'script_loader_src', $src, $handle, $echo ); + if ( $this->in_default_dir($srce) ) { + $this->print_code .= $this->print_scripts_l10n( $handle, false ); + $this->concat .= $handle . ','; + $this->concat_version .= $ver; + return true; + } + } + + $this->print_scripts_l10n( $handle ); + if ( !preg_match('|^https?://|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) { $src = $this->base_url . $src; } $src = add_query_arg('ver', $ver, $src); - $src = clean_url(apply_filters( 'script_loader_src', $src, $handle )); + $src = clean_url(apply_filters( 'script_loader_src', $src, $handle, $echo )); - $this->print_scripts_l10n( $handle ); - - echo "\n"; + if ( $this->do_concat ) + $this->print_html .= "\n"; + else + echo "\n"; return true; } @@ -101,10 +136,47 @@ class WP_Scripts extends WP_Dependencies { return $this->add_data( $handle, 'l10n', array( $object_name, $l10n ) ); } + function set_group( $handle, $recursion, $group = false ) { + $grp = isset($this->registered[$handle]->extra['group']) ? (int) $this->registered[$handle]->extra['group'] : 0; + if ( false !== $group && $grp > $group ) + $grp = $group; + + parent::set_group( $handle, $recursion, $grp ); + } + function all_deps( $handles, $recursion = false ) { $r = parent::all_deps( $handles, $recursion ); if ( !$recursion ) $this->to_do = apply_filters( 'print_scripts_array', $this->to_do ); return $r; } + + function do_head_items() { + $this->do_items(false, 0); + return $this->done; + } + + function do_footer_items() { + if ( !empty($this->in_footer) ) { + foreach( $this->in_footer as $key => $handle ) { + if ( !in_array($handle, $this->done, true) && isset($this->registered[$handle]) ) { + $this->do_item($handle, false, $this->doecho); + $this->done[] = $handle; + unset( $this->in_footer[$key] ); + } + } + } + return $this->done; + } + + function in_default_dir($src) { + if ( ! $this->default_dirs ) + return true; + + foreach ( (array) $this->default_dirs as $test ) { + if ( 0 === strpos($src, $test) ) + return true; + } + return false; + } } diff --git a/wp-includes/class.wp-styles.php b/wp-includes/class.wp-styles.php index 128610674..c67bf2098 100644 --- a/wp-includes/class.wp-styles.php +++ b/wp-includes/class.wp-styles.php @@ -18,8 +18,14 @@ */ class WP_Styles extends WP_Dependencies { var $base_url; + var $content_url; var $default_version; var $text_direction = 'ltr'; + var $concat = ''; + var $concat_version = ''; + var $do_concat = false; + var $print_html = ''; + var $default_dirs; function __construct() { do_action_ref_array( 'wp_default_styles', array(&$this) ); @@ -33,6 +39,14 @@ class WP_Styles extends WP_Dependencies { if ( isset($this->args[$handle]) ) $ver .= '&' . $this->args[$handle]; + if ( $this->do_concat ) { + if ( $this->in_default_dir($this->registered[$handle]->src) && !isset($this->registered[$handle]->extra['conditional']) && !isset($this->registered[$handle]->extra['alt']) ) { + $this->concat .= $handle . ','; + $this->concat_version .= $ver; + return true; + } + } + if ( isset($this->registered[$handle]->args) ) $media = attribute_escape( $this->registered[$handle]->args ); else @@ -42,23 +56,28 @@ class WP_Styles extends WP_Dependencies { $rel = isset($this->registered[$handle]->extra['alt']) && $this->registered[$handle]->extra['alt'] ? 'alternate stylesheet' : 'stylesheet'; $title = isset($this->registered[$handle]->extra['title']) ? "title='" . attribute_escape( $this->registered[$handle]->extra['title'] ) . "'" : ''; - $end_cond = ''; + $end_cond = $tag = ''; if ( isset($this->registered[$handle]->extra['conditional']) && $this->registered[$handle]->extra['conditional'] ) { - echo "\n"; } - echo apply_filters( 'style_loader_tag', "\n", $handle ); + $tag .= apply_filters( 'style_loader_tag', "\n", $handle ); if ( 'rtl' === $this->text_direction && isset($this->registered[$handle]->extra['rtl']) && $this->registered[$handle]->extra['rtl'] ) { if ( is_bool( $this->registered[$handle]->extra['rtl'] ) ) $rtl_href = str_replace( '.css', '-rtl.css', $href ); else $rtl_href = $this->_css_href( $this->registered[$handle]->extra['rtl'], $ver, "$handle-rtl" ); - echo apply_filters( 'style_loader_tag', "\n", $handle ); + $tag .= apply_filters( 'style_loader_tag', "\n", $handle ); } - echo $end_cond; + $tag .= $end_cond; + + if ( $this->do_concat ) + $this->print_html .= $tag; + else + echo $tag; // Could do something with $this->registered[$handle]->extra here to print out extra CSS rules // echo "