( function () {
/* global sas */
/* global wa_smart */
sas.cmd.push( function () {
sas.setup( {
networkid: wa_smart.network_id,
domain: 'https://www15.smartadserver.com',
async: true,
} );
} );
sas.cmd.push( function () {
sas.call( 'onecall', {
siteId: wa_smart.site_id,
pageId: wa_smart.page_id,
formats: wa_smart.formats,
content_source_id: wa_smart.blog_id,
target: wa_smart.target,
} );
} );
sas.cmd.push( function () {
sas.events.on( 'noad', function ( data ) {
var el = document.getElementById( data.tagId );
if ( ! el ) {
return;
}
var target = el.closest( '.wordads-ad-wrapper' );
var slotType = el.classList.contains( 'wordads-ad-inline' ) ? 'inline' : 'belowpost';
wordads.insertFallbackAd( target, slotType );
} );
} );
sas.cmd.push( function () {
sas.events.on( 'load', function ( data ) {
var el = document.getElementById( data.tagId );
if ( ! el ) {
return;
}
el.closest( '.wordads-ad-wrapper' ).style.display = 'inherit';
} );
} );
// Process commands.
wa_smart.cmd.forEach( ( cmd ) => {
sas.cmd.push( cmd );
} );
wa_smart.cmd = {
push: function ( cmd ) {
sas.cmd.push( cmd );
},
};
var wordads = wordads || {};
wordads.trackStat = function ( stat ) {
window._stq = window._stq || [];
window._stq.push( [
'extra',
{
x_wordads_smart: stat,
},
] );
};
wordads.createInlineAdSnippet = function ( tagId ) {
var wrapper = document.createElement( 'div' );
var ad = document.createElement( 'div' );
var title = document.createElement( 'div' );
var content = document.createElement( 'div' );
var controls = document.createElement( 'div' );
wrapper.classList.add( 'wordads-ad-wrapper' );
ad.classList.add( 'wordads-ad' );
title.classList.add( 'wordads-ad-title' );
content.classList.add( 'wordads-ad-content' );
content.classList.add( 'wordads-ad-inline' );
controls.classList.add( 'wordads-ad-controls' );
title.innerText = wa_smart.inline.title;
content.id = tagId;
controls.innerHTML = wa_smart.inline.gdpr;
ad.appendChild( title );
ad.appendChild( content );
ad.appendChild( controls );
wrapper.appendChild( ad );
return wrapper;
};
wordads.insertInlineAdBefore = function ( element ) {
var tagId = 'wordads-ad-' + parseInt( Math.random() * 1000000 );
var snippet = wordads.createInlineAdSnippet( tagId );
element.insertAdjacentElement( 'beforebegin', snippet );
sas.cmd.push( function () {
sas.call( 'std', {
siteId: wa_smart.site_id,
pageId: wa_smart.page_id,
formatId: wa_smart.inline.format_id,
tagId: tagId,
content_source_id: wa_smart.blog_id,
target: wa_smart.target,
} );
} );
};
wordads.insertFallbackAd = function ( target, slotType ) {
var sas_fallback = window.sas_fallback || [];
var slot_fallback = sas_fallback.filter( function ( fallback ) {
return fallback.type === slotType;
} );
if ( slot_fallback.length === 0 ) {
target.remove();
return;
}
// Replace the macro to have a div with a unique id.
var slot_fallback_tag = slot_fallback[ 0 ].tag.replaceAll(
'{{unique_id}}',
parseInt( Math.random() * 1000000 )
);
// Unescape the tag markup.
var e = document.createElement( 'div' );
e.innerHTML = slot_fallback_tag;
slot_fallback_tag = e.childNodes[ 0 ].nodeValue;
// Insert the fallback tag into a parent for helping to find the script tags.
var parent = document.createElement( 'div' );
parent.innerHTML = slot_fallback_tag;
// Make our ad visible. Needed by IPONWEB to calculate the width of the container.
target.style.display = 'inherit';
// Inserting into target.
target.innerHTML = parent.innerHTML;
// Process any scripts in the tag.
var scripts = parent.querySelectorAll( 'script' );
scripts.forEach( function ( script ) {
script.parentNode.removeChild( script );
var scriptTag = document.createElement( 'script' );
if ( script.src ) {
scriptTag.src = script.src;
} else if ( script.textContent ) {
scriptTag.textContent = script.textContent;
} else if ( script.innerText ) {
scriptTag.innerText = script.innerText;
}
document.body.appendChild( scriptTag );
} );
};
wordads.getChildrenByTag = function ( el, tag ) {
var children = [];
el.childNodes.forEach( ( child ) => {
if ( child.nodeName === tag.toUpperCase() ) {
children.push( child );
}
} );
return children;
};
wordads.getFloatingElements = function ( el ) {
var floating = [];
// Get child nodes recursive.
var children = el.getElementsByTagName( '*' );
for ( var i = 0; i < children.length; i++ ) {
var child = children[ i ];
var computed = getComputedStyle( child );
var position = computed.getPropertyValue( 'position' );
var float = computed.getPropertyValue( 'float' );
if ( position === 'relative' || position === 'absolute' || float !== 'none' ) {
floating.push( child );
}
}
return floating;
};
wordads.getElementGlobalPosition = function ( el ) {
var rect = el.getBoundingClientRect();
return {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
bottom: rect.top + window.scrollY + rect.height,
right: rect.left + window.scrollX + rect.width,
};
};
wordads.collidesWithElements = function ( target, elements ) {
var targetRect = wordads.getElementGlobalPosition( target );
var collides = false;
elements.forEach( ( el ) => {
var collideRect = wordads.getElementGlobalPosition( el );
if (
! (
targetRect.bottom < collideRect.top ||
targetRect.top > collideRect.bottom ||
targetRect.right < collideRect.left ||
targetRect.left > collideRect.left
)
) {
collides = true;
}
} );
return collides;
};
wordads.initializeInlineAds = function () {
// Check if feature is enabled.
if ( ! wa_smart.inline.enabled ) {
return;
}
// Check for inline ads marker.
var marker = document.getElementById( 'wordads-inline-marker' );
// Stop if no marker is found.
if ( ! marker ) {
wordads.trackStat( 'inline_no_marker' );
return;
}
// Get the post content area element based on marker position.
var post = marker.parentElement;
// Remove marker, we don't need it anymore.
marker.remove();
// Set threshold for maximum slots.
var maxSlots = wa_smart.inline.max_slots;
var maxBlazeSlots = wa_smart.inline.max_blaze_slots;
var slotCount = 0;
// Calculate insertion intervals based on ratio of viewport height.
var viewportHeight = window.innerHeight;
var initialViewportRatio = 1.35;
var initialInsertionInterval = Math.ceil( viewportHeight * initialViewportRatio );
var viewportRatio = 1.35;
var insertionInterval = Math.ceil( viewportHeight * viewportRatio );
// Calculate initial threshold.
var postOffset = post.getBoundingClientRect().top + window.scrollY;
var minThreshold = postOffset + initialInsertionInterval;
// Loop through content to find slots to insert.
var paras = wordads.getChildrenByTag( post, 'p' );
// Get floating elements.
var floating = wordads.getFloatingElements( post );
paras.forEach( ( p ) => {
var offset = p.getBoundingClientRect().top + window.scrollY;
var previous = p.previousElementSibling;
if (
offset > minThreshold &&
slotCount < maxSlots &&
previous.nodeName === 'P' &&
! wordads.collidesWithElements( p, floating )
) {
if ( maxBlazeSlots > slotCount ) {
wordads.insertInlineAdBefore( p );
wordads.trackStat( 'render_inline' );
} else {
// Need to wrap first.
var target = document.createElement( 'div' );
target.className = 'wordads-ad-wrapper';
p.insertAdjacentElement( 'beforebegin', target );
wordads.insertFallbackAd( target, 'inline' );
wordads.trackStat( 'render_inline_fallback' );
}
minThreshold = offset + insertionInterval;
slotCount++;
}
} );
if ( slotCount === 0 ) {
wordads.trackStat( 'inline_no_insert' );
}
};
document.addEventListener( 'DOMContentLoaded', function () {
wordads.initializeInlineAds();
} );
} )();
;
( function() {
var cookieValue = document.cookie.replace( /(?:(?:^|.*;\s*)eucookielaw\s*\=\s*([^;]*).*$)|^.*$/, '$1' );
var overlay = document.querySelector( '#eu-cookie-law' );
var container = document.querySelector( '.widget_eu_cookie_law_widget' );
var initialScrollPosition, scrollFunction;
function remove( el ) {
return el && el.parentElement && el.parentElement.removeChild( el );
}
function triggerDismissEvent() {
try {
const dismissEvent = new Event( 'eucookielaw-dismissed' );
document.dispatchEvent( dismissEvent );
} catch ( err ) { }
}
function removeOverlay() {
remove( overlay );
triggerDismissEvent();
}
function fade( el, type, fn ) {
var duration = 400;
el.style.display = 'block';
el.style.transitionProperty = 'opacity';
el.style.transitionDuration = duration + 'ms';
el.style.opacity = type === 'in' ? 0 : 1;
// Double rAF to ensure styles are applied cross-browser.
requestAnimationFrame( function () {
requestAnimationFrame( function() {
el.style.opacity = type === 'in' ? 1 : 0;
// Wait for animation.
setTimeout( function () {
// Clean up.
el.style.removeProperty( 'opacity' );
el.style.removeProperty( 'transition-property' );
el.style.removeProperty( 'transition-duration' );
if ( type === 'out' ) {
el.style.display = 'none';
}
if ( typeof fn === 'function' ) {
fn();
}
}, duration + 50 );
} );
} );
}
function appendWidget() {
document.body.appendChild( container );
overlay.style.display = 'block';
fade( container, 'in' );
}
if ( typeof wp !== 'undefined' && !! wp.customize ) {
appendWidget();
return;
}
if ( ! overlay || ! container ) {
return;
}
if ( overlay.classList.contains( 'ads-active' ) ) {
var adsCookieValue = document.cookie.replace( /(?:(?:^|.*;\s*)personalized-ads-consent\s*\=\s*([^;]*).*$)|^.*$/, '$1' );
if ( cookieValue !== '' && adsCookieValue !== '' ) {
removeOverlay();
}
} else if ( cookieValue !== '' ) {
removeOverlay();
}
appendWidget();
overlay.querySelector( 'form' ).addEventListener( 'submit', accept );
if ( overlay.classList.contains( 'hide-on-scroll' ) ) {
initialScrollPosition = window.pageYOffset;
scrollFunction = function() {
if ( Math.abs( window.pageYOffset - initialScrollPosition ) > 50 ) {
accept();
}
};
window.addEventListener( 'scroll', scrollFunction );
} else if ( overlay.classList.contains( 'hide-on-time' ) ) {
var timeout = parseInt( overlay.getAttribute( 'data-hide-timeout' ), 10 ) || 0;
setTimeout( accept, timeout * 1000 );
}
var accepted = false;
function accept( event ) {
if ( accepted ) {
return;
}
accepted = true;
if ( event && event.preventDefault ) {
event.preventDefault();
}
if ( overlay.classList.contains( 'hide-on-scroll' ) ) {
window.removeEventListener( 'scroll', scrollFunction );
}
var expireTime = new Date();
var consentExpiration = parseInt( overlay.getAttribute( 'data-consent-expiration' ), 10 ) || 0;
expireTime.setTime( expireTime.getTime() + ( consentExpiration * 24 * 60 * 60 * 1000 ) );
document.cookie = 'eucookielaw=' + expireTime.getTime() + ';path=/;expires=' + expireTime.toGMTString();
if ( overlay.classList.contains( 'ads-active' ) && overlay.classList.contains( 'hide-on-button' ) ) {
document.cookie = 'personalized-ads-consent=' + expireTime.getTime() + ';path=/;expires=' + expireTime.toGMTString();
}
fade( overlay, 'out', function() {
removeOverlay();
remove( container );
} );
}
} )();
;
/* global wpcom_reblog */
var jetpackLikesWidgetBatch = [];
var jetpackLikesMasterReady = false;
// Due to performance problems on pages with a large number of widget iframes that need to be loaded,
// we are limiting the processing at any instant to unloaded widgets that are currently in viewport,
// plus this constant that will allow processing of widgets above and bellow the current fold.
// This aim of it is to improve the UX and hide the transition from unloaded to loaded state from users.
var jetpackLikesLookAhead = 2000; // pixels
// Keeps track of loaded comment likes widget so we can unload them when they are scrolled out of view.
var jetpackCommentLikesLoadedWidgets = [];
var jetpackLikesDocReadyPromise = new Promise( resolve => {
if ( document.readyState !== 'loading' ) {
resolve();
} else {
window.addEventListener( 'DOMContentLoaded', () => resolve() );
}
} );
function JetpackLikesPostMessage( message, target ) {
if ( typeof message === 'string' ) {
try {
message = JSON.parse( message );
} catch ( e ) {
return;
}
}
if ( target && typeof target.postMessage === 'function' ) {
try {
target.postMessage(
JSON.stringify( {
type: 'likesMessage',
data: message,
} ),
'*'
);
} catch ( e ) {
return;
}
}
}
function JetpackLikesBatchHandler() {
const requests = [];
document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' ).forEach( widget => {
if ( jetpackLikesWidgetBatch.indexOf( widget.id ) > -1 ) {
return;
}
if ( ! jetpackIsScrolledIntoView( widget ) ) {
return;
}
jetpackLikesWidgetBatch.push( widget.id );
var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/,
match = regex.exec( widget.id ),
info;
if ( ! match || match.length !== 5 ) {
return;
}
info = {
blog_id: match[ 2 ],
width: widget.width,
};
if ( 'post' === match[ 1 ] ) {
info.post_id = match[ 3 ];
} else if ( 'comment' === match[ 1 ] ) {
info.comment_id = match[ 3 ];
}
info.obj_id = match[ 4 ];
requests.push( info );
} );
if ( requests.length > 0 ) {
JetpackLikesPostMessage(
{ event: 'initialBatch', requests: requests },
window.frames[ 'likes-master' ]
);
}
}
function JetpackLikesMessageListener( event ) {
let message = event && event.data;
if ( typeof message === 'string' ) {
try {
message = JSON.parse( message );
} catch ( err ) {
return;
}
}
const type = message && message.type;
const data = message && message.data;
if ( type !== 'likesMessage' || typeof data.event === 'undefined' ) {
return;
}
// We only allow messages from one origin
const allowedOrigin = 'https://widgets.wp.com';
if ( allowedOrigin !== event.origin ) {
return;
}
switch ( data.event ) {
case 'masterReady':
jetpackLikesDocReadyPromise.then( () => {
jetpackLikesMasterReady = true;
const stylesData = {
event: 'injectStyles',
};
const sdTextColor = document.querySelector( '.sd-text-color' );
const sdLinkColor = document.querySelector( '.sd-link-color' );
const sdTextColorStyles = ( sdTextColor && getComputedStyle( sdTextColor ) ) || {};
const sdLinkColorStyles = ( sdLinkColor && getComputedStyle( sdLinkColor ) ) || {};
if ( document.querySelectorAll( 'iframe.admin-bar-likes-widget' ).length > 0 ) {
JetpackLikesPostMessage( { event: 'adminBarEnabled' }, window.frames[ 'likes-master' ] );
const bgSource = document.querySelector(
'#wpadminbar .quicklinks li#wp-admin-bar-wpl-like > a'
);
const wpAdminBar = document.querySelector( '#wpadminbar' );
stylesData.adminBarStyles = {
background: bgSource && getComputedStyle( bgSource ).background,
isRtl: wpAdminBar && getComputedStyle( wpAdminBar ).direction === 'rtl',
};
}
// enable reblogs if they are enabled for the page
if ( document.body.classList.contains( 'jetpack-reblog-enabled' ) ) {
JetpackLikesPostMessage( { event: 'reblogsEnabled' }, window.frames[ 'likes-master' ] );
}
stylesData.textStyles = {
color: sdTextColorStyles[ 'color' ],
fontFamily: sdTextColorStyles[ 'font-family' ],
fontSize: sdTextColorStyles[ 'font-size' ],
direction: sdTextColorStyles[ 'direction' ],
fontWeight: sdTextColorStyles[ 'font-weight' ],
fontStyle: sdTextColorStyles[ 'font-style' ],
textDecoration: sdTextColorStyles[ 'text-decoration' ],
};
stylesData.linkStyles = {
color: sdLinkColorStyles[ 'color' ],
fontFamily: sdLinkColorStyles[ 'font-family' ],
fontSize: sdLinkColorStyles[ 'font-size' ],
textDecoration: sdLinkColorStyles[ 'text-decoration' ],
fontWeight: sdLinkColorStyles[ 'font-weight' ],
fontStyle: sdLinkColorStyles[ 'font-style' ],
};
JetpackLikesPostMessage( stylesData, window.frames[ 'likes-master' ] );
JetpackLikesBatchHandler();
} );
break;
case 'showLikeWidget': {
const placeholder = document.querySelector( `#${ data.id } .likes-widget-placeholder` );
if ( placeholder ) {
placeholder.style.display = 'none';
}
break;
}
case 'showCommentLikeWidget': {
const placeholder = document.querySelector( `#${ data.id } .likes-widget-placeholder` );
if ( placeholder ) {
placeholder.style.display = 'none';
}
break;
}
case 'killCommentLikes':
// If kill switch for comment likes is enabled remove all widgets wrappers and `Loading...` placeholders.
document
.querySelectorAll( '.jetpack-comment-likes-widget-wrapper' )
.forEach( wrapper => wrapper.remove() );
break;
case 'clickReblogFlair':
if ( wpcom_reblog && typeof wpcom_reblog.toggle_reblog_box_flair === 'function' ) {
wpcom_reblog.toggle_reblog_box_flair( data.obj_id, data.post_id );
}
break;
case 'showOtherGravatars': {
const container = document.querySelector( '#likes-other-gravatars' );
if ( ! container ) {
break;
}
const list = container.querySelector( 'ul' );
container.style.display = 'none';
list.innerHTML = '';
container
.querySelectorAll( '.likes-text span' )
.forEach( item => ( item.textContent = data.total ) );
( data.likers || [] ).forEach( async liker => {
if ( liker.profile_URL.substr( 0, 4 ) !== 'http' ) {
// We only display gravatars with http or https schema
return;
}
try {
const response = await fetch( liker.avatar_URL, { method: 'HEAD' } );
if ( !response.ok ) {
// Image doesn't exist, don't create the element
return;
}
} catch ( error ) {
// Error occurred while checking image existence, don't create the element
return;
}
const element = document.createElement( 'li' );
element.innerHTML = `
`;
list.append( element );
// Add some extra attributes through native methods, to ensure strings are sanitized.
element.classList.add( liker.css_class );
element.querySelector( 'img' ).alt = liker.name;
} );
const el = document.querySelector( `*[name='${ data.parent }']` );
const rect = el.getBoundingClientRect();
const win = el.ownerDocument.defaultView;
const offset = {
top: rect.top + win.pageYOffset,
left: rect.left + win.pageXOffset,
};
container.style.left = offset.left + data.position.left - 10 + 'px';
container.style.top = offset.top + data.position.top - 33 + 'px';
// Container width - padding
const initContainerWidth = data.width - 20;
const rowLength = Math.floor( initContainerWidth / 37 );
// # of rows + (avatar + avatar padding) + text above + container padding
let height = Math.ceil( data.likers.length / rowLength ) * 37 + 17 + 22;
if ( height > 204 ) {
height = 204;
}
// Avatars + padding
const containerWidth = rowLength * 37 + 13;
container.style.height = height + 'px';
container.style.width = containerWidth + 'px';
const listWidth = rowLength * 37;
list.style.width = listWidth + 'px';
container.style.display = 'block';
}
}
}
window.addEventListener( 'message', JetpackLikesMessageListener );
document.addEventListener( 'click', e => {
const container = document.querySelector( '#likes-other-gravatars' );
if ( container && ! container.contains( e.target ) ) {
container.style.display = 'none';
}
} );
function JetpackLikesWidgetQueueHandler() {
var wrapperID;
if ( ! jetpackLikesMasterReady ) {
setTimeout( JetpackLikesWidgetQueueHandler, 500 );
return;
}
// Restore widgets to initial unloaded state when they are scrolled out of view.
jetpackUnloadScrolledOutWidgets();
var unloadedWidgetsInView = jetpackGetUnloadedWidgetsInView();
if ( unloadedWidgetsInView.length > 0 ) {
// Grab any unloaded widgets for a batch request
JetpackLikesBatchHandler();
}
for ( var i = 0, length = unloadedWidgetsInView.length; i <= length - 1; i++ ) {
wrapperID = unloadedWidgetsInView[ i ].id;
if ( ! wrapperID ) {
continue;
}
jetpackLoadLikeWidgetIframe( wrapperID );
}
}
function jetpackLoadLikeWidgetIframe( wrapperID ) {
if ( typeof wrapperID === 'undefined' ) {
return;
}
const wrapper = document.querySelector( '#' + wrapperID );
wrapper.querySelectorAll( 'iframe' ).forEach( iFrame => iFrame.remove() );
const placeholder = wrapper.querySelector( '.likes-widget-placeholder' );
// Post like iframe
if ( placeholder && placeholder.classList.contains( 'post-likes-widget-placeholder' ) ) {
const postLikesFrame = document.createElement( 'iframe' );
postLikesFrame.classList.add( 'post-likes-widget', 'jetpack-likes-widget' );
postLikesFrame.name = wrapper.dataset.name;
postLikesFrame.src = wrapper.dataset.src;
postLikesFrame.height = '55px';
postLikesFrame.width = '100%';
postLikesFrame.frameBorder = '0';
postLikesFrame.scrolling = 'no';
postLikesFrame.title = wrapper.dataset.title;
placeholder.after( postLikesFrame );
}
// Comment like iframe
if ( placeholder.classList.contains( 'comment-likes-widget-placeholder' ) ) {
const commentLikesFrame = document.createElement( 'iframe' );
commentLikesFrame.class = 'comment-likes-widget-frame jetpack-likes-widget-frame';
commentLikesFrame.name = wrapper.dataset.name;
commentLikesFrame.src = wrapper.dataset.src;
commentLikesFrame.height = '18px';
commentLikesFrame.width = '100%';
commentLikesFrame.frameBorder = '0';
commentLikesFrame.scrolling = 'no';
wrapper.querySelector( '.comment-like-feedback' ).after( commentLikesFrame );
jetpackCommentLikesLoadedWidgets.push( commentLikesFrame );
}
wrapper.classList.remove( 'jetpack-likes-widget-unloaded' );
wrapper.classList.add( 'jetpack-likes-widget-loading' );
wrapper.querySelector( 'iframe' ).addEventListener( 'load', e => {
JetpackLikesPostMessage(
{ event: 'loadLikeWidget', name: e.target.name, width: e.target.width },
window.frames[ 'likes-master' ]
);
wrapper.classList.remove( 'jetpack-likes-widget-loading' );
wrapper.classList.add( 'jetpack-likes-widget-loaded' );
} );
}
function jetpackGetUnloadedWidgetsInView() {
const unloadedWidgets = document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' );
return [ ...unloadedWidgets ].filter( item => jetpackIsScrolledIntoView( item ) );
}
function jetpackIsScrolledIntoView( element ) {
const top = element.getBoundingClientRect().top;
const bottom = element.getBoundingClientRect().bottom;
// Allow some slack above and bellow the fold with jetpackLikesLookAhead,
// with the aim of hiding the transition from unloaded to loaded widget from users.
return top + jetpackLikesLookAhead >= 0 && bottom <= window.innerHeight + jetpackLikesLookAhead;
}
function jetpackUnloadScrolledOutWidgets() {
for ( let i = jetpackCommentLikesLoadedWidgets.length - 1; i >= 0; i-- ) {
const currentWidgetIframe = jetpackCommentLikesLoadedWidgets[ i ];
if ( ! jetpackIsScrolledIntoView( currentWidgetIframe ) ) {
const widgetWrapper =
currentWidgetIframe &&
currentWidgetIframe.parentElement &&
currentWidgetIframe.parentElement.parentElement;
// Restore parent class to 'unloaded' so this widget can be picked up by queue manager again if needed.
widgetWrapper.classList.remove( 'jetpack-likes-widget-loaded' );
widgetWrapper.classList.remove( 'jetpack-likes-widget-loading' );
widgetWrapper.classList.add( 'jetpack-likes-widget-unloaded' );
// Bring back the loading placeholder into view.
widgetWrapper
.querySelectorAll( '.comment-likes-widget-placeholder' )
.forEach( item => ( item.style.display = 'block' ) );
// Remove it from the list of loaded widgets.
jetpackCommentLikesLoadedWidgets.splice( i, 1 );
// Remove comment like widget iFrame.
currentWidgetIframe.remove();
}
}
}
var jetpackWidgetsDelayedExec = function ( after, fn ) {
var timer;
return function () {
clearTimeout( timer );
timer = setTimeout( fn, after );
};
};
var jetpackOnScrollStopped = jetpackWidgetsDelayedExec( 250, JetpackLikesWidgetQueueHandler );
// Load initial batch of widgets, prior to any scrolling events.
JetpackLikesWidgetQueueHandler();
// Add event listener to execute queue handler after scroll.
window.addEventListener( 'scroll', jetpackOnScrollStopped, true );
;
/**
* Comment Likes - JavaScript
*
* This handles liking and unliking comments, as well as viewing who has
* liked a particular comment.
*
* @dependency Swipe (dynamically loaded when needed)
*
* @package Comment_Likes
* @subpackage JavaScript
*/
(function () {
function init() {
let extWin;
let extWinCheck;
let commentLikeEvent;
// Only run once.
if (window.comment_likes_loaded) {
return;
}
window.comment_likes_loaded = true;
// Client-side cache of who liked a particular comment to avoid
// having to hit the server multiple times for the same data.
const commentLikeCache = {};
let swipeLibPromise;
// Load the Swipe library, if it's not already loaded.
function swipeLibLoader() {
if (!swipeLibPromise) {
swipeLibPromise = new Promise((resolve, reject) => {
if (window.Swipe) {
resolve(window.Swipe);
} else {
const swipeScript = document.createElement('script');
swipeScript.src = comment_like_text.swipeUrl;
swipeScript.async = true;
document.body.appendChild(swipeScript);
swipeScript.addEventListener('load', () => resolve(window.Swipe));
swipeScript.addEventListener('error', error => reject(error));
}
});
}
return swipeLibPromise;
}
/**
* Parse the comment ID from a comment like link.
*/
function getCommentId(link) {
const commentId =
link && link.getAttribute('href') && link.getAttribute('href').split('like_comment=');
return commentId[1].split('&_wpnonce=')[0];
}
/**
* Handle an ajax action on the comment like link.
*/
function handleLinkAction(link, action, commentId, callback) {
const nonce =
link && link.getAttribute('href') && link.getAttribute('href').split('_wpnonce=')[1];
fetch('/wp-admin/admin-ajax.php', {
method: 'POST',
body: new URLSearchParams({
action: action,
_wpnonce: nonce,
like_comment: commentId,
blog_id: Number(link.dataset.blog),
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
Accept: 'application/json',
'cache-control': 'no-cache',
pragma: 'no-cache',
},
})
.then(response => response.json())
.then(callback);
}
function startPolling() {
// Append cookie polling login iframe to this window to wait for user to finish logging in (or cancel)
const loginIframe = document.createElement('iframe');
loginIframe.id = 'wp-login-polling-iframe';
loginIframe.src = 'https://wordpress.com/public.api/connect/?iframe=true';
document.body.appendChild(loginIframe);
loginIframe.style.display = 'none';
}
function stopPolling() {
const iframe = document.querySelector('#wp-login-polling-iframe');
if (iframe) {
iframe.remove();
}
}
function hide(el) {
if (el && el.style) {
el.style.display = 'none';
}
}
function show(el) {
if (el && el.style) {
el.style.removeProperty('display');
}
}
// Overlay used for displaying comment like info.
class Overlay {
constructor() {
// Overlay element.
this.el = document.createElement('div');
this.el.classList.add('comment-likes-overlay');
document.body.appendChild(this.el);
hide(this.el);
this.el.addEventListener('mouseenter', () => {
// Don't hide the overlay if the user is mousing over it.
overlay.cancelHide();
});
this.el.addEventListener('mouseleave', () => overlay.requestHide());
// Inner contents of overlay.
this.innerEl = null;
// Instance of the Swipe library.
this.swipe = null;
// Timeout used for hiding the overlay.
this.hideTimeout = null;
}
// Initialise the overlay for use, removing any old content.
clear() {
// Unload any previous instance of Swipe (to avoid leaking a global
// event handler). This is done before clearing the contents of the
// overlay because Swipe expects the slides to still be present.
if (this.swipe) {
this.swipe.kill();
this.swipe = null;
}
this.el.innerHTML = '';
this.innerEl = document.createElement('div');
this.innerEl.classList.add('inner');
this.el.appendChild(this.innerEl);
}
/**
* Construct a list (