PageRenderTime 264ms CodeModel.GetById 111ms app.highlight 105ms RepoModel.GetById 36ms app.codeStats 0ms

/wp-includes/class-wp-editor.php

https://bitbucket.org/Wallynm/iptb
PHP | 798 lines | 598 code | 132 blank | 68 comment | 130 complexity | 344076ae1d5cfc1a2aaf0e49af5a223b MD5 | raw file
  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
  7 *
  8 * Private, not included by default. See wp_editor() in wp-includes/general-template.php.
  9 */
 10
 11final 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' => get_option('default_post_edit_rows', 10), // rows="..."
 36			'tabindex' => '',
 37			'editor_css' => '', // intended for extra styles for both visual and HTML editors buttons, needs to include the <style> tags, can use "scoped".
 38			'editor_class' => '', // add extra class(es) to the editor textarea
 39			'teeny' => false, // output the minimal editor config used in Press This
 40			'dfw' => false, // replace the default fullscreen with DFW (needs specific DOM elements and css)
 41			'tinymce' => true, // load TinyMCE, can be used to pass settings directly to TinyMCE using an array()
 42			'quicktags' => true // load Quicktags, can be used to pass settings directly to Quicktags using an array()
 43		) );
 44
 45		self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() );
 46		self::$this_quicktags = (bool) $set['quicktags'];
 47
 48		if ( self::$this_tinymce )
 49			self::$has_tinymce = true;
 50
 51		if ( self::$this_quicktags )
 52			self::$has_quicktags = true;
 53
 54		return $set;
 55	}
 56
 57	/**
 58	 * Outputs the HTML for a single instance of the editor.
 59	 *
 60	 * @param string $content The initial content of the editor.
 61	 * @param string $editor_id ID for the textarea and TinyMCE and Quicktags instances (can contain only ASCII letters and numbers).
 62	 * @param array $settings See the _parse_settings() method for description.
 63	 */
 64	public static function editor( $content, $editor_id, $settings = array() ) {
 65
 66		$set = self::parse_settings($editor_id, $settings);
 67		$editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"';
 68		$tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : '';
 69		$rows = ' rows="' . (int) $set['textarea_rows'] . '"';
 70		$switch_class = 'html-active';
 71		$toolbar = $buttons = '';
 72
 73		if ( !current_user_can( 'upload_files' ) )
 74			$set['media_buttons'] = false;
 75
 76		if ( self::$this_quicktags && self::$this_tinymce ) {
 77			$switch_class = 'html-active';
 78
 79			if ( 'html' == wp_default_editor() ) {
 80				add_filter('the_editor_content', 'wp_htmledit_pre');
 81			} else {
 82				add_filter('the_editor_content', 'wp_richedit_pre');
 83				$switch_class = 'tmce-active';
 84			}
 85
 86			$buttons .= '<a id="' . $editor_id . '-html" class="hide-if-no-js wp-switch-editor switch-html" onclick="switchEditors.switchto(this);">' . __('HTML') . "</a>\n";
 87			$buttons .= '<a id="' . $editor_id . '-tmce" class="hide-if-no-js wp-switch-editor switch-tmce" onclick="switchEditors.switchto(this);">' . __('Visual') . "</a>\n";
 88		}
 89
 90		echo '<div id="wp-' . $editor_id . '-wrap" class="wp-editor-wrap ' . $switch_class . '">';
 91
 92		if ( self::$editor_buttons_css ) {
 93			wp_print_styles('editor-buttons');
 94			self::$editor_buttons_css = false;
 95		}
 96
 97		if ( !empty($set['editor_css']) )
 98			echo $set['editor_css'] . "\n";
 99
100		if ( !empty($buttons) || $set['media_buttons'] ) {
101			echo '<div id="wp-' . $editor_id . '-editor-tools" class="wp-editor-tools">';
102			echo $buttons;
103
104			if ( $set['media_buttons'] ) {
105				self::$has_medialib = true;
106
107				if ( !function_exists('media_buttons') )
108					include(ABSPATH . 'wp-admin/includes/media.php');
109
110				echo '<div id="wp-' . $editor_id . '-media-buttons" class="hide-if-no-js wp-media-buttons">';
111				do_action('media_buttons', $editor_id);
112				echo "</div>\n";
113			}
114			echo "</div>\n";
115		}
116
117		$the_editor = apply_filters('the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container"><textarea' . $editor_class . $rows . $tabindex . ' cols="40" name="' . $set['textarea_name'] . '" id="' . $editor_id . '">%s</textarea></div>');
118		$content = apply_filters('the_editor_content', $content);
119
120		printf($the_editor, $content);
121		echo "\n</div>\n\n";
122
123		self::editor_settings($editor_id, $set);
124	}
125
126	public static function editor_settings($editor_id, $set) {
127		global $editor_styles;
128		$first_run = false;
129
130		if ( empty(self::$first_init) ) {
131			if ( is_admin() ) {
132				add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 );
133				add_action( 'admin_footer', array( __CLASS__, 'enqueue_scripts'), 1 );
134			} else {
135				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 );
136				add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts'), 1 );
137			}
138		}
139
140		if ( self::$this_quicktags ) {
141
142			$qtInit = array(
143				'id' => $editor_id,
144				'buttons' => ''
145			);
146
147			if ( is_array($set['quicktags']) )
148				$qtInit = array_merge($qtInit, $set['quicktags']);
149
150			if ( empty($qtInit['buttons']) )
151				$qtInit['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,spell,close';
152
153			if ( $set['dfw'] )
154				$qtInit['buttons'] .= ',fullscreen';
155
156			$qtInit = apply_filters('quicktags_settings', $qtInit, $editor_id);
157			self::$qt_settings[$editor_id] = $qtInit;
158
159			self::$qt_buttons = array_merge( self::$qt_buttons, explode(',', $qtInit['buttons']) );
160		}
161
162		if ( self::$this_tinymce ) {
163
164			if ( empty(self::$first_init) ) {
165				self::$baseurl = includes_url('js/tinymce');
166				self::$mce_locale = $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
167				$no_captions = (bool) apply_filters( 'disable_captions', '' );
168				$plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' );
169				$first_run = true;
170
171				if ( $set['teeny'] ) {
172					self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array('inlinepopups', 'fullscreen', 'wordpress', 'wplink', 'wpdialogs'), $editor_id );
173					$ext_plugins = '';
174				} else {
175					/*
176					The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'.
177					It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin.
178					The url should be absolute and should include the js file name to be loaded. Example:
179					array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' )
180					If the plugin uses a button, it should be added with one of the "$mce_buttons" filters.
181					*/
182					$mce_external_plugins = apply_filters('mce_external_plugins', array());
183
184					$ext_plugins = '';
185					if ( ! empty($mce_external_plugins) ) {
186
187						/*
188						The following filter loads external language files for TinyMCE plugins.
189						It takes an associative array 'plugin_name' => 'path', where path is the
190						include path to the file. The language file should follow the same format as
191						/tinymce/langs/wp-langs.php and should define a variable $strings that
192						holds all translated strings.
193						When this filter is not used, the function will try to load {mce_locale}.js.
194						If that is not found, en.js will be tried next.
195						*/
196						$mce_external_languages = apply_filters('mce_external_languages', array());
197
198						$loaded_langs = array();
199						$strings = '';
200
201						if ( ! empty($mce_external_languages) ) {
202							foreach ( $mce_external_languages as $name => $path ) {
203								if ( @is_file($path) && @is_readable($path) ) {
204									include_once($path);
205									$ext_plugins .= $strings . "\n";
206									$loaded_langs[] = $name;
207								}
208							}
209						}
210
211						foreach ( $mce_external_plugins as $name => $url ) {
212
213							if ( is_ssl() ) $url = str_replace('http://', 'https://', $url);
214
215							$plugins[] = '-' . $name;
216
217							$plugurl = dirname($url);
218							$strings = $str1 = $str2 = '';
219							if ( ! in_array($name, $loaded_langs) ) {
220								$path = str_replace( content_url(), '', $plugurl );
221								$path = WP_CONTENT_DIR . $path . '/langs/';
222
223								if ( function_exists('realpath') )
224									$path = trailingslashit( realpath($path) );
225
226								if ( @is_file($path . $mce_locale . '.js') )
227									$strings .= @file_get_contents($path . $mce_locale . '.js') . "\n";
228
229								if ( @is_file($path . $mce_locale . '_dlg.js') )
230									$strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n";
231
232								if ( 'en' != $mce_locale && empty($strings) ) {
233									if ( @is_file($path . 'en.js') ) {
234										$str1 = @file_get_contents($path . 'en.js');
235										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n";
236									}
237
238									if ( @is_file($path . 'en_dlg.js') ) {
239										$str2 = @file_get_contents($path . 'en_dlg.js');
240										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n";
241									}
242								}
243
244								if ( ! empty($strings) )
245									$ext_plugins .= "\n" . $strings . "\n";
246							}
247
248							$ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
249							$ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
250
251							self::$ext_plugins .= $ext_plugins;
252						}
253					}
254
255					$plugins = array_unique( apply_filters('tiny_mce_plugins', $plugins) );
256				}
257
258				if ( $set['dfw'] )
259					$plugins[] = 'wpfullscreen';
260
261				self::$plugins = $plugins;
262
263				/*
264				The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu.
265				By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server.
266				The + sign marks the default language. More information:
267				http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
268				*/
269				$mce_spellchecker_languages = apply_filters('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');
270
271				self::$first_init = array(
272					'mode' => 'exact',
273					'width' => '100%',
274					'theme' => 'advanced',
275					'skin' => 'wp_theme',
276					'language' => self::$mce_locale,
277					'spellchecker_languages' => $mce_spellchecker_languages,
278					'theme_advanced_toolbar_location' => 'top',
279					'theme_advanced_toolbar_align' => 'left',
280					'theme_advanced_statusbar_location' => 'bottom',
281					'theme_advanced_resizing' => true,
282					'theme_advanced_resize_horizontal' => false,
283					'dialog_type' => 'modal',
284					'formats' => "{
285						alignleft : [
286							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}},
287							{selector : 'img,table', classes : 'alignleft'}
288						],
289						aligncenter : [
290							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}},
291							{selector : 'img,table', classes : 'aligncenter'}
292						],
293						alignright : [
294							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}},
295							{selector : 'img,table', classes : 'alignright'}
296						],
297						strikethrough : {inline : 'del'}
298					}",
299					'relative_urls' => false,
300					'remove_script_host' => false,
301					'convert_urls' => false,
302					'remove_linebreaks' => true,
303					'gecko_spellcheck' => true,
304					'keep_styles' => false,
305					'entities' => '38,amp,60,lt,62,gt',
306					'accessibility_focus' => true,
307					'tabfocus_elements' => 'major-publishing-actions',
308					'media_strict' => false,
309					'paste_remove_styles' => true,
310					'paste_remove_spans' => true,
311					'paste_strip_class_attributes' => 'all',
312					'paste_text_use_dialog' => true,
313					'extended_valid_elements' => 'article[*],aside[*],audio[*],canvas[*],command[*],datalist[*],details[*],embed[*],figcaption[*],figure[*],footer[*],header[*],hgroup[*],keygen[*],mark[*],meter[*],nav[*],output[*],progress[*],section[*],source[*],summary,time[*],video[*],wbr',
314					'wpeditimage_disable_captions' => $no_captions,
315					'wp_fullscreen_content_css' => self::$baseurl . '/plugins/wpfullscreen/css/wp-fullscreen.css',
316					'plugins' => implode( ',', $plugins )
317				);
318
319				// load editor_style.css if the current theme supports it
320				if ( ! empty( $editor_styles ) && is_array( $editor_styles ) ) {
321					$mce_css = array();
322					$editor_styles = array_unique($editor_styles);
323					$style_uri = get_stylesheet_directory_uri();
324					if ( ! is_child_theme() ) {
325						foreach ( $editor_styles as $file )
326							$mce_css[] = "$style_uri/$file";
327					} else {
328						$style_dir    = get_stylesheet_directory();
329						$template_uri = get_template_directory_uri();
330						$template_dir = get_template_directory();
331
332						foreach ( $editor_styles as $file ) {
333							if ( file_exists( "$template_dir/$file" ) )
334								$mce_css[] = "$template_uri/$file";
335						}
336
337						foreach ( $editor_styles as $file ) {
338							if ( file_exists( "$style_dir/$file" ) )
339								$mce_css[] = "$style_uri/$file";
340						}
341					}
342					$mce_css = implode( ',', $mce_css );
343				} else {
344					$mce_css = '';
345				}
346
347				$mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' );
348
349				if ( ! empty($mce_css) )
350					self::$first_init['content_css'] = $mce_css;
351			}
352
353			if ( $set['teeny'] ) {
354				$mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'separator', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id );
355				$mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = array();
356			} else {
357				$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);
358				$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);
359				$mce_buttons_3 = apply_filters('mce_buttons_3', array(), $editor_id);
360				$mce_buttons_4 = apply_filters('mce_buttons_4', array(), $editor_id);
361			}
362
363			if ( $set['dfw'] ) {
364				// replace the first 'fullscreen' with 'wp_fullscreen'
365				if ( ($key = array_search('fullscreen', $mce_buttons)) !== false )
366					$mce_buttons[$key] = 'wp_fullscreen';
367				elseif ( ($key = array_search('fullscreen', $mce_buttons_2)) !== false )
368					$mce_buttons_2[$key] = 'wp_fullscreen';
369				elseif ( ($key = array_search('fullscreen', $mce_buttons_3)) !== false )
370					$mce_buttons_3[$key] = 'wp_fullscreen';
371				elseif ( ($key = array_search('fullscreen', $mce_buttons_4)) !== false )
372					$mce_buttons_4[$key] = 'wp_fullscreen';
373			}
374
375			$mceInit = array (
376				'elements' => $editor_id,
377				'wpautop' => (bool) $set['wpautop'],
378				'remove_linebreaks' => (bool) $set['wpautop'],
379				'apply_source_formatting' => (bool) !$set['wpautop'],
380				'theme_advanced_buttons1' => implode($mce_buttons, ','),
381				'theme_advanced_buttons2' => implode($mce_buttons_2, ','),
382				'theme_advanced_buttons3' => implode($mce_buttons_3, ','),
383				'theme_advanced_buttons4' => implode($mce_buttons_4, ',')
384			);
385
386			if ( $first_run )
387				$mceInit = array_merge(self::$first_init, $mceInit);
388
389			if ( is_array($set['tinymce']) )
390				$mceInit = array_merge($mceInit, $set['tinymce']);
391
392			// For people who really REALLY know what they're doing with TinyMCE
393			// You can modify initArray to add, remove, change elements of the config before tinyMCE.init
394			// Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through this filter.
395			// Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0.
396			if ( $set['teeny'] ) {
397				$mceInit = apply_filters('teeny_mce_before_init', $mceInit, $editor_id);
398			} else {
399				$mceInit = apply_filters('tiny_mce_before_init', $mceInit, $editor_id);
400			}
401
402			if ( empty($mceInit['theme_advanced_buttons3']) && !empty($mceInit['theme_advanced_buttons4']) ) {
403				$mceInit['theme_advanced_buttons3'] = $mceInit['theme_advanced_buttons4'];
404				$mceInit['theme_advanced_buttons4'] = '';
405			}
406
407			self::$mce_settings[$editor_id] = $mceInit;
408		} // end if self::$this_tinymce
409	}
410
411	private static function _parse_init($init) {
412		$options = '';
413
414		foreach ( $init as $k => $v ) {
415			if ( is_bool($v) ) {
416				$val = $v ? 'true' : 'false';
417				$options .= $k . ':' . $val . ',';
418				continue;
419			} elseif ( !empty($v) && is_string($v) && ( ('{' == $v{0} && '}' == $v{strlen($v) - 1}) || ('[' == $v{0} && ']' == $v{strlen($v) - 1}) || preg_match('/^\(?function ?\(/', $v) ) ) {
420				$options .= $k . ':' . $v . ',';
421				continue;
422			}
423			$options .= $k . ':"' . $v . '",';
424		}
425
426		return '{' . trim( $options, ' ,' ) . '}';
427	}
428
429	public static function enqueue_scripts() {
430		wp_enqueue_script('word-count');
431
432		if ( self::$has_tinymce )
433			wp_enqueue_script('editor');
434
435		if ( self::$has_quicktags )
436			wp_enqueue_script('quicktags');
437
438		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) {
439			wp_enqueue_script('wplink');
440			wp_enqueue_script('wpdialogs-popup');
441			wp_enqueue_style('wp-jquery-ui-dialog');
442		}
443
444		if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
445			wp_enqueue_script('wp-fullscreen');
446
447		if ( self::$has_medialib ) {
448			add_thickbox();
449			wp_enqueue_script('media-upload');
450		}
451	}
452
453	public static function editor_js() {
454		global $tinymce_version, $concatenate_scripts, $compress_scripts;
455
456		/**
457		 * Filter "tiny_mce_version" is deprecated
458		 *
459		 * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE.
460		 * These plugins can be refreshed by appending query string to the URL passed to "mce_external_plugins" filter.
461		 * 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).
462		 */
463		$version = 'ver=' . $tinymce_version;
464		$tmce_on = !empty(self::$mce_settings);
465
466		if ( ! isset($concatenate_scripts) )
467			script_concat_settings();
468
469		$compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
470			&& false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
471
472		if ( $tmce_on && 'en' != self::$mce_locale )
473			include_once(ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php');
474
475		$mceInit = $qtInit = '';
476		if ( $tmce_on ) {
477			foreach ( self::$mce_settings as $editor_id => $init ) {
478				$options = self::_parse_init( $init );
479				$mceInit .= "'$editor_id':{$options},";
480			}
481			$mceInit = '{' . trim($mceInit, ',') . '}';
482		} else {
483			$mceInit = '{}';
484		}
485
486		if ( !empty(self::$qt_settings) ) {
487			foreach ( self::$qt_settings as $editor_id => $init ) {
488				$options = self::_parse_init( $init );
489				$qtInit .= "'$editor_id':{$options},";
490			}
491			$qtInit = '{' . trim($qtInit, ',') . '}';
492		} else {
493			$qtInit = '{}';
494		}
495
496		$ref = array(
497			'plugins' => implode( ',', self::$plugins ),
498			'theme' => 'advanced',
499			'language' => self::$mce_locale
500		);
501
502		do_action('before_wp_tiny_mce', self::$mce_settings);
503?>
504
505	<script type="text/javascript">
506		tinyMCEPreInit = {
507			base : "<?php echo self::$baseurl; ?>",
508			suffix : "",
509			query : "<?php echo $version; ?>",
510			mceInit : <?php echo $mceInit; ?>,
511			qtInit : <?php echo $qtInit; ?>,
512			ref : <?php echo self::_parse_init( $ref ); ?>,
513			load_ext : function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
514		};
515	</script>
516<?php
517
518		$baseurl = self::$baseurl;
519
520		if ( $tmce_on ) {
521			if ( $compressed )
522				echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
523			else
524				echo "<script type='text/javascript' src='{$baseurl}/tiny_mce.js?$version'></script>\n";
525
526			if ( 'en' != self::$mce_locale && isset($lang) )
527				echo "<script type='text/javascript'>\n$lang\n</script>\n";
528			else
529				echo "<script type='text/javascript' src='{$baseurl}/langs/wp-langs-en.js?$version'></script>\n";
530		}
531?>
532
533	<script type="text/javascript">
534		(function(){
535			var init, ed, qt, first_init, mce = <?php echo wp_default_editor() == 'tinymce' ? 'true' : 'false'; ?>;
536
537			if ( typeof(tinymce) == 'object' ) {
538				// mark wp_theme/ui.css as loaded
539				tinymce.DOM.files[tinymce.baseURI.getURI() + '/themes/advanced/skins/wp_theme/ui.css'] = true;
540
541				for ( ed in tinyMCEPreInit.mceInit ) {
542					if ( first_init ) {
543						init = tinyMCEPreInit.mceInit[ed] = tinymce.extend( {}, first_init, tinyMCEPreInit.mceInit[ed] );
544					} else {
545						init = first_init = tinyMCEPreInit.mceInit[ed];
546					}
547
548					if ( mce )
549						try { tinymce.init(init); } catch(e){}
550				}
551			}
552
553			if ( typeof(QTags) == 'function' ) {
554				for ( qt in tinyMCEPreInit.qtInit ) {
555					try { quicktags( tinyMCEPreInit.qtInit[qt] ); } catch(e){}
556				}
557			}
558		})();
559
560		var wpActiveEditor;
561
562		jQuery('.wp-editor-wrap').mousedown(function(e){
563			wpActiveEditor = this.id.slice(3, -5);
564		});
565
566<?php
567
568		if ( self::$ext_plugins )
569			echo self::$ext_plugins . "\n";
570
571		if ( ! $compressed && $tmce_on ) {
572?>
573		(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');}});})();
574<?php
575		}
576
577		if ( !is_admin() )
578			echo 'var ajaxurl = "' . admin_url('admin-ajax.php') . '";';
579?>
580	</script>
581<?php
582
583		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) )
584			self::wp_link_dialog();
585
586		if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
587			self::wp_fullscreen_html();
588
589		do_action('after_wp_tiny_mce', self::$mce_settings);
590	}
591
592	public static function wp_fullscreen_html() {
593		global $content_width, $post;
594
595		$width = isset($content_width) && 800 > $content_width ? $content_width : 800;
596		$width = $width + 22; // compensate for the padding and border
597		$dfw_width = get_user_setting( 'dfw_width', $width );
598		$save = isset($post->post_status) && $post->post_status == 'publish' ? __('Update') : __('Save');
599	?>
600	<div id="wp-fullscreen-body">
601	<div id="fullscreen-topbar">
602		<div id="wp-fullscreen-toolbar">
603			<div id="wp-fullscreen-close"><a href="#" onclick="fullscreen.off();return false;"><?php _e('Exit fullscreen'); ?></a></div>
604			<div id="wp-fullscreen-central-toolbar" style="width:<?php echo $width; ?>px;">
605
606			<div id="wp-fullscreen-mode-bar"><div id="wp-fullscreen-modes">
607				<a href="#" onclick="fullscreen.switchmode('tinymce');return false;"><?php _e('Visual'); ?></a>
608				<a href="#" onclick="fullscreen.switchmode('html');return false;"><?php _e('HTML'); ?></a>
609			</div></div>
610
611			<div id="wp-fullscreen-button-bar"><div id="wp-fullscreen-buttons" class="wp_themeSkin">
612	<?php
613
614		$buttons = array(
615			// format: title, onclick, show in both editors
616			'bold' => array( 'title' => __('Bold (Ctrl + B)'), 'onclick' => 'fullscreen.b();', 'both' => false ),
617			'italic' => array( 'title' => __('Italic (Ctrl + I)'), 'onclick' => 'fullscreen.i();', 'both' => false ),
618			'0' => 'separator',
619			'bullist' => array( 'title' => __('Unordered list (Alt + Shift + U)'), 'onclick' => 'fullscreen.ul();', 'both' => false ),
620			'numlist' => array( 'title' => __('Ordered list (Alt + Shift + O)'), 'onclick' => 'fullscreen.ol();', 'both' => false ),
621			'1' => 'separator',
622			'blockquote' => array( 'title' => __('Blockquote (Alt + Shift + Q)'), 'onclick' => 'fullscreen.blockquote();', 'both' => false ),
623			'image' => array( 'title' => __('Insert/edit image (Alt + Shift + M)'), 'onclick' => "fullscreen.medialib();", 'both' => true ),
624			'2' => 'separator',
625			'link' => array( 'title' => __('Insert/edit link (Alt + Shift + A)'), 'onclick' => 'fullscreen.link();', 'both' => true ),
626			'unlink' => array( 'title' => __('Unlink (Alt + Shift + S)'), 'onclick' => 'fullscreen.unlink();', 'both' => false ),
627			'3' => 'separator',
628			'help' => array( 'title' => __('Help (Alt + Shift + H)'), 'onclick' => 'fullscreen.help();', 'both' => false )
629		);
630
631		$buttons = apply_filters( 'wp_fullscreen_buttons', $buttons );
632
633		foreach ( $buttons as $button => $args ) {
634			if ( 'separator' == $args ) { ?>
635				<div><span aria-orientation="vertical" role="separator" class="mceSeparator"></span></div>
636	<?php		continue;
637			} ?>
638
639			<div<?php if ( $args['both'] ) { ?> class="wp-fullscreen-both"<?php } ?>>
640			<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">
641			<span class="mceIcon mce_<?php echo $button; ?>"></span>
642			</a>
643			</div>
644	<?php
645		} ?>
646
647			</div></div>
648
649			<div id="wp-fullscreen-save">
650				<span><?php if ( $post->post_status == 'publish' ) _e('Updated.'); else _e('Saved.'); ?></span>
651				<img src="images/wpspin_light.gif" alt="" />
652				<input type="button" class="button-primary" value="<?php echo $save; ?>" onclick="fullscreen.save();" />
653			</div>
654
655			</div>
656		</div>
657	</div>
658
659	<div id="wp-fullscreen-wrap" style="width:<?php echo $dfw_width; ?>px;">
660		<?php if ( post_type_supports($post->post_type, 'title') ) { ?>
661		<label id="wp-fullscreen-title-prompt-text" for="wp-fullscreen-title"><?php echo apply_filters( 'enter_title_here', __( 'Enter title here' ), $post ); ?></label>
662		<input type="text" id="wp-fullscreen-title" value="" autocomplete="off" />
663		<?php } ?>
664
665		<div id="wp-fullscreen-container">
666			<textarea id="wp_mce_fullscreen"></textarea>
667		</div>
668
669		<div id="wp-fullscreen-status">
670			<div id="wp-fullscreen-count"><?php printf( __( 'Word count: %s' ), '<span class="word-count">0</span>' ); ?></div>
671			<div id="wp-fullscreen-tagline"><?php _e('Just write.'); ?></div>
672		</div>
673	</div>
674	</div>
675
676	<div class="fullscreen-overlay" id="fullscreen-overlay"></div>
677	<div class="fullscreen-overlay fullscreen-fader fade-600" id="fullscreen-fader"></div>
678	<?php
679	}
680
681	/**
682	 * Performs post queries for internal linking.
683	 *
684	 * @since 3.1.0
685	 *
686	 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
687	 * @return array Results.
688	 */
689	public static function wp_link_query( $args = array() ) {
690		$pts = get_post_types( array( 'public' => true ), 'objects' );
691		$pt_names = array_keys( $pts );
692
693		$query = array(
694			'post_type' => $pt_names,
695			'suppress_filters' => true,
696			'update_post_term_cache' => false,
697			'update_post_meta_cache' => false,
698			'post_status' => 'publish',
699			'order' => 'DESC',
700			'orderby' => 'post_date',
701			'posts_per_page' => 20,
702		);
703
704		$args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
705
706		if ( isset( $args['s'] ) )
707			$query['s'] = $args['s'];
708
709		$query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
710
711		// Do main query.
712		$get_posts = new WP_Query;
713		$posts = $get_posts->query( $query );
714		// Check if any posts were found.
715		if ( ! $get_posts->post_count )
716			return false;
717
718		// Build results.
719		$results = array();
720		foreach ( $posts as $post ) {
721			if ( 'post' == $post->post_type )
722				$info = mysql2date( __( 'Y/m/d' ), $post->post_date );
723			else
724				$info = $pts[ $post->post_type ]->labels->singular_name;
725
726			$results[] = array(
727				'ID' => $post->ID,
728				'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
729				'permalink' => get_permalink( $post->ID ),
730				'info' => $info,
731			);
732		}
733
734		return $results;
735	}
736
737	/**
738	 * Dialog for internal linking.
739	 *
740	 * @since 3.1.0
741	 */
742	public static function wp_link_dialog() {
743	?>
744	<div style="display:none;">
745	<form id="wp-link" tabindex="-1">
746	<?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?>
747	<div id="link-selector">
748		<div id="link-options">
749			<p class="howto"><?php _e( 'Enter the destination URL' ); ?></p>
750			<div>
751				<label><span><?php _e( 'URL' ); ?></span><input id="url-field" type="text" tabindex="10" name="href" /></label>
752			</div>
753			<div>
754				<label><span><?php _e( 'Title' ); ?></span><input id="link-title-field" type="text" tabindex="20" name="linktitle" /></label>
755			</div>
756			<div class="link-target">
757				<label><input type="checkbox" id="link-target-checkbox" tabindex="30" /> <?php _e( 'Open link in a new window/tab' ); ?></label>
758			</div>
759		</div>
760		<?php $show_internal = '1' == get_user_setting( 'wplink', '0' ); ?>
761		<p class="howto toggle-arrow <?php if ( $show_internal ) echo 'toggle-arrow-active'; ?>" id="internal-toggle"><?php _e( 'Or link to existing content' ); ?></p>
762		<div id="search-panel"<?php if ( ! $show_internal ) echo ' style="display:none"'; ?>>
763			<div class="link-search-wrapper">
764				<label>
765					<span><?php _e( 'Search' ); ?></span>
766					<input type="text" id="search-field" class="link-search-field" tabindex="60" autocomplete="off" />
767					<img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
768				</label>
769			</div>
770			<div id="search-results" class="query-results">
771				<ul></ul>
772				<div class="river-waiting">
773					<img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
774				</div>
775			</div>
776			<div id="most-recent-results" class="query-results">
777				<div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div>
778				<ul></ul>
779				<div class="river-waiting">
780					<img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
781				</div>
782			</div>
783		</div>
784	</div>
785	<div class="submitbox">
786		<div id="wp-link-cancel">
787			<a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
788		</div>
789		<div id="wp-link-update">
790			<input type="submit" tabindex="100" value="<?php esc_attr_e( 'Add Link' ); ?>" class="button-primary" id="wp-link-submit" name="wp-link-submit">
791		</div>
792	</div>
793	</form>
794	</div>
795	<?php
796	}
797}
798