Completed
Push — add/xmlrpc-user-api ( 457a7a...d35894 )
by
unknown
538:26 queued 531:29
created

Jetpack_Comments::get_avatar()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 3
nop 4
dl 0
loc 17
rs 9.3888
c 0
b 0
f 0
1
<?php
2
3
require dirname( __FILE__ ) . '/base.php';
4
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
5
6
/**
7
 * Main Comments class
8
 *
9
 * @package JetpackComments
10
 * @version 1.4
11
 * @since   1.4
12
 */
13
class Jetpack_Comments extends Highlander_Comments_Base {
14
15
	/** Variables *************************************************************/
16
17
	/**
18
	 * Possible comment form sources
19
	 * @var array
20
	 */
21
	public $id_sources = array();
22
23
	/**
24
	 * URL
25
	 * @var string
26
	 */
27
	public $signed_url = '';
28
29
	/**
30
	 * The default comment form color scheme
31
	 * @var string
32
	 * @see ::set_default_color_theme_based_on_theme_settings()
33
	 */
34
	public $default_color_scheme = 'light';
35
36
	/** Methods ***************************************************************/
37
38
	public static function init() {
39
		static $instance = false;
40
41
		if ( ! $instance ) {
42
			$instance = new Jetpack_Comments;
43
		}
44
45
		return $instance;
46
	}
47
48
	/**
49
	 * Main constructor for Comments
50
	 *
51
	 * @since JetpackComments (1.4)
52
	 */
53
	public function __construct() {
54
		parent::__construct();
55
56
		// Comments is loaded
57
58
		/**
59
		 * Fires after the Jetpack_Comments object has been instantiated
60
		 *
61
		 * @module comments
62
		 *
63
		 * @since  1.4.0
64
		 *
65
		 * @param array $jetpack_comments_loaded First element in array of type Jetpack_Comments
66
		 **/
67
		do_action_ref_array( 'jetpack_comments_loaded', array( $this ) );
68
		add_action( 'after_setup_theme', array( $this, 'set_default_color_theme_based_on_theme_settings' ), 100 );
69
	}
70
71
	public function set_default_color_theme_based_on_theme_settings() {
72
		if ( function_exists( 'twentyeleven_get_theme_options' ) ) {
73
			$theme_options      = twentyeleven_get_theme_options();
74
			$theme_color_scheme = isset( $theme_options['color_scheme'] ) ? $theme_options['color_scheme'] : 'transparent';
75
		} else {
76
			$theme_color_scheme = get_theme_mod( 'color_scheme', 'transparent' );
77
		}
78
		// Default for $theme_color_scheme is 'transparent' just so it doesn't match 'light' or 'dark'
79
		// The default for Jetpack's color scheme is still defined above as 'light'
80
81
		if ( false !== stripos( $theme_color_scheme, 'light' ) ) {
82
			$this->default_color_scheme = 'light';
83
		} elseif ( false !== stripos( $theme_color_scheme, 'dark' ) ) {
84
			$this->default_color_scheme = 'dark';
85
		}
86
	}
87
88
	/** Private Methods *******************************************************/
89
90
	/**
91
	 * Set any global variables or class variables
92
	 * @since JetpackComments (1.4)
93
	 */
94
	protected function setup_globals() {
95
		parent::setup_globals();
96
97
		// Sources
98
		$this->id_sources = array(
99
			'guest',
100
			'jetpack',
101
			'wordpress',
102
			'twitter',
103
			'facebook',
104
		);
105
	}
106
107
	/**
108
	 * Setup actions for methods in this class
109
	 * @since JetpackComments (1.4)
110
	 */
111
	protected function setup_actions() {
112
		parent::setup_actions();
113
114
		// Selfishly remove everything from the existing comment form
115
		remove_all_actions( 'comment_form_before' );
116
117
		// Selfishly add only our actions back to the comment form
118
		add_action( 'comment_form_before', array( $this, 'comment_form_before' ) );
119
		add_action( 'comment_form_after', array( $this, 'comment_form_after' ), 1 ); // Set very early since we remove everything outputed before our action.
120
121
		// Before a comment is posted
122
		add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ), 1 );
123
124
		// After a comment is posted
125
		add_action( 'comment_post', array( $this, 'add_comment_meta' ) );
126
	}
127
128
	/**
129
	 * Setup filters for methods in this class
130
	 * @since 1.6.2
131
	 */
132
	protected function setup_filters() {
133
		parent::setup_filters();
134
135
		add_filter( 'comment_post_redirect', array( $this, 'capture_comment_post_redirect_to_reload_parent_frame' ), 100 );
136
		add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 4 );
137
	}
138
139
	/**
140
	 * Get the comment avatar from Gravatar, Twitter, or Facebook
141
	 *
142
	 * @since JetpackComments (1.4)
143
	 *
144
	 * @param string $avatar  Current avatar URL
145
	 * @param string $comment Comment for the avatar
146
	 * @param int    $size    Size of the avatar
147
	 * @param string $default Not used
148
	 *
149
	 * @return string New avatar
150
	 */
151
	public function get_avatar( $avatar, $comment, $size, $default ) {
152
		if ( ! isset( $comment->comment_post_ID ) || ! isset( $comment->comment_ID ) ) {
153
			// it's not a comment - bail
154
			return $avatar;
155
		}
156
157
		// Detect whether it's a Facebook or Twitter avatar
158
		$foreign_avatar          = get_comment_meta( $comment->comment_ID, 'hc_avatar', true );
159
		$foreign_avatar_hostname = parse_url( $foreign_avatar, PHP_URL_HOST );
160
		if ( ! $foreign_avatar_hostname ||
0 ignored issues
show
Bug Best Practice introduced by
The expression $foreign_avatar_hostname of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
161
			! preg_match( '/\.?(graph\.facebook\.com|twimg\.com)$/', $foreign_avatar_hostname ) ) {
162
			return $avatar;
163
		}
164
165
		// Return the FB or Twitter avatar
166
		return preg_replace( '#src=([\'"])[^\'"]+\\1#', 'src=\\1' . esc_url( set_url_scheme( $this->photon_avatar( $foreign_avatar, $size ), 'https' ) ) . '\\1', $avatar );
167
	}
168
169
	/** Output Methods ********************************************************/
170
171
	/**
172
	 * Start capturing the core comment_form() output
173
	 * @since JetpackComments (1.4)
174
	 */
175
	public function comment_form_before() {
176
		/**
177
		 * Filters the setting that determines if Jetpagk comments should be enabled for
178
		 * the current post type.
179
		 *
180
		 * @module comments
181
		 *
182
		 * @since  3.8.1
183
		 *
184
		 * @param boolean $return Should comments be enabled?
185
		 */
186
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
187
			return;
188
		}
189
190
		// Add some JS to the footer
191
		add_action( 'wp_footer', array( $this, 'watch_comment_parent' ), 100 );
192
193
		ob_start();
194
	}
195
196
	/**
197
	 * Noop the default comment form output, get some options, and output our
198
	 * tricked out totally radical comment form.
199
	 *
200
	 * @since JetpackComments (1.4)
201
	 */
202
	public function comment_form_after() {
203
		/** This filter is documented in modules/comments/comments.php */
204
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
205
			return;
206
		}
207
208
		// Throw it all out and drop in our replacement
209
		ob_end_clean();
210
211
		// If users are required to be logged in, and they're not, then we don't need to do anything else
212
		if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
213
			/**
214
			 * Changes the log in to comment prompt.
215
			 *
216
			 * @module comments
217
			 *
218
			 * @since  1.4.0
219
			 *
220
			 * @param string $var Default is "You must log in to post a comment."
221
			 */
222
			echo '<p class="must-log-in">' . sprintf( apply_filters( 'jetpack_must_log_in_to_comment', __( 'You must <a href="%s">log in</a> to post a comment.', 'jetpack' ) ), wp_login_url( get_permalink() . '#respond' ) ) . '</p>';
223
224
			return;
225
		}
226
227
		if ( in_array( 'subscriptions', Jetpack::get_active_modules() ) ) {
228
			$stb_enabled = get_option( 'stb_enabled', 1 );
229
			$stb_enabled = empty( $stb_enabled ) ? 0 : 1;
230
231
			$stc_enabled = get_option( 'stc_enabled', 1 );
232
			$stc_enabled = empty( $stc_enabled ) ? 0 : 1;
233
		} else {
234
			$stb_enabled = 0;
235
			$stc_enabled = 0;
236
		}
237
238
		$params = array(
239
			'blogid'               => Jetpack_Options::get_option( 'id' ),
240
			'postid'               => get_the_ID(),
241
			'comment_registration' => ( get_option( 'comment_registration' ) ? '1' : '0' ), // Need to explicitly send a '1' or a '0' for these
242
			'require_name_email'   => ( get_option( 'require_name_email' ) ? '1' : '0' ),
243
			'stc_enabled'          => $stc_enabled,
244
			'stb_enabled'          => $stb_enabled,
245
			'show_avatars'         => ( get_option( 'show_avatars' ) ? '1' : '0' ),
246
			'avatar_default'       => get_option( 'avatar_default' ),
247
			'greeting'             => get_option( 'highlander_comment_form_prompt', __( 'Leave a Reply', 'jetpack' ) ),
248
			/**
249
			 * Changes the comment form prompt.
250
			 *
251
			 * @module comments
252
			 *
253
			 * @since  2.3.0
254
			 *
255
			 * @param string $var Default is "Leave a Reply to %s."
256
			 */
257
			'greeting_reply'       => apply_filters( 'jetpack_comment_form_prompt_reply', __( 'Leave a Reply to %s', 'jetpack' ) ),
258
			'color_scheme'         => get_option( 'jetpack_comment_form_color_scheme', $this->default_color_scheme ),
259
			'lang'                 => get_locale(),
260
			'jetpack_version'      => JETPACK__VERSION,
261
		);
262
263
		// Extra parameters for logged in user
264
		if ( is_user_logged_in() ) {
265
			$current_user           = wp_get_current_user();
266
			$params['hc_post_as']   = 'jetpack';
267
			$params['hc_userid']    = $current_user->ID;
268
			$params['hc_username']  = $current_user->display_name;
269
			$params['hc_userurl']   = $current_user->user_url;
270
			$params['hc_useremail'] = md5( strtolower( trim( $current_user->user_email ) ) );
271
			if ( current_user_can( 'unfiltered_html' ) ) {
272
				$params['_wp_unfiltered_html_comment'] = wp_create_nonce( 'unfiltered-html-comment_' . get_the_ID() );
273
			}
274
		} else {
275
			$commenter                     = wp_get_current_commenter();
276
			$params['show_cookie_consent'] = (int) has_action( 'set_comment_cookies', 'wp_set_comment_cookies' );
277
			$params['has_cookie_consent']  = (int) ! empty( $commenter['comment_author_email'] );
278
		}
279
280
		$blog_token = Jetpack_Data::get_access_token();
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Data::get_access_token() has been deprecated with message: 7.5 Use Connection_Manager instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
281
		list( $token_key ) = explode( '.', $blog_token->secret, 2 );
282
		// Prophylactic check: anything else should never happen.
283
		if ( $token_key && $token_key !== $blog_token->secret ) {
284
			// Is the token a Special Token (@see class.jetpack-data.php)?
285
			if ( preg_match( '/^;.\d+;\d+;$/', $token_key, $matches ) ) {
286
				// The token key for a Special Token is public.
287
				$params['token_key'] = $token_key;
288
			} else {
289
				/*
290
				 * The token key for a Normal Token is public but
291
				 * looks like sensitive data. Since there can only be
292
				 * one Normal Token per site, avoid concern by
293
				 * sending the magic "use the Normal Token" token key.
294
				 */
295
				$params['token_key'] = Connection_Manager::MAGIC_NORMAL_TOKEN_KEY;
296
			}
297
		}
298
299
		$signature = Jetpack_Comments::sign_remote_comment_parameters( $params, $blog_token->secret );
300
		if ( is_wp_error( $signature ) ) {
301
			$signature = 'error';
302
		}
303
304
		$params['sig']    = $signature;
305
		$url_origin       = set_url_scheme( 'http://jetpack.wordpress.com' );
306
		$url              = "{$url_origin}/jetpack-comment/?" . http_build_query( $params );
307
		$url              = "{$url}#parent=" . urlencode( set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) );
308
		$this->signed_url = $url;
309
		$height           = $params['comment_registration'] || is_user_logged_in() ? '315' : '430'; // Iframe can be shorter if we're not allowing guest commenting
310
		$transparent      = ( $params['color_scheme'] == 'transparent' ) ? 'true' : 'false';
311
312
		if ( isset( $_GET['replytocom'] ) ) {
313
			$url .= '&replytocom=' . (int) $_GET['replytocom'];
314
		}
315
316
		/**
317
		 * Filter whether the comment title can be displayed.
318
		 *
319
		 * @module comments
320
		 *
321
		 * @since  4.7.0
322
		 *
323
		 * @param bool $show Can the comment be displayed? Default to true.
324
		 */
325
		$show_greeting = apply_filters( 'jetpack_comment_form_display_greeting', true );
326
327
		// The actual iframe (loads comment form from Jetpack server)
328
		?>
329
330
		<div id="respond" class="comment-respond">
331
			<?php if ( true === $show_greeting ) : ?>
332
				<h3 id="reply-title" class="comment-reply-title"><?php comment_form_title( esc_html( $params['greeting'] ), esc_html( $params['greeting_reply'] ) ); ?>
333
					<small><?php cancel_comment_reply_link( esc_html__( 'Cancel reply', 'jetpack' ) ); ?></small>
334
				</h3>
335
			<?php endif; ?>
336
			<form id="commentform" class="comment-form">
337
				<iframe title="<?php esc_attr_e( 'Comment Form', 'jetpack' ); ?>" src="<?php echo esc_url( $url ); ?>" style="width:100%; height: <?php echo $height; ?>px; border:0;" name="jetpack_remote_comment" class="jetpack_remote_comment" id="jetpack_remote_comment" sandbox="allow-same-origin allow-top-navigation allow-scripts allow-forms allow-popups"></iframe>
338
				<?php if ( ! Jetpack_AMP_Support::is_amp_request() ) : ?>
339
					<!--[if !IE]><!-->
340
					<script>
341
						document.addEventListener('DOMContentLoaded', function () {
342
							var commentForms = document.getElementsByClassName('jetpack_remote_comment');
343
							for (var i = 0; i < commentForms.length; i++) {
344
								commentForms[i].allowTransparency = <?php echo $transparent; ?>;
345
								commentForms[i].scrolling = 'no';
346
							}
347
						});
348
					</script>
349
					<!--<![endif]-->
350
				<?php endif; ?>
351
			</form>
352
		</div>
353
354
		<?php // Below is required for comment reply JS to work ?>
355
356
		<input type="hidden" name="comment_parent" id="comment_parent" value="" />
357
358
		<?php
359
	}
360
361
	/**
362
	 * Add some JS to wp_footer to watch for hierarchical reply parent change
363
	 *
364
	 * @since JetpackComments (1.4)
365
	 */
366
	public function watch_comment_parent() {
367
		$url_origin = set_url_scheme( 'http://jetpack.wordpress.com' );
368
		?>
369
370
		<!--[if IE]>
371
		<script type="text/javascript">
372
			if ( 0 === window.location.hash.indexOf( '#comment-' ) ) {
373
				// window.location.reload() doesn't respect the Hash in IE
374
				window.location.hash = window.location.hash;
375
			}
376
		</script>
377
		<![endif]-->
378
		<script type="text/javascript">
379
			(function () {
380
				var comm_par_el = document.getElementById( 'comment_parent' ),
381
					comm_par = ( comm_par_el && comm_par_el.value ) ? comm_par_el.value : '',
382
					frame = document.getElementById( 'jetpack_remote_comment' ),
383
					tellFrameNewParent;
384
385
				tellFrameNewParent = function () {
386
					if ( comm_par ) {
387
						frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>" + '&replytocom=' + parseInt( comm_par, 10 ).toString();
388
					} else {
389
						frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>";
390
					}
391
				};
392
393
				<?php if ( get_option( 'thread_comments' ) && get_option( 'thread_comments_depth' ) ) : ?>
394
395
				if ( 'undefined' !== typeof addComment ) {
396
					addComment._Jetpack_moveForm = addComment.moveForm;
397
398
					addComment.moveForm = function ( commId, parentId, respondId, postId ) {
399
						var returnValue = addComment._Jetpack_moveForm( commId, parentId, respondId, postId ),
400
							cancelClick, cancel;
401
402
						if ( false === returnValue ) {
403
							cancel = document.getElementById( 'cancel-comment-reply-link' );
404
							cancelClick = cancel.onclick;
405
							cancel.onclick = function () {
406
								var cancelReturn = cancelClick.call( this );
407
								if ( false !== cancelReturn ) {
408
									return cancelReturn;
409
								}
410
411
								if ( ! comm_par ) {
412
									return cancelReturn;
413
								}
414
415
								comm_par = 0;
416
417
								tellFrameNewParent();
418
419
								return cancelReturn;
420
							};
421
						}
422
423
						if ( comm_par == parentId ) {
424
							return returnValue;
425
						}
426
427
						comm_par = parentId;
428
429
						tellFrameNewParent();
430
431
						return returnValue;
432
					};
433
				}
434
435
				<?php endif; ?>
436
437
				// Do the post message bit after the dom has loaded.
438
				document.addEventListener( 'DOMContentLoaded', function () {
439
					var iframe_url = <?php echo json_encode( esc_url_raw( $url_origin ) ); ?>;
440
					if ( window.postMessage ) {
441
						if ( document.addEventListener ) {
442
							window.addEventListener( 'message', function ( event ) {
443
								var origin = event.origin.replace( /^http:\/\//i, 'https://' );
444
								if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) {
445
									return;
446
								}
447
								jQuery( frame ).height( event.data );
448
							});
449
						} else if ( document.attachEvent ) {
450
							window.attachEvent( 'message', function ( event ) {
451
								var origin = event.origin.replace( /^http:\/\//i, 'https://' );
452
								if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) {
453
									return;
454
								}
455
								jQuery( frame ).height( event.data );
456
							});
457
						}
458
					}
459
				})
460
461
			})();
462
		</script>
463
464
		<?php
465
	}
466
467
	/**
468
	 * Verify the hash included in remote comments.
469
	 *
470
	 * @since JetpackComments (1.4)
471
	 *
472
	 * @param type $comment Not used
473
	 */
474
	public function pre_comment_on_post( $comment ) {
475
		$post_array = stripslashes_deep( $_POST );
476
477
		// Bail if missing the Jetpack token
478
		if ( ! isset( $post_array['sig'] ) || ! isset( $post_array['token_key'] ) ) {
479
			unset( $_POST['hc_post_as'] );
480
481
			return;
482
		}
483
484
		if ( false !== strpos( $post_array['hc_avatar'], '.gravatar.com' ) ) {
485
			$post_array['hc_avatar'] = htmlentities( $post_array['hc_avatar'] );
486
		}
487
488
		$blog_token = Jetpack_Data::get_access_token( false, $post_array['token_key'] );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Data::get_access_token() has been deprecated with message: 7.5 Use Connection_Manager instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
489
		if ( ! $blog_token ) {
490
			wp_die( __( 'Unknown security token.', 'jetpack' ), 400 );
491
		}
492
		$check = Jetpack_Comments::sign_remote_comment_parameters( $post_array, $blog_token->secret );
493
		if ( is_wp_error( $check ) ) {
494
			wp_die( $check );
495
		}
496
497
		// Bail if token is expired or not valid
498
		if ( ! hash_equals( $check, $post_array['sig'] ) ) {
499
			wp_die( __( 'Invalid security token.', 'jetpack' ), 400 );
500
		}
501
502
		/** This filter is documented in modules/comments/comments.php */
503
		if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type( $post_array['comment_post_ID'] ), true ) ) {
504
			// In case the comment POST is legit, but the comments are
505
			// now disabled, we don't allow the comment
506
507
			wp_die( __( 'Comments are not allowed.', 'jetpack' ), 403 );
508
		}
509
	}
510
511
	/** Capabilities **********************************************************/
512
513
	/**
514
	 * Add some additional comment meta after comment is saved about what
515
	 * service the comment is from, the avatar, user_id, etc...
516
	 *
517
	 * @since JetpackComments (1.4)
518
	 *
519
	 * @param type $comment_id
520
	 */
521
	public function add_comment_meta( $comment_id ) {
522
		$comment_meta = array();
523
524
		switch ( $this->is_highlander_comment_post() ) {
525 View Code Duplication
			case 'facebook':
526
				$comment_meta['hc_post_as']         = 'facebook';
527
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
528
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
529
				break;
530
531 View Code Duplication
			case 'twitter':
532
				$comment_meta['hc_post_as']         = 'twitter';
533
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
534
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
535
				break;
536
537
			// phpcs:ignore WordPress.WP.CapitalPDangit
538
			case 'wordpress':
539
				// phpcs:ignore WordPress.WP.CapitalPDangit
540
				$comment_meta['hc_post_as']         = 'wordpress';
541
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
542
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
543
				$comment_meta['hc_wpcom_id_sig']    = stripslashes( $_POST['hc_wpcom_id_sig'] ); //since 1.9
544
				break;
545
546 View Code Duplication
			case 'jetpack':
547
				$comment_meta['hc_post_as']         = 'jetpack';
548
				$comment_meta['hc_avatar']          = stripslashes( $_POST['hc_avatar'] );
549
				$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
550
				break;
551
552
		}
553
554
		// Bail if no extra comment meta
555
		if ( empty( $comment_meta ) ) {
556
			return;
557
		}
558
559
		// Loop through extra meta and add values
560
		foreach ( $comment_meta as $key => $value ) {
561
			add_comment_meta( $comment_id, $key, $value, true );
562
		}
563
	}
564
565
	function capture_comment_post_redirect_to_reload_parent_frame( $url ) {
566
		if ( ! isset( $_GET['for'] ) || 'jetpack' != $_GET['for'] ) {
567
			return $url;
568
		}
569
		?>
570
		<!DOCTYPE html>
571
		<html <?php language_attributes(); ?>>
572
		<!--<![endif]-->
573
		<head>
574
			<meta charset="<?php bloginfo( 'charset' ); ?>" />
575
			<title><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '&hellip;' ); ?></title>
576
			<style type="text/css">
577
				body {
578
					display: table;
579
					width: 100%;
580
					height: 60%;
581
					position: absolute;
582
					top: 0;
583
					left: 0;
584
					overflow: hidden;
585
					color: #333;
586
				}
587
588
				h1 {
589
					text-align: center;
590
					margin: 0;
591
					padding: 0;
592
					display: table-cell;
593
					vertical-align: middle;
594
					font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif;
595
					font-weight: normal;
596
				}
597
598
				.hidden {
599
					opacity: 0;
600
				}
601
602
				h1 span {
603
					-moz-transition-property: opacity;
604
					-moz-transition-duration: 1s;
605
					-moz-transition-timing-function: ease-in-out;
606
607
					-webkit-transition-property: opacity;
608
					-webkit-transition-duration: 1s;
609
					-webbit-transition-timing-function: ease-in-out;
610
611
					-o-transition-property: opacity;
612
					-o-transition-duration: 1s;
613
					-o-transition-timing-function: ease-in-out;
614
615
					-ms-transition-property: opacity;
616
					-ms-transition-duration: 1s;
617
					-ms-transition-timing-function: ease-in-out;
618
619
					transition-property: opacity;
620
					transition-duration: 1s;
621
					transition-timing-function: ease-in-out;
622
				}
623
			</style>
624
		</head>
625
		<body>
626
		<h1><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '<span id="ellipsis" class="hidden">&hellip;</span>' ); ?></h1>
627
		<script type="text/javascript">
628
			try {
629
				window.parent.location = <?php echo json_encode( $url ); ?>;
630
				window.parent.location.reload(true);
631
			} catch (e) {
632
				window.location = <?php echo json_encode( $url ); ?>;
633
				window.location.reload(true);
634
			}
635
			ellipsis = document.getElementById('ellipsis');
636
637
			function toggleEllipsis() {
638
				ellipsis.className = ellipsis.className ? '' : 'hidden';
639
			}
640
641
			setInterval(toggleEllipsis, 1200);
642
		</script>
643
		</body>
644
		</html>
645
		<?php
646
		exit;
647
	}
648
}
649
650
Jetpack_Comments::init();
651