WordPress.org

Make WordPress Core

Ticket #31373: 31373.10.patch

File 31373.10.patch, 31.7 KB (added by stephdau, 5 years ago)

Same as 31373.9.patch, but with WP_Press_This::get_embeds() fixed (needed to use $data['_embed'], not $data['_embeds']).

  • src/wp-admin/includes/class-wp-press-this.php

     
    1414 */
    1515class WP_Press_This {
    1616
     17        private $images = array();
     18
     19        private $embeds = array();
     20
    1721        /**
    1822         * Constructor.
    1923         *
     
    3135         * @return array Site settings.
    3236         */
    3337        public function site_settings() {
    34                 $default_html = array(
    35                         'quote' => '<blockquote>%1$s</blockquote>',
    36                         'link' => '<p>' . _x( 'Source:', 'Used in Press This to indicate where the content comes from.' ) .
    37                                 ' <em><a href="%1$s">%2$s</a></em></p>',
    38                 );
    39 
    4038                return array(
    4139                        // Used to trigger the bookmarklet update notice.
    4240                        // Needs to be set here and in get_shortcut_link() in wp-includes/link-template.php.
    43                         'version' => '6',
     41                        'version' => '7',
    4442
    4543                        /**
    4644                         * Filter whether or not Press This should redirect the user in the parent window upon save.
     
    5048                         * @param bool false Whether to redirect in parent window or not. Default false.
    5149                         */
    5250                        'redirInParent' => apply_filters( 'press_this_redirect_in_parent', false ),
    53 
    54                         /**
    55                          * Filter the default HTML for the Press This editor.
    56                          *
    57                          * @since 4.2.0
    58                          *
    59                          * @param array $default_html Associative array with two keys: 'quote' where %1$s is replaced with the site description
    60                          *                            or the selected content, and 'link' there %1$s is link href, %2$s is link text.
    61                          */
    62                         'html' => apply_filters( 'press_this_suggested_html', $default_html ),
    6351                );
    6452        }
    6553
     
    435423        }
    436424
    437425        private function _process_meta_entry( $meta_name, $meta_value, $data ) {
    438                 if ( preg_match( '/:?(title|description|keywords)$/', $meta_name ) ) {
     426                if ( preg_match( '/:?(title|description|keywords|site_name)$/', $meta_name ) ) {
    439427                        $data['_meta'][ $meta_name ] = $meta_value;
    440428                } else {
    441429                        switch ( $meta_name ) {
     
    572560                        $items = $this->_limit_array( $matches[0] );
    573561
    574562                        foreach ( $items as $value ) {
    575                                 if ( preg_match( '/(rel|itemprop)="([^"]+)"[^>]+href="([^"]+)"/', $value, $new_matches ) ) {
    576                                         if ( 'alternate' === $new_matches[2] || 'thumbnailUrl' === $new_matches[2] || 'url' === $new_matches[2] ) {
    577                                                 $url = $this->_limit_url( $new_matches[3] );
     563                                if ( preg_match( '/rel=["\'](canonical|shortlink|icon)["\']/i', $value, $matches_rel ) && preg_match( '/href=[\'"]([^\'" ]+)[\'"]/i', $value, $matches_url ) ) {
     564                                        $rel = $matches_rel[1];
     565                                        $url = $this->_limit_url( $matches_url[1] );
    578566
    579                                                 if ( ! empty( $url ) && empty( $data['_links'][ $new_matches[2] ] ) ) {
    580                                                         $data['_links'][ $new_matches[2] ] = $url;
    581                                                 }
     567                                        if ( ! empty( $url ) && empty( $data['_links'][ $rel ] ) ) {
     568                                                $data['_links'][ $rel ] = $url;
    582569                                        }
    583570                                }
    584571                        }
     
    600587                $data = array();
    601588
    602589                // Only instantiate the keys we want. Sanity check and sanitize each one.
    603                 foreach ( array( 'u', 's', 't', 'v', '_version' ) as $key ) {
     590                foreach ( array( 'u', 's', 't', 'v' ) as $key ) {
    604591                        if ( ! empty( $_POST[ $key ] ) ) {
    605592                                $value = wp_unslash( $_POST[ $key ] );
    606593                        } else if ( ! empty( $_GET[ $key ] ) ) {
     
    635622                        if ( empty( $_POST ) && ! empty( $data['u'] ) ) {
    636623                                $data = $this->source_data_fetch_fallback( $data['u'], $data );
    637624                        } else {
    638                                 foreach ( array( '_img', '_embed', '_meta' ) as $type ) {
     625                                foreach ( array( '_img', '_embed' ) as $type ) {
    639626                                        if ( empty( $_POST[ $type ] ) ) {
    640627                                                continue;
    641628                                        }
     
    642629
    643630                                        $data[ $type ] = array();
    644631                                        $items = $this->_limit_array( $_POST[ $type ] );
    645                                         $items = wp_unslash( $items );
    646632
    647633                                        foreach ( $items as $key => $value ) {
    648                                                 if ( ! is_numeric( $key ) ) {
    649                                                         $key = $this->_limit_string( wp_unslash( $key ) );
     634                                                if ( $type === '_img' ) {
     635                                                        $value = $this->_limit_img( wp_unslash( $value ) );
     636                                                } else if ( $type === '_embed' ) {
     637                                                        $value = $this->_limit_embed( wp_unslash( $value ) );
     638                                                }
    650639
    651                                                         // Sanity check. $key is usually things like 'title', 'description', 'keywords', etc.
    652                                                         if ( empty( $key ) || strlen( $key ) > 100 ) {
    653                                                                 continue;
    654                                                         }
     640                                                if ( ! empty( $value ) ) {
     641                                                        $data[ $type ][] = $value;
    655642                                                }
     643                                        }
     644                                }
    656645
     646                                foreach ( array( '_meta', '_links' ) as $type ) {
     647                                        if ( empty( $_POST[ $type ] ) ) {
     648                                                continue;
     649                                        }
     650
     651                                        $data[ $type ] = array();
     652                                        $items = $this->_limit_array( $_POST[ $type ] );
     653
     654                                        foreach ( $items as $key => $value ) {
     655                                                // Sanity check. These are associative arrays, $key is usually things like 'title', 'description', 'keywords', etc.
     656                                                if ( empty( $key ) || strlen( $key ) > 100 ) {
     657                                                        continue;
     658                                                }
     659
    657660                                                if ( $type === '_meta' ) {
    658                                                         $value = $this->_limit_string( $value );
     661                                                        $value = $this->_limit_string( wp_unslash( $value ) );
    659662
    660663                                                        if ( ! empty( $value ) ) {
    661664                                                                $data = $this->_process_meta_entry( $key, $value, $data );
    662665                                                        }
    663                                                 } else if ( $type === '_img' ) {
    664                                                         $value = $this->_limit_img( $value );
    665 
    666                                                         if ( ! empty( $value ) ) {
    667                                                                 $data[ $type ][] = $value;
     666                                                } elseif ( $type === '_links' ) {
     667                                                        if ( in_array( $key, array( 'canonical', 'shortlink', 'icon' ) ) ) {
     668                                                                $data[ $type ][ $key ] = $this->_limit_url( wp_unslash( $value ) );
    668669                                                        }
    669                                                 } else if ( $type === '_embed' ) {
    670                                                         $value = $this->_limit_embed( $value );
    671 
    672                                                         if ( ! empty( $value ) ) {
    673                                                                 $data[ $type ][] = $value;
    674                                                         }
    675670                                                }
    676671                                        }
    677672                                }
     
    851846        }
    852847
    853848        /**
     849         * Get a list of embeds with no duplicates.
     850         *
     851         * @param array $data The site's data.
     852         * @returns array
     853         */
     854        public function get_embeds( $data ) {
     855                $selected_embeds = array();
     856
     857                if ( ! empty( $data['_embed'] ) ) {
     858                        foreach( $data['_embed'] as $src ) {
     859                                $prot_relative_src = preg_replace( '/^https?:/', '', $src );
     860
     861                                if ( in_array( $prot_relative_src, $this->embeds ) ) {
     862                                        continue;
     863                                }
     864
     865                                $selected_embeds[] = $src;
     866                                $this->embeds[] = $prot_relative_src;
     867                        }
     868                }
     869
     870                return $selected_embeds;
     871        }
     872
     873        /**
     874         * Get a list of images with no duplicates.
     875         *
     876         * @param array $data The site's data.
     877         * @returns array
     878         */
     879        public function get_images( $data ) {
     880                $selected_images = array();
     881
     882                if ( ! empty( $data['_img'] ) ) {
     883                        foreach( $data['_img'] as $src ) {
     884                                if ( false !== strpos( $src, 'gravatar.com' ) ) {
     885                                        $src = preg_replace( '%http://[\d]+\.gravatar\.com/%', 'https://secure.gravatar.com/', $src );
     886                                }
     887
     888                                $prot_relative_src = preg_replace( '/^https?:/', '', $src );
     889
     890                                if ( in_array( $prot_relative_src, $this->images ) ||
     891                                        ( false !== strpos( $src, 'avatar' ) && count( $this->images ) > 15 ) ) {
     892                                        // Skip: already selected or some type of avatar and we've already gathered more than 15 images.
     893                                        continue;
     894                                }
     895
     896                                $selected_images[] = $src;
     897                                $this->images[] = $prot_relative_src;
     898                        }
     899                }
     900
     901                return $selected_images;
     902        }
     903
     904        /**
     905         * Gets the source page's canonical link, based on passed location and meta data.
     906         *
     907         * @param array $data The site's data.
     908         * @returns string Discovered canonical URL, or empty
     909         */
     910        public function get_canonical_link( $data ) {
     911                $link = '';
     912
     913                if ( ! empty( $data['_links']['canonical'] ) ) {
     914                        $link = $data['_links']['canonical'];
     915                } elseif ( ! empty( $data['u'] ) ) {
     916                        $link = $data['u'];
     917                } elseif ( ! empty( $data['_meta'] ) ) {
     918                        if ( ! empty( $data['_meta']['twitter:url'] ) ) {
     919                                $link = $data['_meta']['twitter:url'];
     920                        } else if ( ! empty( $data['_meta']['og:url'] ) ) {
     921                                $link = $data['_meta']['og:url'];
     922                        }
     923                }
     924
     925                if ( empty( $link ) && ! empty( $data['_links']['shortlink'] ) ) {
     926                        $link = $data['_links']['shortlink'];
     927                }
     928
     929                return $link;
     930        }
     931
     932        /**
     933         * Gets the source page's site name, based on passed meta data.
     934         *
     935         * @param array $data The site's data.
     936         * @returns string Discovered site name, or empty
     937         */
     938        public function get_source_site_name( $data ) {
     939                $name = '';
     940
     941                if ( ! empty( $data['_meta'] ) ) {
     942                        if ( ! empty( $data['_meta']['og:site_name'] ) ) {
     943                                $name = $data['_meta']['og:site_name'];
     944                        } else if ( ! empty( $data['_meta']['application-name'] ) ) {
     945                                $name = $data['_meta']['application-name'];
     946                        }
     947                }
     948
     949                return $name;
     950        }
     951
     952        /**
     953         * Gets the source page's title, based on passed title and meta data.
     954         *
     955         * @param array $data The site's data.
     956         * @returns string Discovered page title, or empty
     957         */
     958        public function get_suggested_title( $data ) {
     959                $title = '';
     960
     961                if ( ! empty( $data['t'] ) ) {
     962                        $title = $data['t'];
     963                } elseif( ! empty( $data['_meta'] ) ) {
     964                        if ( ! empty( $data['_meta']['twitter:title'] ) ) {
     965                                $title = $data['_meta']['twitter:title'];
     966                        } else if ( ! empty( $data['_meta']['og:title'] ) ) {
     967                                $title = $data['_meta']['og:title'];
     968                        } else if ( ! empty( $data['_meta']['title'] ) ) {
     969                                $title = $data['_meta']['title'];
     970                        }
     971                }
     972
     973                return $title;
     974        }
     975
     976        /**
     977         * Gets the source page's suggested content, based on passed data (description, selection, etc).
     978         * Features a blockquoted excerpt, as well as content attribution, if any.
     979         *
     980         * @param array $data The site's data.
     981         * @returns string Discovered content, or empty
     982         */
     983        public function get_suggested_content( $data ) {
     984                $content = $text = '';
     985
     986                if ( ! empty( $data['s'] ) ) {
     987                        $text = $data['s'];
     988                } else if ( ! empty( $data['_meta'] ) ) {
     989                        if ( ! empty( $data['_meta']['twitter:description'] ) ) {
     990                                $text = $data['_meta']['twitter:description'];
     991                        } else if ( ! empty( $data['_meta']['og:description'] ) ) {
     992                                $text = $data['_meta']['og:description'];
     993                        } else if ( ! empty( $data['_meta']['description'] ) ) {
     994                                $text = $data['_meta']['description'];
     995                        }
     996                }
     997
     998                $default_html = array(
     999                        'quote' => '<blockquote>%1$s</blockquote>',
     1000                        'link' => '<p>' . _x( 'Source:', 'Used in Press This to indicate where the content comes from.' ) .
     1001                                ' <em><a href="%1$s">%2$s</a></em></p>',
     1002                );
     1003
     1004                /**
     1005                 * Filter the default HTML for the Press This editor.
     1006                 *
     1007                 * @since 4.2.0
     1008                 *
     1009                 * @param array $default_html Associative array with two keys: 'quote' where %1$s is replaced with the site description
     1010                 *                            or the selected content, and 'link' there %1$s is link href, %2$s is link text.
     1011                 */
     1012                $default_html = apply_filters( 'press_this_suggested_html', $default_html, $data );
     1013
     1014                // Wrap suggested content in the specified HTML.
     1015                if ( ! empty( $default_html['quote'] ) ) {
     1016                        $content = sprintf( $default_html['quote'], $text );
     1017                }
     1018
     1019                // Add source attribution if there is one available.
     1020                if ( ! empty( $default_html['link'] ) ) {
     1021                        $title = $this->get_suggested_title( $data );
     1022                        $url = $this->get_canonical_link( $data );
     1023
     1024                        if ( ! $title ) {
     1025                                $title = $this->get_source_site_name( $data );
     1026                        }
     1027
     1028                        if ( $url && $title ) {
     1029                                $content .= sprintf( $default_html['link'], $url, $title );
     1030                        }
     1031                }
     1032
     1033                return $content;
     1034        }
     1035
     1036        /**
    8541037         * Serves the app's base HTML, which in turns calls the load script.
    8551038         *
    8561039         * @since 4.2.0
     
    8621045                // Get data, new (POST) and old (GET).
    8631046                $data = $this->merge_or_fetch_data();
    8641047
     1048                $post_title = $this->get_suggested_title( $data );
     1049
     1050                if ( empty( $title ) ) {
     1051                        $title = __( 'New Post' );
     1052                }
     1053
     1054                $post_content = $this->get_suggested_content( $data );
     1055
    8651056                // Get site settings array/data.
    8661057                $site_settings = $this->site_settings();
    8671058
    868                 // Set the passed data.
    869                 $data['_version'] = $site_settings['version'];
     1059                // Pass the images and embeds
     1060                $images = $this->get_images( $data );
     1061                $embeds = $this->get_embeds( $data );
    8701062
     1063                $site_data = array(
     1064                        'v' => ! empty( $data['v'] ) ? $data['v'] : '',
     1065                        'hasData' => ! empty( $data ),
     1066                );
     1067
     1068                if ( ! empty( $images ) ) {
     1069                        $site_data['_images'] = $images;
     1070                }
     1071
     1072                if ( ! empty( $embeds ) ) {
     1073                        $site_data['_embeds'] = $embeds;
     1074                }
     1075
    8711076                // Add press-this-editor.css and remove theme's editor-style.css, if any.
    8721077                remove_editor_styles();
    8731078
     
    8901095        <title><?php esc_html_e( 'Press This!' ) ?></title>
    8911096
    8921097        <script>
    893                 window.wpPressThisData   = <?php echo wp_json_encode( $data ) ?>;
    894                 window.wpPressThisConfig = <?php echo wp_json_encode( $site_settings ) ?>;
     1098                window.wpPressThisData   = <?php echo wp_json_encode( $site_data ); ?>;
     1099                window.wpPressThisConfig = <?php echo wp_json_encode( $site_settings ); ?>;
    8951100        </script>
    8961101
    8971102        <script type="text/javascript">
     
    9591164        $admin_body_class .= ' version-' . str_replace( '.', '-', preg_replace( '/^([.0-9]+).*/', '$1', $wp_version ) );
    9601165        $admin_body_class .= ' admin-color-' . sanitize_html_class( get_user_option( 'admin_color' ), 'fresh' );
    9611166        $admin_body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
    962        
     1167
    9631168        /** This filter is documented in wp-admin/admin-header.php */
    9641169        $admin_body_classes = apply_filters( 'admin_body_class', '' );
    9651170
     
    10071212
    10081213                        <div id='app-container' class="editor">
    10091214                                <span id="title-container-label" class="post-title-placeholder" aria-hidden="true"><?php _e( 'Post title' ); ?></span>
    1010                                 <h2 id="title-container" class="post-title" contenteditable="true" spellcheck="true" aria-label="<?php esc_attr_e( 'Post title' ); ?>" tabindex="0"></h2>
     1215                                <h2 id="title-container" class="post-title" contenteditable="true" spellcheck="true" aria-label="<?php esc_attr_e( 'Post title' ); ?>" tabindex="0"><?php echo esc_html( $post_title ); ?></h2>
    10111216                                <div id='featured-media-container' class="featured-container no-media">
    10121217                                        <div id='all-media-widget' class="all-media">
    10131218                                                <div id='all-media-container'></div>
     
    10151220                                </div>
    10161221
    10171222                                <?php
    1018                                 wp_editor( '', 'pressthis', array(
     1223                                wp_editor( $post_content, 'pressthis', array(
    10191224                                        'drag_drop_upload' => true,
    10201225                                        'editor_height'    => 600,
    10211226                                        'media_buttons'    => false,
     
    10391244                        </div>
    10401245                </div>
    10411246
    1042                 <div class="options-panel-back is-hidden" tabindex="-1"></div> 
     1247                <div class="options-panel-back is-hidden" tabindex="-1"></div>
    10431248                <div class="options-panel is-off-screen is-hidden" tabindex="-1">
    10441249                        <div class="post-options">
    10451250
  • src/wp-admin/js/bookmarklet.js

     
    3131                selection = document.selection.createRange().text || '';
    3232        }
    3333
    34         pt_url += ( pt_url.indexOf( '?' ) > -1 ? '&' : '?' ) + 'buster=' + ( new Date().getTime() );
     34        pt_url += '&buster=' + ( new Date().getTime() );
    3535
    3636        if ( ! canPost ) {
    3737                if ( document.title ) {
     
    117117                                case 'icon':
    118118                                case 'shortlink':
    119119                                        add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) );
    120                                         break;
    121                                 case 'alternate':
    122                                         if ( 'application/json+oembed' === g.getAttribute( 'type' ) ) {
    123                                                 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) );
    124                                         } else if ( 'handheld' === g.getAttribute( 'media' ) ) {
    125                                                 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) );
    126                                         }
    127120                        }
    128121                }
    129122        }
  • src/wp-admin/js/bookmarklet.min.js

     
    1 (function(a,b,c,d){function e(a,c){if("undefined"!=typeof c){var d=b.createElement("input");d.name=a,d.value=c,d.type="hidden",o.appendChild(d)}}var f,g,h,i,j,k,l,m,n=a.encodeURIComponent,o=b.createElement("form"),p=b.getElementsByTagName("head")[0],q=new Image,r="_press_this_app",s=!0;if(d){if(!c.match(/^https?:/))return void(top.location.href=d);if(d+="&u="+n(c),c.match(/^https:/)&&d.match(/^http:/)&&(s=!1),a.getSelection?m=a.getSelection()+"":b.getSelection?m=b.getSelection()+"":b.selection&&(m=b.selection.createRange().text||""),d+=(d.indexOf("?")>-1?"&":"?")+"buster="+(new Date).getTime(),s||(b.title&&(d+="&t="+n(b.title.substr(0,256))),m&&(d+="&s="+n(m.substr(0,512)))),f=a.outerWidth||b.documentElement.clientWidth||600,g=a.outerHeight||b.documentElement.clientHeight||700,f=800>f||f>5e3?600:.7*f,g=800>g||g>3e3?700:.9*g,!s)return void a.open(d,r,"location,resizable,scrollbars,width="+f+",height="+g);c.match(/\/\/www\.youtube\.com\/watch/)?e("_embed[]",c):c.match(/\/\/vimeo\.com\/(.+\/)?([\d]+)$/)?e("_embed[]",c):c.match(/\/\/(www\.)?dailymotion\.com\/video\/.+$/)?e("_embed[]",c):c.match(/\/\/soundcloud\.com\/.+$/)?e("_embed[]",c):c.match(/\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/)?e("_embed[]",c):c.match(/\/\/vine\.co\/v\/[^\/]+/)&&e("_embed[]",c),h=p.getElementsByTagName("meta")||[];for(var t=0;t<h.length&&!(t>=50);t++){var u=h[t],v=u.getAttribute("name"),w=u.getAttribute("property"),x=u.getAttribute("content");v?e("_meta["+v+"]",x):w&&e("_meta["+w+"]",x)}i=p.getElementsByTagName("link")||[];for(var y=0;y<i.length&&!(y>=50);y++){var z=i[y],A=z.getAttribute("rel");if(A)switch(A){case"canonical":case"icon":case"shortlink":e("_links["+A+"]",z.getAttribute("href"));break;case"alternate":"application/json+oembed"===z.getAttribute("type")?e("_links["+A+"]",z.getAttribute("href")):"handheld"===z.getAttribute("media")&&e("_links["+A+"]",z.getAttribute("href"))}}b.body.getElementsByClassName&&(j=b.body.getElementsByClassName("hfeed")[0]),j=b.getElementById("content")||j||b.body,k=j.getElementsByTagName("img")||[];for(var B=0;B<k.length&&!(B>=50);B++)k[B].src.indexOf("avatar")>-1||k[B].className.indexOf("avatar")>-1||(q.src=k[B].src,q.width>=256&&q.height>=128&&e("_img[]",q.src));l=b.body.getElementsByTagName("iframe")||[];for(var C=0;C<l.length&&!(C>=50);C++)e("_embed[]",l[C].src);b.title&&e("t",b.title),m&&e("s",m),o.setAttribute("method","POST"),o.setAttribute("action",d),o.setAttribute("target",r),o.setAttribute("style","display: none;"),a.open("about:blank",r,"location,resizable,scrollbars,width="+f+",height="+g),b.body.appendChild(o),o.submit()}})(window,document,top.location.href,window.pt_url);
    2  No newline at end of file
     1(function(a,b,c,d){function e(a,c){if("undefined"!=typeof c){var d=b.createElement("input");d.name=a,d.value=c,d.type="hidden",o.appendChild(d)}}var f,g,h,i,j,k,l,m,n=a.encodeURIComponent,o=b.createElement("form"),p=b.getElementsByTagName("head")[0],q=new Image,r="_press_this_app",s=!0;if(d){if(!c.match(/^https?:/))return void(top.location.href=d);if(d+="&u="+n(c),c.match(/^https:/)&&d.match(/^http:/)&&(s=!1),a.getSelection?m=a.getSelection()+"":b.getSelection?m=b.getSelection()+"":b.selection&&(m=b.selection.createRange().text||""),d+="&buster="+(new Date).getTime(),s||(b.title&&(d+="&t="+n(b.title.substr(0,256))),m&&(d+="&s="+n(m.substr(0,512)))),f=a.outerWidth||b.documentElement.clientWidth||600,g=a.outerHeight||b.documentElement.clientHeight||700,f=800>f||f>5e3?600:.7*f,g=800>g||g>3e3?700:.9*g,!s)return void a.open(d,r,"location,resizable,scrollbars,width="+f+",height="+g);c.match(/\/\/www\.youtube\.com\/watch/)?e("_embed[]",c):c.match(/\/\/vimeo\.com\/(.+\/)?([\d]+)$/)?e("_embed[]",c):c.match(/\/\/(www\.)?dailymotion\.com\/video\/.+$/)?e("_embed[]",c):c.match(/\/\/soundcloud\.com\/.+$/)?e("_embed[]",c):c.match(/\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/)?e("_embed[]",c):c.match(/\/\/vine\.co\/v\/[^\/]+/)&&e("_embed[]",c),h=p.getElementsByTagName("meta")||[];for(var t=0;t<h.length&&!(t>=50);t++){var u=h[t],v=u.getAttribute("name"),w=u.getAttribute("property"),x=u.getAttribute("content");v?e("_meta["+v+"]",x):w&&e("_meta["+w+"]",x)}i=p.getElementsByTagName("link")||[];for(var y=0;y<i.length&&!(y>=50);y++){var z=i[y],A=z.getAttribute("rel");if(A)switch(A){case"canonical":case"icon":case"shortlink":e("_links["+A+"]",z.getAttribute("href"))}}b.body.getElementsByClassName&&(j=b.body.getElementsByClassName("hfeed")[0]),j=b.getElementById("content")||j||b.body,k=j.getElementsByTagName("img")||[];for(var B=0;B<k.length&&!(B>=50);B++)k[B].src.indexOf("avatar")>-1||k[B].className.indexOf("avatar")>-1||(q.src=k[B].src,q.width>=256&&q.height>=128&&e("_img[]",q.src));l=b.body.getElementsByTagName("iframe")||[];for(var C=0;C<l.length&&!(C>=50);C++)e("_embed[]",l[C].src);b.title&&e("t",b.title),m&&e("s",m),o.setAttribute("method","POST"),o.setAttribute("action",d),o.setAttribute("target",r),o.setAttribute("style","display: none;"),a.open("about:blank",r,"location,resizable,scrollbars,width="+f+",height="+g),b.body.appendChild(o),o.submit()}})(window,document,top.location.href,window.pt_url);
     2 No newline at end of file
  • src/wp-admin/js/press-this.js

     
    88                        saveAlert             = false,
    99                        textarea              = document.createElement( 'textarea' ),
    1010                        sidebarIsOpen         = false,
    11                         siteConfig            = window.wpPressThisConfig || {},
     11                        settings              = window.wpPressThisConfig || {},
    1212                        data                  = window.wpPressThisData || {},
    1313                        smallestWidth         = 128,
    14                         interestingImages         = getInterestingImages( data ) || [],
    15                         interestingEmbeds         = getInterestingEmbeds( data ) || [],
    16                         hasEmptyTitleStr      = false,
    17                         suggestedTitleStr     = getSuggestedTitle( data ),
    18                         suggestedContentStr   = getSuggestedContent( data ),
    1914                        hasSetFocus           = false,
    2015                        catsCache             = [],
    2116                        isOffScreen           = 'is-off-screen',
     
    7570                 * @returns string Sanitized text.
    7671                 */
    7772                function sanitizeText( text ) {
    78                         text = stripTags( text );
    79                         textarea.innerHTML = text;
     73                        var _text = stripTags( text );
    8074
    81                         return stripTags( textarea.value );
     75                        try {
     76                                textarea.innerHTML = _text;
     77                                _text = stripTags( textarea.value );
     78                        } catch ( er ) {}
     79
     80                        return _text;
    8281                }
    8382
    8483                /**
     
    9998                }
    10099
    101100                /**
    102                  * Gets the source page's canonical link, based on passed location and meta data.
    103                  *
    104                  * @returns string Discovered canonical URL, or empty
    105                  */
    106                 function getCanonicalLink() {
    107                         var link = '';
    108 
    109                         if ( data._links && data._links.canonical ) {
    110                                 link = data._links.canonical;
    111                         }
    112 
    113                         if ( ! link && data.u ) {
    114                                 link = data.u;
    115                         }
    116 
    117                         if ( ! link && data._meta ) {
    118                                 if ( data._meta['twitter:url'] ) {
    119                                         link = data._meta['twitter:url'];
    120                                 } else if ( data._meta['og:url'] ) {
    121                                         link = data._meta['og:url'];
    122                                 }
    123                         }
    124 
    125                         return checkUrl( decodeURI( link ) );
    126                 }
    127 
    128                 /**
    129                  * Gets the source page's site name, based on passed meta data.
    130                  *
    131                  * @returns string Discovered site name, or empty
    132                  */
    133                 function getSourceSiteName() {
    134                         var name = '';
    135 
    136                         if ( data._meta ) {
    137                                 if ( data._meta['og:site_name'] ) {
    138                                         name = data._meta['og:site_name'];
    139                                 } else if ( data._meta['application-name'] ) {
    140                                         name = data._meta['application-name'];
    141                                 }
    142                         }
    143 
    144                         return sanitizeText( name );
    145                 }
    146 
    147                 /**
    148                  * Gets the source page's title, based on passed title and meta data.
    149                  *
    150                  * @returns string Discovered page title, or empty
    151                  */
    152                 function getSuggestedTitle() {
    153                         var title = '';
    154 
    155                         if ( data.t ) {
    156                                 title = data.t;
    157                         }
    158 
    159                         if ( ! title && data._meta ) {
    160                                 if ( data._meta['twitter:title'] ) {
    161                                         title = data._meta['twitter:title'];
    162                                 } else if ( data._meta['og:title'] ) {
    163                                         title = data._meta['og:title'];
    164                                 } else if ( data._meta.title ) {
    165                                         title = data._meta.title;
    166                                 }
    167                         }
    168 
    169                         if ( ! title ) {
    170                                 title = __( 'newPost' );
    171                                 hasEmptyTitleStr = true;
    172                         }
    173 
    174                         return sanitizeText( title );
    175                 }
    176 
    177                 /**
    178                  * Gets the source page's suggested content, based on passed data (description, selection, etc).
    179                  * Features a blockquoted excerpt, as well as content attribution, if any.
    180                  *
    181                  * @returns string Discovered content, or empty
    182                  */
    183                 function getSuggestedContent() {
    184                         var content  = '',
    185                                 text     = '',
    186                                 title    = getSuggestedTitle(),
    187                                 url      = getCanonicalLink(),
    188                                 siteName = getSourceSiteName();
    189 
    190                         if ( data.s ) {
    191                                 text = data.s;
    192                         } else if ( data._meta ) {
    193                                 if ( data._meta['twitter:description'] ) {
    194                                         text = data._meta['twitter:description'];
    195                                 } else if ( data._meta['og:description'] ) {
    196                                         text = data._meta['og:description'];
    197                                 } else if ( data._meta.description ) {
    198                                         text = data._meta.description;
    199                                 }
    200                         }
    201 
    202                         if ( text && siteConfig.html.quote ) {
    203                                 // Wrap suggested content in specified HTML.
    204                                 content = siteConfig.html.quote.replace( /%1\$s/g, sanitizeText( text ) );
    205                         }
    206 
    207                         // Add a source attribution if there is one available.
    208                         if ( url && siteConfig.html.link && ( ( title && __( 'newPost' ) !== title ) || siteName ) ) {
    209                                 content += siteConfig.html.link.replace( /%1\$s/g, encodeURI( url ) ).replace( /%2\$s/g, ( title || siteName ) );
    210                         }
    211 
    212                         return content || '';
    213                 }
    214 
    215                 /**
    216                  * Get a list of valid embeds from what was passed via WpPressThis_App.data._embed on page load.
    217                  *
    218                  * @returns array
    219                  */
    220                 function getInterestingEmbeds() {
    221                         var embeds             = data._embed || [],
    222                                 interestingEmbeds  = [],
    223                                 alreadySelected    = [];
    224 
    225                         if ( embeds.length ) {
    226                                 $.each( embeds, function ( i, src ) {
    227                                         if ( ! src ) {
    228                                                 // Skip: no src value
    229                                                 return;
    230                                         }
    231 
    232                                         var schemelessSrc = src.replace( /^https?:/, '' );
    233 
    234                                         if ( $.inArray( schemelessSrc, alreadySelected ) > -1 ) {
    235                                                 // Skip: already shown
    236                                                 return;
    237                                         }
    238 
    239                                         interestingEmbeds.push( src );
    240                                         alreadySelected.push( schemelessSrc );
    241                                 } );
    242                         }
    243 
    244                         return interestingEmbeds;
    245                 }
    246 
    247                 /**
    248                  * Get a list of valid images from what was passed via WpPressThis_App.data._img and WpPressThis_App.data._meta on page load.
    249                  *
    250                  * @returns array
    251                  */
    252                 function getInterestingImages( data ) {
    253                         var imgs             = data._img || [],
    254                                 interestingImgs  = [],
    255                                 alreadySelected  = [];
    256 
    257                         if ( imgs.length ) {
    258                                 $.each( imgs, function ( i, src ) {
    259                                         src = src.replace( /http:\/\/[\d]+\.gravatar\.com\//, 'https://secure.gravatar.com/' );
    260                                         src = checkUrl( src );
    261 
    262                                         if ( ! src ) {
    263                                                 // Skip: no src value
    264                                                 return;
    265                                         }
    266 
    267                                         var schemelessSrc = src.replace( /^https?:/, '' );
    268 
    269                                         if ( Array.prototype.indexOf && alreadySelected.indexOf( schemelessSrc ) > -1 ) {
    270                                                 // Skip: already shown
    271                                                 return;
    272                                         } else if ( src.indexOf( 'avatar' ) > -1 && interestingImgs.length >= 15 ) {
    273                                                 // Skip:  some type of avatar and we've already gathered more than 23 diff images to show
    274                                                 return;
    275                                         }
    276 
    277                                         interestingImgs.push( src );
    278                                         alreadySelected.push( schemelessSrc );
    279                                 } );
    280                         }
    281 
    282                         return interestingImgs;
    283                 }
    284 
    285                 /**
    286101                 * Show UX spinner
    287102                 */
    288103                function showSpinner() {
     
    345160                                                renderError( response.data.errorMessage );
    346161                                                hideSpinner();
    347162                                        } else if ( response.data.redirect ) {
    348                                                 if ( window.opener && siteConfig.redirInParent ) {
     163                                                if ( window.opener && settings.redirInParent ) {
    349164                                                        try {
    350165                                                                window.opener.location.href = response.data.redirect;
    351166                                                        } catch( er ) {}
     
    456271                 * Hide the form letting users enter a URL to be scanned, if a URL was already passed.
    457272                 */
    458273                function renderToolsVisibility() {
    459                         if ( data.u && data.u.match( /^https?:/ ) ) {
     274                        if ( data.hasData ) {
    460275                                $( '#scanbar' ).hide();
    461276                        }
    462277                }
     
    495310                        }
    496311
    497312                        // Prompt user to upgrade their bookmarklet if there is a version mismatch.
    498                         if ( data.v && data._version && ( data.v + '' ) !== ( data._version + '' ) ) {
     313                        if ( data.v && settings.version && ( data.v + '' ) !== ( settings.version + '' ) ) {
    499314                                $( '.should-upgrade-bookmarklet' ).removeClass( 'is-hidden' );
    500315                        }
    501316                }
    502317
    503318                /**
    504                  * Render the suggested title, if any
    505                  */
    506                 function renderSuggestedTitle() {
    507                         var suggestedTitle = suggestedTitleStr || '',
    508                                 $title = $( '#title-container' );
    509 
    510                         if ( ! hasEmptyTitleStr ) {
    511                                 $( '#post_title' ).val( suggestedTitle );
    512                                 $title.text( suggestedTitle );
    513                                 $( '.post-title-placeholder' ).addClass( 'is-hidden' );
    514                         }
    515 
    516                         $title.on( 'keyup', function() {
    517                                 saveAlert = true;
    518                         }).on( 'paste', function() {
    519                                 saveAlert = true;
    520 
    521                                 setTimeout( function() {
    522                                         $title.text( $title.text() );
    523                                 }, 100 );
    524                         } );
    525 
    526                 }
    527 
    528                 /**
    529                  * Render the suggested content, if any
    530                  */
    531                 function renderSuggestedContent() {
    532                         if ( ! suggestedContentStr ) {
    533                                 return;
    534                         }
    535 
    536                         if ( ! editor ) {
    537                                 editor = window.tinymce.get( 'pressthis' );
    538                         }
    539 
    540                         if ( editor ) {
    541                                 editor.setContent( suggestedContentStr );
    542                                 editor.on( 'focus', function() {
    543                                         hasSetFocus = true;
    544                                 } );
    545                         }
    546                 }
    547 
    548                 /**
    549319                 * Render the detected images and embed for selection, if any
    550320                 */
    551321                function renderDetectedMedia() {
     
    555325
    556326                        listContainer.empty();
    557327
    558                         if ( interestingEmbeds || interestingImages ) {
    559                                 listContainer.append( '<h2 class="screen-reader-text">' + __( 'allMediaHeading' ) + '</h2><ul class="wppt-all-media-list"/>' );
     328                        if ( data._embeds || data._images ) {
     329                                listContainer.append( '<h2 class="screen-reader-text">' + __( 'allMediaHeading' ) + '</h2><ul class="wppt-all-media-list" />' );
    560330                        }
    561331
    562                         if ( interestingEmbeds ) {
    563                                 $.each( interestingEmbeds, function ( i, src ) {
     332                        if ( data._embeds ) {
     333                                $.each( data._embeds, function ( i, src ) {
    564334                                        src = checkUrl( src );
    565335
    566336                                        var displaySrc = '',
     
    601371                                } );
    602372                        }
    603373
    604                         if ( interestingImages ) {
    605                                 $.each( interestingImages, function ( i, src ) {
     374                        if ( data._images ) {
     375                                $.each( data._images, function( i, src ) {
    606376                                        src = checkUrl( src );
    607377
    608378                                        var displaySrc = src.replace(/^(http[^\?]+)(\?.*)?$/, '$1');
     
    716486                                        // Reset to options list
    717487                                        $( '.post-options' ).removeClass( offscreenHidden );
    718488                                        $( '.setting-modal').addClass( offscreenHidden );
    719                                 } );
     489                                });
    720490                }
    721491
    722492                /**
     
    723493                 * Interactive behavior for the post title's field placeholder
    724494                 */
    725495                function monitorPlaceholder() {
    726                         var $selector = $( '#title-container'),
     496                        var $titleField = $( '#title-container'),
    727497                                $placeholder = $('.post-title-placeholder');
    728498
    729                         $selector.on( 'focus', function() {
     499                        $titleField.on( 'focus', function() {
    730500                                $placeholder.addClass('is-hidden');
    731                         } );
    732 
    733                         $selector.on( 'blur', function() {
    734                                 if ( ! $( this ).text() ) {
     501                        }).on( 'blur', function() {
     502                                if ( ! $titleField.text() ) {
    735503                                        $placeholder.removeClass('is-hidden');
    736504                                }
    737                         } );
     505                        });
     506
     507                        if ( $titleField.text() ) {
     508                                $placeholder.addClass('is-hidden');
     509                        }
    738510                }
    739511
    740512                /* ***************************************************************
     
    747519                function render(){
    748520                        // We're on!
    749521                        renderToolsVisibility();
    750                         renderSuggestedTitle();
    751522                        renderDetectedMedia();
    752                         $( document ).on( 'tinymce-editor-init', renderSuggestedContent );
    753523                        renderStartupNotices();
    754524
    755525                        if ( window.tagBox ) {
     
    761531                 * Set app events and other state monitoring related code.
    762532                 */
    763533                function monitor(){
     534                        $( document ).on( 'tinymce-editor-init', function( event, ed ) {
     535                                editor = ed;
     536
     537                                ed.on( 'focus', function() {
     538                                        hasSetFocus = true;
     539                                } );
     540                        });
     541
    764542                        $( '#current-site a').click( function( e ) {
    765543                                e.preventDefault();
    766544                        } );
    767545
    768                         // Publish and Draft buttons and submit
     546                        // Publish, Draft and Preview buttons
    769547
    770 
    771548                        $( '.post-actions' ).on( 'click.press-this', function( event ) {
    772549                                var $target = $( event.target );
    773550
     
    876653                        refreshCatsCache();
    877654                });
    878655
    879                 // Expose public methods
    880                 // TODO: which are needed?
     656                // Expose public methods?
    881657                return {
    882658                        renderNotice: renderNotice,
    883659                        renderError: renderError
  • src/wp-includes/link-template.php

     
    26002600function get_shortcut_link() {
    26012601        global $is_IE, $wp_version;
    26022602
    2603         $bookmarklet_version = '6';
     2603        $bookmarklet_version = '7';
    26042604        $link = '';
    26052605
    26062606        if ( $is_IE ) {