[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Facilitates adding of the WordPress editor as used on the Write and Edit screens. 4 * 5 * @package WordPress 6 * @since 3.3.0 7 * 8 * Private, not included by default. See wp_editor() in wp-includes/general-template.php. 9 */ 10 11 final class _WP_Editors { 12 public static $mce_locale; 13 14 private static $mce_settings = array(); 15 private static $qt_settings = array(); 16 private static $plugins = array(); 17 private static $qt_buttons = array(); 18 private static $ext_plugins; 19 private static $baseurl; 20 private static $first_init; 21 private static $this_tinymce = false; 22 private static $this_quicktags = false; 23 private static $has_tinymce = false; 24 private static $has_quicktags = false; 25 private static $has_medialib = false; 26 private static $editor_buttons_css = true; 27 28 private function __construct() {} 29 30 public static function parse_settings($editor_id, $settings) { 31 $set = wp_parse_args( $settings, array( 32 'wpautop' => true, // use wpautop? 33 'media_buttons' => true, // show insert/upload button(s) 34 'textarea_name' => $editor_id, // set the textarea name to something different, square brackets [] can be used here 35 'textarea_rows' => 20, 36 'tabindex' => '', 37 'tabfocus_elements' => ':prev,:next', // the previous and next element ID to move the focus to when pressing the Tab key in TinyMCE 38 'editor_css' => '', // intended for extra styles for both visual and Text editors buttons, needs to include the <style> tags, can use "scoped". 39 'editor_class' => '', // add extra class(es) to the editor textarea 40 'teeny' => false, // output the minimal editor config used in Press This 41 'dfw' => false, // replace the default fullscreen with DFW (needs specific DOM elements and css) 42 'tinymce' => true, // load TinyMCE, can be used to pass settings directly to TinyMCE using an array() 43 'quicktags' => true // load Quicktags, can be used to pass settings directly to Quicktags using an array() 44 ) ); 45 46 self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() ); 47 self::$this_quicktags = (bool) $set['quicktags']; 48 49 if ( self::$this_tinymce ) 50 self::$has_tinymce = true; 51 52 if ( self::$this_quicktags ) 53 self::$has_quicktags = true; 54 55 if ( empty( $set['editor_height'] ) ) 56 return $set; 57 58 if ( 'content' === $editor_id ) { 59 // A cookie (set when a user resizes the editor) overrides the height. 60 $cookie = (int) get_user_setting( 'ed_size' ); 61 62 // Upgrade an old TinyMCE cookie if it is still around, and the new one isn't. 63 if ( ! $cookie && isset( $_COOKIE['TinyMCE_content_size'] ) ) { 64 parse_str( $_COOKIE['TinyMCE_content_size'], $cookie ); 65 $cookie = $cookie['ch']; 66 } 67 68 if ( $cookie ) 69 $set['editor_height'] = $cookie; 70 } 71 72 if ( $set['editor_height'] < 50 ) 73 $set['editor_height'] = 50; 74 elseif ( $set['editor_height'] > 5000 ) 75 $set['editor_height'] = 5000; 76 77 return $set; 78 } 79 80 /** 81 * Outputs the HTML for a single instance of the editor. 82 * 83 * @param string $content The initial content of the editor. 84 * @param string $editor_id ID for the textarea and TinyMCE and Quicktags instances (can contain only ASCII letters and numbers). 85 * @param array $settings See the _parse_settings() method for description. 86 */ 87 public static function editor( $content, $editor_id, $settings = array() ) { 88 89 $set = self::parse_settings($editor_id, $settings); 90 $editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"'; 91 $tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : ''; 92 $switch_class = 'html-active'; 93 $toolbar = $buttons = ''; 94 95 if ( ! empty( $set['editor_height'] ) ) 96 $height = ' style="height: ' . $set['editor_height'] . 'px"'; 97 else 98 $height = ' rows="' . $set['textarea_rows'] . '"'; 99 100 if ( !current_user_can( 'upload_files' ) ) 101 $set['media_buttons'] = false; 102 103 if ( self::$this_quicktags && self::$this_tinymce ) { 104 $switch_class = 'html-active'; 105 106 // 'html' and 'switch-html' are used for the "Text" editor tab. 107 if ( 'html' == wp_default_editor() ) { 108 add_filter('the_editor_content', 'wp_htmledit_pre'); 109 } else { 110 add_filter('the_editor_content', 'wp_richedit_pre'); 111 $switch_class = 'tmce-active'; 112 } 113 114 $buttons .= '<a id="' . $editor_id . '-html" class="wp-switch-editor switch-html" onclick="switchEditors.switchto(this);">' . _x( 'Text', 'Name for the Text editor tab (formerly HTML)' ) . "</a>\n"; 115 $buttons .= '<a id="' . $editor_id . '-tmce" class="wp-switch-editor switch-tmce" onclick="switchEditors.switchto(this);">' . __('Visual') . "</a>\n"; 116 } 117 118 echo '<div id="wp-' . $editor_id . '-wrap" class="wp-core-ui wp-editor-wrap ' . $switch_class . '">'; 119 120 if ( self::$editor_buttons_css ) { 121 wp_print_styles('editor-buttons'); 122 self::$editor_buttons_css = false; 123 } 124 125 if ( !empty($set['editor_css']) ) 126 echo $set['editor_css'] . "\n"; 127 128 if ( !empty($buttons) || $set['media_buttons'] ) { 129 echo '<div id="wp-' . $editor_id . '-editor-tools" class="wp-editor-tools hide-if-no-js">'; 130 131 if ( $set['media_buttons'] ) { 132 self::$has_medialib = true; 133 134 if ( !function_exists('media_buttons') ) 135 include (ABSPATH . 'wp-admin/includes/media.php'); 136 137 echo '<div id="wp-' . $editor_id . '-media-buttons" class="wp-media-buttons">'; 138 do_action('media_buttons', $editor_id); 139 echo "</div>\n"; 140 } 141 142 echo '<div class="wp-editor-tabs">' . $buttons . "</div>\n"; 143 echo "</div>\n"; 144 } 145 146 $the_editor = apply_filters('the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container"><textarea' . $editor_class . $height . $tabindex . ' cols="40" name="' . $set['textarea_name'] . '" id="' . $editor_id . '">%s</textarea></div>'); 147 $content = apply_filters('the_editor_content', $content); 148 149 printf($the_editor, $content); 150 echo "\n</div>\n\n"; 151 152 self::editor_settings($editor_id, $set); 153 } 154 155 public static function editor_settings($editor_id, $set) { 156 $first_run = false; 157 158 if ( empty(self::$first_init) ) { 159 if ( is_admin() ) { 160 add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 ); 161 add_action( 'admin_footer', array( __CLASS__, 'enqueue_scripts'), 1 ); 162 } else { 163 add_action( 'wp_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 ); 164 add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts'), 1 ); 165 } 166 } 167 168 if ( self::$this_quicktags ) { 169 170 $qtInit = array( 171 'id' => $editor_id, 172 'buttons' => '' 173 ); 174 175 if ( is_array($set['quicktags']) ) 176 $qtInit = array_merge($qtInit, $set['quicktags']); 177 178 if ( empty($qtInit['buttons']) ) 179 $qtInit['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close'; 180 181 if ( $set['dfw'] ) 182 $qtInit['buttons'] .= ',fullscreen'; 183 184 $qtInit = apply_filters('quicktags_settings', $qtInit, $editor_id); 185 self::$qt_settings[$editor_id] = $qtInit; 186 187 self::$qt_buttons = array_merge( self::$qt_buttons, explode(',', $qtInit['buttons']) ); 188 } 189 190 if ( self::$this_tinymce ) { 191 192 if ( empty(self::$first_init) ) { 193 self::$baseurl = includes_url('js/tinymce'); 194 self::$mce_locale = $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1 195 $no_captions = (bool) apply_filters( 'disable_captions', '' ); 196 $plugins = array( 'inlinepopups', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' ); 197 $first_run = true; 198 $ext_plugins = ''; 199 200 if ( $set['teeny'] ) { 201 self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array('inlinepopups', 'fullscreen', 'wordpress', 'wplink', 'wpdialogs' ), $editor_id ); 202 } else { 203 /* 204 The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'. 205 It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin. 206 The url should be absolute and should include the js file name to be loaded. Example: 207 array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' ) 208 If the plugin uses a button, it should be added with one of the "$mce_buttons" filters. 209 */ 210 $mce_external_plugins = apply_filters('mce_external_plugins', array()); 211 212 if ( ! empty($mce_external_plugins) ) { 213 214 /* 215 The following filter loads external language files for TinyMCE plugins. 216 It takes an associative array 'plugin_name' => 'path', where path is the 217 include path to the file. The language file should follow the same format as 218 /tinymce/langs/wp-langs.php and should define a variable $strings that 219 holds all translated strings. 220 When this filter is not used, the function will try to load {mce_locale}.js. 221 If that is not found, en.js will be tried next. 222 */ 223 $mce_external_languages = apply_filters('mce_external_languages', array()); 224 225 $loaded_langs = array(); 226 $strings = ''; 227 228 if ( ! empty($mce_external_languages) ) { 229 foreach ( $mce_external_languages as $name => $path ) { 230 if ( @is_file($path) && @is_readable($path) ) { 231 include_once($path); 232 $ext_plugins .= $strings . "\n"; 233 $loaded_langs[] = $name; 234 } 235 } 236 } 237 238 foreach ( $mce_external_plugins as $name => $url ) { 239 240 $url = set_url_scheme( $url ); 241 242 $plugins[] = '-' . $name; 243 244 $plugurl = dirname($url); 245 $strings = $str1 = $str2 = ''; 246 if ( ! in_array($name, $loaded_langs) ) { 247 $path = str_replace( content_url(), '', $plugurl ); 248 $path = WP_CONTENT_DIR . $path . '/langs/'; 249 250 if ( function_exists('realpath') ) 251 $path = trailingslashit( realpath($path) ); 252 253 if ( @is_file($path . $mce_locale . '.js') ) 254 $strings .= @file_get_contents($path . $mce_locale . '.js') . "\n"; 255 256 if ( @is_file($path . $mce_locale . '_dlg.js') ) 257 $strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n"; 258 259 if ( 'en' != $mce_locale && empty($strings) ) { 260 if ( @is_file($path . 'en.js') ) { 261 $str1 = @file_get_contents($path . 'en.js'); 262 $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n"; 263 } 264 265 if ( @is_file($path . 'en_dlg.js') ) { 266 $str2 = @file_get_contents($path . 'en_dlg.js'); 267 $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n"; 268 } 269 } 270 271 if ( ! empty($strings) ) 272 $ext_plugins .= "\n" . $strings . "\n"; 273 } 274 275 $ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n"; 276 $ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n"; 277 } 278 } 279 280 $plugins = array_unique( apply_filters('tiny_mce_plugins', $plugins) ); 281 } 282 283 if ( $set['dfw'] ) 284 $plugins[] = 'wpfullscreen'; 285 286 self::$plugins = $plugins; 287 self::$ext_plugins = $ext_plugins; 288 289 if ( in_array( 'spellchecker', $plugins ) ) { 290 /* 291 translators: These languages show up in the spellchecker drop-down menu, in the order specified, and with the first 292 language listed being the default language. They must be comma-separated and take the format of name=code, where name 293 is the language name (which you may internationalize), and code is a valid ISO 639 language code. Please test the 294 spellchecker with your values. 295 */ 296 $mce_spellchecker_languages = __( 'English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv' ); 297 298 /* 299 The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu. 300 By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server. 301 The + sign marks the default language. More: http://www.tinymce.com/wiki.php/Plugin:spellchecker. 302 */ 303 $mce_spellchecker_languages = apply_filters( 'mce_spellchecker_languages', '+' . $mce_spellchecker_languages ); 304 } 305 306 self::$first_init = array( 307 'mode' => 'exact', 308 'width' => '100%', 309 'theme' => 'advanced', 310 'skin' => 'wp_theme', 311 'language' => self::$mce_locale, 312 'theme_advanced_toolbar_location' => 'top', 313 'theme_advanced_toolbar_align' => 'left', 314 'theme_advanced_statusbar_location' => 'bottom', 315 'theme_advanced_resizing' => true, 316 'theme_advanced_resize_horizontal' => false, 317 'dialog_type' => 'modal', 318 'formats' => "{ 319 alignleft : [ 320 {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}}, 321 {selector : 'img,table', classes : 'alignleft'} 322 ], 323 aligncenter : [ 324 {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}}, 325 {selector : 'img,table', classes : 'aligncenter'} 326 ], 327 alignright : [ 328 {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}}, 329 {selector : 'img,table', classes : 'alignright'} 330 ], 331 strikethrough : {inline : 'del'} 332 }", 333 'relative_urls' => false, 334 'remove_script_host' => false, 335 'convert_urls' => false, 336 'remove_linebreaks' => true, 337 'gecko_spellcheck' => true, 338 'fix_list_elements' => true, 339 'keep_styles' => false, 340 'entities' => '38,amp,60,lt,62,gt', 341 'accessibility_focus' => true, 342 'media_strict' => false, 343 'paste_remove_styles' => true, 344 'paste_remove_spans' => true, 345 'paste_strip_class_attributes' => 'all', 346 'paste_text_use_dialog' => true, 347 'webkit_fake_resize' => false, 348 'preview_styles' => 'font-family font-weight text-decoration text-transform', 349 'schema' => 'html5', 350 'wpeditimage_disable_captions' => $no_captions, 351 'wp_fullscreen_content_css' => self::$baseurl . '/plugins/wpfullscreen/css/wp-fullscreen.css', 352 'plugins' => implode( ',', $plugins ) 353 ); 354 355 if ( in_array( 'spellchecker', $plugins ) ) { 356 self::$first_init['spellchecker_rpc_url'] = self::$baseurl . '/plugins/spellchecker/rpc.php'; 357 self::$first_init['spellchecker_languages'] = $mce_spellchecker_languages; 358 } 359 360 // load editor_style.css if the current theme supports it 361 if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) { 362 $editor_styles = $GLOBALS['editor_styles']; 363 364 $mce_css = array(); 365 $editor_styles = array_unique( array_filter( $editor_styles ) ); 366 $style_uri = get_stylesheet_directory_uri(); 367 $style_dir = get_stylesheet_directory(); 368 369 // Support externally referenced styles (like, say, fonts). 370 foreach ( $editor_styles as $key => $file ) { 371 if ( preg_match( '~^(https?:)?//~', $file ) ) { 372 $mce_css[] = esc_url_raw( $file ); 373 unset( $editor_styles[ $key ] ); 374 } 375 } 376 377 // Look in a parent theme first, that way child theme CSS overrides. 378 if ( is_child_theme() ) { 379 $template_uri = get_template_directory_uri(); 380 $template_dir = get_template_directory(); 381 382 foreach ( $editor_styles as $key => $file ) { 383 if ( $file && file_exists( "$template_dir/$file" ) ) 384 $mce_css[] = "$template_uri/$file"; 385 } 386 } 387 388 foreach ( $editor_styles as $file ) { 389 if ( $file && file_exists( "$style_dir/$file" ) ) 390 $mce_css[] = "$style_uri/$file"; 391 } 392 393 $mce_css = implode( ',', $mce_css ); 394 } else { 395 $mce_css = ''; 396 } 397 398 $mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' ); 399 400 if ( ! empty($mce_css) ) 401 self::$first_init['content_css'] = $mce_css; 402 } 403 404 if ( $set['teeny'] ) { 405 $mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id ); 406 $mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = array(); 407 } else { 408 $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'justifyleft', 'justifycenter', 'justifyright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id); 409 $mce_buttons_2 = apply_filters('mce_buttons_2', array( 'formatselect', 'underline', 'justifyfull', 'forecolor', 'pastetext', 'pasteword', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ), $editor_id); 410 $mce_buttons_3 = apply_filters('mce_buttons_3', array(), $editor_id); 411 $mce_buttons_4 = apply_filters('mce_buttons_4', array(), $editor_id); 412 } 413 414 $body_class = $editor_id; 415 416 if ( $post = get_post() ) { 417 $body_class .= ' post-type-' . sanitize_html_class( $post->post_type ) . ' post-status-' . sanitize_html_class( $post->post_status ); 418 if ( post_type_supports( $post->post_type, 'post-formats' ) ) { 419 $post_format = get_post_format( $post ); 420 if ( $post_format && ! is_wp_error( $post_format ) ) 421 $body_class .= ' post-format-' . sanitize_html_class( $post_format ); 422 else 423 $body_class .= ' post-format-standard'; 424 } 425 } 426 427 if ( !empty($set['tinymce']['body_class']) ) { 428 $body_class .= ' ' . $set['tinymce']['body_class']; 429 unset($set['tinymce']['body_class']); 430 } 431 432 if ( $set['dfw'] ) { 433 // replace the first 'fullscreen' with 'wp_fullscreen' 434 if ( ($key = array_search('fullscreen', $mce_buttons)) !== false ) 435 $mce_buttons[$key] = 'wp_fullscreen'; 436 elseif ( ($key = array_search('fullscreen', $mce_buttons_2)) !== false ) 437 $mce_buttons_2[$key] = 'wp_fullscreen'; 438 elseif ( ($key = array_search('fullscreen', $mce_buttons_3)) !== false ) 439 $mce_buttons_3[$key] = 'wp_fullscreen'; 440 elseif ( ($key = array_search('fullscreen', $mce_buttons_4)) !== false ) 441 $mce_buttons_4[$key] = 'wp_fullscreen'; 442 } 443 444 $mceInit = array ( 445 'elements' => $editor_id, 446 'wpautop' => (bool) $set['wpautop'], 447 'remove_linebreaks' => (bool) $set['wpautop'], 448 'apply_source_formatting' => (bool) !$set['wpautop'], 449 'theme_advanced_buttons1' => implode($mce_buttons, ','), 450 'theme_advanced_buttons2' => implode($mce_buttons_2, ','), 451 'theme_advanced_buttons3' => implode($mce_buttons_3, ','), 452 'theme_advanced_buttons4' => implode($mce_buttons_4, ','), 453 'tabfocus_elements' => $set['tabfocus_elements'], 454 'body_class' => $body_class 455 ); 456 457 // The main editor doesn't use the TinyMCE resizing cookie. 458 $mceInit['theme_advanced_resizing_use_cookie'] = 'content' !== $editor_id || empty( $set['editor_height'] ); 459 460 if ( $first_run ) 461 $mceInit = array_merge(self::$first_init, $mceInit); 462 463 if ( is_array($set['tinymce']) ) 464 $mceInit = array_merge($mceInit, $set['tinymce']); 465 466 // For people who really REALLY know what they're doing with TinyMCE 467 // You can modify $mceInit to add, remove, change elements of the config before tinyMCE.init 468 // Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through this filter. 469 // Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0. 470 if ( $set['teeny'] ) { 471 $mceInit = apply_filters('teeny_mce_before_init', $mceInit, $editor_id); 472 } else { 473 $mceInit = apply_filters('tiny_mce_before_init', $mceInit, $editor_id); 474 } 475 476 if ( empty($mceInit['theme_advanced_buttons3']) && !empty($mceInit['theme_advanced_buttons4']) ) { 477 $mceInit['theme_advanced_buttons3'] = $mceInit['theme_advanced_buttons4']; 478 $mceInit['theme_advanced_buttons4'] = ''; 479 } 480 481 self::$mce_settings[$editor_id] = $mceInit; 482 } // end if self::$this_tinymce 483 } 484 485 private static function _parse_init($init) { 486 $options = ''; 487 488 foreach ( $init as $k => $v ) { 489 if ( is_bool($v) ) { 490 $val = $v ? 'true' : 'false'; 491 $options .= $k . ':' . $val . ','; 492 continue; 493 } elseif ( !empty($v) && is_string($v) && ( ('{' == $v{0} && '}' == $v{strlen($v) - 1}) || ('[' == $v{0} && ']' == $v{strlen($v) - 1}) || preg_match('/^\(?function ?\(/', $v) ) ) { 494 $options .= $k . ':' . $v . ','; 495 continue; 496 } 497 $options .= $k . ':"' . $v . '",'; 498 } 499 500 return '{' . trim( $options, ' ,' ) . '}'; 501 } 502 503 public static function enqueue_scripts() { 504 wp_enqueue_script('word-count'); 505 506 if ( self::$has_tinymce ) 507 wp_enqueue_script('editor'); 508 509 if ( self::$has_quicktags ) 510 wp_enqueue_script('quicktags'); 511 512 if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) { 513 wp_enqueue_script('wplink'); 514 wp_enqueue_script('wpdialogs-popup'); 515 wp_enqueue_style('wp-jquery-ui-dialog'); 516 } 517 518 if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) ) 519 wp_enqueue_script('wp-fullscreen'); 520 521 if ( self::$has_medialib ) { 522 add_thickbox(); 523 wp_enqueue_script('media-upload'); 524 } 525 } 526 527 public static function editor_js() { 528 global $tinymce_version, $concatenate_scripts, $compress_scripts; 529 530 /** 531 * Filter "tiny_mce_version" is deprecated 532 * 533 * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE. 534 * These plugins can be refreshed by appending query string to the URL passed to "mce_external_plugins" filter. 535 * If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code). 536 */ 537 $version = 'ver=' . $tinymce_version; 538 $tmce_on = !empty(self::$mce_settings); 539 540 if ( ! isset($concatenate_scripts) ) 541 script_concat_settings(); 542 543 $compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING']) 544 && false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'); 545 546 if ( $tmce_on && 'en' != self::$mce_locale ) 547 include_once (ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php'); 548 549 $mceInit = $qtInit = ''; 550 if ( $tmce_on ) { 551 foreach ( self::$mce_settings as $editor_id => $init ) { 552 $options = self::_parse_init( $init ); 553 $mceInit .= "'$editor_id':{$options},"; 554 } 555 $mceInit = '{' . trim($mceInit, ',') . '}'; 556 } else { 557 $mceInit = '{}'; 558 } 559 560 if ( !empty(self::$qt_settings) ) { 561 foreach ( self::$qt_settings as $editor_id => $init ) { 562 $options = self::_parse_init( $init ); 563 $qtInit .= "'$editor_id':{$options},"; 564 } 565 $qtInit = '{' . trim($qtInit, ',') . '}'; 566 } else { 567 $qtInit = '{}'; 568 } 569 570 $ref = array( 571 'plugins' => implode( ',', self::$plugins ), 572 'theme' => 'advanced', 573 'language' => self::$mce_locale 574 ); 575 576 $suffix = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ? '_src' : ''; 577 578 do_action('before_wp_tiny_mce', self::$mce_settings); 579 ?> 580 581 <script type="text/javascript"> 582 tinyMCEPreInit = { 583 base : "<?php echo self::$baseurl; ?>", 584 suffix : "<?php echo $suffix; ?>", 585 query : "<?php echo $version; ?>", 586 mceInit : <?php echo $mceInit; ?>, 587 qtInit : <?php echo $qtInit; ?>, 588 ref : <?php echo self::_parse_init( $ref ); ?>, 589 load_ext : function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');} 590 }; 591 </script> 592 <?php 593 594 $baseurl = self::$baseurl; 595 596 if ( $tmce_on ) { 597 if ( $compressed ) { 598 echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&$version'></script>\n"; 599 } else { 600 echo "<script type='text/javascript' src='{$baseurl}/tiny_mce.js?$version'></script>\n"; 601 echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce-schema.js?$version'></script>\n"; 602 } 603 604 if ( 'en' != self::$mce_locale && isset($lang) ) 605 echo "<script type='text/javascript'>\n$lang\n</script>\n"; 606 else 607 echo "<script type='text/javascript' src='{$baseurl}/langs/wp-langs-en.js?$version'></script>\n"; 608 } 609 610 $mce = ( self::$has_tinymce && wp_default_editor() == 'tinymce' ) || ! self::$has_quicktags; 611 ?> 612 613 <script type="text/javascript"> 614 var wpActiveEditor; 615 616 (function(){ 617 var init, ed, qt, first_init, DOM, el, i, mce = <?php echo (int) $mce; ?>; 618 619 if ( typeof(tinymce) == 'object' ) { 620 DOM = tinymce.DOM; 621 // mark wp_theme/ui.css as loaded 622 DOM.files[tinymce.baseURI.getURI() + '/themes/advanced/skins/wp_theme/ui.css'] = true; 623 624 DOM.events.add( DOM.select('.wp-editor-wrap'), 'mousedown', function(e){ 625 if ( this.id ) 626 wpActiveEditor = this.id.slice(3, -5); 627 }); 628 629 for ( ed in tinyMCEPreInit.mceInit ) { 630 if ( first_init ) { 631 init = tinyMCEPreInit.mceInit[ed] = tinymce.extend( {}, first_init, tinyMCEPreInit.mceInit[ed] ); 632 } else { 633 init = first_init = tinyMCEPreInit.mceInit[ed]; 634 } 635 636 if ( mce ) 637 try { tinymce.init(init); } catch(e){} 638 } 639 } else { 640 if ( tinyMCEPreInit.qtInit ) { 641 for ( i in tinyMCEPreInit.qtInit ) { 642 el = tinyMCEPreInit.qtInit[i].id; 643 if ( el ) 644 document.getElementById('wp-'+el+'-wrap').onmousedown = function(){ wpActiveEditor = this.id.slice(3, -5); } 645 } 646 } 647 } 648 649 if ( typeof(QTags) == 'function' ) { 650 for ( qt in tinyMCEPreInit.qtInit ) { 651 try { quicktags( tinyMCEPreInit.qtInit[qt] ); } catch(e){} 652 } 653 } 654 })(); 655 <?php 656 657 if ( self::$ext_plugins ) 658 echo self::$ext_plugins . "\n"; 659 660 if ( ! $compressed && $tmce_on ) { 661 ?> 662 (function(){var t=tinyMCEPreInit,sl=tinymce.ScriptLoader,ln=t.ref.language,th=t.ref.theme,pl=t.ref.plugins;sl.markDone(t.base+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'_dlg.js');sl.markDone(t.base+'/themes/advanced/skins/wp_theme/ui.css');tinymce.each(pl.split(','),function(n){if(n&&n.charAt(0)!='-'){sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'.js');sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'_dlg.js');}});})(); 663 <?php 664 } 665 666 if ( !is_admin() ) 667 echo 'var ajaxurl = "' . admin_url( 'admin-ajax.php', 'relative' ) . '";'; 668 669 ?> 670 </script> 671 <?php 672 673 if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) 674 self::wp_link_dialog(); 675 676 if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) ) 677 self::wp_fullscreen_html(); 678 679 do_action('after_wp_tiny_mce', self::$mce_settings); 680 } 681 682 public static function wp_fullscreen_html() { 683 global $content_width; 684 $post = get_post(); 685 686 $width = isset($content_width) && 800 > $content_width ? $content_width : 800; 687 $width = $width + 22; // compensate for the padding and border 688 $dfw_width = get_user_setting( 'dfw_width', $width ); 689 $save = isset($post->post_status) && $post->post_status == 'publish' ? __('Update') : __('Save'); 690 ?> 691 <div id="wp-fullscreen-body"<?php if ( is_rtl() ) echo ' class="rtl"'; ?>> 692 <div id="fullscreen-topbar"> 693 <div id="wp-fullscreen-toolbar"> 694 <div id="wp-fullscreen-close"><a href="#" onclick="fullscreen.off();return false;"><?php _e('Exit fullscreen'); ?></a></div> 695 <div id="wp-fullscreen-central-toolbar" style="width:<?php echo $width; ?>px;"> 696 697 <div id="wp-fullscreen-mode-bar"><div id="wp-fullscreen-modes"> 698 <a href="#" onclick="fullscreen.switchmode('tinymce');return false;"><?php _e( 'Visual' ); ?></a> 699 <a href="#" onclick="fullscreen.switchmode('html');return false;"><?php _ex( 'Text', 'Name for the Text editor tab (formerly HTML)' ); ?></a> 700 </div></div> 701 702 <div id="wp-fullscreen-button-bar"><div id="wp-fullscreen-buttons" class="wp_themeSkin"> 703 <?php 704 705 $buttons = array( 706 // format: title, onclick, show in both editors 707 'bold' => array( 'title' => __('Bold (Ctrl + B)'), 'onclick' => 'fullscreen.b();', 'both' => false ), 708 'italic' => array( 'title' => __('Italic (Ctrl + I)'), 'onclick' => 'fullscreen.i();', 'both' => false ), 709 '0' => 'separator', 710 'bullist' => array( 'title' => __('Unordered list (Alt + Shift + U)'), 'onclick' => 'fullscreen.ul();', 'both' => false ), 711 'numlist' => array( 'title' => __('Ordered list (Alt + Shift + O)'), 'onclick' => 'fullscreen.ol();', 'both' => false ), 712 '1' => 'separator', 713 'blockquote' => array( 'title' => __('Blockquote (Alt + Shift + Q)'), 'onclick' => 'fullscreen.blockquote();', 'both' => false ), 714 'image' => array( 'title' => __('Insert/edit image (Alt + Shift + M)'), 'onclick' => "fullscreen.medialib();", 'both' => true ), 715 '2' => 'separator', 716 'link' => array( 'title' => __('Insert/edit link (Alt + Shift + A)'), 'onclick' => 'fullscreen.link();', 'both' => true ), 717 'unlink' => array( 'title' => __('Unlink (Alt + Shift + S)'), 'onclick' => 'fullscreen.unlink();', 'both' => false ), 718 '3' => 'separator', 719 'help' => array( 'title' => __('Help (Alt + Shift + H)'), 'onclick' => 'fullscreen.help();', 'both' => false ) 720 ); 721 722 $buttons = apply_filters( 'wp_fullscreen_buttons', $buttons ); 723 724 foreach ( $buttons as $button => $args ) { 725 if ( 'separator' == $args ) { ?> 726 <div><span aria-orientation="vertical" role="separator" class="mceSeparator"></span></div> 727 <?php continue; 728 } ?> 729 730 <div<?php if ( $args['both'] ) { ?> class="wp-fullscreen-both"<?php } ?>> 731 <a title="<?php echo $args['title']; ?>" onclick="<?php echo $args['onclick']; ?>return false;" class="mceButton mceButtonEnabled mce_<?php echo $button; ?>" href="#" id="wp_fs_<?php echo $button; ?>" role="button" aria-pressed="false"> 732 <span class="mceIcon mce_<?php echo $button; ?>"></span> 733 </a> 734 </div> 735 <?php 736 } ?> 737 738 </div></div> 739 740 <div id="wp-fullscreen-save"> 741 <input type="button" class="button-primary right" value="<?php echo $save; ?>" onclick="fullscreen.save();" /> 742 <span class="spinner"></span> 743 <span class="fs-saved"><?php if ( $post->post_status == 'publish' ) _e('Updated.'); else _e('Saved.'); ?></span> 744 </div> 745 746 </div> 747 </div> 748 </div> 749 750 <div id="wp-fullscreen-wrap" style="width:<?php echo $dfw_width; ?>px;"> 751 <?php if ( post_type_supports($post->post_type, 'title') ) { ?> 752 <label id="wp-fullscreen-title-prompt-text" for="wp-fullscreen-title"><?php echo apply_filters( 'enter_title_here', __( 'Enter title here' ), $post ); ?></label> 753 <input type="text" id="wp-fullscreen-title" value="" autocomplete="off" /> 754 <?php } ?> 755 756 <div id="wp-fullscreen-container"> 757 <textarea id="wp_mce_fullscreen"></textarea> 758 </div> 759 760 <div id="wp-fullscreen-status"> 761 <div id="wp-fullscreen-count"><?php printf( __( 'Word count: %s' ), '<span class="word-count">0</span>' ); ?></div> 762 <div id="wp-fullscreen-tagline"><?php _e('Just write.'); ?></div> 763 </div> 764 </div> 765 </div> 766 767 <div class="fullscreen-overlay" id="fullscreen-overlay"></div> 768 <div class="fullscreen-overlay fullscreen-fader fade-600" id="fullscreen-fader"></div> 769 <?php 770 } 771 772 /** 773 * Performs post queries for internal linking. 774 * 775 * @since 3.1.0 776 * 777 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments. 778 * @return array Results. 779 */ 780 public static function wp_link_query( $args = array() ) { 781 $pts = get_post_types( array( 'public' => true ), 'objects' ); 782 $pt_names = array_keys( $pts ); 783 784 $query = array( 785 'post_type' => $pt_names, 786 'suppress_filters' => true, 787 'update_post_term_cache' => false, 788 'update_post_meta_cache' => false, 789 'post_status' => 'publish', 790 'posts_per_page' => 20, 791 ); 792 793 $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1; 794 795 if ( isset( $args['s'] ) ) 796 $query['s'] = $args['s']; 797 798 $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0; 799 800 /** 801 * Filter the link query arguments. 802 * 803 * Allows modification of the link query arguments before querying. 804 * 805 * @see WP_Query for a full list of arguments 806 * 807 * @since 3.7.0 808 * 809 * @param array $query An array of WP_Query arguments. 810 */ 811 $query = apply_filters( 'wp_link_query_args', $query ); 812 813 // Do main query. 814 $get_posts = new WP_Query; 815 $posts = $get_posts->query( $query ); 816 // Check if any posts were found. 817 if ( ! $get_posts->post_count ) 818 return false; 819 820 // Build results. 821 $results = array(); 822 foreach ( $posts as $post ) { 823 if ( 'post' == $post->post_type ) 824 $info = mysql2date( __( 'Y/m/d' ), $post->post_date ); 825 else 826 $info = $pts[ $post->post_type ]->labels->singular_name; 827 828 $results[] = array( 829 'ID' => $post->ID, 830 'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ), 831 'permalink' => get_permalink( $post->ID ), 832 'info' => $info, 833 ); 834 } 835 836 /** 837 * Filter the link query results. 838 * 839 * Allows modification of the returned link query results. 840 * 841 * @since 3.7.0 842 * 843 * @param array $results { 844 * An associative array of query results. 845 * 846 * @type array { 847 * @type int 'ID' The post ID. 848 * @type string 'title' The trimmed, escaped post title. 849 * @type string 'permalink' The post permalink. 850 * @type string 'info' A 'Y/m/d'-formatted date for 'post' post type, the 'singular_name' post type label otherwise. 851 * } 852 * } 853 * @param array $query An array of WP_Query arguments. @see 'wp_link_query_args' filter 854 */ 855 return apply_filters( 'wp_link_query', $results, $query ); 856 } 857 858 /** 859 * Dialog for internal linking. 860 * 861 * @since 3.1.0 862 */ 863 public static function wp_link_dialog() { 864 ?> 865 <div style="display:none;"> 866 <form id="wp-link" tabindex="-1"> 867 <?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?> 868 <div id="link-selector"> 869 <div id="link-options"> 870 <p class="howto"><?php _e( 'Enter the destination URL' ); ?></p> 871 <div> 872 <label><span><?php _e( 'URL' ); ?></span><input id="url-field" type="text" name="href" /></label> 873 </div> 874 <div> 875 <label><span><?php _e( 'Title' ); ?></span><input id="link-title-field" type="text" name="linktitle" /></label> 876 </div> 877 <div class="link-target"> 878 <label><input type="checkbox" id="link-target-checkbox" /> <?php _e( 'Open link in a new window/tab' ); ?></label> 879 </div> 880 </div> 881 <?php $show_internal = '1' == get_user_setting( 'wplink', '0' ); ?> 882 <p class="howto toggle-arrow <?php if ( $show_internal ) echo 'toggle-arrow-active'; ?>" id="internal-toggle"><?php _e( 'Or link to existing content' ); ?></p> 883 <div id="search-panel"<?php if ( ! $show_internal ) echo ' style="display:none"'; ?>> 884 <div class="link-search-wrapper"> 885 <label> 886 <span class="search-label"><?php _e( 'Search' ); ?></span> 887 <input type="search" id="search-field" class="link-search-field" autocomplete="off" /> 888 <span class="spinner"></span> 889 </label> 890 </div> 891 <div id="search-results" class="query-results"> 892 <ul></ul> 893 <div class="river-waiting"> 894 <span class="spinner"></span> 895 </div> 896 </div> 897 <div id="most-recent-results" class="query-results"> 898 <div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div> 899 <ul></ul> 900 <div class="river-waiting"> 901 <span class="spinner"></span> 902 </div> 903 </div> 904 </div> 905 </div> 906 <div class="submitbox"> 907 <div id="wp-link-update"> 908 <input type="submit" value="<?php esc_attr_e( 'Add Link' ); ?>" class="button-primary" id="wp-link-submit" name="wp-link-submit"> 909 </div> 910 <div id="wp-link-cancel"> 911 <a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a> 912 </div> 913 </div> 914 </form> 915 </div> 916 <?php 917 } 918 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |