~canonical-sysadmins/wordpress/4.7.4

« back to all changes in this revision

Viewing changes to wp-includes/class-wp-editor.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

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