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