6 * @since 3.3.0 |
6 * @since 3.3.0 |
7 * |
7 * |
8 * Private, not included by default. See wp_editor() in wp-includes/general-template.php. |
8 * Private, not included by default. See wp_editor() in wp-includes/general-template.php. |
9 */ |
9 */ |
10 |
10 |
|
11 #[AllowDynamicProperties] |
11 final class _WP_Editors { |
12 final class _WP_Editors { |
12 public static $mce_locale; |
13 public static $mce_locale; |
13 |
14 |
14 private static $mce_settings = array(); |
15 private static $mce_settings = array(); |
15 private static $qt_settings = array(); |
16 private static $qt_settings = array(); |
103 ); |
104 ); |
104 |
105 |
105 self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() ); |
106 self::$this_tinymce = ( $set['tinymce'] && user_can_richedit() ); |
106 |
107 |
107 if ( self::$this_tinymce ) { |
108 if ( self::$this_tinymce ) { |
108 if ( false !== strpos( $editor_id, '[' ) ) { |
109 if ( str_contains( $editor_id, '[' ) ) { |
109 self::$this_tinymce = false; |
110 self::$this_tinymce = false; |
110 _deprecated_argument( 'wp_editor()', '3.9.0', 'TinyMCE editor IDs cannot have brackets.' ); |
111 _deprecated_argument( 'wp_editor()', '3.9.0', 'TinyMCE editor IDs cannot have brackets.' ); |
111 } |
112 } |
112 } |
113 } |
113 |
114 |
145 |
146 |
146 /** |
147 /** |
147 * Outputs the HTML for a single instance of the editor. |
148 * Outputs the HTML for a single instance of the editor. |
148 * |
149 * |
149 * @since 3.3.0 |
150 * @since 3.3.0 |
|
151 * |
|
152 * @global WP_Screen $current_screen WordPress current screen object. |
150 * |
153 * |
151 * @param string $content Initial content for the editor. |
154 * @param string $content Initial content for the editor. |
152 * @param string $editor_id HTML ID for the textarea and TinyMCE and Quicktags instances. |
155 * @param string $editor_id HTML ID for the textarea and TinyMCE and Quicktags instances. |
153 * Should not contain square brackets. |
156 * Should not contain square brackets. |
154 * @param array $settings See _WP_Editors::parse_settings() for description. |
157 * @param array $settings See _WP_Editors::parse_settings() for description. |
326 } |
329 } |
327 } |
330 } |
328 |
331 |
329 if ( self::$this_quicktags ) { |
332 if ( self::$this_quicktags ) { |
330 |
333 |
331 $qtInit = array( |
334 $qt_init = array( |
332 'id' => $editor_id, |
335 'id' => $editor_id, |
333 'buttons' => '', |
336 'buttons' => '', |
334 ); |
337 ); |
335 |
338 |
336 if ( is_array( $set['quicktags'] ) ) { |
339 if ( is_array( $set['quicktags'] ) ) { |
337 $qtInit = array_merge( $qtInit, $set['quicktags'] ); |
340 $qt_init = array_merge( $qt_init, $set['quicktags'] ); |
338 } |
341 } |
339 |
342 |
340 if ( empty( $qtInit['buttons'] ) ) { |
343 if ( empty( $qt_init['buttons'] ) ) { |
341 $qtInit['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close'; |
344 $qt_init['buttons'] = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close'; |
342 } |
345 } |
343 |
346 |
344 if ( $set['_content_editor_dfw'] ) { |
347 if ( $set['_content_editor_dfw'] ) { |
345 $qtInit['buttons'] .= ',dfw'; |
348 $qt_init['buttons'] .= ',dfw'; |
346 } |
349 } |
347 |
350 |
348 /** |
351 /** |
349 * Filters the Quicktags settings. |
352 * Filters the Quicktags settings. |
350 * |
353 * |
351 * @since 3.3.0 |
354 * @since 3.3.0 |
352 * |
355 * |
353 * @param array $qtInit Quicktags settings. |
356 * @param array $qt_init Quicktags settings. |
354 * @param string $editor_id Unique editor identifier, e.g. 'content'. |
357 * @param string $editor_id Unique editor identifier, e.g. 'content'. |
355 */ |
358 */ |
356 $qtInit = apply_filters( 'quicktags_settings', $qtInit, $editor_id ); |
359 $qt_init = apply_filters( 'quicktags_settings', $qt_init, $editor_id ); |
357 |
360 |
358 self::$qt_settings[ $editor_id ] = $qtInit; |
361 self::$qt_settings[ $editor_id ] = $qt_init; |
359 |
362 |
360 self::$qt_buttons = array_merge( self::$qt_buttons, explode( ',', $qtInit['buttons'] ) ); |
363 self::$qt_buttons = array_merge( self::$qt_buttons, explode( ',', $qt_init['buttons'] ) ); |
361 } |
364 } |
362 |
365 |
363 if ( self::$this_tinymce ) { |
366 if ( self::$this_tinymce ) { |
364 |
367 |
365 if ( empty( self::$first_init ) ) { |
368 if ( empty( self::$first_init ) ) { |
455 */ |
458 */ |
456 $plugins = array_unique( apply_filters( 'tiny_mce_plugins', $plugins, $editor_id ) ); |
459 $plugins = array_unique( apply_filters( 'tiny_mce_plugins', $plugins, $editor_id ) ); |
457 |
460 |
458 $key = array_search( 'spellchecker', $plugins, true ); |
461 $key = array_search( 'spellchecker', $plugins, true ); |
459 if ( false !== $key ) { |
462 if ( false !== $key ) { |
460 // Remove 'spellchecker' from the internal plugins if added with 'tiny_mce_plugins' filter to prevent errors. |
463 /* |
461 // It can be added with 'mce_external_plugins'. |
464 * Remove 'spellchecker' from the internal plugins if added with 'tiny_mce_plugins' filter to prevent errors. |
|
465 * It can be added with 'mce_external_plugins'. |
|
466 */ |
462 unset( $plugins[ $key ] ); |
467 unset( $plugins[ $key ] ); |
463 } |
468 } |
464 |
469 |
465 if ( ! empty( $mce_external_plugins ) ) { |
470 if ( ! empty( $mce_external_plugins ) ) { |
466 |
471 |
506 $strings = ''; |
511 $strings = ''; |
507 |
512 |
508 // Try to load langs/[locale].js and langs/[locale]_dlg.js. |
513 // Try to load langs/[locale].js and langs/[locale]_dlg.js. |
509 if ( ! in_array( $name, $loaded_langs, true ) ) { |
514 if ( ! in_array( $name, $loaded_langs, true ) ) { |
510 $path = str_replace( content_url(), '', $plugurl ); |
515 $path = str_replace( content_url(), '', $plugurl ); |
511 $path = WP_CONTENT_DIR . $path . '/langs/'; |
516 $path = realpath( WP_CONTENT_DIR . $path . '/langs/' ); |
512 |
517 |
513 $path = trailingslashit( realpath( $path ) ); |
518 if ( ! $path ) { |
|
519 continue; |
|
520 } |
|
521 |
|
522 $path = trailingslashit( $path ); |
514 |
523 |
515 if ( @is_file( $path . $mce_locale . '.js' ) ) { |
524 if ( @is_file( $path . $mce_locale . '.js' ) ) { |
516 $strings .= @file_get_contents( $path . $mce_locale . '.js' ) . "\n"; |
525 $strings .= @file_get_contents( $path . $mce_locale . '.js' ) . "\n"; |
517 } |
526 } |
518 |
527 |
568 $editor_styles = get_editor_stylesheets(); |
577 $editor_styles = get_editor_stylesheets(); |
569 |
578 |
570 if ( ! empty( $editor_styles ) ) { |
579 if ( ! empty( $editor_styles ) ) { |
571 // Force urlencoding of commas. |
580 // Force urlencoding of commas. |
572 foreach ( $editor_styles as $key => $url ) { |
581 foreach ( $editor_styles as $key => $url ) { |
573 if ( strpos( $url, ',' ) !== false ) { |
582 if ( str_contains( $url, ',' ) ) { |
574 $editor_styles[ $key ] = str_replace( ',', '%2C', $url ); |
583 $editor_styles[ $key ] = str_replace( ',', '%2C', $url ); |
575 } |
584 } |
576 } |
585 } |
577 |
586 |
578 $mce_css .= ',' . implode( ',', $editor_styles ); |
587 $mce_css .= ',' . implode( ',', $editor_styles ); |
750 if ( ! empty( $set['tinymce']['body_class'] ) ) { |
759 if ( ! empty( $set['tinymce']['body_class'] ) ) { |
751 $body_class .= ' ' . $set['tinymce']['body_class']; |
760 $body_class .= ' ' . $set['tinymce']['body_class']; |
752 unset( $set['tinymce']['body_class'] ); |
761 unset( $set['tinymce']['body_class'] ); |
753 } |
762 } |
754 |
763 |
755 $mceInit = array( |
764 $mce_init = array( |
756 'selector' => "#$editor_id", |
765 'selector' => "#$editor_id", |
757 'wpautop' => (bool) $set['wpautop'], |
766 'wpautop' => (bool) $set['wpautop'], |
758 'indent' => ! $set['wpautop'], |
767 'indent' => ! $set['wpautop'], |
759 'toolbar1' => implode( ',', $mce_buttons ), |
768 'toolbar1' => implode( ',', $mce_buttons ), |
760 'toolbar2' => implode( ',', $mce_buttons_2 ), |
769 'toolbar2' => implode( ',', $mce_buttons_2 ), |
763 'tabfocus_elements' => $set['tabfocus_elements'], |
772 'tabfocus_elements' => $set['tabfocus_elements'], |
764 'body_class' => $body_class, |
773 'body_class' => $body_class, |
765 ); |
774 ); |
766 |
775 |
767 // Merge with the first part of the init array. |
776 // Merge with the first part of the init array. |
768 $mceInit = array_merge( self::$first_init, $mceInit ); |
777 $mce_init = array_merge( self::$first_init, $mce_init ); |
769 |
778 |
770 if ( is_array( $set['tinymce'] ) ) { |
779 if ( is_array( $set['tinymce'] ) ) { |
771 $mceInit = array_merge( $mceInit, $set['tinymce'] ); |
780 $mce_init = array_merge( $mce_init, $set['tinymce'] ); |
772 } |
781 } |
773 |
782 |
774 /* |
783 /* |
775 * For people who really REALLY know what they're doing with TinyMCE |
784 * For people who really REALLY know what they're doing with TinyMCE |
776 * You can modify $mceInit to add, remove, change elements of the config |
785 * You can modify $mceInit to add, remove, change elements of the config |
785 * Filters the teenyMCE config before init. |
794 * Filters the teenyMCE config before init. |
786 * |
795 * |
787 * @since 2.7.0 |
796 * @since 2.7.0 |
788 * @since 3.3.0 The `$editor_id` parameter was added. |
797 * @since 3.3.0 The `$editor_id` parameter was added. |
789 * |
798 * |
790 * @param array $mceInit An array with teenyMCE config. |
799 * @param array $mce_init An array with teenyMCE config. |
791 * @param string $editor_id Unique editor identifier, e.g. 'content'. |
800 * @param string $editor_id Unique editor identifier, e.g. 'content'. |
792 */ |
801 */ |
793 $mceInit = apply_filters( 'teeny_mce_before_init', $mceInit, $editor_id ); |
802 $mce_init = apply_filters( 'teeny_mce_before_init', $mce_init, $editor_id ); |
794 } else { |
803 } else { |
795 |
804 |
796 /** |
805 /** |
797 * Filters the TinyMCE config before init. |
806 * Filters the TinyMCE config before init. |
798 * |
807 * |
799 * @since 2.5.0 |
808 * @since 2.5.0 |
800 * @since 3.3.0 The `$editor_id` parameter was added. |
809 * @since 3.3.0 The `$editor_id` parameter was added. |
801 * |
810 * |
802 * @param array $mceInit An array with TinyMCE config. |
811 * @param array $mce_init An array with TinyMCE config. |
803 * @param string $editor_id Unique editor identifier, e.g. 'content'. Accepts 'classic-block' |
812 * @param string $editor_id Unique editor identifier, e.g. 'content'. Accepts 'classic-block' |
804 * when called from block editor's Classic block. |
813 * when called from block editor's Classic block. |
805 */ |
814 */ |
806 $mceInit = apply_filters( 'tiny_mce_before_init', $mceInit, $editor_id ); |
815 $mce_init = apply_filters( 'tiny_mce_before_init', $mce_init, $editor_id ); |
807 } |
816 } |
808 |
817 |
809 if ( empty( $mceInit['toolbar3'] ) && ! empty( $mceInit['toolbar4'] ) ) { |
818 if ( empty( $mce_init['toolbar3'] ) && ! empty( $mce_init['toolbar4'] ) ) { |
810 $mceInit['toolbar3'] = $mceInit['toolbar4']; |
819 $mce_init['toolbar3'] = $mce_init['toolbar4']; |
811 $mceInit['toolbar4'] = ''; |
820 $mce_init['toolbar4'] = ''; |
812 } |
821 } |
813 |
822 |
814 self::$mce_settings[ $editor_id ] = $mceInit; |
823 self::$mce_settings[ $editor_id ] = $mce_init; |
815 } // End if self::$this_tinymce. |
824 } // End if self::$this_tinymce. |
816 } |
825 } |
817 |
826 |
818 /** |
827 /** |
819 * @since 3.3.0 |
828 * @since 3.3.0 |
1448 * |
1457 * |
1449 * @since 3.9.0 |
1458 * @since 3.9.0 |
1450 * |
1459 * |
1451 * @param string $mce_locale The locale used for the editor. |
1460 * @param string $mce_locale The locale used for the editor. |
1452 * @param bool $json_only Optional. Whether to include the JavaScript calls to tinymce.addI18n() and |
1461 * @param bool $json_only Optional. Whether to include the JavaScript calls to tinymce.addI18n() and |
1453 * tinymce.ScriptLoader.markDone(). |
1462 * tinymce.ScriptLoader.markDone(). Default false. |
1454 * @return string Translation object, JSON encoded. |
1463 * @return string Translation object, JSON encoded. |
1455 */ |
1464 */ |
1456 public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { |
1465 public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { |
1457 if ( ! $mce_locale ) { |
1466 if ( ! $mce_locale ) { |
1458 $mce_locale = self::get_mce_locale(); |
1467 $mce_locale = self::get_mce_locale(); |
1481 if ( $key === $value ) { |
1490 if ( $key === $value ) { |
1482 unset( $mce_translation[ $key ] ); |
1491 unset( $mce_translation[ $key ] ); |
1483 continue; |
1492 continue; |
1484 } |
1493 } |
1485 |
1494 |
1486 if ( false !== strpos( $value, '&' ) ) { |
1495 if ( str_contains( $value, '&' ) ) { |
1487 $mce_translation[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8' ); |
1496 $mce_translation[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8' ); |
1488 } |
1497 } |
1489 } |
1498 } |
1490 |
1499 |
1491 // Set direction. |
1500 // Set direction. |
1505 |
1514 |
1506 /** |
1515 /** |
1507 * Force uncompressed TinyMCE when a custom theme has been defined. |
1516 * Force uncompressed TinyMCE when a custom theme has been defined. |
1508 * |
1517 * |
1509 * The compressed TinyMCE file cannot deal with custom themes, so this makes |
1518 * The compressed TinyMCE file cannot deal with custom themes, so this makes |
1510 * sure that we use the uncompressed TinyMCE file if a theme is defined. |
1519 * sure that WordPress uses the uncompressed TinyMCE file if a theme is defined. |
1511 * Even if we are on a production environment. |
1520 * Even if the website is running on a production environment. |
1512 * |
1521 * |
1513 * @since 5.0.0 |
1522 * @since 5.0.0 |
1514 */ |
1523 */ |
1515 public static function force_uncompressed_tinymce() { |
1524 public static function force_uncompressed_tinymce() { |
1516 $has_custom_theme = false; |
1525 $has_custom_theme = false; |
1564 * @global string $tinymce_version |
1573 * @global string $tinymce_version |
1565 */ |
1574 */ |
1566 public static function editor_js() { |
1575 public static function editor_js() { |
1567 global $tinymce_version; |
1576 global $tinymce_version; |
1568 |
1577 |
1569 $tmce_on = ! empty( self::$mce_settings ); |
1578 $tmce_on = ! empty( self::$mce_settings ); |
1570 $mceInit = ''; |
1579 $mce_init = ''; |
1571 $qtInit = ''; |
1580 $qt_init = ''; |
1572 |
1581 |
1573 if ( $tmce_on ) { |
1582 if ( $tmce_on ) { |
1574 foreach ( self::$mce_settings as $editor_id => $init ) { |
1583 foreach ( self::$mce_settings as $editor_id => $init ) { |
1575 $options = self::_parse_init( $init ); |
1584 $options = self::_parse_init( $init ); |
1576 $mceInit .= "'$editor_id':{$options},"; |
1585 $mce_init .= "'$editor_id':{$options},"; |
1577 } |
1586 } |
1578 $mceInit = '{' . trim( $mceInit, ',' ) . '}'; |
1587 $mce_init = '{' . trim( $mce_init, ',' ) . '}'; |
1579 } else { |
1588 } else { |
1580 $mceInit = '{}'; |
1589 $mce_init = '{}'; |
1581 } |
1590 } |
1582 |
1591 |
1583 if ( ! empty( self::$qt_settings ) ) { |
1592 if ( ! empty( self::$qt_settings ) ) { |
1584 foreach ( self::$qt_settings as $editor_id => $init ) { |
1593 foreach ( self::$qt_settings as $editor_id => $init ) { |
1585 $options = self::_parse_init( $init ); |
1594 $options = self::_parse_init( $init ); |
1586 $qtInit .= "'$editor_id':{$options},"; |
1595 $qt_init .= "'$editor_id':{$options},"; |
1587 } |
1596 } |
1588 $qtInit = '{' . trim( $qtInit, ',' ) . '}'; |
1597 $qt_init = '{' . trim( $qt_init, ',' ) . '}'; |
1589 } else { |
1598 } else { |
1590 $qtInit = '{}'; |
1599 $qt_init = '{}'; |
1591 } |
1600 } |
1592 |
1601 |
1593 $ref = array( |
1602 $ref = array( |
1594 'plugins' => implode( ',', self::$plugins ), |
1603 'plugins' => implode( ',', self::$plugins ), |
1595 'theme' => 'modern', |
1604 'theme' => 'modern', |
1619 if ( self::$drag_drop_upload ) { |
1628 if ( self::$drag_drop_upload ) { |
1620 echo 'dragDropUpload: true,'; |
1629 echo 'dragDropUpload: true,'; |
1621 } |
1630 } |
1622 |
1631 |
1623 ?> |
1632 ?> |
1624 mceInit: <?php echo $mceInit; ?>, |
1633 mceInit: <?php echo $mce_init; ?>, |
1625 qtInit: <?php echo $qtInit; ?>, |
1634 qtInit: <?php echo $qt_init; ?>, |
1626 ref: <?php echo self::_parse_init( $ref ); ?>, |
1635 ref: <?php echo self::_parse_init( $ref ); ?>, |
1627 load_ext: function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');} |
1636 load_ext: function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');} |
1628 }; |
1637 }; |
1629 </script> |
1638 </script> |
1630 <?php |
1639 <?php |
1748 /** |
1757 /** |
1749 * Performs post queries for internal linking. |
1758 * Performs post queries for internal linking. |
1750 * |
1759 * |
1751 * @since 3.1.0 |
1760 * @since 3.1.0 |
1752 * |
1761 * |
1753 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments. |
1762 * @param array $args { |
|
1763 * Optional. Array of link query arguments. |
|
1764 * |
|
1765 * @type int $pagenum Page number. Default 1. |
|
1766 * @type string $s Search keywords. |
|
1767 * } |
1754 * @return array|false $results { |
1768 * @return array|false $results { |
1755 * An array of associative arrays of query results, false if there are none. |
1769 * An array of associative arrays of query results, false if there are none. |
1756 * |
1770 * |
1757 * @type array ...$0 { |
1771 * @type array ...$0 { |
1758 * @type int $ID Post ID. |
1772 * @type int $ID Post ID. |
1796 * @param array $query An array of WP_Query arguments. |
1810 * @param array $query An array of WP_Query arguments. |
1797 */ |
1811 */ |
1798 $query = apply_filters( 'wp_link_query_args', $query ); |
1812 $query = apply_filters( 'wp_link_query_args', $query ); |
1799 |
1813 |
1800 // Do main query. |
1814 // Do main query. |
1801 $get_posts = new WP_Query; |
1815 $get_posts = new WP_Query(); |
1802 $posts = $get_posts->query( $query ); |
1816 $posts = $get_posts->query( $query ); |
1803 |
1817 |
1804 // Build results. |
1818 // Build results. |
1805 $results = array(); |
1819 $results = array(); |
1806 foreach ( $posts as $post ) { |
1820 foreach ( $posts as $post ) { |
1859 self::$link_dialog_printed = true; |
1873 self::$link_dialog_printed = true; |
1860 |
1874 |
1861 // `display: none` is required here, see #WP27605. |
1875 // `display: none` is required here, see #WP27605. |
1862 ?> |
1876 ?> |
1863 <div id="wp-link-backdrop" style="display: none"></div> |
1877 <div id="wp-link-backdrop" style="display: none"></div> |
1864 <div id="wp-link-wrap" class="wp-core-ui" style="display: none" role="dialog" aria-labelledby="link-modal-title"> |
1878 <div id="wp-link-wrap" class="wp-core-ui" style="display: none" role="dialog" aria-modal="true" aria-labelledby="link-modal-title"> |
1865 <form id="wp-link" tabindex="-1"> |
1879 <form id="wp-link" tabindex="-1"> |
1866 <?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?> |
1880 <?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?> |
1867 <h1 id="link-modal-title"><?php _e( 'Insert/edit link' ); ?></h1> |
1881 <h1 id="link-modal-title"><?php _e( 'Insert/edit link' ); ?></h1> |
1868 <button type="button" id="wp-link-close"><span class="screen-reader-text"><?php _e( 'Close' ); ?></span></button> |
1882 <button type="button" id="wp-link-close"><span class="screen-reader-text"> |
|
1883 <?php |
|
1884 /* translators: Hidden accessibility text. */ |
|
1885 _e( 'Close' ); |
|
1886 ?> |
|
1887 </span></button> |
1869 <div id="link-selector"> |
1888 <div id="link-selector"> |
1870 <div id="link-options"> |
1889 <div id="link-options"> |
1871 <p class="howto" id="wplink-enter-url"><?php _e( 'Enter the destination URL' ); ?></p> |
1890 <p class="howto" id="wplink-enter-url"><?php _e( 'Enter the destination URL' ); ?></p> |
1872 <div> |
1891 <div> |
1873 <label><span><?php _e( 'URL' ); ?></span> |
1892 <label><span><?php _e( 'URL' ); ?></span> |
1898 </div> |
1917 </div> |
1899 </div> |
1918 </div> |
1900 <div id="most-recent-results" class="query-results" tabindex="0"> |
1919 <div id="most-recent-results" class="query-results" tabindex="0"> |
1901 <div class="query-notice" id="query-notice-message"> |
1920 <div class="query-notice" id="query-notice-message"> |
1902 <em class="query-notice-default"><?php _e( 'No search term specified. Showing recent items.' ); ?></em> |
1921 <em class="query-notice-default"><?php _e( 'No search term specified. Showing recent items.' ); ?></em> |
1903 <em class="query-notice-hint screen-reader-text"><?php _e( 'Search or use up and down arrow keys to select an item.' ); ?></em> |
1922 <em class="query-notice-hint screen-reader-text"> |
|
1923 <?php |
|
1924 /* translators: Hidden accessibility text. */ |
|
1925 _e( 'Search or use up and down arrow keys to select an item.' ); |
|
1926 ?> |
|
1927 </em> |
1904 </div> |
1928 </div> |
1905 <ul></ul> |
1929 <ul></ul> |
1906 <div class="river-waiting"> |
1930 <div class="river-waiting"> |
1907 <span class="spinner"></span> |
1931 <span class="spinner"></span> |
1908 </div> |
1932 </div> |