wp/wp-includes/class-wp-editor.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
    22 	private static $this_quicktags = false;
    22 	private static $this_quicktags = false;
    23 	private static $has_tinymce = false;
    23 	private static $has_tinymce = false;
    24 	private static $has_quicktags = false;
    24 	private static $has_quicktags = false;
    25 	private static $has_medialib = false;
    25 	private static $has_medialib = false;
    26 	private static $editor_buttons_css = true;
    26 	private static $editor_buttons_css = true;
       
    27 	private static $drag_drop_upload = false;
    27 
    28 
    28 	private function __construct() {}
    29 	private function __construct() {}
    29 
    30 
    30 	public static function parse_settings($editor_id, $settings) {
    31 	/**
    31 		$set = wp_parse_args( $settings,  array(
    32 	 * Parse default arguments for the editor instance.
    32 			'wpautop' => true, // use wpautop?
    33 	 *
    33 			'media_buttons' => true, // show insert/upload button(s)
    34 	 * @param string $editor_id ID for the current editor instance.
    34 			'textarea_name' => $editor_id, // set the textarea name to something different, square brackets [] can be used here
    35 	 * @param array  $settings {
    35 			'textarea_rows' => 20,
    36 	 *     Array of editor arguments.
    36 			'tabindex' => '',
    37 	 *
    37 			'tabfocus_elements' => ':prev,:next', // the previous and next element ID to move the focus to when pressing the Tab key in TinyMCE
    38 	 *     @type bool       $wpautop           Whether to use wpautop(). Default true.
    38 			'editor_css' => '', // intended for extra styles for both visual and Text editors buttons, needs to include the <style> tags, can use "scoped".
    39 	 *     @type bool       $media_buttons     Whether to show the Add Media/other media buttons.
    39 			'editor_class' => '', // add extra class(es) to the editor textarea
    40 	 *     @type string     $default_editor    When both TinyMCE and Quicktags are used, set which
    40 			'teeny' => false, // output the minimal editor config used in Press This
    41 	 *                                         editor is shown on page load. Default empty.
    41 			'dfw' => false, // replace the default fullscreen with DFW (needs specific DOM elements and css)
    42 	 *     @type bool       $drag_drop_upload  Whether to enable drag & drop on the editor uploading. Default false.
    42 			'tinymce' => true, // load TinyMCE, can be used to pass settings directly to TinyMCE using an array()
    43 	 *                                         Requires the media modal.
    43 			'quicktags' => true // load Quicktags, can be used to pass settings directly to Quicktags using an array()
    44 	 *     @type string     $textarea_name     Give the textarea a unique name here. Square brackets
       
    45 	 *                                         can be used here. Default $editor_id.
       
    46 	 *     @type int        $textarea_rows     Number rows in the editor textarea. Default 20.
       
    47 	 *     @type string|int $tabindex          Tabindex value to use. Default empty.
       
    48 	 *     @type string     $tabfocus_elements The previous and next element ID to move the focus to
       
    49 	 *                                         when pressing the Tab key in TinyMCE. Defualt ':prev,:next'.
       
    50 	 *     @type string     $editor_css        Intended for extra styles for both Visual and Text editors.
       
    51 	 *                                         Should include `<style>` tags, and can use "scoped". Default empty.
       
    52 	 *     @type string     $editor_class      Extra classes to add to the editor textarea elemen. Default empty.
       
    53 	 *     @type bool       $teeny             Whether to output the minimal editor config. Examples include
       
    54 	 *                                         Press This and the Comment editor. Default false.
       
    55 	 *     @type bool       $dfw               Whether to replace the default fullscreen with "Distraction Free
       
    56 	 *                                         Writing". DFW requires specific DOM elements and css). Default false.
       
    57 	 *     @type bool|array $tinymce           Whether to load TinyMCE. Can be used to pass settings directly to
       
    58 	 *                                         TinyMCE using an array. Default true.
       
    59 	 *     @type bool|array $quicktags         Whether to load Quicktags. Can be used to pass settings directly to
       
    60 	 *                                         Quicktags using an array. Default true.
       
    61 	 * }
       
    62 	 * @return array Parsed arguments array.
       
    63 	 */
       
    64 	public static function parse_settings( $editor_id, $settings ) {
       
    65 
       
    66 		/**
       
    67 		 * Filter the wp_editor() settings.
       
    68 		 *
       
    69 		 * @since 4.0.0
       
    70 		 *
       
    71 		 * @see _WP_Editors()::parse_settings()
       
    72 		 *
       
    73 		 * @param array  $settings  Array of editor arguments.
       
    74 		 * @param string $editor_id ID for the current editor instance.
       
    75 		 */
       
    76 		$settings = apply_filters( 'wp_editor_settings', $settings, $editor_id );
       
    77 
       
    78 		$set = wp_parse_args( $settings, array(
       
    79 			'wpautop'             => true,
       
    80 			'media_buttons'       => true,
       
    81 			'default_editor'      => '',
       
    82 			'drag_drop_upload'    => false,
       
    83 			'textarea_name'       => $editor_id,
       
    84 			'textarea_rows'       => 20,
       
    85 			'tabindex'            => '',
       
    86 			'tabfocus_elements'   => ':prev,:next',
       
    87 			'editor_css'          => '',
       
    88 			'editor_class'        => '',
       
    89 			'teeny'               => false,
       
    90 			'dfw'                 => false,
       
    91 			'_content_editor_dfw' => false,
       
    92 			'tinymce'             => true,
       
    93 			'quicktags'           => true
    44 		) );
    94 		) );
    45 
    95 
    46 		self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() );
    96 		self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() );
       
    97 
       
    98 		if ( self::$this_tinymce ) {
       
    99 			if ( false !== strpos( $editor_id, '[' ) ) {
       
   100 				self::$this_tinymce = false;
       
   101 				_deprecated_argument( 'wp_editor()', '3.9', 'TinyMCE editor IDs cannot have brackets.' );
       
   102 			}
       
   103 		}
       
   104 
    47 		self::$this_quicktags = (bool) $set['quicktags'];
   105 		self::$this_quicktags = (bool) $set['quicktags'];
    48 
   106 
    49 		if ( self::$this_tinymce )
   107 		if ( self::$this_tinymce )
    50 			self::$has_tinymce = true;
   108 			self::$has_tinymce = true;
    51 
   109 
    53 			self::$has_quicktags = true;
   111 			self::$has_quicktags = true;
    54 
   112 
    55 		if ( empty( $set['editor_height'] ) )
   113 		if ( empty( $set['editor_height'] ) )
    56 			return $set;
   114 			return $set;
    57 
   115 
    58 		if ( 'content' === $editor_id ) {
   116 		if ( 'content' === $editor_id && empty( $set['tinymce']['wp_autoresize_on'] ) ) {
    59 			// A cookie (set when a user resizes the editor) overrides the height.
   117 			// A cookie (set when a user resizes the editor) overrides the height.
    60 			$cookie = (int) get_user_setting( 'ed_size' );
   118 			$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 
   119 
    68 			if ( $cookie )
   120 			if ( $cookie )
    69 				$set['editor_height'] = $cookie;
   121 				$set['editor_height'] = $cookie;
    70 		}
   122 		}
    71 
   123 
    84 	 * @param string $editor_id ID for the textarea and TinyMCE and Quicktags instances (can contain only ASCII letters and numbers).
   136 	 * @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.
   137 	 * @param array $settings See the _parse_settings() method for description.
    86 	 */
   138 	 */
    87 	public static function editor( $content, $editor_id, $settings = array() ) {
   139 	public static function editor( $content, $editor_id, $settings = array() ) {
    88 
   140 
    89 		$set = self::parse_settings($editor_id, $settings);
   141 		$set = self::parse_settings( $editor_id, $settings );
    90 		$editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"';
   142 		$editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"';
    91 		$tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : '';
   143 		$tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : '';
    92 		$switch_class = 'html-active';
   144 		$switch_class = 'html-active';
    93 		$toolbar = $buttons = '';
   145 		$toolbar = $buttons = $autocomplete = '';
       
   146 
       
   147 		if ( $set['drag_drop_upload'] ) {
       
   148 			self::$drag_drop_upload = true;
       
   149 		}
    94 
   150 
    95 		if ( ! empty( $set['editor_height'] ) )
   151 		if ( ! empty( $set['editor_height'] ) )
    96 			$height = ' style="height: ' . $set['editor_height'] . 'px"';
   152 			$height = ' style="height: ' . $set['editor_height'] . 'px"';
    97 		else
   153 		else
    98 			$height = ' rows="' . $set['textarea_rows'] . '"';
   154 			$height = ' rows="' . $set['textarea_rows'] . '"';
    99 
   155 
   100 		if ( !current_user_can( 'upload_files' ) )
   156 		if ( !current_user_can( 'upload_files' ) )
   101 			$set['media_buttons'] = false;
   157 			$set['media_buttons'] = false;
   102 
   158 
   103 		if ( self::$this_quicktags && self::$this_tinymce ) {
   159 		if ( ! self::$this_quicktags && self::$this_tinymce ) {
   104 			$switch_class = 'html-active';
   160 			$switch_class = 'tmce-active';
   105 
   161 			$autocomplete = ' autocomplete="off"';
   106 			// 'html' and 'switch-html' are used for the "Text" editor tab.
   162 		} elseif ( self::$this_quicktags && self::$this_tinymce ) {
   107 			if ( 'html' == wp_default_editor() ) {
   163 			$default_editor = $set['default_editor'] ? $set['default_editor'] : wp_default_editor();
       
   164 			$autocomplete = ' autocomplete="off"';
       
   165 
       
   166 			// 'html' is used for the "Text" editor tab.
       
   167 			if ( 'html' === $default_editor ) {
   108 				add_filter('the_editor_content', 'wp_htmledit_pre');
   168 				add_filter('the_editor_content', 'wp_htmledit_pre');
       
   169 				$switch_class = 'html-active';
   109 			} else {
   170 			} else {
   110 				add_filter('the_editor_content', 'wp_richedit_pre');
   171 				add_filter('the_editor_content', 'wp_richedit_pre');
   111 				$switch_class = 'tmce-active';
   172 				$switch_class = 'tmce-active';
   112 			}
   173 			}
   113 
   174 
   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";
   175 			$buttons .= '<button type="button" id="' . $editor_id . '-tmce" class="wp-switch-editor switch-tmce" onclick="switchEditors.switchto(this);">' . __('Visual') . "</button>\n";
   115 			$buttons .= '<a id="' . $editor_id . '-tmce" class="wp-switch-editor switch-tmce" onclick="switchEditors.switchto(this);">' . __('Visual') . "</a>\n";
   176 			$buttons .= '<button type="button" id="' . $editor_id . '-html" class="wp-switch-editor switch-html" onclick="switchEditors.switchto(this);">' . _x( 'Text', 'Name for the Text editor tab (formerly HTML)' ) . "</button>\n";
   116 		}
   177 		}
   117 
   178 
   118 		echo '<div id="wp-' . $editor_id . '-wrap" class="wp-core-ui wp-editor-wrap ' . $switch_class . '">';
   179 		$wrap_class = 'wp-core-ui wp-editor-wrap ' . $switch_class;
       
   180 
       
   181 		if ( $set['_content_editor_dfw'] ) {
       
   182 			$wrap_class .= ' has-dfw';
       
   183 		}
       
   184 
       
   185 		echo '<div id="wp-' . $editor_id . '-wrap" class="' . $wrap_class . '">';
   119 
   186 
   120 		if ( self::$editor_buttons_css ) {
   187 		if ( self::$editor_buttons_css ) {
   121 			wp_print_styles('editor-buttons');
   188 			wp_print_styles('editor-buttons');
   122 			self::$editor_buttons_css = false;
   189 			self::$editor_buttons_css = false;
   123 		}
   190 		}
   125 		if ( !empty($set['editor_css']) )
   192 		if ( !empty($set['editor_css']) )
   126 			echo $set['editor_css'] . "\n";
   193 			echo $set['editor_css'] . "\n";
   127 
   194 
   128 		if ( !empty($buttons) || $set['media_buttons'] ) {
   195 		if ( !empty($buttons) || $set['media_buttons'] ) {
   129 			echo '<div id="wp-' . $editor_id . '-editor-tools" class="wp-editor-tools hide-if-no-js">';
   196 			echo '<div id="wp-' . $editor_id . '-editor-tools" class="wp-editor-tools hide-if-no-js">';
   130 			echo $buttons;
       
   131 
   197 
   132 			if ( $set['media_buttons'] ) {
   198 			if ( $set['media_buttons'] ) {
   133 				self::$has_medialib = true;
   199 				self::$has_medialib = true;
   134 
   200 
   135 				if ( !function_exists('media_buttons') )
   201 				if ( !function_exists('media_buttons') )
   136 					include(ABSPATH . 'wp-admin/includes/media.php');
   202 					include(ABSPATH . 'wp-admin/includes/media.php');
   137 
   203 
   138 				echo '<div id="wp-' . $editor_id . '-media-buttons" class="wp-media-buttons">';
   204 				echo '<div id="wp-' . $editor_id . '-media-buttons" class="wp-media-buttons">';
   139 				do_action('media_buttons', $editor_id);
   205 
       
   206 				/**
       
   207 				 * Fires after the default media button(s) are displayed.
       
   208 				 *
       
   209 				 * @since 2.5.0
       
   210 				 *
       
   211 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   212 				 */
       
   213 				do_action( 'media_buttons', $editor_id );
   140 				echo "</div>\n";
   214 				echo "</div>\n";
   141 			}
   215 			}
       
   216 
       
   217 			echo '<div class="wp-editor-tabs">' . $buttons . "</div>\n";
   142 			echo "</div>\n";
   218 			echo "</div>\n";
   143 		}
   219 		}
   144 
   220 
   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>');
   221 		/**
   146 		$content = apply_filters('the_editor_content', $content);
   222 		 * Filter the HTML markup output that displays the editor.
   147 
   223 		 *
   148 		printf($the_editor, $content);
   224 		 * @since 2.1.0
       
   225 		 *
       
   226 		 * @param string $output Editor's HTML markup.
       
   227 		 */
       
   228 		$the_editor = apply_filters( 'the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container">' .
       
   229 			'<textarea' . $editor_class . $height . $tabindex . $autocomplete . ' cols="40" name="' . $set['textarea_name'] . '" ' .
       
   230 			'id="' . $editor_id . '">%s</textarea></div>' );
       
   231 
       
   232 		/**
       
   233 		 * Filter the default editor content.
       
   234 		 *
       
   235 		 * @since 2.1.0
       
   236 		 *
       
   237 		 * @param string $content Default editor content.
       
   238 		 */
       
   239 		$content = apply_filters( 'the_editor_content', $content );
       
   240 
       
   241 		printf( $the_editor, $content );
   149 		echo "\n</div>\n\n";
   242 		echo "\n</div>\n\n";
   150 
   243 
   151 		self::editor_settings($editor_id, $set);
   244 		self::editor_settings($editor_id, $set);
   152 	}
   245 	}
   153 
   246 
       
   247 	/**
       
   248 	 * @param string $editor_id
       
   249 	 * @param array  $set
       
   250 	 */
   154 	public static function editor_settings($editor_id, $set) {
   251 	public static function editor_settings($editor_id, $set) {
   155 		$first_run = false;
   252 		$first_run = false;
   156 
   253 
   157 		if ( empty(self::$first_init) ) {
   254 		if ( empty(self::$first_init) ) {
   158 			if ( is_admin() ) {
   255 			if ( is_admin() ) {
   159 				add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 );
   256 				add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_js' ), 50 );
   160 				add_action( 'admin_footer', array( __CLASS__, 'enqueue_scripts'), 1 );
   257 				add_action( 'admin_print_footer_scripts', array( __CLASS__, 'enqueue_scripts' ), 1 );
   161 			} else {
   258 			} else {
   162 				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'editor_js'), 50 );
   259 				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'editor_js' ), 50 );
   163 				add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts'), 1 );
   260 				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'enqueue_scripts' ), 1 );
   164 			}
   261 			}
   165 		}
   262 		}
   166 
   263 
   167 		if ( self::$this_quicktags ) {
   264 		if ( self::$this_quicktags ) {
   168 
   265 
   178 				$qtInit['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close';
   275 				$qtInit['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close';
   179 
   276 
   180 			if ( $set['dfw'] )
   277 			if ( $set['dfw'] )
   181 				$qtInit['buttons'] .= ',fullscreen';
   278 				$qtInit['buttons'] .= ',fullscreen';
   182 
   279 
   183 			$qtInit = apply_filters('quicktags_settings', $qtInit, $editor_id);
   280 			if ( $set['_content_editor_dfw'] ) {
       
   281 				$qtInit['buttons'] .= ',dfw';
       
   282 			}
       
   283 
       
   284 			/**
       
   285 			 * Filter the Quicktags settings.
       
   286 			 *
       
   287 			 * @since 3.3.0
       
   288 			 *
       
   289 			 * @param array  $qtInit    Quicktags settings.
       
   290 			 * @param string $editor_id The unique editor ID, e.g. 'content'.
       
   291 			 */
       
   292 			$qtInit = apply_filters( 'quicktags_settings', $qtInit, $editor_id );
       
   293 
   184 			self::$qt_settings[$editor_id] = $qtInit;
   294 			self::$qt_settings[$editor_id] = $qtInit;
   185 
   295 
   186 			self::$qt_buttons = array_merge( self::$qt_buttons, explode(',', $qtInit['buttons']) );
   296 			self::$qt_buttons = array_merge( self::$qt_buttons, explode(',', $qtInit['buttons']) );
   187 		}
   297 		}
   188 
   298 
   189 		if ( self::$this_tinymce ) {
   299 		if ( self::$this_tinymce ) {
   190 
   300 
   191 			if ( empty(self::$first_init) ) {
   301 			if ( empty( self::$first_init ) ) {
   192 				self::$baseurl = includes_url('js/tinymce');
   302 				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
   303 
       
   304 				$mce_locale = get_locale();
       
   305 				self::$mce_locale = $mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1
       
   306 
       
   307 				/** This filter is documented in wp-admin/includes/media.php */
   194 				$no_captions = (bool) apply_filters( 'disable_captions', '' );
   308 				$no_captions = (bool) apply_filters( 'disable_captions', '' );
   195 				$plugins = array( 'inlinepopups', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' );
       
   196 				$first_run = true;
   309 				$first_run = true;
   197 				$ext_plugins = '';
   310 				$ext_plugins = '';
   198 
   311 
   199 				if ( $set['teeny'] ) {
   312 				if ( $set['teeny'] ) {
   200 					self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array('inlinepopups', 'fullscreen', 'wordpress', 'wplink', 'wpdialogs' ), $editor_id );
   313 
       
   314 					/**
       
   315 					 * Filter the list of teenyMCE plugins.
       
   316 					 *
       
   317 					 * @since 2.7.0
       
   318 					 *
       
   319 					 * @param array  $plugins   An array of teenyMCE plugins.
       
   320 					 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   321 					 */
       
   322 					self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );
   201 				} else {
   323 				} else {
   202 					/*
   324 
   203 					The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'.
   325 					/**
   204 					It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin.
   326 					 * Filter the list of TinyMCE external plugins.
   205 					The url should be absolute and should include the js file name to be loaded. Example:
   327 					 *
   206 					array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' )
   328 					 * The filter takes an associative array of external plugins for
   207 					If the plugin uses a button, it should be added with one of the "$mce_buttons" filters.
   329 					 * TinyMCE in the form 'plugin_name' => 'url'.
   208 					*/
   330 					 *
   209 					$mce_external_plugins = apply_filters('mce_external_plugins', array());
   331 					 * The url should be absolute, and should include the js filename
   210 
   332 					 * to be loaded. For example:
   211 					if ( ! empty($mce_external_plugins) ) {
   333 					 * 'myplugin' => 'http://mysite.com/wp-content/plugins/myfolder/mce_plugin.js'.
   212 
   334 					 *
   213 						/*
   335 					 * If the external plugin adds a button, it should be added with
   214 						The following filter loads external language files for TinyMCE plugins.
   336 					 * one of the 'mce_buttons' filters.
   215 						It takes an associative array 'plugin_name' => 'path', where path is the
   337 					 *
   216 						include path to the file. The language file should follow the same format as
   338 					 * @since 2.5.0
   217 						/tinymce/langs/wp-langs.php and should define a variable $strings that
   339 					 *
   218 						holds all translated strings.
   340 					 * @param array $external_plugins An array of external TinyMCE plugins.
   219 						When this filter is not used, the function will try to load {mce_locale}.js.
   341 					 */
   220 						If that is not found, en.js will be tried next.
   342 					$mce_external_plugins = apply_filters( 'mce_external_plugins', array() );
   221 						*/
   343 
   222 						$mce_external_languages = apply_filters('mce_external_languages', array());
   344 					$plugins = array(
       
   345 						'charmap',
       
   346 						'colorpicker',
       
   347 						'hr',
       
   348 						'lists',
       
   349 						'media',
       
   350 						'paste',
       
   351 						'tabfocus',
       
   352 						'textcolor',
       
   353 						'fullscreen',
       
   354 						'wordpress',
       
   355 						'wpautoresize',
       
   356 						'wpeditimage',
       
   357 						'wpemoji',
       
   358 						'wpgallery',
       
   359 						'wplink',
       
   360 						'wpdialogs',
       
   361 						'wpview',
       
   362 					);
       
   363 
       
   364 					if ( ! self::$has_medialib ) {
       
   365 						$plugins[] = 'image';
       
   366 					}
       
   367 
       
   368 					/**
       
   369 					 * Filter the list of default TinyMCE plugins.
       
   370 					 *
       
   371 					 * The filter specifies which of the default plugins included
       
   372 					 * in WordPress should be added to the TinyMCE instance.
       
   373 					 *
       
   374 					 * @since 3.3.0
       
   375 					 *
       
   376 					 * @param array $plugins An array of default TinyMCE plugins.
       
   377 					 */
       
   378 					$plugins = array_unique( apply_filters( 'tiny_mce_plugins', $plugins ) );
       
   379 
       
   380 					if ( ( $key = array_search( 'spellchecker', $plugins ) ) !== false ) {
       
   381 						// Remove 'spellchecker' from the internal plugins if added with 'tiny_mce_plugins' filter to prevent errors.
       
   382 						// It can be added with 'mce_external_plugins'.
       
   383 						unset( $plugins[$key] );
       
   384 					}
       
   385 
       
   386 					if ( ! empty( $mce_external_plugins ) ) {
       
   387 
       
   388 						/**
       
   389 						 * Filter the translations loaded for external TinyMCE 3.x plugins.
       
   390 						 *
       
   391 						 * The filter takes an associative array ('plugin_name' => 'path')
       
   392 						 * where 'path' is the include path to the file.
       
   393 						 *
       
   394 						 * The language file should follow the same format as wp_mce_translation(),
       
   395 						 * and should define a variable ($strings) that holds all translated strings.
       
   396 						 *
       
   397 						 * @since 2.5.0
       
   398 						 *
       
   399 						 * @param array $translations Translations for external TinyMCE plugins.
       
   400 						 */
       
   401 						$mce_external_languages = apply_filters( 'mce_external_languages', array() );
   223 
   402 
   224 						$loaded_langs = array();
   403 						$loaded_langs = array();
   225 						$strings = '';
   404 						$strings = '';
   226 
   405 
   227 						if ( ! empty($mce_external_languages) ) {
   406 						if ( ! empty( $mce_external_languages ) ) {
   228 							foreach ( $mce_external_languages as $name => $path ) {
   407 							foreach ( $mce_external_languages as $name => $path ) {
   229 								if ( @is_file($path) && @is_readable($path) ) {
   408 								if ( @is_file( $path ) && @is_readable( $path ) ) {
   230 									include_once($path);
   409 									include_once( $path );
   231 									$ext_plugins .= $strings . "\n";
   410 									$ext_plugins .= $strings . "\n";
   232 									$loaded_langs[] = $name;
   411 									$loaded_langs[] = $name;
   233 								}
   412 								}
   234 							}
   413 							}
   235 						}
   414 						}
   236 
   415 
   237 						foreach ( $mce_external_plugins as $name => $url ) {
   416 						foreach ( $mce_external_plugins as $name => $url ) {
       
   417 							if ( in_array( $name, $plugins, true ) ) {
       
   418 								unset( $mce_external_plugins[ $name ] );
       
   419 								continue;
       
   420 							}
   238 
   421 
   239 							$url = set_url_scheme( $url );
   422 							$url = set_url_scheme( $url );
   240 
   423 							$mce_external_plugins[ $name ] = $url;
   241 							$plugins[] = '-' . $name;
   424 							$plugurl = dirname( $url );
   242 
   425 							$strings = '';
   243 							$plugurl = dirname($url);
   426 
   244 							$strings = $str1 = $str2 = '';
   427 							// Try to load langs/[locale].js and langs/[locale]_dlg.js
   245 							if ( ! in_array($name, $loaded_langs) ) {
   428 							if ( ! in_array( $name, $loaded_langs, true ) ) {
   246 								$path = str_replace( content_url(), '', $plugurl );
   429 								$path = str_replace( content_url(), '', $plugurl );
   247 								$path = WP_CONTENT_DIR . $path . '/langs/';
   430 								$path = WP_CONTENT_DIR . $path . '/langs/';
   248 
   431 
   249 								if ( function_exists('realpath') )
   432 								if ( function_exists('realpath') )
   250 									$path = trailingslashit( realpath($path) );
   433 									$path = trailingslashit( realpath($path) );
   251 
   434 
   252 								if ( @is_file($path . $mce_locale . '.js') )
   435 								if ( @is_file( $path . $mce_locale . '.js' ) )
   253 									$strings .= @file_get_contents($path . $mce_locale . '.js') . "\n";
   436 									$strings .= @file_get_contents( $path . $mce_locale . '.js' ) . "\n";
   254 
   437 
   255 								if ( @is_file($path . $mce_locale . '_dlg.js') )
   438 								if ( @is_file( $path . $mce_locale . '_dlg.js' ) )
   256 									$strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n";
   439 									$strings .= @file_get_contents( $path . $mce_locale . '_dlg.js' ) . "\n";
   257 
   440 
   258 								if ( 'en' != $mce_locale && empty($strings) ) {
   441 								if ( 'en' != $mce_locale && empty( $strings ) ) {
   259 									if ( @is_file($path . 'en.js') ) {
   442 									if ( @is_file( $path . 'en.js' ) ) {
   260 										$str1 = @file_get_contents($path . 'en.js');
   443 										$str1 = @file_get_contents( $path . 'en.js' );
   261 										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n";
   444 										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n";
   262 									}
   445 									}
   263 
   446 
   264 									if ( @is_file($path . 'en_dlg.js') ) {
   447 									if ( @is_file( $path . 'en_dlg.js' ) ) {
   265 										$str2 = @file_get_contents($path . 'en_dlg.js');
   448 										$str2 = @file_get_contents( $path . 'en_dlg.js' );
   266 										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n";
   449 										$strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n";
   267 									}
   450 									}
   268 								}
   451 								}
   269 
   452 
   270 								if ( ! empty($strings) )
   453 								if ( ! empty( $strings ) )
   271 									$ext_plugins .= "\n" . $strings . "\n";
   454 									$ext_plugins .= "\n" . $strings . "\n";
   272 							}
   455 							}
   273 
   456 
   274 							$ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
   457 							$ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
   275 							$ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
   458 							$ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
   276 						}
   459 						}
   277 					}
   460 					}
   278 
       
   279 					$plugins = array_unique( apply_filters('tiny_mce_plugins', $plugins) );
       
   280 				}
   461 				}
   281 
   462 
   282 				if ( $set['dfw'] )
   463 				if ( $set['dfw'] )
   283 					$plugins[] = 'wpfullscreen';
   464 					$plugins[] = 'wpfullscreen';
   284 
   465 
   285 				self::$plugins = $plugins;
   466 				self::$plugins = $plugins;
   286 				self::$ext_plugins = $ext_plugins;
   467 				self::$ext_plugins = $ext_plugins;
   287 
   468 
   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(
   469 				self::$first_init = array(
   306 					'mode' => 'exact',
   470 					'theme' => 'modern',
   307 					'width' => '100%',
   471 					'skin' => 'lightgray',
   308 					'theme' => 'advanced',
       
   309 					'skin' => 'wp_theme',
       
   310 					'language' => self::$mce_locale,
   472 					'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' => "{
   473 					'formats' => "{
   318 						alignleft : [
   474 						alignleft: [
   319 							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}},
   475 							{selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'left'}},
   320 							{selector : 'img,table', classes : 'alignleft'}
   476 							{selector: 'img,table,dl.wp-caption', classes: 'alignleft'}
   321 						],
   477 						],
   322 						aligncenter : [
   478 						aligncenter: [
   323 							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}},
   479 							{selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'center'}},
   324 							{selector : 'img,table', classes : 'aligncenter'}
   480 							{selector: 'img,table,dl.wp-caption', classes: 'aligncenter'}
   325 						],
   481 						],
   326 						alignright : [
   482 						alignright: [
   327 							{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}},
   483 							{selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'right'}},
   328 							{selector : 'img,table', classes : 'alignright'}
   484 							{selector: 'img,table,dl.wp-caption', classes: 'alignright'}
   329 						],
   485 						],
   330 						strikethrough : {inline : 'del'}
   486 						strikethrough: {inline: 'del'}
   331 					}",
   487 					}",
   332 					'relative_urls' => false,
   488 					'relative_urls' => false,
   333 					'remove_script_host' => false,
   489 					'remove_script_host' => false,
   334 					'convert_urls' => false,
   490 					'convert_urls' => false,
   335 					'remove_linebreaks' => true,
   491 					'browser_spellcheck' => true,
   336 					'gecko_spellcheck' => true,
       
   337 					'fix_list_elements' => true,
   492 					'fix_list_elements' => true,
       
   493 					'entities' => '38,amp,60,lt,62,gt',
       
   494 					'entity_encoding' => 'raw',
   338 					'keep_styles' => false,
   495 					'keep_styles' => false,
   339 					'entities' => '38,amp,60,lt,62,gt',
   496 					'cache_suffix' => 'wp-mce-' . $GLOBALS['tinymce_version'],
   340 					'accessibility_focus' => true,
   497 
   341 					'media_strict' => false,
   498 					// Limit the preview styles in the menu/toolbar
   342 					'paste_remove_styles' => true,
   499 					'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',
   343 					'paste_remove_spans' => true,
   500 
   344 					'paste_strip_class_attributes' => 'all',
   501 					'end_container_on_empty_block' => true,
   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,
   502 					'wpeditimage_disable_captions' => $no_captions,
   350 					'wp_fullscreen_content_css' => self::$baseurl . '/plugins/wpfullscreen/css/wp-fullscreen.css',
   503 					'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ),
   351 					'plugins' => implode( ',', $plugins )
   504 					'plugins' => implode( ',', $plugins ),
   352 				);
   505 				);
   353 
   506 
   354 				if ( in_array( 'spellchecker', $plugins ) ) {
   507 				if ( ! empty( $mce_external_plugins ) ) {
   355 					self::$first_init['spellchecker_rpc_url'] = self::$baseurl . '/plugins/spellchecker/rpc.php';
   508 					self::$first_init['external_plugins'] = wp_json_encode( $mce_external_plugins );
   356 					self::$first_init['spellchecker_languages'] = $mce_spellchecker_languages;
       
   357 				}
   509 				}
   358 
   510 
   359 				// load editor_style.css if the current theme supports it
   511 				$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
   360 				if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) {
   512 				$version = 'ver=' . $GLOBALS['wp_version'];
   361 					$editor_styles = $GLOBALS['editor_styles'];
   513 				$dashicons = includes_url( "css/dashicons$suffix.css?$version" );
   362 
   514 
   363 					$mce_css = array();
   515 				// WordPress default stylesheet and dashicons
   364 					$editor_styles = array_unique( array_filter( $editor_styles ) );
   516 				$mce_css = array(
   365 					$style_uri = get_stylesheet_directory_uri();
   517 					$dashicons,
   366 					$style_dir = get_stylesheet_directory();
   518 					self::$baseurl . '/skins/wordpress/wp-content.css?' . $version
   367 
   519 				);
   368 					// Support externally referenced styles (like, say, fonts).
   520 
   369 					foreach ( $editor_styles as $key => $file ) {
   521 				$editor_styles = get_editor_stylesheets();
   370 						if ( preg_match( '~^(https?:)?//~', $file ) ) {
   522 				if ( ! empty( $editor_styles ) ) {
   371 							$mce_css[] = esc_url_raw( $file );
   523 					foreach ( $editor_styles as $style ) {
   372 							unset( $editor_styles[ $key ] );
   524 						$mce_css[] = $style;
   373 						}
       
   374 					}
   525 					}
   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 				}
   526 				}
   396 
   527 
   397 				$mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' );
   528 				/**
       
   529 				 * Filter the comma-delimited list of stylesheets to load in TinyMCE.
       
   530 				 *
       
   531 				 * @since 2.1.0
       
   532 				 *
       
   533 				 * @param array $stylesheets Comma-delimited list of stylesheets.
       
   534 				 */
       
   535 				$mce_css = trim( apply_filters( 'mce_css', implode( ',', $mce_css ) ), ' ,' );
   398 
   536 
   399 				if ( ! empty($mce_css) )
   537 				if ( ! empty($mce_css) )
   400 					self::$first_init['content_css'] = $mce_css;
   538 					self::$first_init['content_css'] = $mce_css;
   401 			}
   539 			}
   402 
   540 
   403 			if ( $set['teeny'] ) {
   541 			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 );
   542 
       
   543 				/**
       
   544 				 * Filter the list of teenyMCE buttons (Text tab).
       
   545 				 *
       
   546 				 * @since 2.7.0
       
   547 				 *
       
   548 				 * @param array  $buttons   An array of teenyMCE buttons.
       
   549 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   550 				 */
       
   551 				$mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id );
   405 				$mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = array();
   552 				$mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = array();
   406 			} else {
   553 			} 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);
   554 				$mce_buttons = array( 'bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker' );
   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);
   555 
   409 				$mce_buttons_3 = apply_filters('mce_buttons_3', array(), $editor_id);
   556 				if ( $set['_content_editor_dfw'] ) {
   410 				$mce_buttons_4 = apply_filters('mce_buttons_4', array(), $editor_id);
   557 					$mce_buttons[] = 'dfw';
       
   558 				} else {
       
   559 					$mce_buttons[] = 'fullscreen';
       
   560 				}
       
   561 
       
   562 				$mce_buttons[] = 'wp_adv';
       
   563 
       
   564 				/**
       
   565 				 * Filter the first-row list of TinyMCE buttons (Visual tab).
       
   566 				 *
       
   567 				 * @since 2.0.0
       
   568 				 *
       
   569 				 * @param array  $buttons   First-row list of buttons.
       
   570 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   571 				 */
       
   572 				$mce_buttons = apply_filters( 'mce_buttons', $mce_buttons, $editor_id );
       
   573 
       
   574 				$mce_buttons_2 = array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo' );
       
   575 
       
   576 				if ( ! wp_is_mobile() ) {
       
   577 					$mce_buttons_2[] = 'wp_help';
       
   578 				}
       
   579 
       
   580 				/**
       
   581 				 * Filter the second-row list of TinyMCE buttons (Visual tab).
       
   582 				 *
       
   583 				 * @since 2.0.0
       
   584 				 *
       
   585 				 * @param array  $buttons   Second-row list of buttons.
       
   586 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   587 				 */
       
   588 				$mce_buttons_2 = apply_filters( 'mce_buttons_2', $mce_buttons_2, $editor_id );
       
   589 
       
   590 				/**
       
   591 				 * Filter the third-row list of TinyMCE buttons (Visual tab).
       
   592 				 *
       
   593 				 * @since 2.0.0
       
   594 				 *
       
   595 				 * @param array  $buttons   Third-row list of buttons.
       
   596 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   597 				 */
       
   598 				$mce_buttons_3 = apply_filters( 'mce_buttons_3', array(), $editor_id );
       
   599 
       
   600 				/**
       
   601 				 * Filter the fourth-row list of TinyMCE buttons (Visual tab).
       
   602 				 *
       
   603 				 * @since 2.5.0
       
   604 				 *
       
   605 				 * @param array  $buttons   Fourth-row list of buttons.
       
   606 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   607 				 */
       
   608 				$mce_buttons_4 = apply_filters( 'mce_buttons_4', array(), $editor_id );
   411 			}
   609 			}
   412 
   610 
   413 			$body_class = $editor_id;
   611 			$body_class = $editor_id;
   414 
   612 
   415 			if ( $post = get_post() ) {
   613 			if ( $post = get_post() ) {
   420 						$body_class .= ' post-format-' . sanitize_html_class( $post_format );
   618 						$body_class .= ' post-format-' . sanitize_html_class( $post_format );
   421 					else
   619 					else
   422 						$body_class .= ' post-format-standard';
   620 						$body_class .= ' post-format-standard';
   423 				}
   621 				}
   424 			}
   622 			}
       
   623 
       
   624 			$body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
   425 
   625 
   426 			if ( !empty($set['tinymce']['body_class']) ) {
   626 			if ( !empty($set['tinymce']['body_class']) ) {
   427 				$body_class .= ' ' . $set['tinymce']['body_class'];
   627 				$body_class .= ' ' . $set['tinymce']['body_class'];
   428 				unset($set['tinymce']['body_class']);
   628 				unset($set['tinymce']['body_class']);
   429 			}
   629 			}
   439 				elseif ( ($key = array_search('fullscreen', $mce_buttons_4)) !== false )
   639 				elseif ( ($key = array_search('fullscreen', $mce_buttons_4)) !== false )
   440 					$mce_buttons_4[$key] = 'wp_fullscreen';
   640 					$mce_buttons_4[$key] = 'wp_fullscreen';
   441 			}
   641 			}
   442 
   642 
   443 			$mceInit = array (
   643 			$mceInit = array (
   444 				'elements' => $editor_id,
   644 				'selector' => "#$editor_id",
       
   645 				'resize' => 'vertical',
       
   646 				'menubar' => false,
   445 				'wpautop' => (bool) $set['wpautop'],
   647 				'wpautop' => (bool) $set['wpautop'],
   446 				'remove_linebreaks' => (bool) $set['wpautop'],
   648 				'indent' => ! $set['wpautop'],
   447 				'apply_source_formatting' => (bool) !$set['wpautop'],
   649 				'toolbar1' => implode($mce_buttons, ','),
   448 				'theme_advanced_buttons1' => implode($mce_buttons, ','),
   650 				'toolbar2' => implode($mce_buttons_2, ','),
   449 				'theme_advanced_buttons2' => implode($mce_buttons_2, ','),
   651 				'toolbar3' => implode($mce_buttons_3, ','),
   450 				'theme_advanced_buttons3' => implode($mce_buttons_3, ','),
   652 				'toolbar4' => implode($mce_buttons_4, ','),
   451 				'theme_advanced_buttons4' => implode($mce_buttons_4, ','),
       
   452 				'tabfocus_elements' => $set['tabfocus_elements'],
   653 				'tabfocus_elements' => $set['tabfocus_elements'],
   453 				'body_class' => $body_class
   654 				'body_class' => $body_class
   454 			);
   655 			);
   455 
   656 
   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 )
   657 			if ( $first_run )
   460 				$mceInit = array_merge(self::$first_init, $mceInit);
   658 				$mceInit = array_merge( self::$first_init, $mceInit );
   461 
   659 
   462 			if ( is_array($set['tinymce']) )
   660 			if ( is_array( $set['tinymce'] ) )
   463 				$mceInit = array_merge($mceInit, $set['tinymce']);
   661 				$mceInit = array_merge( $mceInit, $set['tinymce'] );
   464 
   662 
   465 			// For people who really REALLY know what they're doing with TinyMCE
   663 			/*
   466 			// You can modify $mceInit to add, remove, change elements of the config before tinyMCE.init
   664 			 * For people who really REALLY know what they're doing with TinyMCE
   467 			// Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through this filter.
   665 			 * You can modify $mceInit to add, remove, change elements of the config
   468 			// Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0.
   666 			 * before tinyMCE.init. Setting "valid_elements", "invalid_elements"
       
   667 			 * and "extended_valid_elements" can be done through this filter. Best
       
   668 			 * is to use the default cleanup by not specifying valid_elements,
       
   669 			 * as TinyMCE contains full set of XHTML 1.0.
       
   670 			 */
   469 			if ( $set['teeny'] ) {
   671 			if ( $set['teeny'] ) {
   470 				$mceInit = apply_filters('teeny_mce_before_init', $mceInit, $editor_id);
   672 
       
   673 				/**
       
   674 				 * Filter the teenyMCE config before init.
       
   675 				 *
       
   676 				 * @since 2.7.0
       
   677 				 *
       
   678 				 * @param array  $mceInit   An array with teenyMCE config.
       
   679 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   680 				 */
       
   681 				$mceInit = apply_filters( 'teeny_mce_before_init', $mceInit, $editor_id );
   471 			} else {
   682 			} else {
   472 				$mceInit = apply_filters('tiny_mce_before_init', $mceInit, $editor_id);
   683 
   473 			}
   684 				/**
   474 
   685 				 * Filter the TinyMCE config before init.
   475 			if ( empty($mceInit['theme_advanced_buttons3']) && !empty($mceInit['theme_advanced_buttons4']) ) {
   686 				 *
   476 				$mceInit['theme_advanced_buttons3'] = $mceInit['theme_advanced_buttons4'];
   687 				 * @since 2.5.0
   477 				$mceInit['theme_advanced_buttons4'] = '';
   688 				 *
       
   689 				 * @param array  $mceInit   An array with TinyMCE config.
       
   690 				 * @param string $editor_id Unique editor identifier, e.g. 'content'.
       
   691 				 */
       
   692 				$mceInit = apply_filters( 'tiny_mce_before_init', $mceInit, $editor_id );
       
   693 			}
       
   694 
       
   695 			if ( empty( $mceInit['toolbar3'] ) && ! empty( $mceInit['toolbar4'] ) ) {
       
   696 				$mceInit['toolbar3'] = $mceInit['toolbar4'];
       
   697 				$mceInit['toolbar4'] = '';
   478 			}
   698 			}
   479 
   699 
   480 			self::$mce_settings[$editor_id] = $mceInit;
   700 			self::$mce_settings[$editor_id] = $mceInit;
   481 		} // end if self::$this_tinymce
   701 		} // end if self::$this_tinymce
   482 	}
   702 	}
   503 		wp_enqueue_script('word-count');
   723 		wp_enqueue_script('word-count');
   504 
   724 
   505 		if ( self::$has_tinymce )
   725 		if ( self::$has_tinymce )
   506 			wp_enqueue_script('editor');
   726 			wp_enqueue_script('editor');
   507 
   727 
   508 		if ( self::$has_quicktags )
   728 		if ( self::$has_quicktags ) {
   509 			wp_enqueue_script('quicktags');
   729 			wp_enqueue_script( 'quicktags' );
       
   730 			wp_enqueue_style( 'buttons' );
       
   731 		}
   510 
   732 
   511 		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) {
   733 		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) {
   512 			wp_enqueue_script('wplink');
   734 			wp_enqueue_script('wplink');
   513 			wp_enqueue_script('wpdialogs-popup');
       
   514 			wp_enqueue_style('wp-jquery-ui-dialog');
       
   515 		}
   735 		}
   516 
   736 
   517 		if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
   737 		if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
   518 			wp_enqueue_script('wp-fullscreen');
   738 			wp_enqueue_script('wp-fullscreen');
   519 
   739 
   520 		if ( self::$has_medialib ) {
   740 		if ( self::$has_medialib ) {
   521 			add_thickbox();
   741 			add_thickbox();
   522 			wp_enqueue_script('media-upload');
   742 			wp_enqueue_script('media-upload');
   523 		}
   743 		}
       
   744 
       
   745 		/**
       
   746 		 * Fires when scripts and styles are enqueued for the editor.
       
   747 		 *
       
   748 		 * @since 3.9.0
       
   749 		 *
       
   750 		 * @param array $to_load An array containing boolean values whether TinyMCE
       
   751 		 *                       and Quicktags are being loaded.
       
   752 		 */
       
   753 		do_action( 'wp_enqueue_editor', array(
       
   754 			'tinymce'   => self::$has_tinymce,
       
   755 			'quicktags' => self::$has_quicktags,
       
   756 		) );
       
   757 	}
       
   758 
       
   759 	/**
       
   760 	 * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n().
       
   761 	 * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object.
       
   762 	 *
       
   763 	 * @param string $mce_locale The locale used for the editor.
       
   764 	 * @param bool $json_only optional Whether to include the JavaScript calls to tinymce.addI18n() and tinymce.ScriptLoader.markDone().
       
   765 	 * @return string Translation object, JSON encoded.
       
   766 	 */
       
   767 	public static function wp_mce_translation( $mce_locale = '', $json_only = false ) {
       
   768 
       
   769 		$mce_translation = array(
       
   770 			// Default TinyMCE strings
       
   771 			'New document' => __( 'New document' ),
       
   772 			'Formats' => _x( 'Formats', 'TinyMCE' ),
       
   773 
       
   774 			'Headings' => _x( 'Headings', 'TinyMCE' ),
       
   775 			'Heading 1' => __( 'Heading 1' ),
       
   776 			'Heading 2' => __( 'Heading 2' ),
       
   777 			'Heading 3' => __( 'Heading 3' ),
       
   778 			'Heading 4' => __( 'Heading 4' ),
       
   779 			'Heading 5' => __( 'Heading 5' ),
       
   780 			'Heading 6' => __( 'Heading 6' ),
       
   781 
       
   782 			/* translators: block tags */
       
   783 			'Blocks' => _x( 'Blocks', 'TinyMCE' ),
       
   784 			'Paragraph' => __( 'Paragraph' ),
       
   785 			'Blockquote' => __( 'Blockquote' ),
       
   786 			'Div' => _x( 'Div', 'HTML tag' ),
       
   787 			'Pre' => _x( 'Pre', 'HTML tag' ),
       
   788 			'Address' => _x( 'Address', 'HTML tag' ),
       
   789 
       
   790 			'Inline' => _x( 'Inline', 'HTML elements' ),
       
   791 			'Underline' => __( 'Underline' ),
       
   792 			'Strikethrough' => __( 'Strikethrough' ),
       
   793 			'Subscript' => __( 'Subscript' ),
       
   794 			'Superscript' => __( 'Superscript' ),
       
   795 			'Clear formatting' => __( 'Clear formatting' ),
       
   796 			'Bold' => __( 'Bold' ),
       
   797 			'Italic' => __( 'Italic' ),
       
   798 			'Code' => _x( 'Code', 'editor button' ),
       
   799 			'Source code' => __( 'Source code' ),
       
   800 			'Font Family' => __( 'Font Family' ),
       
   801 			'Font Sizes' => __( 'Font Sizes' ),
       
   802 
       
   803 			'Align center' => __( 'Align center' ),
       
   804 			'Align right' => __( 'Align right' ),
       
   805 			'Align left' => __( 'Align left' ),
       
   806 			'Justify' => __( 'Justify' ),
       
   807 			'Increase indent' => __( 'Increase indent' ),
       
   808 			'Decrease indent' => __( 'Decrease indent' ),
       
   809 
       
   810 			'Cut' => __( 'Cut' ),
       
   811 			'Copy' => __( 'Copy' ),
       
   812 			'Paste' => __( 'Paste' ),
       
   813 			'Select all' => __( 'Select all' ),
       
   814 			'Undo' => __( 'Undo' ),
       
   815 			'Redo' => __( 'Redo' ),
       
   816 
       
   817 			'Ok' => __( 'OK' ),
       
   818 			'Cancel' => __( 'Cancel' ),
       
   819 			'Close' => __( 'Close' ),
       
   820 			'Visual aids' => __( 'Visual aids' ),
       
   821 
       
   822 			'Bullet list' => __( 'Bulleted list' ),
       
   823 			'Numbered list' => __( 'Numbered list' ),
       
   824 			'Square' => _x( 'Square', 'list style' ),
       
   825 			'Default' => _x( 'Default', 'list style' ),
       
   826 			'Circle' => _x( 'Circle', 'list style' ),
       
   827 			'Disc' => _x('Disc', 'list style' ),
       
   828 			'Lower Greek' => _x( 'Lower Greek', 'list style' ),
       
   829 			'Lower Alpha' => _x( 'Lower Alpha', 'list style' ),
       
   830 			'Upper Alpha' => _x( 'Upper Alpha', 'list style' ),
       
   831 			'Upper Roman' => _x( 'Upper Roman', 'list style' ),
       
   832 			'Lower Roman' => _x( 'Lower Roman', 'list style' ),
       
   833 
       
   834 			// Anchor plugin
       
   835 			'Name' => _x( 'Name', 'Name of link anchor (TinyMCE)' ),
       
   836 			'Anchor' => _x( 'Anchor', 'Link anchor (TinyMCE)' ),
       
   837 			'Anchors' => _x( 'Anchors', 'Link anchors (TinyMCE)' ),
       
   838 
       
   839 			// Fullpage plugin
       
   840 			'Document properties' => __( 'Document properties' ),
       
   841 			'Robots' => __( 'Robots' ),
       
   842 			'Title' => __( 'Title' ),
       
   843 			'Keywords' => __( 'Keywords' ),
       
   844 			'Encoding' => __( 'Encoding' ),
       
   845 			'Description' => __( 'Description' ),
       
   846 			'Author' => __( 'Author' ),
       
   847 
       
   848 			// Media, image plugins
       
   849 			'Insert/edit image' => __( 'Insert/edit image' ),
       
   850 			'General' => __( 'General' ),
       
   851 			'Advanced' => __( 'Advanced' ),
       
   852 			'Source' => __( 'Source' ),
       
   853 			'Border' => __( 'Border' ),
       
   854 			'Constrain proportions' => __( 'Constrain proportions' ),
       
   855 			'Vertical space' => __( 'Vertical space' ),
       
   856 			'Image description' => __( 'Image description' ),
       
   857 			'Style' => __( 'Style' ),
       
   858 			'Dimensions' => __( 'Dimensions' ),
       
   859 			'Insert image' => __( 'Insert image' ),
       
   860 			'Insert date/time' => __( 'Insert date/time' ),
       
   861 			'Insert/edit video' => __( 'Insert/edit video' ),
       
   862 			'Poster' => __( 'Poster' ),
       
   863 			'Alternative source' => __( 'Alternative source' ),
       
   864 			'Paste your embed code below:' => __( 'Paste your embed code below:' ),
       
   865 			'Insert video' => __( 'Insert video' ),
       
   866 			'Embed' => __( 'Embed' ),
       
   867 
       
   868 			// Each of these have a corresponding plugin
       
   869 			'Special character' => __( 'Special character' ),
       
   870 			'Right to left' => _x( 'Right to left', 'editor button' ),
       
   871 			'Left to right' => _x( 'Left to right', 'editor button' ),
       
   872 			'Emoticons' => __( 'Emoticons' ),
       
   873 			'Nonbreaking space' => __( 'Nonbreaking space' ),
       
   874 			'Page break' => __( 'Page break' ),
       
   875 			'Paste as text' => __( 'Paste as text' ),
       
   876 			'Preview' => __( 'Preview' ),
       
   877 			'Print' => __( 'Print' ),
       
   878 			'Save' => __( 'Save' ),
       
   879 			'Fullscreen' => __( 'Fullscreen' ),
       
   880 			'Horizontal line' => __( 'Horizontal line' ),
       
   881 			'Horizontal space' => __( 'Horizontal space' ),
       
   882 			'Restore last draft' => __( 'Restore last draft' ),
       
   883 			'Insert/edit link' => __( 'Insert/edit link' ),
       
   884 			'Remove link' => __( 'Remove link' ),
       
   885 
       
   886 			'Color' => __( 'Color' ),
       
   887 			'Custom color' => __( 'Custom color' ),
       
   888 			'Custom...' => _x( 'Custom...', 'label for custom color' ),
       
   889 			'No color' => __( 'No color' ),
       
   890 
       
   891 			// Spelling, search/replace plugins
       
   892 			'Could not find the specified string.' => __( 'Could not find the specified string.' ),
       
   893 			'Replace' => _x( 'Replace', 'find/replace' ),
       
   894 			'Next' => _x( 'Next', 'find/replace' ),
       
   895 			/* translators: previous */
       
   896 			'Prev' => _x( 'Prev', 'find/replace' ),
       
   897 			'Whole words' => _x( 'Whole words', 'find/replace' ),
       
   898 			'Find and replace' => __( 'Find and replace' ),
       
   899 			'Replace with' => _x('Replace with', 'find/replace' ),
       
   900 			'Find' => _x( 'Find', 'find/replace' ),
       
   901 			'Replace all' => _x( 'Replace all', 'find/replace' ),
       
   902 			'Match case' => __( 'Match case' ),
       
   903 			'Spellcheck' => __( 'Check Spelling' ),
       
   904 			'Finish' => _x( 'Finish', 'spellcheck' ),
       
   905 			'Ignore all' => _x( 'Ignore all', 'spellcheck' ),
       
   906 			'Ignore' => _x( 'Ignore', 'spellcheck' ),
       
   907 			'Add to Dictionary' => __( 'Add to Dictionary' ),
       
   908 
       
   909 			// TinyMCE tables
       
   910 			'Insert table' => __( 'Insert table' ),
       
   911 			'Delete table' => __( 'Delete table' ),
       
   912 			'Table properties' => __( 'Table properties' ),
       
   913 			'Row properties' => __( 'Table row properties' ),
       
   914 			'Cell properties' => __( 'Table cell properties' ),
       
   915 			'Border color' => __( 'Border color' ),
       
   916 
       
   917 			'Row' => __( 'Row' ),
       
   918 			'Rows' => __( 'Rows' ),
       
   919 			'Column' => _x( 'Column', 'table column' ),
       
   920 			'Cols' => _x( 'Cols', 'table columns' ),
       
   921 			'Cell' => _x( 'Cell', 'table cell' ),
       
   922 			'Header cell' => __( 'Header cell' ),
       
   923 			'Header' => _x( 'Header', 'table header' ),
       
   924 			'Body' => _x( 'Body', 'table body' ),
       
   925 			'Footer' => _x( 'Footer', 'table footer' ),
       
   926 
       
   927 			'Insert row before' => __( 'Insert row before' ),
       
   928 			'Insert row after' => __( 'Insert row after' ),
       
   929 			'Insert column before' => __( 'Insert column before' ),
       
   930 			'Insert column after' => __( 'Insert column after' ),
       
   931 			'Paste row before' => __( 'Paste table row before' ),
       
   932 			'Paste row after' => __( 'Paste table row after' ),
       
   933 			'Delete row' => __( 'Delete row' ),
       
   934 			'Delete column' => __( 'Delete column' ),
       
   935 			'Cut row' => __( 'Cut table row' ),
       
   936 			'Copy row' => __( 'Copy table row' ),
       
   937 			'Merge cells' => __( 'Merge table cells' ),
       
   938 			'Split cell' => __( 'Split table cell' ),
       
   939 
       
   940 			'Height' => __( 'Height' ),
       
   941 			'Width' => __( 'Width' ),
       
   942 			'Caption' => __( 'Caption' ),
       
   943 			'Alignment' => __( 'Alignment' ),
       
   944 			'H Align' => _x( 'H Align', 'horizontal table cell alignment' ),
       
   945 			'Left' => __( 'Left' ),
       
   946 			'Center' => __( 'Center' ),
       
   947 			'Right' => __( 'Right' ),
       
   948 			'None' => _x( 'None', 'table cell alignment attribute' ),
       
   949 			'V Align' => _x( 'V Align', 'vertical table cell alignment' ),
       
   950 			'Top' => __( 'Top' ),
       
   951 			'Middle' => __( 'Middle' ),
       
   952 			'Bottom' => __( 'Bottom' ),
       
   953 
       
   954 			'Row group' => __( 'Row group' ),
       
   955 			'Column group' => __( 'Column group' ),
       
   956 			'Row type' => __( 'Row type' ),
       
   957 			'Cell type' => __( 'Cell type' ),
       
   958 			'Cell padding' => __( 'Cell padding' ),
       
   959 			'Cell spacing' => __( 'Cell spacing' ),
       
   960 			'Scope' => _x( 'Scope', 'table cell scope attribute' ),
       
   961 
       
   962 			'Insert template' => _x( 'Insert template', 'TinyMCE' ),
       
   963 			'Templates' => _x( 'Templates', 'TinyMCE' ),
       
   964 
       
   965 			'Background color' => __( 'Background color' ),
       
   966 			'Text color' => __( 'Text color' ),
       
   967 			'Show blocks' => _x( 'Show blocks', 'editor button' ),
       
   968 			'Show invisible characters' => __( 'Show invisible characters' ),
       
   969 
       
   970 			/* translators: word count */
       
   971 			'Words: {0}' => sprintf( __( 'Words: %s' ), '{0}' ),
       
   972 			'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' => __( 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' ) . "\n\n" . __( 'If you&#8217;re looking to paste rich content from Microsoft Word, try turning this option off. The editor will clean up text pasted from Word automatically.' ),
       
   973 			'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help' => __( 'Rich Text Area. Press Alt-Shift-H for help' ),
       
   974 			'You have unsaved changes are you sure you want to navigate away?' => __( 'The changes you made will be lost if you navigate away from this page.' ),
       
   975 			'Your browser doesn\'t support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.' => __( 'Your browser does not support direct access to the clipboard. Please use keyboard shortcuts or your browser&#8217;s edit menu instead.' ),
       
   976 
       
   977 			// TinyMCE menus
       
   978 			'Insert' => _x( 'Insert', 'TinyMCE menu' ),
       
   979 			'File' => _x( 'File', 'TinyMCE menu' ),
       
   980 			'Edit' => _x( 'Edit', 'TinyMCE menu' ),
       
   981 			'Tools' => _x( 'Tools', 'TinyMCE menu' ),
       
   982 			'View' => _x( 'View', 'TinyMCE menu' ),
       
   983 			'Table' => _x( 'Table', 'TinyMCE menu' ),
       
   984 			'Format' => _x( 'Format', 'TinyMCE menu' ),
       
   985 
       
   986 			// WordPress strings
       
   987 			'Keyboard Shortcuts' => __( 'Keyboard Shortcuts' ),
       
   988 			'Toolbar Toggle' => __( 'Toolbar Toggle' ),
       
   989 			'Insert Read More tag' => __( 'Insert Read More tag' ),
       
   990 			'Read more...' => __( 'Read more...' ), // Title on the placeholder inside the editor
       
   991 			'Distraction-free writing mode' => __( 'Distraction-free writing mode' ),
       
   992 			'No alignment' => __( 'No alignment' ), // Tooltip for the 'alignnone' button in the image toolbar
       
   993 			'Remove' => __( 'Remove' ), // Tooltip for the 'remove' button in the image toolbar
       
   994 			'Edit ' => __( 'Edit' ), // Tooltip for the 'edit' button in the image toolbar
       
   995 		);
       
   996 
       
   997 		/**
       
   998 		 * Link plugin (not included):
       
   999 		 *	Insert link
       
  1000 		 *	Target
       
  1001 		 *	New window
       
  1002 		 *	Text to display
       
  1003 		 *	The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?
       
  1004 		 *	The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?
       
  1005 		 *	Url
       
  1006 		 */
       
  1007 
       
  1008 		if ( ! $mce_locale ) {
       
  1009 			$mce_locale = self::$mce_locale;
       
  1010 		}
       
  1011 
       
  1012 		/**
       
  1013 		 * Filter translated strings prepared for TinyMCE.
       
  1014 		 *
       
  1015 		 * @since 3.9.0
       
  1016 		 *
       
  1017 		 * @param array  $mce_translation Key/value pairs of strings.
       
  1018 		 * @param string $mce_locale      Locale.
       
  1019 		 */
       
  1020 		$mce_translation = apply_filters( 'wp_mce_translation', $mce_translation, $mce_locale );
       
  1021 
       
  1022 		foreach ( $mce_translation as $key => $value ) {
       
  1023 			// Remove strings that are not translated.
       
  1024 			if ( $key === $value ) {
       
  1025 				unset( $mce_translation[$key] );
       
  1026 				continue;
       
  1027 			}
       
  1028 
       
  1029 			if ( false !== strpos( $value, '&' ) ) {
       
  1030 				$mce_translation[$key] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8' );
       
  1031 			}
       
  1032 		}
       
  1033 
       
  1034 		// Set direction
       
  1035 		if ( is_rtl() ) {
       
  1036 			$mce_translation['_dir'] = 'rtl';
       
  1037 		}
       
  1038 
       
  1039 		if ( $json_only ) {
       
  1040 			return wp_json_encode( $mce_translation );
       
  1041 		}
       
  1042 
       
  1043 		$baseurl = self::$baseurl ? self::$baseurl : includes_url( 'js/tinymce' );
       
  1044 
       
  1045 		return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" .
       
  1046 			"tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n";
   524 	}
  1047 	}
   525 
  1048 
   526 	public static function editor_js() {
  1049 	public static function editor_js() {
   527 		global $tinymce_version, $concatenate_scripts, $compress_scripts;
  1050 		global $tinymce_version, $concatenate_scripts, $compress_scripts;
   528 
  1051 
   540 			script_concat_settings();
  1063 			script_concat_settings();
   541 
  1064 
   542 		$compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
  1065 		$compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
   543 			&& false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
  1066 			&& false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
   544 
  1067 
   545 		if ( $tmce_on && 'en' != self::$mce_locale )
       
   546 			include_once(ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php');
       
   547 
       
   548 		$mceInit = $qtInit = '';
  1068 		$mceInit = $qtInit = '';
   549 		if ( $tmce_on ) {
  1069 		if ( $tmce_on ) {
   550 			foreach ( self::$mce_settings as $editor_id => $init ) {
  1070 			foreach ( self::$mce_settings as $editor_id => $init ) {
   551 				$options = self::_parse_init( $init );
  1071 				$options = self::_parse_init( $init );
   552 				$mceInit .= "'$editor_id':{$options},";
  1072 				$mceInit .= "'$editor_id':{$options},";
   566 			$qtInit = '{}';
  1086 			$qtInit = '{}';
   567 		}
  1087 		}
   568 
  1088 
   569 		$ref = array(
  1089 		$ref = array(
   570 			'plugins' => implode( ',', self::$plugins ),
  1090 			'plugins' => implode( ',', self::$plugins ),
   571 			'theme' => 'advanced',
  1091 			'theme' => 'modern',
   572 			'language' => self::$mce_locale
  1092 			'language' => self::$mce_locale
   573 		);
  1093 		);
   574 
  1094 
   575 		$suffix = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ? '_src' : '';
  1095 		$suffix = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ? '' : '.min';
   576 
  1096 
   577 		do_action('before_wp_tiny_mce', self::$mce_settings);
  1097 		/**
   578 ?>
  1098 		 * Fires immediately before the TinyMCE settings are printed.
   579 
  1099 		 *
   580 	<script type="text/javascript">
  1100 		 * @since 3.2.0
       
  1101 		 *
       
  1102 		 * @param array $mce_settings TinyMCE settings array.
       
  1103 		 */
       
  1104 		do_action( 'before_wp_tiny_mce', self::$mce_settings );
       
  1105 		?>
       
  1106 
       
  1107 		<script type="text/javascript">
   581 		tinyMCEPreInit = {
  1108 		tinyMCEPreInit = {
   582 			base : "<?php echo self::$baseurl; ?>",
  1109 			baseURL: "<?php echo self::$baseurl; ?>",
   583 			suffix : "<?php echo $suffix; ?>",
  1110 			suffix: "<?php echo $suffix; ?>",
   584 			query : "<?php echo $version; ?>",
  1111 			<?php
   585 			mceInit : <?php echo $mceInit; ?>,
  1112 
   586 			qtInit : <?php echo $qtInit; ?>,
  1113 			if ( self::$drag_drop_upload ) {
   587 			ref : <?php echo self::_parse_init( $ref ); ?>,
  1114 				echo 'dragDropUpload: true,';
   588 			load_ext : function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
  1115 			}
       
  1116 
       
  1117 			?>
       
  1118 			mceInit: <?php echo $mceInit; ?>,
       
  1119 			qtInit: <?php echo $qtInit; ?>,
       
  1120 			ref: <?php echo self::_parse_init( $ref ); ?>,
       
  1121 			load_ext: function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
   589 		};
  1122 		};
   590 	</script>
  1123 		</script>
   591 <?php
  1124 		<?php
   592 
  1125 
   593 		$baseurl = self::$baseurl;
  1126 		$baseurl = self::$baseurl;
       
  1127 		// Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG)
       
  1128 		$mce_suffix = false !== strpos( $GLOBALS['wp_version'], '-src' ) ? '' : '.min';
   594 
  1129 
   595 		if ( $tmce_on ) {
  1130 		if ( $tmce_on ) {
   596 			if ( $compressed ) {
  1131 			if ( $compressed ) {
   597 				echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
  1132 				echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
   598 			} else {
  1133 			} else {
   599 				echo "<script type='text/javascript' src='{$baseurl}/tiny_mce.js?$version'></script>\n";
  1134 				echo "<script type='text/javascript' src='{$baseurl}/tinymce{$mce_suffix}.js?$version'></script>\n";
   600 				echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce-schema.js?$version'></script>\n";
  1135 				echo "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin{$suffix}.js?$version'></script>\n";
   601 			}
  1136 			}
   602 
  1137 
   603 			if ( 'en' != self::$mce_locale && isset($lang) )
  1138 			echo "<script type='text/javascript'>\n" . self::wp_mce_translation() . "</script>\n";
   604 				echo "<script type='text/javascript'>\n$lang\n</script>\n";
  1139 
   605 			else
  1140 			if ( self::$ext_plugins ) {
       
  1141 				// Load the old-format English strings to prevent unsightly labels in old style popups
   606 				echo "<script type='text/javascript' src='{$baseurl}/langs/wp-langs-en.js?$version'></script>\n";
  1142 				echo "<script type='text/javascript' src='{$baseurl}/langs/wp-langs-en.js?$version'></script>\n";
   607 		}
  1143 			}
   608 
  1144 		}
   609 		$mce = ( self::$has_tinymce && wp_default_editor() == 'tinymce' ) || ! self::$has_quicktags;
  1145 
   610 ?>
  1146 		/**
   611 
  1147 		 * Fires after tinymce.js is loaded, but before any TinyMCE editor
   612 	<script type="text/javascript">
  1148 		 * instances are created.
   613 		var wpActiveEditor;
  1149 		 *
   614 
  1150 		 * @since 3.9.0
   615 		(function(){
  1151 		 *
   616 			var init, ed, qt, first_init, DOM, el, i, mce = <?php echo (int) $mce; ?>;
  1152 		 * @param array $mce_settings TinyMCE settings array.
   617 
  1153 		 */
   618 			if ( typeof(tinymce) == 'object' ) {
  1154 		do_action( 'wp_tiny_mce_init', self::$mce_settings );
   619 				DOM = tinymce.DOM;
  1155 
   620 				// mark wp_theme/ui.css as loaded
  1156 		?>
   621 				DOM.files[tinymce.baseURI.getURI() + '/themes/advanced/skins/wp_theme/ui.css'] = true;
  1157 		<script type="text/javascript">
   622 
  1158 		<?php
   623 				DOM.events.add( DOM.select('.wp-editor-wrap'), 'mousedown', function(e){
  1159 
   624 					if ( this.id )
  1160 		if ( self::$ext_plugins )
   625 						wpActiveEditor = this.id.slice(3, -5);
  1161 			echo self::$ext_plugins . "\n";
   626 				});
  1162 
   627 
  1163 		if ( ! is_admin() )
   628 				for ( ed in tinyMCEPreInit.mceInit ) {
  1164 			echo 'var ajaxurl = "' . admin_url( 'admin-ajax.php', 'relative' ) . '";';
   629 					if ( first_init ) {
  1165 
   630 						init = tinyMCEPreInit.mceInit[ed] = tinymce.extend( {}, first_init, tinyMCEPreInit.mceInit[ed] );
  1166 		?>
       
  1167 
       
  1168 		( function() {
       
  1169 			var init, edId, qtId, firstInit, wrapper;
       
  1170 
       
  1171 			if ( typeof tinymce !== 'undefined' ) {
       
  1172 				for ( edId in tinyMCEPreInit.mceInit ) {
       
  1173 					if ( firstInit ) {
       
  1174 						init = tinyMCEPreInit.mceInit[edId] = tinymce.extend( {}, firstInit, tinyMCEPreInit.mceInit[edId] );
   631 					} else {
  1175 					} else {
   632 						init = first_init = tinyMCEPreInit.mceInit[ed];
  1176 						init = firstInit = tinyMCEPreInit.mceInit[edId];
   633 					}
  1177 					}
   634 
  1178 
   635 					if ( mce )
  1179 					wrapper = tinymce.DOM.select( '#wp-' + edId + '-wrap' )[0];
   636 						try { tinymce.init(init); } catch(e){}
  1180 
   637 				}
  1181 					if ( ( tinymce.DOM.hasClass( wrapper, 'tmce-active' ) || ! tinyMCEPreInit.qtInit.hasOwnProperty( edId ) ) &&
   638 			} else {
  1182 						! init.wp_skip_init ) {
   639 				if ( tinyMCEPreInit.qtInit ) {
  1183 
   640 					for ( i in tinyMCEPreInit.qtInit ) {
  1184 						try {
   641 						el = tinyMCEPreInit.qtInit[i].id;
  1185 							tinymce.init( init );
   642 						if ( el )
  1186 
   643 							document.getElementById('wp-'+el+'-wrap').onmousedown = function(){ wpActiveEditor = this.id.slice(3, -5); }
  1187 							if ( ! window.wpActiveEditor ) {
       
  1188 								window.wpActiveEditor = edId;
       
  1189 							}
       
  1190 						} catch(e){}
   644 					}
  1191 					}
   645 				}
  1192 				}
   646 			}
  1193 			}
   647 
  1194 
   648 			if ( typeof(QTags) == 'function' ) {
  1195 			if ( typeof quicktags !== 'undefined' ) {
   649 				for ( qt in tinyMCEPreInit.qtInit ) {
  1196 				for ( qtId in tinyMCEPreInit.qtInit ) {
   650 					try { quicktags( tinyMCEPreInit.qtInit[qt] ); } catch(e){}
  1197 					try {
       
  1198 						quicktags( tinyMCEPreInit.qtInit[qtId] );
       
  1199 
       
  1200 						if ( ! window.wpActiveEditor ) {
       
  1201 							window.wpActiveEditor = qtId;
       
  1202 						}
       
  1203 					} catch(e){};
   651 				}
  1204 				}
   652 			}
  1205 			}
   653 		})();
  1206 
   654 		<?php
  1207 			if ( typeof jQuery !== 'undefined' ) {
   655 
  1208 				jQuery('.wp-editor-wrap').on( 'click.wp-editor', function() {
   656 		if ( self::$ext_plugins )
  1209 					if ( this.id ) {
   657 			echo self::$ext_plugins . "\n";
  1210 						window.wpActiveEditor = this.id.slice( 3, -5 );
   658 
  1211 					}
   659 		if ( ! $compressed && $tmce_on ) {
  1212 				});
   660 			?>
  1213 			} else {
   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');}});})();
  1214 				for ( qtId in tinyMCEPreInit.qtInit ) {
   662 			<?php
  1215 					document.getElementById( 'wp-' + qtId + '-wrap' ).onclick = function() {
   663 		}
  1216 						window.wpActiveEditor = this.id.slice( 3, -5 );
   664 
  1217 					}
   665 		if ( !is_admin() )
  1218 				}
   666 			echo 'var ajaxurl = "' . admin_url( 'admin-ajax.php', 'relative' ) . '";';
  1219 			}
   667 
  1220 		}());
   668 		?>
       
   669 		</script>
  1221 		</script>
   670 		<?php
  1222 		<?php
   671 
  1223 
   672 		if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) )
  1224 		if ( in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) )
   673 			self::wp_link_dialog();
  1225 			self::wp_link_dialog();
   674 
  1226 
   675 		if ( in_array('wpfullscreen', self::$plugins, true) || in_array('fullscreen', self::$qt_buttons, true) )
  1227 		if ( in_array( 'wpfullscreen', self::$plugins, true ) || in_array( 'fullscreen', self::$qt_buttons, true ) )
   676 			self::wp_fullscreen_html();
  1228 			self::wp_fullscreen_html();
   677 
  1229 
   678 		do_action('after_wp_tiny_mce', self::$mce_settings);
  1230 		/**
       
  1231 		 * Fires after any core TinyMCE editor instances are created.
       
  1232 		 *
       
  1233 		 * @since 3.2.0
       
  1234 		 *
       
  1235 		 * @param array $mce_settings TinyMCE settings array.
       
  1236 		 */
       
  1237 		do_action( 'after_wp_tiny_mce', self::$mce_settings );
   679 	}
  1238 	}
   680 
  1239 
   681 	public static function wp_fullscreen_html() {
  1240 	public static function wp_fullscreen_html() {
   682 		global $content_width;
  1241 		global $content_width;
   683 		$post = get_post();
  1242 		$post = get_post();
   684 
  1243 
   685 		$width = isset($content_width) && 800 > $content_width ? $content_width : 800;
  1244 		$width = isset( $content_width ) && 800 > $content_width ? $content_width : 800;
   686 		$width = $width + 22; // compensate for the padding and border
  1245 		$width = $width + 22; // compensate for the padding and border
   687 		$dfw_width = get_user_setting( 'dfw_width', $width );
  1246 		$dfw_width = get_user_setting( 'dfw_width', $width );
   688 		$save = isset($post->post_status) && $post->post_status == 'publish' ? __('Update') : __('Save');
  1247 		$save = $post && $post->post_status == 'publish' ? __('Update') : __('Save');
   689 	?>
  1248 
   690 	<div id="wp-fullscreen-body"<?php if ( is_rtl() ) echo ' class="rtl"'; ?>>
  1249 		?>
   691 	<div id="fullscreen-topbar">
  1250 		<div id="wp-fullscreen-body" class="wp-core-ui<?php if ( is_rtl() ) echo ' rtl'; ?>" data-theme-width="<?php echo (int) $width; ?>" data-dfw-width="<?php echo (int) $dfw_width; ?>">
   692 		<div id="wp-fullscreen-toolbar">
  1251 		<div id="fullscreen-topbar">
   693 			<div id="wp-fullscreen-close"><a href="#" onclick="fullscreen.off();return false;"><?php _e('Exit fullscreen'); ?></a></div>
  1252 			<div id="wp-fullscreen-toolbar">
       
  1253 			<div id="wp-fullscreen-close"><a href="#" onclick="wp.editor.fullscreen.off();return false;"><?php _e('Exit fullscreen'); ?></a></div>
   694 			<div id="wp-fullscreen-central-toolbar" style="width:<?php echo $width; ?>px;">
  1254 			<div id="wp-fullscreen-central-toolbar" style="width:<?php echo $width; ?>px;">
   695 
  1255 
   696 			<div id="wp-fullscreen-mode-bar"><div id="wp-fullscreen-modes">
  1256 			<div id="wp-fullscreen-mode-bar">
   697 				<a href="#" onclick="fullscreen.switchmode('tinymce');return false;"><?php _e( 'Visual' ); ?></a>
  1257 				<div id="wp-fullscreen-modes" class="button-group">
   698 				<a href="#" onclick="fullscreen.switchmode('html');return false;"><?php _ex( 'Text', 'Name for the Text editor tab (formerly HTML)' ); ?></a>
  1258 					<a class="button wp-fullscreen-mode-tinymce" href="#" onclick="wp.editor.fullscreen.switchmode( 'tinymce' ); return false;"><?php _e( 'Visual' ); ?></a>
   699 			</div></div>
  1259 					<a class="button wp-fullscreen-mode-html" href="#" onclick="wp.editor.fullscreen.switchmode( 'html' ); return false;"><?php _ex( 'Text', 'Name for the Text editor tab (formerly HTML)' ); ?></a>
   700 
  1260 				</div>
   701 			<div id="wp-fullscreen-button-bar"><div id="wp-fullscreen-buttons" class="wp_themeSkin">
  1261 			</div>
   702 	<?php
  1262 
       
  1263 			<div id="wp-fullscreen-button-bar"><div id="wp-fullscreen-buttons" class="mce-toolbar">
       
  1264 		<?php
   703 
  1265 
   704 		$buttons = array(
  1266 		$buttons = array(
   705 			// format: title, onclick, show in both editors
  1267 			// format: title, onclick, show in both editors
   706 			'bold' => array( 'title' => __('Bold (Ctrl + B)'), 'onclick' => 'fullscreen.b();', 'both' => false ),
  1268 			'bold' => array( 'title' => __('Bold (Ctrl + B)'), 'both' => false ),
   707 			'italic' => array( 'title' => __('Italic (Ctrl + I)'), 'onclick' => 'fullscreen.i();', 'both' => false ),
  1269 			'italic' => array( 'title' => __('Italic (Ctrl + I)'), 'both' => false ),
   708 			'0' => 'separator',
  1270 			'bullist' => array( 'title' => __('Unordered list (Alt + Shift + U)'), 'both' => false ),
   709 			'bullist' => array( 'title' => __('Unordered list (Alt + Shift + U)'), 'onclick' => 'fullscreen.ul();', 'both' => false ),
  1271 			'numlist' => array( 'title' => __('Ordered list (Alt + Shift + O)'), 'both' => false ),
   710 			'numlist' => array( 'title' => __('Ordered list (Alt + Shift + O)'), 'onclick' => 'fullscreen.ol();', 'both' => false ),
  1272 			'blockquote' => array( 'title' => __('Blockquote (Alt + Shift + Q)'), 'both' => false ),
   711 			'1' => 'separator',
  1273 			'wp-media-library' => array( 'title' => __('Media library (Alt + Shift + M)'), 'both' => true ),
   712 			'blockquote' => array( 'title' => __('Blockquote (Alt + Shift + Q)'), 'onclick' => 'fullscreen.blockquote();', 'both' => false ),
  1274 			'link' => array( 'title' => __('Insert/edit link (Alt + Shift + A)'), 'both' => true ),
   713 			'image' => array( 'title' => __('Insert/edit image (Alt + Shift + M)'), 'onclick' => "fullscreen.medialib();", 'both' => true ),
  1275 			'unlink' => array( 'title' => __('Unlink (Alt + Shift + S)'), 'both' => false ),
   714 			'2' => 'separator',
  1276 			'help' => array( 'title' => __('Help (Alt + Shift + H)'), 'both' => false ),
   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 		);
  1277 		);
   720 
  1278 
       
  1279 		/**
       
  1280 		 * Filter the list of TinyMCE buttons for the fullscreen
       
  1281 		 * 'Distraction-Free Writing' editor.
       
  1282 		 *
       
  1283 		 * @since 3.2.0
       
  1284 		 *
       
  1285 		 * @param array $buttons An array of TinyMCE buttons for the DFW editor.
       
  1286 		 */
   721 		$buttons = apply_filters( 'wp_fullscreen_buttons', $buttons );
  1287 		$buttons = apply_filters( 'wp_fullscreen_buttons', $buttons );
   722 
  1288 
   723 		foreach ( $buttons as $button => $args ) {
  1289 		foreach ( $buttons as $button => $args ) {
   724 			if ( 'separator' == $args ) { ?>
  1290 			if ( 'separator' == $args ) {
   725 				<div><span aria-orientation="vertical" role="separator" class="mceSeparator"></span></div>
  1291 				continue;
   726 	<?php		continue;
  1292 			}
   727 			} ?>
  1293 
   728 
  1294 			$onclick = ! empty( $args['onclick'] ) ? ' onclick="' . $args['onclick'] . '"' : '';
   729 			<div<?php if ( $args['both'] ) { ?> class="wp-fullscreen-both"<?php } ?>>
  1295 			$title = esc_attr( $args['title'] );
   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">
  1296 			?>
   731 			<span class="mceIcon mce_<?php echo $button; ?>"></span>
  1297 
   732 			</a>
  1298 			<div class="mce-widget mce-btn<?php if ( $args['both'] ) { ?> wp-fullscreen-both<?php } ?>">
       
  1299 			<button type="button" aria-label="<?php echo $title; ?>" title="<?php echo $title; ?>"<?php echo $onclick; ?> id="wp_fs_<?php echo $button; ?>">
       
  1300 				<i class="mce-ico mce-i-<?php echo $button; ?>"></i>
       
  1301 			</button>
   733 			</div>
  1302 			</div>
   734 	<?php
  1303 			<?php
   735 		} ?>
  1304 		}
   736 
  1305 
   737 			</div></div>
  1306 		?>
   738 
  1307 
   739 			<div id="wp-fullscreen-save">
  1308 		</div></div>
   740 				<input type="button" class="button-primary right" value="<?php echo $save; ?>" onclick="fullscreen.save();" />
  1309 
   741 				<span class="spinner"></span>
  1310 		<div id="wp-fullscreen-save">
   742 				<span class="fs-saved"><?php if ( $post->post_status == 'publish' ) _e('Updated.'); else _e('Saved.'); ?></span>
  1311 			<input type="button" class="button button-primary right" value="<?php echo $save; ?>" onclick="wp.editor.fullscreen.save();" />
   743 			</div>
  1312 			<span class="wp-fullscreen-saved-message"><?php if ( $post && $post->post_status == 'publish' ) _e('Updated.'); else _e('Saved.'); ?></span>
   744 
  1313 			<span class="wp-fullscreen-error-message"><?php _e('Save failed.'); ?></span>
   745 			</div>
  1314 			<span class="spinner"></span>
       
  1315 		</div>
       
  1316 
       
  1317 		</div>
   746 		</div>
  1318 		</div>
   747 	</div>
  1319 	</div>
   748 
  1320 	<div id="wp-fullscreen-statusbar">
   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">
  1321 		<div id="wp-fullscreen-status">
   760 			<div id="wp-fullscreen-count"><?php printf( __( 'Word count: %s' ), '<span class="word-count">0</span>' ); ?></div>
  1322 			<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>
  1323 			<div id="wp-fullscreen-tagline"><?php _e('Just write.'); ?></div>
   762 		</div>
  1324 		</div>
   763 	</div>
  1325 	</div>
   764 	</div>
  1326 	</div>
   765 
  1327 
   766 	<div class="fullscreen-overlay" id="fullscreen-overlay"></div>
  1328 	<div class="fullscreen-overlay" id="fullscreen-overlay"></div>
   767 	<div class="fullscreen-overlay fullscreen-fader fade-600" id="fullscreen-fader"></div>
  1329 	<div class="fullscreen-overlay fullscreen-fader fade-300" id="fullscreen-fader"></div>
   768 	<?php
  1330 	<?php
   769 	}
  1331 	}
   770 
  1332 
   771 	/**
  1333 	/**
   772 	 * Performs post queries for internal linking.
  1334 	 * Performs post queries for internal linking.
   773 	 *
  1335 	 *
   774 	 * @since 3.1.0
  1336 	 * @since 3.1.0
   775 	 *
  1337 	 *
   776 	 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
  1338 	 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
   777 	 * @return array Results.
  1339 	 * @return false|array Results.
   778 	 */
  1340 	 */
   779 	public static function wp_link_query( $args = array() ) {
  1341 	public static function wp_link_query( $args = array() ) {
   780 		$pts = get_post_types( array( 'public' => true ), 'objects' );
  1342 		$pts = get_post_types( array( 'public' => true ), 'objects' );
   781 		$pt_names = array_keys( $pts );
  1343 		$pt_names = array_keys( $pts );
   782 
  1344 
   784 			'post_type' => $pt_names,
  1346 			'post_type' => $pt_names,
   785 			'suppress_filters' => true,
  1347 			'suppress_filters' => true,
   786 			'update_post_term_cache' => false,
  1348 			'update_post_term_cache' => false,
   787 			'update_post_meta_cache' => false,
  1349 			'update_post_meta_cache' => false,
   788 			'post_status' => 'publish',
  1350 			'post_status' => 'publish',
   789 			'order' => 'DESC',
       
   790 			'orderby' => 'post_date',
       
   791 			'posts_per_page' => 20,
  1351 			'posts_per_page' => 20,
   792 		);
  1352 		);
   793 
  1353 
   794 		$args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
  1354 		$args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
   795 
  1355 
   839 		 *
  1399 		 *
   840 		 * Allows modification of the returned link query results.
  1400 		 * Allows modification of the returned link query results.
   841 		 *
  1401 		 *
   842 		 * @since 3.7.0
  1402 		 * @since 3.7.0
   843 		 *
  1403 		 *
       
  1404 		 * @see 'wp_link_query_args' filter
       
  1405 		 *
   844 		 * @param array $results {
  1406 		 * @param array $results {
   845 		 *     An associative array of query results.
  1407 		 *     An associative array of query results.
   846 		 *
  1408 		 *
   847 		 *     @type array {
  1409 		 *     @type array {
   848 		 *         @type int    'ID'        The post ID.
  1410 		 *         @type int    $ID        Post ID.
   849 		 *         @type string 'title'     The trimmed, escaped post title.
  1411 		 *         @type string $title     The trimmed, escaped post title.
   850 		 *         @type string 'permalink' The post permalink.
  1412 		 *         @type string $permalink Post permalink.
   851 		 *         @type string 'info'      A 'Y/m/d'-formatted date for 'post' post type, the 'singular_name' post type label otherwise.
  1413 		 *         @type string $info      A 'Y/m/d'-formatted date for 'post' post type,
       
  1414 		 *                                 the 'singular_name' post type label otherwise.
   852 		 *     }
  1415 		 *     }
   853 		 * }
  1416 		 * }
   854 		 * @param array $query   An array of WP_Query arguments. @see 'wp_link_query_args' filter
  1417 		 * @param array $query  An array of WP_Query arguments.
   855 		 */
  1418 		 */
   856 		return apply_filters( 'wp_link_query', $results, $query );
  1419 		return apply_filters( 'wp_link_query', $results, $query );
   857 	}
  1420 	}
   858 
  1421 
   859 	/**
  1422 	/**
   860 	 * Dialog for internal linking.
  1423 	 * Dialog for internal linking.
   861 	 *
  1424 	 *
   862 	 * @since 3.1.0
  1425 	 * @since 3.1.0
   863 	 */
  1426 	 */
   864 	public static function wp_link_dialog() {
  1427 	public static function wp_link_dialog() {
   865 	?>
  1428 		$search_panel_visible = '1' == get_user_setting( 'wplink', '0' ) ? ' search-panel-visible' : '';
   866 	<div style="display:none;">
  1429 
   867 	<form id="wp-link" tabindex="-1">
  1430 		// display: none is required here, see #WP27605
   868 	<?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?>
  1431 		?>
   869 	<div id="link-selector">
  1432 		<div id="wp-link-backdrop" style="display: none"></div>
   870 		<div id="link-options">
  1433 		<div id="wp-link-wrap" class="wp-core-ui<?php echo $search_panel_visible; ?>" style="display: none">
   871 			<p class="howto"><?php _e( 'Enter the destination URL' ); ?></p>
  1434 		<form id="wp-link" tabindex="-1">
   872 			<div>
  1435 		<?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?>
   873 				<label><span><?php _e( 'URL' ); ?></span><input id="url-field" type="text" name="href" /></label>
  1436 		<div id="link-modal-title">
   874 			</div>
  1437 			<?php _e( 'Insert/edit link' ) ?>
   875 			<div>
  1438 			<button type="button" id="wp-link-close"><span class="screen-reader-text"><?php _e( 'Close' ); ?></span></button>
   876 				<label><span><?php _e( 'Title' ); ?></span><input id="link-title-field" type="text" name="linktitle" /></label>
  1439 	 	</div>
   877 			</div>
  1440 		<div id="link-selector">
   878 			<div class="link-target">
  1441 			<div id="link-options">
   879 				<label><input type="checkbox" id="link-target-checkbox" /> <?php _e( 'Open link in a new window/tab' ); ?></label>
  1442 				<p class="howto"><?php _e( 'Enter the destination URL' ); ?></p>
   880 			</div>
  1443 				<div>
   881 		</div>
  1444 					<label><span><?php _e( 'URL' ); ?></span><input id="wp-link-url" type="text" /></label>
   882 		<?php $show_internal = '1' == get_user_setting( 'wplink', '0' ); ?>
  1445 				</div>
   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>
  1446 				<div class="wp-link-text-field">
   884 		<div id="search-panel"<?php if ( ! $show_internal ) echo ' style="display:none"'; ?>>
  1447 					<label><span><?php _e( 'Link Text' ); ?></span><input id="wp-link-text" type="text" /></label>
   885 			<div class="link-search-wrapper">
  1448 				</div>
   886 				<label>
  1449 				<div class="link-target">
   887 					<span class="search-label"><?php _e( 'Search' ); ?></span>
  1450 					<label><span>&nbsp;</span><input type="checkbox" id="wp-link-target" /> <?php _e( 'Open link in a new window/tab' ); ?></label>
   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>
  1451 				</div>
   897 			</div>
  1452 			</div>
   898 			<div id="most-recent-results" class="query-results">
  1453 			<p class="howto"><a href="#" id="wp-link-search-toggle"><?php _e( 'Or link to existing content' ); ?></a></p>
   899 				<div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div>
  1454 			<div id="search-panel">
   900 				<ul></ul>
  1455 				<div class="link-search-wrapper">
   901 				<div class="river-waiting">
  1456 					<label>
   902 					<span class="spinner"></span>
  1457 						<span class="search-label"><?php _e( 'Search' ); ?></span>
       
  1458 						<input type="search" id="wp-link-search" class="link-search-field" autocomplete="off" />
       
  1459 						<span class="spinner"></span>
       
  1460 					</label>
       
  1461 				</div>
       
  1462 				<div id="search-results" class="query-results" tabindex="0">
       
  1463 					<ul></ul>
       
  1464 					<div class="river-waiting">
       
  1465 						<span class="spinner"></span>
       
  1466 					</div>
       
  1467 				</div>
       
  1468 				<div id="most-recent-results" class="query-results" tabindex="0">
       
  1469 					<div class="query-notice" id="query-notice-message">
       
  1470 						<em class="query-notice-default"><?php _e( 'No search term specified. Showing recent items.' ); ?></em>
       
  1471 						<em class="query-notice-hint screen-reader-text"><?php _e( 'Search or use up and down arrow keys to select an item.' ); ?></em>
       
  1472 					</div>
       
  1473 					<ul></ul>
       
  1474 					<div class="river-waiting">
       
  1475 						<span class="spinner"></span>
       
  1476 					</div>
   903 				</div>
  1477 				</div>
   904 			</div>
  1478 			</div>
   905 		</div>
  1479 		</div>
   906 	</div>
  1480 		<div class="submitbox">
   907 	<div class="submitbox">
  1481 			<div id="wp-link-cancel">
   908 		<div id="wp-link-update">
  1482 				<a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
   909 			<input type="submit" value="<?php esc_attr_e( 'Add Link' ); ?>" class="button-primary" id="wp-link-submit" name="wp-link-submit">
  1483 			</div>
       
  1484 			<div id="wp-link-update">
       
  1485 				<input type="submit" value="<?php esc_attr_e( 'Add Link' ); ?>" class="button button-primary" id="wp-link-submit" name="wp-link-submit">
       
  1486 			</div>
   910 		</div>
  1487 		</div>
   911 		<div id="wp-link-cancel">
  1488 		</form>
   912 			<a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
       
   913 		</div>
  1489 		</div>
   914 	</div>
  1490 		<?php
   915 	</form>
       
   916 	</div>
       
   917 	<?php
       
   918 	}
  1491 	}
   919 }
  1492 }