/* Detect-zoom * ----------- * Cross Browser Zoom and Pixel Ratio Detector * Version 1.0.4 | Apr 1 2013 * dual-licensed under the WTFPL and MIT license * Maintained by https://github/tombigel * Original developer https://github.com/yonran */ //AMD and CommonJS initialization copied from https://github.com/zohararad/audio5js (function (root, ns, factory) { "use strict"; if (typeof (module) !== 'undefined' && module.exports) { // CommonJS module.exports = factory(ns, root); } else if (typeof (define) === 'function' && define.amd) { // AMD define("factory", function () { return factory(ns, root); }); } else { root[ns] = factory(ns, root); } }(window, 'detectZoom', function () { /** * Use devicePixelRatio if supported by the browser * @return {Number} * @private */ var devicePixelRatio = function () { return window.devicePixelRatio || 1; }; /** * Fallback function to set default values * @return {Object} * @private */ var fallback = function () { return { zoom: 1, devicePxPerCssPx: 1 }; }; /** * IE 8 and 9: no trick needed! * TODO: Test on IE10 and Windows 8 RT * @return {Object} * @private **/ var ie8 = function () { var zoom = Math.round((screen.deviceXDPI / screen.logicalXDPI) * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * For IE10 we need to change our technique again... * thanks https://github.com/stefanvanburen * @return {Object} * @private */ var ie10 = function () { var zoom = Math.round((document.documentElement.offsetHeight / window.innerHeight) * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Mobile WebKit * the trick: window.innerWIdth is in CSS pixels, while * screen.width and screen.height are in system pixels. * And there are no scrollbars to mess up the measurement. * @return {Object} * @private */ var webkitMobile = function () { var deviceWidth = (Math.abs(window.orientation) == 90) ? screen.height : screen.width; var zoom = deviceWidth / window.innerWidth; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Desktop Webkit * the trick: an element's clientHeight is in CSS pixels, while you can * set its line-height in system pixels using font-size and * -webkit-text-size-adjust:none. * device-pixel-ratio: http://www.webkit.org/blog/55/high-dpi-web-sites/ * * Previous trick (used before http://trac.webkit.org/changeset/100847): * documentElement.scrollWidth is in CSS pixels, while * document.width was in system pixels. Note that this is the * layout width of the document, which is slightly different from viewport * because document width does not include scrollbars and might be wider * due to big elements. * @return {Object} * @private */ var webkit = function () { var important = function (str) { return str.replace(/;/g, " !important;"); }; var div = document.createElement('div'); div.innerHTML = "1
2
3
4
5
6
7
8
9
0"; div.setAttribute('style', important('font: 100px/1em sans-serif; -webkit-text-size-adjust: none; text-size-adjust: none; height: auto; width: 1em; padding: 0; overflow: visible;')); // The container exists so that the div will be laid out in its own flow // while not impacting the layout, viewport size, or display of the // webpage as a whole. // Add !important and relevant CSS rule resets // so that other rules cannot affect the results. var container = document.createElement('div'); container.setAttribute('style', important('width:0; height:0; overflow:hidden; visibility:hidden; position: absolute;')); container.appendChild(div); document.body.appendChild(container); var zoom = 1000 / div.clientHeight; zoom = Math.round(zoom * 100) / 100; document.body.removeChild(container); return{ zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * no real trick; device-pixel-ratio is the ratio of device dpi / css dpi. * (Note that this is a different interpretation than Webkit's device * pixel ratio, which is the ratio device dpi / system dpi). * * Also, for Mozilla, there is no difference between the zoom factor and the device ratio. * * @return {Object} * @private */ var firefox4 = function () { var zoom = mediaQueryBinarySearch('min--moz-device-pixel-ratio', '', 0, 10, 20, 0.0001); zoom = Math.round(zoom * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom }; }; /** * Firefox 18.x * Mozilla added support for devicePixelRatio to Firefox 18, * but it is affected by the zoom level, so, like in older * Firefox we can't tell if we are in zoom mode or in a device * with a different pixel ratio * @return {Object} * @private */ var firefox18 = function () { return { zoom: firefox4().zoom, devicePxPerCssPx: devicePixelRatio() }; }; /** * works starting Opera 11.11 * the trick: outerWidth is the viewport width including scrollbars in * system px, while innerWidth is the viewport width including scrollbars * in CSS px * @return {Object} * @private */ var opera11 = function () { var zoom = window.top.outerWidth / window.top.innerWidth; zoom = Math.round(zoom * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Use a binary search through media queries to find zoom level in Firefox * @param property * @param unit * @param a * @param b * @param maxIter * @param epsilon * @return {Number} */ var mediaQueryBinarySearch = function (property, unit, a, b, maxIter, epsilon) { var matchMedia; var head, style, div; if (window.matchMedia) { matchMedia = window.matchMedia; } else { head = document.getElementsByTagName('head')[0]; style = document.createElement('style'); head.appendChild(style); div = document.createElement('div'); div.className = 'mediaQueryBinarySearch'; div.style.display = 'none'; document.body.appendChild(div); matchMedia = function (query) { style.sheet.insertRule('@media ' + query + '{.mediaQueryBinarySearch ' + '{text-decoration: underline} }', 0); var matched = getComputedStyle(div, null).textDecoration == 'underline'; style.sheet.deleteRule(0); return {matches: matched}; }; } var ratio = binarySearch(a, b, maxIter); if (div) { head.removeChild(style); document.body.removeChild(div); } return ratio; function binarySearch(a, b, maxIter) { var mid = (a + b) / 2; if (maxIter <= 0 || b - a < epsilon) { return mid; } var query = "(" + property + ":" + mid + unit + ")"; if (matchMedia(query).matches) { return binarySearch(mid, b, maxIter - 1); } else { return binarySearch(a, mid, maxIter - 1); } } }; /** * Generate detection function * @private */ var detectFunction = (function () { var func = fallback; //IE8+ if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { func = ie8; } // IE10+ / Touch else if (window.navigator.msMaxTouchPoints) { func = ie10; } //Mobile Webkit else if ('orientation' in window && typeof document.body.style.webkitMarquee === 'string') { func = webkitMobile; } //WebKit else if (typeof document.body.style.webkitMarquee === 'string') { func = webkit; } //Opera else if (navigator.userAgent.indexOf('Opera') >= 0) { func = opera11; } //Last one is Firefox //FF 18.x else if (window.devicePixelRatio) { func = firefox18; } //FF 4.0 - 17.x else if (firefox4().zoom > 0.001) { func = firefox4; } return func; }()); return ({ /** * Ratios.zoom shorthand * @return {Number} Zoom level */ zoom: function () { return detectFunction().zoom; }, /** * Ratios.devicePxPerCssPx shorthand * @return {Number} devicePxPerCssPx level */ device: function () { return detectFunction().devicePxPerCssPx; } }); })); var wpcom_img_zoomer = { zoomed: false, timer: null, interval: 1000, // zoom polling interval in millisecond // Should we apply width/height attributes to control the image size? imgNeedsSizeAtts: function( img ) { // Do not overwrite existing width/height attributes. if ( img.getAttribute('width') !== null || img.getAttribute('height') !== null ) return false; // Do not apply the attributes if the image is already constrained by a parent element. if ( img.width < img.naturalWidth || img.height < img.naturalHeight ) return false; return true; }, init: function() { var t = this; try{ t.zoomImages(); t.timer = setInterval( function() { t.zoomImages(); }, t.interval ); } catch(e){ } }, stop: function() { if ( this.timer ) clearInterval( this.timer ); }, getScale: function() { var scale = detectZoom.device(); // Round up to 1.5 or the next integer below the cap. if ( scale <= 1.0 ) scale = 1.0; else if ( scale <= 1.5 ) scale = 1.5; else if ( scale <= 2.0 ) scale = 2.0; else if ( scale <= 3.0 ) scale = 3.0; else if ( scale <= 4.0 ) scale = 4.0; else scale = 5.0; return scale; }, shouldZoom: function( scale ) { var t = this; // Do not operate on hidden frames. if ( "innerWidth" in window && !window.innerWidth ) return false; // Don't do anything until scale > 1 if ( scale == 1.0 && t.zoomed == false ) return false; return true; }, zoomImages: function() { var t = this; var scale = t.getScale(); if ( ! t.shouldZoom( scale ) ){ return; } t.zoomed = true; // Loop through all the elements on the page. var imgs = document.getElementsByTagName("img"); for ( var i = 0; i < imgs.length; i++ ) { // Wait for original images to load if ( "complete" in imgs[i] && ! imgs[i].complete ) continue; // For browsers that support srcset and sizes attributes, // skip images that have them. if ( imgs[i].hasAttribute('srcset') && imgs[i].hasAttribute('sizes') && ( 'sizes' in imgs[i] ) ) { continue; } // Skip images that don't need processing. var imgScale = imgs[i].getAttribute("scale"); if ( imgScale == scale || imgScale == "0" ) continue; // Skip images that have already failed at this scale var scaleFail = imgs[i].getAttribute("scale-fail"); if ( scaleFail && scaleFail <= scale ) continue; // Skip images that have no dimensions yet. if ( ! ( imgs[i].width && imgs[i].height ) ) continue; // Skip images from Lazy Load plugins if ( ! imgScale && imgs[i].getAttribute("data-lazy-src") && (imgs[i].getAttribute("data-lazy-src") !== imgs[i].getAttribute("src"))) continue; if ( t.scaleImage( imgs[i], scale ) ) { // Mark the img as having been processed at this scale. imgs[i].setAttribute("scale", scale); } else { // Set the flag to skip this image. imgs[i].setAttribute("scale", "0"); } } }, scaleImage: function( img, scale ) { var t = this; var newSrc = img.src; // Skip slideshow images if ( img.parentNode.className.match(/slideshow-slide/) ) return false; // Scale gravatars that have ?s= or ?size= if ( img.src.match( /^https?:\/\/([^\/]*\.)?gravatar\.com\/.+[?&](s|size)=/ ) ) { newSrc = img.src.replace( /([?&](s|size)=)(\d+)/, function( $0, $1, $2, $3 ) { // Stash the original size var originalAtt = "originals", originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $3; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width/height of the image in CSS pixels var size = img.clientWidth; // Convert CSS pixels to device pixels var targetSize = Math.ceil(img.clientWidth * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go larger than the service supports targetSize = Math.min( targetSize, 512 ); return $1 + targetSize; }); } // Scale resize queries (*.files.wordpress.com) that have ?w= or ?h= else if ( img.src.match( /^https?:\/\/([^\/]+)\.files\.wordpress\.com\/.+[?&][wh]=/ ) ) { if ( img.src.match( /[?&]crop/ ) ) return false; var changedAttrs = {}; var matches = img.src.match( /([?&]([wh])=)(\d+)/g ); for ( var i = 0; i < matches.length; i++ ) { var lr = matches[i].split( '=' ); var thisAttr = lr[0].replace(/[?&]/g, '' ); var thisVal = lr[1]; // Stash the original size var originalAtt = 'original' + thisAttr, originalSize = img.getAttribute( originalAtt ); if ( originalSize === null ) { originalSize = thisVal; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width/height of the image in CSS pixels var size = thisAttr == 'w' ? img.clientWidth : img.clientHeight; var naturalSize = ( thisAttr == 'w' ? img.naturalWidth : img.naturalHeight ); // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= naturalSize ) targetSize = thisVal; // Don't try to go bigger if the image is already smaller than was requested if ( naturalSize < thisVal ) targetSize = thisVal; if ( targetSize != thisVal ) changedAttrs[ thisAttr ] = targetSize; } var w = changedAttrs.w || false; var h = changedAttrs.h || false; if ( w ) { newSrc = img.src.replace(/([?&])w=\d+/g, function( $0, $1 ) { return $1 + 'w=' + w; }); } if ( h ) { newSrc = newSrc.replace(/([?&])h=\d+/g, function( $0, $1 ) { return $1 + 'h=' + h; }); } } // Scale mshots that have width else if ( img.src.match(/^https?:\/\/([^\/]+\.)*(wordpress|wp)\.com\/mshots\/.+[?&]w=\d+/) ) { newSrc = img.src.replace( /([?&]w=)(\d+)/, function($0, $1, $2) { // Stash the original size var originalAtt = 'originalw', originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $2; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width of the image in CSS pixels var size = img.clientWidth; // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= img.naturalWidth ) targetSize = $2; if ( $2 != targetSize ) return $1 + targetSize; return $0; }); // Update height attribute to match width newSrc = newSrc.replace( /([?&]h=)(\d+)/, function($0, $1, $2) { if ( newSrc == img.src ) { return $0; } // Stash the original size var originalAtt = 'originalh', originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $2; img.setAttribute(originalAtt, originalSize); } // Get the height of the image in CSS pixels var size = img.clientHeight; // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= img.naturalHeight ) targetSize = $2; if ( $2 != targetSize ) return $1 + targetSize; return $0; }); } // Scale simple imgpress queries (s0.wp.com) that only specify w/h/fit else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/imgpress\?(.+)/) ) { var imgpressSafeFunctions = ["zoom", "url", "h", "w", "fit", "filter", "brightness", "contrast", "colorize", "smooth", "unsharpmask"]; // Search the query string for unsupported functions. var qs = RegExp.$3.split('&'); for ( var q in qs ) { q = qs[q].split('=')[0]; if ( imgpressSafeFunctions.indexOf(q) == -1 ) { return false; } } // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; // Compute new src if ( scale == 1 ) newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?'); else newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?zoom=' + scale + '&'); } // Scale LaTeX images or Photon queries (i#.wp.com) else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/latex\.php\?(latex|zoom)=(.+)/) || img.src.match(/^https?:\/\/i[\d]{1}\.wp\.com\/(.+)/) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; // Compute new src if ( scale == 1 ) { newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?'); } else { newSrc = img.src; var url_var = newSrc.match( /\?w=(\d+)/ ); if ( url_var !== null && url_var[1] ) { newSrc = newSrc.replace( new RegExp( 'w=' + url_var[1] ), 'w=' + img.width ); } url_var = newSrc.match( /\?h=(\d+)/ ); if ( url_var !== null && url_var[1] ) { newSrc = newSrc.replace( new RegExp( 'h=' + url_var[1] ), 'h=' + img.height ); } var zoom_arg = '&zoom=2'; if ( !newSrc.match( /\?/ ) ) { zoom_arg = '?zoom=2'; } img.setAttribute( 'srcset', newSrc + zoom_arg + ' ' + scale + 'x' ); } } // Scale static assets that have a name matching *-1x.png or *@1x.png else if ( img.src.match(/^https?:\/\/[^\/]+\/.*[-@]([12])x\.(gif|jpeg|jpg|png)(\?|$)/) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; var currentSize = RegExp.$1, newSize = currentSize; if ( scale <= 1 ) newSize = 1; else newSize = 2; if ( currentSize != newSize ) newSrc = img.src.replace(/([-@])[12]x\.(gif|jpeg|jpg|png)(\?|$)/, '$1'+newSize+'x.$2$3'); } else { return false; } // Don't set img.src unless it has changed. This avoids unnecessary reloads. if ( newSrc != img.src ) { // Store the original img.src var prevSrc, origSrc = img.getAttribute("src-orig"); if ( !origSrc ) { origSrc = img.src; img.setAttribute("src-orig", origSrc); } // In case of error, revert img.src prevSrc = img.src; img.onerror = function(){ img.src = prevSrc; if ( img.getAttribute("scale-fail") < scale ) img.setAttribute("scale-fail", scale); img.onerror = null; }; // Finally load the new image img.src = newSrc; } return true; } }; wpcom_img_zoomer.init(); ; /* global pm, wpcom_reblog */ var jetpackLikesWidgetQueue = []; var jetpackLikesWidgetBatch = []; var jetpackLikesMasterReady = false; function JetpackLikespostMessage( message, target ) { if ( 'string' === typeof message ){ try { message = JSON.parse( message ); } catch(e) { return; } } pm( { target: target, type: 'likesMessage', data: message, origin: '*' } ); } function JetpackLikesBatchHandler() { var requests = []; jQuery( 'div.jetpack-likes-widget-unloaded' ).each( function() { if ( jetpackLikesWidgetBatch.indexOf( this.id ) > -1 ) { return; } jetpackLikesWidgetBatch.push( this.id ); var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/, match = regex.exec( this.id ), info; if ( ! match || match.length !== 5 ) { return; } info = { blog_id: match[2], width: this.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, message ) { var allowedOrigin, $container, $list, offset, rowLength, height, scrollbarWidth; if ( 'undefined' === typeof event.event ) { return; } // We only allow messages from one origin allowedOrigin = window.location.protocol + '//widgets.wp.com'; if ( allowedOrigin !== message.origin ) { return; } if ( 'masterReady' === event.event ) { jQuery( document ).ready( function() { jetpackLikesMasterReady = true; var stylesData = { event: 'injectStyles' }, $sdTextColor = jQuery( '.sd-text-color' ), $sdLinkColor = jQuery( '.sd-link-color' ); if ( jQuery( 'iframe.admin-bar-likes-widget' ).length > 0 ) { JetpackLikespostMessage( { event: 'adminBarEnabled' }, window.frames[ 'likes-master' ] ); stylesData.adminBarStyles = { background: jQuery( '#wpadminbar .quicklinks li#wp-admin-bar-wpl-like > a' ).css( 'background' ), isRtl: ( 'rtl' === jQuery( '#wpadminbar' ).css( 'direction' ) ) }; } if ( ! window.addEventListener ) { jQuery( '#wp-admin-bar-admin-bar-likes-widget' ).hide(); } stylesData.textStyles = { color: $sdTextColor.css( 'color' ), fontFamily: $sdTextColor.css( 'font-family' ), fontSize: $sdTextColor.css( 'font-size' ), direction: $sdTextColor.css( 'direction' ), fontWeight: $sdTextColor.css( 'font-weight' ), fontStyle: $sdTextColor.css( 'font-style' ), textDecoration: $sdTextColor.css('text-decoration') }; stylesData.linkStyles = { color: $sdLinkColor.css('color'), fontFamily: $sdLinkColor.css('font-family'), fontSize: $sdLinkColor.css('font-size'), textDecoration: $sdLinkColor.css('text-decoration'), fontWeight: $sdLinkColor.css( 'font-weight' ), fontStyle: $sdLinkColor.css( 'font-style' ) }; JetpackLikespostMessage( stylesData, window.frames[ 'likes-master' ] ); JetpackLikesBatchHandler(); jQuery( document ).on( 'inview', 'div.jetpack-likes-widget-unloaded', function() { jetpackLikesWidgetQueue.push( this.id ); }); }); } if ( 'showLikeWidget' === event.event ) { jQuery( '#' + event.id + ' .post-likes-widget-placeholder' ).fadeOut( 'fast', function() { jQuery( '#' + event.id + ' .post-likes-widget' ).fadeIn( 'fast', function() { JetpackLikespostMessage( { event: 'likeWidgetDisplayed', blog_id: event.blog_id, post_id: event.post_id, obj_id: event.obj_id }, window.frames['likes-master'] ); }); }); } if ( 'clickReblogFlair' === event.event ) { wpcom_reblog.toggle_reblog_box_flair( event.obj_id ); } if ( 'showOtherGravatars' === event.event ) { $container = jQuery( '#likes-other-gravatars' ); $list = $container.find( 'ul' ); $container.hide(); $list.html( '' ); $container.find( '.likes-text span' ).text( event.total ); jQuery.each( event.likers, function( i, liker ) { var element = jQuery( '
  • ' ); element.addClass( liker.css_class ); element.find( 'a' ). attr({ href: liker.profile_URL, rel: 'nofollow', target: '_parent' }). addClass( 'wpl-liker' ); element.find( 'img' ). attr({ src: liker.avatar_URL, alt: liker.name }). css({ width: '30px', height: '30px', paddingRight: '3px' }); $list.append( element ); } ); offset = jQuery( '[name=\'' + event.parent + '\']' ).offset(); $container.css( 'left', offset.left + event.position.left - 10 + 'px' ); $container.css( 'top', offset.top + event.position.top - 33 + 'px' ); rowLength = Math.floor( event.width / 37 ); height = ( Math.ceil( event.likers.length / rowLength ) * 37 ) + 13; if ( height > 204 ) { height = 204; } $container.css( 'height', height + 'px' ); $container.css( 'width', rowLength * 37 - 7 + 'px' ); $list.css( 'width', rowLength * 37 + 'px' ); $container.fadeIn( 'slow' ); scrollbarWidth = $list[0].offsetWidth - $list[0].clientWidth; if ( scrollbarWidth > 0 ) { $container.width( $container.width() + scrollbarWidth ); $list.width( $list.width() + scrollbarWidth ); } } } pm.bind( 'likesMessage', JetpackLikesMessageListener ); jQuery( document ).click( function( e ) { var $container = jQuery( '#likes-other-gravatars' ); if ( $container.has( e.target ).length === 0 ) { $container.fadeOut( 'slow' ); } }); function JetpackLikesWidgetQueueHandler() { var $wrapper, wrapperID, found; if ( ! jetpackLikesMasterReady ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } if ( jetpackLikesWidgetQueue.length > 0 ) { // We may have a widget that needs creating now found = false; while( jetpackLikesWidgetQueue.length > 0 ) { // Grab the first member of the queue that isn't already loading. wrapperID = jetpackLikesWidgetQueue.splice( 0, 1 )[0]; if ( jQuery( '#' + wrapperID ).hasClass( 'jetpack-likes-widget-unloaded' ) ) { found = true; break; } } if ( ! found ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } } else if ( jQuery( 'div.jetpack-likes-widget-unloaded' ).length > 0 ) { // Grab any unloaded widgets for a batch request JetpackLikesBatchHandler(); // Get the next unloaded widget wrapperID = jQuery( 'div.jetpack-likes-widget-unloaded' ).first()[0].id; if ( ! wrapperID ) { // Everything is currently loaded setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } } if ( 'undefined' === typeof wrapperID ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } $wrapper = jQuery( '#' + wrapperID ); $wrapper.find( 'iframe' ).remove(); if ( $wrapper.hasClass( 'slim-likes-widget' ) ) { $wrapper.find( '.post-likes-widget-placeholder' ).after( '' ); } else { $wrapper.find( '.post-likes-widget-placeholder' ).after( '' ); } $wrapper.removeClass( 'jetpack-likes-widget-unloaded' ).addClass( 'jetpack-likes-widget-loading' ); $wrapper.find( 'iframe' ).load( function( e ) { var $iframe = jQuery( e.target ); $wrapper.removeClass( 'jetpack-likes-widget-loading' ).addClass( 'jetpack-likes-widget-loaded' ); JetpackLikespostMessage( { event: 'loadLikeWidget', name: $iframe.attr( 'name' ), width: $iframe.width() }, window.frames[ 'likes-master' ] ); if ( $wrapper.hasClass( 'slim-likes-widget' ) ) { $wrapper.find( 'iframe' ).Jetpack( 'resizeable' ); } }); setTimeout( JetpackLikesWidgetQueueHandler, 250 ); } JetpackLikesWidgetQueueHandler(); ; /** * navigation.js * * Handles toggling the navigation menu for small screens. */ ( function() { var container = document.getElementById( 'site-navigation' ), button = container.getElementsByTagName( 'h1' )[0], menu = container.getElementsByTagName( 'ul' )[0]; if ( undefined == button || undefined == menu ) return false; button.onclick = function() { if ( -1 == menu.className.indexOf( 'nav-menu' ) ) menu.className = 'nav-menu'; if ( -1 != button.className.indexOf( 'toggled-on' ) ) { button.className = button.className.replace( ' toggled-on', '' ); menu.className = menu.className.replace( ' toggled-on', '' ); container.className = container.className.replace( 'main-small-navigation', 'navigation-main' ); } else { button.className += ' toggled-on'; menu.className += ' toggled-on'; container.className = container.className.replace( 'navigation-main', 'main-small-navigation' ); } }; // Hide menu toggle button if menu is empty. if ( ! menu.childNodes.length ) button.style.display = 'none'; // Fix child menus for touch devices. function fixMenuTouchTaps( container ) { var touchStartFn, parentLink = container.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' ); if ( 'ontouchstart' in window ) { touchStartFn = function( e ) { var menuItem = this.parentNode; if ( ! menuItem.classList.contains( 'focus' ) ) { e.preventDefault(); for( var i = 0; i < menuItem.parentNode.children.length; ++i ) { if ( menuItem === menuItem.parentNode.children[i] ) { continue; } menuItem.parentNode.children[i].classList.remove( 'focus' ); } menuItem.classList.add( 'focus' ); } else { menuItem.classList.remove( 'focus' ); } }; for ( var i = 0; i < parentLink.length; ++i ) { parentLink[i].addEventListener( 'touchstart', touchStartFn, false ) } } } fixMenuTouchTaps( container ); } )();; ( function() { var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; if ( ( is_webkit || is_opera || is_ie ) && 'undefined' !== typeof( document.getElementById ) ) { var eventMethod = ( window.addEventListener ) ? 'addEventListener' : 'attachEvent'; window[ eventMethod ]( 'hashchange', function() { var element = document.getElementById( location.hash.substring( 1 ) ); if ( element ) { if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) element.tabIndex = -1; element.focus(); } }, false ); } })(); ; var addComment={moveForm:function(a,b,c,d){var e,f,g,h,i=this,j=i.I(a),k=i.I(c),l=i.I("cancel-comment-reply-link"),m=i.I("comment_parent"),n=i.I("comment_post_ID"),o=k.getElementsByTagName("form")[0];if(j&&k&&l&&m&&o){i.respondId=c,d=d||!1,i.I("wp-temp-form-div")||(e=document.createElement("div"),e.id="wp-temp-form-div",e.style.display="none",k.parentNode.insertBefore(e,k)),j.parentNode.insertBefore(k,j.nextSibling),n&&d&&(n.value=d),m.value=b,l.style.display="",l.onclick=function(){var a=addComment,b=a.I("wp-temp-form-div"),c=a.I(a.respondId);if(b&&c)return a.I("comment_parent").value="0",b.parentNode.insertBefore(c,b),b.parentNode.removeChild(b),this.style.display="none",this.onclick=null,!1};try{for(var p=0;p' + customizeIcon + '' + fbd.i18n.customize + ''; } // Edit Icon editIcon = ''; if ( fbd.canEditPost ) { fhtml += '
  • ' + editIcon + '' + fbd.i18n.edit + '
  • '; } // Stats Icon statsIcon = ''; if ( fbd.canEditPost ) { fhtml += '
  • ' + statsIcon + '' + fbd.i18n.stats + '
  • '; } // Follow/Unfollow Icon followingbtn = ''; followbtn = ''; fbhtml = '' + followbtn + '' + fbd.i18n.follow + ''; if ( fbd.isFollowing ) { fbhtml = '' + followingbtn + '' + fbd.i18n.following + ''; } // Show follow/unfollow icon on top level, when this is not your own site if ( fbd.canFollow && ! ( fbd.canEditPost || fbd.canCustomizeSite ) ) { fhtml += '
  • \ ' + fbhtml + ' \
    \
    \
    \
    \
  • '; } if ( ! fbd.canCustomizeSite ) { // Report Link reporthtml = '
  • ' + fbd.i18n.report + '
  • '; } // Show shortlink on single posts if ( fbd.isSingular ) { slkhtml = '' } // Set up fold/unfold menu item foldhtml = '
  • ' + fbd.i18n.foldBar + '
  • ' if ( fbd.isFolded ) { foldhtml = '
  • ' + fbd.i18n.unfoldBar + '
  • ' } if ( ! fbd.isLoggedIn && ! fbd.canFollow ) { foldhtml = ''; } if ( fbd.isLoggedIn ) { if ( '' != fbd.themeURL ) { themeHtml = '
  • ' + fbd.i18n.themeInfo.replace( /{theme}/, fbd.themeName ) + '
  • '; } if ( fbd.canFollow ) { viewReaderHtml = '
  • ' + fbd.i18n.viewReader + '
  • '; } editFollowsHtml = '
  • ' + fbd.i18n.editSubs + '
  • '; } else { loginHtml += ''; signupHtml = ''; editSubsHtml = '
  • ' + fbd.i18n.editSubs + '
  • '; } // Hide follow/unfollow completely for static sites, and sites not allowing followers (VIP, private, etc). if ( ! fbd.canFollow ) { fbHtmlLi = ''; } else { fbHtmlLi = '
  • ' + fbhtml + '
  • '; } // Ellipsis Menu fhtml += '
  • \ \
    \
    \
    \ \
    \
    \
  • \ '; fbdf = d.createElement( 'div' ); fbdf.id = 'actionbar'; fbdf.innerHTML = fhtml; b.appendChild( fbdf ); $actionbar = $( '#actionbar' ).addClass( 'actnbr-' + fbd.themeSlug.replace( '/', '-' ) ); // Add classes based on contents if ( fbd.canCustomizeSite ) { $actionbar.addClass( 'actnbr-has-customize' ); } if ( fbd.canEditPost ) { $actionbar.addClass( 'actnbr-has-edit' ); } if ( ! fbd.canCustomizeSite ) { $actionbar.addClass( 'actnbr-has-follow' ); } if ( fbd.isFolded ) { $actionbar.addClass( 'actnbr-folded' ); } // Show status message if available if ( fbd.statusMessage ) { showActionBarStatusMessage( fbd.statusMessage ); } // *** Actions ***************** // Follow Site $actionbar.on( 'click', '.actnbr-actn-follow', function(e) { e.preventDefault(); if ( fbd.isLoggedIn ) { showActionBarStatusMessage( '
    ' + fbd.i18n.followedText + '
    ' ); bumpStat( 'followed' ); request( 'ab_subscribe_to_blog' ); } else { showActionBarFollowForm(); } } ) // UnFollow Site .on( 'click', '.actnbr-actn-following', function(e) { e.preventDefault(); $( '#actionbar .actnbr-actn-following' ).replaceWith( '' + followbtn + '' + fbd.i18n.follow + '' ); bumpStat( 'unfollowed' ); request( 'ab_unsubscribe_from_blog' ); } ) // Show shortlink prompt .on( 'click', '.actnbr-shortlink a', function(e) { e.preventDefault(); window.prompt( "Shortlink: ", fbd.shortlink ); } ) // Toggle more menu .on( 'click', '.actnbr-ellipsis', function(e) { if ( $( e.target ).closest( 'a' ).hasClass( 'actnbr-action' ) ) { return false; } var popoverLi = $( '#actionbar .actnbr-ellipsis' ); popoverLi.toggleClass( 'actnbr-hidden' ); setTimeout( function() { if ( ! popoverLi.hasClass( 'actnbr-hidden' ) ) { $( document ).on( 'click.actnbr-body-click', function(e) { popoverLi.addClass( 'actnbr-hidden' ); $( document ).off( 'click.actnbr-body-click' ); } ); } }, 10 ); }) // Fold/Unfold .on( 'click', '.actnbr-fold', function(e) { e.preventDefault(); if ( $( '#actionbar' ).hasClass( 'actnbr-folded' ) ) { $( '.actnbr-fold a' ).html( fbd.i18n.foldBar ); $( '#actionbar' ).removeClass( 'actnbr-folded' ); $.post( fbd.xhrURL, { 'action': 'unfold_actionbar' } ); } else { $( '.actnbr-fold a' ).html( fbd.i18n.unfoldBar ); $( '#actionbar' ).addClass( 'actnbr-folded' ); $.post( fbd.xhrURL, { 'action': 'fold_actionbar' } ); } }) // Record stats for clicks .on( 'click', '.actnbr-sitename a', function(e) { bumpStat( 'clicked_site_title' ); }) .on( 'click', '.actnbr-customize a', function(e) { bumpStat( 'customized' ); }) .on( 'click', '.actnbr-folded-customize a', function(e) { bumpStat( 'customized' ); }) .on( 'click', '.actnbr-theme a', function(e) { bumpStat( 'explored_theme' ); }) .on( 'click', '.actnbr-edit a', function(e) { bumpStat( 'edited' ); }) .on( 'click', '.actnbr-stats a', function(e) { bumpStat( 'clicked_stats' ); }) .on( 'click', '.flb-report a', function(e) { bumpStat( 'reported_content' ); }) .on( 'click', '.actnbr-follows a', function(e) { bumpStat( 'managed_following' ); }) .on( 'click', '.actnbr-shortlink a', function(e) { bumpStat( 'copied_shortlink' ); }) .on( 'click', '.actnbr-reader a', function(e) { bumpStat( 'view_reader' ); }) .on( 'submit', '.actnbr-follow-bubble form', function ( e ) { $( '#actionbar .actnbr-follow-bubble form button' ).attr( 'disabled', true ); }); // Make Follow/Unfollow requests var request = function( action ) { $.post( fbd.xhrURL, { 'action': action, '_wpnonce': fbd.nonce, 'source': 'actionbar', 'blog_id': fbd.siteID }); }; // Show/Hide actionbar on scroll fb = $('#actionbar'); toggleactionbar = function() { var st = $(window).scrollTop(), topOffset = 0; if ( $(window).scrollTop() < 0 ) { return; } // Still if ( lastScrollTop == 0 || ( ( st == lastScrollTop ) && lastScrollDir == 'up' ) ) { fb.removeClass( 'actnbr-hidden' ); // Moving } else { // Scrolling Up if ( st < lastScrollTop ){ fb.removeClass( 'actnbr-hidden' ); lastScrollDir = 'up'; // Scrolling Down } else { // check if there are any popovers open, and only hide action bar if not if ( $( '#actionbar > ul > li:not(.actnbr-hidden) > .actnbr-popover' ).length === 0 ) { fb.addClass( 'actnbr-hidden' ) lastScrollDir = 'down'; // Hide any menus $( '#actionbar li' ).addClass( 'actnbr-hidden' ); } } } lastScrollTop = st; } setInterval( toggleactionbar, 100 ); // Bump stats var bumpStat = function( stat ) { $.post( fbd.xhrURL, { 'action': 'actionbar_stats', 'stat': stat }); } function actionBarEscapeHtml(string) { return String(string).replace(/[&<>"'\/]/g, function (s) { var entityMap = { "&": "&", "<": "<", ">": ">", '"': '"', "'": ''', "/": '/' }; return entityMap[s]; }); }; function showActionBarStatusMessage( message ) { $( '#actionbar .actnbr-actn-follow' ).replaceWith( '' + followingbtn + '' + fbd.i18n.following + '' ); $( '#actionbar .actnbr-follow-bubble' ).html( ' \ \ '); var btn = $( '#actionbar .actnbr-btn' ); btn.removeClass( 'actnbr-hidden' ); setTimeout( function() { if ( ! btn.hasClass( 'actnbr-hidden' ) ) { $( '#actionbar .actnbr-email-field' ).focus(); $( document ).on( 'click.actnbr-body-click', function(e) { if ( $( e.target ).closest( '.actnbr-popover' )[0] ) { return; } btn.addClass( 'actnbr-hidden' ); $( document ).off( 'click.actnbr-body-click' ); } ); } }, 10 ); } function showActionBarFollowForm() { var btn = $( '#actionbar .actnbr-btn' ); btn.toggleClass( 'actnbr-hidden' ); var form = $('
    '); if ( fbd.i18n.followers ) form.append($('
    ').html(fbd.i18n.followers)); form.append($('
    ').append($('').attr({"type": "email", "name": "email", "placeholder": fbd.i18n.enterEmail, "class": "actnbr-email-field"}))); form.append($('')); form.append($('').attr('value', fbd.siteID)); form.append($('').attr('value', fbd.referer)); form.append($('')); form.append($(fbd.subscribeNonce)); form.append($('
    ').append($('