@@ -46,20 +46,51 @@ class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
4646 * Registers embed.
4747 */
4848 public function register_embed () {
49+ add_filter ( 'embed_oembed_html ' , [ $ this , 'filter_embed_oembed_html ' ], 10 , 2 );
4950 add_shortcode ( 'tweet ' , [ $ this , 'shortcode ' ] ); // Note: This is a Jetpack shortcode.
50- wp_embed_register_handler ( 'amp-twitter ' , self ::URL_PATTERN , [ $ this , 'oembed ' ], -1 );
5151 wp_embed_register_handler ( 'amp-twitter-timeline ' , self ::URL_PATTERN_TIMELINE , [ $ this , 'oembed_timeline ' ], -1 );
5252 }
5353
5454 /**
5555 * Unregisters embed.
5656 */
5757 public function unregister_embed () {
58+ remove_filter ( 'embed_oembed_html ' , [ $ this , 'filter_embed_oembed_html ' ] );
5859 remove_shortcode ( 'tweet ' ); // Note: This is a Jetpack shortcode.
59- wp_embed_unregister_handler ( 'amp-twitter ' , -1 );
6060 wp_embed_unregister_handler ( 'amp-twitter-timeline ' , -1 );
6161 }
6262
63+ /**
64+ * Filter oEmbed HTML for Twitter to prepare it for AMP.
65+ *
66+ * @param string $cache Cache for oEmbed.
67+ * @param string $url Embed URL.
68+ * @return string Embed.
69+ */
70+ public function filter_embed_oembed_html ( $ cache , $ url ) {
71+ $ parsed_url = wp_parse_url ( $ url );
72+ if ( false === strpos ( $ parsed_url ['host ' ], 'twitter.com ' ) ) {
73+ return $ cache ;
74+ }
75+
76+ if ( ! preg_match ( '#^https?://twitter.com/.+/status/(\d+)# ' , $ url , $ matches ) ) {
77+ return $ cache ;
78+ }
79+ $ tweet_id = $ matches [1 ];
80+
81+ $ cache = preg_replace (
82+ '#(<blockquote[^>]+?twitter-tweet[^>]+)(>[^\r]+)<script.*$# ' ,
83+ sprintf (
84+ '<amp-twitter width="%d" height="%d" layout="responsive" data-tweetid="%s">$1 placeholder $2</amp-twitter> ' ,
85+ esc_attr ( $ this ->DEFAULT_WIDTH ),
86+ esc_attr ( $ this ->DEFAULT_HEIGHT ),
87+ esc_attr ( $ tweet_id )
88+ ),
89+ $ cache
90+ );
91+ return $ cache ;
92+ }
93+
6394 /**
6495 * Gets AMP-compliant markup for the Twitter shortcode.
6596 *
@@ -110,12 +141,14 @@ public function shortcode( $attr ) {
110141 /**
111142 * Render oEmbed.
112143 *
144+ * @deprecated Since 1.1 as now the sanitize_raw_embeds() is used exclusively, allowing the original oEmbed response to be rapped by amp-twitter.
113145 * @see \WP_Embed::shortcode()
114146 *
115147 * @param array $matches URL pattern matches.
116148 * @return string Rendered oEmbed.
117149 */
118150 public function oembed ( $ matches ) {
151+ _deprecated_function ( __METHOD__ , '1.1 ' );
119152 $ id = false ;
120153
121154 if ( isset ( $ matches ['tweet ' ] ) && is_numeric ( $ matches ['tweet ' ] ) ) {
@@ -206,12 +239,17 @@ public function sanitize_raw_embeds( $dom ) {
206239 }
207240
208241 /**
209- * Checks whether it's a twitter blockquote or not
242+ * Checks whether it's a twitter blockquote or not.
210243 *
211244 * @param DOMElement $node The DOMNode to adjust and replace.
212245 * @return bool Whether node is for raw embed.
213246 */
214247 private function is_tweet_raw_embed ( $ node ) {
248+ // Skip processing blockquotes that have already been passed through while being wrapped with <amp-twitter>.
249+ if ( $ node ->parentNode && 'amp-twitter ' === $ node ->parentNode ->nodeName ) {
250+ return false ;
251+ }
252+
215253 $ class_attr = $ node ->getAttribute ( 'class ' );
216254
217255 return null !== $ class_attr && false !== strpos ( $ class_attr , 'twitter-tweet ' );
@@ -248,6 +286,11 @@ private function create_amp_twitter_and_replace_node( $dom, $node ) {
248286 $ attributes
249287 );
250288
289+ $ placeholder = $ node ->cloneNode ( true );
290+ $ placeholder ->setAttribute ( 'placeholder ' , '' );
291+
292+ $ new_node ->appendChild ( $ placeholder );
293+
251294 $ this ->sanitize_embed_script ( $ node );
252295
253296 $ node ->parentNode ->replaceChild ( $ new_node , $ node );
0 commit comments