From 9c7db112193fba4d40f4d89e9468761ee4c47535 Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 11 Feb 2008 17:45:18 +0000 Subject: [PATCH] New gzip compressor for TinyMCE from azaozz. fixes #5807 git-svn-id: http://svn.automattic.com/wordpress/trunk@6789 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/default-filters.php | 4 +- wp-includes/functions.php | 28 +- wp-includes/js/tinymce/tiny_mce_config.php | 332 ++++++++++++++----- wp-includes/js/tinymce/tiny_mce_gzip.php | 363 --------------------- wp-includes/script-loader.php | 6 +- 5 files changed, 260 insertions(+), 473 deletions(-) diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php index cb297a5fd9..2c6020082c 100644 --- a/wp-includes/default-filters.php +++ b/wp-includes/default-filters.php @@ -143,8 +143,7 @@ add_filter('option_ping_sites', 'privacy_ping_filter'); add_filter('option_blog_charset', 'wp_specialchars'); add_filter('option_home', '_config_wp_home'); add_filter('option_siteurl', '_config_wp_siteurl'); -add_filter('mce_plugins', '_mce_load_rtl_plugin'); -add_filter('mce_buttons', '_mce_add_direction_buttons'); +add_filter('tiny_mce_before_init', '_mce_set_direction'); add_filter('pre_kses', 'wp_pre_kses_less_than'); add_filter('sanitize_title', 'sanitize_title_with_dashes'); add_action('check_comment_flood', 'check_comment_flood_db', 10, 3); @@ -173,7 +172,6 @@ add_action('do_pings', 'do_all_pings', 10, 1); add_action('do_robots', 'do_robots'); add_action('sanitize_comment_cookies', 'sanitize_comment_cookies'); add_action('admin_print_scripts', 'wp_print_scripts', 20); -add_action('mce_options', '_mce_set_direction'); add_action('init', 'smilies_init', 5); add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 ); add_action( 'shutdown', 'wp_ob_end_flush_all', 1); diff --git a/wp-includes/functions.php b/wp-includes/functions.php index e5a37e5d0e..74fb0b3619 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -1382,32 +1382,14 @@ function _config_wp_siteurl( $url = '' ) { } -function _mce_set_direction() { +function _mce_set_direction( $input ) { global $wp_locale; if ( 'rtl' == $wp_locale->text_direction ) { - echo 'directionality : "rtl" ,'; - echo 'theme_advanced_toolbar_align : "right" ,'; - } -} - - -function _mce_load_rtl_plugin( $input ) { - global $wp_locale; - - if ( 'rtl' == $wp_locale->text_direction ) - $input[] = 'directionality'; - - return $input; -} - - -function _mce_add_direction_buttons( $input ) { - global $wp_locale; - - if ( 'rtl' == $wp_locale->text_direction ) { - $new_buttons = array( 'separator', 'ltr', 'rtl' ); - $input = array_merge( $input, $new_buttons ); + $input['directionality'] = 'rtl'; + $input['theme_advanced_toolbar_align'] = 'right'; + $input['plugins'] .= ',directionality'; + $input['theme_advanced_buttons2'] .= ',|,ltr,rtl'; } return $input; diff --git a/wp-includes/js/tinymce/tiny_mce_config.php b/wp-includes/js/tinymce/tiny_mce_config.php index 2f0c5e30d4..276ddf8871 100644 --- a/wp-includes/js/tinymce/tiny_mce_config.php +++ b/wp-includes/js/tinymce/tiny_mce_config.php @@ -1,100 +1,272 @@ - "url". +It adds the plugin's name (including the required dash) to TinyMCE's plugins init and the call to PluginManager to load the plugin. +The url should be absolute and should include the js file name to be loaded. +Example: array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' ). +If the plugin uses a button, it should be added with one of the "$mce_buttons" filters. +*/ +$mce_external_plugins = apply_filters('mce_external_plugins', array()); - $mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', '|', 'removeformat', 'cleanup', '|', 'media', 'charmap', 'blockquote', '|', 'undo', 'redo', 'fullscreen' )); - $mce_buttons_2 = implode($mce_buttons_2, ','); +$ext_plugins = "\n"; +foreach ( $mce_external_plugins as $name => $url ) { + $plugins[] = '-' . $name; + $url = $https ? str_replace('http://', 'https://', $url) : $url; + + $ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n"; +} - $mce_buttons_3 = apply_filters('mce_buttons_3', array()); - $mce_buttons_3 = implode($mce_buttons_3, ','); +$plugins = implode($plugins, ','); - $mce_buttons_4 = apply_filters('mce_buttons_4', array()); - $mce_buttons_4 = implode($mce_buttons_4, ','); +$mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'outdent', 'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'image', 'wp_more', '|', 'spellchecker', '|', 'wp_help', 'wp_adv' )); +$mce_buttons = implode($mce_buttons, ','); - $mce_browsers = apply_filters('mce_browsers', array('msie', 'gecko', 'opera', 'safari')); - $mce_browsers = implode($mce_browsers, ','); +$mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', '|', 'removeformat', 'cleanup', '|', 'media', 'charmap', 'blockquote', '|', 'undo', 'redo', 'fullscreen' )); +$mce_buttons_2 = implode($mce_buttons_2, ','); - $mce_css = get_option('siteurl') . '/wp-includes/js/tinymce/wordpress.css'; - $mce_css = apply_filters('mce_css', $mce_css); - if ( $_SERVER['HTTPS'] == 'on' ) - $mce_css = str_replace('http://', 'https://', $mce_css); +$mce_buttons_3 = apply_filters('mce_buttons_3', array()); +$mce_buttons_3 = implode($mce_buttons_3, ','); + +$mce_buttons_4 = apply_filters('mce_buttons_4', array()); +$mce_buttons_4 = implode($mce_buttons_4, ','); - $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1 -?> +// all these browsers are now 100% supported, no need for this +//$mce_browsers = apply_filters('mce_browsers', array('msie', 'gecko', 'opera', 'safari')); +//$mce_browsers = implode($mce_browsers, ','); -initArray = { - mode : "none", - onpageload : "wpEditorInit", - width : "100%", - theme : "advanced", - skin : "wp_theme", - theme_advanced_buttons1 : "", - theme_advanced_buttons2 : "", - theme_advanced_buttons3 : "", - theme_advanced_buttons4 : "", - language : "", - theme_advanced_toolbar_location : "top", - theme_advanced_toolbar_align : "left", - theme_advanced_statusbar_location : "bottom", - theme_advanced_resizing : true, - browsers : "", - dialog_type : "modal", - theme_advanced_resize_horizontal : false, - convert_urls : false, - relative_urls : false, - remove_script_host : false, - fix_list_elements : true, - fix_table_elements : true, - gecko_spellcheck : true, - entities : "38,amp,60,lt,62,gt", - accessibility_focus : false, - tab_focus : ":next", - content_css : "", - - - save_callback : "switchEditors.saveCallback", - - plugins : "" -}; +$mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1 - +// TinyMCE init settings +$initArray = array ( + 'mode' => 'none', + 'onpageload' => 'wpEditorInit', + 'width' => '100%', + 'theme' => 'advanced', + 'skin' => 'wp_theme', + 'theme_advanced_buttons1' => "$mce_buttons", + 'theme_advanced_buttons2' => "$mce_buttons_2", + 'theme_advanced_buttons3' => "$mce_buttons_3", + 'theme_advanced_buttons4' => "$mce_buttons_4", + 'language' => "$mce_locale", + 'theme_advanced_toolbar_location' => 'top', + 'theme_advanced_toolbar_align' => 'left', + 'theme_advanced_statusbar_location' => 'bottom', + 'theme_advanced_resizing' => true, + 'theme_advanced_resize_horizontal' => false, +// 'browsers' => "$mce_browsers", + 'dialog_type' => 'modal', + 'convert_urls' => false, + 'relative_urls' => false, + 'remove_script_host' => false, + 'fix_list_elements' => true, + 'fix_table_elements' => true, + 'gecko_spellcheck' => true, + 'entities' => '38,amp,60,lt,62,gt', + 'accessibility_focus' => false, + 'tab_focus' => ':next', + 'content_css' => "$mce_css", + 'save_callback' => 'switchEditors.saveCallback', + 'plugins' => "$plugins", + // pass-through the settings for compression and caching, so they can be changed with "tiny_mce_before_init" + 'disk_cache' => true, + 'compress' => true, + 'del_old_cache' => true +); -tinyMCE_GZ.init(initArray); +if ( $valid_elements ) $initArray['valid_elements'] = $valid_elements; +if ( $invalid_elements ) $initArray['invalid_elements'] = $invalid_elements; + +// For people who really REALLY know what they're doing with TinyMCE +// You can modify initArray to add, remove, change elements of the config before tinyMCE.init +$initArray = apply_filters('tiny_mce_before_init', $initArray); // changed from action to filter + +// support for deprecated actions +ob_start(); +do_action('mce_options'); +$mce_deprecated1 = ob_get_contents() || ''; +ob_end_clean(); + +/* +// Do we need to support this? Most likely will breal TinyMCE 3... +ob_start(); +do_action('tinymce_before_init'); +$mce_deprecated2 = ob_get_contents() || ''; +ob_end_clean(); +*/ + +// Settings for the gzip compression and cache +$cache_path = dirname(__FILE__); // Cache path, this is where the .gz files will be stored +$cache_ext = '.js'; + +$disk_cache = ( ! isset($initArray['disk_cache']) || false == $initArray['disk_cache'] ) ? false : true; +$compress = ( ! isset($initArray['compress']) || false == $initArray['compress'] ) ? false : true; +$del_old_cache = ( ! isset($initArray['del_old_cache']) || false == $initArray['del_old_cache'] ) ? false : true; + +$initArray['disk_cache'] = $initArray['compress'] = $initArray['del_old_cache'] = null; +unset( $initArray['disk_cache'], $initArray['compress'], $initArray['del_old_cache'] ); + +$plugins = explode( ',', $initArray['plugins'] ); +$theme = ( 'simple' == $initArray['theme'] ) ? 'simple' : 'advanced'; +$language = isset($initArray['language']) ? substr( $initArray['language'], 0, 2 ) : 'en'; +$enc = $cacheKey = $suffix = $mce_options = ''; + +// Custom extra javascripts to pack +$custom_js = array(); //$custom_js = apply_filters('tinymce_custom_js', array()); + +// Check if supports gzip +if ( $compress && isset($_SERVER['HTTP_ACCEPT_ENCODING']) ) { + $encodings = explode( ',', strtolower( preg_replace('/\s+/', '', $_SERVER['HTTP_ACCEPT_ENCODING']) ) ); + + if ( (in_array('gzip', $encodings) || in_array('x-gzip', $encodings) || isset($_SERVER['---------------']) ) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression') ) { + $enc = in_array('x-gzip', $encodings) ? 'x-gzip' : 'gzip'; + $cache_ext = '.gz'; + } +} + +// Setup cache info +if ( $disk_cache && $cache_path ) { + + $ver = isset($_GET['ver']) ? (int) $_GET['ver'] : ''; + $cacheKey = $initArray['plugins'] . $language . $theme . $suffix . $ver; + + foreach ( $custom_js as $file ) + $cacheKey .= $file; + + $cacheKey = md5( $cacheKey ); + $cache_file = $cache_path . '/tiny_mce_' . $cacheKey . $cache_ext; +} + +cache_javascript_headers(); + +// Use cached file if exists +if ( $disk_cache && file_exists($cache_file) ) { + if ( '.gz' == $cache_ext ) + header( 'Content-Encoding: ' . $enc ); + + echo getFileContents( $cache_file ); + exit; +} + +foreach ( $initArray as $k => $v ) + $mce_options .= $k . ':"' . $v . '", '; + +$mce_options .= $mce_deprecated1; +$mce_options = rtrim( trim($mce_options), '\n\r,' ); + +$content = 'var tinyMCEPreInit = { suffix : "' . $suffix . '", base : "' . $baseurl . '" };'; +$content .= 'var tinyMCE_GZ = { settings : { themes : "' . $theme . '", plugins : "' . $initArray['plugins'] . '", languages : "' . $language . '", debug : false, suffix : "' . $suffix . '" }, baseURL : "' . $baseurl . '" };'; + +// Load patch +$content .= getFileContents( 'tiny_mce_ext.js' ); + +// Add core +$content .= getFileContents( 'tiny_mce' . $suffix . '.js' ); + +// Patch loading functions +$content .= 'tinyMCE_GZ.start();'; + +// Add all languages (WP) +include_once( dirname(__FILE__).'/langs/wp-langs.php' ); +$content .= $strings; + +// Add themes +$content .= getFileContents( 'themes/' . $theme . '/editor_template' . $suffix . '.js' ); + +// Add plugins +foreach ( $plugins as $plugin ) + $content .= getFileContents( 'plugins/' . $plugin . '/editor_plugin' . $suffix . '.js' ); + +// Add custom files +foreach ( $custom_js as $file ) + $content .= getFileContents($file); + +// Add external plugins and init +$content .= $ext_plugins . 'tinyMCE.init({' . $mce_options . '});'; // $mce_deprecated2 . + +// Generate GZIP'd content +if ( '.gz' == $cache_ext ) { + header('Content-Encoding: ' . $enc); + $cache_data = gzencode( $content, 9, FORCE_GZIP ); +} else + $cache_data = $content; + +// Stream to client +echo $cache_data; + +// Write file +if ( '' != $cacheKey ) { + if ( $del_old_cache ) { + $old_key = getFileContents('tiny_mce_compressed_key'); + + if ( '' != $old_key ) { // && $old_key != $cacheKey + $old_cache = $cache_path . '/tiny_mce_' . $old_key . $cache_ext; + @unlink($old_cache); + } + + putFileContents( 'tiny_mce_compressed_key', $cacheKey ); + } + + putFileContents( $cache_file, $cache_data ); +} +?> \ No newline at end of file diff --git a/wp-includes/js/tinymce/tiny_mce_gzip.php b/wp-includes/js/tinymce/tiny_mce_gzip.php index a6795dd610..e69de29bb2 100644 --- a/wp-includes/js/tinymce/tiny_mce_gzip.php +++ b/wp-includes/js/tinymce/tiny_mce_gzip.php @@ -1,363 +0,0 @@ - - -var tinyMCEPreInit = {suffix : ''}; - -var tinyMCE_GZ = { - settings : { - themes : '', - plugins : '', - languages : '', - disk_cache : false, - page_name : 'tiny_mce_gzip.php', - debug : false, - suffix : '' - }, - - opt : {}, - - init : function(o, cb) { - var t = this, n, s = t.settings, nl = document.getElementsByTagName('script'); - - t.opt = o; - - s.themes = o.theme; - s.plugins = o.plugins; - s.languages = o.language; - t.settings = s; - - t.cb = cb || ''; - - for (i=0; i'); - - // Send request - x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Msxml2.XMLHTTP') || get('Microsoft.XMLHTTP'); - x.overrideMimeType && x.overrideMimeType('text/javascript'); - x.open('GET', t.baseURL + '/' + s.page_name + '?' + q, !!cb); -// x.setRequestHeader('Content-Type', 'text/javascript'); - x.send(''); - - // Handle asyncronous loading - if (cb) { - // Wait for response - ti = w.setInterval(function() { - if (x.readyState == 4 || c++ > 10000) { - w.clearInterval(ti); - - if (c < 10000 && x.status == 200) { - t.loaded = 1; - t.eval(x.responseText); - tinymce.dom.Event.domLoaded = true; - // cb.call(sc || t, x); - } - - ti = x = null; - } - }, 10); - } else - t.eval(x.responseText); - }, - - start : function() { - var t = this, each = tinymce.each, s = t.settings, sl, ln = s.languages.split(','); - - tinymce.suffix = s.suffix; - - // Extend script loader - tinymce.create('tinymce.compressor.ScriptLoader:tinymce.dom.ScriptLoader', { - loadScripts : function(sc, cb, s) { - var ti = this, th = [], pl = [], la = []; - - each(sc, function(o) { - var u = o.url; - - if ((!ti.lookup[u] || ti.lookup[u].state != 2) && u.indexOf(t.baseURL) === 0) { - // Collect theme - if (u.indexOf('editor_template') != -1) { - th.push(/\/themes\/([^\/]+)/.exec(u)[1]); - load(u, 1); - } - - // Collect plugin - if (u.indexOf('editor_plugin') != -1) { - pl.push(/\/plugins\/([^\/]+)/.exec(u)[1]); - load(u, 1); - } - - // Collect language - if (u.indexOf('/langs/') != -1) { - la.push(/\/langs\/([^.]+)/.exec(u)[1]); - load(u, 1); - } - } - }); - - if (th.length + pl.length + la.length > 0) { - if (sl.settings.strict_mode) { - // Async - t.loadScripts(0, th.join(','), pl.join(','), la.join(','), cb, s); - return; - } else - t.loadScripts(0, th.join(','), pl.join(','), la.join(','), cb, s); - } - - return ti.parent(sc, cb, s); - } - }); - - sl = tinymce.ScriptLoader = new tinymce.compressor.ScriptLoader(); - - function load(u, sp) { - var o; - - if (!sp) - u = t.baseURL + u; - - o = {url : u, state : 2}; - sl.queue.push(o); - sl.lookup[o.url] = o; - }; - - // Add core languages - each (ln, function(c) { - if (c) - load('/langs/' + c + '.js'); - }); - - // Add themes with languages - each(s.themes.split(','), function(n) { - if (n) { - load('/themes/' + n + '/editor_template' + s.suffix + '.js'); - - each (ln, function(c) { - if (c) - load('/themes/' + n + '/langs/' + c + '.js'); - }); - } - }); - - // Add plugins with languages - each(s.plugins.split(','), function(n) { - if (n) { - load('/plugins/' + n + '/editor_plugin' + s.suffix + '.js'); - - each (ln, function(c) { - if (c) - load('/plugins/' + n + '/langs/' + c + '.js'); - }); - } - }); - }, - - end : function() { - tinyMCE.init(this.opt); - }, - - eval : function(co) { - var w = window; - - // Evaluate script - if (!w.execScript) { - try { - eval.call(w, co); - } catch (ex) { - eval(co, w); // Firefox 3.0a8 - } - } else - w.execScript(co); // IE - } -}; diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index cfcc482f96..d7d0a3831d 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -30,10 +30,8 @@ class WP_Scripts { $this->add( 'colorpicker', '/wp-includes/js/colorpicker.js', false, '3517' ); // Modify this version when tinyMCE plugins are changed - $this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '20080208' ); - $mce_config = apply_filters('tiny_mce_config_url', '/wp-includes/js/tinymce/tiny_mce_config.php'); - $this->add( 'wp_tiny_mce', $mce_config, array('tiny_mce'), '20080208' ); + $this->add( 'tiny_mce', $mce_config, false, '20080209' ); $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6'); @@ -478,7 +476,7 @@ function wp_prototype_before_jquery( $js_array ) { // These localizations require information that may not be loaded even by init function wp_just_in_time_script_localization() { - wp_localize_script( 'wp_tiny_mce', 'wpTinyMCEConfig', array( 'defaultEditor' => wp_default_editor() ) ); + wp_localize_script( 'tiny_mce', 'wpTinyMCEConfig', array( 'defaultEditor' => wp_default_editor() ) ); } add_filter( 'wp_print_scripts', 'wp_just_in_time_script_localization' );